Make program compilable
[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 xdxfplugin.cpp
23 \author Jakub Jaszczynski <j.j.jaszczynski@gmail.com>
24 */
25
26 #include "StarDictPlugin.h"
27 #include <QDebug>
28 #include "../../include/Notify.h"
29 #include <QTranslator>
30 #include <QCoreApplication>
31 #include <QThread>
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
42     _settings->setValue("type","xdxf");
43     _icon = QIcon("/usr/share/mdictionary/xdxf.png");
44     _wordsCount = -1;
45     stopped = false;
46
47     initAccents();
48 }
49
50 void StarDictPlugin::retranslate() {
51     QString locale = QLocale::system().name();
52
53     QTranslator *translator = new QTranslator(this);
54
55     if(!translator->load(":/xdxf/translations/" + locale)) {
56         translator->load(":/xdxf/translations/en_US");
57     }
58     QCoreApplication::installTranslator(translator);
59 }
60
61
62 StarDictPlugin::~StarDictPlugin() {
63     delete _settings;
64     delete _dictDialog;
65 }
66
67
68 QString StarDictPlugin::langFrom() const {
69     return _langFrom;
70 }
71
72
73 QString StarDictPlugin::langTo() const {
74     return  _langTo;
75 }
76
77
78 QString StarDictPlugin::name() const {
79     return  _name;
80 }
81
82
83 QString StarDictPlugin::type() const {
84     return QString("stardict");
85 }
86
87
88 QString StarDictPlugin::infoNote() const {
89     return _infoNote;
90 }
91
92
93 QList<Translation*> StarDictPlugin::searchWordList(QString word, int limit) {
94     if( word.indexOf("*")==-1 && word.indexOf("?")==-1 &&
95         word.indexOf("_")==-1 && word.indexOf("%")==-1)
96         word+="*";
97
98     if(isCached())
99         return searchWordListCache(word,limit);
100     return searchWordListFile(word, limit);
101 }
102
103
104
105 QList<Translation*> StarDictPlugin::searchWordListFile(QString word, int limit) {
106     QSet<Translation*> translations;
107     QFile dictionaryFile(_settings->value("path"));
108     word = word.toLower();
109     stopped = false;
110
111     QRegExp regWord(word);
112     regWord.setCaseSensitivity(Qt::CaseInsensitive);
113     regWord.setPatternSyntax(QRegExp::Wildcard);
114
115     /*check xdxf file exist*/
116     if(!QFile::exists(_settings->value("path"))
117                 || !dictionaryFile.open(QFile::ReadOnly | QFile::Text)) {
118         qDebug()<<"Error: could not open file";
119         Q_EMIT notify(Notify::Warning,
120                 QString(tr("XDXF file cannot be read for %1").arg(name())));
121         return translations.toList();
122     }
123
124     QXmlStreamReader reader(&dictionaryFile);
125     QString readKey;
126     int i=0;
127
128     /*search words list*/
129     while(!reader.atEnd() && !stopped){
130         reader.readNextStartElement();
131         if(reader.name()=="ar") {
132             while(reader.name()!="k" && !reader.atEnd())
133                 reader.readNextStartElement();
134             if(!reader.atEnd())
135                 readKey = reader.readElementText();
136             if((regWord.exactMatch(readKey)
137                     || regWord.exactMatch(removeAccents(readKey)))
138                     && (i<limit || limit==0) && !reader.atEnd())  {
139  //               qDebug()<<readKey;
140                 translations<<(new TranslationStarDict(readKey.toLower(),
141                                _dictionaryInfo,this));
142                 if(translations.size()==limit && limit!=0)
143                     break;
144             }
145         }
146         this->thread()->yieldCurrentThread();
147     }
148     stopped=false;
149     dictionaryFile.close();
150     return translations.toList();
151 }
152
153
154 QString StarDictPlugin::search(QString key) {
155     return searchFile(key);
156 }
157
158
159
160 QString StarDictPlugin::searchFile(QString key) {
161     QFile dictionaryFile(_settings->value("path"));
162     QString resultString("");
163     key = key.toLower();
164
165     /*check xdxf file exist*/
166     if(!QFile::exists(_settings->value("path"))
167                 || !dictionaryFile.open(QFile::ReadOnly | QFile::Text)) {
168         Q_EMIT notify(Notify::Warning,
169                 QString(tr("XDXF file cannot be read for %1").arg(name())));
170         qDebug()<<"Error: could not open file";
171         return "";
172     }
173
174     QXmlStreamReader reader(&dictionaryFile);
175     QString readKey;
176     bool match =false;
177     stopped = false;
178
179     /*search translations for word*/
180     while (!reader.atEnd()&& !stopped) {
181         reader.readNext();
182         if(reader.tokenType() == QXmlStreamReader::StartElement) {
183             if(reader.name()=="k") {
184                 readKey = reader.readElementText();
185                 if(readKey.toLower()==key.toLower())
186                     match = true;
187             }
188         }
189         if(match) {
190             QString temp("");
191             while(reader.name()!="ar" && !reader.atEnd()) {
192                 if(reader.name()!="" && reader.name()!="k") {
193                     if(reader.tokenType()==QXmlStreamReader::EndElement)
194                         temp+="</";
195                     if(reader.tokenType()==QXmlStreamReader::StartElement)
196                         temp+="<";
197                     temp+=reader.name().toString();
198                     if(reader.name().toString()=="c" &&
199                             reader.tokenType()==QXmlStreamReader::StartElement)
200                        temp= temp + " c=\"" + reader.attributes().
201                                value("c").toString() + "\"";
202                     temp+=">";
203                 }
204                 temp+= reader.text().toString().replace("<","&lt;").
205                         replace(">","&gt;");
206                 reader.readNext();
207             }
208             if(temp.at(0)==QChar('\n'))
209                 temp.remove(0,1);
210             resultString+="<key>" + readKey +"</key>";
211             resultString+="<t>" + temp + "</t>";
212             match=false;
213         }
214         this->thread()->yieldCurrentThread();
215     }
216     stopped=false;
217     dictionaryFile.close();
218     return resultString;
219 }
220
221
222 void StarDictPlugin::stop() {
223    //qDebug()<<"stop";
224     stopped=true;
225 }
226
227
228 DictDialog* StarDictPlugin::dictDialog() {
229      return _dictDialog;
230 }
231
232
233 CommonDictInterface* StarDictPlugin::getNew(const Settings *settings) const {
234     StarDictPlugin *plugin = new StarDictPlugin();
235
236     connect(plugin, SIGNAL(notify(Notify::NotifyType,QString)),
237             this, SIGNAL(notify(Notify::NotifyType,QString)));
238
239     ((StarDictDialog*)plugin->dictDialog())->setLastDialogParent(_dictDialog->lastDialogParent());
240
241
242
243     if(settings && plugin->setSettings(settings)) {
244
245         disconnect(plugin, SIGNAL(notify(Notify::NotifyType,QString)),
246                 this, SIGNAL(notify(Notify::NotifyType,QString)));
247         return plugin;
248     }
249     else {
250         disconnect(plugin, SIGNAL(notify(Notify::NotifyType,QString)),
251                 this, SIGNAL(notify(Notify::NotifyType,QString)));
252         delete plugin;
253         return 0;
254     }
255 }
256
257
258 bool StarDictPlugin::isAvailable() const {
259     return true;
260 }
261
262
263 Settings* StarDictPlugin::settings() {
264     return _settings;
265 }
266
267
268 bool StarDictPlugin::isCached() {
269     if(_settings->value("cached") == "true")
270         return true;
271     return false;
272 }
273
274
275 bool StarDictPlugin::setSettings(const Settings *settings) {
276     if(settings) {
277         bool isPathChange=false;
278         QString oldPath = _settings->value("path");
279         Settings *oldSettings =  new Settings ;
280
281         if(oldPath != settings->value("path")) {
282             if(oldPath!="" && _settings->value("cache_path")!="")
283                 clean();
284             isPathChange=true;
285         }
286
287         foreach(QString key, _settings->keys())
288             oldSettings->setValue(key, _settings->value(key));
289
290         foreach(QString key, settings->keys()) {
291            if(key != "generateCache")
292                _settings->setValue(key, settings->value(key));
293         }
294
295         if(!getDictionaryInfo()) {
296             Q_EMIT notify(Notify::Warning,
297                 QString(tr("XDXF file is in wrong format")));
298             qDebug()<<"Error: xdxf file is in wrong format";
299             delete _settings;
300             _settings=oldSettings;
301             return false;
302         }
303
304         if(isPathChange) {
305             _wordsCount=0;
306             if(oldPath!="")
307                 _settings->setValue("cached","false");
308         }
309
310         if((_settings->value("cached") == "false" ||
311             _settings->value("cached").isEmpty()) &&
312             settings->value("generateCache") == "true") {
313             clean();
314         }
315
316         else if (settings->value("generateCache") == "false") {
317             _settings->setValue("cached", "false");
318         }
319     }
320     else
321         return false;
322     Q_EMIT settingsChanged();
323     return true;
324 }
325
326
327 bool StarDictPlugin::getDictionaryInfo() {
328     QFile dictionaryFile(_settings->value("path"));
329     if(!QFile::exists(_settings->value("path"))
330                 || !dictionaryFile.open(QFile::ReadOnly | QFile::Text)) {
331        Q_EMIT notify(Notify::Warning,
332                QString(tr("XDXF dictionary cannot be read from file")));
333         qDebug()<<"Error: could not open file";
334         return false;
335     }
336
337     bool okFormat=false;
338     QXmlStreamReader reader(&dictionaryFile);
339     reader.readNextStartElement();
340     if(reader.name()=="xdxf") {
341         okFormat=true;
342         if(reader.attributes().hasAttribute("lang_from"))
343             _langFrom = reader.attributes().value("lang_from").toString();
344         if(reader.attributes().hasAttribute("lang_to"))
345             _langTo = reader.attributes().value("lang_to").toString();
346     }
347     reader.readNextStartElement();
348     if(reader.name()=="full_name")
349         _name=reader.readElementText();
350     else
351         qDebug()<<"no full_name";
352     reader.readNextStartElement();
353     if(reader.name()=="description")
354         _infoNote=reader.readElementText();
355     else
356         qDebug()<<"no description";
357
358     _dictionaryInfo= _name + " [" + _langFrom + "-"
359                 + _langTo + "]";
360
361     dictionaryFile.close();
362     if(okFormat)
363         return true;
364     return false;
365 }
366
367
368 QIcon* StarDictPlugin::icon() {
369     return &_icon;
370 }
371
372
373 int StarDictPlugin::countWords() {
374     if(_wordsCount>0)
375         return _wordsCount;
376     QFile dictionaryFile(_settings->value("path"));
377     if(!QFile::exists(_settings->value("path"))
378                 || !dictionaryFile.open(QFile::ReadOnly | QFile::Text)) {
379         Q_EMIT notify(Notify::Warning,
380                 QString(tr("XDXF file cannot be read for %1 dictionary")
381                 .arg(name())));
382         qDebug()<<"Error: could not open file";
383         return -1;
384     }
385
386     dictionaryFile.seek(0);
387
388     long wordsCount = 0;
389
390     QString line;
391     while(!dictionaryFile.atEnd()) {
392         line = dictionaryFile.readLine();
393         if(line.contains("<k>")) {
394             wordsCount++;
395         }
396     }
397     _wordsCount = wordsCount;
398     dictionaryFile.close();
399     return wordsCount;
400 }
401
402
403
404 void StarDictPlugin::clean() {
405
406 }
407
408
409 Q_EXPORT_PLUGIN2(stardict, StarDictPlugin)