Imported version 0.4-3
[mstardict] / src / mstardict.cpp
index 5e4e9e2..1b9e0a6 100644 (file)
@@ -47,8 +47,9 @@
 #include <list>
 
 #include "conf.hpp"
+#include "dictmngr.hpp"
 #include "libwrapper.hpp"
-#include "file.hpp"
+#include "transwin.hpp"
 #include "mstardict.hpp"
 
 MStarDict *pMStarDict;
@@ -58,25 +59,9 @@ enum {
     N_COLUMNS
 };
 
-enum {
-    BOOKNAME_DICT_INFO_COLUMN,
-    FILENAME_DICT_INFO_COLUMN,
-    N_DICT_INFO_COLUMNS
-};
-
-class GetAllDictList {
-  public:
-    GetAllDictList(std::list < std::string > &dict_all_list_):dict_all_list(dict_all_list_) {
-    } void operator() (const std::string & url, bool disable) {
-       dict_all_list.push_back(url);
-    }
-  private:
-    std::list < std::string > &dict_all_list;
-};
-
 MStarDict::MStarDict()
 {
-    main_window = NULL;
+    window = NULL;
     label_widget = NULL;
     results_widget = NULL;
     results_view = NULL;
@@ -87,10 +72,23 @@ MStarDict::MStarDict()
                                      G_TYPE_STRING);   /* DEF_COLUMN */
 
     /* initialize configuration */
-    oConf = new MStarDictConf();
+    oConf = new Conf();
+
+    /* initialize stardict plugins */
+    std::list < std::string > plugin_order_list;
+    std::list < std::string > plugin_disable_list;
+    oStarDictPlugins = new StarDictPlugins("/usr/lib/mstardict/plugins",
+                                          plugin_order_list,
+                                          plugin_disable_list);
+
+    /* initialize dict manager */
+    oDict = new DictMngr(this);
+
+    /* initialize translation window */
+    oTransWin = new TransWin(this);
 
     /* initialize stardict library */
-    oLibs = new Library();
+    oLibs = new Library(this);
 }
 
 MStarDict::~MStarDict()
@@ -101,6 +99,15 @@ MStarDict::~MStarDict()
     /* deinitialize stardict library */
     delete oLibs;
 
+    /* deinitialize translation window */
+    delete oTransWin;
+
+    /* deinitialize dict manager */
+    delete oDict;
+
+    /* deinitialize stardict plugins */
+    delete oStarDictPlugins;
+
     /* deinitialize configuration */
     delete oConf;
 }
@@ -111,46 +118,33 @@ MStarDict::onResultsViewSelectionChanged(GtkTreeSelection *selection,
 {
     GtkTreeModel *model;
     GtkTreeIter iter;
-    char *bookname, *def, *exp;
     const gchar *sWord;
     bool bFound = false;
 
     if (gtk_tree_selection_get_selected(selection, &model, &iter)) {
+       GList *results = NULL;
+
        /* unselect selected rows */
        gtk_tree_selection_unselect_all(selection);
 
        gtk_tree_model_get(model, &iter, DEF_COLUMN, &sWord, -1);
 
-       /* clear previous search results */
-       mStarDict->results.clear();
-
        for (size_t iLib = 0; iLib < mStarDict->oLibs->query_dictmask.size(); iLib++) {
            bFound =
                mStarDict->oLibs->BuildResultData(mStarDict->oLibs->query_dictmask, sWord,
                                                  mStarDict->oLibs->iCurrentIndex, iLib,
-                                                 mStarDict->results);
+                                                 &results);
        }
 
-       bookname =
-           g_markup_printf_escaped
-           ("<span color=\"dimgray\" size=\"x-small\">%s</span>",
-            mStarDict->results[0].bookname.c_str());
-       def =
-           g_markup_printf_escaped
-           ("<span color=\"darkred\" weight=\"heavy\" size=\"large\">%s</span>",
-            mStarDict->results[0].def.c_str());
-       exp = g_strdup(mStarDict->results[0].exp.c_str());
-
        /* create translation window */
-       mStarDict->CreateTranslationWindow(bookname, def, exp);
+       mStarDict->oTransWin->CreateTransWindow(results);
 
-       g_free(bookname);
-       g_free(def);
-       g_free(exp);
+       /* free result data */
+       mStarDict->oLibs->FreeResultData(results);
     }
 
     /* grab focus to search entry */
-    gtk_widget_grab_focus(GTK_WIDGET(mStarDict->search));
+    mStarDict->GrabFocus();
 
     return true;
 }
@@ -159,39 +153,33 @@ gboolean
 MStarDict::onSearchEntryChanged(GtkEditable* editable,
                                MStarDict* mStarDict)
 {
-    GtkTreeSelection *selection;
     const gchar *sWord;
     bool bFound = false;
     std::string query;
 
-    sWord = gtk_entry_get_text(GTK_ENTRY(editable));
-
     if (mStarDict->oLibs->query_dictmask.empty())
        return true;
 
+    sWord = gtk_entry_get_text(GTK_ENTRY(editable));
     if (strcmp(sWord, "") == 0) {
        mStarDict->ShowNoResults(true);
     } else {
-       selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(mStarDict->results_view));
-       gtk_tree_selection_set_mode(selection, GTK_SELECTION_NONE);
-
-       /* unselect rows */
-       selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(mStarDict->results_view));
-       gtk_tree_selection_unselect_all(selection);
-
-       /* show progress indicator */
-//     mStarDict->ShowProgressIndicator(true);
+       mStarDict->ShowProgressIndicator(true);
+       mStarDict->ResultsUnselectAll(GTK_SELECTION_NONE);
 
        switch (analyse_query(sWord, query)) {
        case qtFUZZY:
            bFound = mStarDict->oLibs->LookupWithFuzzy(query.c_str());
            break;
+
        case qtPATTERN:
            bFound = mStarDict->oLibs->LookupWithRule(query.c_str());
            break;
+
        case qtREGEX:
            bFound = mStarDict->oLibs->LookupWithRegex(query.c_str());
            break;
+
        case qtSIMPLE:
            bFound = mStarDict->oLibs->SimpleLookup(query.c_str(), mStarDict->oLibs->iCurrentIndex);
            if (!bFound) {
@@ -209,140 +197,41 @@ MStarDict::onSearchEntryChanged(GtkEditable* editable,
            }
            mStarDict->oLibs->ListWords(mStarDict->oLibs->iCurrentIndex);
            break;
-       case qtDATA:
-           bFound = mStarDict->oLibs->LookupData(query.c_str());
-           break;
+
        default:
-           /* nothing */ ;
+           break;
        }
 
-       /* unselect selected rows */
-       gtk_tree_selection_unselect_all(selection);
-       gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
-
-       /* hide progress indicator */
-//     mStarDict->ShowProgressIndicator(false);
-
        if (bFound)
            mStarDict->ShowNoResults(false);
        else
            mStarDict->ShowNoResults(true);
+
+       mStarDict->ResultsUnselectAll(GTK_SELECTION_SINGLE);
+       mStarDict->ShowProgressIndicator(false);
     }
 
     return true;
 }
 
 gboolean
+MStarDict::onSearchClearClicked(GtkButton* button,
+                               MStarDict* mStarDict)
+{
+    gtk_entry_set_text(GTK_ENTRY(mStarDict->search_entry), "");
+    mStarDict->GrabFocus();
+    return true;
+}
+
+gboolean
 MStarDict::onDictionariesMenuItemClicked(GtkButton *button,
                                         MStarDict *mStarDict)
 {
-    GtkWidget *dialog, *selector;
-    GtkCellRenderer *renderer;
-    HildonTouchSelectorColumn *column;
-    GtkTreeModel *tree_model;
-    GtkTreeIter iter;
-    gboolean iter_valid = TRUE;
-    std::list < std::string > all_dict_list;
-    std::list < std::string > selected_dict_list;
-    GtkListStore *dict_list = NULL;
-
-    dict_list = gtk_list_store_new(N_DICT_INFO_COLUMNS,
-                                  G_TYPE_STRING,       /* bookname */
-                                  G_TYPE_STRING);      /* filename */
-
-    /* create dialog */
-    dialog = gtk_dialog_new();
-    gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
-    gtk_window_set_title(GTK_WINDOW(dialog), _("Dictionaries"));
-    gtk_dialog_add_button(GTK_DIALOG(dialog), "OK", GTK_RESPONSE_ACCEPT);
-    gtk_window_set_default_size(GTK_WINDOW(dialog), -1, 400);
-
-    /* dictionary selector */
-    selector = hildon_touch_selector_new();
-    gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), selector);
-
-    renderer = gtk_cell_renderer_text_new();
-    g_object_set(G_OBJECT(renderer), "xpad", 10, NULL);
-    column =
-       hildon_touch_selector_append_column(HILDON_TOUCH_SELECTOR
-                                           (selector),
-                                           GTK_TREE_MODEL(dict_list),
-                                           renderer, "text", BOOKNAME_DICT_INFO_COLUMN, NULL);
-    hildon_touch_selector_column_set_text_column(column, 0);
-
-    /* fill list with all available dictionaries */
-    mStarDict->GetAllDictionaryList(all_dict_list);
-    for (std::list < std::string >::iterator i = all_dict_list.begin();
-        i != all_dict_list.end(); ++i) {
-       DictInfo dictinfo;
-
-       dictinfo.load_from_ifo_file(i->c_str(), 0);
-       gtk_list_store_append(dict_list, &iter);
-       gtk_list_store_set(dict_list, &iter,
-                          BOOKNAME_DICT_INFO_COLUMN,
-                          dictinfo.bookname.c_str(), FILENAME_DICT_INFO_COLUMN, i->c_str(), -1);
-    }
-    g_object_unref(dict_list);
-
-    /* set selector mode to multiple */
-    hildon_touch_selector_set_column_selection_mode(HILDON_TOUCH_SELECTOR
-                                                   (selector),
-                                                   HILDON_TOUCH_SELECTOR_SELECTION_MODE_MULTIPLE);
-    hildon_touch_selector_unselect_all(HILDON_TOUCH_SELECTOR(selector), BOOKNAME_DICT_INFO_COLUMN);
-
-    /* select all load dictionaries */
-    tree_model =
-       hildon_touch_selector_get_model(HILDON_TOUCH_SELECTOR(selector), BOOKNAME_DICT_INFO_COLUMN);
-    for (iter_valid = gtk_tree_model_get_iter_first(tree_model, &iter);
-        iter_valid; iter_valid = gtk_tree_model_iter_next(tree_model, &iter)) {
-       const gchar *bookname;
-
-       gtk_tree_model_get(tree_model, &iter, BOOKNAME_DICT_INFO_COLUMN, &bookname, -1);
-       for (size_t iLib = 0; iLib < mStarDict->oLibs->query_dictmask.size(); iLib++) {
-           if (!strcmp(mStarDict->oLibs->dict_name(iLib).c_str(), bookname)) {
-               hildon_touch_selector_select_iter(HILDON_TOUCH_SELECTOR
-                                                 (selector),
-                                                 BOOKNAME_DICT_INFO_COLUMN, &iter, FALSE);
-               break;
-           }
-       }
-    }
-
-    /* show dialog */
-    gtk_widget_show_all(GTK_WIDGET(dialog));
-
-    /* run the dialog */
-    if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
-       GList *selected_dicts = NULL;
-
-       selected_dicts =
-           hildon_touch_selector_get_selected_rows(HILDON_TOUCH_SELECTOR
-                                                   (selector), BOOKNAME_DICT_INFO_COLUMN);
-       if (selected_dicts) {
-           GList *dict = selected_dicts;
-           const gchar *filename;
-
-           while (dict) {
-               gtk_tree_model_get_iter(GTK_TREE_MODEL(tree_model), &iter,
-                                       (GtkTreePath *) (dict->data));
-               gtk_tree_model_get(GTK_TREE_MODEL(tree_model), &iter,
-                                  FILENAME_DICT_INFO_COLUMN, &filename, -1);
-               selected_dict_list.push_back(std::string(filename));
-               dict = dict->next;
-           }
-           g_list_foreach(selected_dicts, (GFunc) gtk_tree_path_free, NULL);
-           g_list_free(selected_dicts);
-       }
+    mStarDict->oDict->CreateDictMngrDialog();
 
-       if (mStarDict->oConf->SetStringList("/apps/maemo/mstardict/dict_list", selected_dict_list)) {
-           /* reload dictionaries */
-           mStarDict->ReLoadDictionaries(selected_dict_list);
-
-           /* trigger re-search */
-           mStarDict->onSearchEntryChanged(GTK_EDITABLE(mStarDict->search), mStarDict);
-       }
-    }
-    gtk_widget_destroy(GTK_WIDGET(dialog));
+    /* trigger re-search */
+    mStarDict->onSearchEntryChanged(GTK_EDITABLE(mStarDict->search_entry), mStarDict);
+    mStarDict->GrabFocus();
     return true;
 }
 
@@ -354,119 +243,66 @@ MStarDict::onQuitMenuItemClicked(GtkButton *button,
     return true;
 }
 
-void
-MStarDict::GetAllDictionaryList(std::list < std::string > &dict_list)
-{
-    strlist_t dicts_dir_list;
-    strlist_t order_list;
-    strlist_t disable_list;
-
-    /* dictionary directory */
-    dicts_dir_list.push_back(std::string("/home/user/MyDocs/mstardict"));
-    for_each_file(dicts_dir_list, ".ifo", order_list, disable_list, GetAllDictList(dict_list));
-}
-
-void
-MStarDict::LoadDictionaries()
+gboolean
+MStarDict::onLookupProgressDialogResponse(GtkDialog *dialog,
+                                         gint response_id,
+                                         bool *cancel)
 {
-    std::list < std::string > dict_list;
-
-    if (!oConf->GetStringList("/apps/maemo/mstardict/dict_list", dict_list)) {
-       GetAllDictionaryList(dict_list);
-       oConf->SetStringList("/apps/maemo/mstardict/dict_list", dict_list);
-    }
-
-    oLibs->load(dict_list);
-    oLibs->query_dictmask.clear();
-    for (std::list < std::string >::iterator i = dict_list.begin(); i != dict_list.end(); ++i) {
-       size_t iLib;
-       if (oLibs->find_lib_by_filename(i->c_str(), iLib)) {
-           InstantDictIndex instance_dict_index;
-           instance_dict_index.type = InstantDictType_LOCAL;
-           instance_dict_index.index = iLib;
-           oLibs->query_dictmask.push_back(instance_dict_index);
-       }
-    }
-
-    if (oLibs->iCurrentIndex)
-       g_free(oLibs->iCurrentIndex);
-    oLibs->iCurrentIndex =
-       (CurrentIndex *) g_malloc(sizeof(CurrentIndex) * oLibs->query_dictmask.size());
-
-    if (oLibs->query_dictmask.empty())
-       ShowNoDictionary(true);
+    *cancel = true;
+    return true;
 }
 
-void
-MStarDict::ReLoadDictionaries(std::list < std::string > &dict_list)
+gboolean
+MStarDict::onMainWindowKeyPressEvent(GtkWidget *window,
+                                    GdkEventKey *event,
+                                    MStarDict *mStarDict)
 {
-    oLibs->reload(dict_list, 0, 0);
-    oLibs->query_dictmask.clear();
-    for (std::list < std::string >::iterator i = dict_list.begin(); i != dict_list.end(); ++i) {
-       size_t iLib;
-       if (oLibs->find_lib_by_filename(i->c_str(), iLib)) {
-           InstantDictIndex instance_dict_index;
-           instance_dict_index.type = InstantDictType_LOCAL;
-           instance_dict_index.index = iLib;
-           oLibs->query_dictmask.push_back(instance_dict_index);
-       }
+    if (event->type == GDK_KEY_PRESS && event->keyval == GDK_KP_Enter) {
+       mStarDict->SearchWord();
+    } else if (event->type == GDK_KEY_PRESS && event->keyval >= 0x21 && event->keyval <= 0x7E) {
+       mStarDict->GrabFocus();
     }
-
-    if (oLibs->iCurrentIndex)
-       g_free(oLibs->iCurrentIndex);
-    oLibs->iCurrentIndex =
-       (CurrentIndex *) g_malloc(sizeof(CurrentIndex) * oLibs->query_dictmask.size());
-
-    if (oLibs->query_dictmask.empty())
-       ShowNoDictionary(true);
+    return false;
 }
 
-void
-MStarDict::CreateTranslationWindow(const gchar *bookname,
-                                  const gchar *def,
-                                  const gchar *exp)
+GtkWidget *
+MStarDict::CreateLookupProgressDialog(bool *cancel)
 {
-    GtkWidget *window, *alignment, *pannable, *vbox, *label;
+    GtkWidget *dialog, *progress;
 
-    window = hildon_stackable_window_new();
-    gtk_window_set_title(GTK_WINDOW(window), _("Translation"));
-
-    alignment = gtk_alignment_new(0.0, 0.0, 1.0, 1.0);
-    gtk_alignment_set_padding(GTK_ALIGNMENT(alignment),
-                             HILDON_MARGIN_DEFAULT,
-                             HILDON_MARGIN_DEFAULT, HILDON_MARGIN_DOUBLE, HILDON_MARGIN_DEFAULT);
-    gtk_container_add(GTK_CONTAINER(window), alignment);
+    /* create dialog */
+    dialog = gtk_dialog_new();
+    gtk_window_set_title(GTK_WINDOW(dialog), _("Searching"));
+    gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(window));
+    gtk_dialog_add_button(GTK_DIALOG(dialog), _("Cancel"), GTK_RESPONSE_OK);
 
-    pannable = hildon_pannable_area_new();
-    g_object_set(G_OBJECT(pannable), "mov-mode", HILDON_MOVEMENT_MODE_BOTH, NULL);
-    gtk_container_add(GTK_CONTAINER(alignment), pannable);
+    g_signal_connect(dialog, "response", G_CALLBACK(onLookupProgressDialogResponse), cancel);
 
-    vbox = gtk_vbox_new(FALSE, 0);
-    hildon_pannable_area_add_with_viewport(HILDON_PANNABLE_AREA(pannable), vbox);
+    /* add progress bar */
+    progress = gtk_progress_bar_new();
+    gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), progress);
+    g_object_set_data(G_OBJECT(dialog), "progress_bar", progress);
 
-    label = gtk_label_new("Bookname");
-    gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
-    gtk_label_set_markup(GTK_LABEL(label), bookname);
-    gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
+    /* show dialog */
+    gtk_widget_show_all(dialog);
 
-    label = gtk_label_new("Definition");
-    gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
-    gtk_label_set_markup(GTK_LABEL(label), def);
-    gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
+    while (gtk_events_pending())
+       gtk_main_iteration();
 
-    label = gtk_label_new("Expresion");
-    gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.0);
-    gtk_label_set_markup(GTK_LABEL(label), exp);
-    gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
+    return dialog;
+}
 
-    gtk_widget_show_all(window);
+void
+MStarDict::DestroyLookupProgressDialog(GtkWidget *dialog)
+{
+    gtk_widget_destroy(GTK_WIDGET(dialog));
 }
 
 void
 MStarDict::CreateMainWindow()
 {
     HildonProgram *program = NULL;
-    GtkWidget *alignment, *vbox;
+    GtkWidget *alignment, *main_vbox, *search;
     GtkCellRenderer *renderer;
     GtkTreeSelection *selection;
 
@@ -475,31 +311,31 @@ MStarDict::CreateMainWindow()
     g_set_application_name(_("MStardict"));
 
     /* main window */
-    main_window = hildon_stackable_window_new();
-    hildon_program_add_window(program, HILDON_WINDOW(main_window));
+    window = hildon_stackable_window_new();
+    hildon_program_add_window(program, HILDON_WINDOW(window));
 
     /* aligment */
     alignment = gtk_alignment_new(0.5, 0.5, 1.0, 1.0);
     gtk_alignment_set_padding(GTK_ALIGNMENT(alignment),
                              HILDON_MARGIN_HALF, 0, HILDON_MARGIN_DEFAULT, HILDON_MARGIN_DEFAULT);
-    gtk_container_add(GTK_CONTAINER(main_window), alignment);
+    gtk_container_add(GTK_CONTAINER(window), alignment);
 
     /* main vbox */
-    vbox = gtk_vbox_new(FALSE, 0);
-    gtk_container_add(GTK_CONTAINER(alignment), vbox);
+    main_vbox = gtk_vbox_new(FALSE, 0);
+    gtk_container_add(GTK_CONTAINER(alignment), main_vbox);
 
     /* no_search_result label */
     label_widget = gtk_label_new(_("No search result"));
     hildon_helper_set_logical_color(label_widget, GTK_RC_FG,
                                    GTK_STATE_NORMAL, "SecondaryTextColor");
     hildon_helper_set_logical_font(label_widget, "LargeSystemFont");
-    gtk_box_pack_start(GTK_BOX(vbox), label_widget, TRUE, TRUE, 0);
+    gtk_box_pack_start(GTK_BOX(main_vbox), label_widget, TRUE, TRUE, 0);
 
     /* alignment for pannable area */
     results_widget = gtk_alignment_new(0.5, 0.5, 1.0, 1.0);
     gtk_alignment_set_padding(GTK_ALIGNMENT(results_widget),
                              0, 0, HILDON_MARGIN_DEFAULT, HILDON_MARGIN_DEFAULT);
-    gtk_box_pack_start(GTK_BOX(vbox), results_widget, TRUE, TRUE, 0);
+    gtk_box_pack_start(GTK_BOX(main_vbox), results_widget, TRUE, TRUE, 0);
 
     /* pannable for tree view */
     results_view_scroll = hildon_pannable_area_new();
@@ -518,23 +354,61 @@ MStarDict::CreateMainWindow()
     gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW
                                                (results_view), -1, "Def",
                                                renderer, "text", DEF_COLUMN, NULL);
-    g_object_set(G_OBJECT(renderer), "xpad", 10, NULL);
+    g_object_set(G_OBJECT(renderer),
+                "xpad", 10,
+                "ellipsize", PANGO_ELLIPSIZE_END,
+                "ellipsize-set", TRUE,
+                NULL);
 
-    /* search entry */
-    search = hildon_entry_new(HILDON_SIZE_FINGER_HEIGHT);
-    gtk_box_pack_end(GTK_BOX(vbox), search, FALSE, TRUE, 0);
-    g_signal_connect(search, "changed", G_CALLBACK(onSearchEntryChanged), this);
+    /* create search bar */
+    search = CreateSearchBar();
+    gtk_box_pack_end(GTK_BOX(main_vbox), search, FALSE, TRUE, 0);
 
     /* window signals */
-    g_signal_connect(G_OBJECT(main_window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
+    g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
+    g_signal_connect(G_OBJECT(window), "key_press_event", G_CALLBACK(onMainWindowKeyPressEvent), this);
 
     /* show all widget instead of alignment */
-    gtk_widget_show_all(GTK_WIDGET(main_window));
+    gtk_widget_show_all(GTK_WIDGET(window));
 
     /* grab focus to search entry */
-    gtk_widget_grab_focus(GTK_WIDGET(search));
+    GrabFocus();
 }
 
+GtkWidget *
+MStarDict::CreateSearchBar()
+{
+    GtkWidget *hbox, *entry, *button;
+    GtkEntryCompletion *completion;
+
+    /* search hbox */
+    hbox = gtk_hbox_new(FALSE, HILDON_MARGIN_DEFAULT);
+
+    /* search entry */
+    entry = hildon_entry_new(HILDON_SIZE_FINGER_HEIGHT);
+    hildon_gtk_entry_set_input_mode(GTK_ENTRY(entry), HILDON_GTK_INPUT_MODE_FULL);
+    gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0);
+
+    completion = gtk_entry_completion_new();
+    gtk_entry_completion_set_inline_completion(completion, TRUE);
+    gtk_entry_completion_set_popup_completion(completion, FALSE);
+    gtk_entry_set_completion(GTK_ENTRY(entry), completion);
+
+    /* clear button */
+    button = GTK_WIDGET(gtk_tool_button_new(gtk_image_new_from_icon_name("general_delete",
+                                                                        (GtkIconSize)HILDON_ICON_PIXEL_SIZE_FINGER),
+                                           "Clear"));
+    gtk_box_pack_end(GTK_BOX (hbox), button, FALSE, TRUE, 0);
+
+    /* search signals */
+    g_signal_connect(entry, "changed", G_CALLBACK(onSearchEntryChanged), this);
+    g_signal_connect(button, "clicked", G_CALLBACK(onSearchClearClicked), this);
+
+    search_entry = entry;
+    return hbox;
+}
+
+
 void
 MStarDict::CreateMainMenu()
 {
@@ -542,7 +416,7 @@ MStarDict::CreateMainMenu()
     GtkWidget *item;
 
     menu = HILDON_APP_MENU(hildon_app_menu_new());
-    hildon_window_set_app_menu(HILDON_WINDOW(main_window), menu);
+    hildon_window_set_app_menu(HILDON_WINDOW(window), menu);
 
     /* dictionaries menu item */
     item = hildon_gtk_button_new(HILDON_SIZE_AUTO);
@@ -561,6 +435,41 @@ MStarDict::CreateMainMenu()
 }
 
 void
+MStarDict::SearchWord()
+{
+    const gchar *sWord;
+    bool bFound = false;
+    std::string query;
+
+    if (oLibs->query_dictmask.empty())
+       return;
+
+    sWord = gtk_entry_get_text(GTK_ENTRY(search_entry));
+    if (strcmp(sWord, "") == 0) {
+       ShowNoResults(true);
+    } else {
+       /* unselect rows */
+       ResultsUnselectAll(GTK_SELECTION_NONE);
+
+       switch (analyse_query(sWord, query)) {
+       case qtDATA:
+           bFound = oLibs->LookupData(query.c_str());
+           break;
+       default:
+           /* nothing */ ;
+       }
+
+       /* unselect selected rows */
+       ResultsUnselectAll(GTK_SELECTION_SINGLE);
+
+       if (bFound)
+           ShowNoResults(false);
+       else
+           ShowNoResults(true);
+    }
+}
+
+void
 MStarDict::ResultsListClear()
 {
     gtk_list_store_clear(results_list);
@@ -575,12 +484,22 @@ MStarDict::ResultsListInsertLast(const gchar *word)
 }
 
 void
-MStarDict::ReScroll()
+MStarDict::ResultsReScroll()
 {
     hildon_pannable_area_scroll_to(HILDON_PANNABLE_AREA(results_view_scroll), -1, 0);
 }
 
 void
+MStarDict::ResultsUnselectAll(GtkSelectionMode mode)
+{
+    GtkTreeSelection *selection;
+
+    selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(results_view));
+    gtk_tree_selection_set_mode(selection, mode);
+    gtk_tree_selection_unselect_all(selection);
+}
+
+void
 MStarDict::ShowNoResults(bool bNoResults)
 {
     if (bNoResults) {
@@ -610,9 +529,15 @@ void
 MStarDict::ShowProgressIndicator(bool bShow)
 {
     if (bShow)
-       hildon_gtk_window_set_progress_indicator(GTK_WINDOW(main_window), 1);
+       hildon_gtk_window_set_progress_indicator(GTK_WINDOW(window), 1);
     else
-       hildon_gtk_window_set_progress_indicator(GTK_WINDOW(main_window), 0);
+       hildon_gtk_window_set_progress_indicator(GTK_WINDOW(window), 0);
+}
+
+void
+MStarDict::GrabFocus()
+{
+    gtk_widget_grab_focus(GTK_WIDGET(search_entry));
 }
 
 int
@@ -635,8 +560,8 @@ main(int argc,
     mStarDict.CreateMainMenu();
     mStarDict.ShowNoResults(true);
 
-    /* load all dictionaries */
-    mStarDict.LoadDictionaries();
+    /* load dictionaries */
+    mStarDict.oDict->LoadDictionaries();
 
     gtk_main();
     return 0;