2 * MStarDict - International dictionary for Maemo.
3 * Copyright (C) 2010 Roman Moravcik
5 * base on code of stardict:
6 * Copyright (C) 2003-2007 Hu Zheng <huzheng_001@163.com>
8 * based on code of sdcv:
9 * Copyright (C) 2005-2006 Evgeniy <dushistov@mail.ru>
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.
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.
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
37 #include <glib/gi18n.h>
38 #include <glib/gstdio.h>
41 #include <hildon/hildon.h>
50 #include "libwrapper.hpp"
52 #include "mstardict.hpp"
54 MStarDict *pMStarDict;
62 BOOKNAME_DICT_INFO_COLUMN,
63 FILENAME_DICT_INFO_COLUMN,
67 class GetAllDictList {
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);
74 std::list < std::string > &dict_all_list;
77 MStarDict::MStarDict()
81 results_widget = NULL;
83 results_view_scroll = NULL;
85 /* create list of ressults */
86 results_list = gtk_list_store_new(N_COLUMNS,
87 G_TYPE_STRING); /* DEF_COLUMN */
89 /* initialize configuration */
90 oConf = new MStarDictConf();
92 /* initialize stardict library */
93 oLibs = new Library();
96 MStarDict::~MStarDict()
98 /* destroy list of results */
99 g_object_unref(results_list);
101 /* deinitialize stardict library */
104 /* deinitialize configuration */
109 MStarDict::onResultsViewSelectionChanged(GtkTreeSelection *selection,
110 MStarDict *mStarDict)
114 char *bookname, *def, *exp;
118 if (gtk_tree_selection_get_selected(selection, &model, &iter)) {
119 /* unselect selected rows */
120 gtk_tree_selection_unselect_all(selection);
122 gtk_tree_model_get(model, &iter, DEF_COLUMN, &sWord, -1);
124 /* clear previous search results */
125 mStarDict->results.clear();
127 for (size_t iLib = 0; iLib < mStarDict->oLibs->query_dictmask.size(); iLib++) {
129 mStarDict->oLibs->BuildResultData(mStarDict->oLibs->query_dictmask, sWord,
130 mStarDict->oLibs->iCurrentIndex, iLib,
135 g_markup_printf_escaped
136 ("<span color=\"dimgray\" size=\"x-small\">%s</span>",
137 mStarDict->results[0].bookname.c_str());
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());
144 /* create translation window */
145 mStarDict->CreateTranslationWindow(bookname, def, exp);
152 /* grab focus to search entry */
153 gtk_widget_grab_focus(GTK_WIDGET(mStarDict->search));
159 MStarDict::onSearchEntryChanged(GtkEditable* editable,
160 MStarDict* mStarDict)
162 GtkTreeSelection *selection;
167 sWord = gtk_entry_get_text(GTK_ENTRY(editable));
169 if (mStarDict->oLibs->query_dictmask.empty())
172 if (strcmp(sWord, "") == 0) {
173 mStarDict->ShowNoResults(true);
175 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(mStarDict->results_view));
176 gtk_tree_selection_set_mode(selection, GTK_SELECTION_NONE);
179 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(mStarDict->results_view));
180 gtk_tree_selection_unselect_all(selection);
182 /* show progress indicator */
183 // mStarDict->ShowProgressIndicator(true);
185 switch (analyse_query(sWord, query)) {
187 bFound = mStarDict->oLibs->LookupWithFuzzy(query.c_str());
190 bFound = mStarDict->oLibs->LookupWithRule(query.c_str());
193 bFound = mStarDict->oLibs->LookupWithRegex(query.c_str());
196 bFound = mStarDict->oLibs->SimpleLookup(query.c_str(), mStarDict->oLibs->iCurrentIndex);
198 const gchar *sugWord = mStarDict->oLibs->GetSuggestWord(query.c_str(),
200 oLibs->iCurrentIndex,
202 oLibs->query_dictmask, 0);
204 gchar *sSugWord = g_strdup(sugWord);
206 mStarDict->oLibs->SimpleLookup(sSugWord, mStarDict->oLibs->iCurrentIndex);
210 mStarDict->oLibs->ListWords(mStarDict->oLibs->iCurrentIndex);
213 bFound = mStarDict->oLibs->LookupData(query.c_str());
219 /* unselect selected rows */
220 gtk_tree_selection_unselect_all(selection);
221 gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
223 /* hide progress indicator */
224 // mStarDict->ShowProgressIndicator(false);
227 mStarDict->ShowNoResults(false);
229 mStarDict->ShowNoResults(true);
236 MStarDict::onDictionariesMenuItemClicked(GtkButton *button,
237 MStarDict *mStarDict)
239 GtkWidget *dialog, *selector;
240 GtkCellRenderer *renderer;
241 HildonTouchSelectorColumn *column;
242 GtkTreeModel *tree_model;
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;
249 dict_list = gtk_list_store_new(N_DICT_INFO_COLUMNS,
250 G_TYPE_STRING, /* bookname */
251 G_TYPE_STRING); /* filename */
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);
260 /* dictionary selector */
261 selector = hildon_touch_selector_new();
262 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), selector);
264 renderer = gtk_cell_renderer_text_new();
265 g_object_set(G_OBJECT(renderer), "xpad", 10, NULL);
267 hildon_touch_selector_append_column(HILDON_TOUCH_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);
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) {
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);
285 g_object_unref(dict_list);
287 /* set selector mode to multiple */
288 hildon_touch_selector_set_column_selection_mode(HILDON_TOUCH_SELECTOR
290 HILDON_TOUCH_SELECTOR_SELECTION_MODE_MULTIPLE);
291 hildon_touch_selector_unselect_all(HILDON_TOUCH_SELECTOR(selector), BOOKNAME_DICT_INFO_COLUMN);
293 /* select all load dictionaries */
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;
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
305 BOOKNAME_DICT_INFO_COLUMN, &iter, FALSE);
312 gtk_widget_show_all(GTK_WIDGET(dialog));
315 if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
316 GList *selected_dicts = NULL;
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;
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));
333 g_list_foreach(selected_dicts, (GFunc) gtk_tree_path_free, NULL);
334 g_list_free(selected_dicts);
337 if (mStarDict->oConf->SetStringList("/apps/maemo/mstardict/dict_list", selected_dict_list)) {
338 /* reload dictionaries */
339 mStarDict->ReLoadDictionaries(selected_dict_list);
341 /* trigger re-search */
342 mStarDict->onSearchEntryChanged(GTK_EDITABLE(mStarDict->search), mStarDict);
345 gtk_widget_destroy(GTK_WIDGET(dialog));
350 MStarDict::onQuitMenuItemClicked(GtkButton *button,
351 MStarDict *mStarDict)
358 MStarDict::GetAllDictionaryList(std::list < std::string > &dict_list)
360 strlist_t dicts_dir_list;
361 strlist_t order_list;
362 strlist_t disable_list;
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));
370 MStarDict::LoadDictionaries()
372 std::list < std::string > dict_list;
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);
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) {
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);
391 if (oLibs->iCurrentIndex)
392 g_free(oLibs->iCurrentIndex);
393 oLibs->iCurrentIndex =
394 (CurrentIndex *) g_malloc(sizeof(CurrentIndex) * oLibs->query_dictmask.size());
396 if (oLibs->query_dictmask.empty())
397 ShowNoDictionary(true);
401 MStarDict::ReLoadDictionaries(std::list < std::string > &dict_list)
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) {
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);
415 if (oLibs->iCurrentIndex)
416 g_free(oLibs->iCurrentIndex);
417 oLibs->iCurrentIndex =
418 (CurrentIndex *) g_malloc(sizeof(CurrentIndex) * oLibs->query_dictmask.size());
420 if (oLibs->query_dictmask.empty())
421 ShowNoDictionary(true);
425 MStarDict::CreateTranslationWindow(const gchar *bookname,
429 GtkWidget *window, *alignment, *pannable, *vbox, *label;
431 window = hildon_stackable_window_new();
432 gtk_window_set_title(GTK_WINDOW(window), _("Translation"));
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);
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);
444 vbox = gtk_vbox_new(FALSE, 0);
445 hildon_pannable_area_add_with_viewport(HILDON_PANNABLE_AREA(pannable), vbox);
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);
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);
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);
462 gtk_widget_show_all(window);
466 MStarDict::CreateMainWindow()
468 HildonProgram *program = NULL;
469 GtkWidget *alignment, *vbox;
470 GtkCellRenderer *renderer;
471 GtkTreeSelection *selection;
474 program = hildon_program_get_instance();
475 g_set_application_name(_("MStardict"));
478 main_window = hildon_stackable_window_new();
479 hildon_program_add_window(program, HILDON_WINDOW(main_window));
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);
488 vbox = gtk_vbox_new(FALSE, 0);
489 gtk_container_add(GTK_CONTAINER(alignment), vbox);
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);
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);
504 /* pannable for tree view */
505 results_view_scroll = hildon_pannable_area_new();
506 gtk_container_add(GTK_CONTAINER(results_widget), results_view_scroll);
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);
513 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(results_view));
514 g_signal_connect(selection, "changed", G_CALLBACK(onResultsViewSelectionChanged), this);
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);
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);
529 g_signal_connect(G_OBJECT(main_window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
531 /* show all widget instead of alignment */
532 gtk_widget_show_all(GTK_WIDGET(main_window));
534 /* grab focus to search entry */
535 gtk_widget_grab_focus(GTK_WIDGET(search));
539 MStarDict::CreateMainMenu()
544 menu = HILDON_APP_MENU(hildon_app_menu_new());
545 hildon_window_set_app_menu(HILDON_WINDOW(main_window), menu);
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);
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);
560 gtk_widget_show_all(GTK_WIDGET(menu));
564 MStarDict::ResultsListClear()
566 gtk_list_store_clear(results_list);
570 MStarDict::ResultsListInsertLast(const gchar *word)
573 gtk_list_store_append(results_list, &iter);
574 gtk_list_store_set(results_list, &iter, DEF_COLUMN, word, -1);
578 MStarDict::ReScroll()
580 hildon_pannable_area_scroll_to(HILDON_PANNABLE_AREA(results_view_scroll), -1, 0);
584 MStarDict::ShowNoResults(bool 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);
591 gtk_widget_hide(label_widget);
592 gtk_widget_show(results_widget);
597 MStarDict::ShowNoDictionary(bool 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);
604 gtk_widget_hide(label_widget);
605 gtk_widget_show(results_widget);
610 MStarDict::ShowProgressIndicator(bool bShow)
613 hildon_gtk_window_set_progress_indicator(GTK_WINDOW(main_window), 1);
615 hildon_gtk_window_set_progress_indicator(GTK_WINDOW(main_window), 0);
622 /* initialize hildon */
623 hildon_gtk_init(&argc, &argv);
625 /* initialize localization */
626 setlocale(LC_ALL, "");
627 bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
628 bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
629 textdomain(GETTEXT_PACKAGE);
631 /* create main window */
633 pMStarDict = &mStarDict;
634 mStarDict.CreateMainWindow();
635 mStarDict.CreateMainMenu();
636 mStarDict.ShowNoResults(true);
638 /* load all dictionaries */
639 mStarDict.LoadDictionaries();