Added multi-dictionary handling
authorBartosz Szatkowski <bulislaw@linux.com>
Thu, 5 Aug 2010 11:52:32 +0000 (13:52 +0200)
committerBartosz Szatkowski <bulislaw@linux.com>
Thu, 5 Aug 2010 11:52:32 +0000 (13:52 +0200)
Commit has two part (sadly couldnt divide it to few separate)
* Changed dictionaries->translation handling to QFuture and timer events
    (earlier it was based on signals)

* Added possibility of handling multiple dictionaries/plugins at one time

trunk/src/base/backbone/backbone.cpp
trunk/src/base/backbone/backbone.h
trunk/src/includes/settings.h
trunk/tests/mDictionaryTests/CommonDictInterfaceMock.h
trunk/tests/mDictionaryTests/tst_Backbone.cpp

index 9be3804..f0251c5 100644 (file)
 
 #include "backbone.h"
 #include <QDebug>
+
+void Backbone::init() {
+   _searchLimit = 10;
+   _interval = 250; //msec
+   loadPlugins();
+   if(!connect(&_timer, SIGNAL(timeout()), this, SLOT(translation())))
+       qDebug() << "Timer signal not connected";
+}
+
 Backbone::Backbone(QObject *parent)
     : QObject(parent)
 {
-   searchLimitv = 10;
-   loadPlugins();
+    init();
 }
 
 
 
 Backbone::~Backbone()
 {
-    QListIterator<CommonDictInterface*> it(dicts.keys());
+    QListIterator<CommonDictInterface*> it(_dicts.keys());
 
     while(it.hasNext())
         delete it.next();
 
-    it = QListIterator<CommonDictInterface*>(plugins);
+    it = QListIterator<CommonDictInterface*>(_plugins);
     while(it.hasNext())
         delete it.next();
 
@@ -53,31 +61,32 @@ Backbone::~Backbone()
 
 
 Backbone::Backbone(const Backbone &b) :QObject(b.parent()) {
-    dicts = QHash<CommonDictInterface*, bool > (b.dicts);
-    plugins = QList<CommonDictInterface* > (b.plugins);
+    init();
+    _dicts = QHash<CommonDictInterface*, bool > (b._dicts);
+    _plugins = QList<CommonDictInterface* > (b._plugins);
     _result = QHash<QString, Translation* > (b._result);
-    searchLimitv = b.searchLimit();
+    _searchLimit = b.searchLimit();
 }
 
 
 
 
 int Backbone::searchLimit() const {
-    return searchLimitv;
+    return _searchLimit;
 }
 
 
 
 
 QHash<CommonDictInterface*, bool > Backbone::getDictionaries() {
-    return dicts;
+    return _dicts;
 }
 
 
 
 
 QList<CommonDictInterface* > Backbone::getPlugins() {
-    return plugins;
+    return _plugins;
 }
 
 
@@ -98,7 +107,9 @@ QMultiHash<QString, Translation*> Backbone::result() {
 
 
 void Backbone::stopSearching() {
-    foreach(CommonDictInterface* dict, dicts.keys())
+    _timer.stop();
+    _innerResult.clear();
+    foreach(CommonDictInterface* dict, _dicts.keys())
         dict->stop();
 }
 
@@ -107,40 +118,39 @@ void Backbone::stopSearching() {
 
 void Backbone::search(QString word) {
     //TODO add running searches in new threads
+    _timer.stop();
     _result.clear();
-    activeSearchNum = 0;
-    foreach(CommonDictInterface* dict, dicts.keys())
-        if(dicts[dict] == 1) {
-            activeSearchNum ++;
+    _innerResult.clear();
+
+    _timer.start(_interval);
+    foreach(CommonDictInterface* dict, _dicts.keys())
+        if(_dicts[dict] == 1) {
+            QFuture<QList<Translation*> > tr =
+                    QtConcurrent::run(dict,
+                                      &CommonDictInterface::searchWordList,word,
+                                                             searchLimit());
+            _innerResult.append(tr);
         }
 
-    foreach(CommonDictInterface* dict, dicts.keys())
-        if(dicts[dict] == 1) {
-            translation(dict->searchWordList(word, searchLimit()));
-        }
 }
 
 
 
 
  void Backbone::selectedDictionaries(QList<CommonDictInterface* > activeDicts) {
-     foreach(CommonDictInterface* dict, dicts.keys())
+     foreach(CommonDictInterface* dict, _dicts.keys())
          if(activeDicts.contains(dict))
-             dicts[dict] = 1;
+             _dicts[dict] = 1;
          else
-             dicts[dict] = 0;
+             _dicts[dict] = 0;
  }
 
 
 
 
  void Backbone::addDictionary(CommonDictInterface* dict) {
-     dicts[dict] = 1;
-
-     //connect(dict, SIGNAL(finalTranslation()),
-      //       this, SLOT(translation()),
-      //       Qt::UniqueConnection);
-
+     dict->setHash(_dicts.size()+1);
+     _dicts[dict] = 1;
  }
 
 
@@ -153,21 +163,24 @@ void Backbone::search(QString word) {
 
 
 int Backbone::activeSearches() const {
-    return activeSearchNum;
+    return _innerResult.size();
 }
 
 
 
-void Backbone::translation(QList<Translation *> trans) {
-    activeSearchNum--;
-    foreach(Translation* t, trans)
-    {
-        _result.insert(t->key(), t);
-        qDebug()<<t->key();
+void Backbone::translation() {
+    foreach(QFuture<QList<Translation*> > trans, _innerResult) {
+        if(!trans.isFinished())
+            continue;
+        QList<Translation*> tList = trans.result();
+        foreach(Translation* t, tList)
+            _result.insert(t->key(), t);
+        _innerResult.removeOne(trans);
     }
-
-    if(activeSearchNum < 1)
+    if(!_innerResult.size()) {
+        _timer.stop();
         Q_EMIT ready();
+    }
 }
 
 
@@ -175,8 +188,7 @@ void Backbone::translation(QList<Translation *> trans) {
 
 void Backbone::loadPlugins() {
     QPluginLoader loader("xdxf.so");
-    if(!loader.load())
-    {
+    if(!loader.load()) {
         qDebug()<<loader.errorString();
         return;
     }
@@ -184,8 +196,8 @@ void Backbone::loadPlugins() {
 
     qDebug()<<"loaded";
     CommonDictInterface *plugin = qobject_cast<CommonDictInterface*>(pl);
-    plugins.append(plugin);
-    addDictionary(plugin);
+    _plugins.append(plugin);
+    addDictionary(plugin->getNew(0)); //TODO change 0 to real settings
 }
 
 
index 76dff08..fa4cba8 100644 (file)
 #include <QList>
 #include <QHash>
 #include <QPluginLoader>
+#include <QFuture>
+#include <QtConcurrentRun>
+#include <QTimer>
+#include <QTime>
 #include "../../includes/CommonDictInterface.h"
 #include "../../includes/settings.h"
 #include "../../includes/translation.h"
@@ -80,7 +84,7 @@ public Q_SLOTS:
 
 
     //! Fired when dictionary call finalTranslation(..) with translation ready
-    void translation(QList<Translation*>);
+    void translation();
 
     // TODO void removeDictionary(CommonDictInterface* dict);
     // TODO addToBookmark(Translation*);
@@ -98,11 +102,17 @@ Q_SIGNALS:
 
 private:
     void loadPlugins(); //< locate and load plugins
-    QHash<CommonDictInterface*, bool> dicts;
-    QList<CommonDictInterface*> plugins;
+    QHash<CommonDictInterface*, bool> _dicts;
+    QList<CommonDictInterface*> _plugins;
+    QList<QFuture<QList<Translation*> > > _innerResult;
     QMultiHash<QString, Translation*> _result;
-    int searchLimitv;
-    int activeSearchNum;
+    QTimer _timer;
+    int _searchLimit;
+    int _activeSearchNum;
+    QTime _time;
+    int _interval; //Search fetching timer.timeout interval in msec
+
+    void init();
 
 };
 
index 6a05410..be73d72 100644 (file)
@@ -37,7 +37,7 @@ class Settings {
     //! \retrun value fo given key
     //! \param key
     QString value(const QString key) const {
-        if(!settings.contains(key)) return QString;
+        if(!settings.contains(key)) return QString();
         return settings[key];
     }
 
index 1dc77e5..c4d0db0 100644 (file)
@@ -35,6 +35,7 @@ class CommonDictInterfaceMock : public CommonDictInterface
 public:
     QString fromv, tov, namev, typev, infoNotev;
     bool available,stopped;
+    uint _hash;
     CommonDictInterfaceMock(QObject* parent = 0) :
             CommonDictInterface(parent) {}
 
@@ -47,22 +48,23 @@ public:
     QDialog* settingsDialog() {return 0;}
     CommonDictInterface* getNew(const Settings *) const { return 0;}
     bool isAvailable() const {return available;}
-    uint hash() const { return namev.length() + 10*typev.length();}
+    uint hash() const { return _hash;}
+    void setHash(uint h) {_hash = h;}
     void stop() {stopped = 1;}
     QString search(QString key) {}
     QList<Translation*> searchWordList(QString word, int limit) {
+        qDebug() << "search " << this->thread()->currentThreadId();
         stopped = 0;
         QList<Translation*> list;
 
         TranslationMock *tm = new TranslationMock();
-        tm->_key = fromv;
-        tm->_translation = tov;
+        tm->_key = langFrom();
+        tm->_translation = langTo();
         TranslationMock *tm1 = new TranslationMock();
-        tm1->_key = namev;
-        tm1->_translation = typev;
+        tm1->_key = name();
+        tm1->_translation = type();
         list << tm << tm1;
 
-        Q_EMIT finalTranslation();
         return list;
     }
 
index 8098aed..047ebe1 100644 (file)
@@ -37,6 +37,7 @@ class BackboneTest : public QObject
     QList<CommonDictInterface*> dict;
     int total;
     Backbone* back;
+
 public:
     BackboneTest();
 
@@ -151,7 +152,9 @@ void BackboneTest::searchTest() {
         QCOMPARE(m->stopped, 1);
     }
 
+    qDebug() << "main " << this->thread()->currentThreadId();
     back->search("pigwa");
+    usleep(2000);
 
     for(int i = 0; i < total; i++) {
         CommonDictInterfaceMock *m = (CommonDictInterfaceMock*)dict[i];
@@ -167,20 +170,15 @@ void BackboneTest::translationTest() {
     QSignalSpy translatS(back, SIGNAL(ready()));
     QVERIFY2 (translatS.isValid() == true, "ready() signal is invalid");
 
-    qRegisterMetaType<Translation*>("Translation*");
-    qRegisterMetaType<QList<Translation*> >("QList<Translation*>");
     for(int i = 0; i < total; i++) {
         CommonDictInterfaceMock *m = (CommonDictInterfaceMock*) dict[i];
         m->stopped = 1;
         back->addDictionary(dict[i]);
-        ss.append(new QSignalSpy(m,SIGNAL(finalTranslation())));
-        QVERIFY2(ss[i]->isValid() == 1, "Signal invalid");
     }
 
     back->search("nic");
-    for(int i = 0; i < total; i++) {
-        QVERIFY2(ss[i]->count() == 1, "Translation signal lost");
-    }
+    usleep(2000);
+    back->translation();
 
     QVERIFY2(translatS.count() == 1, "Lost finall 'ready()' signal");
     QVERIFY2(back->result().size() == total*2, "Lost some of translations");