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,
117 guint32 data_size, sec_size = 0;
119 const gchar *p = data;
120 data_size = *((guint32 *) p);
121 p += sizeof(guint32);
123 size_t nPlugins = pMStarDict->oStarDictPlugins->ParseDataPlugins.nplugins();
124 unsigned int parsed_size;
125 ParseResult parse_result;
127 while (guint32(p - data) < data_size) {
128 for (iPlugin = 0; iPlugin < nPlugins; iPlugin++) {
129 parse_result.clear();
130 if (pMStarDict->oStarDictPlugins->ParseDataPlugins.parse(iPlugin, p, &parsed_size, parse_result, oword)) {
135 if (iPlugin != nPlugins) {
136 for (std::list<ParseResultItem>::iterator it = parse_result.item_list.begin(); it != parse_result.item_list.end(); ++it) {
138 case ParseResultItemType_mark:
139 g_debug("ParseResultItemType_mark");
140 mark += it->mark->pango;
142 case ParseResultItemType_link:
143 // g_debug("ParseResultItemType_link: %s", it->mark->pango.c_str());
144 mark += it->mark->pango;
146 case ParseResultItemType_res:
148 g_debug("ParseResultItemType_res");
150 if (it->res->type == "image") {
151 } else if (it->res->type == "sound") {
152 } else if (it->res->type == "video") {
156 mark += "<span foreground=\"red\">";
157 gchar *m_str = g_markup_escape_text(it->res->key.c_str(), -1);
164 case ParseResultItemType_widget:
165 g_debug("ParseResultItemType_widget");
168 g_debug("ParseResultItemType_default");
172 parse_result.clear();
180 case 'l': //need more work...
181 sec_size = strlen(p);
184 m_str = g_strndup(p, sec_size);
191 sec_size = strlen(p);
194 m_str = g_strndup(p, sec_size);
195 mark += xdxf2text(m_str);
201 sec_size = strlen(p);
204 m_str = g_strndup(p, sec_size);
205 mark += "[" + string(m_str) + "]";
211 sec_size = strlen(p);
216 sec_size = *((guint32 *) p);
217 sec_size += sizeof(guint32);
227 Library::ListWords(CurrentIndex *iIndex)
229 CurrentIndex *iCurrent = (CurrentIndex *) g_memdup(iIndex,
230 sizeof(CurrentIndex) *
231 query_dictmask.size());
233 oStarDict->ResultsListClear();
236 const gchar *poCurrentWord = poGetCurrentWord(iIndex, query_dictmask, 0);
238 oStarDict->ResultsListInsertLast(poCurrentWord);
241 while (iWordCount < 30 && (poCurrentWord = poGetNextWord(NULL, iIndex, query_dictmask, 0))) {
242 oStarDict->ResultsListInsertLast(poCurrentWord);
246 oStarDict->ResultsReScroll();
253 Library::BuildResultData(std::vector < InstantDictIndex > &dictmask,
255 CurrentIndex *iIndex,
257 TSearchResultList &res_list)
260 bool bFound = false, bLookupWord = false, bLookupSynonymWord = false;
261 gint nWord = 0, count = 0, i = 0, j = 0;
264 iRealLib = dictmask[iLib].index;
266 bLookupWord = LookupWord(sWord, iIndex[iLib].idx, iIndex[iLib].idx_suggest, iRealLib, 0);
269 LookupSimilarWord(sWord, iIndex[iLib].idx, iIndex[iLib].idx_suggest, iRealLib, 0);
272 SimpleLookupWord(sWord, iIndex[iLib].idx, iIndex[iLib].idx_suggest, iRealLib, 0);
275 LookupSynonymWord(sWord, iIndex[iLib].synidx, iIndex[iLib].synidx_suggest, iRealLib, 0);
276 if (!bLookupSynonymWord)
278 LookupSynonymSimilarWord(sWord, iIndex[iLib].synidx,
279 iIndex[iLib].synidx_suggest, iRealLib, 0);
280 if (!bLookupSynonymWord)
282 SimpleLookupSynonymWord(sWord, iIndex[iLib].synidx,
283 iIndex[iLib].synidx_suggest, iRealLib, 0);
285 if (bLookupWord || bLookupSynonymWord) {
289 if (bLookupSynonymWord)
290 nWord += GetOrigWordCount(iIndex[iLib].synidx, iRealLib, false);
293 count = GetOrigWordCount(iIndex[iLib].idx, iRealLib, true);
294 for (i = 0; i < count; i++) {
295 res_list.push_back(TSearchResult(dict_name(iLib),
296 poGetOrigWord(iIndex[iLib].idx, iRealLib),
297 parse_data(poGetOrigWordData(iIndex[iLib].idx + i, iRealLib),
298 poGetOrigWord(iIndex[iLib].idx, iRealLib))));
304 for (j = 0; i < nWord; i++, j++) {
305 iWordIdx = poGetOrigSynonymWordIdx(iIndex[iLib].synidx + j, iRealLib);
306 res_list.push_back(TSearchResult(dict_name(iLib),
307 poGetOrigWord(iWordIdx, iRealLib),
308 parse_data(poGetOrigWordData(iWordIdx, iRealLib),
309 poGetOrigWord(iWordIdx, iRealLib))));
319 Library::SimpleLookup(const gchar *sWord,
320 CurrentIndex *piIndex)
322 CurrentIndex *iIndex;
323 TSearchResultList results;
327 iIndex = (CurrentIndex *) g_malloc(sizeof(CurrentIndex) * query_dictmask.size());
331 for (size_t iLib = 0; iLib < query_dictmask.size(); iLib++) {
332 if (BuildResultData(query_dictmask, sWord, iIndex, iLib, results))
343 Library::LookupWithFuzzy(const gchar *sWord)
345 static const int MAX_FUZZY_MATCH_ITEM = 100;
346 gchar *fuzzy_reslist[MAX_FUZZY_MATCH_ITEM];
349 oStarDict->ResultsListClear();
351 bFound = Libs::LookupWithFuzzy(sWord, fuzzy_reslist, MAX_FUZZY_MATCH_ITEM, query_dictmask);
353 SimpleLookup(fuzzy_reslist[0], iCurrentIndex);
355 for (int i = 0; i < MAX_FUZZY_MATCH_ITEM && fuzzy_reslist[i]; i++) {
356 oStarDict->ResultsListInsertLast(fuzzy_reslist[i]);
357 g_free(fuzzy_reslist[i]);
359 oStarDict->ResultsReScroll();
366 Library::LookupWithRule(const gchar *sWord)
368 gint iMatchCount = 0;
370 gchar **ppMatchWord =
371 (gchar **) g_malloc(sizeof(gchar *) * (MAX_MATCH_ITEM_PER_LIB) * query_dictmask.size());
373 oStarDict->ResultsListClear();
375 iMatchCount = Libs::LookupWithRule(sWord, ppMatchWord, query_dictmask);
377 for (gint i = 0; i < iMatchCount; i++)
378 oStarDict->ResultsListInsertLast(ppMatchWord[i]);
380 SimpleLookup(ppMatchWord[0], iCurrentIndex);
381 oStarDict->ResultsReScroll();
383 for (gint i = 0; i < iMatchCount; i++)
384 g_free(ppMatchWord[i]);
393 Library::LookupWithRegex(const gchar *sWord)
395 gint iMatchCount = 0;
397 gchar **ppMatchWord =
398 (gchar **) g_malloc(sizeof(gchar *) * (MAX_MATCH_ITEM_PER_LIB) * query_dictmask.size());
400 oStarDict->ResultsListClear();
402 iMatchCount = Libs::LookupWithRegex(sWord, ppMatchWord, query_dictmask);
404 for (gint i = 0; i < iMatchCount; i++)
405 oStarDict->ResultsListInsertLast(ppMatchWord[i]);
407 SimpleLookup(ppMatchWord[0], iCurrentIndex);
408 oStarDict->ResultsReScroll();
410 for (gint i = 0; i < iMatchCount; i++)
411 g_free(ppMatchWord[i]);
420 LookupProgressDialogUpdate(gpointer data,
423 GtkWidget *dialog = GTK_WIDGET(data);
426 progress = GTK_WIDGET(g_object_get_data(G_OBJECT(dialog), "progress_bar"));
427 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progress), fraction);
429 while (gtk_events_pending())
430 gtk_main_iteration();
434 Library::LookupData(const gchar *sWord)
440 std::vector < std::vector < gchar * > > reslist(query_dictmask.size());
443 oStarDict->ResultsListClear();
444 oStarDict->ShowProgressIndicator(true);
445 dialog = oStarDict->CreateLookupProgressDialog(&cancel);
447 bFound = Libs::LookupData(sWord, &reslist[0], LookupProgressDialogUpdate, (gpointer) dialog, &cancel, query_dictmask);
449 for (size_t iLib = 0; iLib < query_dictmask.size(); iLib++) {
450 if (!reslist[iLib].empty()) {
451 SimpleLookup(reslist[iLib][0], iCurrentIndex);
453 for (std::vector < gchar *>::iterator i = reslist[iLib].begin();
454 i != reslist[iLib].end(); ++i) {
455 oStarDict->ResultsListInsertLast(*i);
460 oStarDict->ResultsReScroll();
462 oStarDict->ShowProgressIndicator(false);
463 oStarDict->DestroyLookupProgressDialog(dialog);
467 Library::Library(MStarDict *mStarDict):Libs(NULL, FALSE, 0, 0)
469 oStarDict = mStarDict;
470 iCurrentIndex = NULL;
476 g_free(iCurrentIndex);