Fixed typo in word Preferences (Preferencies->Preferences).
[mstardict] / src / dictmngr.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 <list>
31
32 #include <glib.h>
33 #include <glib/gi18n.h>
34 #include <glib/gstdio.h>
35
36 #include <gtk/gtk.h>
37 #include <hildon/hildon.h>
38
39 #include "conf.hpp"
40 #include "libwrapper.hpp"
41 #include "mstardict.hpp"
42 #include "dictmngr.hpp"
43
44 #define DEFAULT_DICT_DIR "/home/user/MyDocs/mstardict"
45 #define STARDICT_DICT_DIR "/home/user/.stardict/dic"
46
47 enum {
48     BOOKNAME_DICT_INFO_COLUMN,
49     FILENAME_DICT_INFO_COLUMN,
50     N_DICT_INFO_COLUMNS
51 };
52
53 class GetAllDictList {
54   public:
55     GetAllDictList(std::list < std::string > &dict_all_list_):dict_all_list(dict_all_list_) {
56     } void operator() (const std::string & url, bool disable) {
57         dict_all_list.push_back(url);
58     }
59   private:
60     std::list < std::string > &dict_all_list;
61 };
62
63 DictMngr::DictMngr(MStarDict *mStarDict)
64 {
65     oStarDict = mStarDict;
66
67     /* check if default dictionary exists */
68     if (!g_file_test(DEFAULT_DICT_DIR, GFileTest(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) {
69             if (g_mkdir(DEFAULT_DICT_DIR, S_IRWXU)==-1)
70                 g_warning("Cannot create directory %s.", DEFAULT_DICT_DIR);
71     }
72 }
73
74 DictMngr::~DictMngr()
75 {
76 }
77
78 void
79 DictMngr::CreateDictMngrDialog()
80 {
81     GtkWidget *dialog, *selector;
82     GtkCellRenderer *renderer;
83     HildonTouchSelectorColumn *column;
84     GtkTreeModel *tree_model;
85     GtkTreeIter iter;
86     gboolean iter_valid = TRUE;
87     std::list < std::string > all_dict_list;
88     std::list < std::string > selected_dict_list;
89     GtkListStore *dict_list = NULL;
90
91     dict_list = gtk_list_store_new(N_DICT_INFO_COLUMNS,
92                                    G_TYPE_STRING,       /* bookname */
93                                    G_TYPE_STRING);      /* filename */
94
95     /* create dialog */
96     dialog = gtk_dialog_new();
97     gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
98     gtk_window_set_title(GTK_WINDOW(dialog), _("Dictionaries"));
99     gtk_dialog_add_button(GTK_DIALOG(dialog), "OK", GTK_RESPONSE_ACCEPT);
100     gtk_window_set_default_size(GTK_WINDOW(dialog), -1, 400);
101
102     /* dictionary selector */
103     selector = hildon_touch_selector_new();
104     gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), selector);
105
106     renderer = gtk_cell_renderer_text_new();
107     g_object_set(G_OBJECT(renderer),
108                  "xpad", 10,
109                  "ellipsize", PANGO_ELLIPSIZE_END,
110                  "ellipsize-set", TRUE,
111                  NULL);
112
113     column =
114         hildon_touch_selector_append_column(HILDON_TOUCH_SELECTOR
115                                             (selector),
116                                             GTK_TREE_MODEL(dict_list),
117                                             renderer, "text", BOOKNAME_DICT_INFO_COLUMN, NULL);
118     hildon_touch_selector_column_set_text_column(column, 0);
119
120     /* fill list with all available dictionaries */
121     GetAllDictionaryList(all_dict_list);
122     for (std::list < std::string >::iterator i = all_dict_list.begin();
123          i != all_dict_list.end(); ++i) {
124         DictInfo dictinfo;
125
126         dictinfo.load_from_ifo_file(i->c_str(), 0);
127         gtk_list_store_append(dict_list, &iter);
128         gtk_list_store_set(dict_list, &iter,
129                            BOOKNAME_DICT_INFO_COLUMN,
130                            dictinfo.bookname.c_str(), FILENAME_DICT_INFO_COLUMN, i->c_str(), -1);
131     }
132     g_object_unref(dict_list);
133
134     /* set selector mode to multiple */
135     hildon_touch_selector_set_column_selection_mode(HILDON_TOUCH_SELECTOR
136                                                     (selector),
137                                                     HILDON_TOUCH_SELECTOR_SELECTION_MODE_MULTIPLE);
138     hildon_touch_selector_unselect_all(HILDON_TOUCH_SELECTOR(selector), BOOKNAME_DICT_INFO_COLUMN);
139
140     /* select all load dictionaries */
141     tree_model =
142         hildon_touch_selector_get_model(HILDON_TOUCH_SELECTOR(selector), BOOKNAME_DICT_INFO_COLUMN);
143     for (iter_valid = gtk_tree_model_get_iter_first(tree_model, &iter);
144          iter_valid; iter_valid = gtk_tree_model_iter_next(tree_model, &iter)) {
145         const gchar *bookname;
146
147         gtk_tree_model_get(tree_model, &iter, BOOKNAME_DICT_INFO_COLUMN, &bookname, -1);
148         for (size_t iLib = 0; iLib < oStarDict->oLibs->query_dictmask.size(); iLib++) {
149             if (!strcmp(oStarDict->oLibs->dict_name(iLib).c_str(), bookname)) {
150                 hildon_touch_selector_select_iter(HILDON_TOUCH_SELECTOR
151                                                   (selector),
152                                                   BOOKNAME_DICT_INFO_COLUMN, &iter, FALSE);
153                 break;
154             }
155         }
156     }
157
158     /* show dialog */
159     gtk_widget_show_all(GTK_WIDGET(dialog));
160
161     /* run the dialog */
162     if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
163         GList *selected_dicts = NULL;
164
165         selected_dicts =
166             hildon_touch_selector_get_selected_rows(HILDON_TOUCH_SELECTOR
167                                                     (selector), BOOKNAME_DICT_INFO_COLUMN);
168         if (selected_dicts) {
169             GList *dict = selected_dicts;
170             const gchar *filename;
171
172             while (dict) {
173                 gtk_tree_model_get_iter(GTK_TREE_MODEL(tree_model), &iter,
174                                         (GtkTreePath *) (dict->data));
175                 gtk_tree_model_get(GTK_TREE_MODEL(tree_model), &iter,
176                                    FILENAME_DICT_INFO_COLUMN, &filename, -1);
177                 selected_dict_list.push_back(std::string(filename));
178                 dict = dict->next;
179             }
180             g_list_foreach(selected_dicts, (GFunc) gtk_tree_path_free, NULL);
181             g_list_free(selected_dicts);
182         }
183
184         if (oStarDict->oConf->SetStringList("/apps/maemo/mstardict/dict_list", selected_dict_list)) {
185             /* reload dictionaries */
186             ReLoadDictionaries(selected_dict_list);
187         }
188     }
189     gtk_widget_destroy(GTK_WIDGET(dialog));
190 }
191
192 void
193 DictMngr::GetAllDictionaryList(std::list < std::string > &dict_list)
194 {
195     strlist_t dicts_dir_list;
196     strlist_t order_list;
197     strlist_t disable_list;
198
199     /* default mstardict dictionary directory */
200     dicts_dir_list.push_back(std::string(DEFAULT_DICT_DIR));
201
202     /* stardict dictionary directory */
203     dicts_dir_list.push_back(std::string(STARDICT_DICT_DIR));
204     for_each_file(dicts_dir_list, ".ifo", order_list, disable_list, GetAllDictList(dict_list));
205 }
206
207 void
208 DictMngr::LoadDictionaries()
209 {
210     std::list < std::string > dict_list;
211
212     if (!oStarDict->oConf->GetStringList("/apps/maemo/mstardict/dict_list", dict_list)) {
213         GetAllDictionaryList(dict_list);
214         oStarDict->oConf->SetStringList("/apps/maemo/mstardict/dict_list", dict_list);
215     }
216
217     oStarDict->oLibs->load(dict_list);
218     oStarDict->oLibs->query_dictmask.clear();
219     for (std::list < std::string >::iterator i = dict_list.begin(); i != dict_list.end(); ++i) {
220         size_t iLib;
221         if (oStarDict->oLibs->find_lib_by_filename(i->c_str(), iLib)) {
222             InstantDictIndex instance_dict_index;
223             instance_dict_index.type = InstantDictType_LOCAL;
224             instance_dict_index.index = iLib;
225             oStarDict->oLibs->query_dictmask.push_back(instance_dict_index);
226         }
227     }
228
229     if (oStarDict->oLibs->iCurrentIndex)
230         g_free(oStarDict->oLibs->iCurrentIndex);
231     oStarDict->oLibs->iCurrentIndex =
232         (CurrentIndex *) g_malloc(sizeof(CurrentIndex) * oStarDict->oLibs->query_dictmask.size());
233
234     if (oStarDict->oLibs->query_dictmask.empty())
235         oStarDict->ShowNoDictionary(true);
236 }
237
238 void
239 DictMngr::ReLoadDictionaries(std::list < std::string > &dict_list)
240 {
241     oStarDict->oLibs->reload(dict_list, 0, 0);
242     oStarDict->oLibs->query_dictmask.clear();
243     for (std::list < std::string >::iterator i = dict_list.begin(); i != dict_list.end(); ++i) {
244         size_t iLib;
245         if (oStarDict->oLibs->find_lib_by_filename(i->c_str(), iLib)) {
246             InstantDictIndex instance_dict_index;
247             instance_dict_index.type = InstantDictType_LOCAL;
248             instance_dict_index.index = iLib;
249             oStarDict->oLibs->query_dictmask.push_back(instance_dict_index);
250         }
251     }
252
253     if (oStarDict->oLibs->iCurrentIndex)
254         g_free(oStarDict->oLibs->iCurrentIndex);
255     oStarDict->oLibs->iCurrentIndex =
256         (CurrentIndex *) g_malloc(sizeof(CurrentIndex) * oStarDict->oLibs->query_dictmask.size());
257
258     if (oStarDict->oLibs->query_dictmask.empty())
259         oStarDict->ShowNoDictionary(true);
260 }