bf75e6ae42b4389753e46a5c49dc6346124dfe03
[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 uint qHash(const TranslationStarDict &key) {
28    return qHash(key.key());
29 }
30
31 StarDictPlugin::StarDictPlugin(QObject *parent) : CommonDictInterface(parent),
32                     _langFrom(""), _langTo(""),_name(""), _infoNote("") {
33     _settings = new Settings();
34     _dictDialog = new StarDictDialog(this, this);
35
36     connect(_dictDialog, SIGNAL(notify(Notify::NotifyType,QString)),
37             this, SIGNAL(notify(Notify::NotifyType,QString)));
38
39
40     _settings->setValue("type","stardict");
41     _icon = QIcon("/usr/share/mdictionary/stardict.png");
42     _wordsCount = -1;
43     stopped = false;
44
45     initAccents();
46 }
47
48 void StarDictPlugin::retranslate() {
49     QString locale = QLocale::system().name();
50
51     QTranslator *translator = new QTranslator(this);
52
53     if(!translator->load(":/xdxf/translations/" + locale)) {
54         translator->load(":/xdxf/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     qDebug() << "StarDict searachWordList" << word;
93     QList<TranslationStarDict> translations;
94     bool is32b = false;
95     if(settings()->value("idxoffsetbits") == "32" ||
96             settings()->value("idxoffsetbits") == "")
97        is32b = true;
98
99     bool err = 0;
100     int wordcount = settings()->value("wordcount").toInt(&err);
101     if(!err)
102         return QList<Translation*>();
103
104     QString idxPath = settings()->value("idxFileName");
105     StarDictReader * reader = StarDictReaderFactory::createReader(idxPath);
106     QString fkey;
107     qint64 offset = 0, len = 0;
108     QRegExp keyword(word, Qt::CaseInsensitive, QRegExp::Wildcard);
109
110     int counter = 0;
111     int counterLimit = 0;
112     stopped=false;
113     while(counter < wordcount && (counterLimit<limit || limit==0) && !stopped) {
114         counter++;
115         fkey = reader->readKeyword();
116         if(is32b)
117             offset = reader->readInt32BigEndian();
118         else
119             offset = reader->readInt64BigEndian();
120         len = reader->readInt32BigEndian();
121
122         if(keyword.exactMatch(fkey)) {
123             qDebug()<<"InfoNote"<<infoNote();
124             TranslationStarDict tran(fkey, infoNote(), this);
125             qDebug() << "off/len" << offset << len;
126             int id = translations.indexOf(tran);
127             if(id == -1) {
128                 tran.add(offset, len);
129                 translations.push_front(tran);
130             } else
131                 translations[id].add(offset, len);
132             counterLimit++;
133         }
134     }
135     QList<Translation*> ret;
136     QListIterator<TranslationStarDict> it(translations);
137     while(it.hasNext())
138         ret.push_back(new TranslationStarDict(it.next()));
139
140
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         if(it == end) qDebug()<<"end";
153         else  qDebug()<<"000";
154     }
155     else
156         for(int i = 0; i < bytes && it != end; i++)
157             ret.append(*it++);
158     return ret;
159 }
160
161
162 QString StarDictPlugin::interpret(QByteArray::iterator it,
163         QByteArray::iterator end, QChar mode,QString key, bool last) {
164     QString result;
165     qDebug()<<"****** mode:     "<<mode;
166     if(mode == 'm'){
167         result += "<key>" + key + "</key>";
168         result += QString::fromUtf8(read(it++, end));
169     }
170     else if(mode == 'l'){
171         result += "<key>" + key + "</key>";
172         result += QString::fromUtf8(read(it++, end));
173     }
174     else if(mode ==  'g'){
175         result += "<key>" + key + "</key>";
176         result += QString::fromUtf8(read(it++, end));
177
178         /* delete "small" tag  from translation*/
179         int indexOfSmall=result.indexOf("<small>");
180         while(indexOfSmall!=-1){
181             int indexOfEndSmall= result.indexOf("</small>");
182             if(indexOfEndSmall!=-1)
183                 result.remove(indexOfSmall,indexOfEndSmall-indexOfSmall+8);
184             indexOfSmall=result.indexOf("<small>");
185         }
186     }
187     else if(mode == 't'){
188         result += "<key>" + key + "</key>";
189         result += QString::fromUtf8(read(it++, end));
190     }
191     else if(mode == 'x'){
192         result += QString::fromUtf8(read(it++, end));
193         result.replace("</k>","</key><t>");
194         result.replace("<k>","</t><key>");
195         int pos=result.indexOf("</t>");
196         if(pos!=-1)
197             result.remove(pos,4);
198         if(result.contains("<t>"))
199             result+="</t>";
200     }
201     else if(mode == 'y') {
202         result += "<key>" + key + "</key>";
203         result += QString::fromUtf8(read(it++, end));
204     }
205     else if(mode == 'k'){
206         result += "<key>" + key + "</key>";
207         result += QString::fromUtf8(read(it++, end));
208     }
209     else if(mode == 'w'){
210         result += "<key>" + key + "</key>";
211         result += QString::fromUtf8(read(it++, end));
212     }
213     else if(mode == 'h'){
214         result += "<key>" + key + "</key>";
215         result += QString::fromUtf8(read(it++, end));
216     }
217     else if(mode == 'r'){
218         result += "<key>" + key + "</key>";
219         result += QString::fromUtf8(read(it++, end));
220     }
221
222 // Dont know whether mDictionary would ever handle binary stardict format
223 //     to be honest dont see any kind of adventages (can't find any binary dict)
224  /*
225     }
226     else if(mode == 'W') {
227         result += "<key>" + key + "</key>";
228         if(!last) {
229             QByteArray tmp ;
230             tmp.append(*(it++));
231             tmp.append(*(it++));
232             tmp.append(*(it++));
233             tmp.append(*(it));
234             result += read(it++, end, (qint32)qFromBigEndian(*(qint32*)tmp.data()));
235         } else
236             result += read(it++, end);
237     } else if(mode == 'P') {
238         result += "<key>" + key + "</key>";
239         if(!last) {
240             QByteArray tmp ;
241             tmp.append(*(it++));
242             tmp.append(*(it++));
243             tmp.append(*(it++));
244             tmp.append(*(it));
245             result += read(it++, end, (qint32)qFromBigEndian(*(qint32*)tmp.data()));
246         } else
247             result += read(it++, end);
248     } */
249
250     qDebug()<<"wynik  "<<result;
251     return result;
252 }
253
254 QString StarDictPlugin::format(QByteArray raw, QString mode,QString key) {
255     QString result;
256     if(mode == "") {
257         for(QByteArray::iterator it = raw.begin(); it != raw.end(); it++) {
258             char tmp = *(++it);
259             result += interpret(--it, raw.end(), tmp, key);
260         }
261     } else {
262         QByteArray::iterator it = raw.begin();
263         foreach(QChar tmp, mode) {
264             result += interpret(it, raw.end(), tmp, key);
265         }
266     }
267     return result;
268 }
269
270
271
272 QString StarDictPlugin::search(QString key, qint64 offset, qint32 len) {
273     QString dictPath = settings()->value("dictFileName");
274     StarDictReader *reader = StarDictReaderFactory::createReader(dictPath);
275
276     QByteArray raw = reader->readString(offset, len);
277     qDebug()<<"mod"<<settings()->value("sametypesequence");
278     QString result= format(raw, settings()->value("sametypesequence"),key);
279     delete reader;
280     return result;
281 }
282
283
284
285 void StarDictPlugin::stop() {
286     qDebug()<<"zatrzymanie programu";
287     stopped=true;
288 }
289
290
291 DictDialog* StarDictPlugin::dictDialog() {
292      return _dictDialog;
293 }
294
295
296 CommonDictInterface* StarDictPlugin::getNew(const Settings *settings) const {
297     StarDictPlugin *plugin = new StarDictPlugin();
298
299     connect(plugin, SIGNAL(notify(Notify::NotifyType,QString)),
300             this, SIGNAL(notify(Notify::NotifyType,QString)));
301
302     ((StarDictDialog*)plugin->dictDialog())->
303             setLastDialogParent(_dictDialog->lastDialogParent());
304
305     if(settings && plugin->setSettings(settings)) {
306         disconnect(plugin, SIGNAL(notify(Notify::NotifyType,QString)),
307                 this, SIGNAL(notify(Notify::NotifyType,QString)));
308         plugin->getDictionaryInfo();
309         return plugin;
310     }
311     else {
312         disconnect(plugin, SIGNAL(notify(Notify::NotifyType,QString)),
313                 this, SIGNAL(notify(Notify::NotifyType,QString)));
314         delete plugin;
315         return 0;
316     }
317 }
318
319
320 bool StarDictPlugin::isAvailable() const {
321     return true;
322 }
323
324
325 Settings* StarDictPlugin::settings() {
326     return _settings;
327 }
328
329
330 bool StarDictPlugin::isCached() {
331     return false;
332 }
333
334
335 bool StarDictPlugin::setSettings(const Settings *sett) {
336     if(sett) {
337         foreach(QString key, sett->keys())
338             _settings->setValue(key, sett->value(key));
339
340     } else
341         return false;
342     Q_EMIT settingsChanged();
343     return true;
344 }
345
346
347 bool StarDictPlugin::getDictionaryInfo() {
348     QFile file(settings()->value("ifoFileName"));
349     if(!QFile::exists(_settings->value("ifoFileName"))
350                 || !file.open(QFile::ReadOnly | QFile::Text)) {
351        Q_EMIT notify(Notify::Warning,
352                QString(tr("StarDict dictionary cannot be read from file")));
353         qDebug()<<"Error: could not open the file";
354         return false;
355     }
356
357     QTextStream in(&file);
358     while (!in.atEnd()) {
359         QString line = in.readLine();
360         QStringList list = line.split("=");
361         if(list.size() == 2) {
362             settings()->setValue(list.at(0),list.at(1));
363         }
364     }
365
366     _name = settings()->value("bookname");
367     return true;
368 }
369
370
371 QIcon* StarDictPlugin::icon() {
372     return &_icon;
373 }
374
375
376 int StarDictPlugin::countWords() {
377     return 0;
378 }
379
380
381
382 void StarDictPlugin::clean() {
383
384 }
385
386
387 Q_EXPORT_PLUGIN2(stardict, StarDictPlugin)