removeAccents refactorized out to the AccentsNormalizer class
[mdictionary] / trunk / src / plugins / xdxf / src / xdxfplugin.cpp
index 42312e4..0cac66b 100644 (file)
 
 *******************************************************************************/
 
+/*! \file xdxfplugin.cpp
+*/
+
 #include "xdxfplugin.h"
 #include <QDebug>
-#include <QFile>
-#include <QXmlStreamReader>
-#include <QtPlugin>
-#include "TranslationXdxf.h"
-#include "../../../includes/settings.h"
+#include "../../../includes/Notify.h"
 
 XdxfPlugin::XdxfPlugin(QObject *parent) : CommonDictInterface(parent),
                     _langFrom(tr("")), _langTo(tr("")),_name(tr("")),
                     _type(tr("xdxf")), _infoNote(tr("")) {
     _wordsCount = -1;
     _settings = new Settings();
-    _dictDialog = new XdxfDictDialog(this, this);
-    cachingDialog = new XdxfCachingDialog(this);
+    _dictDialog = new XdxfDictDialog(this);
+    cachingDialog = new XdxfCachingDialog();
 
     connect(cachingDialog, SIGNAL(cancelCaching()),
             this, SLOT(stop()));
 
+    connect(this, SIGNAL(updateCachingProgress(int,int)),
+            cachingDialog, SLOT(updateCachingProgress(int,int)));
+
     _settings->setValue("type","xdxf");
 
     stopped = false;
 
     _icon = QIcon(":/icons/xdxf.png");
+    initAccents();
+}
+
+
+
+XdxfPlugin::~XdxfPlugin()
+{
+//  QString connection(db.connectionName());
+//   db.close();
+//  QSqlDatabase::removeDatabase(connection);
+
+    delete _settings;
 }
 
+
 QString XdxfPlugin::langFrom() const {   
     return _langFrom;
 }
@@ -67,7 +82,6 @@ QString XdxfPlugin::infoNote() const {
 }
 
 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+="*";
@@ -83,38 +97,53 @@ QList<Translation*> XdxfPlugin::searchWordListCache(QString word, int limit) {
         db.setDatabaseName(cacheFilePath);
         if(!db.open()) {
             qDebug() << "Database error" << db.lastError().text() << endl;
+            Q_EMIT notify(Notify::Warning, QString("Cache database cannot be "
+                    "opened for %1 dictionary. Searching in xdxf file. "
+                    "You may want to recache.").arg(name()));
             return searchWordListFile(word, limit);
         }
 
         stopped = false;
-        if(word.indexOf("*")==-1 && word.indexOf("?")== 0)
-            word+="%";
         word = word.toLower();
         word = word.replace("*", "%");
         word = word.replace("?", "_");
-        word = removeAccents(word);
-        qDebug() << word;
 
         QSqlQuery cur(db);
-        cur.prepare("select word from dict where word like ? limit ?");
+        if(limit !=0)
+            cur.prepare("select word from dict where word like ? or normalized like ? limit ?");
+        else
+            cur.prepare("select word from dict where word like ? or normalized like ?");
+        cur.addBindValue(word);
         cur.addBindValue(word);
-        cur.addBindValue(limit);
+        if(limit !=0)
+            cur.addBindValue(limit);
         cur.exec();
-        while(cur.next())
-            translations.insert(new TranslationXdxf(
+        bool in = false;
+        while(cur.next()){
+            in = true;
+            bool ok=true;
+            Translation *tran;
+            foreach(tran,translations) {
+                if(tran->key().toLower()==cur.value(0).toString().toLower())
+                        ok=false;
+            }
+            if(ok)  /*add key word to list*/
+                translations.insert(new TranslationXdxf(
                         cur.value(0).toString().toLower(),
                         _infoNote, this));
-        return translations.toList();
+        }
+        db.close();
+    return translations.toList();
 }
 
-
-
 QList<Translation*> XdxfPlugin::searchWordListFile(QString word, int limit) {
+    QTime time;
+    time.start();
     QSet<Translation*> translations;
     QFile dictionaryFile(path);
 
     word = word.toLower();
-    word = removeAccents(word);
+    //word = removeAccents(word);
 
     stopped = false;
     QRegExp regWord(word);
@@ -122,25 +151,29 @@ QList<Translation*> XdxfPlugin::searchWordListFile(QString word, int limit) {
     regWord.setPatternSyntax(QRegExp::Wildcard);
     if(!dictionaryFile.open(QFile::ReadOnly | QFile::Text)) {
         qDebug()<<"Error: could not open file";
+        Q_EMIT notify(Notify::Warning,
+                QString("Xdxf file cannot be read for %1").arg(name()));
         return translations.toList();
     }
 
-    QXmlStreamReader dictionaryReader(&dictionaryFile);
+    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();
-            if(!dictionaryReader.atEnd())
-                a = dictionaryReader.readElementText();
-            if(regWord.exactMatch(removeAccents(a)) && (i<limit || limit==0)) {
+    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(a) || regWord.exactMatch(removeAccents(a))) &&
+                    (i<limit || limit==0)) {
                 bool ok=true;
                 Translation *tran;
                 foreach(tran,translations) {
-                    if(tran->key()==a)
+                    if(tran->key().toLower()==a.toLower())
                         ok=false;  /*if key word is in the dictionary more that one */
                 }
                 if(ok)  /*add key word to list*/
@@ -155,6 +188,7 @@ QList<Translation*> XdxfPlugin::searchWordListFile(QString word, int limit) {
     }
     stopped=false;
     dictionaryFile.close();
+    qDebug() << time.elapsed();
     return translations.toList();
 }
 
@@ -165,75 +199,87 @@ QString XdxfPlugin::search(QString key) {
     return searchFile(key);
 }
 
-
-
 QString XdxfPlugin::searchCache(QString key) {
-    QString result;
+    QString result("");
     QString cacheFilePath = _settings->value("cache_path");
     db.setDatabaseName(cacheFilePath);
     key = key.toLower();
 
     if(!db.open()) {
         qDebug() << "Database error" << db.lastError().text() << endl;
+        Q_EMIT notify(Notify::Warning, QString("Cache database cannot be "
+                "opened for %1 dictionary. Searching in xdxf file. "
+                "You may want to recache.").arg(name()));
         return searchFile(key);
     }
 
     QSqlQuery cur(db);
-    cur.prepare("select translation from dict where word like ? limit 1");
+    cur.prepare("select translation from dict where word like ?");
     cur.addBindValue(key);
     cur.exec();
-    if(cur.next())
-        result = cur.value(0).toString();
-    return result;
-
-}
+    while(cur.next())
+        result += cur.value(0).toString();
 
+    db.close();
 
+    return result;
 
+}
 
 QString XdxfPlugin::searchFile(QString key) {
     key = key.toLower();
     QFile dictionaryFile(path);
     QString resultString("");
     if(!dictionaryFile.open(QFile::ReadOnly | QFile::Text)) {
+        Q_EMIT notify(Notify::Warning,
+                QString("Xdxf file cannot be read for %1").arg(name()));
         qDebug()<<"Error: could not open file";
         return "";
     }
-    QXmlStreamReader dictionaryReader(&dictionaryFile);
-
-
+    QXmlStreamReader reader(&dictionaryFile);
     QString a;
 
     bool match =false;
     stopped = false;
-    while (!dictionaryReader.atEnd()&& !stopped) {
-        dictionaryReader.readNext();
-        if(dictionaryReader.tokenType() == QXmlStreamReader::StartElement) {
-            if(dictionaryReader.name()=="k") {
-                a = dictionaryReader.readElementText();
-                if(a==key)
+    while (!reader.atEnd()&& !stopped) {
+        reader.readNext();
+        if(reader.tokenType() == QXmlStreamReader::StartElement) {
+            if(reader.name()=="k") {
+                a = reader.readElementText();
+                if(a.toLower()==key.toLower())
                     match = true;
             }
         }
-        else if(dictionaryReader.tokenType() == QXmlStreamReader::Characters) {
-            if(match) {
-                QString temp(dictionaryReader.text().toString());
-                temp.replace("\n","");
-                if(temp == ""){
-                    while(dictionaryReader.name()!="ar"&&
-                                !dictionaryReader.atEnd()){
-                        dictionaryReader.readNext();
-                        temp+=dictionaryReader.text().toString();
-                    }
+        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(">");
                 }
-                resultString+=temp.replace("\n","")+"\n";
-                match=false;
+                temp+= reader.text().toString().replace("<","&lt;").
+                        replace(">","&gt;");
+                reader.readNext();
             }
+            if(temp.at(0)==QChar('\n'))
+                temp.remove(0,1);
+            resultString+=tr("<key>") + a +tr("</key>");
+            resultString+=tr("<t>") + temp + tr("</t>");
+            match=false;
         }
         this->thread()->yieldCurrentThread();
     }
     stopped=false;
     dictionaryFile.close();
+
     return resultString;
 }
 
@@ -251,27 +297,26 @@ void XdxfPlugin::setPath(QString path){
     //getDictionaryInfo();
 }
 
-
 CommonDictInterface* XdxfPlugin::getNew(const Settings *settings) const {
     XdxfPlugin *plugin = new XdxfPlugin();
+    static int a=0;
     if(settings){
         plugin->setPath(settings->value("path"));
-
         QStringList list = settings->keys();
         foreach(QString key, list)
             plugin->settings()->setValue(key, settings->value(key));
 
-
+        a=a+1;
         plugin->db_name = plugin->_settings->value("type")
-               + plugin->_settings->value("path");
+                         + plugin->_settings->value("path");
         plugin->db = QSqlDatabase::addDatabase("QSQLITE", plugin->db_name);
 
         if(settings->value("cached").isEmpty() &&
            settings->value("generateCache") == "true") {
             plugin->makeCache("");
         }
+        delete settings;
     }
-
     plugin->getDictionaryInfo();
     return  plugin;
 }
@@ -313,53 +358,48 @@ void XdxfPlugin::setSettings(Settings *settings) {
     else {
        _settings->setValue("cached", "false");
     }
+   foreach(QString key, settings->keys())
+       if(key != "generateCache")
+           _settings->setValue(key, settings->value(key));
+    delete settings;
 
     emit settingsChanged();
 }
 
-
 void XdxfPlugin::getDictionaryInfo() {
     QFile dictionaryFile(path);
     if(!dictionaryFile.open(QFile::ReadOnly | QFile::Text)) {
+       Q_EMIT notify(Notify::Warning,
+               QString("Xdxf file cannot be read dictionary"));
         qDebug()<<"Error: could not open file";
         return;
     }
 
-    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();
+    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();
     }
-    dictionaryReader.readNextStartElement();
-    if(dictionaryReader.name()=="full_name")
-        _name=dictionaryReader.readElementText();
-    dictionaryReader.readNextStartElement();
-    if(dictionaryReader.name()=="description")
-        _infoNote=dictionaryReader.readElementText();
+    reader.readNextStartElement();
+    if(reader.name()=="full_name")
+        _name=reader.readElementText();
+    reader.readNextStartElement();
+    if(reader.name()=="description")
+        _infoNote=reader.readElementText();
+
+    QString format = "png";
+    QString initialPath = QDir::currentPath() + tr("/xdxf.") + format;
+
+    _infoNote="path=\""+initialPath+"\">"+"\n" + _name + " [" + _langFrom +
+            "-" + _langTo + "] "+ "(" + _type + ")";
 
     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;
@@ -371,6 +411,9 @@ int XdxfPlugin::countWords() {
 
     QFile dictionaryFile(path);
     if(!dictionaryFile.open(QFile::ReadOnly | QFile::Text)) {
+        Q_EMIT notify(Notify::Warning,
+                QString("Xdxf file cannot be read for %1 dictionary")
+                .arg(name()));
         qDebug()<<"Error: could not open file";
         return -1;
     }
@@ -391,8 +434,6 @@ int XdxfPlugin::countWords() {
     return wordsCount;
 }
 
-
-
 bool XdxfPlugin::makeCache(QString dir) {
     cachingDialog->setVisible(true);
     QCoreApplication::processEvents();
@@ -406,14 +447,21 @@ bool XdxfPlugin::makeCache(QString dir) {
 
 
     if (!dictionaryFile.open(QFile::ReadOnly | QFile::Text)) {
+        Q_EMIT updateCachingProgress(100, 0);
+        Q_EMIT notify(Notify::Warning,
+                QString("Xdxf file cannot be read for %1 dictionary")
+                .arg(name()));
         return 0;
     }
-
     QXmlStreamReader reader(&dictionaryFile);
 
     db.setDatabaseName(cachePathN);
     if(!db.open()) {
         qDebug() << "Database error" << db.lastError().text() << endl;
+        Q_EMIT updateCachingProgress(100, 0);
+        Q_EMIT notify(Notify::Warning, QString("Cache database cannot be "
+                "opened for %1 dictionary. Searching in xdxf file. "
+                "You may want to recache.").arg(name()));
         return false;
     }
     QCoreApplication::processEvents();
@@ -421,7 +469,7 @@ bool XdxfPlugin::makeCache(QString dir) {
     cur.exec("PRAGMA synchronous = 0");
     cur.exec("drop table dict");
     QCoreApplication::processEvents();
-    cur.exec("create table dict(word text ,translation text)");
+    cur.exec("create table dict(word text, normalized text ,translation text)");
     int counter = 0;
     cur.exec("BEGIN;");
 
@@ -446,31 +494,39 @@ bool XdxfPlugin::makeCache(QString dir) {
                 match = true;
             }
         }
-        else if(reader.tokenType() == QXmlStreamReader::Characters) {
-             if(match) {
-                QString temp(reader.text().toString());
-                temp.replace("\n","");
-                if(temp == ""){
-                    while(reader.name()!="ar"&&
-                                !reader.atEnd()){
-                        reader.readNext();
-                        temp+=reader.text().toString();
-                    }
-                }
-                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;
+        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().replace("<","&lt;").replace(">","&gt;");;
+                reader.readNext();
+            }
+            if(temp.at(0)==QChar('\n'))
+                temp.remove(0,1);
+            temp=tr("<key>") + a + tr("</key>") + tr("<t>") + temp+ tr("</t>");
+            match=false;
+            cur.prepare("insert into dict values(?,?,?)");
+            cur.addBindValue(a);
+            cur.addBindValue(removeAccents(a));
+            cur.addBindValue(temp);
+            cur.exec();
+            counter++;
+            int prog = counter*100/_wordsCount;
+            if(prog % 5 == 0 && lastProg != prog) {
+                qDebug() << prog;
+                Q_EMIT updateCachingProgress(prog,
+                                             timer.restart());
+                lastProg = prog;
             }
-
         }
     }
 
@@ -481,12 +537,19 @@ bool XdxfPlugin::makeCache(QString dir) {
     cachingDialog->setVisible(false);
 
     if(!cur.next() || countWords() != cur.value(0).toInt())
+    {
+        Q_EMIT updateCachingProgress(100, timer.restart());
+        Q_EMIT notify(Notify::Warning,
+                QString("Database caching error, please try againg."));
+        db.close();
         return false;
+    }
     _settings->setValue("cache_path", cachePathN);
     _settings->setValue("cached", "true");
 
+
+    db.close();
     return true;
 }
 
-
 Q_EXPORT_PLUGIN2(xdxf, XdxfPlugin)