Newer
Older
scim-wnn / skim_honoka / src / skim_honoka.cpp
/***************************************************************************
 *   Copyright (C) 2005 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.             *
 ***************************************************************************/

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

  #define _(String) QString(i18n(String)).local8Bit().data()

#define Uses_SCIM_CONFIG_MODULE
#define Uses_SCIM_CONFIG_PATH
#define Uses_SCIM_GLOBAL_CONFIG


#include <scim.h>
#include <scim_global_config.h>

#include <sys/types.h>
#include <dirent.h>
#include <dlfcn.h>

using namespace scim;

class scimConfigPrivate {
public:
    scim::ConfigModule configModule;
    scim::ConfigPointer config;
};

#include <qlayout.h>

#include <klocale.h>
#include <kglobal.h>
#include <qpushbutton.h>
#include <qlayout.h>
#include <kparts/genericfactory.h>
#include <klocale.h>

#include "skim_honoka.h"
#include <honokasetupkde.h>
#include "honoka_def.h"
#include "honoka_plugin_def.h"

#include <honokapluginbase.h>
typedef HonokaSetupCorePage *pluginSetupFunc();
typedef int getPluginVersionFunc();

static HonokaSetupKde *_setup;

typedef KGenericFactory<skim_honoka, QWidget> skim_honokaFactory;
K_EXPORT_COMPONENT_FACTORY( kcm_skim_honoka, skim_honokaFactory("skim_honoka"))

skim_honoka::skim_honoka(QWidget *parent, const char *name, const QStringList&)
    : KCModule(parent, name), myAboutData(0)
{
    KGlobal::locale()->insertCatalogue("skim_honoka");
//    scim::String mod = scim::scim_global_config_read(scim::String("/DefaultConfigModule"),scim::String("simple"));
//    config.configModule.load(mod);
//    config.config = config.configModule.create_config();
    
    QGridLayout *grid = new QGridLayout(this,0,0,4);
    HonokaSetupKde *setup = new HonokaSetup("setup","","");
    HonokaSetupPage *page;
    std::vector<scim::String> l;
    
    
    //
    // general setting 
    //
    
    page = new HonokaSetupPage(_("general setting"),"","");
    page->append(new HonokaSetupIntItem(
        _("_Auto candidates popup: "),
        HONOKA_CONFIG_ALP,
        _("set the count of conversion until displaying the list of lookup result automatically."),
        HONOKA_DEFAULT_ALP,
        -1,10
    ));
    page->append(new HonokaSetupBoolItem(
        _("Auto _conversion: "),
        HONOKA_CONFIG_AUTO_CONVERSION,
        _("If you set default to the auto conversion mode use, check this."),
        HONOKA_DEFAULT_AUTO_CONVERSION
    ));
    page->append(new HonokaSetupBoolItem(
        _("_NumKey selection: "),
        HONOKA_CONFIG_NUMKEY_SELECT,
        _("If you use the candidate selection by numkey, check this."),
        HONOKA_DEFAULT_NUMKEY_SELECT
    ));
    page->append(new HonokaSetupBoolItem(
        _("use _Prediction: "),
        HONOKA_CONFIG_PREDICTION,
        _("If you use the prediction, check this."),
        HONOKA_DEFAULT_PREDICTION
    ));
    page->append(new HonokaSetupBoolItem(
        _("_Realtime Prediction: "),
        HONOKA_CONFIG_REALTIME_PREDICTION,
        _("If you use the realtime prediction, check this."),
        HONOKA_DEFAULT_REALTIME_PREDICTION
    ));
    page->append(new HonokaSetupIntItem(
        _("_Delay Prediction search: "),
        HONOKA_CONFIG_PREDICTION_DELAY,
        _("set the time to delay prediction search. (1/10secs)"),
        HONOKA_DEFAULT_PREDICTION_DELAY,
        0,10
    ));
    page->append(new HonokaSetupBoolItem(
        _("_Select prediction direct: "),
        HONOKA_CONFIG_SELECT_PREDICTION_DIRECT,
        _("If you want select prediction direct with numkey, check this."),
        HONOKA_DEFAULT_SELECT_PREDICTION_DIRECT
    ));
    page->append(new HonokaSetupBoolItem(
        _("Restore previous setting: "),
        HONOKA_CONFIG_SAVE_SETTING,
        _("if you restore previous setting at the startup time ,check this."),
        HONOKA_DEFAULT_SAVE_SETTING
    ));
    page->append(new HonokaSetupEntryItem(
        _("Default _PreEditor: "),
        HONOKA_CONFIG_DEFAULT_PREEDITOR,
        _("select the default preeditor."),
        HONOKA_DEFAULT_DEFAULT_PREEDITOR
    ));
    page->append(new HonokaSetupEntryItem(
        _("Default _Convertor: "),
        HONOKA_CONFIG_DEFAULT_CONVERTOR,
        _("select the default Convertor."),
        HONOKA_DEFAULT_DEFAULT_CONVERTOR
    ));
    page->append(new HonokaSetupEntryItem(
        _("Default _Predictor: "),
        HONOKA_CONFIG_DEFAULT_PREDICTOR,
        _("select the default predictor."),
        HONOKA_DEFAULT_DEFAULT_PREDICTOR
    ));
    
    setup->append(page);
    
    
    //
    // key setting
    //
    
    HonokaSetup * keys = new HonokaSetup(_("key setting"),"","");

    page = new HonokaSetupPage(_("Common keys"),"","");
    page->append(new HonokaSetupKeyItem(
        _("Commit keys:"),
        HONOKA_CONFIG_KEY_COMMIT,
        _("The key events to commit the preedit string. "),
        HONOKA_DEFAULT_KEY_COMMIT
    ));
    page->append(new HonokaSetupKeyItem(
        _("Convert keys:"),
        HONOKA_CONFIG_KEY_CONVERSION_START,
        _("The key events to convert the preedit string to kanji. "),
        HONOKA_DEFAULT_KEY_CONVERSION_START
    ));
    page->append(new HonokaSetupKeyItem(
        _("Cancel keys:"),
        HONOKA_CONFIG_KEY_CANCEL,
        _("The key events to cancel preediting or converting. "),
        HONOKA_DEFAULT_KEY_CANCEL
    ));
    page->append(new HonokaSetupKeyItem(
        _("Backspace keys:"),
        HONOKA_CONFIG_KEY_BACKSPACE,
        _("The key events to delete a character before caret. "),
        HONOKA_DEFAULT_KEY_BACKSPACE
    ));
    page->append(new HonokaSetupKeyItem(
        _("Delete keys:"),
        HONOKA_CONFIG_KEY_DELETE,
        _("The key events to delete a character after caret. "),
        HONOKA_DEFAULT_KEY_DELETE
    ));
    keys->append(page);

    page = new HonokaSetupPage(_("Preedit keys"),"","");
    page->append(new HonokaSetupKeyItem(
        _("Move forward keys:"),
        HONOKA_CONFIG_KEY_FORWARD,
        _("The key events to move the caret to forward. "),
        HONOKA_DEFAULT_KEY_FORWARD
    ));
    page->append(new HonokaSetupKeyItem(
        _("Move backward keys:"),
        HONOKA_CONFIG_KEY_BACKWARD,
        _("The key events to move the caret to backward. "),
        HONOKA_DEFAULT_KEY_BACKWARD
    ));
    keys->append(page);

    page = new HonokaSetupPage(_("Segment keys"),"","");
    page->append(new HonokaSetupKeyItem(
        _("Next segment keys:"),
        HONOKA_CONFIG_KEY_CONVERSION_FORWARD,
        _("The key events to select next segment. "),
        HONOKA_DEFAULT_KEY_CONVERSION_FORWARD
    ));
    page->append(new HonokaSetupKeyItem(
        _("Previous segment keys:"),
        HONOKA_CONFIG_KEY_CONVERSION_BACKWARD,
        _("The key events to select previous segment. "),
        HONOKA_DEFAULT_KEY_CONVERSION_BACKWARD
    ));
    page->append(new HonokaSetupKeyItem(
        _("Shrink segment keys:"),
        HONOKA_CONFIG_KEY_CONVERSION_SHRINK,
        _("The key events to shrink the selected segment. "),
        HONOKA_DEFAULT_KEY_CONVERSION_SHRINK
    ));
    page->append(new HonokaSetupKeyItem(
        _("Expand segment keys:"),
        HONOKA_CONFIG_KEY_CONVERSION_EXPAND,
        _("The key events to expand the selected segment. "),
        HONOKA_DEFAULT_KEY_CONVERSION_EXPAND
    ));
    keys->append(page);

    page = new HonokaSetupPage(_("Candidates keys"),"","");
    page->append(new HonokaSetupKeyItem(
        _("Next keys:"),
        HONOKA_CONFIG_KEY_CONVERSION_NEXT,
        _("The key events to select next candidate. "),
        HONOKA_DEFAULT_KEY_CONVERSION_NEXT
    ));
    page->append(new HonokaSetupKeyItem(
        _("Previous keys:"),
        HONOKA_CONFIG_KEY_CONVERSION_PREV,
        _("The key events to select previous candidate. "),
        HONOKA_DEFAULT_KEY_CONVERSION_PREV
    ));
    page->append(new HonokaSetupKeyItem(
        _("candidates list keys:"),
        HONOKA_CONFIG_KEY_LOOKUPPOPUP,
        _("The key events to popup candidates list. "),
        HONOKA_DEFAULT_KEY_LOOKUPPOPUP
    ));
    page->append(new HonokaSetupKeyItem(
        _("Page up keys:"),
        HONOKA_CONFIG_KEY_LOOKUPPAGEUP,
        _("The key events to select page up candidates. "),
        HONOKA_DEFAULT_KEY_LOOKUPPAGEUP
    ));
    page->append(new HonokaSetupKeyItem(
        _("Page down keys:"),
        HONOKA_CONFIG_KEY_LOOKUPPAGEDOWN,
        _("The key events to select page down candidates. "),
        HONOKA_DEFAULT_KEY_LOOKUPPAGEDOWN
    ));
    keys->append(page);

    page = new HonokaSetupPage(_("Other function keys"),"","");
    page->append(new HonokaSetupKeyItem(
        _("auto conversion mode keys:"),
        HONOKA_CONFIG_KEY_AUTO_CONVERSION,
        _("The key events to change auto conversion mode. "),
        HONOKA_DEFAULT_KEY_AUTO_CONVERSION
    ));
    page->append(new HonokaSetupKeyItem(
        _("Prediction keys:"),
        HONOKA_CONFIG_KEY_SELECT_PREDICTION,
        _("The key events to select from prediction list. "),
        HONOKA_DEFAULT_KEY_SELECT_PREDICTION
    ));
    page->append(new HonokaSetupKeyItem(
        _("Convert to HIRAGANA keys:"),
        HONOKA_CONFIG_KEY_CONVERT_HIRAGANA,
        _("The key events to convert the selected candidate or the preedit string to HIRAGANA. "),
        HONOKA_DEFAULT_KEY_CONVERT_HIRAGANA
    ));
    page->append(new HonokaSetupKeyItem(
        _("Convert to KATAKANA keys:"),
        HONOKA_CONFIG_KEY_CONVERT_KATAKANA,
        _("The key events to convert the selected candidate or the preedit string to KATAKANA. "),
        HONOKA_DEFAULT_KEY_CONVERT_KATAKANA
    ));
    page->append(new HonokaSetupKeyItem(
        _("Convert to WIDE keys:"),
        HONOKA_CONFIG_KEY_CONVERT_WIDE,
        _("The key events to convert the selected candidate or the preedit string to WIDE-charactors. "),
        HONOKA_DEFAULT_KEY_CONVERT_WIDE
    ));
    page->append(new HonokaSetupKeyItem(
        _("Convert to HALF keys:"),
        HONOKA_CONFIG_KEY_CONVERT_HALF,
        _("The key events to convert the selected candidate or the preedit string to HALF-charactors. "),
        HONOKA_DEFAULT_KEY_CONVERT_HALF
    ));
    page->append(new HonokaSetupKeyItem(
        _("Convert to ikeiji keys:"),
        HONOKA_CONFIG_KEY_CONVERSION_IKEIJI,
        _("The key events to convert the selected candidate to ikei-kanji. "),
        HONOKA_DEFAULT_KEY_CONVERSION_IKEIJI
    ));
    page->append(new HonokaSetupKeyItem(
        _("Convert to rensou keys:"),
        HONOKA_CONFIG_KEY_CONVERSION_RENSOU,
        _("The key events to convert the selected candidate to the associated acceptation string.  "),
        HONOKA_DEFAULT_KEY_CONVERSION_RENSOU
    ));
    keys->append(page);
    
    setup->append(keys);
    
    //
    // plugins setting
    //
    
    HonokaSetup * plugins = new HonokaSetup(_("plugins setting"),"","");

    ////
    DIR *dir = opendir(HONOKA_PLUGINDIR);
    if (dir) {
        struct dirent *entry;
        while((entry = readdir(dir)) != NULL) {
            String d = entry->d_name;
            if ((d.substr(0,6) == "plugin") && (d.substr(d.length() - 3,3) == ".so")) {
                String pluginName = d.substr(0,d.length() - 3);
                d = String(HONOKA_PLUGINDIR) + "/" + d;
                void* plugin = dlopen(d.c_str(), RTLD_LAZY);
                if (!plugin) continue;
                pluginSetupFunc *pluginSetup = (pluginSetupFunc *)dlsym(plugin,"HonokaPluginSetup");
                getPluginVersionFunc *getPluginVersion = (getPluginVersionFunc *)dlsym(plugin,"getHonokaPluginVersion");
                if ((!pluginSetup) || (!getPluginVersion)) {
                    dlclose(plugin);
                    continue;
                }
                if (getPluginVersion() == HONOKA_PLUGIN_VERSION) {
                    HonokaSetupCorePage *p = pluginSetup();
                    // "if you use this plugin, check this." ----
                    HonokaSetupKdePage *page = new HonokaSetupKdePage(p->getLabel(),p->getName(),p->getTip());
                    page->append(new HonokaSetupBoolItem(
                        _("_Use this plugin: "),
                        String(HONOKA_CONFIG_PLUGINLOADER_PREFIX) + "/" + pluginName,
                        _("if you use this plugin, check this."),
                        true
                    ));
                    for(unsigned int i = 0;i < p->getChildren().size();i ++) {
                        page->append(HonokaSetup::HonokaSetupCoreToKde(p->getChildren()[i]));
                    }
                    plugins->append(page);
                    //plugin->append(p);
                }
                dlclose(plugin);
            }
        }
    }
    ////


    setup->append(plugins);
    
    setup->getValueWidget()->reparent(this,QPoint());
    setup->getValueWidget()->show();
    grid->addWidget(setup->getValueWidget(),0,0);
    setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
    
    //emit changed(true);
    connect(setup,SIGNAL(changed()),this,SLOT(configChanged()));
    _setup = setup;

    load();
    

};


skim_honoka::~skim_honoka()
{
}


void skim_honoka::load()
{
    scimConfigPrivate config;
    if (!config.configModule.valid()) {
        scim::String mod = scim::scim_global_config_read(scim::String("/DefaultConfigModule"),scim::String("simple"));
        config.configModule.load(mod);
    }
    config.config = config.configModule.create_config();
    

    _setup->readConfig(config.config);
}


void skim_honoka::defaults()
{
    // insert your default settings code here...
    emit changed(true);
}


void skim_honoka::save()
{
    scimConfigPrivate config;
    if (!config.configModule.valid()) {
        scim::String mod = scim::scim_global_config_read(scim::String("/DefaultConfigModule"),scim::String("simple"));
        config.configModule.load(mod);
    }
    config.config = config.configModule.create_config();
    _setup->saveConfig(config.config);
    emit changed(true);
}


int skim_honoka::buttons()
{
    return KCModule::Default|KCModule::Apply|KCModule::Help;
}


void skim_honoka::configChanged()
{
    // insert your saving code here...
    emit changed(true);
}


QString skim_honoka::quickHelp() const
{
    return i18n("Helpful information about the skim_honoka module.");
}


#include "skim_honoka.moc"