Imported version 0.2-5
[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                                 mStarDict->oLibs->LookupWithFuzzy(sWord);
150                                 break;
151                         case qtREGEX:
152                                 g_debug ("REGEX");
153                                 mStarDict->oLibs->LookupWithRule(sWord);
154                                 break;
155                         case qtSIMPLE:
156                                 g_debug ("SIMPLE");
157                                 bFound = mStarDict->oLibs->SimpleLookup(sWord, mStarDict->oLibs->iCurrentIndex);
158                                 if (!bFound) {
159                                         const gchar *sugWord = mStarDict->oLibs->GetSuggestWord(sWord, mStarDict->oLibs->iCurrentIndex, mStarDict->oLibs->query_dictmask, 0);
160                                         if (sugWord) {
161                                                 gchar *sSugWord = g_strdup(sugWord);
162                                                 bFound = mStarDict->oLibs->SimpleLookup(sSugWord, mStarDict->oLibs->iCurrentIndex);
163                                                 g_free(sSugWord);
164                                         }
165                                 }
166                                 mStarDict->oLibs->ListWords(mStarDict->oLibs->iCurrentIndex);
167                                 break;
168                         case qtDATA:
169                                 g_debug ("DATA");
170 //                              oLibs->LookupData(query, res_list);
171                                 break;
172                         default:
173                                 g_debug ("DEFAULT");
174                                 /*nothing*/;
175                         }
176
177                 /* unselect selected rows */
178                 gtk_tree_selection_unselect_all (selection);
179                 gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
180
181                 gtk_widget_hide (mStarDict->label_widget);
182                 gtk_widget_show (mStarDict->results_widget);
183         }
184
185         return TRUE;
186 }
187
188 class GetAllDictList {
189 public:
190         GetAllDictList(std::list<std::string> &dict_all_list_) :
191                                         dict_all_list(dict_all_list_) {}
192         void operator()(const std::string& url, bool disable) {
193                 dict_all_list.push_back(url);
194         }
195 private:
196         std::list<std::string> &dict_all_list;
197 };
198
199 void
200 MStarDict::LoadDictionaries ()
201 {
202         strlist_t dicts_dir_list;
203         strlist_t order_list;
204         strlist_t disable_list;
205
206         std::list<std::string> load_list;
207
208         /* dictionary directory */
209         dicts_dir_list.push_back (std::string ("/home/user/MyDocs/mstardict"));
210
211         for_each_file(dicts_dir_list, ".ifo", order_list, disable_list, GetAllDictList(load_list));
212         oLibs->load(load_list);
213
214         oLibs->query_dictmask.clear();
215         for (std::list<std::string>::iterator i = load_list.begin(); i != load_list.end(); ++i) {
216                 size_t iLib;
217                 if (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                         oLibs->query_dictmask.push_back(instance_dict_index);
222                 }
223         }
224
225         if (oLibs->iCurrentIndex)
226                 g_free (oLibs->iCurrentIndex);
227         oLibs->iCurrentIndex = (CurrentIndex *)g_malloc(sizeof(CurrentIndex) * oLibs->query_dictmask.size());
228
229 }
230
231 void
232 MStarDict::CreateTranslationWindow (const gchar *bookname,
233                                       const gchar *def,
234                                       const gchar *exp)
235 {
236         GtkWidget *window, *alignment, *pannable, *vbox, *label;
237
238         window = hildon_stackable_window_new ();
239         gtk_window_set_title (GTK_WINDOW (window), _("Translation"));
240
241         alignment = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
242         gtk_alignment_set_padding (GTK_ALIGNMENT (alignment),
243                                    HILDON_MARGIN_DEFAULT,
244                                    HILDON_MARGIN_DEFAULT,
245                                    HILDON_MARGIN_DOUBLE,
246                                    HILDON_MARGIN_DEFAULT);
247         gtk_container_add (GTK_CONTAINER (window), alignment);
248
249         pannable = hildon_pannable_area_new ();
250         g_object_set (G_OBJECT (pannable), "mov-mode", HILDON_MOVEMENT_MODE_BOTH,
251                       NULL);
252         gtk_container_add (GTK_CONTAINER (alignment), pannable);
253
254         vbox = gtk_vbox_new (FALSE, 0);
255         hildon_pannable_area_add_with_viewport (HILDON_PANNABLE_AREA (pannable),
256                                                 vbox);
257
258         label = gtk_label_new ("Bookname");
259         gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
260         gtk_label_set_markup (GTK_LABEL (label), bookname);
261         gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
262
263         label = gtk_label_new ("Definition");
264         gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
265         gtk_label_set_markup (GTK_LABEL (label), def);
266         gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
267
268         label = gtk_label_new ("Expresion");
269         gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0);
270         gtk_label_set_markup (GTK_LABEL (label), exp);
271         gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
272
273         gtk_widget_show_all (window);
274 }
275
276 void
277 MStarDict::CreateMainWindow ()
278 {
279         HildonProgram *program = NULL;
280         GtkWidget *window, *alignment, *vbox;
281         GtkCellRenderer *renderer;
282         GtkTreeSelection *selection;
283
284         /* hildon program */
285         program = hildon_program_get_instance ();
286         g_set_application_name (_("MStardict"));
287
288         /* main window */
289         window = hildon_stackable_window_new ();
290         hildon_program_add_window (program, HILDON_WINDOW (window));
291
292         /* aligment */
293         alignment = gtk_alignment_new (0.5, 0.5, 1.0, 1.0);
294         gtk_alignment_set_padding (GTK_ALIGNMENT (alignment),
295                                    HILDON_MARGIN_HALF,
296                                    0,
297                                    HILDON_MARGIN_DEFAULT,
298                                    HILDON_MARGIN_DEFAULT);
299         gtk_container_add (GTK_CONTAINER (window), alignment);
300
301         /* main vbox */
302         vbox = gtk_vbox_new (FALSE, 0);
303         gtk_container_add (GTK_CONTAINER (alignment), vbox);
304
305         /* no_search_result label */
306         label_widget = gtk_label_new (_("No search result"));
307         hildon_helper_set_logical_color (label_widget, GTK_RC_FG, 
308                                          GTK_STATE_NORMAL, "SecondaryTextColor");
309         hildon_helper_set_logical_font (label_widget, "LargeSystemFont");
310         gtk_box_pack_start (GTK_BOX (vbox), label_widget, TRUE, TRUE, 0);
311
312         /* alignment for pannable area */
313         results_widget = gtk_alignment_new (0.5, 0.5, 1.0, 1.0);
314         gtk_alignment_set_padding (GTK_ALIGNMENT (results_widget),
315                                    0,
316                                    0,
317                                    HILDON_MARGIN_DEFAULT,
318                                    HILDON_MARGIN_DEFAULT);
319         gtk_box_pack_start (GTK_BOX (vbox), results_widget, TRUE, TRUE, 0);
320
321         /* pannable for tree view */
322         results_view_scroll = hildon_pannable_area_new ();
323         gtk_container_add (GTK_CONTAINER (results_widget), results_view_scroll);
324
325         /* result tree view */
326         results_view = hildon_gtk_tree_view_new (HILDON_UI_MODE_EDIT);
327         gtk_tree_view_set_model (GTK_TREE_VIEW (results_view),
328                                  GTK_TREE_MODEL (results_list));
329         gtk_container_add (GTK_CONTAINER (results_view_scroll), results_view);
330
331         selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (results_view));
332         g_signal_connect (selection, "changed",
333                           G_CALLBACK (onResultsViewSelectionChanged), this);
334
335         /* def column */
336         renderer = gtk_cell_renderer_text_new ();
337         gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (results_view),
338                                                      -1,
339                                                      "Def", renderer,
340                                                      "text", DEF_COLUMN,
341                                                      NULL);
342         g_object_set (G_OBJECT (renderer), "xpad", 10, NULL);
343
344         /* search entry */
345         search = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT);
346         gtk_box_pack_end (GTK_BOX (vbox), search, FALSE, TRUE, 0);
347         g_signal_connect (search, "changed",
348                           G_CALLBACK (onSearchEntryChanged), this);
349
350         /* window signals */
351         g_signal_connect (G_OBJECT (window), "destroy",
352                           G_CALLBACK (gtk_main_quit), NULL);
353
354         /* show all widget instead of alignment */
355         gtk_widget_show_all (GTK_WIDGET (window));
356         gtk_widget_hide (results_widget);
357
358         /* grab focus to search entry */
359         gtk_widget_grab_focus (GTK_WIDGET (search));
360 }
361
362 void
363 MStarDict::ResultsListClear()
364 {
365         gtk_list_store_clear (results_list);
366 }
367
368 void
369 MStarDict::ResultsListInsertLast(const gchar *word)
370 {
371         GtkTreeIter iter;
372         gtk_list_store_append (results_list, &iter);
373         gtk_list_store_set (results_list, &iter, DEF_COLUMN, word, -1);
374 }
375
376 void
377 MStarDict::ReScroll()
378 {
379         hildon_pannable_area_scroll_to (HILDON_PANNABLE_AREA (results_view_scroll), -1, 0);
380 }
381
382 int
383 main (int argc, char **argv)
384 {
385         /* initialize hildon */
386         hildon_gtk_init (&argc, &argv);
387
388         /* initialize localization */
389         setlocale(LC_ALL, "");
390         bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
391         bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
392         textdomain(GETTEXT_PACKAGE);
393
394         /* create main window */
395         MStarDict mStarDict;
396         pMStarDict = &mStarDict;
397         mStarDict.CreateMainWindow();
398
399         /* load all dictionaries */
400         mStarDict.LoadDictionaries();
401
402         gtk_main ();
403         return 0;
404 }