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