Newer
Older
scim-wnn / scim-wnn / src / romkan.cpp
@tamra tamra on 29 Nov 2004 5 KB 細いバグ修正。
/***************************************************************************
 *   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 "romkan.h"
#include "romkan_table.h"

Romkan::Romkan()
{
    reset();
    iconvert.set_encoding ("EUC-JP");
}


Romkan::~Romkan()
{
}


/*!
    \fn Romkan::getPos()
 */
int Romkan::getPos()
{
    return(pos);
}


/*!
    \fn Romkan::getTextLength()
 */
int Romkan::getTextLength()
{
    return(text.length());
}


/*!
    \fn Romkan::setPos(int p)
 */
void Romkan::setPos(int p)
{
    if (p < 0) p = 0;
    else if (p > getTextLength()) p = getTextLength();
    pos = p;
    buf.clear();
}


/*!
    \fn Romkan::clear()
 */
void Romkan::clear()
{
    text.clear();
    buf.clear();
}


/*!
    \fn Romkan::insert(char k)
 */
WideString Romkan::insert(char k)
{
    buf += k;
    String s;
    s = k;
    text = text.substr(0,pos) + utf8_mbstowcs(s) + text.substr(pos);
    pos ++;
    //return(text);
    return(eval());
}


/*!
    \fn Romkan::eval()
 */
WideString Romkan::eval()
{
    // エヴァる。

    if (buf.length() == 2) {

        // n+母音以外は「ん」+子音である
        // ただし、nyは除外である。
        if (buf[0] == 'n') {
            String b = "aiueoy";
            bool boin = false;
            for(unsigned int i = 0;i < b.length();i ++) {
                if (buf[1] == b[i]) boin = true;
            }
            if (!boin) {
                WideString w;
                iconvert.convert(w,String("ん"));
                text = text.substr(0,pos - 2) + w + text.substr(pos - 1);
                buf = buf.substr(buf.length() - 1,1);
            }
        }

        // 同じ文字が2文字続くとそれは「っ」+子音である。母音の連打がbufに残ってはいないはず。
        else if (buf[0] == buf[1]) {
            WideString w;
            iconvert.convert(w,String("っ"));
            text = text.substr(0,pos - 2) + w + text.substr(pos - 1);
            buf = buf.substr(buf.length() - 1,1);
            return(text);
        }
    }

    // テーブルを検索して入力する。
    unsigned int i = 0;
    while(RomkanTable[i] != "") {
        if (buf == String(RomkanTable[i])) {
            if (String(RomkanTable[i + 1]) == "") {
                return(text); // 保留する。
            }
            WideString w;
            iconvert.convert(w,String(RomkanTable[i + 1]));
            text = text.substr(0,pos - buf.length()) + w + text.substr(pos);
            pos = pos - buf.length() + w.length();
            buf.clear();
            return(text);
        }
        i += 2;
    }
    buf.clear();
    return(text);
}




/*!
    \fn Romkan::reset()
 */
void Romkan::reset()
{
    clear();
    pos = 0;
}


/*!
    \fn Romkan::getText(bool hosei)
 */
WideString Romkan::getText(bool hosei)
{
    if (hosei) {
        if (text.substr(pos - 1,1) == utf8_mbstowcs("n")) {
            WideString w;
            iconvert.convert(w,String("ん"));
            text = text.substr(0,pos - 1) + w;
        }
    }
    return(text);
}


/*!
    \fn Romkan::backspace()
 */
void Romkan::backspace()
{
    if (getPos() == 0) return;
    text = text.substr(0,pos - 1) + text.substr(pos);
    setPos(pos - 1);
    // BSは小バッファもBSするゾ。
    if (buf.length()) buf = buf.substr(0,buf.length() - 1);
}



/*!
    \fn Romkan::del()
 */
void Romkan::del()
{
    if (getPos() == getTextLength()) return;
    text = text.substr(0,pos) + text.substr(pos + 1);
}


/*!
    \fn Romkan::convHiraKata(WideString &t)
 */
void Romkan::convHiraKata(WideString &t)
{
    WideString start_c,end_c,conv_c;
    iconvert.convert(start_c,String("ぁ"));
    iconvert.convert(end_c,String("ん"));
    iconvert.convert(conv_c,String("ァ"));
    for(unsigned int i = 0;i < t.size();i ++) {
        if ((t[i] >= start_c[0]) && (t[i] <= end_c[0]))
            t[i] = t[i] - start_c[0] + conv_c[0];
    }
    return;
}


/*!
    \fn Romkan::convKataHira(WideString &t)
 */
void Romkan::convKataHira(WideString &t)
{
    WideString start_c,end_c,conv_c;
    iconvert.convert(start_c,String("ァ"));
    iconvert.convert(end_c,String("ン"));
    iconvert.convert(conv_c,String("ぁ"));
    for(unsigned int i = 0;i < t.size();i ++) {
        if ((t[i] >= start_c[0]) && (t[i] <= end_c[0]))
            t[i] = t[i] - start_c[0] + conv_c[0];
    }
    return;

}


/*!
    \fn Romkan::hiraKata()
 */
void Romkan::hiraKata()
{
    convHiraKata(text);
}


/*!
    \fn Romkan::kataHira()
 */
void Romkan::kataHira()
{
    convKataHira(text);
}


/*!
    \fn Romkan::keyEventHook(const KeyEvent &key)
 */
bool Romkan::keyEventHook(const KeyEvent &key)
{
    if (!buf.length()) return(false);
    if (buf[buf.length() - 1] == 'Z') {
        if (key.code == SCIM_KEY_space) {
            insert(' ');
            return(true);
        }
    }
    return(false);
}