Imported version 0.3-1
[mstardict] / src / mstardict.cpp
1 /*
2  *  MStarDict - International dictionary for Maemo.
3  *  Copyright (C) 2010 Roman Moravcik
4  *
5  *  base on code of stardict:
6  *  Copyright (C) 2003-2007 Hu Zheng <huzheng_001@163.com>
7  *
8  *  based on code of sdcv:
9  *  Copyright (C) 2005-2006 Evgeniy <dushistov@mail.ru>
10  *
11  *  This program is free software; you can redistribute it and/or modify
12  *  it under the terms of the GNU General Public License as published by
13  *  the Free Software Foundation; either version 2 of the License, or
14  *  (at your option) any later version.
15  *
16  *  This program is distributed in the hope that it will be useful,
17  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  *  GNU General Public License for more details.
20  *
21  *  You should have received a copy of the GNU General Public License
22  *  along with this program; if not, write to the Free Software
23  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24  */
25
26 #ifdef HAVE_CONFIG_H
27 #  include "config.h"
28 #endif
29
30 #include <cerrno>
31 #include <cstring>
32 #include <cstdlib>
33 #include <cstdio>
34 #include <clocale>
35
36 #include <glib.h>
37 #include <glib/gi18n.h>
38 #include <glib/gstdio.h>
39
40 #include <gtk/gtk.h>
41 #include <hildon/hildon.h>
42
43 #include <getopt.h>
44 #include <string>
45 #include <vector>
46 #include <memory>
47 #include <list>
48
49 #include "conf.hpp"
50 #include "libwrapper.hpp"
51 #include "file.hpp"
52 #include "mstardict.hpp"
53
54 MStarDict *pMStarDict;
55
56 enum {
57     DEF_COLUMN,
58     N_COLUMNS
59 };
60
61 enum {
62     BOOKNAME_DICT_INFO_COLUMN,
63     FILENAME_DICT_INFO_COLUMN,
64     N_DICT_INFO_COLUMNS
65 };
66
67 class GetAllDictList {
68   public:
69     GetAllDictList(std::list < std::string > &dict_all_list_):dict_all_list(dict_all_list_) {
70     } void operator() (const std::string & url, bool disable) {
71         dict_all_list.push_back(url);
72     }
73   private:
74     std::list < std::string > &dict_all_list;
75 };
76
77 MStarDict::MStarDict()
78 {
79     main_window = NULL;
80     label_widget = NULL;
81     results_widget = NULL;
82     results_view = NULL;
83     results_view_scroll = NULL;
84
85     /* create list of ressults */
86     results_list = gtk_list_store_new(N_COLUMNS,
87                                       G_TYPE_STRING);   /* DEF_COLUMN */
88
89     /* initialize configuration */
90     oConf = new MStarDictConf();
91
92     /* initialize stardict library */
93     oLibs = new Library();
94 }
95
96 MStarDict::~MStarDict()
97 {
98     /* destroy list of results */
99     g_object_unref(results_list);
100
101     /* deinitialize stardict library */
102     delete oLibs;
103
104     /* deinitialize configuration */
105     delete oConf;
106 }
107
108 gboolean
109 MStarDict::onResultsViewSelectionChanged(GtkTreeSelection *selection,
110                                          MStarDict *mStarDict)
111 {
112     GtkTreeModel *model;
113     GtkTreeIter iter;
114     char *bookname, *def, *exp;
115     const gchar *sWord;
116     bool bFound = false;
117
118     if (gtk_tree_selection_get_selected(selection, &model, &iter)) {
119         /* unselect selected rows */
120         gtk_tree_selection_unselect_all(selection);
121
122         gtk_tree_model_get(model, &iter, DEF_COLUMN, &sWord, -1);
123
124         /* clear previous search results */
125         mStarDict->results.clear();
126
127         for (size_t iLib = 0; iLib < mStarDict->oLibs->query_dictmask.size(); iLib++) {
128             bFound =
129                 mStarDict->oLibs->BuildResultData(mStarDict->oLibs->query_dictmask, sWord,
130                                                   mStarDict->oLibs->iCurrentIndex, iLib,
131                                                   mStarDict->results);
132         }
133
134         bookname =
135             g_markup_printf_escaped
136             ("<span color=\"dimgray\" size=\"x-small\">%s</span>",
137              mStarDict->results[0].bookname.c_str());
138         def =
139             g_markup_printf_escaped
140             ("<span color=\"darkred\" weight=\"heavy\" size=\"large\">%s</span>",
141              mStarDict->results[0].def.c_str());
142         exp = g_strdup(mStarDict->results[0].exp.c_str());
143
144         /* create translation window */
145         mStarDict->CreateTranslationWindow(bookname, def, exp);
146
147         g_free(bookname);
148         g_free(def);
149         g_free(exp);
150     }
151
152     /* grab focus to search entry */
153     gtk_widget_grab_focus(GTK_WIDGET(mStarDict->search));
154
155     return true;
156 }
157
158 gboolean
159 MStarDict::onSearchEntryChanged(GtkEditable* editable,
160                                 MStarDict* mStarDict)
161 {
162     GtkTreeSelection *selection;
163     const gchar *sWord;
164     bool bFound = false;
165     std::string query;
166
167     sWord = gtk_entry_get_text(GTK_ENTRY(editable));
168
169     if (mStarDict->oLibs->query_dictmask.empty())
170         return true;
171
172     if (strcmp(sWord, "") == 0) {
173         mStarDict->ShowNoResults(true);
174     } else {
175         selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(mStarDict->results_view));
176         gtk_tree_selection_set_mode(selection, GTK_SELECTION_NONE);
177
178         /* unselect rows */
179         selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(mStarDict->results_view));
180         gtk_tree_selection_unselect_all(selection);
181
182         /* show progress indicator */
183 //      mStarDict->ShowProgressIndicator(true);
184
185         switch (analyse_query(sWord, query)) {
186         case qtFUZZY:
187             bFound = mStarDict->oLibs->LookupWithFuzzy(query.c_str());
188             break;
189         case qtPATTERN:
190             bFound = mStarDict->oLibs->LookupWithRule(query.c_str());
191             break;
192         case qtREGEX:
193             bFound = mStarDict->oLibs->LookupWithRegex(query.c_str());
194             break;
195         case qtSIMPLE:
196             bFound = mStarDict->oLibs->SimpleLookup(query.c_str(), mStarDict->oLibs->iCurrentIndex);
197             if (!bFound) {
198                 const gchar *sugWord = mStarDict->oLibs->GetSuggestWord(query.c_str(),
199                                                                         mStarDict->
200                                                                         oLibs->iCurrentIndex,
201                                                                         mStarDict->
202                                                                         oLibs->query_dictmask, 0);
203                 if (sugWord) {
204                     gchar *sSugWord = g_strdup(sugWord);
205                     bFound =
206                         mStarDict->oLibs->SimpleLookup(sSugWord, mStarDict->oLibs->iCurrentIndex);
207                     g_free(sSugWord);
208                 }
209             }
210             mStarDict->oLibs->ListWords(mStarDict->oLibs->iCurrentIndex);
211             break;
212         case qtDATA:
213             bFound = mStarDict->oLibs->LookupData(query.c_str());
214             break;
215         default:
216             /* nothing */ ;
217         }
218
219         /* unselect selected rows */
220         gtk_tree_selection_unselect_all(selection);
221         gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
222
223         /* hide progress indicator */
224 //      mStarDict->ShowProgressIndicator(false);
225
226         if (bFound)
227             mStarDict->ShowNoResults(false);
228         else
229             mStarDict->ShowNoResults(true);
230     }
231
232     return true;
233 }
234
235 gboolean
236 MStarDict::onDictionariesMenuItemClicked(GtkButton *button,
237                                          MStarDict *mStarDict)
238 {
239     GtkWidget *dialog, *selector;
240     GtkCellRenderer *renderer;
241     HildonTouchSelectorColumn *column;
242     GtkTreeModel *tree_model;
243     GtkTreeIter iter;
244     gboolean iter_valid = TRUE;
245     std::list < std::string > all_dict_list;
246     std::list < std::string > selected_dict_list;
247     GtkListStore *dict_list = NULL;
248
249     dict_list = gtk_list_store_new(N_DICT_INFO_COLUMNS,
250                                    G_TYPE_STRING,       /* bookname */
251                                    G_TYPE_STRING);      /* filename */
252
253     /* create dialog */
254     dialog = gtk_dialog_new();
255     gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
256     gtk_window_set_title(GTK_WINDOW(dialog), _("Dictionaries"));
257     gtk_dialog_add_button(GTK_DIALOG(dialog), "OK", GTK_RESPONSE_ACCEPT);
258     gtk_window_set_default_size(GTK_WINDOW(dialog), -1, 400);
259
260     /* dictionary selector */
261     selector = hildon_touch_selector_new();
262     gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), selector);
263
264     renderer = gtk_cell_renderer_text_new();
265     g_object_set(G_OBJECT(renderer), "xpad", 10, NULL);
266     column =
267         hildon_touch_selector_append_column(HILDON_TOUCH_SELECTOR
268                                             (selector),
269                                             GTK_TREE_MODEL(dict_list),
270                                             renderer, "text", BOOKNAME_DICT_INFO_COLUMN, NULL);
271     hildon_touch_selector_column_set_text_column(column, 0);
272
273     /* fill list with all available dictionaries */
274     mStarDict->GetAllDictionaryList(all_dict_list);
275     for (std::list < std::string >::iterator i = all_dict_list.begin();
276          i != all_dict_list.end(); ++i) {
277         DictInfo dictinfo;
278
279         dictinfo.load_from_ifo_file(i->c_str(), 0);
280         gtk_list_store_append(dict_list, &iter);
281         gtk_list_store_set(dict_list, &iter,
282                            BOOKNAME_DICT_INFO_COLUMN,
283                            dictinfo.bookname.c_str(), FILENAME_DICT_INFO_COLUMN, i->c_str(), -1);
284     }
285     g_object_unref(dict_list);
286
287     /* set selector mode to multiple */
288     hildon_touch_selector_set_column_selection_mode(HILDON_TOUCH_SELECTOR
289                                                     (selector),
290                                                     HILDON_TOUCH_SELECTOR_SELECTION_MODE_MULTIPLE);
291     hildon_touch_selector_unselect_all(HILDON_TOUCH_SELECTOR(selector), BOOKNAME_DICT_INFO_COLUMN);
292
293     /* select all load dictionaries */
294     tree_model =
295         hildon_touch_selector_get_model(HILDON_TOUCH_SELECTOR(selector), BOOKNAME_DICT_INFO_COLUMN);
296     for (iter_valid = gtk_tree_model_get_iter_first(tree_model, &iter);
297          iter_valid; iter_valid = gtk_tree_model_iter_next(tree_model, &iter)) {
298         const gchar *bookname;
299
300         gtk_tree_model_get(tree_model, &iter, BOOKNAME_DICT_INFO_COLUMN, &bookname, -1);
301         for (size_t iLib = 0; iLib < mStarDict->oLibs->query_dictmask.size(); iLib++) {
302             if (!strcmp(mStarDict->oLibs->dict_name(iLib).c_str(), bookname)) {
303                 hildon_touch_selector_select_iter(HILDON_TOUCH_SELECTOR
304                                                   (selector),
305                                                   BOOKNAME_DICT_INFO_COLUMN, &iter, FALSE);
306                 break;
307             }
308         }
309     }
310
311     /* show dialog */
312     gtk_widget_show_all(GTK_WIDGET(dialog));
313
314     /* run the dialog */
315     if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
316         GList *selected_dicts = NULL;
317
318         selected_dicts =
319             hildon_touch_selector_get_selected_rows(HILDON_TOUCH_SELECTOR
320                                                     (selector), BOOKNAME_DICT_INFO_COLUMN);
321         if (selected_dicts) {
322             GList *dict = selected_dicts;
323             const gchar *filename;
324
325             while (dict) {
326                 gtk_tree_model_get_iter(GTK_TREE_MODEL(tree_model), &iter,
327                                         (GtkTreePath *) (dict->data));
328                 gtk_tree_model_get(GTK_TREE_MODEL(tree_model), &iter,
329                                    FILENAME_DICT_INFO_COLUMN, &filename, -1);
330                 selected_dict_list.push_back(std::string(filename));
331                 dict = dict->next;
332             }
333             g_list_foreach(selected_dicts, (GFunc) gtk_tree_path_free, NULL);
334             g_list_free(selected_dicts);
335         }
336
337         if (mStarDict->oConf->SetStringList("/apps/maemo/mstardict/dict_list", selected_dict_list)) {
338             /* reload dictionaries */
339             mStarDict->ReLoadDictionaries(selected_dict_list);
340
341             /* trigger re-search */
342             mStarDict->onSearchEntryChanged(GTK_EDITABLE(mStarDict->search), mStarDict);
343         }
344     }
345     gtk_widget_destroy(GTK_WIDGET(dialog));
346     return true;
347 }
348
349 gboolean
350 MStarDict::onQuitMenuItemClicked(GtkButton *button,
351                                  MStarDict *mStarDict)
352 {
353     gtk_main_quit();
354     return true;
355 }
356
357 void
358 MStarDict::GetAllDictionaryList(std::list < std::string > &dict_list)
359 {
360     strlist_t dicts_dir_list;
361     strlist_t order_list;
362     strlist_t disable_list;
363
364     /* dictionary directory */
365     dicts_dir_list.push_back(std::string("/home/user/MyDocs/mstardict"));
366     for_each_file(dicts_dir_list, ".ifo", order_list, disable_list, GetAllDictList(dict_list));
367 }
368
369 void
370 MStarDict::LoadDictionaries()
371 {
372     std::list < std::string > dict_list;
373
374     if (!oConf->GetStringList("/apps/maemo/mstardict/dict_list", dict_list)) {
375         GetAllDictionaryList(dict_list);
376         oConf->SetStringList("/apps/maemo/mstardict/dict_list", dict_list);
377     }
378
379     oLibs->load(dict_list);
380     oLibs->query_dictmask.clear();
381     for (std::list < std::string >::iterator i = dict_list.begin(); i != dict_list.end(); ++i) {
382         size_t iLib;
383         if (oLibs->find_lib_by_filename(i->c_str(), iLib)) {
384             InstantDictIndex instance_dict_index;
385             instance_dict_index.type = InstantDictType_LOCAL;
386             instance_dict_index.index = iLib;
387             oLibs->query_dictmask.push_back(instance_dict_index);
388         }
389     }
390
391     if (oLibs->iCurrentIndex)
392         g_free(oLibs->iCurrentIndex);
393     oLibs->iCurrentIndex =
394         (CurrentIndex *) g_malloc(sizeof(CurrentIndex) * oLibs->query_dictmask.size());
395
396     if (oLibs->query_dictmask.empty())
397         ShowNoDictionary(true);
398 }
399
400 void
401 MStarDict::ReLoadDictionaries(std::list < std::string > &dict_list)
402 {
403     oLibs->reload(dict_list, 0, 0);
404     oLibs->query_dictmask.clear();
405     for (std::list < std::string >::iterator i = dict_list.begin(); i != dict_list.end(); ++i) {
406         size_t iLib;
407         if (oLibs->find_lib_by_filename(i->c_str(), iLib)) {
408             InstantDictIndex instance_dict_index;
409             instance_dict_index.type = InstantDictType_LOCAL;
410             instance_dict_index.index = iLib;
411             oLibs->query_dictmask.push_back(instance_dict_index);
412         }
413     }
414
415     if (oLibs->iCurrentIndex)
416         g_free(oLibs->iCurrentIndex);
417     oLibs->iCurrentIndex =
418         (CurrentIndex *) g_malloc(sizeof(CurrentIndex) * oLibs->query_dictmask.size());
419
420     if (oLibs->query_dictmask.empty())
421         ShowNoDictionary(true);
422 }
423
424 void
425 MStarDict::CreateTranslationWindow(const gchar *bookname,
426                                    const gchar *def,
427                                    const gchar *exp)
428 {
429     GtkWidget *window, *alignment, *pannable, *vbox, *label;
430
431     window = hildon_stackable_window_new();
432     gtk_window_set_title(GTK_WINDOW(window), _("Translation"));
433
434     alignment = gtk_alignment_new(0.0, 0.0, 1.0, 1.0);
435     gtk_alignment_set_padding(GTK_ALIGNMENT(alignment),
436                               HILDON_MARGIN_DEFAULT,
437                               HILDON_MARGIN_DEFAULT, HILDON_MARGIN_DOUBLE, HILDON_MARGIN_DEFAULT);
438     gtk_container_add(GTK_CONTAINER(window), alignment);
439
440     pannable = hildon_pannable_area_new();
441     g_object_set(G_OBJECT(pannable), "mov-mode", HILDON_MOVEMENT_MODE_BOTH, NULL);
442     gtk_container_add(GTK_CONTAINER(alignment), pannable);
443
444     vbox = gtk_vbox_new(FALSE, 0);
445     hildon_pannable_area_add_with_viewport(HILDON_PANNABLE_AREA(pannable), vbox);
446
447     label = gtk_label_new("Bookname");
448     gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
449     gtk_label_set_markup(GTK_LABEL(label), bookname);
450     gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
451
452     label = gtk_label_new("Definition");
453     gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
454     gtk_label_set_markup(GTK_LABEL(label), def);
455     gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
456
457     label = gtk_label_new("Expresion");
458     gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.0);
459     gtk_label_set_markup(GTK_LABEL(label), exp);
460     gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
461
462     gtk_widget_show_all(window);
463 }
464
465 void
466 MStarDict::CreateMainWindow()
467 {
468     HildonProgram *program = NULL;
469     GtkWidget *alignment, *vbox;
470     GtkCellRenderer *renderer;
471     GtkTreeSelection *selection;
472
473     /* hildon program */
474     program = hildon_program_get_instance();
475     g_set_application_name(_("MStardict"));
476
477     /* main window */
478     main_window = hildon_stackable_window_new();
479     hildon_program_add_window(program, HILDON_WINDOW(main_window));
480
481     /* aligment */
482     alignment = gtk_alignment_new(0.5, 0.5, 1.0, 1.0);
483     gtk_alignment_set_padding(GTK_ALIGNMENT(alignment),
484                               HILDON_MARGIN_HALF, 0, HILDON_MARGIN_DEFAULT, HILDON_MARGIN_DEFAULT);
485     gtk_container_add(GTK_CONTAINER(main_window), alignment);
486
487     /* main vbox */
488     vbox = gtk_vbox_new(FALSE, 0);
489     gtk_container_add(GTK_CONTAINER(alignment), vbox);
490
491     /* no_search_result label */
492     label_widget = gtk_label_new(_("No search result"));
493     hildon_helper_set_logical_color(label_widget, GTK_RC_FG,
494                                     GTK_STATE_NORMAL, "SecondaryTextColor");
495     hildon_helper_set_logical_font(label_widget, "LargeSystemFont");
496     gtk_box_pack_start(GTK_BOX(vbox), label_widget, TRUE, TRUE, 0);
497
498     /* alignment for pannable area */
499     results_widget = gtk_alignment_new(0.5, 0.5, 1.0, 1.0);
500     gtk_alignment_set_padding(GTK_ALIGNMENT(results_widget),
501                               0, 0, HILDON_MARGIN_DEFAULT, HILDON_MARGIN_DEFAULT);
502     gtk_box_pack_start(GTK_BOX(vbox), results_widget, TRUE, TRUE, 0);
503
504     /* pannable for tree view */
505     results_view_scroll = hildon_pannable_area_new();
506     gtk_container_add(GTK_CONTAINER(results_widget), results_view_scroll);
507
508     /* result tree view */
509     results_view = hildon_gtk_tree_view_new(HILDON_UI_MODE_EDIT);
510     gtk_tree_view_set_model(GTK_TREE_VIEW(results_view), GTK_TREE_MODEL(results_list));
511     gtk_container_add(GTK_CONTAINER(results_view_scroll), results_view);
512
513     selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(results_view));
514     g_signal_connect(selection, "changed", G_CALLBACK(onResultsViewSelectionChanged), this);
515
516     /* def column */
517     renderer = gtk_cell_renderer_text_new();
518     gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW
519                                                 (results_view), -1, "Def",
520                                                 renderer, "text", DEF_COLUMN, NULL);
521     g_object_set(G_OBJECT(renderer), "xpad", 10, NULL);
522
523     /* search entry */
524     search = hildon_entry_new(HILDON_SIZE_FINGER_HEIGHT);
525     gtk_box_pack_end(GTK_BOX(vbox), search, FALSE, TRUE, 0);
526     g_signal_connect(search, "changed", G_CALLBACK(onSearchEntryChanged), this);
527
528     /* window signals */
529     g_signal_connect(G_OBJECT(main_window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
530
531     /* show all widget instead of alignment */
532     gtk_widget_show_all(GTK_WIDGET(main_window));
533
534     /* grab focus to search entry */
535     gtk_widget_grab_focus(GTK_WIDGET(search));
536 }
537
538 void
539 MStarDict::CreateMainMenu()
540 {
541     HildonAppMenu *menu;
542     GtkWidget *item;
543
544     menu = HILDON_APP_MENU(hildon_app_menu_new());
545     hildon_window_set_app_menu(HILDON_WINDOW(main_window), menu);
546
547     /* dictionaries menu item */
548     item = hildon_gtk_button_new(HILDON_SIZE_AUTO);
549     gtk_button_set_label(GTK_BUTTON(item), _("Dictionaries"));
550     hildon_app_menu_append(menu, GTK_BUTTON(item));
551     g_signal_connect(item, "clicked", G_CALLBACK(onDictionariesMenuItemClicked), this);
552
553     /* quit menu item */
554     item = hildon_gtk_button_new(HILDON_SIZE_AUTO);
555     gtk_button_set_label(GTK_BUTTON(item), _("Quit"));
556     hildon_app_menu_append(menu, GTK_BUTTON(item));
557     g_signal_connect(item, "clicked", G_CALLBACK(onQuitMenuItemClicked), this);
558
559     /* show main menu */
560     gtk_widget_show_all(GTK_WIDGET(menu));
561 }
562
563 void
564 MStarDict::ResultsListClear()
565 {
566     gtk_list_store_clear(results_list);
567 }
568
569 void
570 MStarDict::ResultsListInsertLast(const gchar *word)
571 {
572     GtkTreeIter iter;
573     gtk_list_store_append(results_list, &iter);
574     gtk_list_store_set(results_list, &iter, DEF_COLUMN, word, -1);
575 }
576
577 void
578 MStarDict::ReScroll()
579 {
580     hildon_pannable_area_scroll_to(HILDON_PANNABLE_AREA(results_view_scroll), -1, 0);
581 }
582
583 void
584 MStarDict::ShowNoResults(bool bNoResults)
585 {
586     if (bNoResults) {
587         gtk_label_set_text(GTK_LABEL(label_widget), _("No search result"));
588         gtk_widget_show(label_widget);
589         gtk_widget_hide(results_widget);
590     } else {
591         gtk_widget_hide(label_widget);
592         gtk_widget_show(results_widget);
593     }
594 }
595
596 void
597 MStarDict::ShowNoDictionary(bool bNoDictionary)
598 {
599     if (bNoDictionary) {
600         gtk_label_set_text(GTK_LABEL(label_widget), _("No loaded dictionary"));
601         gtk_widget_show(label_widget);
602         gtk_widget_hide(results_widget);
603     } else {
604         gtk_widget_hide(label_widget);
605         gtk_widget_show(results_widget);
606     }
607 }
608
609 void
610 MStarDict::ShowProgressIndicator(bool bShow)
611 {
612     if (bShow)
613         hildon_gtk_window_set_progress_indicator(GTK_WINDOW(main_window), 1);
614     else
615         hildon_gtk_window_set_progress_indicator(GTK_WINDOW(main_window), 0);
616 }
617
618 int
619 main(int argc,
620      char **argv)
621 {
622     /* initialize hildon */
623     hildon_gtk_init(&argc, &argv);
624
625     /* initialize localization */
626     setlocale(LC_ALL, "");
627     bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
628     bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
629     textdomain(GETTEXT_PACKAGE);
630
631     /* create main window */
632     MStarDict mStarDict;
633     pMStarDict = &mStarDict;
634     mStarDict.CreateMainWindow();
635     mStarDict.CreateMainMenu();
636     mStarDict.ShowNoResults(true);
637
638     /* load all dictionaries */
639     mStarDict.LoadDictionaries();
640
641     gtk_main();
642     return 0;
643 }