Newer
Older
scim-wnn / honoka / src / honokasetupgtk.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.             *
 ***************************************************************************/

#include "honokasetupgtk.h"

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

#include <scim.h>
#include <gtk/scimkeyselection.h>

#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

GtkTooltips * HonokaSetupGtkItem::tipWidget = 0;
bool HonokaSetupGtkItem::changed = false;

HonokaSetupGtkItem::HonokaSetupGtkItem(String _label,String _name,String _tip)
{
    label = _label;
    name = _name;
    tip = _tip;
    
    valueWidget = 0;
    labelWidget = 0;
    if (!tipWidget) tipWidget = gtk_tooltips_new();
}

HonokaSetupGtkItem::~HonokaSetupGtkItem()
{
};

GtkWidget *HonokaSetupGtkItem::getValueWidget()
{
    if (!valueWidget) {
        createValueWidget();
        createTipWidget();
    }
    return valueWidget;
}

GtkWidget *HonokaSetupGtkItem::getLabelWidget()
{
    if (!labelWidget) createLabelWidget();
    return labelWidget;
}

void HonokaSetupGtkItem::createLabelWidget()
{
    labelWidget = gtk_label_new_with_mnemonic(label.c_str());
    gtk_misc_set_alignment(GTK_MISC(labelWidget),1.0,0.5);
    gtk_misc_set_padding(GTK_MISC(labelWidget),4,0);
    gtk_widget_show(labelWidget);
}

void HonokaSetupGtkItem::createValueWidget()
{
    valueWidget = gtk_label_new_with_mnemonic(".");
    gtk_misc_set_alignment(GTK_MISC(valueWidget),1.0,0.5);
    gtk_misc_set_padding(GTK_MISC(valueWidget),4,0);
    gtk_widget_show(valueWidget);
}

void HonokaSetupGtkItem::createTipWidget()
{
    if (!valueWidget) createValueWidget();
    gtk_tooltips_set_tip(tipWidget,valueWidget,tip.c_str(),NULL);
}

void HonokaSetupGtkItem::readConfig(ConfigPointer cfg)
{
    return;
}

void HonokaSetupGtkItem::saveConfig(ConfigPointer cfg)
{
    return;
}


//
// EntryItem
//

HonokaSetupGtkEntryItem::HonokaSetupGtkEntryItem(String _label,String _name,String _tip,String _default)
: HonokaSetupGtkItem(_label,_name,_tip)
{
    stringData = _default;
}

HonokaSetupGtkEntryItem::~HonokaSetupGtkEntryItem()
{
}

void HonokaSetupGtkEntryItem::createValueWidget()
{
    valueWidget = gtk_entry_new();
    gtk_label_set_mnemonic_widget(GTK_LABEL(getLabelWidget()),valueWidget);
    g_signal_connect((gpointer)valueWidget,"changed",G_CALLBACK(onEditableChanged),this);
    gtk_widget_show(valueWidget);
}

void HonokaSetupGtkEntryItem::readConfig(ConfigPointer cfg)
{
    stringData = cfg->read(name,stringData);
    gtk_entry_set_text(GTK_ENTRY(getValueWidget()),stringData.c_str());
    return;
}

void HonokaSetupGtkEntryItem::saveConfig(ConfigPointer cfg)
{
    cfg->write(name,stringData);
    return;
}

void HonokaSetupGtkEntryItem::onEditableChanged(GtkEditable *widget,gpointer self)
{
    HonokaSetupGtkEntryItem *s = static_cast<HonokaSetupGtkEntryItem *>(self);
    String str = String(gtk_entry_get_text(GTK_ENTRY(widget)));
    if (s->stringData != str) {
        s->stringData = str;
        changed = true;
    }
}

//
// Container
//

HonokaSetupGtkContainer::HonokaSetupGtkContainer()
{
    items.clear();
}

HonokaSetupGtkContainer::~HonokaSetupGtkContainer()
{
}


HonokaSetupGtkItem * HonokaSetupGtkContainer::getLastItem() {
    if (!items.size()) return 0;
    return items[items.size() - 1];
}

void HonokaSetupGtkContainer::append(HonokaSetupGtkItem *item)
{
    items.push_back(item);
}

//
// KeyItem
//

HonokaSetupGtkKeyItem::HonokaSetupGtkKeyItem(String _label,String _name,String _tip,String _default)
: HonokaSetupGtkItem(_label,_name,_tip)
{
    stringData = _default;
}

HonokaSetupGtkKeyItem::~HonokaSetupGtkKeyItem()
{
}

void HonokaSetupGtkKeyItem::createValueWidget()
{
    valueWidget = gtk_hbox_new(false,5);
    entry = gtk_entry_new();
    gtk_entry_set_editable(GTK_ENTRY(entry),FALSE);
    button = gtk_button_new_with_label("...");
    gtk_box_pack_start(GTK_BOX(valueWidget),entry,true,true,0);
    gtk_box_pack_end(GTK_BOX(valueWidget),button,false,false,0);
    gtk_label_set_mnemonic_widget(GTK_LABEL(getLabelWidget()),entry);
    g_signal_connect((gpointer)entry,"changed",G_CALLBACK(onEditableChanged),this);
    g_signal_connect((gpointer)button,"clicked",G_CALLBACK(onSelectButtonClicked),this);
    gtk_widget_show(entry);
    gtk_widget_show(button);
    gtk_widget_show(valueWidget);
}

void HonokaSetupGtkKeyItem::createTipWidget()
{
    if (!valueWidget) createValueWidget();
    gtk_tooltips_set_tip(tipWidget,entry,tip.c_str(),NULL);
    gtk_tooltips_set_tip(tipWidget,button,tip.c_str(),NULL);
}

void HonokaSetupGtkKeyItem::readConfig(ConfigPointer cfg)
{
    stringData = cfg->read(name,stringData);
    gtk_entry_set_text(GTK_ENTRY(entry),stringData.c_str());
    return;
}

void HonokaSetupGtkKeyItem::saveConfig(ConfigPointer cfg)
{
    cfg->write(name,stringData);
    return;
}

void HonokaSetupGtkKeyItem::onEditableChanged(GtkEditable *widget,gpointer self)
{
    HonokaSetupGtkKeyItem *s = static_cast<HonokaSetupGtkKeyItem *>(self);
    String str = String(gtk_entry_get_text(GTK_ENTRY(widget)));
    if (s->stringData != str) {
        s->stringData = str;
        changed = true;
    }
}

void HonokaSetupGtkKeyItem::onSelectButtonClicked(GtkEditable *widget,gpointer self)
{
    HonokaSetupGtkKeyItem *s = static_cast<HonokaSetupGtkKeyItem *>(self);
    if (s) {
        GtkWidget *dialog = scim_key_selection_dialog_new(s->label.c_str());
        scim_key_selection_dialog_set_keys(SCIM_KEY_SELECTION_DIALOG(dialog),gtk_entry_get_text(GTK_ENTRY(s->entry)));
        gint result = gtk_dialog_run(GTK_DIALOG(dialog));
        if (result == GTK_RESPONSE_OK) {
            const gchar *keys = scim_key_selection_dialog_get_keys(SCIM_KEY_SELECTION_DIALOG(dialog));
            if (!keys) keys = "";
            if (strcmp(keys,gtk_entry_get_text(GTK_ENTRY(s->entry))) != 0)
                gtk_entry_set_text(GTK_ENTRY(s->entry),keys);
        }
        gtk_widget_destroy (dialog);
        changed = true;
    }
}

//
// file
// 
HonokaSetupGtkFileItem::HonokaSetupGtkFileItem(String _label,String _name,String _tip,String _default)
: HonokaSetupGtkItem(_label,_name,_tip)
{
    stringData = _default;
}

HonokaSetupGtkFileItem::~HonokaSetupGtkFileItem()
{
}

void HonokaSetupGtkFileItem::createValueWidget()
{
    valueWidget = gtk_hbox_new(false,5);
    entry = gtk_entry_new();
    button = gtk_button_new_with_label("...");
    gtk_box_pack_start(GTK_BOX(valueWidget),entry,true,true,0);
    gtk_box_pack_end(GTK_BOX(valueWidget),button,false,false,0);
    gtk_label_set_mnemonic_widget(GTK_LABEL(getLabelWidget()),entry);
    g_signal_connect((gpointer)entry,"changed",G_CALLBACK(onEditableChanged),this);
    g_signal_connect((gpointer)button,"clicked",G_CALLBACK(onSelectButtonClicked),this);
    gtk_widget_show(entry);
    gtk_widget_show(button);
    gtk_widget_show(valueWidget);
}

void HonokaSetupGtkFileItem::createTipWidget()
{
    if (!valueWidget) createValueWidget();
    gtk_tooltips_set_tip(tipWidget,entry,tip.c_str(),NULL);
    gtk_tooltips_set_tip(tipWidget,button,tip.c_str(),NULL);
}

void HonokaSetupGtkFileItem::readConfig(ConfigPointer cfg)
{
    stringData = cfg->read(name,stringData);
    gtk_entry_set_text(GTK_ENTRY(entry),stringData.c_str());
    return;
}

void HonokaSetupGtkFileItem::saveConfig(ConfigPointer cfg)
{
    cfg->write(name,stringData);
    return;
}

void HonokaSetupGtkFileItem::onOkButtonClicked(GtkButton *widget,gpointer ok)
{
    bool *_ok = static_cast<bool*>(ok);
    if (_ok) *_ok = true;
}

void HonokaSetupGtkFileItem::onEditableChanged(GtkEditable *widget,gpointer self)
{
    HonokaSetupGtkFileItem *s = static_cast<HonokaSetupGtkFileItem *>(self);
    String str = String(gtk_entry_get_text(GTK_ENTRY(widget)));
    if (s->stringData != str) {
        s->stringData = str;
        changed = true;
    }
}

void HonokaSetupGtkFileItem::onSelectButtonClicked(GtkEditable *widget,gpointer self)
{
    HonokaSetupGtkFileItem *s = static_cast<HonokaSetupGtkFileItem *>(self);
    bool ok = false;
    const char *path = gtk_entry_get_text(GTK_ENTRY(s->entry));
    if (s) {
        GtkFileSelection *dialog = GTK_FILE_SELECTION(gtk_file_selection_new("Select a file"));
        gtk_file_selection_set_filename(dialog,path);
        g_signal_connect (G_OBJECT(dialog->ok_button),"clicked",G_CALLBACK(onOkButtonClicked),(gpointer)&ok);
        gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(s->entry))));
        gtk_dialog_run(GTK_DIALOG (dialog));
        if (ok) {
            gtk_entry_set_text(GTK_ENTRY(s->entry),gtk_file_selection_get_filename(dialog));
            changed = true;
        }
        gtk_widget_destroy (GTK_WIDGET (dialog));
    }
}


//
// bool
//

HonokaSetupGtkBoolItem::HonokaSetupGtkBoolItem(String _label,String _name,String _tip,bool _default)
: HonokaSetupGtkItem(_label,_name,_tip)
{
    boolData = _default;
}

HonokaSetupGtkBoolItem::~HonokaSetupGtkBoolItem()
{
}

void HonokaSetupGtkBoolItem::createValueWidget()
{
    valueWidget = gtk_check_button_new();
    gtk_label_set_mnemonic_widget(GTK_LABEL(getLabelWidget()),valueWidget);
    g_signal_connect((gpointer)valueWidget,"toggled",G_CALLBACK(onToggleButtonToggled),this);
    gtk_widget_show(valueWidget);
}

void HonokaSetupGtkBoolItem::readConfig(ConfigPointer cfg)
{
    boolData = cfg->read(name,boolData);
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(getValueWidget()),boolData);
    return;
}

void HonokaSetupGtkBoolItem::saveConfig(ConfigPointer cfg)
{
    cfg->write(name,boolData);
    return;
}

void HonokaSetupGtkBoolItem::onToggleButtonToggled(GtkEditable *widget,gpointer self)
{
    HonokaSetupGtkBoolItem *s = static_cast<HonokaSetupGtkBoolItem *>(self);
    if (s) {
        s->boolData = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(s->valueWidget));
        changed = true;
    }
}

//
// Int
//

HonokaSetupGtkIntItem::HonokaSetupGtkIntItem(String _label,String _name,String _tip,int _default,int lower,int upper)
: HonokaSetupGtkItem(_label,_name,_tip)
{
    intData = _default;
    aj = (GtkAdjustment *) gtk_adjustment_new(_default,lower,upper,1,1,1);
}

HonokaSetupGtkIntItem::~HonokaSetupGtkIntItem()
{
}

void HonokaSetupGtkIntItem::createValueWidget()
{
    valueWidget = gtk_spin_button_new(aj,1,0);
    gtk_label_set_mnemonic_widget(GTK_LABEL(getLabelWidget()),valueWidget);
    g_signal_connect((gpointer)valueWidget,"changed",G_CALLBACK(onValueChanged),this);
    gtk_widget_show(valueWidget);
}

void HonokaSetupGtkIntItem::readConfig(ConfigPointer cfg)
{
    intData = cfg->read(name,intData);
    gtk_spin_button_set_value(GTK_SPIN_BUTTON(getValueWidget()),intData);
    return;
}

void HonokaSetupGtkIntItem::saveConfig(ConfigPointer cfg)
{
    cfg->write(name,intData);
    return;
}

void HonokaSetupGtkIntItem::onValueChanged(GtkSpinButton *widget,gpointer self)
{
    HonokaSetupGtkIntItem *s = static_cast<HonokaSetupGtkIntItem *>(self);
    if (s) {
        s->intData = gtk_spin_button_get_value_as_int(widget);
        changed = true;
    }
}


//
// Select
//

HonokaSetupGtkSelectItem::HonokaSetupGtkSelectItem(String _label,String _name,String _tip,String _default,vector<String> _list)
: HonokaSetupGtkItem(_label,_name,_tip)
{
    stringData = _default;
    stringListData = _list;
}


HonokaSetupGtkSelectItem::~HonokaSetupGtkSelectItem()
{
}

void HonokaSetupGtkSelectItem::createValueWidget()
{
    valueWidget = gtk_option_menu_new();
    menu = gtk_menu_new();
    gtk_option_menu_set_menu(GTK_OPTION_MENU(valueWidget),menu);
    for(unsigned int i = 0;i < stringListData.size();i ++) {
        GtkWidget *menuitem = gtk_menu_item_new_with_label(stringListData[i].c_str());
        gtk_menu_shell_append(GTK_MENU_SHELL(menu),menuitem);
        gtk_widget_show(menuitem);
    }
    gtk_label_set_mnemonic_widget(GTK_LABEL(getLabelWidget()),valueWidget);
    gtk_option_menu_set_history(GTK_OPTION_MENU(valueWidget),0);
    g_signal_connect((gpointer)valueWidget,"changed",G_CALLBACK(onSelected),this);
    gtk_widget_show(valueWidget);
    gtk_widget_show(menu);
}

void HonokaSetupGtkSelectItem::readConfig(ConfigPointer cfg)
{
    stringData = cfg->read(name,stringData);
    for(unsigned int i = 0;i < stringListData.size();i ++) {
        if (stringData == stringListData[i]) {
            gtk_option_menu_set_history(GTK_OPTION_MENU(valueWidget),i);
            break;
        }
    }
    return;
}

void HonokaSetupGtkSelectItem::saveConfig(ConfigPointer cfg)
{
    cfg->write(name,stringData);
    return;
}

void HonokaSetupGtkSelectItem::onSelected(GtkOptionMenu *widget,gpointer self)
{
    HonokaSetupGtkSelectItem *s = static_cast<HonokaSetupGtkSelectItem *>(self);
    if (s) {
        String c = s->stringListData[gtk_option_menu_get_history(widget)];
        if (s->stringData != c) {
            s->stringData = c;
            changed = true;
        }
    }
}



//
// Page
//

HonokaSetupGtkPage::HonokaSetupGtkPage(String _label,String _name,String _tip)
: HonokaSetupGtkItem(_label,_name,_tip),HonokaSetupGtkContainer()
{
    valueWidget = gtk_vbox_new(FALSE, 0);
    gtk_widget_show(valueWidget);

    table = gtk_table_new(3,1,FALSE);
    gtk_box_pack_start(GTK_BOX(valueWidget),table,FALSE,FALSE,0);
    gtk_widget_show(table);
}

void HonokaSetupGtkPage::append(HonokaSetupGtkItem *item)
{
    items.push_back(item);
    gtk_misc_set_alignment(GTK_MISC(item->getLabelWidget()),1.0,0.5);
    gtk_misc_set_padding(GTK_MISC(item->getLabelWidget()),4,0);
    if (dynamic_cast<HonokaSetupGtk *>(item) != 0) {
        gtk_table_attach(GTK_TABLE(table),item->getValueWidget(),0,2,items.size() - 1,items.size(),
            (GtkAttachOptions)(GTK_FILL|GTK_EXPAND),(GtkAttachOptions)(GTK_FILL),4,4);
    } else {
        gtk_table_attach(GTK_TABLE(table),item->getLabelWidget(),0,1,items.size() - 1,items.size(),
            (GtkAttachOptions)(GTK_FILL),(GtkAttachOptions)(GTK_FILL),4,4);
        gtk_table_attach(GTK_TABLE(table),item->getValueWidget(),1,2,items.size() - 1,items.size(),
            (GtkAttachOptions)(GTK_FILL|GTK_EXPAND),(GtkAttachOptions)(GTK_FILL),4,4);
    }
}

void HonokaSetupGtkPage::readConfig(ConfigPointer cfg)
{
    for(unsigned int i = 0;i < items.size();i ++) {
        items[i]->readConfig(cfg);
    }
    return;
}

void HonokaSetupGtkPage::saveConfig(ConfigPointer cfg)
{
    for(unsigned int i = 0;i < items.size();i ++) {
        items[i]->saveConfig(cfg);
    }
    return;
}


//


HonokaSetupGtk::HonokaSetupGtk(String _label,String _name,String _tip)
: HonokaSetupGtkItem(_label,_name,_tip),HonokaSetupGtkContainer()
{
    valueWidget = gtk_notebook_new();
    gtk_widget_show(valueWidget);
    gtk_notebook_set_scrollable(GTK_NOTEBOOK(valueWidget),TRUE);

}


HonokaSetupGtk::~HonokaSetupGtk()
{
}

void HonokaSetupGtk::append(HonokaSetupGtkItem *page)
{
    items.push_back(page);

    gtk_widget_show(page->getLabelWidget());
    gtk_notebook_append_page(GTK_NOTEBOOK(valueWidget),page->getValueWidget(),page->getLabelWidget());
    if (dynamic_cast<HonokaSetupGtk *>(page) != 0) gtk_notebook_set_tab_pos(GTK_NOTEBOOK(page->getValueWidget()),GTK_POS_LEFT);
}

void HonokaSetupGtk::readConfig(ConfigPointer cfg)
{
    for(unsigned int i = 0;i < items.size();i ++) {
        items[i]->readConfig(cfg);
    }
    return;
}

void HonokaSetupGtk::saveConfig(ConfigPointer cfg)
{
    for(unsigned int i = 0;i < items.size();i ++) {
        items[i]->saveConfig(cfg);
    }
    return;
}

HonokaSetupGtkItem *HonokaSetupGtk::HonokaSetupCoreToGtk(Honoka::HonokaSetupCoreItem *item)
{
    if (item->getType() == HONOKA_SETUP_ITEM_ENTRY) {
        return new HonokaSetupGtkEntryItem(item->getLabel(),item->getName(),item->getTip(),item->getStringData());
    }
    if (item->getType() == HONOKA_SETUP_ITEM_KEY) {
        return new HonokaSetupGtkKeyItem(item->getLabel(),item->getName(),item->getTip(),item->getStringData());
    }
    if (item->getType() == HONOKA_SETUP_ITEM_FILE) {
        return new HonokaSetupGtkFileItem(item->getLabel(),item->getName(),item->getTip(),item->getStringData());
    }
    if (item->getType() == HONOKA_SETUP_ITEM_BOOL) {
        return new HonokaSetupGtkBoolItem(item->getLabel(),item->getName(),item->getTip(),item->getBoolData());
    }
    if (item->getType() == HONOKA_SETUP_ITEM_INT) {
        return new HonokaSetupGtkIntItem(item->getLabel(),item->getName(),item->getTip(),item->getIntData(),
            item->getIntLower(),item->getIntUpper());
    }
    if (item->getType() == HONOKA_SETUP_ITEM_SELECT) {
        return new HonokaSetupGtkSelectItem(item->getLabel(),item->getName(),item->getTip(),item->getStringData(),
            item->getStringListData());
    }
    if (item->getType() == HONOKA_SETUP_ITEM_PAGE) {
        HonokaSetupGtkPage *page = new HonokaSetupGtkPage(item->getLabel(),item->getName(),item->getTip());
        for(unsigned int i = 0;i < static_cast<Honoka::HonokaSetupCorePage *>(item)->getChildren().size(); i ++) {
            page->append(HonokaSetupCoreToGtk(static_cast<Honoka::HonokaSetupCorePage *>(item)->getChildren()[i]));
        }
        return page;
    }
    if (item->getType() == HONOKA_SETUP_ITEM_SETUP) {
        HonokaSetupGtk *page = new HonokaSetupGtk(item->getLabel(),item->getName(),item->getTip());
        for(unsigned int i = 0;i < static_cast<Honoka::HonokaSetupCore *>(item)->getChildren().size(); i ++) {
            page->append(HonokaSetupCoreToGtk(static_cast<Honoka::HonokaSetupCore *>(item)->getChildren()[i]));
        }
        return page;
    }
    return 0;
}