Newer
Older
scim-wnn / honoka / libhonoka / preeditor.cpp
/***************************************************************************
 *   Copyright (C) 2004 by TAM(Teppei Tamra)                               *
 *   tam-t@par.odn.ne.jp                                                   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include "preeditor.h"


PreEditor::PreEditor(ConfigPointer cfg) : HonokaPluginBase(String("PreEditor"))
{
    // コンストラクタ。
    // ここではPreEditor内蔵の処理(半角全角変換等)の処理をやってます。
    iconvert.set_encoding ("EUC-JP");
    config = cfg;
    if (!convChars.size())
        convChars = utf8_mbstowcs(String("ぁんァン!~!}んっ"));
    if (!hKanaChars.size()) {
        // 強引だけどこれ以外方法思いつかないよー
        const String hKana[] = {
            "ァ","ア","ィ","イ","ゥ","ウ","ェ","エ","ォ","オ","カ","ガ","キ","ギ","ク",
            "グ","ケ","ゲ","コ","ゴ","サ","ザ","シ","ジ","ス","ズ","セ","ゼ","ソ",
            "ゾ","タ","ダ","チ","ヂ","ッ","ツ","ヅ","テ","デ","ト","ド","ナ","ニ","ヌ",
            "ネ","ノ","ハ","バ","パ","ヒ","ビ","ピ","フ","ブ","プ","ヘ","ベ","ペ",
            "ホ","ボ","ポ","マ","ミ","ム","メ","モ","ャ","ヤ","ュ","ユ","ョ","ヨ","ラ",
            "リ","ル","レ","ロ","ワ","ワ","イ","エ","ヲ","ン","","","","","","","",
            "゙","゚","","","","",
            "ァ","ア","ィ","イ","ゥ","ウ","ェ","エ","ォ","オ","カ","ガ","キ","ギ","ク",
            "グ","ケ","ゲ","コ","ゴ","サ","ザ","シ","ジ","ス","ズ","セ","ゼ","ソ",
            "ゾ","タ","ダ","チ","ヂ","ッ","ツ","ヅ","テ","デ","ト","ド","ナ","ニ","ヌ",
            "ネ","ノ","ハ","バ","パ","ヒ","ビ","ピ","フ","ブ","プ","ヘ","ベ","ペ",
            "ホ","ボ","ポ","マ","ミ","ム","メ","モ","ャ","ヤ","ュ","ユ","ョ","ヨ","ラ",
            "リ","ル","レ","ロ","ワ","ワ","イ","エ","ヲ","ン","ヴ","カ","ケ","","","","",
            "","-","オワリダゴルァ"
            };
        for(unsigned int i = 0;hKana[i] != "オワリダゴルァ";i ++) {
            if (hKana[i] != "") {
                hKanaChars.insert(pair<ucs4_t,WideString>(convChars[HIRA_START] + i,utf8_mbstowcs(hKana[i])));
            }
        }
    }
}


PreEditor::~PreEditor()
{
    // 正しい終了処理をデストラクタに書きましょう。
}

WideString PreEditor::text = WideString();
WideString PreEditor::convChars = WideString();
map<ucs4_t,WideString> PreEditor::hKanaChars;
int PreEditor::pos = 0;
IConvert PreEditor::iconvert;
WideString PreEditor::commitString = WideString();

/*!
    \fn PreEditor::getPos()
 */
int PreEditor::getPos()
{
    // キャレットの位置を返します。
    // キャレット位置の管理は自前で行って下さい。
    return pos;
}


/*!
    \fn PreEditor::getTextLength()
 */
int PreEditor::getTextLength()
{
    // PreEditテキストの長さを返します。
    // WideString、つまりはwcsでの文字数です。
    return text.length();
}


/*!
    \fn PreEditor::textIsEmpty()
 */
bool PreEditor::textIsEmpty()
{
    // PreEditテキストが空かどうか返します。
    // getTextLengthがあるので要らないような気もします。
    return text.empty();
}


/*!
    \fn PreEditor::setPos(int p)
 */
void PreEditor::setPos(int p)
{
    // キャレットの位置をセットします。
    if (p < 0) p = 0;
    else if (p > getTextLength()) p = getTextLength();
    pos = p;
}


/*!
    \fn PreEditor::clear()
 */
void PreEditor::clear()
{
    // PreEditテキストを消去します。
    text.clear();
}



/*!
    \fn PreEditor::reset()
 */
void PreEditor::reset()
{
    // PreEditorのリセット処理を記述します。
    clear();
    pos = 0;
}


/*!
    \fn PreEditor::getText(bool hosei)
 */
WideString PreEditor::getText(bool hosei)
{
    // PreEditテキストを返します。
    // hosei=trueの場合は「完全な状態」のテキストを返します。
    // 例えばローマ字変換における文末の「n」等を「ん」に直す等です。
    return text;
}


/*!
    \fn PreEditor::backspace()
 */
void PreEditor::backspace()
{
    // バックスペースが押された場合の処理を記述します。
    if (getPos() == 0) return;
    text = text.substr(0,pos - 1) + text.substr(pos);
    setPos(pos - 1);
}



/*!
    \fn PreEditor::del()
 */
void PreEditor::del()
{
    // デリートが押された場合の処理を記述します。
    if (getPos() == getTextLength()) return;
    text = text.substr(0,pos) + text.substr(pos + 1);
}


/*!
    \fn PreEditor::convHiraKata(WideString &t)
 */
void PreEditor::convHiraKata(WideString &t)
{
    // ひらがな->カタカナ変換用staticメソッドです。
    for(unsigned int i = 0;i < t.size();i ++) {
        if ((t[i] >= convChars[HIRA_START]) && (t[i] <= convChars[HIRA_END]))
            t[i] = t[i] - convChars[HIRA_START] + convChars[KATA_START];
    }
    return;
}


/*!
    \fn PreEditor::convKataHira(WideString &t)
 */
void PreEditor::convKataHira(WideString &t)
{
    // カタカナ->ひらがな変換用staticメソッドです。
    for(unsigned int i = 0;i < t.size();i ++) {
        if ((t[i] >= convChars[KATA_START]) && (t[i] <= convChars[KATA_END]))
            t[i] = t[i] - convChars[KATA_START] + convChars[HIRA_START];
    }
    return;

}


/*!
    \fn PreEditor::convHanZen(WideString &t,int p)
 */
int PreEditor::convHanZen(WideString &t,int p)
{
    // 半角->全角変換用staticメソッドです。
    for(unsigned int i = 0;i < t.size();i ++) {
        if ((t[i] >= convChars[ASCII_START]) && (t[i] <= convChars[ASCII_END]))
            t[i] = t[i] - convChars[ASCII_START] + convChars[WASCII_START];
    }
    return p;

}


/*!
    \fn PreEditor::convZenHan(WideString &t,int p)
 */
int PreEditor::convZenHan(WideString &t,int p)
{
    // 全角->半角変換用staticメソッドです。
    for(unsigned int i = 0;i < t.size();i ++) {
        if ((t[i] >= convChars[WASCII_START]) && (t[i] <= convChars[WASCII_END]))
            t[i] = t[i] - convChars[WASCII_START] + convChars[ASCII_START];

        // 超絶半角カナ変換
        map<ucs4_t,WideString>::iterator it = hKanaChars.find(t[i]);
        if (it != hKanaChars.end()) {
            WideString m1 = t.substr(0,i);
            WideString m2 = t.substr(i + 1);
            t = m1 + it->second + m2;
            if (p > i) p += it->second.size() - 1;
            i += it->second.length() - 1;
        }
    }
    return p;

}


/*!
    \fn PreEditor::hiraKata()
 */
void PreEditor::hiraKata()
{
    // ひらがな->カタカナ変換処理を記述します。
    // 特に問題なければオーバロードの必要はありません。
    convHiraKata(text);
}


/*!
    \fn PreEditor::kataHira()
 */
void PreEditor::kataHira()
{
    // カタカナ->ひらがな変換処理を記述します。
    // 特に問題なければオーバロードの必要はありません。
    convKataHira(text);
}


/*!
    \fn PreEditor::toHalf()
 */
void PreEditor::toHalf()
{
    // 全角->半角変換処理を記述します。
    // 特に問題なければオーバロードの必要はありません。
    convZenHan(text,pos);
}

/*!
    \fn PreEditor::toWide()
 */
void PreEditor::toWide()
{
    // 半角->全角変換処理を記述します。
    // 特に問題なければオーバロードの必要はありません。
    convHanZen(text,pos);
}


/*!
    \fn PreEditor::keyEventHook(const KeyEvent &key)
 */
bool PreEditor::keyEventHook(const KeyEvent &key)
{
    // IMEngineのインスタンスより先に処理されるキーイベント処理を書きます。
    // 特殊な場合を除いて、ここは使用しない方が良いと思います。
    // 例えばSpaceを含む処理をPreEditorで処理したい場合等に利用すれば、
    // 変換キーとしてSpaceが割り当てられていたとしても処理できます。
    // trueを返すことで以後の処理は破棄されます。
    return false;
}



/*!
    \fn PreEditor::getModeName()
 */
String PreEditor::getModeName()
{
    // ツールバーのプロパティに表示されるモード部分の名前を指定します。
    // 「全角」「半角」等の文字を表示させたりできます。
    String s;
    return s;
}


/*!
    \fn PreEditor::cancelEvent()
 */
bool PreEditor::cancelEvent()
{
    // キャンセルに割り当てられたキーが押された時の処理を書きます。
    return false;
}



/*!
    \fn PreEditor::inputEvent(const KeyEvent &key)
 */
bool PreEditor::inputEvent(const KeyEvent &key)
{
    // キーイベント処理を書きます。
    // trueを返すことで以後の処理は破棄されます。
    if (key.get_unicode_code()){
        text = text.substr(0,pos) + key.get_unicode_code() + text.substr(pos);
        pos ++;
        return true;
    }
    return false;
}


/*!
    \fn PreEditor::getName()
 */
String PreEditor::getName()
{
    // 名前を返します。
    // ユニークな名前を割り当てましょう。
    return String("PreEditor");
}


/*!
    \fn PreEditor::setText(const WideString &t)
 */
void PreEditor::setText(const WideString &t)
{
    // PreEditテキストをセットします。
    text = t;
}



/*!
    \fn PreEditor::getAttributeList()
 */
AttributeList PreEditor::getAttributeList()
{
    // getTextと同時に使われるAttributeを返します。
    return AttributeList();
}


/*!
    \fn PreEditor::selected()
 */
void PreEditor::selected()
{
    return;
}


/*!
    \fn PreEditor::unSelected()
 */
void PreEditor::unSelected()
{
    return;
}


/*!
    \fn PreEditor::getCommitString()
 */
const WideString PreEditor::getCommitString()
{
    return commitString;
}


/*!
    \fn PreEditor::setCommitString(const WideString &t)
 */
void PreEditor::setCommitString(const WideString &t)
{
    commitString = t;
}


/*!
    \fn PreEditor::resetCommitString()
 */
void PreEditor::resetCommitString()
{
    commitString.clear();
}


/*!
    \fn PreEditor::isPrintable(const KeyEvent &key)
 */
bool PreEditor::isPrintable(const KeyEvent &key)
{
    if ((key.code == SCIM_KEY_Return) ||
        (key.code == SCIM_KEY_Linefeed) ||
        (key.code == SCIM_KEY_Tab)) return false;

    if (key.get_unicode_code() && (!key.is_alt_down()) && (!key.is_control_down())) return true;
    return false;
}

/*!
    \fn PreEditor::isThrough(const KeyEvent &key)
 */
bool PreEditor::isThrough(const KeyEvent &key)
{
    // 喰っておくべきもの。
    if ((key.code == SCIM_KEY_Shift_L) ||
        (key.code == SCIM_KEY_Shift_R) ||
        (key.code == SCIM_KEY_Control_L) ||
        (key.code == SCIM_KEY_Control_R) ||
        (key.code == SCIM_KEY_Alt_L) ||
        (key.code == SCIM_KEY_Alt_R) ||
        (key.code == SCIM_KEY_Super_L) ||
        (key.code == SCIM_KEY_Super_R) ||
        (key.code == SCIM_KEY_Hyper_L) ||
        (key.code == SCIM_KEY_Hyper_R) ||
        (key.code == SCIM_KEY_Meta_L) ||
        (key.code == SCIM_KEY_Meta_R) ||
        (key.code == SCIM_KEY_Num_Lock) ||
        (key.code == SCIM_KEY_Caps_Lock) ||
        (key.code == SCIM_KEY_Shift_Lock) ||
        (key.code == SCIM_KEY_Mode_switch) ||
        (key.code == SCIM_KEY_ISO_Next_Group)) return true;
    return false;
}