fix bug's (translation color in stardict and kept settings after leave)
[mdictionary] / src / plugins / stardict / StarDictPlugin.cpp
1 /*******************************************************************************
2
3     This file is part of mDictionary.
4
5     mDictionary 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 3 of the License, or
8     (at your option) any later version.
9
10     mDictionary 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 mDictionary.  If not, see <http://www.gnu.org/licenses/>.
17
18     Copyright 2010 Comarch S.A.
19
20 *******************************************************************************/
21
22 /*! \file stardictplugin.cpp
23 */
24
25 #include "StarDictPlugin.h"
26
27 /**/
28 uint qHash(const TranslationStarDict &key) {
29    return qHash(key.key());
30 }
31
32
33 StarDictPlugin::StarDictPlugin(QObject *parent) : CommonDictInterface(parent),
34                     _langFrom(""), _langTo(""),_name(""), _infoNote("") {
35     _settings = new Settings();
36     _dictDialog = new StarDictDialog(this, this);
37
38     connect(_dictDialog, SIGNAL(notify(Notify::NotifyType,QString)),
39             this, SIGNAL(notify(Notify::NotifyType,QString)));
40
41     _settings->setValue("type","stardict");
42     _icon = QIcon("/usr/share/mdictionary/stardict.png");
43     stopped = false;
44
45     initAccents();
46 }
47
48
49 void StarDictPlugin::retranslate() {
50     QString locale = QLocale::system().name();
51     QTranslator *translator = new QTranslator(this);
52
53     if(!translator->load(":/stardict/translations/" + locale)) {
54         translator->load(":/stardicts/translations/en_US");
55     }
56     QCoreApplication::installTranslator(translator);
57 }
58
59
60 StarDictPlugin::~StarDictPlugin() {
61     delete _settings;
62     delete _dictDialog;
63 }
64
65
66 QString StarDictPlugin::langFrom() const {
67     return _langFrom;
68 }
69
70
71 QString StarDictPlugin::langTo() const {
72     return  _langTo;
73 }
74
75
76 QString StarDictPlugin::name() const {
77     return  _name;
78 }
79
80
81 QString StarDictPlugin::type() const {
82     return QString("stardict");
83 }
84
85
86 QString StarDictPlugin::infoNote() const {
87     return _name;
88 }
89
90
91 QList<Translation*> StarDictPlugin::searchWordList(QString word, int limit) {
92     QList<TranslationStarDict> translations;
93     bool is32b = false;
94     bool err = 0;
95     int wordcount = settings()->value("wordcount").toInt(&err);
96     int counter = 0;
97     int counterLimit = 0;
98     QString idxPath = settings()->value("idxFileName");
99     StarDictReader * reader = StarDictReaderFactory::createReader(idxPath);
100     QString fkey;
101     qint64 offset = 0, len = 0;
102     QRegExp keyword(word, Qt::CaseInsensitive, QRegExp::Wildcard);
103
104     if( word.indexOf("*")==-1 && word.indexOf("?")==-1 &&
105         word.indexOf("_")==-1 && word.indexOf("%")==-1)
106         word+="*";
107
108     if((settings()->value("idxoffsetbits") == "32") ||
109                          (settings()->value("idxoffsetbits") == ""))
110         is32b = true;
111
112     if(!err)
113         return QList<Translation*>();
114
115     stopped=false;
116     while(counter < wordcount && (counterLimit<limit || limit==0) && !stopped) {
117         counter++;
118         fkey = reader->readKeyword();
119         if(is32b)
120             offset = reader->readInt32BigEndian();
121         else
122             offset = reader->readInt64BigEndian();
123         len = reader->readInt32BigEndian();
124
125         if(keyword.exactMatch(fkey)) {
126             TranslationStarDict tran(fkey, infoNote(), this);
127             qDebug() << "off/len" << offset << len;
128             int id = translations.indexOf(tran);
129             if(id == -1) {
130                 tran.add(offset, len);
131                 translations.push_front(tran);
132             } else
133                 translations[id].add(offset, len);
134             counterLimit++;
135         }
136     }
137     QList<Translation*> ret;
138     QListIterator<TranslationStarDict> it(translations);
139     while(it.hasNext())
140         ret.push_back(new TranslationStarDict(it.next()));
141     return ret;
142 }
143
144
145 QByteArray StarDictPlugin::read(QByteArray::iterator it,
146         QByteArray::iterator end, int bytes) {
147     QByteArray ret;
148
149     if(bytes == 0 && it != end){
150         while(*it != '\0' && it != end)
151             ret.append(*it++);
152     }
153     else
154         for(int i = 0; i < bytes && it != end; i++)
155             ret.append(*it++);
156     return ret;
157 }
158
159
160 QString StarDictPlugin::interpret(QByteArray::iterator it,
161         QByteArray::iterator end, QChar mode,QString key, bool last) {
162     QString result;
163     qDebug()<<"****** mode:     "<<mode;
164
165     if(mode == 'm' ||
166             mode == 'l' ||
167             mode == 'g' ||
168             mode == 't' ||
169             mode == 'y' ||
170             mode == 'k' ||
171             mode == 'w' ||
172             mode == 'h' ||
173             mode == 'r' ){
174         result += "<key>" + key + "</key>";
175         result += "<t>" + QString::fromUtf8(read(it++, end)) + "</t>";
176     }
177
178     if(mode ==  'g'){
179         /* delete "small" tag  from g translation*/
180         int indexOfSmall=result.indexOf("<small>");
181         while(indexOfSmall!=-1){
182             int indexOfEndSmall= result.indexOf("</small>");
183             if(indexOfEndSmall!=-1)
184                 result.remove(indexOfSmall,indexOfEndSmall-indexOfSmall+8);
185             indexOfSmall=result.indexOf("<small>");
186         }
187     }
188     if(mode == 'x'){
189         result += QString::fromUtf8(read(it++, end));
190         result.replace("</k>","</key><t>");
191         result.replace("<k>","</t><key>");
192         int pos=result.indexOf("</t>");
193         if(pos!=-1)
194             result.remove(pos,4);
195         if(result.contains("<t>"))
196             result+="</t>";
197     }
198
199 // Dont know whether mDictionary would ever handle binary stardict format
200 // to be honest dont see any kind of adventages (can't find any binary dict)
201  /*
202     }
203     else if(mode == 'W') {
204         result += "<key>" + key + "</key>";
205         if(!last) {
206             QByteArray tmp ;
207             tmp.append(*(it++));
208             tmp.append(*(it++));
209             tmp.append(*(it++));
210             tmp.append(*(it));
211             result += read(it++, end, (qint32)qFromBigEndian(*(qint32*)tmp.data()));
212         } else
213             result += read(it++, end);
214     } else if(mode == 'P') {
215         result += "<key>" + key + "</key>";
216         if(!last) {
217             QByteArray tmp ;
218             tmp.append(*(it++));
219             tmp.append(*(it++));
220             tmp.append(*(it++));
221             tmp.append(*(it));
222             result += read(it++, end, (qint32)qFromBigEndian(*(qint32*)tmp.data()));
223         } else
224             result += read(it++, end);
225     } */
226
227     qDebug()<<"wynik  "<<result;
228     return result;
229 }
230
231
232 QString StarDictPlugin::format(QByteArray raw, QString mode,QString key) {
233     QString result;
234     if(mode == "") {
235         for(QByteArray::iterator it = raw.begin(); it != raw.end(); it++) {
236             char tmp = *(++it);
237             result += interpret(--it, raw.end(), tmp, key);
238         }
239     } else {
240         QByteArray::iterator it = raw.begin();
241         foreach(QChar tmp, mode) {
242             result += interpret(it, raw.end(), tmp, key);
243         }
244     }
245     return result;
246 }
247
248
249 QString StarDictPlugin::search(QString key, qint64 offset, qint32 len) {
250     QString dictPath = settings()->value("dictFileName");
251     StarDictReader *reader = StarDictReaderFactory::createReader(dictPath);
252     QByteArray raw = reader->readString(offset, len);
253     QString result= format(raw, settings()->value("sametypesequence"),key);
254
255     delete reader;
256     return result;
257 }
258
259
260 void StarDictPlugin::stop() {
261     stopped=true;
262 }
263
264
265 DictDialog* StarDictPlugin::dictDialog() {
266      return _dictDialog;
267 }
268
269
270 CommonDictInterface* StarDictPlugin::getNew(const Settings *settings) const {
271     StarDictPlugin *plugin = new StarDictPlugin();
272
273     connect(plugin, SIGNAL(notify(Notify::NotifyType,QString)),
274             this, SIGNAL(notify(Notify::NotifyType,QString)));
275
276     ((StarDictDialog*)plugin->dictDialog())->
277             setLastDialogParent(_dictDialog->lastDialogParent());
278
279     if(settings && plugin->setSettings(settings)) {
280         disconnect( plugin, SIGNAL(notify(Notify::NotifyType,QString)),
281                     this, SIGNAL(notify(Notify::NotifyType,QString)));
282         plugin->getDictionaryInfo();
283         return plugin;
284     }
285     else {
286         disconnect( plugin, SIGNAL(notify(Notify::NotifyType,QString)),
287                     this, SIGNAL(notify(Notify::NotifyType,QString)));
288         delete plugin;
289         return 0;
290     }
291 }
292
293
294 bool StarDictPlugin::isAvailable() const {
295     return true;
296 }
297
298
299 Settings* StarDictPlugin::settings() {
300     return _settings;
301 }
302
303
304 bool StarDictPlugin::setSettings(const Settings *sett) {
305     if(sett) {
306         foreach(QString key, sett->keys())
307             _settings->setValue(key, sett->value(key));
308
309     } else
310         return false;
311     Q_EMIT settingsChanged();
312     return true;
313 }
314
315
316 bool StarDictPlugin::getDictionaryInfo() {
317     QFile file(settings()->value("ifoFileName"));
318     if(!QFile::exists(_settings->value("ifoFileName"))
319                 || !file.open(QFile::ReadOnly | QFile::Text)) {
320         Q_EMIT notify(Notify::Warning,
321                QString(tr("StarDict dictionary cannot be read from file")));
322         qDebug()<<"Error: could not open the file";
323         return false;
324     }
325     QTextStream in(&file);
326     while (!in.atEnd()) {
327         QString line = in.readLine();
328         QStringList list = line.split("=");
329         if(list.size() == 2) {
330             settings()->setValue(list.at(0),list.at(1));
331         }
332     }
333     _name = settings()->value("bookname");
334     return true;
335 }
336
337
338 QIcon* StarDictPlugin::icon() {
339     return &_icon;
340 }
341
342
343 int StarDictPlugin::countWords() {
344     return 0;
345 }
346
347
348 void StarDictPlugin::clean() {
349
350 }
351
352
353 Q_EXPORT_PLUGIN2(stardict, StarDictPlugin)