Newer
Older
scim-wnn / scim-wnn / src / scim_wnn_imengine.cpp
@tamra tamra on 20 Nov 2004 9 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.             *
 ***************************************************************************/

// って言うか先にWnnをC++向けに優しく包み込む母のようなライブラリ激しく希望。
// ああそうですね、「お前がやれ」ですよね。

#define Uses_SCIM_UTILITY
#define Uses_SCIM_IMENGINE
#define Uses_SCIM_LOOKUP_TABLE
#define Uses_SCIM_CONFIG_BASE
#define Uses_SCIM_ICONV

#ifdef HAVE_CONFIG_H
  #include <config.h>
#endif

// 国際化のおまじない。
// まぁ愚痴を言わせてもらえば、これを毎回どうにかしなきゃいけないっつーのは
// どうなんでしょうなぁ…。
// KDEなら飛ばせる部分ですが何か?。
#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

// scimのおまじない。
// 一言で言えば、めんどくs
#include "scim_wnn_imengine.h"

#define scim_module_init wnn_LTX_scim_module_init
#define scim_module_exit wnn_LTX_scim_module_exit
#define scim_imengine_module_init wnn_LTX_scim_imengine_module_init
#define scim_imengine_module_create_factory wnn_LTX_scim_imengine_module_create_factory
#ifndef SCIM_WNN_ICON_FILE
  #define SCIM_WNN_ICON_FILE           (SCIM_ICONDIR "/scim-wnn.png")
#endif

static Pointer <WnnFactory> _scim_wnn_factory;
static ConfigPointer _scim_config;

extern "C" {
    // あれでしょう。
    // KDEなんかでも使われてる動的ローディングの小技。
    // Cリンケージで関数名固定させて、そっからインスタンス作るっつーあれ。
    // 面倒だよねぇ。まぁ別に良いけどさ。
    void scim_module_init (void)
    {
    }

    void scim_module_exit (void)
    {
        _scim_wnn_factory.reset ();
        _scim_config.reset ();
    }

    unsigned int scim_imengine_module_init (const ConfigPointer &config)
    {
        _scim_config = config;
        return 1;
    }

    IMEngineFactoryPointer scim_imengine_module_create_factory (unsigned int factory)
    {
        if (factory != 0) return NULL;
        if (_scim_wnn_factory.null ()) {
            _scim_wnn_factory =
                new WnnFactory (utf8_mbstowcs (String (_("WNN"))),String("ja_JP"));
        }
        return _scim_wnn_factory;
    }
}

WnnFactory::WnnFactory() {
    m_name = utf8_mbstowcs(_("Wnn"));
    set_languages(String("ja_JP"));
}

WnnFactory::~ WnnFactory() {
}

WnnFactory::WnnFactory(const WideString & name, const String & languages) {
    // 文字数制限か。
    if (name.length () <= 8)
        m_name = name;
    else
        m_name.assign (name.begin (), name.begin () + 8);
    // とりあえず日本語環境で固定したいトコだ。
    if (languages == String ("default"))
        set_languages (String (_("ja_JP")));
    else
        set_languages (languages);
}

WideString WnnFactory::get_name () const
{
    // 名前を返すのね。utf8_mbstowcs(_("Wnn"))で。
    return m_name;
}

WideString WnnFactory::get_authors () const
{
    // AUTHERね。
    return utf8_mbstowcs (String (_("(C) 2004 TAM(Teppei Tamra) <tam-t@par.odn.ne.jp>")));
}

WideString WnnFactory::get_credits () const
{
    // CREDITね。とりあえず空で。
    return WideString ();
}

WideString WnnFactory::get_help () const
{
    // HELPも書かないとダメなのね。
    return utf8_mbstowcs (String (_("SCIM-WNN HELP")));
}

String WnnFactory::get_uuid () const
{
    // uuidgen叩いて識別と。ユニークならなんでもよさげだけども。
    return String ("c069395a-d62f-4a77-8229-446e44a99976");
}

String WnnFactory::get_icon_file () const
{
    // アイコンを指定。作らないとね。
    return String (SCIM_WNN_ICON_FILE);
}

IMEngineInstancePointer WnnFactory::create_instance (const String& encoding, int id)
{
    // 実際にインスタンスを作る。
    return new WnnInstance (this, encoding, id);
}


// 淫 醋 箪 笥
// 現物。


WnnInstance::WnnInstance (WnnFactory *factory, const String& encoding, int id)
    : IMEngineInstanceBase (factory, encoding, id)
{
    m_conversion = false;
}

WnnInstance::~ WnnInstance()
{
}

bool WnnInstance::process_key_event (const KeyEvent& key)
{
    if (key.is_key_release()) return false;
    if (m_conversion) return(process_conversion_key_event(key));
    else return(process_preedit_key_event(key));
}


/*!
    \fn WnnInstance::process_preedit_key_event(const KeyEvent &key)
 */
bool WnnInstance::process_preedit_key_event(const KeyEvent &key)
{
    // キーコードを直指定ってダサいよね。追々修正しますがとりあえずこのままで。

    if (key.code == SCIM_KEY_space) {
        if (!m_rk.getTextLength()) {
            return(false);
        }
        m_conversion = true;
        startConversion(m_rk.getText(true));
        return(process_conversion_key_event(key));
    }
    if (key.code == SCIM_KEY_Return) {
        if (!m_rk.getTextLength()) {
            return(false);
        }
        commit_string(m_rk.getText(true));
        m_rk.reset();
        hide_preedit_string();
        return(true);
    }
    if ((key.code == SCIM_KEY_Left) || (key.code == SCIM_KEY_Right)) {
        if (!m_rk.getTextLength()) {
            return(false);
        }
        key.code == SCIM_KEY_Left ? m_rk.setPos(m_rk.getPos() - 1) : m_rk.setPos(m_rk.getPos() + 1);
        update_preedit_caret(m_rk.getPos());
        return(true);
    }
    if (key.code == SCIM_KEY_BackSpace) {
        if (!m_rk.getTextLength()) {
            return(false);
        }
        m_rk.backspace();
        update_preedit_string(m_rk.getText());
        update_preedit_caret(m_rk.getPos());
        return(true);
    }
    if (isprint(key.code)) {
        show_preedit_string();
        SCIM_DEBUG_IMENGINE(1) << key.get_key_string() << "\n";
        update_preedit_string(m_rk.insert(key.get_ascii_code()));
        update_preedit_caret(m_rk.getPos());
        return true;
    }
    return false;
}

/*!
    \fn WnnInstance::process_conversion_key_event(const KeyEvent &key)
 */
bool WnnInstance::process_conversion_key_event(const KeyEvent &key)
{
    show_preedit_string();
    update_preedit_string(wnn.getText());
    update_preedit_caret(wnn.getText().length());

    if (key.code == SCIM_KEY_Return) {
        commit_string(wnn.getText());
        m_rk.reset();
        wnn.reset();
        m_conversion = false;
        hide_preedit_string();
        return(true);
    }
    if ((key.code == SCIM_KEY_Escape) || (key.code == SCIM_KEY_BackSpace)) {
        wnn.reset();
        m_conversion = false;
        update_preedit_string(m_rk.getText());
        update_preedit_caret(m_rk.getPos());
        return(true);
    }
    return(true);
}


void WnnInstance::move_preedit_caret (unsigned int pos)
{
    m_rk.setPos(pos);
    update_preedit_caret(pos);
}

void WnnInstance::select_candidate (unsigned int item)
{
   if (!m_lookup_table.number_of_candidates ()) return;

    unsigned int current = m_lookup_table.get_cursor_pos_in_current_page ();

    if (current != item) {
        m_lookup_table.set_cursor_pos_in_current_page (item);
        update_lookup_table (m_lookup_table);
    }

}

void WnnInstance::update_lookup_table_page_size (unsigned int page_size)
{
    m_lookup_table.set_page_size (page_size);
}

void WnnInstance::lookup_table_page_up ()
{
    if (!m_lookup_table.number_of_candidates () || !m_lookup_table.get_current_page_start ()) return;

    m_lookup_table.page_up ();

    update_lookup_table (m_lookup_table);

}

void WnnInstance::lookup_table_page_down ()
{
    if (!m_lookup_table.number_of_candidates () ||
        m_lookup_table.get_current_page_start () + m_lookup_table.get_current_page_size () >=
          m_lookup_table.number_of_candidates ())
        return;

    m_lookup_table.page_down ();

    update_lookup_table (m_lookup_table);

}

void WnnInstance::reset ()
{

}

void WnnInstance::focus_in ()
{
    hide_aux_string ();

    if (m_lookup_table.number_of_candidates ()) {
        update_lookup_table (m_lookup_table);
        show_lookup_table ();
    } else {
        hide_lookup_table ();
    }

}

void WnnInstance::focus_out ()
{
}

void WnnInstance::trigger_property (const String &property)
{
}






/*!
    \fn WnnInstance::startConversion(WideString s)
 */
void WnnInstance::startConversion(WideString s)
{
    wnn.setYomiText(s);
    wnn.ren_conversion();
}