Added caching dialog with casching progress
[mdictionary] / trunk / src / plugins / xdxf / src / xdxfplugin.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 #include "xdxfplugin.h"
23 #include <QDebug>
24 #include <QFile>
25 #include <QXmlStreamReader>
26 #include <QtPlugin>
27 #include "TranslationXdxf.h"
28 #include "../../../includes/settings.h"
29
30 XdxfPlugin::XdxfPlugin(QObject *parent) : CommonDictInterface(parent),
31                     _langFrom(tr("")), _langTo(tr("")),_name(tr("")),
32                     _type(tr("xdxf")), _infoNote(tr("")) {
33     _wordsCount = -1;
34     _settings = new Settings();
35     _dictDialog = new XdxfDictDialog(this, this);
36     cachingDialog = new XdxfCachingDialog(this);
37
38     _settings->setValue("type","xdxf");
39     if(isCached())
40         _settings->setValue("cached","true");
41     else
42         _settings->setValue("cached","false");
43
44
45     stopped = false;
46
47     _icon = QIcon(":/icons/xdxf.png");
48 }
49
50 QString XdxfPlugin::langFrom() const {   
51     return _langFrom;
52 }
53
54 QString XdxfPlugin::langTo() const {
55     return  _langTo;
56 }
57
58 QString XdxfPlugin::name() const {
59     return  _name;
60 }
61
62 QString XdxfPlugin::type() const {
63 //    return _settings->value("type");
64     return _type;
65 }
66
67 QString XdxfPlugin::infoNote() const {
68     return  _infoNote;
69 }
70
71 QList<Translation*> XdxfPlugin::searchWordList(QString word, int limit) {
72     if(_settings->value("cached") == "true")
73         return searchWordListCache(word,limit);
74     return searchWordListFile(word, limit);
75 }
76
77 QList<Translation*> XdxfPlugin::searchWordListCache(QString word, int limit) {
78
79
80 }
81
82
83
84 QList<Translation*> XdxfPlugin::searchWordListFile(QString word, int limit) {
85     QSet<Translation*> translations;
86     QFile dictionaryFile(path);
87
88     word = removeAccents(word);
89
90     stopped = false;
91     if(word.indexOf("*")==-1)
92         word+="*";
93     QRegExp regWord(word);
94     regWord.setCaseSensitivity(Qt::CaseInsensitive);
95     regWord.setPatternSyntax(QRegExp::Wildcard);
96     if(!dictionaryFile.open(QFile::ReadOnly | QFile::Text)) {
97         qDebug()<<"Error: could not open file";
98         return translations.toList();
99     }
100
101     QXmlStreamReader dictionaryReader(&dictionaryFile);
102     /*search words list*/
103     QString a;
104     int i=0;
105     while(!dictionaryReader.atEnd() && !stopped){
106         dictionaryReader.readNextStartElement();
107         if(dictionaryReader.name()=="ar"){
108             while(dictionaryReader.name()!="k" && !dictionaryReader.atEnd())
109                 dictionaryReader.readNextStartElement();
110             if(!dictionaryReader.atEnd())
111                 a = dictionaryReader.readElementText();
112             if(regWord.exactMatch(removeAccents(a)) && (i<limit || limit==0)) {
113                 bool ok=true;
114                 Translation *tran;
115                 foreach(tran,translations)
116                 {
117                     if(tran->key()==a)
118                         ok=false;  /*if key word is in the dictionary more that one */
119                 }
120                 if(ok)  /*add key word to list*/
121                     translations<<(new TranslationXdxf(a,_infoNote,this));
122                 i++;
123                 if(i>=limit && limit!=0)
124                     break;
125             }
126         }
127         this->thread()->yieldCurrentThread();
128     }
129     stopped=false;
130     dictionaryFile.close();
131     return translations.toList();
132 }
133
134 QString XdxfPlugin::search(QString key) {
135     QFile dictionaryFile(path);
136     QString resultString("");
137     if(!dictionaryFile.open(QFile::ReadOnly | QFile::Text)) {
138         qDebug()<<"Error: could not open file";
139         return "";
140     }
141     QXmlStreamReader dictionaryReader(&dictionaryFile);
142
143
144     QString a;
145
146     bool match =false;
147     stopped = false;
148     while (!dictionaryReader.atEnd()&& !stopped) {
149         dictionaryReader.readNext();
150         if(dictionaryReader.tokenType() == QXmlStreamReader::StartElement) {
151             if(dictionaryReader.name()=="k") {
152                 a = dictionaryReader.readElementText();
153                 if(a==key)
154                     match = true;
155             }
156         }
157         else if(dictionaryReader.tokenType() == QXmlStreamReader::Characters) {
158             if(match) {
159                 QString temp(dictionaryReader.text().toString());
160                 temp.replace("\n","");
161                 if(temp == ""){
162                     while(dictionaryReader.name()!="ar"&&
163                                 !dictionaryReader.atEnd()){
164                         dictionaryReader.readNext();
165                         temp+=dictionaryReader.text().toString();
166                     }
167                 }
168                 resultString+=temp.replace("\n","")+"\n";
169                 match=false;
170             }
171         }
172         this->thread()->yieldCurrentThread();
173     }
174     stopped=false;
175     dictionaryFile.close();
176     return resultString;
177 }
178
179 void XdxfPlugin::stop() {
180     stopped=true;
181 }
182
183 DictDialog* XdxfPlugin::dictDialog() {
184      return _dictDialog;
185 }
186
187 void XdxfPlugin::setPath(QString path){
188     this->path=path;
189     _settings->setValue("path",path);
190     getDictionaryInfo();
191 }
192
193
194 CommonDictInterface* XdxfPlugin::getNew(const Settings *settings) const {
195     XdxfPlugin *plugin = new XdxfPlugin();
196     if(settings){
197         plugin->setPath(settings->value("path"));
198         QStringList list = settings->keys();
199         foreach(QString key, list)
200             plugin->settings()->setValue(key, settings->value(key));
201         plugin->makeCache("");
202     }
203     return  plugin;
204 }
205
206 bool XdxfPlugin::isAvailable() const {
207     return true;
208 }
209
210 void XdxfPlugin::setHash(uint _hash)
211 {
212     this->_hash=_hash;
213 }
214
215 uint XdxfPlugin::hash() const
216 {
217    return _hash;
218 }
219
220 Settings* XdxfPlugin::settings() {
221     return _settings;
222 }
223
224 bool XdxfPlugin::isCached()
225 {
226     return false;
227 }
228
229 void XdxfPlugin::setSettings(Settings *settings) {
230     _settings = settings;
231     setPath(_settings->value("path"));
232     emit settingsChanged();
233 }
234
235
236 void XdxfPlugin::getDictionaryInfo() {
237     QFile dictionaryFile(path);
238     if(!dictionaryFile.open(QFile::ReadOnly | QFile::Text)) {
239         qDebug()<<"Error: could not open file";
240         return;
241     }
242
243     QXmlStreamReader dictionaryReader(&dictionaryFile);
244     dictionaryReader.readNextStartElement();
245     if(dictionaryReader.name()=="xdxf") {
246       if(dictionaryReader.attributes().hasAttribute("lang_from"))
247         _langFrom = dictionaryReader.attributes().value("lang_from").toString();
248       if(dictionaryReader.attributes().hasAttribute("lang_to"))
249         _langTo = dictionaryReader.attributes().value("lang_to").toString();
250     }
251     dictionaryReader.readNextStartElement();
252     if(dictionaryReader.name()=="full_name")
253         _name=dictionaryReader.readElementText();
254     dictionaryReader.readNextStartElement();
255     if(dictionaryReader.name()=="description")
256         _infoNote=dictionaryReader.readElementText();
257
258     dictionaryFile.close();
259 }
260
261 QString XdxfPlugin::removeAccents(QString string) {
262
263     string = string.replace(QString::fromUtf8("ł"), "l", Qt::CaseInsensitive);
264     QString normalized = string.normalized(QString::NormalizationForm_D);
265     normalized = normalized;
266     for(int i=0; i<normalized.size(); i++) {
267         if( !normalized[i].isLetterOrNumber() &&
268             !normalized[i].isSpace() &&
269             !normalized[i].isDigit()) {
270             normalized.remove(i,1);
271         }
272     }
273     return normalized;
274 }
275
276 QIcon* XdxfPlugin::icon() {
277     return &_icon;
278 }
279
280 int XdxfPlugin::countWords() {
281     if(_wordsCount > 0)
282         return _wordsCount;
283
284     QFile dictionaryFile(path);
285     if(!dictionaryFile.open(QFile::ReadOnly | QFile::Text)) {
286         qDebug()<<"Error: could not open file";
287         return -1;
288     }
289
290     dictionaryFile.seek(0);
291
292     long wordsCount = 0;
293
294     QString line;
295     while(!dictionaryFile.atEnd()) {
296         line = dictionaryFile.readLine();
297         if(line.contains("<k>")) {
298             wordsCount++;
299         }
300     }
301     _wordsCount = wordsCount;
302     dictionaryFile.close();
303     return wordsCount;
304 }
305
306
307
308 bool XdxfPlugin::makeCache(QString dir) {
309     cachingDialog->setVisible(true);
310     QFileInfo dictFileN(_settings->value("path"));
311     QString cachePathN;
312     cachePathN = dictFileN.dir().absolutePath() + "/"
313                  + dictFileN.completeBaseName() + ".cache";
314
315     QFile dictionaryFile(dictFileN.filePath());
316
317
318     qDebug() << dictFileN.path();
319     if (!dictionaryFile.open(QFile::ReadOnly | QFile::Text)) {
320         return 0;
321     }
322     qDebug() << "OLE";
323
324     QXmlStreamReader reader(&dictionaryFile);
325
326     QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
327
328     db.setDatabaseName(cachePathN);
329     if(!db.open()) {
330         qDebug() << "Database error" << endl;
331         return false;
332     }
333     QSqlQuery cur;
334     cur.exec("PRAGMA synchronous = 0");
335     cur.exec("drop table dict");
336     cur.exec("create table dict(word text ,transl text)");
337     int counter = 0;
338     cur.exec("BEGIN;");
339
340     QString a;
341     bool match = false;
342     QTime timer;
343     timer.start();
344     countWords();
345
346
347     counter=0;
348     while (!reader.atEnd()) {
349
350         QCoreApplication::processEvents();
351         //usleep(50);
352         reader.readNext();
353
354         if(reader.tokenType() == QXmlStreamReader::StartElement) {
355             if(reader.name()=="k"){
356                 a = reader.readElementText();
357                 match = true;
358             }
359         }
360         else if(reader.tokenType() == QXmlStreamReader::Characters) {
361              if(match) {
362                 QString temp(reader.text().toString());
363                 temp.replace("\n","");
364                 if(temp == ""){
365                     while(reader.name()!="ar"&&
366                                 !reader.atEnd()){
367                         reader.readNext();
368                         temp+=reader.text().toString();
369                     }
370                 }
371                 match = false;
372                 cur.prepare("insert into dict values(?,?)");
373                 cur.addBindValue(a);
374                 cur.addBindValue(temp);
375                 cur.exec();
376                 counter++;
377                 int prog = counter*100/_wordsCount;
378                 if(prog % 5 == 0)
379                     Q_EMIT updateCachingProgress(prog);
380             }
381
382         }
383     }
384
385     cachingDialog->setVisible(false);
386
387     qDebug()<<counter;
388     cur.exec("END;");
389     cur.exec("select count(*) from dict");
390     if(!cur.next() || countWords() != cur.value(0).toInt()) {
391         qDebug() << countWords() << " " << cur.value(0).toInt();
392         qDebug() << "ŻLEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE";
393         return false;
394     }
395     return true;
396 }
397
398
399 Q_EXPORT_PLUGIN2(xdxf, XdxfPlugin)