9a0d964341261024ff00ba469d9f6acd7850bad2
[mstardict] / src / mstardict.cpp
1 /*
2  *  MStarDict - International dictionary for Maemo.
3  *  Copyright (C) 2010 Roman Moravcik
4  *  
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2 of the License, or
8  *  (at your option) any later version.
9  *  
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *  
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program; if not, write to the Free Software
17  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #  include "config.h"
22 #endif
23
24 #include <cerrno>
25 #include <cstring>
26 #include <cstdlib>
27 #include <cstdio>
28 #include <clocale>
29
30 #include <glib.h>
31 #include <glib/gi18n.h>
32 #include <glib/gstdio.h>
33
34 #include <gtk/gtk.h>
35 #include <hildon/hildon.h>
36
37 #include <getopt.h>
38 #include <string>
39 #include <vector>
40 #include <memory>
41
42 #include "libwrapper.hpp"
43 #include "file.hpp"
44 #include "mstardict.hpp"
45
46 MStarDict *pMStarDict;
47
48 enum {
49         DEF_COLUMN,
50         N_COLUMNS
51 };
52
53 MStarDict::MStarDict ()
54 {
55         label_widget = NULL;
56         results_widget = NULL;
57         results_view = NULL;
58         results_view_scroll = NULL;
59
60         /* create list of ressults */
61         results_list = gtk_list_store_new (N_COLUMNS,
62                                            G_TYPE_STRING);      /* DEF_COLUMN */
63
64         /* initialize stardict library */
65         oLibs = new Library ();
66 }
67
68 MStarDict::~MStarDict ()
69 {
70         /* destroy list of results */
71         g_object_unref (results_list);
72
73         /* deinitialize stardict library */
74         delete oLibs;
75 }
76
77 gboolean
78 MStarDict::onResultsViewSelectionChanged (GtkTreeSelection *selection,
79                                               MStarDict *mStarDict)
80 {
81         GtkTreeModel *model;
82         GtkTreeIter iter;
83         char *bookname, *def, *exp;
84         const gchar *sWord;
85         bool bFound = false;
86
87         if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
88                 /* unselect selected rows */
89                 gtk_tree_selection_unselect_all (selection);
90
91                 gtk_tree_model_get (model, &iter, DEF_COLUMN, &sWord, -1);
92
93                 /* clear previous search results */
94                 mStarDict->results.clear();
95
96                 for (size_t iLib=0; iLib<mStarDict->oLibs->query_dictmask.size(); iLib++) {
97                         bFound = mStarDict->oLibs->BuildResultData(mStarDict->oLibs->query_dictmask,
98                                                                    sWord,
99                                                                    mStarDict->oLibs->iCurrentIndex,
100                                                                    iLib,
101                                                                    mStarDict->results);
102                 }
103
104                 bookname = g_markup_printf_escaped ("<span color=\"dimgray\" size=\"x-small\">%s</span>",
105                                                     mStarDict->results[0].bookname.c_str());
106                 def = g_markup_printf_escaped ("<span color=\"darkred\" weight=\"heavy\" size=\"large\">%s</span>",
107                                                mStarDict->results[0].def.c_str());
108                 exp = g_strdup (mStarDict->results[0].exp.c_str());
109
110                 /* create translation window */
111                 mStarDict->CreateTranslationWindow (bookname, def, exp);
112
113                 g_free (bookname);
114                 g_free (def);
115                 g_free (exp);
116         }
117
118         /* grab focus to search entry */
119         gtk_widget_grab_focus (GTK_WIDGET (mStarDict->search));
120
121         return TRUE;
122 }
123
124 gboolean
125 MStarDict::onSearchEntryChanged (GtkEditable *editable,
126                                     MStarDict *mStarDict)
127 {
128         GtkTreeSelection *selection;
129         const gchar *sWord;
130         bool bFound = false;
131         std::string query;
132
133         sWord = gtk_entry_get_text (GTK_ENTRY (editable));
134
135         if (strcmp (sWord, "") == 0) {
136                 gtk_widget_show (mStarDict->label_widget);
137                 gtk_widget_hide (mStarDict->results_widget);
138         } else {
139                 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (mStarDict->results_view));
140                 gtk_tree_selection_set_mode (selection, GTK_SELECTION_NONE);
141
142                 /* unselect rows */
143                 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (mStarDict->results_view));
144                 gtk_tree_selection_unselect_all (selection);
145
146                 switch (analyse_query(sWord, query)) {
147                         case qtFUZZY:
148                                 g_debug ("FUZZY");
149 //                              oLibs->LookupWithFuzzy(query, res_list);
150                                 break;
151                         case qtREGEX:
152                                 g_debug ("REGEX");
153 //                              oLibs->LookupWithRule(query, res_list);
154                                 break;
155                         case qtSIMPLE:
156                                 g_debug ("SIMPLE");
157                                 bFound = mStarDict->oLibs->SimpleLookup(sWord, mStarDict->oLibs->iCurrentIndex);
158                                 if (!bFound) {
159                                         /* suggested */
160                                 }
161                                 mStarDict->oLibs->ListWords(mStarDict->oLibs->iCurrentIndex);
162                                 break;
163                         case qtDATA:
164                                 g_debug ("DATA");
165 //                              oLibs->LookupData(query, res_list);
166                                 break;
167                         default:
168                                 g_debug ("DEFAULT");
169                                 /*nothing*/;
170                         }
171
172                 /* unselect selected rows */
173                 gtk_tree_selection_unselect_all (selection);
174                 gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
175
176                 gtk_widget_hide (mStarDict->label_widget);
177                 gtk_widget_show (mStarDict->results_widget);
178         }
179
180         return TRUE;
181 }
182
183 class GetAllDictList {
184 public:
185         GetAllDictList(std::list<std::string> &dict_all_list_) :
186                                         dict_all_list(dict_all_list_) {}
187         void operator()(const std::string& url, bool disable) {
188                 dict_all_list.push_back(url);
189         }
190 private:
191         std::list<std::string> &dict_all_list;
192 };
193
194 void
195 MStarDict::LoadDictionaries ()
196 {
197         strlist_t dicts_dir_list;
198         strlist_t order_list;
199         strlist_t disable_list;
200
201         std::list<std::string> load_list;
202
203         /* dictionary directory */
204         dicts_dir_list.push_back (std::string ("/home/user/MyDocs/mstardict"));
205
206         for_each_file(dicts_dir_list, ".ifo", order_list, disable_list, GetAllDictList(load_list));
207         oLibs->load(load_list);
208
209         oLibs->query_dictmask.clear();
210         for (std::list<std::string>::iterator i = load_list.begin(); i != load_list.end(); ++i) {
211                 size_t iLib;
212                 if (oLibs->find_lib_by_filename(i->c_str(), iLib)) {
213                         InstantDictIndex instance_dict_index;
214                         instance_dict_index.type = InstantDictType_LOCAL;
215                         instance_dict_index.index = iLib;
216                         oLibs->query_dictmask.push_back(instance_dict_index);
217                 }
218         }
219
220         if (oLibs->iCurrentIndex)
221                 g_free (oLibs->iCurrentIndex);
222         oLibs->iCurrentIndex = (CurrentIndex *)g_malloc(sizeof(CurrentIndex) * oLibs->query_dictmask.size());
223
224 }
225
226 void
227 MStarDict::CreateTranslationWindow (const gchar *bookname,
228                                       const gchar *def,
229                                       const gchar *exp)
230 {
231         GtkWidget *window, *alignment, *pannable, *vbox, *label;
232
233         window = hildon_stackable_window_new ();
234         gtk_window_set_title (GTK_WINDOW (window), _("Translation"));
235
236         alignment = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
237         gtk_alignment_set_padding (GTK_ALIGNMENT (alignment),
238                                    HILDON_MARGIN_DEFAULT,
239                                    HILDON_MARGIN_DEFAULT,
240                                    HILDON_MARGIN_DOUBLE,
241                                    HILDON_MARGIN_DEFAULT);
242         gtk_container_add (GTK_CONTAINER (window), alignment);
243
244         pannable = hildon_pannable_area_new ();
245         g_object_set (G_OBJECT (pannable), "mov-mode", HILDON_MOVEMENT_MODE_BOTH,
246                       NULL);
247         gtk_container_add (GTK_CONTAINER (alignment), pannable);
248
249         vbox = gtk_vbox_new (FALSE, 0);
250         hildon_pannable_area_add_with_viewport (HILDON_PANNABLE_AREA (pannable),
251                                                 vbox);
252
253         label = gtk_label_new ("Bookname");
254         gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
255         gtk_label_set_markup (GTK_LABEL (label), bookname);
256         gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
257
258         label = gtk_label_new ("Definition");
259         gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
260         gtk_label_set_markup (GTK_LABEL (label), def);
261         gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
262
263         label = gtk_label_new ("Expresion");
264         gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0);
265         gtk_label_set_markup (GTK_LABEL (label), exp);
266         gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
267
268         gtk_widget_show_all (window);
269 }
270
271 void
272 MStarDict::CreateMainWindow ()
273 {
274         HildonProgram *program = NULL;
275         GtkWidget *window, *alignment, *vbox;
276         GtkCellRenderer *renderer;
277         GtkTreeSelection *selection;
278
279         /* hildon program */
280         program = hildon_program_get_instance ();
281         g_set_application_name (_("MStardict"));
282
283         /* main window */
284         window = hildon_stackable_window_new ();
285         hildon_program_add_window (program, HILDON_WINDOW (window));
286
287         /* aligment */
288         alignment = gtk_alignment_new (0.5, 0.5, 1.0, 1.0);
289         gtk_alignment_set_padding (GTK_ALIGNMENT (alignment),
290                                    HILDON_MARGIN_HALF,
291                                    0,
292                                    HILDON_MARGIN_DEFAULT,
293                                    HILDON_MARGIN_DEFAULT);
294         gtk_container_add (GTK_CONTAINER (window), alignment);
295
296         /* main vbox */
297         vbox = gtk_vbox_new (FALSE, 0);
298         gtk_container_add (GTK_CONTAINER (alignment), vbox);
299
300         /* no_search_result label */
301         label_widget = gtk_label_new (_("No search result"));
302         hildon_helper_set_logical_color (label_widget, GTK_RC_FG, 
303                                          GTK_STATE_NORMAL, "SecondaryTextColor");
304         hildon_helper_set_logical_font (label_widget, "LargeSystemFont");
305         gtk_box_pack_start (GTK_BOX (vbox), label_widget, TRUE, TRUE, 0);
306
307         /* alignment for pannable area */
308         results_widget = gtk_alignment_new (0.5, 0.5, 1.0, 1.0);
309         gtk_alignment_set_padding (GTK_ALIGNMENT (results_widget),
310                                    0,
311                                    0,
312                                    HILDON_MARGIN_DEFAULT,
313                                    HILDON_MARGIN_DEFAULT);
314         gtk_box_pack_start (GTK_BOX (vbox), results_widget, TRUE, TRUE, 0);
315
316         /* pannable for tree view */
317         results_view_scroll = hildon_pannable_area_new ();
318         gtk_container_add (GTK_CONTAINER (results_widget), results_view_scroll);
319
320         /* result tree view */
321         results_view = hildon_gtk_tree_view_new (HILDON_UI_MODE_EDIT);
322         gtk_tree_view_set_model (GTK_TREE_VIEW (results_view),
323                                  GTK_TREE_MODEL (results_list));
324         gtk_container_add (GTK_CONTAINER (results_view_scroll), results_view);
325
326         selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (results_view));
327         g_signal_connect (selection, "changed",
328                           G_CALLBACK (onResultsViewSelectionChanged), this);
329
330         /* def column */
331         renderer = gtk_cell_renderer_text_new ();
332         gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (results_view),
333                                                      -1,
334                                                      "Def", renderer,
335                                                      "text", DEF_COLUMN,
336                                                      NULL);
337         g_object_set (G_OBJECT (renderer), "xpad", 10, NULL);
338
339         /* search entry */
340         search = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT);
341         gtk_box_pack_end (GTK_BOX (vbox), search, FALSE, TRUE, 0);
342         g_signal_connect (search, "changed",
343                           G_CALLBACK (onSearchEntryChanged), this);
344
345         /* window signals */
346         g_signal_connect (G_OBJECT (window), "destroy",
347                           G_CALLBACK (gtk_main_quit), NULL);
348
349         /* show all widget instead of alignment */
350         gtk_widget_show_all (GTK_WIDGET (window));
351         gtk_widget_hide (results_widget);
352
353         /* grab focus to search entry */
354         gtk_widget_grab_focus (GTK_WIDGET (search));
355 }
356
357 void
358 MStarDict::ResultsListClear()
359 {
360         gtk_list_store_clear (results_list);
361 }
362
363 void
364 MStarDict::ResultsListInsertLast(const gchar *word)
365 {
366         GtkTreeIter iter;
367         gtk_list_store_append (results_list, &iter);
368         gtk_list_store_set (results_list, &iter, DEF_COLUMN, word, -1);
369 }
370
371 void
372 MStarDict::ReScroll()
373 {
374         hildon_pannable_area_scroll_to (HILDON_PANNABLE_AREA (results_view_scroll), -1, 0);
375 }
376
377 int
378 main (int argc, char **argv)
379 {
380         /* initialize hildon */
381         hildon_gtk_init (&argc, &argv);
382
383         /* initialize localization */
384         setlocale(LC_ALL, "");
385         bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
386         bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
387         textdomain(GETTEXT_PACKAGE);
388
389         /* create main window */
390         MStarDict mStarDict;
391         pMStarDict = &mStarDict;
392         mStarDict.CreateMainWindow();
393
394         /* load all dictionaries */
395         mStarDict.LoadDictionaries();
396
397         gtk_main ();
398         return 0;
399 }