Merge branch 'master' into google
[mdictionary] / trunk / src / plugins / xdxf / src / xdxfplugin.cpp
index c20185d..09af5e7 100644 (file)
 *******************************************************************************/
 
 /*! \file xdxfplugin.cpp
+\author Jakub Jaszczynski <j.j.jaszczynski@gmail.com>
 */
 
 #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);
+    _dictDialog = new XdxfDictDialog(this);
     cachingDialog = new XdxfCachingDialog(this);
 
+
     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()
-{
-    db.removeDatabase(_type+path);
+
+
+XdxfPlugin::~XdxfPlugin() {
+    delete _settings;
+    delete cachingDialog;
 }
 
+
 QString XdxfPlugin::langFrom() const {   
     return _langFrom;
 }
@@ -66,7 +71,6 @@ QString XdxfPlugin::name() const {
 }
 
 QString XdxfPlugin::type() const {
-//    return _settings->value("type");
     return _type;
 }
 
@@ -75,7 +79,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+="*";
@@ -85,53 +88,61 @@ QList<Translation*> XdxfPlugin::searchWordList(QString word, int limit) {
 }
 
 QList<Translation*> XdxfPlugin::searchWordListCache(QString word, int limit) {
-
+    int i=0;
     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);
-        }
+    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;
-        word = word.toLower();
-        word = word.replace("*", "%");
-        word = word.replace("?", "_");
-        word = removeAccents(word);
-        //qDebug() << word;
-
-        QSqlQuery cur(db);
-        if(limit !=0)
-            cur.prepare("select word from dict where word like ? limit ?");
-        else
-            cur.prepare("select word from dict where word like ?");
-        cur.addBindValue(word);
-        if(limit !=0)
-            cur.addBindValue(limit);
-        cur.exec();
-        while(cur.next()){
-            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));
+    stopped = false;
+    word = word.toLower();
+    word = word.replace("*", "%");
+    word = word.replace("?", "_");
+
+    QSqlQuery cur(db);
+    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);
+    if(limit !=0)
+        cur.addBindValue(limit);
+    cur.exec();
+    bool in = false;
+    while(cur.next() && (i<limit || limit==0 ) ) {
+        in = true;
+        bool ok=true;
+        Translation *tran;
+        foreach(tran,translations) {
+            if(tran->key().toLower()==cur.value(0).toString().toLower())
+                    ok=false;
         }
-        db.close();
-       return translations.toList();
+        if(ok) {  /*add key word to list*/
+            translations.insert(new TranslationXdxf(
+                    cur.value(0).toString().toLower(),
+                    _infoNote, this));
+            i++;
+        }
+    }
+    db.close();
+    return translations.toList();
 }
 
 QList<Translation*> XdxfPlugin::searchWordListFile(QString word, int limit) {
+    QTime time;
     QSet<Translation*> translations;
     QFile dictionaryFile(path);
 
     word = word.toLower();
-    word = removeAccents(word);
+    //word = removeAccents(word);
 
     stopped = false;
     QRegExp regWord(word);
@@ -139,12 +150,15 @@ 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 reader(&dictionaryFile);
     /*search words list*/
     QString a;
+
     int i=0;
     while(!reader.atEnd() && !stopped){
         reader.readNextStartElement();
@@ -153,17 +167,19 @@ QList<Translation*> XdxfPlugin::searchWordListFile(QString word, int limit) {
                 reader.readNextStartElement();
             if(!reader.atEnd())
                 a = reader.readElementText();
-            if(regWord.exactMatch(removeAccents(a)) && (i<limit || limit==0)) {
+            if((regWord.exactMatch(a) || regWord.exactMatch(removeAccents(a))) &&
+                    (i<limit || limit==0)) {
                 bool ok=true;
                 Translation *tran;
                 foreach(tran,translations) {
                     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*/
+                if(ok) {  /*add key word to list*/
                     translations<<(new TranslationXdxf(a.toLower(),
                                 _infoNote,this));
-                i++;
+                    i++;
+                }
                 if(i>=limit && limit!=0)
                     break;
             }
@@ -190,6 +206,9 @@ QString XdxfPlugin::searchCache(QString key) {
 
     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);
     }
 
@@ -199,7 +218,9 @@ QString XdxfPlugin::searchCache(QString key) {
     cur.exec();
     while(cur.next())
         result += cur.value(0).toString();
+
     db.close();
+
     return result;
 
 }
@@ -209,13 +230,12 @@ QString XdxfPlugin::searchFile(QString key) {
     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 reader(&dictionaryFile);
-
-
-
     QString a;
 
     bool match =false;
@@ -238,11 +258,14 @@ QString XdxfPlugin::searchFile(QString key) {
                     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("\"");
+                    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;");
+                temp+= reader.text().toString().replace("<","&lt;").
+                        replace(">","&gt;");
                 reader.readNext();
             }
             if(temp.at(0)==QChar('\n'))
@@ -275,23 +298,21 @@ void XdxfPlugin::setPath(QString path){
 
 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");
-//        if(!plugin->db.connectionName().isEmpty() || settings->value("generateCache")=="true")
-            plugin->db = QSqlDatabase::addDatabase("QSQLITE", plugin->db_name);
+                         + plugin->_settings->value("path");
+        plugin->db = QSqlDatabase::addDatabase("QSQLITE", plugin->db_name);
 
         if(settings->value("cached").isEmpty() &&
            settings->value("generateCache") == "true") {
             plugin->makeCache("");
         }
+        foreach(QString key, list)
+           if(key != "generateCache")
+                plugin->settings()->setValue(key, settings->value(key));
         delete settings;
     }
     plugin->getDictionaryInfo();
@@ -302,47 +323,68 @@ bool XdxfPlugin::isAvailable() const {
     return true;
 }
 
+
+
 void XdxfPlugin::setHash(uint _hash) {
     this->_hash=_hash;
 }
 
+
+
 uint XdxfPlugin::hash() 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) {
+    if(settings)
+    {
+        QString oldPath = _settings->value("path");
+        if(oldPath != settings->value("path")) {
+            setPath(settings->value("path"));
+        }
 
-    QString oldPath = _settings->value("path");
-    if(oldPath != settings->value("path")) {
-        setPath(settings->value("path"));
-    }
+       foreach(QString key, settings->keys())
+           if(key != "generateCache")
+               _settings->setValue(key, settings->value(key));
 
-    if((_settings->value("cached") == "false" ||
-        _settings->value("cached").isEmpty()) &&
-       settings->value("generateCache") == "true") {
-        makeCache("");
-    }
-    else {
-       _settings->setValue("cached", "false");
-    }
-    delete settings;
+        if((_settings->value("cached") == "false" ||
+                _settings->value("cached").isEmpty()) &&
+                settings->value("generateCache") == "true") {
+            makeCache("");
+        }
+        else if (settings->value("generateCache") != "true") {
+           _settings->setValue("cached", "false");
+        }
 
-    emit settingsChanged();
+        getDictionaryInfo();
+        delete settings;
+    }
+    Q_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;
     }
@@ -364,35 +406,12 @@ void XdxfPlugin::getDictionaryInfo() {
 
     QString format = "png";
     QString initialPath = QDir::currentPath() + tr("/xdxf.") + format;
-//  qDebug()<<initialPath;
-//  QPixmap test(":/icons/xdxf.png");
-//  qDebug()<<QPixmap(test).save(initialPath,format.toAscii());
-//  qDebug()<<QPixmap("/home/jakub/star.jpg").save(initialPath,format.toAscii());
-
-    _infoNote="<info path=\""+initialPath+"\">"+"\n" + _name + " [" + _langFrom + "-" + _langTo + "] "+ "(" + _type + ")"  + "</info>";
-
-
 
+    _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;
@@ -404,6 +423,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;
     }
@@ -424,7 +446,7 @@ int XdxfPlugin::countWords() {
     return wordsCount;
 }
 
-bool XdxfPlugin::makeCache(QString dir) {
+bool XdxfPlugin::makeCache(QString) {
     cachingDialog->setVisible(true);
     QCoreApplication::processEvents();
     stopped = false;
@@ -435,16 +457,23 @@ bool XdxfPlugin::makeCache(QString dir) {
 
     QFile dictionaryFile(dictFileN.filePath());
 
-
     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();
@@ -452,7 +481,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;");
 
@@ -464,6 +493,9 @@ bool XdxfPlugin::makeCache(QString dir) {
 
     int lastProg = -1;
 
+    QString stripAcc = settings()->value("strip_accents");
+    settings()->setValue("strip_accents", "true");
+
 
     counter=0;
     while (!reader.atEnd() && !stopped) {
@@ -497,8 +529,9 @@ bool XdxfPlugin::makeCache(QString dir) {
                 temp.remove(0,1);
             temp=tr("<key>") + a + tr("</key>") + tr("<t>") + temp+ tr("</t>");
             match=false;
-            cur.prepare("insert into dict values(?,?)");
+            cur.prepare("insert into dict values(?,?,?)");
             cur.addBindValue(a);
+            cur.addBindValue(removeAccents(a));
             cur.addBindValue(temp);
             cur.exec();
             counter++;
@@ -513,18 +546,23 @@ bool XdxfPlugin::makeCache(QString dir) {
 
     cur.exec("END;");
     cur.exec("select count(*) from dict");
+    settings()->setValue("strip_accents", stripAcc);
 
     countWords();
     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;
 }