+/*******************************************************************************
+
+ This file is part of mDictionary.
+
+ mDictionary is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ mDictionary is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with mDictionary. If not, see <http://www.gnu.org/licenses/>.
+
+ Copyright 2010 Comarch S.A.
+
+*******************************************************************************/
+
#include "xdxfplugin.h"
#include <QDebug>
#include <QFile>
#include <QXmlStreamReader>
#include <QtPlugin>
#include "TranslationXdxf.h"
+#include "../../../includes/settings.h"
XdxfPlugin::XdxfPlugin(QObject *parent) : CommonDictInterface(parent),
_langFrom(tr("")), _langTo(tr("")),_name(tr("")),
_type(tr("xdxf")), _infoNote(tr("")) {
- path="dict.xdxf";
+ _wordsCount = -1;
+ _settings = new Settings();
+ _dictDialog = new XdxfDictDialog(this, this);
+ cachingDialog = new XdxfCachingDialog(this);
+
+ connect(cachingDialog, SIGNAL(cancelCaching()),
+ this, SLOT(stop()));
+
+ _settings->setValue("type","xdxf");
+
stopped = false;
+
+ _icon = QIcon(":/icons/xdxf.png");
}
-QString XdxfPlugin::langFrom() const {
- return _langFrom;
+QString XdxfPlugin::langFrom() const {
+ return _langFrom;
}
QString XdxfPlugin::langTo() const {
}
QString XdxfPlugin::type() const {
+// return _settings->value("type");
return _type;
}
}
QList<Translation*> XdxfPlugin::searchWordList(QString word, int limit) {
+ //if(_settings->value("cached") == "true")
+ if(word.indexOf("*")==-1 && word.indexOf("?")==-1 && word.indexOf("_")==-1
+ && word.indexOf("%")==-1)
+ word+="*";
+ if(isCached())
+ return searchWordListCache(word,limit);
+ return searchWordListFile(word, limit);
+}
+
+QList<Translation*> XdxfPlugin::searchWordListCache(QString word, int limit) {
+
+ QSet<Translation*> translations;
+ QString cacheFilePath = _settings->value("cache_path");
+ db.setDatabaseName(cacheFilePath);
+ if(!db.open()) {
+ qDebug() << "Database error" << db.lastError().text() << endl;
+ return searchWordListFile(word, limit);
+ }
+
+ stopped = false;
+ if(word.indexOf("*")==-1 && word.indexOf("?")== 0)
+ word+="%";
+ word = word.replace("*", "%");
+ word = word.replace("?", "_");
+ word = removeAccents(word);
+ qDebug() << word;
+
+ QSqlQuery cur(db);
+ cur.prepare("select word from dict where word like ? limit ?");
+ cur.addBindValue(word);
+ cur.addBindValue(limit);
+ cur.exec();
+ while(cur.next())
+ translations.insert(new TranslationXdxf(cur.value(0).toString(),
+ _infoNote, this));
+ return translations.toList();
+}
+
+
+
+QList<Translation*> XdxfPlugin::searchWordListFile(QString word, int limit) {
+ QSet<Translation*> translations;
+ QFile dictionaryFile(path);
+
+ word = removeAccents(word);
+
stopped = false;
QRegExp regWord(word);
regWord.setCaseSensitivity(Qt::CaseInsensitive);
regWord.setPatternSyntax(QRegExp::Wildcard);
-
- QList<Translation*> translations;
- QFile dictionaryFile(path);
if(!dictionaryFile.open(QFile::ReadOnly | QFile::Text)) {
qDebug()<<"Error: could not open file";
- return translations;
- }
- QXmlStreamReader dictionaryReader(&dictionaryFile);
- dictionaryReader.readNextStartElement();
- if(dictionaryReader.name()=="xdxf") {
- if(dictionaryReader.attributes().hasAttribute("lang_from"))
- _langFrom = dictionaryReader.attributes().value("lang_from").toString();
- if(dictionaryReader.attributes().hasAttribute("lang_to"))
- _langTo = dictionaryReader.attributes().value("lang_to").toString();
- }
- dictionaryReader.readNextStartElement();
- if(dictionaryReader.name()=="full_name")
- _name=dictionaryReader.readElementText();
- dictionaryReader.readNextStartElement();
- if(dictionaryReader.name()=="description")
- _infoNote=dictionaryReader.readElementText();
+ return translations.toList();
+ }
+
+ QXmlStreamReader reader(&dictionaryFile);
+ /*search words list*/
QString a;
int i=0;
- while(!dictionaryReader.atEnd() && !stopped){
- dictionaryReader.readNextStartElement();
- if(dictionaryReader.name()=="ar"){
- while(dictionaryReader.name()!="k" && !dictionaryReader.atEnd())
- dictionaryReader.readNextStartElement();
- a = dictionaryReader.readElementText();
- if(regWord.exactMatch(a) && i<limit) {
- translations.append(new TranslationXdxf(a,_infoNote,this));
+ while(!reader.atEnd() && !stopped){
+ reader.readNextStartElement();
+ if(reader.name()=="ar") {
+ while(reader.name()!="k" && !reader.atEnd())
+ reader.readNextStartElement();
+ if(!reader.atEnd())
+ a = reader.readElementText();
+ if(regWord.exactMatch(removeAccents(a)) && (i<limit || limit==0)) {
+ bool ok=true;
+ Translation *tran;
+ foreach(tran,translations)
+ {
+ if(tran->key()==a)
+ ok=false; /*if key word is in the dictionary more that one */
+ }
+ if(ok) /*add key word to list*/
+ translations<<(new TranslationXdxf(a,_infoNote,this));
i++;
- if(i>=limit)
+ if(i>=limit && limit!=0)
break;
}
}
+ this->thread()->yieldCurrentThread();
}
stopped=false;
dictionaryFile.close();
- return translations;
+ return translations.toList();
}
QString XdxfPlugin::search(QString key) {
+// if(_settings->value("cached") == "true")
+ if(isCached())
+ return searchCache(key);
+ return searchFile(key);
+}
+
+
+
+QString XdxfPlugin::searchCache(QString key) {
+ QString result;
+ QString cacheFilePath = _settings->value("cache_path");
+ db.setDatabaseName(cacheFilePath);
+
+ if(!db.open()) {
+ qDebug() << "Database error" << db.lastError().text() << endl;
+ return searchFile(key);
+ }
+
+ QSqlQuery cur(db);
+ cur.prepare("select translation from dict where word like ? limit 1");
+ cur.addBindValue(key);
+ cur.exec();
+ if(cur.next())
+ result = cur.value(0).toString();
+ return result;
+
+}
+
+
+
+
+QString XdxfPlugin::searchFile(QString key) {
QFile dictionaryFile(path);
+ QString resultString("");
if(!dictionaryFile.open(QFile::ReadOnly | QFile::Text)) {
qDebug()<<"Error: could not open file";
return "";
}
- QXmlStreamReader dictionaryReader(&dictionaryFile);
+ QXmlStreamReader reader(&dictionaryFile);
+
QString a;
+
bool match =false;
- while (!dictionaryReader.atEnd()) {
- dictionaryReader.readNext();
- if(dictionaryReader.tokenType() == QXmlStreamReader::StartElement) {
- if(dictionaryReader.name()=="k") {
- a = dictionaryReader.readElementText();
+ stopped = false;
+ while (!reader.atEnd()&& !stopped) {
+ reader.readNext();
+ if(reader.tokenType() == QXmlStreamReader::StartElement) {
+ if(reader.name()=="k") {
+ a = reader.readElementText();
if(a==key)
match = true;
}
}
- else if(dictionaryReader.tokenType() == QXmlStreamReader::Characters) {
- if(match) {
- QString temp(dictionaryReader.text().toString().replace("\n",""));
- dictionaryFile.close();
- return temp;
+ if(match) {
+ QString temp("");
+ while(reader.name()!="ar" && !reader.atEnd()) {
+ if(reader.name()!="" && reader.name()!="k") {
+ if(reader.tokenType()==QXmlStreamReader::EndElement)
+ temp+=tr("</");
+ if(reader.tokenType()==QXmlStreamReader::StartElement)
+ temp+=tr("<");
+ temp+=reader.name().toString();
+ if(reader.name().toString()=="c" && reader.tokenType()==QXmlStreamReader::StartElement)
+ temp= temp + tr(" c=\"") + reader.attributes().value(tr("c")).toString() + tr("\"");
+ temp+=tr(">");
+ }
+ temp+= reader.text().toString();
+ reader.readNext();
}
+ resultString+=tr("<t>") + temp.replace("\n","") + tr("</t>");
+ match=false;
}
+ this->thread()->yieldCurrentThread();
}
- return "";
+ stopped=false;
+ dictionaryFile.close();
+ return resultString;
}
void XdxfPlugin::stop() {
stopped=true;
}
-QDialog* XdxfPlugin::loadDialog() {
- path="dict.xdxf";
+DictDialog* XdxfPlugin::dictDialog() {
+ return _dictDialog;
}
-QDialog* XdxfPlugin::settingsDialog() {
- path="dict.xdxf";
+void XdxfPlugin::setPath(QString path){
+ this->path=path;
+ _settings->setValue("path",path);
+ //getDictionaryInfo();
}
-CommonDictInterface* XdxfPlugin::getNew(const Settings*) const {
- return new XdxfPlugin();
+
+CommonDictInterface* XdxfPlugin::getNew(const Settings *settings) const {
+ XdxfPlugin *plugin = new XdxfPlugin();
+ if(settings){
+ plugin->setPath(settings->value("path"));
+
+ QStringList list = settings->keys();
+ foreach(QString key, list)
+ plugin->settings()->setValue(key, settings->value(key));
+
+
+ plugin->db_name = plugin->_settings->value("type")
+ + plugin->_settings->value("path");
+ plugin->db = QSqlDatabase::addDatabase("QSQLITE", plugin->db_name);
+
+ if(settings->value("cached").isEmpty() &&
+ settings->value("generateCache") == "true") {
+ plugin->makeCache("");
+ }
+ }
+
+ plugin->getDictionaryInfo();
+ return plugin;
}
bool XdxfPlugin::isAvailable() const {
return _hash;
}
+Settings* XdxfPlugin::settings() {
+ return _settings;
+}
+
+bool XdxfPlugin::isCached()
+{
+ if(_settings->value("cached") == "true")
+ return true;
+ return false;
+}
+
+void XdxfPlugin::setSettings(Settings *settings) {
+
+ QString oldPath = _settings->value("path");
+ if(oldPath != settings->value("path")) {
+ setPath(settings->value("path"));
+ }
+
+ if((_settings->value("cached") == "false" ||
+ _settings->value("cached").isEmpty()) &&
+ settings->value("generateCache") == "true") {
+ makeCache("");
+ }
+ else {
+ _settings->setValue("cached", "false");
+ }
+
+ emit settingsChanged();
+}
+
+
+void XdxfPlugin::getDictionaryInfo() {
+ QFile dictionaryFile(path);
+ if(!dictionaryFile.open(QFile::ReadOnly | QFile::Text)) {
+ qDebug()<<"Error: could not open file";
+ return;
+ }
+
+ QXmlStreamReader reader(&dictionaryFile);
+ reader.readNextStartElement();
+ if(reader.name()=="xdxf") {
+ if(reader.attributes().hasAttribute("lang_from"))
+ _langFrom = reader.attributes().value("lang_from").toString();
+ if(reader.attributes().hasAttribute("lang_to"))
+ _langTo = reader.attributes().value("lang_to").toString();
+ }
+ reader.readNextStartElement();
+ if(reader.name()=="full_name")
+ _name=reader.readElementText();
+ reader.readNextStartElement();
+ if(reader.name()=="description")
+ _infoNote=reader.readElementText();
+
+ dictionaryFile.close();
+}
+
+QString XdxfPlugin::removeAccents(QString string) {
+
+ string = string.replace(QString::fromUtf8("ł"), "l", Qt::CaseInsensitive);
+ QString normalized = string.normalized(QString::NormalizationForm_D);
+ normalized = normalized;
+ for(int i=0; i<normalized.size(); i++) {
+ if( !normalized[i].isLetterOrNumber() &&
+ !normalized[i].isSpace() &&
+ !normalized[i].isDigit() &&
+ normalized[i] != '*' &&
+ normalized[i] != '%' &&
+ normalized[i] != '_' &&
+ normalized[i] != '?' ) {
+ normalized.remove(i,1);
+ }
+ }
+ return normalized;
+}
+
+QIcon* XdxfPlugin::icon() {
+ return &_icon;
+}
+
+int XdxfPlugin::countWords() {
+ if(_wordsCount > 0)
+ return _wordsCount;
+
+ QFile dictionaryFile(path);
+ if(!dictionaryFile.open(QFile::ReadOnly | QFile::Text)) {
+ qDebug()<<"Error: could not open file";
+ return -1;
+ }
+
+ dictionaryFile.seek(0);
+
+ long wordsCount = 0;
+
+ QString line;
+ while(!dictionaryFile.atEnd()) {
+ line = dictionaryFile.readLine();
+ if(line.contains("<k>")) {
+ wordsCount++;
+ }
+ }
+ _wordsCount = wordsCount;
+ dictionaryFile.close();
+ return wordsCount;
+}
+
+
+
+bool XdxfPlugin::makeCache(QString dir) {
+ cachingDialog->setVisible(true);
+ QCoreApplication::processEvents();
+ stopped = false;
+ QFileInfo dictFileN(_settings->value("path"));
+ QString cachePathN;
+ cachePathN = QDir::homePath() + "/.mdictionary/"
+ + dictFileN.completeBaseName() + ".cache";
+
+ QFile dictionaryFile(dictFileN.filePath());
+
+
+ if (!dictionaryFile.open(QFile::ReadOnly | QFile::Text)) {
+ return 0;
+ }
+
+ QXmlStreamReader reader(&dictionaryFile);
+
+
+ db.setDatabaseName(cachePathN);
+ if(!db.open()) {
+ qDebug() << "Database error" << endl;
+ return false;
+ }
+ QCoreApplication::processEvents();
+ QSqlQuery cur(db);
+ cur.exec("PRAGMA synchronous = 0");
+ cur.exec("drop table dict");
+ QCoreApplication::processEvents();
+ cur.exec("create table dict(word text ,translation text)");
+ int counter = 0;
+ cur.exec("BEGIN;");
+
+ QString a;
+ bool match = false;
+ QTime timer;
+ timer.start();
+ countWords();
+
+ int lastProg = -1;
+
+
+ counter=0;
+ while (!reader.atEnd() && !stopped) {
+
+ QCoreApplication::processEvents();
+ // usleep(50);
+ reader.readNext();
+
+ if(reader.tokenType() == QXmlStreamReader::StartElement) {
+ if(reader.name()=="k"){
+ a = reader.readElementText();
+ match = true;
+ }
+ }
+ if(match) {
+ QString temp("");
+ while(reader.name()!="ar" && !reader.atEnd()) {
+ if(reader.name()!="" && reader.name()!="k") {
+ if(reader.tokenType()==QXmlStreamReader::EndElement)
+ temp+=tr("</");
+ if(reader.tokenType()==QXmlStreamReader::StartElement)
+ temp+=tr("<");
+ temp+=reader.name().toString();
+ if(reader.name().toString()=="c" && reader.tokenType()==QXmlStreamReader::StartElement)
+ temp= temp + tr(" c=\"") + reader.attributes().value(tr("c")).toString() + tr("\"");
+ temp+=tr(">");
+ }
+ temp+= reader.text().toString();
+ reader.readNext();
+ }
+ temp += tr("<t>") + temp.replace("\n","") + tr("</t>");
+ match=false;
+ cur.prepare("insert into dict values(?,?)");
+ cur.addBindValue(a);
+ cur.addBindValue(temp);
+ cur.exec();
+ counter++;
+ int prog = counter*100/_wordsCount;
+ if(prog % 5 == 0 && lastProg != prog) {
+ Q_EMIT updateCachingProgress(prog,
+ timer.restart());
+ lastProg = prog;
+ }
+ }
+ }
+
+ cur.exec("END;");
+ cur.exec("select count(*) from dict");
+
+ countWords();
+ cachingDialog->setVisible(false);
+
+ if(!cur.next() || countWords() != cur.value(0).toInt())
+ return false;
+ _settings->setValue("cache_path", cachePathN);
+ _settings->setValue("cached", "true");
+
+ return true;
+}
+
+
Q_EXPORT_PLUGIN2(xdxf, XdxfPlugin)