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
30 #include <glib/gi18n.h>
33 #include "libwrapper.hpp"
34 #include "mstardict.hpp"
37 std::string xdxf2text(const char *p)
42 if (g_str_has_prefix(p, ">")) {
45 } else if (g_str_has_prefix(p, "<")) {
48 } else if (g_str_has_prefix(p, "&")) {
51 } else if (g_str_has_prefix(p, """)) {
59 const char *next = strchr(p, '>');
63 std::string name(p + 1, next - p - 1);
67 else if (name == "/abr")
69 else if (name == "k") {
70 const char *begin = next;
71 if ((next = strstr(begin, "</k>")) != NULL)
72 next += sizeof("</k>") - 1 - 1;
75 } else if (name == "b")
77 else if (name == "/b")
81 else if (name == "/i")
83 else if (name == "tr")
85 else if (name == "/tr")
87 else if (name == "ex")
89 else if (name == "/ex")
91 else if (!name.empty() && name[0] == 'c' && name != "co") {
92 std::string::size_type pos = name.find("code");
93 if (pos != std::string::size_type(-1)) {
94 pos += sizeof("code=\"") - 1;
95 std::string::size_type end_pos = name.find("\"");
96 std::string color(name, pos, end_pos - pos);
101 } else if (name == "/c")
110 string parse_data(const gchar *data)
116 guint32 data_size, sec_size = 0;
118 const gchar *p = data;
119 data_size = *((guint32 *) p);
120 p += sizeof(guint32);
121 while (guint32(p - data) < data_size) {
125 case 'l': //need more work...
126 sec_size = strlen(p);
129 m_str = g_strndup(p, sec_size);
136 sec_size = strlen(p);
139 m_str = g_strndup(p, sec_size);
140 res += xdxf2text(m_str);
146 sec_size = strlen(p);
149 m_str = g_strndup(p, sec_size);
150 res += "[" + string(m_str) + "]";
156 sec_size = strlen(p);
161 sec_size = *((guint32 *) p);
162 sec_size += sizeof(guint32);
172 Library::ListWords(CurrentIndex *iIndex)
174 CurrentIndex *iCurrent = (CurrentIndex *) g_memdup(iIndex,
175 sizeof(CurrentIndex) *
176 query_dictmask.size());
178 oStarDict->ResultsListClear();
181 const gchar *poCurrentWord = poGetCurrentWord(iIndex, query_dictmask, 0);
183 oStarDict->ResultsListInsertLast(poCurrentWord);
186 while (iWordCount < 30 && (poCurrentWord = poGetNextWord(NULL, iIndex, query_dictmask, 0))) {
187 oStarDict->ResultsListInsertLast(poCurrentWord);
191 oStarDict->ResultsReScroll();
198 Library::BuildResultData(std::vector < InstantDictIndex > &dictmask,
200 CurrentIndex *iIndex,
202 TSearchResultList &res_list)
205 bool bFound = false, bLookupWord = false, bLookupSynonymWord = false;
206 gint nWord = 0, count = 0, i = 0, j = 0;
208 iRealLib = dictmask[iLib].index;
210 bLookupWord = LookupWord(sWord, iIndex[iLib].idx, iIndex[iLib].idx_suggest, iRealLib, 0);
213 LookupSimilarWord(sWord, iIndex[iLib].idx, iIndex[iLib].idx_suggest, iRealLib, 0);
216 SimpleLookupWord(sWord, iIndex[iLib].idx, iIndex[iLib].idx_suggest, iRealLib, 0);
219 LookupSynonymWord(sWord, iIndex[iLib].synidx, iIndex[iLib].synidx_suggest, iRealLib, 0);
220 if (!bLookupSynonymWord)
222 LookupSynonymSimilarWord(sWord, iIndex[iLib].synidx,
223 iIndex[iLib].synidx_suggest, iRealLib, 0);
224 if (!bLookupSynonymWord)
226 SimpleLookupSynonymWord(sWord, iIndex[iLib].synidx,
227 iIndex[iLib].synidx_suggest, iRealLib, 0);
229 if (bLookupWord || bLookupSynonymWord) {
233 if (bLookupSynonymWord)
234 nWord += GetOrigWordCount(iIndex[iLib].synidx, iRealLib, false);
237 count = GetOrigWordCount(iIndex[iLib].idx, iRealLib, true);
238 for (i = 0; i < count; i++) {
239 res_list.push_back(TSearchResult(dict_name(iLib),
240 poGetWord(iIndex[iLib].idx, iRealLib,
244 (iIndex[iLib].idx + i, iRealLib))));
250 for (j = 0; i < nWord; i++, j++) {
251 res_list.push_back(TSearchResult(dict_name(iLib),
252 poGetWord(iIndex[iLib].synidx + j,
254 parse_data(poGetOrigWordData
255 (iIndex[iLib].synidx + j, iRealLib))));
265 Library::SimpleLookup(const gchar *sWord,
266 CurrentIndex *piIndex)
268 CurrentIndex *iIndex;
269 TSearchResultList results;
273 iIndex = (CurrentIndex *) g_malloc(sizeof(CurrentIndex) * query_dictmask.size());
277 for (size_t iLib = 0; iLib < query_dictmask.size(); iLib++) {
278 if (BuildResultData(query_dictmask, sWord, iIndex, iLib, results))
289 Library::LookupWithFuzzy(const gchar *sWord)
291 static const int MAX_FUZZY_MATCH_ITEM = 100;
292 gchar *fuzzy_reslist[MAX_FUZZY_MATCH_ITEM];
295 oStarDict->ResultsListClear();
297 bFound = Libs::LookupWithFuzzy(sWord, fuzzy_reslist, MAX_FUZZY_MATCH_ITEM, query_dictmask);
299 SimpleLookup(fuzzy_reslist[0], iCurrentIndex);
301 for (int i = 0; i < MAX_FUZZY_MATCH_ITEM && fuzzy_reslist[i]; i++) {
302 oStarDict->ResultsListInsertLast(fuzzy_reslist[i]);
303 g_free(fuzzy_reslist[i]);
305 oStarDict->ResultsReScroll();
312 Library::LookupWithRule(const gchar *sWord)
314 gint iMatchCount = 0;
316 gchar **ppMatchWord =
317 (gchar **) g_malloc(sizeof(gchar *) * (MAX_MATCH_ITEM_PER_LIB) * query_dictmask.size());
319 oStarDict->ResultsListClear();
321 iMatchCount = Libs::LookupWithRule(sWord, ppMatchWord, query_dictmask);
323 for (gint i = 0; i < iMatchCount; i++)
324 oStarDict->ResultsListInsertLast(ppMatchWord[i]);
326 SimpleLookup(ppMatchWord[0], iCurrentIndex);
327 oStarDict->ResultsReScroll();
329 for (gint i = 0; i < iMatchCount; i++)
330 g_free(ppMatchWord[i]);
339 Library::LookupWithRegex(const gchar *sWord)
341 gint iMatchCount = 0;
343 gchar **ppMatchWord =
344 (gchar **) g_malloc(sizeof(gchar *) * (MAX_MATCH_ITEM_PER_LIB) * query_dictmask.size());
346 oStarDict->ResultsListClear();
348 iMatchCount = Libs::LookupWithRegex(sWord, ppMatchWord, query_dictmask);
350 for (gint i = 0; i < iMatchCount; i++)
351 oStarDict->ResultsListInsertLast(ppMatchWord[i]);
353 SimpleLookup(ppMatchWord[0], iCurrentIndex);
354 oStarDict->ResultsReScroll();
356 for (gint i = 0; i < iMatchCount; i++)
357 g_free(ppMatchWord[i]);
366 LookupProgressDialogUpdate(gpointer data,
369 GtkWidget *dialog = GTK_WIDGET(data);
372 progress = GTK_WIDGET(g_object_get_data(G_OBJECT(dialog), "progress"));
373 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progress), fraction);
375 while (gtk_events_pending())
376 gtk_main_iteration();
380 Library::LookupData(const gchar *sWord)
386 std::vector < std::vector < gchar * > > reslist(query_dictmask.size());
389 oStarDict->ResultsListClear();
390 oStarDict->ShowProgressIndicator(true);
391 dialog = oStarDict->CreateLookupProgressDialog(&cancel);
393 bFound = Libs::LookupData(sWord, &reslist[0], LookupProgressDialogUpdate, (gpointer) dialog, &cancel, query_dictmask);
395 for (size_t iLib = 0; iLib < query_dictmask.size(); iLib++) {
396 if (!reslist[iLib].empty()) {
397 SimpleLookup(reslist[iLib][0], iCurrentIndex);
399 for (std::vector < gchar *>::iterator i = reslist[iLib].begin();
400 i != reslist[iLib].end(); ++i) {
401 oStarDict->ResultsListInsertLast(*i);
406 oStarDict->ResultsReScroll();
408 oStarDict->ShowProgressIndicator(false);
409 oStarDict->DestroyLookupProgressDialog(dialog);
413 Library::Library(MStarDict *mStarDict):Libs(NULL, FALSE, 0, 0)
415 oStarDict = mStarDict;
416 iCurrentIndex = NULL;
422 g_free(iCurrentIndex);