/*************************************************************************** * 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" #ifdef HAVE_CONFIG_H #include <config.h> #endif // 国際化のおまじない。 #ifdef HAVE_GETTEXT #include <libintl.h> #define _(String) dgettext(GETTEXT_PACKAGE,String) #define N_(String) (String) #else #define _(String) (String) #define N_(String) (String) #define bindtextdomain(Package,Directory) #define textdomain(domain) #define bind_textdomain_codeset(domain,codeset) #endif Romkan::Romkan(ConfigPointer cfg) : PreEditor(cfg) { reset(); iconvert.set_encoding ("EUC-JP"); mode = ROMA; } Romkan::~Romkan() { } /*! \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) { String s; s = k; if (k == 0) return(text); switch(mode) { case LATIN: { buf.clear(); text = text.substr(0,pos) + utf8_mbstowcs(s) + text.substr(pos); pos ++; return(text); break; } case WLATIN: { buf.clear(); WideString w = utf8_mbstowcs(s); convHanZen(w); text = text.substr(0,pos) + w + text.substr(pos); pos ++; return(text); break; } case ROMA: { if (k == 'q') { mode = LATIN; buf.clear(); return(text); break; } else if (k == 'Q') { mode = WLATIN; buf.clear(); return(text); break; } buf += k; text = text.substr(0,pos) + utf8_mbstowcs(s) + text.substr(pos); pos ++; return(eval()); break; } } return(text); } /*! \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(strcmp(RomkanTable[i],"") != 0) { 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; } if (buf.length()) buf = buf.substr(1); return(text); } /*! \fn Romkan::reset() */ void Romkan::reset() { clear(); pos = 0; mode = ROMA; } /*! \fn Romkan::getText(bool hosei) */ WideString Romkan::getText(bool hosei) { if (hosei) { if (buf.length()) { if (buf.substr(buf.length() - 1,1) == "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::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 ((isprint(key.code)) && ((mode == LATIN) || (mode == WLATIN))) { if (!(key.mask & (SCIM_KEY_AltMask | SCIM_KEY_ControlMask))) { insert(key.get_ascii_code()); return(true); } } if (!buf.length()) return(false); if (buf[buf.length() - 1] == 'Z') { if (key.code == SCIM_KEY_space) { insert(' '); return(true); } } return(false); } /*! \fn Romkan::getModeName() */ String Romkan::getModeName() { switch(mode) { case ROMA: { return(String(_("Roma-Kana"))); break; } case LATIN: { return(String(_("Latin"))); break; } case WLATIN: { return(String(_("Wide Latin"))); break; } } } /*! \fn Romkan::cancelEvent() */ bool Romkan::cancelEvent() { if ((mode == LATIN) || (mode == WLATIN)) { mode = ROMA; return(true); } return(false); } /*! \fn Romkan::inputEvent(const KeyEvent &key) */ bool Romkan::inputEvent(const KeyEvent &key) { if (isprint(key.code) && (!key.is_alt_down()) && (!key.is_control_down())) { if (key.get_ascii_code() == ' ') return(false); insert(key.get_ascii_code()); return(true); } return(false); }