Merge branch 'master' into qmake
authorMateusz Półrola <mateusz.polrola@comarch.pl>
Thu, 2 Sep 2010 12:18:31 +0000 (14:18 +0200)
committerMateusz Półrola <mateusz.polrola@comarch.pl>
Thu, 2 Sep 2010 12:18:31 +0000 (14:18 +0200)
Conflicts:
mdictionary.pro
src/mdictionary/gui/WordListWidget.cpp
trunk/src/base/base.pro
trunk/src/plugins/xdxf/src/src.pro

17 files changed:
1  2 
src/common/translation.h
src/mdictionary/backbone/BookmarkTranslations.h
src/mdictionary/backbone/Bookmarks.cpp
src/mdictionary/backbone/Bookmarks.h
src/mdictionary/backbone/backbone.cpp
src/mdictionary/gui/DictManagerWidget.cpp
src/mdictionary/gui/SearchBarWidget.cpp
src/mdictionary/gui/TranslationWidget.cpp
src/mdictionary/gui/WordListWidget.cpp
src/mdictionary/gui/WordListWidget.h
src/plugins/google/GooglePlugin.cpp
src/plugins/google/GoogleSettingsDialog.cpp
src/plugins/xdxf/TranslationXdxf.cpp
src/plugins/xdxf/XdxfLoadDialog.cpp
src/plugins/xdxf/XdxfSettingsDialog.cpp
src/plugins/xdxf/xdxfplugin.cpp
tests/XdxfPluginTests/test.cpp

index 6fca57c,0000000..a6a20a9
mode 100644,000000..100644
--- /dev/null
@@@ -1,78 -1,0 +1,80 @@@
 +/*******************************************************************************
 +
 +    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.
 +
 +*******************************************************************************/
 +
 +/*! \file translation.h
 +\brief Interface for translation instances \see Translation
 +
 +\author Bartosz Szatkowski <bulislaw@linux.com>
 +*/
 +
 +#ifndef TRANSLATION_H
 +#define TRANSLATION_H
 +
 +#include <QString>
 +#include <QMetaType>
++#include <QDebug>
++
 +class CommonDictInterface;
 +
 +
 +/*! Translation is kind of GoF proxy, it stores key:translation pair and
 +  provides it in lazy way -> key is available always, but translation is fetched
 +  as late as possible*/
 +class Translation {
 +  public:
-     Translation  () { _bookmark = 0; }
++    Translation  () { _bookmark = 0;}
 +    virtual ~Translation () {}
 +    //! \return word to be translated
 +    virtual QString key() const = 0;
 + 
 +    bool operator==(Translation* translation) {
 +        return this->key()==translation->key();
 +    }
 +
 +    /*! \returns dictionary information (plugin name, languages, <logo> etc)\
 +         to be displayed in translation table header */
 +    virtual QString dictionaryInfo() const = 0;
 +
 +    //! \return parsed raw format into html
 +    virtual QString toHtml() const = 0;
 +
 +    //! \return whether given translation is taken from bookmarks
 +    virtual bool isBookmark() const {
 +        return _bookmark;
 +   }
 +
 +   //! \param b if true then translation is from bookmarks
 +   void setBookmark(bool b) {
 +       _bookmark = b;
 +   }
 +
 +    //! returns coresponding dict object
 +   virtual uint dict() const {return 0;}
 +
 +   protected:
 +       bool _bookmark;
 +
 +};
 +
 +Q_DECLARE_METATYPE(Translation*);
 +Q_DECLARE_METATYPE(QList<Translation*>);
 +
 +#endif
index b3c5345,0000000..0748d30
mode 100644,000000..100644
--- /dev/null
@@@ -1,90 -1,0 +1,91 @@@
 +/*******************************************************************************
 +
 +    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.
 +
 +*******************************************************************************/
 +
 +/*! \file BookmarkTranslation.h
 +\brief Bookmarks functionality needs its own translation  object - because
 +    Translation object should use slightly different api of Bookmarks objects
 +
 +\author Bartosz Szatkowski <bulislaw@linux.com>
 +*/
 +#ifndef BOOKMARKTRANSLATIONS_H
 +#define BOOKMARKTRANSLATIONS_H
 +
 +#include "../../common/settings.h"
 +#include "../../common/translation.h"
 +#include "Bookmarks.h"
++#include "QObject"
 +
 +
 +
 +class BookmarkTranslation : public Translation
 +{
 +public:
-     BookmarkTranslation(QString key, Bookmarks* bookmarks, QString dbName) {
++    BookmarkTranslation(QString key, Bookmarks* bookmarks, QString dbName){
 +        _key = key;
 +        _dictionaryInfo = dbName;
 +        _bookmarks = bookmarks;
 +        _bookmark = 1;
 +    }
 +
 +    //! \return word to be translated
 +    QString key() const {
 +        return _key;
 +    }
 +
 +    /*! \returns dictionary information (plugin name, languages, <logo> etc)\
 +        to be displayed in translation table header*/
 +    QString dictionaryInfo() const {
 +        return _dictionaryInfo;
 +    }
 +
 +    //! \return parsed raw format into html
 +    QString toHtml() const {
 +        if(!_key.size() || !_bookmarks)
 +            return "";
 +
 +        QStringList list = _bookmarks->search(_key, _dictionaryInfo);
 +        QString result;
 +        foreach(QString translation, list)
 +            result += translation + "\n";
 +        return result;
 +
 +    }
 +
 +    /*! sets the word for which we want to find a translation
 +        \param word for which we want to find a translation */
 +    void setKey(QString key) {
 +        _key = key;
 +    };
 +
 +    //! sets information about dictionary
 +    void setDictionaryInfo(QString dictionaryInfo) {
 +        _dictionaryInfo = dictionaryInfo;
 +    }
 +
 +
 +private:
 +    QString _key;
 +    QString _dictionaryInfo;
 +    Bookmarks* _bookmarks;
 +
 +};
 +
 +#endif // HISTORYTRANSLATION_H
index 527a8a5,0000000..c39f868
mode 100644,000000..100644
--- /dev/null
@@@ -1,167 -1,0 +1,175 @@@
 +#include "Bookmarks.h"
 +#include "BookmarkTranslations.h"
 +#include <QThread>
 +
 +Bookmarks::Bookmarks() {
 +    this->dbName = QDir::homePath() + "/.mdictionary/"
 +                 + "bookmarks.db";
 +    checkAndCreateDb();
 +    initAccents();
++
++    mdb = QSqlDatabase::addDatabase("QSQLITE",
++            QString("%2").arg((int)QThread::currentThreadId()));
++    mdb.setDatabaseName(dbName);
++}
++
++
++Bookmarks::~Bookmarks() {
++    mdb.close();
 +}
 +
 +
 +QSqlDatabase Bookmarks::getDbCnx(QString dbName) {
++    QSqlDatabase::removeDatabase(
++            QString("%2").arg((int)QThread::currentThreadId()));
 +    QSqlDatabase db =QSqlDatabase::addDatabase("QSQLITE",
 +            QString("%2").arg((int)QThread::currentThreadId()));
 +    db.setDatabaseName(dbName);
 +    return db;
 +}
 +
 +
 +
 +bool Bookmarks::checkAndCreateDb() {
 +    QSqlDatabase db = getDbCnx(dbName);
 +    db.open();
 +    QSqlQuery cur(db);
 +    cur.exec("create table bookmarks(key text, normalized text, translation text)");
 +    db.close();
 +    return true;
 +}
 +
 +
 +
 +void Bookmarks::clear() {
 +    checkAndCreateDb();
 +    QSqlDatabase db = getDbCnx(dbName);
 +    if(!db.isOpen() && !db.open()) {
 +        qDebug() << "Database error: " << db.lastError().text() << endl;
 +        return ;
 +    }
 +    QSqlQuery cur(db);
 +    cur.exec("drop table bookmarks");
 +    cur.exec("create table bookmarks(key text, normalized text,translation text)");
 +    db.close();
 +}
 +
 +
 +
 +void Bookmarks::add(Translation* translation) {
 +    checkAndCreateDb();
 +    QSqlDatabase db = getDbCnx(dbName);
 +    if(!db.isOpen() && !db.open()) {
 +        qDebug() << "Database error: " << db.lastError().text() << endl;
 +        return ;
 +    }
 +    translation->setBookmark(true);
 +    QSqlQuery cur(db);
 +    cur.prepare("insert into bookmarks values (?,?,?)");
 +    cur.addBindValue(translation->key());
 +    cur.addBindValue(removeAccents(translation->key()));
 +    cur.addBindValue(translation->toHtml());
 +    cur.exec();
 +    db.close();
 +}
 +
 +
 +void Bookmarks::remove(Translation* translation) {
 +    checkAndCreateDb();
 +    QSqlDatabase db = getDbCnx(dbName);
 +    if(!db.isOpen() && !db.open()) {
 +        qDebug() << "Database error: " << db.lastError().text() << endl;
 +        return ;
 +    }
 +    QSqlQuery cur(db);
 +    cur.prepare("delete from bookmarks where key=?");
 +    cur.addBindValue(translation->key());
 +    cur.exec();
 +    db.close();
 +}
 +
 +
 +
 +QList<Translation*> Bookmarks::list() {
 +    checkAndCreateDb();
 +    QList<Translation*> res;
 +    QSqlDatabase db = getDbCnx(dbName);
 +    if(!db.isOpen() && !db.open()) {
 +        qDebug() << "Database error: " << db.lastError().text() << endl;
 +        return res;
 +    }
 +    QSqlQuery cur(db);
 +    cur.exec("select distinct key from bookmarks");
 +    while(cur.next())
-         res.append(new BookmarkTranslation(cur.value(0).toString(), this, dbName));
++        res.append(new BookmarkTranslation(cur.value(0).toString(),
++                this, dbName));
 +    db.close();
 +    return res;
 +}
 +
 +
 +
 +QList<Translation*> Bookmarks::searchWordList(QString word) {
 +    checkAndCreateDb();
 +    if(word.indexOf("*")==-1 && word.indexOf("?")== -1)
 +        word+="%";
 +    word = word.replace("*", "%");
 +    word = word.replace("?", "_");
-     qDebug() << word;
 +
 +    QList<Translation*> tr;
 +    QSqlDatabase db = getDbCnx(dbName);
 +    if(!db.isOpen() && !db.open()) {
 +        qDebug() << "Database error: " << db.lastError().text() << endl;
 +        return tr;
 +    }
 +    QSqlQuery cur(db);
 +    cur.prepare("select key from bookmarks where key like ? or normalized like ?");
 +    cur.addBindValue(word);
 +    cur.addBindValue(word);
 +    cur.exec();
 +    QSet<QString> res;
 +    while(cur.next())
 +        res.insert(cur.value(0).toString());
 +    foreach(QString str, res.toList())
 +        tr.append(new BookmarkTranslation(str, this, dbName));
 +    db.close();
 +    return tr;
 +}
 +
 +
 +
 +QStringList Bookmarks::search(QString word, QString dbName) {
-     checkAndCreateDb();
++    //checkAndCreateDb();
 +    QStringList result;
 +    QSqlDatabase db = getDbCnx(dbName);
 +    if(!db.isOpen() && !db.open()) {
 +        qDebug() << "Database error: " << db.lastError().text() << endl;
 +        return result;
 +    }
 +    QSqlQuery cur(db);
 +    cur.prepare("select translation from bookmarks where key=?");
 +    cur.addBindValue(word);
 +    cur.exec();
 +    while(cur.next())
 +        result << cur.value(0).toString();
 +
 +    db.close();
 +    return result;
 +}
 +
 +
 +
 +
 +bool Bookmarks::inBookmarks(QString word) {
-     checkAndCreateDb();
-     QSqlDatabase db = getDbCnx(dbName);
-     if(!db.isOpen() && !db.open()) {
-         qDebug() << "Database error: " << db.lastError().text() << endl;
++    if(!mdb.isOpen() && !mdb.open()) {
++        qDebug() << "Database error: " << mdb.lastError().text() << endl;
 +        return false;
 +    }
-     QSqlQuery cur(db);
++    QSqlQuery cur(mdb);
 +    cur.prepare("select translation from bookmarks where key like ? limit 1");
 +    cur.addBindValue(word);
 +    cur.exec();
 +    if(cur.next())
 +        return true;
-     db.close();
 +    return false;
 +}
index 8fa5d66,0000000..d0fea98
mode 100644,000000..100644
--- /dev/null
@@@ -1,109 -1,0 +1,111 @@@
 +/*******************************************************************************
 +
 +    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.
 +
 +*******************************************************************************/
 +
 +/*! \file Bookmarks.h
 +\brief Bookmarks functionality - marking words as favorite, managing marked
 +    words, searching in marked words (with cached translations)
 +
 +
 +\author Bartosz Szatkowski <bulislaw@linux.com>
 +*/
 +
 +#ifndef BOOKMARKS_H
 +#define BOOKMARKS_H
 +
 +#include <QtSql>
 +#include <QString>
 +#include <QVariant>
 +#include <QStringList>
 +#include <QList>
 +#include <QSqlQuery>
 +#include <QSqlDatabase>
 +#include <QSqlError>
 +#include <QDir>
 +#include <QDebug>
 +#include "../../common/settings.h"
 +#include "../../common/translation.h"
 +#include "../../common/AccentsNormalizer.h"
 +class BookmarkTranslation;
 +
 +
 +/*! Bookmarks are way to store words that You think You will need to search
 +  for often.
 +
 +  When You add bookmark (by clickin on "star" in words list) You add it to
 +  special list with cached translations from all available dictionaries so
 +  You can search for them quickly even when You delete corresponding dict.
 +  */
 +class Bookmarks : public AccentsNormalizer {
 +public:
 +    Bookmarks();
++    ~Bookmarks();
 +
 +    /*! Adds new word and translation to bookmarks
 +      \param translation new translation to be saved and cached as a bookmark
 +    */
 +    void add(Translation* translation);
 +
 +    /*! Removes word and corresponding translation cache from bookmark list
 +        \param translation translation to be removed
 +    */
 +    void remove(Translation* translation);
 +
 +    /*! \return all bookmarks (word and translation as a translation object
 +     as a list)
 +     */
 +    QList<Translation*> list();
 +
 +    /*! Searches in bookmarks for given word (wildcards may apply '*' and '?')
 +      \param word to search for
 +      \return list of matching Translation objects
 +      */
 +    QList<Translation*> searchWordList(QString word);
 +
 +    /*! Searches for final translation of given word
 +      \return word translation list in text format xml or html to be formatted
 +        and displayed
 +      \param word word to search for
 +      */
 +    QStringList search(QString word, QString dbname);
 +
 +
 +    /*! Clears bookmarks database */
 +    void clear();
 +
 +
 +    /*! \return true if given word is already in bookmarks
 +      \param word to check
 +      */
 +    bool inBookmarks(QString word);
 +
 +private:
 +    bool checkAndCreateDb();
 +
 +    
 +    QString dbName;
 +    QSqlDatabase getDbCnx(QString dbName);
 +    QMap<QChar, QRegExp> letters;
 +    QRegExp noLetter;
++    QSqlDatabase mdb;
 +
 +};
 +
 +#endif // BOOKMARKS_H
index 4bbbd78,0000000..16bb487
mode 100644,000000..100644
--- /dev/null
@@@ -1,625 -1,0 +1,629 @@@
 +/*******************************************************************************
 +
 +    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.
 +
 +*******************************************************************************/
 +/*! \file backbone.cpp
 +\brief Backbone/core main file \see Backbone
 +
 +
 +\author Bartosz Szatkowski <bulislaw@linux.com>
 +*/
 +
 +#include "backbone.h"
 +#include "ConfigGenerator.h"
 +class ConfigGenerator;
 +#include <QDebug>
 +
 +int Backbone::_searchLimit;
 +
 +// Sadly QtConcurent::mapped dosent let me use something like calling method of
 +// some class with supplied argument; so i have to sin against art and put
 +// global function and variable so i could supply function with some parametr
 +QString mappedSearch;
 +QList<Translation*> mapSearch(CommonDictInterface *dict) {
 +    if(dict)
 +        return dict->searchWordList(mappedSearch, Backbone::_searchLimit);
 +    return QList<Translation*>();
 +}
 +
 +
 +
 +/*! Smart pointer (kind of) for translation object
 +
 +    QtConcurent::mapped  use collection of data and one function, what i need is
 +    to map signle data object to method calls for multiple objects. TranslationPtr
 +    is try to store method call as a data -> moreover QtConcurent allow only for
 +    methods without any parameters so TranslationPtr is created with Translation
 +    object -> ready to call toHtml() for supplied Translation.
 +
 +    Another thing is that QtConcurent dont like pointers in data collection
 +    so TranslationPtr is way to hide real translation object (pointer for object)
 +    */
 +class TranslationPtr {
 +    Translation* _tr;
 +public:
 +    TranslationPtr(Translation* tr) :_tr(tr) {}
 +
 +    /*! \return translation text for corresponding Translation object */
 +    QString toHtml() const {
 +        QString trans;
 +        trans = _tr->toHtml();
 +        return trans;
 +
 +    }
 +};
 +
 +void Backbone::init() {
 +
 +   _dictNum = 0;
 +   _dir = QDir::homePath() + "/.mdictionary/";
 +   if(!QDir(_dir).exists())
 +       QDir().mkdir(_dir);
 +
 +   if(!_configPath.size())
 +       _configPath = _dir + "mdictionary.config";
 +   if(!_pluginPath.size())
 +       _pluginPath = "/usr/lib/mdictionary/plugins";
 +
 +   //Install default config files
 +   ConfigGenerator confGen;
 +   confGen.generateCss(_dir + "style.css");
 +   confGen.generateDefaultConfig(_configPath);
 +
 +   loadPrefs(_configPath);
 +
 +   loadPlugins();
 +
 +   loadDicts(_configPath);
 +
 +   connect(&_resultWatcher, SIGNAL(finished()), this, SLOT(translationReady()));
 +   connect(&_htmlResultWatcher, SIGNAL(finished()), this,
 +           SLOT(htmlTranslationReady()));
 +   connect(&_bookmarkWatcher, SIGNAL(finished()), this,
 +           SLOT(bookmarksListReady()));
 +   connect(&_bookmarkSearchWatcher, SIGNAL(finished()), this,
 +           SLOT(translationReady()));
 +
 +   // In common opinion perfect thread count is cores_number+1 (in qt perfect
 +   // thread count is set to cores number
 +   QThreadPool::globalInstance()->setMaxThreadCount(
 +           QThreadPool::globalInstance()->maxThreadCount()+1);
 +
 +   _history = new History(_historyLen, this);
 +}
 +
 +
 +
 +Backbone::Backbone(QString pluginPath, QString configPath, bool dry,
 +                   QObject *parent)
 +    : QObject(parent)
 +{
 +    _pluginPath = pluginPath;
 +    _configPath = configPath;
 +
 +    dryRun = false;
 +    if(dry)
 +        dryRun = true;
 +    init();
 +}
 +
 +
 +
 +Backbone::~Backbone()
 +{
 +    QListIterator<CommonDictInterface*> it(_dicts.keys());
 +
 +    while(it.hasNext())
 +        delete it.next();
 +
 +    it = QListIterator<CommonDictInterface*>(_plugins);
 +    while(it.hasNext())
 +        delete it.next();
 +
 +    QHashIterator<QString, Translation*> it2(_result);
 +    while(it2.hasNext())
 +        delete it2.next().value();
 +
 +}
 +
 +
 +
 +
 +Backbone::Backbone(const Backbone &b) :QObject(b.parent()) {
 +    init();
 +    _dicts = QHash<CommonDictInterface*, bool > (b._dicts);
 +    _plugins = QList<CommonDictInterface* > (b._plugins);
 +    _result = QHash<QString, Translation* > (b._result);
 +    _searchLimit = b.searchLimit();
 +}
 +
 +
 +
 +
 +int Backbone::searchLimit() const {
 +    return _searchLimit;
 +}
 +
 +
 +
 +QHash<CommonDictInterface*, bool > Backbone::getDictionaries() {
 +    return _dicts;
 +}
 +
 +
 +
 +QList<CommonDictInterface* > Backbone::getPlugins() {
 +    return _plugins;
 +}
 +
 +
 +
 +History* Backbone::history() {
 +    return _history;
 +}
 +
 +
 +
 +QMultiHash<QString, Translation*> Backbone::result() {
 +    return _result;
 +}
 +
 +
 +
 +void Backbone::stopSearching() {
 +    if(stopped)
 +        return;
 +
 +    foreach(CommonDictInterface* dict, _dicts.keys())
 +        dict->stop();
 +    stopped = true;
 +    _innerHtmlResult.cancel();
 +    _innerResult.cancel();
 +    Q_EMIT searchCanceled();
 +}
 +
 +
 +
 +void Backbone::search(QString word){
 +    _result.clear();
 +    mappedSearch = word.toLower();
 +
 +    stopped = false;
 +
 +    // When dictFin and bookmarkFin is set to true then translationReady()
 +    // signal is emited see translationReady(),
 +    // so when searching only in one of them, coresponding *Fin is set to false
 +    // and other to true so program is waiting only for one translation
 +    dictFin = !_searchDicts;
 +    bookmarkFin = !_searchBookmarks;
 +
 +    if(!_searchDicts && !_searchBookmarks) {
 +        Q_EMIT ready();
 +        Q_EMIT notify(Notify::Warning, tr("You have to specify where You want "
 +                "to look for translations"));
 +    }
 +
 +    if (_searchDicts) {
 +        _innerResult = QtConcurrent::mapped(activeDicts(), mapSearch);
 +        _resultWatcher.setFuture(_innerResult);
 +    }
 +
 +    if(_searchBookmarks) {
 +        _innerBookmarks = QtConcurrent::run(_bookmarks,
 +                &Bookmarks::searchWordList, word);
 +        _bookmarkSearchWatcher.setFuture(_innerBookmarks);
 +    }
 +}
 +
 +
 +
 +void Backbone::selectedDictionaries(QList<CommonDictInterface* > activeDicts) {
 +    foreach(CommonDictInterface* dict, _dicts.keys())
 +        if(activeDicts.contains(dict))
 +            _dicts[dict] = 1;
 +        else
 +            _dicts[dict] = 0;
 +    dictUpdated();
 + }
 +
 +
 +
 +void Backbone::addDictionary(CommonDictInterface *dict, bool active) {
 +    addInternalDictionary(dict,active);
 +    dictUpdated();
 +}
 +
 +
 +
 + void Backbone::addInternalDictionary(CommonDictInterface* dict, bool active) {
 +     dict->setHash(++_dictNum); // Hash must be uniqe in every session but not between
 +     _dicts[dict] = active;
 +     connect(dict, SIGNAL(settingsChanged()), this, SLOT(dictUpdated()));
 +     connect(dict, SIGNAL(notify(Notify::NotifyType,QString)), this,
 +             SIGNAL(notify(Notify::NotifyType,QString)));
 + }
 +
 +
 +
 + void Backbone::removeDictionary(CommonDictInterface *dict) {
 +     _dicts.remove(dict);
-      dict->clean();
++     if(dict)
++        dict->clean();
++     else
++        qDebug()<<"delete empty dict";
 +     delete dict;
 +     dictUpdated();
 +
 + }
 +
 +
 +
 + void Backbone::quit() {
 +    stopSearching();
 +    Q_EMIT closeOk();
 +}
 +
 +
 +
 +void Backbone::translationReady() {
 +    bool changed = 0; // prevents doubling ready() signal, when both if's are
 +                      //  executed in one translationReady() call then second
 +                      // translationReady() call doubles ready*() emit
 +
 +    if(!dictFin && _innerResult.isFinished()) {
 +        changed = 1;
 +        dictFin = 1;
 +        QFutureIterator<QList<Translation*> > it(_innerResult);
 +
 +        while(it.hasNext()) {
 +            QList<Translation* > list = it.next();
 +            foreach(Translation* trans, list) {
 +                if(!trans)
 +                    continue;
 +                if(!_searchBookmarks)
 +                    trans->setBookmark(_bookmarks.
 +                            inBookmarks(trans->key()));
 +                _result.insert(trans->key().toLower(), trans);
 +           }
 +        }
 +    }
 +
 +    if(!bookmarkFin && _innerBookmarks.isFinished()) {
 +        changed = 1;
 +        bookmarkFin = 1;
 +        QList<Translation*> list = _innerBookmarks.result();
 +
 +        foreach(Translation* trans, list)
 +                _result.insert(trans->key().toLower(), trans);
 +    }
 +
 +    if(!stopped && bookmarkFin && dictFin && changed) {
 +        Q_EMIT ready();
 +    }
 +}
 +
 +
 +
 +
 +QStringList Backbone::getFilesFromDir(QString dir, QStringList nameFilter) {
 +    QDir plug(QDir::toNativeSeparators(dir));
 +    if(!plug.exists()) {
 +        qDebug() << plug.absolutePath() << " folder doesn't exist";
 +        Q_EMIT notify(Notify::Warning,
 +                QString("%1 folder doesn't exist.").arg(plug.path()));
 +        return QStringList();
 +    }
 +    plug.setFilter(QDir::Files);
 +    QStringList list = plug.entryList(nameFilter);
 +
 +    for(int i = 0; i < list.size(); i++)
 +        list[i] = plug.absoluteFilePath(list.at(i));
 +    return list;
 +}
 +
 +
 +void Backbone::loadPlugins() {
 +    if(dryRun)
 +        return;
 +    QStringList nameFilter;
 +    nameFilter << "*.so" << "*.so.*";
 +    QStringList files = getFilesFromDir(_pluginPath, nameFilter);
 +
 +    foreach(QString file, files) {
 +        QPluginLoader loader(file);
 +        if(!loader.load()) {
 +            Q_EMIT notify(Notify::Error,
 +                    QString("%1 plugin cannot be loaded: %2.")
 +                    .arg(file).arg(loader.errorString()));
 +            continue;
 +        }
 +        QObject *pl = loader.instance();
 +
 +        bool exists = 0;
 +        CommonDictInterface *plugin = qobject_cast<CommonDictInterface*>(pl);
 +        foreach(CommonDictInterface* pl, _plugins)
 +            if(pl->type() == plugin->type()) {
 +                exists = 1;
 +                break;
 +           }
 +        if(!exists)
 +            _plugins.append(plugin);
 +    }
 +}
 +
 +
 +
 +CommonDictInterface* Backbone::plugin(QString type) {
 +    foreach(CommonDictInterface* plugin, _plugins)
 +        if(plugin->type() == type)
 +            return plugin;
 +    return 0;
 +}
 +
 +
 +
 +void Backbone::loadPrefs(QString fileName) {
 +    if(dryRun)
 +        return;
 +    QFileInfo file(QDir::toNativeSeparators(fileName));
 +    QDir confDir(file.dir());
 +    if(!confDir.exists()){
 +        qDebug() << "Configuration file doesn't exist ("
 +                << file.filePath() << ")";
 +        Q_EMIT notify(Notify::Warning,
 +                QString("%1 configuration file doesn't exist.")
 +                .arg(file.filePath()));
 +        return;
 +    }
 +    QSettings set(file.filePath(), QSettings::IniFormat);
 +    _pluginPath = set.value("general/plugin_path", _pluginPath).toString();
 +    _historyLen = set.value("general/history_size", 10).toInt();
 +    _searchLimit = set.value("general/search_limit", 15).toInt();
 +    _searchBookmarks = set.value("general/search_bookmarks",1).toBool();
 +    _searchDicts = set.value("general/search_dictionaries",1).toBool();
 +    _zoom = set.value("general/zoom", 1.0).toReal();
 +}
 +
 +
 +
 +void Backbone::savePrefs(QSettings *set) {
 +    if(dryRun)
 +        return;
 +    set->setValue("general/plugin_path", _pluginPath);
 +    set->setValue("general/history_size", _historyLen);
 +    set->setValue("general/search_limit", _searchLimit);
 +    set->setValue("general/search_bookmarks", _searchBookmarks);
 +    set->setValue("general/search_dictionaries", _searchDicts);
 +    set->setValue("general/zoom", _zoom);
 +}
 +
 +
 +
 +void Backbone::loadDicts(QString fileName) {
 +    if(dryRun)
 +        return;
 +
 +    QFileInfo file(QDir::toNativeSeparators(fileName));
 +    QDir confDir(file.dir());
 +    if(!confDir.exists()){
 +        qDebug() << "Configuration file doesn't exist ("
 +                << file.filePath() << ")";
 +        Q_EMIT notify(Notify::Warning,
 +                QString("%1 configurationfile doesn't exist.")
 +                .arg(file.filePath()));
 +        return;
 +    }
 +
 +    QSettings set(file.filePath(), QSettings::IniFormat);
 +    QStringList dicts = set.childGroups();
 +    foreach(QString dict, dicts) {
 +        if(!dict.contains("dictionary_"))
 +            continue;
 +        CommonDictInterface* plug = plugin
 +                                    (set.value(dict + "/type", "").toString());
 +        if(!plug) {
 +            qDebug() << "Config file error: "
 +                    << set.value(dict + "/type", "").toString()
 +                    << " doesn't exist";
 +            Q_EMIT notify(Notify::Warning,
 +                    QString("Configuration file error. %2 plugin doesn't exist.")
 +                    .arg(set.value(dict + "/type", "").toString()));
 +            continue;
 +        }
 +        Settings* plugSet = new Settings();
 +        set.beginGroup(dict);
 +        QStringList items = set.childKeys();
 +        foreach(QString item, items) {
 +            plugSet->setValue(item, set.value(item, "").toString());
 +        }
 +        bool active = set.value("active",1).toBool();
 +
 +        set.endGroup();
 +        addInternalDictionary(plug->getNew(plugSet), active);
++        delete plugSet;
 +    }
 +}
 +
 +
 +
 +void Backbone::dictUpdated() {
 +    if(dryRun)
 +        return;
 +
 +    // For convienence this function is called for each change in dictionaries
 +    // and each call dumps configuration for all dictionaries into file.
 +    // Maybe better way would be to store new/changed configuration but
 +    // parsing settings file and figuring out what was changed, in my opinion,
 +    // would take more time
 +    _history->setMaxSize(_historyLen);
 +    QFileInfo file(QDir::toNativeSeparators(_configPath));
 +    QDir confDir(file.dir());
 +    if(!confDir.exists())
 +        confDir.mkpath(file.dir().path());
 +    QSettings set(file.filePath(), QSettings::IniFormat);
 +    set.clear();
 +
 +    savePrefs(&set);
 +
 +    foreach(CommonDictInterface* dict, _dicts.keys()){
 +        if(!dict || !dict->settings())
 +            continue;
 +        saveState(&set, dict->settings(), _dicts[dict], dict->hash());
 +    }
 +}
 +
 +
 +
 +void Backbone::saveState(QSettings* set, Settings* plugSet, bool active
 +                         , uint hash) {
 +    if(dryRun)
 +        return;
 +    if(!set || !plugSet)
 +        return;
 +
 +    QString section;
 +    section.append(QString("dictionary_%1").arg(hash));
 +    QList<QString> keys = plugSet->keys();
 +    foreach(QString key, keys)
 +        set->setValue(section + "/" + key, plugSet->value(key));
 +    set->setValue(section + "/active", active);
 +}
 +
 +
 +
 +QStringList Backbone::htmls() {
 +    return _htmlResult;
 +}
 +
 +
 +
 +void Backbone::searchHtml(QList<Translation *> translations) {
 +    _htmlResult.clear();
 +
 +    QList<TranslationPtr> dummy;
 +    stopped = false;
 +    foreach(Translation* tr, translations) {
 +         if(containsDict(tr->dict()) || !tr->dict())
 +            dummy.append(TranslationPtr(tr));
 +  /*      foreach(CommonDictInterface* dict, activeDicts()) {
 +            Translation* trans = dict->getTranslationFor(tr->key());
 +            if(trans)
 +                dummy.append(TranslationPtr(trans));
 +        } */
 +    }
 +    if(translations.size()>0) {
 +        Translation *tr = translations.at(0);
 +        foreach(CommonDictInterface* dict, activeDicts()) {
 +            Translation* trans = dict->getTranslationFor(tr->key());
 +            if(trans)
 +                dummy.append(TranslationPtr(trans));
 +        }
 +    }
 +
 +   _innerHtmlResult = QtConcurrent::mapped(dummy,
 +                                            &TranslationPtr::toHtml);
 +   _htmlResultWatcher.setFuture(_innerHtmlResult);
 +}
 +
 +
 +
 +void Backbone::htmlTranslationReady() {
 +
 +    QFutureIterator<QString> it(_innerHtmlResult);
 +    QSet<QString> uniqe;
 +    while(it.hasNext())
 +        uniqe.insert(it.next());
 +    _htmlResult.clear();
 +    _htmlResult = uniqe.toList();
 +
 +    if(!stopped)
 +        Q_EMIT htmlReady();
 +
 +}
 +
 +
 +QList<CommonDictInterface*> Backbone::activeDicts() {
 +    QList<CommonDictInterface*>res;
 +    foreach(CommonDictInterface* dict, _dicts.keys())
 +        if(_dicts[dict])
 +            res.append(dict);
 +    return res;
 +
 +}
 +
 +
 +
 +void Backbone::bookmarksListReady() {
 +   _bookmarksResult = _innerBookmarks.result();
 +   Q_EMIT bookmarksReady();
 +}
 +
 +
 +
 +
 +void Backbone::setSettings(Settings *settings) {
 +    _historyLen = settings->value("history_size").toInt();
 +    _searchLimit = settings->value("search_limit").toInt();
 +    if(settings->value("search_dictionaries") == "true")
 +        _searchDicts = 1;
 +    else
 +        _searchDicts = 0;
 +    if(settings->value("search_bookmarks") == "true")
 +        _searchBookmarks = 1;
 +    else
 +        _searchBookmarks = 0;
 +    _zoom = settings->value("zoom").toFloat();
 +    if(!_zoom)
 +        _zoom ++;
 +
 +    dictUpdated();
 +    if(settings)
 +        delete settings;
 +}
 +
 +
 +
 +
 +Settings* Backbone::settings() {
 +    Settings * settings = new Settings();
 +    settings->setValue("history_size", QString("%1").arg(_historyLen));
 +    settings->setValue("search_limit", QString("%1").arg(_searchLimit));
 +    settings->setValue("zoom", QString("%1").arg(_zoom));
 +    if(_searchBookmarks)
 +        settings->setValue("search_bookmarks", "true");
 +    else
 +        settings->setValue("search_bookmarks", "false");
 +
 +    if(_searchDicts)
 +        settings->setValue("search_dictionaries", "true");
 +    else
 +        settings->setValue("search_dictionaries", "false");
 +    return settings;
 +}
 +
 +
 +bool Backbone::containsDict(uint hash) const {
 +    QHashIterator<CommonDictInterface*, bool> it(_dicts);
 +    if (!hash)
 +        return false;
 +    while(it.hasNext())
 +        if(it.next().key()->hash() == hash)
 +            return true;
 +    return false;
 +}
index f0cae5f,0000000..4794eb1
mode 100644,000000..100644
--- /dev/null
@@@ -1,236 -1,0 +1,237 @@@
 +/*******************************************************************************
 +
 +    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.
 +
 +*******************************************************************************/
 +
 +//! \file DictManagerWidget.cpp
 +//! \author Mateusz Półrola <mateusz.polrola@comarch.pl>
 +
 +#include "DictManagerWidget.h"
 +#include "DictTypeSelectDialog.h"
 +#include <QDebug>
 +#include "../../common/DictDialog.h"
 +
 +DictManagerWidget::DictManagerWidget(GUIInterface *parent) :
 +    QDialog(parent) {
 +    setWindowTitle(tr("Dictionaries"));
 +    this->guiInterface = parent;
 +
 +    initalizeUI();
 +}
 +
 +void DictManagerWidget::initalizeUI() {
 +    verticalLayout = new QVBoxLayout;
 +    setLayout(verticalLayout);
 +
 +    dictListWidget = new QListWidget;
 +    verticalLayout->addWidget(dictListWidget);
 +
 +    dictListWidget->setSelectionMode(QAbstractItemView::SingleSelection);
 +    dictListWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
 +
 +    addNewDictButton = new QPushButton(tr("Add"));
 +    removeDictButton = new QPushButton(tr("Remove"));
 +    settingsButton = new QPushButton(tr("Settings"));
 +
 +    removeDictButton->setEnabled(false);
 +    settingsButton->setEnabled(false);
 +
 +    buttonGroup = new QHBoxLayout;
 +
 +    buttonGroup->addWidget(addNewDictButton);
 +    buttonGroup->addWidget(removeDictButton);
 +    buttonGroup->addWidget(settingsButton);
 +
 +    verticalLayout->addLayout(buttonGroup, Qt::AlignBottom);
 +
 +
 +    connect(addNewDictButton, SIGNAL(clicked()),
 +            this, SLOT(saveChanges()));
 +    connect(addNewDictButton, SIGNAL(clicked()),
 +            this, SLOT(addNewDictButtonClicked()));
 +
 +    connect(removeDictButton, SIGNAL(clicked()),
 +            this, SLOT(saveChanges()));
 +    connect(removeDictButton, SIGNAL(clicked()),
 +            this, SLOT(removeButtonClicked()));
 +
 +    connect(settingsButton, SIGNAL(clicked()),
 +            this, SLOT(saveChanges()));
 +    connect(settingsButton, SIGNAL(clicked()),
 +            this, SLOT(settingsButtonClicked()));
 +
 +    connect(dictListWidget, SIGNAL(itemClicked(QListWidgetItem*)),
 +            this, SLOT(itemSelected(QListWidgetItem*)));
 +
 +    connect(dictListWidget, SIGNAL(itemChanged(QListWidgetItem*)),
 +            this, SLOT(changed()));
 +
 +    refreshDictsList();
 +
 +    #ifndef Q_WS_MAEMO_5
 +        setMinimumSize(500,300);
 +        closeButton = new QPushButton(tr("Save"));
 +        buttonGroup->addWidget(closeButton);
 +        connect(closeButton, SIGNAL(clicked()), this, SLOT(save()));
 +    #endif
 +}
 +
 +
 +void DictManagerWidget::refreshDictsList() {
 +
 +    dictListWidget->clear();
 +    dictsHash.clear();
 +    removeDictButton->setEnabled(false);
 +    settingsButton->setEnabled(false);
 +
 +    QHash<CommonDictInterface*, bool> dicts = guiInterface->getDictionaries();
 +
 +    QHashIterator<CommonDictInterface*, bool> i(dicts);
 +
 +    while(i.hasNext()) {
 +        i.next();
 +        QListWidgetItem* item = new QListWidgetItem();
 +        QString name = i.key()->langFrom() + " - " + i.key()->langTo() + " (" +
 +                       i.key()->type() + " " + i.key()->name() + ")";
 +        item->setText(name);
 +        item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
 +        if(i.value()) {
 +            item->setCheckState(Qt::Checked);
 +        }
 +        else {
 +            item->setCheckState(Qt::Unchecked);
 +        }
 +        item->setIcon(*i.key()->icon());
 +
 +        dictListWidget->addItem(item);
 +        dictsHash.insert(item, i.key());
 +    }
 +}
 +
 +void DictManagerWidget::showEvent(QShowEvent *e) {
 +    _changed = false;
 +    #ifndef Q_WS_MAEMO_5
 +      _save = false;
 +    #endif
 +    refreshDictsList();
 +    QWidget::showEvent(e);
 +}
 +
 +void DictManagerWidget::saveChanges() {
 +
 +    #ifndef Q_WS_MAEMO_5
 +        if(_save) {
 +    #else
 +        if(_changed &&
 +                QMessageBox::question(this, tr("Save"),
 +                                      tr("Do you want to save changes?"),
 +                QMessageBox::Save, QMessageBox::Cancel) == QMessageBox::Save) {
 +    #endif
 +        QList<CommonDictInterface*> checkedDicts;
 +
 +        for(int i=0; i<dictListWidget->count(); i++) {
 +            QListWidgetItem* item = dictListWidget->item(i);
 +            if(item->checkState() == Qt::Checked) {
 +                checkedDicts.push_back(dictsHash[item]);
 +            }
 +        }
 +        _changed = false;
 +        emit selectedDictionaries(checkedDicts);
 +    }
 +}
 +
 +void DictManagerWidget::hideEvent(QHideEvent *e) {
 +    saveChanges();
 +    QWidget::hideEvent(e);
 +}
 +
 +
 +void DictManagerWidget::addNewDictButtonClicked() {
 +    #ifndef Q_WS_MAEMO_5
 +    if(!_changed || QMessageBox::question(this,
 +            "Save", "Do you want to save changes?",
 +            QMessageBox::Save, QMessageBox::Cancel) == QMessageBox::Save) {
 +        _save = true;
 +        saveChanges();
 +        _save = false;
 +    }
 +    #endif
 +
 +   CommonDictInterface* selectedPlugin =
 +           DictTypeSelectDialog::addNewDict(guiInterface->getPlugins(),this);
 +   if(selectedPlugin != NULL) {
 +       Settings* settings =
 +               selectedPlugin->dictDialog()->addNewDictionary(this);
 +
 +       if(settings != NULL) {
 +           CommonDictInterface* newDict = selectedPlugin->getNew(settings);
++           delete settings;
 +           Q_EMIT addDictionary(newDict);
 +       }
 +   }
 +   refreshDictsList();
 +}
 +
 +void DictManagerWidget::itemSelected(QListWidgetItem *) {
 +    removeDictButton->setEnabled(true);
 +    settingsButton->setEnabled(true);
 +}
 +
 +void DictManagerWidget::removeButtonClicked() {
 +    if(QMessageBox::question(this, tr("Remove dictionary"),
 +            tr("Do you want to remove selected dictionary?"),
 +            QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) {
 +
 +        QList<QListWidgetItem*> selected = dictListWidget->selectedItems();
 +        if(selected.count() > 0) {
 +            emit removeDictionary(dictsHash[selected[0]]);
 +            refreshDictsList();
 +        }
 +   }
 +}
 +
 +void DictManagerWidget::settingsButtonClicked() {
 +    #ifndef Q_WS_MAEMO_5
 +    if(!_changed || QMessageBox::question(this,
 +            "Save", "Do you want to save changes?",
 +            QMessageBox::Save, QMessageBox::Cancel) == QMessageBox::Save) {
 +        _save = true;
 +        saveChanges();
 +        _save = false;
 +    }
 +    #endif
 +   QList<QListWidgetItem*> selected = dictListWidget->selectedItems();
 +   if(selected.count() > 0) {
 +       dictsHash[selected[0]]->dictDialog()->changeSettings(this);
 +   }
 +   refreshDictsList();
 +}
 +
 +
 +void DictManagerWidget::changed() {
 +    _changed=true;
 +}
 +
 +
 +#ifndef Q_WS_MAEMO_5
 +    void DictManagerWidget::save() {
 +        _save = true;
 +        hide();
 +    }
 +#endif
index 0652236,0000000..62ee99a
mode 100644,000000..100644
--- /dev/null
@@@ -1,316 -1,0 +1,316 @@@
 +/*******************************************************************************
 +
 +    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.
 +
 +*******************************************************************************/
 +
 +//! \file SearchBarWidget.cpp
 +//! \author Mateusz Półrola <mateusz.polrola@comarch.pl>
 +
 +
 +#include "SearchBarWidget.h"
 +#include <QDebug>
 +#include "../../common/DictDialog.h"
 +#include "HistoryListDialog.h"
 +
 +
 +SearchBarWidget::SearchBarWidget(QWidget *parent) :
 +    QWidget(parent) {
 +
 +    initializeUI();
 +
 +
 +    busy = false;
 +
 +    connect(searchPushButton, SIGNAL(clicked()),
 +            this, SLOT(searchPushButtonClicked()));
 +
 +    connect(searchWordLineEdit, SIGNAL(returnPressed()),
 +            this, SLOT(searchPushButtonClicked()));
 +
 +    connect(historyNextToolButton, SIGNAL(clicked()),
 +            this, SIGNAL(historyNext()));
 +
 +    connect(historyPrevToolButton, SIGNAL(clicked()),
 +            this, SIGNAL(historyPrev()));
 +
 +    connect(historyShowToolButton, SIGNAL(clicked()),
 +            this, SLOT(showHistoryButtonClicked()));
 +
 +    connect(clearSearchWordToolButton, SIGNAL(clicked()),
 +            this, SLOT(clearSearchWordToolButtonClicked()));
 +
 +
 +    connect(&delayTimer, SIGNAL(timeout()),
 +            this, SLOT(delaySearchTimeout()));
 +
 +
 +    searchWordLineEdit->setFocus();
 +
 +    historyPrevToolButton->setEnabled(false);
 +    historyNextToolButton->setEnabled(false);
 +    historyShowToolButton->setEnabled(false);
 +
 +    setEnabled(true);
 +}
 +
 +SearchBarWidget::~SearchBarWidget() {
 +
 +}
 +
 +QIcon SearchBarWidget::generateIcon(QIcon oryginal, qreal rotation) {
 +    QPixmap p = oryginal.pixmap(64);
 +
 +    if(rotation != 0) {
 +        QMatrix m;
 +        m.rotate(rotation);
 +
 +        p = p.transformed(m);
 +    }
 +
 +    QIcon newIcon;
 +    newIcon.addPixmap(p);
 +
 +
 +    #ifdef Q_WS_MAEMO_5
 +        QPainter painter(&p);
 +        painter.fillRect(p.rect(), QColor(0,0,0,192));
 +
 +        newIcon.addPixmap(p, QIcon::Disabled, QIcon::Off);
 +    #endif
 +
 +    return newIcon;
 +}
 +
 +
 +void SearchBarWidget::initializeUI() {
 +
 +    #ifdef Q_WS_MAEMO_5
 +        setMaximumHeight(150);
 +    #else
 +        setMaximumHeight(100);
 +    #endif
 +
 +
 +    horizontalLayout = new QHBoxLayout;
 +    verticalLayout = new QVBoxLayout;
 +
 +
 +    searchPushButton = new QPushButton(tr("Search"));
 +    searchPushButton->setMinimumWidth(125);
 +
 +
 +    searchWordLineEdit = new QLineEdit;
 +    searchWordLineEdit->setMinimumWidth(250);
 +
 +
 +
-     completerModel = new QStringListModel;
++    completerModel = new QStringListModel(this);
 +
 +
 +    lineEditCompleter = new QCompleter(searchWordLineEdit);
 +    lineEditCompleter->setModel(completerModel);
 +    lineEditCompleter->setCaseSensitivity(Qt::CaseInsensitive);
 +    lineEditCompleter->setCompletionMode(QCompleter::InlineCompletion);
 +    searchWordLineEdit->setCompleter(lineEditCompleter);
 +
 +
 +    #ifndef Q_WS_MAEMO_5
 +        searchWordLineEdit->setMinimumHeight(
 +                searchWordLineEdit->sizeHint().height()*3/2);
 +    #endif
 +
 +
 +    //create layout for lineEdit to have clear button on it
 +    QHBoxLayout* lineEditLayout = new QHBoxLayout;
 +    searchWordLineEdit->setLayout(lineEditLayout);
 +
 +
 +    clearSearchWordToolButton = new QToolButton;
 +    #ifdef Q_WS_MAEMO_5
 +        clearSearchWordToolButton->setIcon(QIcon::fromTheme("general_stop"));
 +        clearSearchWordToolButton->setMaximumSize(
 +                clearSearchWordToolButton->sizeHint().height()/2,
 +                clearSearchWordToolButton->sizeHint().height()/2);
 +        lineEditLayout->setContentsMargins(0,0,10,0);
 +    #else
 +        clearSearchWordToolButton->setIcon(QIcon::fromTheme("edit-clear"));
 +        clearSearchWordToolButton->setMinimumSize(
 +                searchWordLineEdit->sizeHint().height()*1.2,
 +                searchWordLineEdit->sizeHint().height()*1.2);
 +        lineEditLayout->setContentsMargins(0,0,5,0);
 +    #endif
 +
 +
 +    historyNextToolButton = new QToolButton;
 +    #ifdef Q_WS_MAEMO_5
 +        historyNextToolButton->setIcon(
 +                generateIcon(QIcon::fromTheme("general_forward")));
 +    #else
 +        historyNextToolButton->setIcon(
 +                generateIcon(QIcon::fromTheme("go-next")));
 +    #endif
 +
 +
 +
 +    historyPrevToolButton = new QToolButton;
 +    #ifdef Q_WS_MAEMO_5
 +        historyPrevToolButton->setIcon(
 +                generateIcon(QIcon::fromTheme("general_back")));
 +    #else
 +        historyPrevToolButton->setIcon(
 +                generateIcon(QIcon::fromTheme("go-previous")));
 +    #endif
 +
 +
 +
 +    historyShowToolButton = new QToolButton;
 +    #ifdef Q_WS_MAEMO_5
 +        historyShowToolButton->setIcon(
 +                generateIcon(QIcon::fromTheme("general_back"), 90));
 +    #else
 +        historyShowToolButton->setIcon(
 +                generateIcon(QIcon::fromTheme("go-up")));
 +    #endif
 +
 +    searchingProgressBar = new QProgressBar;
 +    //progress bar have minimum and maximum values set to 0, which will effect
 +    //with "I'm alive" bar
 +    searchingProgressBar->setMinimum(0);
 +    searchingProgressBar->setMaximum(0);
 +    #ifdef Q_WS_MAEMO_5
 +        searchingProgressBar->setMaximumHeight(50);
 +    #endif
 +    searchingProgressBar->hide();
 +
 +
 +    setLayout(verticalLayout);
 +
 +    verticalLayout->addWidget(searchingProgressBar);
 +
 +    //adding widgets to layout
 +    horizontalLayout->addWidget(searchWordLineEdit);
 +    horizontalLayout->addWidget(searchPushButton);
 +    horizontalLayout->addWidget(historyPrevToolButton);
 +    horizontalLayout->addWidget(historyShowToolButton);
 +    horizontalLayout->addWidget(historyNextToolButton);
 +
 +    //adding clear toolButton to textEdit with right alignment
 +    lineEditLayout->addWidget(clearSearchWordToolButton, 0, Qt::AlignRight);
 +
 +
 +    verticalLayout->addLayout(horizontalLayout);
 +}
 +
 +
 +void SearchBarWidget::searchPushButtonClicked() {
 +    if(busy) {
 +        Q_EMIT stopSearching();
 +    }
 +    else {
 +        search(searchWordLineEdit->text());
 +    }
 +}
 +
 +
 +void SearchBarWidget::search(QString word) {
 +    if(!busy && !word.isEmpty()) {
 +        completerModel->insertRow(completerModel->rowCount());
 +        QModelIndex index =
 +                completerModel->index(completerModel->rowCount() -1);
 +
 +        completerModel->setData(index, word);
 +
 +
 +        searchWordLineEdit->setText(word);
 +        Q_EMIT searchForTranslations(word);
 +    }
 +}
 +
 +void SearchBarWidget::searchDelay(QString word) {
 +    if(!busy && !word.isEmpty()) {
 +        searchWordLineEdit->setText(word);
 +
 +
 +        if(delayTimer.isActive()) {
 +            delayTimer.stop();
 +        }
 +
 +        delayString = word;
 +        delayTimer.start(500);
 +    }
 +}
 +
 +void SearchBarWidget::delaySearchTimeout() {
 +    delayTimer.stop();
 +    if(!busy) {
 +        Q_EMIT searchForTranslations(delayString);
 +    }
 +}
 +
 +void SearchBarWidget::setEnabled(bool enabled) {
 +    searchWordLineEdit->setEnabled(enabled);
 +
 +    if(!enabled) {
 +        historyPrevToolButton->setEnabled(false);
 +        historyNextToolButton->setEnabled(false);
 +        historyShowToolButton->setEnabled(false);
 +    }
 +}
 +
 +void SearchBarWidget::setBusy() {
 +    if(busy) return;
 +    searchingProgressBar->show();
 +    searchPushButton->setText(tr("Stop"));
 +    setEnabled(false);
 +    busy = true;
 +}
 +
 +void SearchBarWidget::setIdle() {
 +    if(!busy) return;
 +    searchingProgressBar->hide();
 +    searchPushButton->setText(tr("Search"));
 +    setEnabled(true);
 +    busy = false;
 +    Q_EMIT refreshHistoryButtons();
 +}
 +
 +
 +void SearchBarWidget::clearSearchWordToolButtonClicked() {
 +    searchWordLineEdit->clear();
 +}
 +
 +
 +
 +void SearchBarWidget::updateHistoryButtons(bool prev, bool next, bool list) {
 +    if(!busy) {
 +        historyPrevToolButton->setEnabled(prev);
 +        historyNextToolButton->setEnabled(next);
 +        historyShowToolButton->setEnabled(list);
 +    }
 +}
 +
 +void SearchBarWidget::showHistoryButtonClicked() {
 +    #ifdef Q_WS_MAEMO_5
 +        emit historyShow();
 +    #else
 +        QPoint p = historyShowToolButton->pos();
 +        p.setY(p.y());
 +        emit historyShow(mapToGlobal(p));
 +    #endif
 +}
index 5cea174,0000000..ab9f787
mode 100644,000000..100644
--- /dev/null
@@@ -1,365 -1,0 +1,366 @@@
 +/*******************************************************************************
 +
 +    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.
 +
 +*******************************************************************************/
 +
 +//! \file TranslationWidget.cpp
 +//! \author Mateusz Półrola <mateusz.polrola@comarch.pl>
 +
 +#include "TranslationWidget.h"
 +#include <QDebug>
 +#ifdef Q_WS_MAEMO_5
 +    #include <QtGui/QX11Info>
 +    #include <X11/Xlib.h>
 +    #include <X11/Xatom.h>
 +#endif
 +
 +TranslationWidget::TranslationWidget(QWidget *parent):
 +        QScrollArea(parent){
 +
 +    guiinterface = qobject_cast<GUIInterface*>(parent);
 +
 +    #ifdef Q_WS_MAEMO_5
 +        setAttribute(Qt::WA_Maemo5StackedWindow);
 +        setWindowFlags(windowFlags() | Qt::Window);
 +    #endif
 +
 +
 +    initializeUI();
 +
 +    setWindowTitle("mDictionary");
 +
 +    connect(webkit, SIGNAL(search()),
 +           this, SLOT(searchSelected()));
 +
 +    QFile file(":/xsl/xsl.xsl");
 +    if(!file.open(QFile::ReadOnly))
 +        qDebug()<<"error can't open a xslt file";
 +    else
 +        xslt=file.readAll();
 +}
 +
 +
 +void TranslationWidget::show() {
 +    QScrollArea::show();
 +}
 +
 +
 +void TranslationWidget::show(QStringList translations) {
 +    showMaximized();
 +
 +    #ifdef Q_WS_MAEMO_5
 +        if(!buttonsInitialized)
 +            initButtons();
 +    #endif
 +
 +   // webkit->repaint(this->rect());
 +   // update(this->rect());
 +
 +    QString trans;
 +    QString t;
 +
 +    foreach(t, translations) {
 +        trans += t + "\n";
 +    }
 +
 +    trans=tr("<?xml version=\"1.0\" encoding=\"UTF-8\"?>") + tr("\n <ar>")
 +            + trans + tr("\n </ar>");
 +    trans=XslConversion(trans);
 +
 +    QString head = "<html><head>";
 +    head += "<link rel=\"stylesheet\" type=\"text/css\" " ;
 +    head += "href=\"" + QDir::homePath() + "/.mdictionary/style.css";
 +    head += "\" /></head><body ondragstart=\"return false\">";
 +    trans = head + trans;
 +
 +    trans+= "</body></html>";
 +    trans.replace("$STAR$", "/usr/lib/mdictionary/staron.png");
 +
 +
 +    webkit->setHtml(trans, QUrl().fromLocalFile("/"));
 +
 +
 +    //webkit->repaint(this->rect());
 +    //update(this->rect());
 +
 +  //  Q_EMIT updateSize();
 +}
 +
 +QString TranslationWidget::XslConversion(QString translation)
 +{
 +    QXmlQuery myQuery(QXmlQuery::XSLT20);
 +    myQuery.setFocus(translation);
 +    myQuery.setQuery(xslt);
 +    QString result("");
 +    myQuery.evaluateTo(&result);
 +    return result;
 +}
 +
 +
 +#ifdef Q_WS_MAEMO_5
 +void TranslationWidget::initButtons() {
 +
 +        int x = width() - showButtonsButton->sizeHint().width();
 +        int y = height() - showButtonsButton->sizeHint().height();
 +
 +        showButtonsButton->move(QPoint(x,y));
 +        showButtonsButton->show();
 +
 +
 +
 +        x = width() - zoomOutButton->sizeHint().width();
 +        y = height() - 2*zoomOutButton->sizeHint().height();
 +        zoomOutButton->move(QPoint(x, height()));
 +
 +        zoomOutButtonAnimation =
 +                new QPropertyAnimation(zoomOutButton, "pos", this);
 +
 +        zoomOutButtonAnimation->setStartValue(QPoint(x, height()));
 +        zoomOutButtonAnimation->setEndValue(QPoint(x,y));
 +        zoomOutButtonAnimation->setDuration(200);
 +        zoomOutButtonAnimation->setEasingCurve(QEasingCurve::InOutBack);
 +
 +
 +
 +        x = width() - zoomInButton->sizeHint().width();
 +        y = height() - 3*zoomInButton->sizeHint().height();
 +        zoomInButton->move(QPoint(x, height()));
 +
 +        zoomInButtonAnimation =
 +                new QPropertyAnimation(zoomInButton, "pos", this);
 +
 +        zoomInButtonAnimation->setStartValue(QPoint(x, height()));
 +        zoomInButtonAnimation->setEndValue(QPoint(x,y));
 +        zoomInButtonAnimation->setDuration(400);
 +        zoomInButtonAnimation->setEasingCurve(QEasingCurve::InOutBack);
 +
 +
 +
 +        x = 0;
 +        y = height() - copyButton->sizeHint().height();
 +
 +        copyButton->move(QPoint(x, height()));
 +
 +        copyButtonAnimation =
 +                new QPropertyAnimation(copyButton, "pos", this);
 +
 +        copyButtonAnimation->setStartValue(QPoint(x, height()));
 +        copyButtonAnimation->setEndValue(QPoint(x,y));
 +        copyButtonAnimation->setDuration(200);
 +        copyButtonAnimation->setEasingCurve(QEasingCurve::InOutBack);
 +
 +
 +
 +        x = 0;
 +        y = height() - 2*copyButton->sizeHint().height();
 +
 +        selectAllButton->move(QPoint(x, height()));
 +
 +        selectAllButtonAnimation =
 +                new QPropertyAnimation(selectAllButton, "pos", this);
 +
 +        selectAllButtonAnimation->setStartValue(QPoint(x, height()));
 +        selectAllButtonAnimation->setEndValue(QPoint(x,y));
 +        selectAllButtonAnimation->setDuration(400);
 +        selectAllButtonAnimation->setEasingCurve(QEasingCurve::InOutBack);
 +
 +
 +
 +        x = 0;
 +        y = height() - 3*copyButton->sizeHint().height();
 +
 +        searchButton->move(QPoint(x, height()));
 +
 +        searchButtonAnimation =
 +                new QPropertyAnimation(searchButton, "pos", this);
 +
 +        searchButtonAnimation->setStartValue(QPoint(x, height()));
 +        searchButtonAnimation->setEndValue(QPoint(x,y));
 +        searchButtonAnimation->setDuration(600);
 +        searchButtonAnimation->setEasingCurve(QEasingCurve::InOutBack);
 +
 +
 +
 +
 +        buttonsAnimation = new QParallelAnimationGroup(this);
 +        buttonsAnimation->addAnimation(zoomInButtonAnimation);
 +        buttonsAnimation->addAnimation(zoomOutButtonAnimation);
 +        buttonsAnimation->addAnimation(selectAllButtonAnimation);
 +        buttonsAnimation->addAnimation(copyButtonAnimation);
 +        buttonsAnimation->addAnimation(searchButtonAnimation);
 +        buttonsInitialized = true;
 +        buttonsVisible = false;
 +
 +        connect(showButtonsButton, SIGNAL(clicked()),
 +                this, SLOT(showButtons()));
 +}
 +#endif
 +
 +void TranslationWidget::initializeUI() {
 +
 +    webkit = new TranslationTextEdit(this);
 +    Settings* set = guiinterface->settings();
 +    qreal fac = set->value("zoom").toFloat();
 +    if(!fac)
 +        fac++;
 +    webkit->setZoomFactor(fac);
++    delete set;
 +
 +    QWidget*w = new QWidget(this);
 +    verticalLayout = new QVBoxLayout(w);
 +    verticalLayout->addWidget(webkit);
 +
 +    this->setWidget(w);
 +    this->setWidgetResizable(true);
 +
 +    #ifdef Q_WS_MAEMO_5
 +        zoomInButton = new QToolButton(this);
 +        zoomInButton->setIcon(QIcon::fromTheme("pdf_zoomin"));
 +        zoomInButton->setMinimumSize(zoomInButton->sizeHint());
 +
 +        zoomOutButton = new QToolButton(this);
 +        zoomOutButton->setIcon(QIcon::fromTheme("pdf_zoomout"));
 +        zoomOutButton->setMinimumSize(zoomOutButton->sizeHint());
 +
 +        selectAllButton = new QToolButton(this);
 +        selectAllButton->setIcon(QIcon(":/icons/48x48/edit-select-all.png"));
 +        selectAllButton->setMinimumSize(selectAllButton->sizeHint());
 +
 +        copyButton = new QToolButton(this);
 +        copyButton->setIcon(QIcon::fromTheme("general_notes"));
 +        copyButton->setMinimumSize(copyButton->sizeHint());
 +        copyButton->setEnabled(false);
 +
 +        searchButton = new QToolButton(this);
 +        searchButton->setIcon(QIcon::fromTheme("general_search"));
 +        searchButton->setMinimumSize(searchButton->sizeHint());
 +        searchButton->setEnabled(false);
 +
 +        showButtonsButton = new QToolButton(this);
 +        showButtonsButton->setIcon(QIcon::fromTheme("general_sent"));
 +        showButtonsButton->setMinimumSize(searchButton->sizeHint());
 +
 +        connect(zoomInButton, SIGNAL(clicked()),
 +                webkit, SLOT(zoomIn()));
 +
 +        connect(zoomOutButton, SIGNAL(clicked()),
 +                webkit, SLOT(zoomOut()));
 +
 +
 +        connect(searchButton, SIGNAL(clicked()),
 +                this, SLOT(searchSelected()));
 +
 +        connect(copyButton, SIGNAL(clicked()),
 +                webkit, SLOT(copy()));
 +
 +        connect(webkit, SIGNAL(copyAvailable(bool)),
 +                searchButton, SLOT(setEnabled(bool)));
 +
 +        connect(webkit, SIGNAL(copyAvailable(bool)),
 +                copyButton, SLOT(setEnabled(bool)));
 +
 +        connect(selectAllButton, SIGNAL(clicked()),
 +                webkit, SLOT(selectAll()));
 +
 +        buttonsInitialized = false;
 +
 +
 +
 +        grabZoomKeys(true);
 +    #endif
 +}
 +
 +void TranslationWidget::searchSelected() {
 +    #ifdef Q_WS_MAEMO_5
 +        hide();
 +    #endif
 +    Q_EMIT search(webkit->selectedText().toLower());
 +}
 +
 +#ifdef Q_WS_MAEMO_5
 +void TranslationWidget::showButtons() {
 +    if(!buttonsVisible) {
 +        buttonsAnimation->setDirection(QAbstractAnimation::Forward);
 +        buttonsAnimation->start();
 +        buttonsVisible = true;
 +
 +        showButtonsButton->setIcon(QIcon::fromTheme("general_received"));
 +    }
 +    else if(buttonsVisible) {
 +        buttonsAnimation->setDirection(QAbstractAnimation::Backward);
 +        buttonsAnimation->start();
 +        buttonsVisible = false;
 +        showButtonsButton->setIcon(QIcon::fromTheme("general_sent"));
 +    }
 +}
 +
 +void TranslationWidget::grabZoomKeys(bool grab) {
 +     if (!winId()) {
 +         return;
 +     }
 +
 +    unsigned long val = (grab) ? 1 : 0;
 +    Atom atom = XInternAtom(QX11Info::display(),
 +                            "_HILDON_ZOOM_KEY_ATOM", False);
 +    if (!atom) {
 +        return;
 +    }
 +
 +    XChangeProperty (QX11Info::display(),
 +         winId(),
 +         atom,
 +         XA_INTEGER,
 +         32,
 +         PropModeReplace,
 +         reinterpret_cast<unsigned char *>(&val),
 +         1);
 +}
 +
 +void TranslationWidget::hideEvent(QHideEvent* e) {
 +    if(buttonsVisible)
 +        showButtons();
 +
 +    QScrollArea::hideEvent(e);
 +}
 +
 +void TranslationWidget::keyPressEvent(QKeyEvent* event) {
 +    switch (event->key()) {
 +        case Qt::Key_F7:
 +        webkit->zoomIn();
 +        event->accept();
 +        break;
 +
 +        case Qt::Key_F8:
 +        webkit->zoomOut();
 +        event->accept();
 +        break;
 +    }
 +    QWidget::keyPressEvent(event);
 +}
 +#endif
 +
 +
 +void TranslationWidget::updateZoom(qreal factor) {
 +    Settings* set = guiinterface->settings();
 +    set->setValue("zoom", QString("%1").arg(factor));
 +    guiinterface->setSettings(set);
 +}
 +
 +
 +
index 8085a05,0000000..7d6eaab
mode 100644,000000..100644
--- /dev/null
@@@ -1,192 -1,0 +1,199 @@@
 +
 +/*******************************************************************************
 +
 +    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.
 +
 +*******************************************************************************/
 +
 +//! \file WordListWidget.cpp
 +//! \author Mateusz Półrola <mateusz.polrola@comarch.pl>
 +
 +#include "WordListWidget.h"
 +#include "WordListProxyStyle.h"
 +#include "../../common/translation.h"
 +
 +
 +WordListWidget::WordListWidget(QWidget *parent):
 +    QTreeView(parent) {
 +
 +    //creating new model to store words and stars
 +    model = new QStandardItemModel(this);
 +    setModel(model);
 +    setHeaderHidden(true);
 +    setRootIsDecorated(false);
 +    setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
 +
 +    //set our custom style to draw checkboxes as stars
-     setStyle(new WordListProxyStyle);
++    proxyStyle = new WordListProxyStyle();
++    setStyle(proxyStyle);
 +
 +    //setting size of star in pixels, on maemo checboxes are much bigger
 +    #ifdef Q_WS_MAEMO_5
 +        checkBoxWidth = 70;
 +    #else
 +        checkBoxWidth = 25;
 +    #endif
 +}
 +
++
++WordListWidget::~WordListWidget() {
++    if(proxyStyle)
++        delete proxyStyle;
++}
++
 +void WordListWidget::addWord(QString word, int row) {
 +    QStandardItem* item = new QStandardItem(word);
 +
 +    //we don't want to allow user to edit word
 +    item->setFlags(item->flags() ^ Qt::ItemIsEditable);
 +
 +    QStandardItem* itemCheckBox = new QStandardItem();
 +    //creating checkbox item
 +    itemCheckBox->setFlags((itemCheckBox->flags() ^ Qt::ItemIsEditable) |
 +                           Qt::ItemIsUserCheckable);
 +
 +    /*checking if word is already in bookmarks, information about that is
 +    stored in its translation object (not all translations have to be in
 +    bookmarks)*/
 +    bool bookmark = false;
 +    Translation* t;
 +    foreach(t, searchResult[word]) {
 +        if(t->isBookmark()) {
 +            bookmark = true;
 +            break;
 +        }
 +    }
 +
 +    if(bookmark)
 +        itemCheckBox->setCheckState(Qt::Checked);
 +    else
 +        itemCheckBox->setCheckState(Qt::Unchecked);
 +
 +    //add item to model
 +    model->setItem(row,0, item);
 +    model->setItem(row,1, itemCheckBox);
 +}
 +
 +
 +void WordListWidget::showSearchResults(
 +        QHash<QString, QList<Translation *> > result) {
 +
 +    clear();
 +    searchResult = result;
 +
 +    model->setColumnCount(2);
 +    model->setRowCount(result.count());
 +
 +    int row=0;
 +    QHash<QString, QList<Translation*> >::iterator i;
 +    for(i = searchResult.begin(); i != searchResult.end(); i++) {
 +           addWord(i.key(), row++);
 +    }
 +
 +    model->sort(0);
 +    resizeColumns();    
 +}
 +
 +void WordListWidget::wordClicked(QModelIndex index) {
 +    //we're getting translation based on data in index
 +    Q_EMIT showTranslation(
 +            searchResult[index.data().toString()]);
 +}
 +
 +void WordListWidget::wordChecked(QModelIndex index) {
 +
 +    //save new item state
 +    Qt::CheckState state =
 +            Qt::CheckState(index.data(Qt::CheckStateRole).toInt());
 +
 +
 +    //getting index of item which contains word which should be added/removed
 +    //from bookmarks
 +    QModelIndex item = selectedIndexes().at(0);
 +    if(!item.isValid()) return;
 +
 +    //to shorten lag between clicking on star and its change
 +    repaint();
 +
 +    //depending on new state emit suitable signal
 +    if(state == Qt::Checked) {
 +        Q_EMIT addBookmark(searchResult[item.data().toString()]);
 +    }
 +    else {
 +        Q_EMIT removeBookmark(searchResult[item.data().toString()]);
 +    }
 +}
 +
 +
 +void WordListWidget::mouseReleaseEvent(QMouseEvent *event) {
 +
 +    //firstly we normally handle this event
 +    QTreeView::mouseReleaseEvent(event);
 +
 +    //then we check at which item user clicked
 +    QModelIndex index = indexAt(event->pos());
 +    if(!index.isValid()) return;
 +
 +    /*if there are no selected items we return, that occurs sometimes
 +    on maemo, when user is scrolling list and clicks to stop the scroll,
 +    system doesn't select item but emits mouseReleaseEvent*/
 +    if(selectedIndexes().count() == 0) return;
 +
 +    //if user doesn't click either on word or on star, return
 +    if(selectedIndexes().at(0) != index && selectedIndexes().at(1) != index)
 +        return;
 +
 +    int c = index.column();
 +    if(c==0)
 +        //if column is 0 user clicked word
 +        wordClicked(index);
 +    else
 +        //else user clicked star
 +        wordChecked(index);
 +}
 +
 +void WordListWidget::resizeEvent(QResizeEvent *event) {
 +    resizeColumns();
 +    QTreeView::resizeEvent(event);
 +}
 +
 +void WordListWidget::resizeColumns() {
 +    setColumnWidth(0, viewport()->width() -checkBoxWidth - 5);
 +    setColumnWidth(1, checkBoxWidth);
 +}
 +
 +void WordListWidget::lockList() {
 +    setEnabled(false);
 +}
 +
 +void WordListWidget::unlockList() {
 +    setEnabled(true);
 +}
 +
 +void WordListWidget::clear() {
 +    model->clear();
 +
 +    QHash<QString, QList<Translation*> >::iterator i;
 +    for(i = searchResult.begin(); i != searchResult.end(); i++) {
 +           Translation*t;
 +           foreach(t, i.value()) {
 +               delete t;
 +           }
 +    }
 +    searchResult.clear();
 +}
index cc6d72e,0000000..f06d889
mode 100644,000000..100644
--- /dev/null
@@@ -1,108 -1,0 +1,111 @@@
 +/*******************************************************************************
 +
 +    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.
 +
 +*******************************************************************************/
 +//! \file WordListwidget.h
 +//! \author Mateusz Półrola <mateusz.polrola@comarch.pl>
 +
 +#ifndef WORDLISTWIDGET_H
 +#define WORDLISTWIDGET_H
 +
 +#include <QtGui>
 +#include <QStringListModel>
 +#include "../backbone/backbone.h"
++#include "WordListProxyStyle.h"
 +
 +//! Displays list of words found in dictionaries
 +/*!
 +    It allows user to select word to see its translation or to mark or unmark
 +    it as "star" (add/remove from bookmarks). It inherits from QTreeView
 +    to allow to display two columns, one with words and second with stars.
 +    Star is normal checkable item. To get effect of star we need to set
 +    style (WordListProxyStyle) for this widget.
 +  */
 +class WordListWidget : public QTreeView {
 +    Q_OBJECT
 +public:
 +    explicit WordListWidget(QWidget *parent = 0);
++    ~WordListWidget();
 +
 +
 +Q_SIGNALS:
 +    //! Requests to show translation which is described by passed translations
 +    //! objects
 +    void showTranslation(QList<Translation*>);
 +
 +
 +    //! Requests to add selected word to bookmarks
 +    void addBookmark(QList<Translation*>);
 +
 +    //! Requests to remove selected word from bookmarks
 +    void removeBookmark(QList<Translation*>);
 +
 +
 +public Q_SLOTS:
 +    //! Shows search results
 +    /*!
 +      \param hash of found words and its translations objects
 +    */
 +    void showSearchResults(QHash<QString, QList<Translation*> >);
 +
 +    //! Locks words list, while backbone is doing something in background
 +    void lockList();
 +
 +    //! Unlocks words list
 +    void unlockList();
 +
 +protected:
 +    //! Reimplemented standard mouseReleaseEvent to check if user clicked on
 +    //! word or on its star to emit suitable signal
 +    void mouseReleaseEvent(QMouseEvent *event);
 +
 +    //! Resizes the size of columns to assure that stars are always on right
 +    //! side next to scroll bar
 +    void resizeEvent(QResizeEvent *event);
 +
 +private Q_SLOTS:
 +    //! Emits signal to show translation of clicked item. Signal is emitted
 +    //! only when word was clicked.
 +    void wordClicked(QModelIndex index);
 +
 +    //! Emits signal to show add or remove word from bookmarks.
 +    //! Signal is emitted only when star was clicked.
 +    void wordChecked(QModelIndex index);
 +
 +    //! clears list
 +    void clear();
 +
 +private:
 +    //! Adds word to model. Row is row in the model
 +    void addWord(QString word, int row);
 +
 +    QStandardItemModel* model;
 +
 +    //! Describes width of star checkbox in pixels
 +    int checkBoxWidth;
 +
 +    //! Resizes sizes of colums after adding new words or after resize event.
 +    void resizeColumns();
 +
 +    //! Association between words and their translations
 +    QHash<QString, QList<Translation*> > searchResult;
++    WordListProxyStyle* proxyStyle;
 +};
 +
 +#endif // WORDLISTWIDGET_H
index 3fe8907,0000000..4e53601
mode 100644,000000..100644
--- /dev/null
@@@ -1,421 -1,0 +1,424 @@@
 +/*******************************************************************************
 +
 +    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.
 +
 +*******************************************************************************/
 +
 +/*! \file GooglePlugin.cpp
 +    \author Jakub Jaszczynski <j.j.jaszczynski@gmail.com>
 +*/
 +
 +#include "GooglePlugin.h"
 +#include <QDebug>
 +#include "GoogleDictDialog.h"
 +
 +GooglePlugin::GooglePlugin(QObject *parent): CommonDictInterface(parent),
 +                    _name(""),_infoNote("") {
 +    _settings = new Settings();
 +    _settings->setValue("lang_to","");
 +    _settings->setValue("lang_from","");
 +    _settings->setValue("type","google");
 +    _settings->setValue("connection_accepted","true");
 +    _dictDialog = new GoogleDictDialog(this,this);
 +    _icon = QIcon(":/icons/drawing.png");
-     _hash=123456;
 +
 +    stopped = false;
 +    languages=initLanguages();
 +
 +    http = new QHttp(this);
 +    connect(http, SIGNAL(done(bool)), this, SLOT(done()));
 +}
 +
 +
 +GooglePlugin::~GooglePlugin() {
 +    delete _settings;
++    delete _dictDialog;
 +}
 +
 +
 +QString GooglePlugin::langFrom() const {
 +    return languages.key(_settings->value("lang_from"));
 +}
 +
 +
 +QString GooglePlugin::langTo() const {
 +    return languages.key(_settings->value("lang_to"));
 +}
 +
 +
 +QString GooglePlugin::name() const {
 +    return QString("dictionary");
 +}
 +
 +
 +QString GooglePlugin::type() const {
 +    return QString("google");
 +}
 +
 +
 +QString GooglePlugin::infoNote() const {
 +    return _infoNote;
 +}
 +
 +
 +void GooglePlugin::setLangTo(QString langTo){
 +    _settings->setValue("lang_to",langTo);
 +}
 +
 +
 +void GooglePlugin::setLangFrom(QString langFrom){
 +    _settings->setValue("lang_from",langFrom);;
 +}
 +
 +
 +DictDialog* GooglePlugin::dictDialog() {
 +    return _dictDialog;
 +}
 +
 +
 +bool GooglePlugin::isAvailable() const {
 +    return isConnectionAccept();
 +}
 +
 +
 +void GooglePlugin::setConnectionAccept(QString connectionAcepted) {
 +    if(connectionAcepted=="true")
 +        _settings->setValue("connection_accepted","true");
 +    else
 +        _settings->setValue("connection_accepted","false");
 +}
 +
 +bool GooglePlugin::isConnectionAccept() const {
 +    if(_settings->value("connection_accepted")=="true")
 +        return true;
 +    else
 +        return false;
 +}
 +
 +
 +uint GooglePlugin::hash() const {
 +    return _hash;
 +}
 +
 +
 +void GooglePlugin::setHash(uint _hash) {
 +    this->_hash=_hash;
 +}
 +
 +
 +Settings* GooglePlugin::settings() {
-     Settings *returnSettings=new Settings;
++/*    Settings *returnSettings=new Settings;
 +    QStringList list = _settings->keys();
 +    foreach(QString key, list)
 +            returnSettings->setValue(key,_settings->value(key));
 +    return returnSettings;
++*/
++    return _settings;
 +}
 +
 +
 +void GooglePlugin::setSettings(const Settings* settings) {
 +    if(settings) {
 +        QStringList list = settings->keys();
 +        foreach(QString key, list)
 +            _settings->setValue(key, settings->value(key));
 +        getDictionaryInfo();
 +        Q_EMIT settingsChanged();
 +    }
 +}
 +
 +
 +QIcon* GooglePlugin::icon() {
 +    return &_icon;
 +}
 +
 +
 +CommonDictInterface* GooglePlugin::getNew(const Settings* settings) const {
 +    GooglePlugin *plugin = new GooglePlugin();
-     plugin->setSettings(settings);
++    if(settings)
++        plugin->setSettings(settings);
 +    return plugin;
 +}
 +
 +
 +QString GooglePlugin::search(QString) {
 +    qDebug() << "function is not used this plugin";
 +    return QString("");
 +}
 +
 +
 +Translation* GooglePlugin::getTranslationFor(QString key) {
 +    return (new TranslationGoogle(key,"",_infoNote,this));
 +}
 +
 +
 +QList<Translation*> GooglePlugin::searchWordList(QString word, int ) {
 +    QList<Translation*> translations;
 +    if(isAvailable()) {
 +        QString error("");
 +        word.replace("*","");   /*remove wildcard*/
 +        word.replace("?","");
 +        QString url=QString("/translate_a/t?client=t&sl=%1&tl=%2").arg(
 +                                              _settings->value("lang_from"),
 +                                              _settings->value("lang_to"));
 +        QHttpRequestHeader head = QHttpRequestHeader("POST", url, 1,1);
 +        head.setValue("Host","www.google.pl");
 +        head.setValue("User-Agent", "Mozilla/5.0");
 +        head.setValue("Accept-Encoding", "deflate");
 +        head.setContentLength(word.length());
 +        head.setValue("Connection", "Close");
 +
 +        QByteArray data("text=");
 +        data.append(word.toUtf8());
 +        http->setHost("www.google.pl");
 +
 +        wait=true;      /* bool - change in slot done (initiate by http) */
 +        stopped=false;  /* bool - change in slot stop (initiate in gui)  */
 +        http->request(head, data);
 +        while(wait && (error=="" || error=="Unknown error") && !stopped)
 +            error=http->errorString();
 +
 +        if(error!="" && error!="Unknown error") {
 +            qDebug()<<error;
 +            Q_EMIT notify(Notify::Warning,
 +                    QString("GooglePlugin: %1").arg(error));
 +        }
 +
 +        QString text = QString::fromUtf8(http->readAll());
 +        text=jsonParse(text);
 +        if(text!="") {
 +            text="<key>" + word + "</key>" + "<t>" + text + "</t>";
 +            translations<<(new TranslationGoogle(word,text,_infoNote,this));
 +        }
 +    }
 +    return translations;
 +}
 +
 +
 +QString GooglePlugin::jsonParse(QString result) {
 +    int pos=0,pos2=0,index=0,size=0;
 +    QString returnLang;
 +    QString translation;
 +    QString original;
 +    QList<QString> partOfSpeach;
 +    QList<QList<QString>* > words;
 +    QStringList list1 = result.split("\"");
 +
 +    size=(list1.size()-1)/2;
 +    if(size<=2)
 +        return QString(""); // wrong format of data
 +
 +    translation=list1.at(index*2+1);
 +    index++;
 +    original=list1.at(index*2+1);
 +    pos=result.indexOf("]");
 +    index++;
 +    while(result.at(pos+1)==QChar(',')) {
 +        index++;
 +        translation+=list1.at(index*2+1);
 +        index++;
 +        original=list1.at(index*2+1);
 +        pos=result.indexOf("]",pos+1);
 +        index++;
 +    }
 +
 +    pos=result.indexOf("]",pos+1);
 +    pos++;
 +    index++;
 +    if(result.at(pos+1)==QChar(','))
 +        returnLang=list1.at(index*2+1); /*return when translate sentence*/
 +
 +    while(result.indexOf("[",pos+1)!=-1){
 +        partOfSpeach.append(list1.at(index*2+1));
 +        pos2=result.indexOf("]",pos+1);
 +        pos=result.indexOf("\"",pos+1);
 +        pos=result.indexOf("\"",pos+1);
 +        pos=result.indexOf("\"",pos+1);
 +        pos=result.indexOf("\"",pos+1);
 +        QList<QString> *list=new QList<QString>;
 +        while(pos2>pos && pos2!=-1 && pos!= -1) {
 +            index++;
 +            if(size==index)
 +                return QString("");
 +            list->append(list1.at(index*2+1));
 +            pos=result.indexOf("\"",pos+1);
 +            pos=result.indexOf("\"",pos+1);
 +        }
 +        words.append(list);
 +        index++;
 +        if(size==index)
 +            return QString("");
 +        pos=pos2+2;
 +    }
 +
 +    if(words.size()!=partOfSpeach.size()) {
 +        qDebug()<<"Error in Google Plugin (JsonParse)";
 +        Q_EMIT notify(Notify::Warning,
 +                QString("GooglePlugin: can't parse Json"));
 +        return QString("");
 +    }
 +    returnLang=list1.at(index*2+1);
 +    if(partOfSpeach.size()==0){
 +        if(translation.toLower()==original.toLower()){
 +            return QString(""); // word don't exist";
 +        }
 +        else
 +            return "\""+translation+"\"";
 +    }
 +    result=translation;
 +    for(int i=0; i<words.size();i++) {
 +        result+="<br/><pos>"+partOfSpeach.at(i)+"</pos>: ";
 +        for(int j=0; j<words.at(i)->size();j++)
 +            result+=words.at(i)->at(j)+", ";
 +        result.remove(result.size()-2,2);
 +    }
 +    return result;
 +}
 +
 +
 +void GooglePlugin::done() {
 +    wait=false;
 +}
 +
 +
 +void GooglePlugin::stop() {
 +    stopped=true;
 +}
 +
 +
 +QMap<QString, QString> GooglePlugin::initLanguages() {
 +    QMap<QString, QString> languages;
 +    languages["Afrikaans"] = "af";
 +    languages["Albanian"] = "sq";
 +    languages["Arabic"] = "ar";
 +    languages["Armenian"] = "hy";
 +    languages["Azerbaijani"] = "az";
 +    languages["Basque"] = "eu";
 +    languages["Belarusian"] = "be";
 +    languages["Bulgarian"] = "bg";
 +    languages["Catalan"] = "ca";
 +    languages["Chinese"] = "zh";
 +    languages["Croatian"] = "hr";
 +    languages["Czech"] = "cs";
 +    languages["Danish"] = "da";
 +    languages["Dutch"] = "nl";
 +    languages["English"] = "en";
 +    languages["Estonian"] = "et";
 +    languages["Filipino"] = "tl";
 +    languages["Finnish"] = "fi";
 +    languages["French"] = "fr";
 +    languages["Galician"] = "gl";
 +    languages["Georgian"] = "ka";
 +    languages["German"] = "de";
 +    languages["Greek"] = "el";
 +    languages["Haitian_creole"] = "ht";
 +    languages["Hebrew"] = "iw";
 +    languages["Hindi"] = "hi";
 +    languages["Hungarian"] = "hu";
 +    languages["Icelandic"] = "is";
 +    languages["Indonesian"] = "id";
 +    languages["Irish"] = "ga";
 +    languages["Italian"] = "it";
 +    languages["Japanese"] = "ja";
 +    languages["Korean"] = "ko";
 +    languages["Latvian"] = "lv";
 +    languages["Lithuanian"] = "lt";
 +    languages["Macedonian"] = "mk";
 +    languages["Malay"] = "ms";
 +    languages["Maltese"] = "mt";
 +    languages["Norwegian"] = "no";
 +    languages["Persian"] = "fa";
 +    languages["Polish"] = "pl";
 +    languages["Portuguese"] = "pt";
 +    languages["Romanian"] = "ro";
 +    languages["Russian"] = "ru";
 +    languages["Serbian"] = "sr";
 +    languages["Slovak"] = "sk";
 +    languages["Slovenian"] = "sl";
 +    languages["Spanish"] = "es";
 +    languages["Swahili"] = "sw";
 +    languages["Swedish"] = "sv";
 +    languages["Thai"] = "th";
 +    languages["Turkish"] = "tr";
 +    languages["Ukrainian"] = "uk";
 +    languages["Urdu"] = "ur";
 +    languages["Vietnamese"] = "vi";
 +    languages["Welsh"] = "cy";
 +    languages["Yiddish"] = "yi";
 +    languages["Detect langlage"] = "";
 +//    languages["AMHARIC"] = "am";
 +//    languages["BENGALI"] = "bn";
 +//    languages["BIHARI"] = "bh";
 +//    languages["BRETON"] = "br";
 +//    languages["BURMESE"] = "my";
 +//    languages["CHEROKEE"] = "chr";
 +//    languages["CHINESE_SIMPLIFIED"] = "zh-CN";
 +//    languages["CHINESE_TRADITIONAL"] = "zh-TW";
 +//    languages["CORSICAN"] = "co";
 +//    languages["DHIVEHI"] = "dv";
 +//    languages["ESPERANTO"] = "eo";
 +//    languages["FAROESE"] = "fo";
 +//    languages["FRISIAN"] = "fy";
 +//    languages["GUJARATI"] = "gu";
 +//    languages["INUKTITUT"] = "iu";
 +//    languages["JAVANESE"] = "jw";
 +//    languages["KANNADA"] = "kn";
 +//    languages["KAZAKH"] = "kk";
 +//    languages["KHMER"] = "km";
 +//    languages["KURDISH"] = "ku";
 +//    languages["KYRGYZ"] = "ky";
 +//    languages["LAO"] = "lo";
 +//    languages["LATIN"] = "la";
 +//    languages["LUXEMBOURGISH"] = "lb";
 +//    languages["MALAYALAM"] = "ml";
 +//    languages["MAORI"] = "mi";
 +//    languages["MARATHI"] = "mr";
 +//    languages["MONGOLIAN"] = "mn";
 +//    languages["NEPALI"] = "ne";
 +//    languages["OCCITAN"] = "oc";
 +//    languages["ORIYA"] = "or";
 +//    languages["PASHTO"] = "ps";
 +//    languages["PORTUGUESE_PORTUGAL"] = "pt-PT";
 +//    languages["PUNJABI"] = "pa";
 +//    languages["QUECHUA"] = "qu";
 +//    languages["SANSKRIT"] = "sa";
 +//    languages["SCOTS_GAELIC"] = "gd";
 +//    languages["SINDHI"] = "sd";
 +//    languages["SINHALESE"] = "si";
 +//    languages["SUNDANESE"] = "su";
 +//    languages["SYRIAC"] = "syr";
 +//    languages["TAJIK"] = "tg";
 +//    languages["TAMIL"] = "ta";
 +//    languages["TATAR"] = "tt";
 +//    languages["TELUGU"] = "te";
 +//    languages["TIBETAN"] = "bo";
 +//    languages["TONGA"] = "to";
 +//    languages["UZBEK"] = "uz";
 +//    languages["UIGHUR"] = "ug";
 +    return languages;  
 +}
 +
 +
 +void GooglePlugin::getDictionaryInfo() {
 +    QString fullLangFrom=languages.key(_settings->value("lang_from"));
 +    QString fullLangTo=languages.key(_settings->value("lang_to"));
 +    _infoNote=" [" + fullLangFrom + "-" + fullLangTo + "] (Google)";
 +}
 +
 +
 +Q_EXPORT_PLUGIN2(google, GooglePlugin)
index cdadfe2,0000000..91782ba
mode 100644,000000..100644
--- /dev/null
@@@ -1,187 -1,0 +1,187 @@@
 +/*******************************************************************************
 +
 +    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.
 +
 +*******************************************************************************/
 +
 +/*! \file GoogleSettingsDialog.cpp
 +    \author Jakub Jaszczynski <j.j.jaszczynski@gmail.com>
 +*/
 +
 +#include "GoogleSettingsDialog.h"
 +#include <QDebug>
 +
 +GoogleSettingsDialog::GoogleSettingsDialog(QWidget *parent,
 +                                           Settings *pluginSettings,
 +                                           QString acceptButtonLabel) :
 +                                           QDialog(parent)
 +{
 +    QMap<QString, QString> languages;
 +    languages=GooglePlugin::initLanguages();
 +
 +    int actualLangTo=1;
 +    int actualLangFrom=1;
 +
 +    if(pluginSettings==0) {
 +        _langTo=languages.key("pl");
 +        _langFrom=languages.key("en");
 +    }
 +    else {
 +        _langTo=languages.key(pluginSettings->value("lang_to"));
 +        _langFrom=languages.key(pluginSettings->value("lang_from"));
 +    }
 +
 +    setMinimumHeight(370);
 +    #ifdef Q_WS_MAEMO_5
 +
 +        changeLangButton=new QPushButton(
 +                                 QIcon::fromTheme("general_refresh"), "");
 +    #else
 +        changeLangButton=new QPushButton(
 +                QIcon::fromTheme("object-flip-vertical"),tr(""));
 +    #endif
 +
 +    langFromLabel = new QLabel(tr("From:"));
 +    langToLabel = new QLabel(tr(" To: "));
 +    connectInfoLabel = new QLabel(tr("Google plugin makes use of Internet "
 +                                     "connection, so it may cost You."));
 +
 +    connectInfoLabel->setWordWrap(true);
 +    setWindowTitle(tr("Google Settings"));
 +
 +    verticalLayout = new QVBoxLayout;
 +    langLayout = new QVBoxLayout;
 +    langFromLayout = new QHBoxLayout;
 +    langToLayout = new QHBoxLayout;
 +    changelangLayout = new QHBoxLayout;
 +
 +    setLayout(verticalLayout);
 +
 +    infoLabel = new QLabel;
 +    infoLabel->setText(tr("Plugin: GoogleTranslator \n")+
 +                   tr("From: ") + _langFrom + "\n" +
 +                   tr("To: ") + _langTo);
 +    verticalLayout->addWidget(infoLabel);
 +
 +
 +    langFromComboBox = new QComboBox;
 +    langToComboBox = new QComboBox;
 +
 +    int i=0;
 +    foreach(QString langs,languages.keys()){
 +        if(langs==_langTo)
 +            actualLangTo=i;
 +        if(langs==_langFrom)
 +            actualLangFrom=i;
 +        langToComboBox->addItem(langs);
 +        langFromComboBox->addItem(langs);
 +        i++;
 +    }
 +    langToComboBox->setCurrentIndex(actualLangTo);
 +    langFromComboBox->setCurrentIndex(actualLangFrom);
 +
 +
 +
 +    setWindowTitle(tr("Google Settings"));
 +    verticalLayout->addWidget(connectInfoLabel);
 +
 +    langFromLayout->addWidget(langFromLabel);
 +    langFromLayout->addWidget(langFromComboBox);
 +    langToLayout->addWidget(langToLabel);
 +    langToLayout->addWidget(langToComboBox);
 +
 +
 +    langLayout->addLayout(langFromLayout);
 +    langLayout->addLayout(langToLayout);
 +    changelangLayout->addLayout(langLayout);
 +    changelangLayout->addWidget(changeLangButton);
 +    verticalLayout->addLayout(changelangLayout);
 +
 +    saveButton = new QPushButton(acceptButtonLabel);
 +    verticalLayout->addWidget(saveButton);
 +
 +    setModal(true);
 +
 +    connect(saveButton, SIGNAL(clicked()),
 +            this, SLOT(accept()));
 +
 +
 +    connect(langFromComboBox, SIGNAL(activated(int)),
 +            this, SLOT(activatedFrom(int)));
 +    connect(langToComboBox, SIGNAL(activated(int)),
 +            this, SLOT(activatedTo(int)));
 +
 +
 +    connect(changeLangButton, SIGNAL(clicked()),
 +            this, SLOT(changeLangButtonClicked()));
 +}
 +
 +
 +void GoogleSettingsDialog::activatedFrom(int index) {
 +        _langFrom=langFromComboBox->itemText(index);
 +}
 +
 +void GoogleSettingsDialog::activatedTo(int index) {
 +     _langTo=langToComboBox->itemText(index);
 +}
 +
 +
 +void GoogleSettingsDialog::changeLangButtonClicked() {
 +
 +    int tempIndexTo=langToComboBox->currentIndex();
 +    QString tempLangTo=_langTo;
 +    langToComboBox->setCurrentIndex(langFromComboBox->currentIndex());
 +    langFromComboBox->setCurrentIndex(tempIndexTo);
 +    _langTo=_langFrom;
 +    _langFrom=tempLangTo;
 +
 +}
 +
 +QString GoogleSettingsDialog::langFrom() {
 +    return _langFrom;
 +}
 +
 +QString GoogleSettingsDialog::langTo() {
 +    return _langTo;
 +}
 +
 +Settings* GoogleSettingsDialog::getSettings(QWidget *parent,
 +                                            Settings *pluginSettings,
 +                                             QString acceptButtonLabel) {
 +    GoogleSettingsDialog settingsDialog(parent,pluginSettings,acceptButtonLabel);
 +
 +    QMap<QString, QString> languages;
 +    languages=GooglePlugin::initLanguages();
 +    if(settingsDialog.exec()==QDialog::Accepted) {
 +        Settings *settings = new Settings();
 +        settings->setValue("lang_to",languages.value(settingsDialog.langTo()));
 +        settings->setValue("lang_from",languages.value(settingsDialog.langFrom()));
 +        settings->setValue("connection_accepted","true");
 +        settings->setValue("type","google");
 +        return settings;
 +    }
 +    return 0;
 +}
 +
 +void GoogleSettingsDialog::changeSettings(GooglePlugin* plugin,
 +                                          QWidget *parent) {
 +    Settings *settings = new Settings();
 +    settings=getSettings(parent,plugin->settings(),tr("Save changes"));
-     if(settings)
-         plugin->setSettings(settings);
++    plugin->setSettings(settings);
++    delete settings;
 +}
index c214a7b,0000000..0bd9718
mode 100644,000000..100644
--- /dev/null
@@@ -1,73 -1,0 +1,76 @@@
 +/*******************************************************************************
 +
 +    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.
 +
 +*******************************************************************************/
 +/*! \file TranslationXdxf.cpp
 +    \author Jakub Jaszczynski <j.j.jaszczynski@gmail.com>
 +*/
 +
 +
 +#include "TranslationXdxf.h"
 +#include <QDebug>
 +
 +TranslationXdxf::TranslationXdxf():_key(""),_dictionaryInfo("") {
 +    xdxfPlugin=0;
++//   qDebug()<<"\n\n create translaton Xdxf\n\n";
 +}
 +
 +TranslationXdxf::TranslationXdxf(QString _key, QString _dictionaryInfo,
 +         XdxfPlugin *xdxfPlugin): _key(_key),_dictionaryInfo(_dictionaryInfo) {
 +    this->xdxfPlugin=xdxfPlugin;
 +    if(xdxfPlugin)
 +        _dictHash = xdxfPlugin->hash();
 +    _bookmark=0;
++
++//    qDebug()<<"create translaton Xdxf";
 +}
 +
 +TranslationXdxf::~TranslationXdxf() {
-    // qDebug()<<"\n\n delete translation:: Xdxf\n\n";
++//    qDebug()<<"delete translation:: Xdxf";
 +}
 +
 +QString TranslationXdxf::key() const {
 +    return _key;
 +}
 +
 +QString TranslationXdxf::dictionaryInfo() const {
 +    return _dictionaryInfo;
 +}
 +
 +QString TranslationXdxf::toHtml() const { 
 +    QString result("");
 +    if(!xdxfPlugin)
 +        return result;
 +    result=result + "<dict>" + "<info";
 +    if(isBookmark())
 +        result+= " bookmark=\"true\" ";
 +    else
 +        result+= " bookmark=\"false\" ";
 +    result+= _dictionaryInfo + "</info>" + xdxfPlugin->search(_key) + "</dict>";
 +    return result.replace("&","&amp;");
 +}
 +
 +void TranslationXdxf::setKey(QString _key) {
 +    this->_key=_key;
 +}
 +
 +void TranslationXdxf::setDictionaryInfo(QString _dictionaryInfo) {
 +    this->_dictionaryInfo=_dictionaryInfo;
 +}
 +
index 4bb5282,0000000..c3ce79e
mode 100644,000000..100644
--- /dev/null
@@@ -1,130 -1,0 +1,129 @@@
 +/*******************************************************************************
 +
 +    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.
 +
 +*******************************************************************************/
 +
 +/*! \file XdxfLoadDialog.cpp
 +*/
 +//Created by Mateusz Półrola
 +
 +#include "XdxfLoadDialog.h"
 +
 +XdxfLoadDialog::XdxfLoadDialog(QWidget *parent) :
 +    QDialog(parent) {
 +    verticalLayout = new QVBoxLayout;
 +    setLayout(verticalLayout);
 +
 +    setWindowTitle(tr("Add new XDXF dictionary"));
 +
 +    browseLayout = new QVBoxLayout;
 +
 +    browseButton =  new QPushButton(tr("Browse"));
 +    browseLabel = new QLabel(tr("Dictionary file: not selected"));
 +    //browseLabel->setWordWrap(true);
 +    browseLabel->setMargin(5);
 +
 +    browseLayout->addWidget(browseLabel, 0, Qt::AlignLeft);
 +    browseLayout->addWidget(browseButton);
 +
 +    verticalLayout->addLayout(browseLayout);
 +
 +    cacheLayout = new QHBoxLayout;
 +    verticalLayout->addLayout(cacheLayout);
-     accentsCheckBox = new QCheckBox(tr("Strip accents \n(searching takes more time, "
-                  "but spelling don't have to be exact)"));
++    accentsCheckBox = new QCheckBox(tr("Strip accents \n(searching takes more "
++                 "time, but spelling don't have to be exact)"));
 +    verticalLayout->addWidget(accentsCheckBox);
 +
 +    cacheCheckBox = new QCheckBox(tr("Optimize for quicker searches (may take some time)"),this);
 +    cacheCheckBox->setChecked(true);
 +    cacheLayout->addWidget(cacheCheckBox);
 +
 +    addButton = new QPushButton(tr("Add"));
 +
 +    verticalLayout->addWidget(addButton);
 +
 +    setModal(true);
 +
 +    connect(browseButton, SIGNAL(clicked()),
 +            this, SLOT(selectFile()));
 +
 +    connect(addButton, SIGNAL(clicked()),
 +            this, SLOT(addDictionary()));
 +
 +    _dicitonaryFilePath = QString();
 +}
 +
 +void XdxfLoadDialog::selectFile() {
 +    QString fileName = QFileDialog::getOpenFileName(this,
 +                                     tr("Select dictionary file"),
 +                                     "",
 +                                     tr("XDXF Files (*.xdxf)"),
 +                                     NULL,
 +                                     NULL);
 +
 +    if (!fileName.isEmpty()) {
-         qDebug()<<fileName;
 +        browseLabel->setText(tr("Dictionary file: %1").arg(fileName));
 +        _dicitonaryFilePath = fileName;
 +    }repaint(rect());
 +    resize(size());
 +}
 +
 +void XdxfLoadDialog::addDictionary() {
 +    _generateCache = cacheCheckBox->isChecked();
 +    if(!_dicitonaryFilePath.isEmpty()) {
 +        accept();
 +    }
 +    else {
 +        reject();
 +    }
 +}
 +
 +QString XdxfLoadDialog::dicitonaryFilePath() {
 +    return _dicitonaryFilePath;
 +}
 +
 +bool XdxfLoadDialog::generateCache() {
 +    return _generateCache;
 +}
 +
 +Settings* XdxfLoadDialog::getSettings(QWidget *parent) {
 +    XdxfLoadDialog loadDialog(parent);
 +    Settings* settings = new Settings;
 +
 +    if(loadDialog.exec()==QDialog::Accepted) {
 +        settings->setValue("path", loadDialog.dicitonaryFilePath());
 +        if(loadDialog.generateCache()) {
 +            settings->setValue("generateCache", "true");
 +        }
 +        else {
 +            settings->setValue("generateCache", "false");
 +        }
 +        if(loadDialog.accentsCheckBox->isChecked())
 +            settings->setValue("strip_accents", "true");
 +        else
 +            settings->setValue("strip_accents", "false");
 +
 +
 +        return settings;
 +    }
 +
 +    return NULL;
 +}
 +
 +
index 9f2a3d6,0000000..7afb707
mode 100644,000000..100644
--- /dev/null
@@@ -1,155 -1,0 +1,156 @@@
 +/*******************************************************************************
 +
 +    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.
 +
 +*******************************************************************************/
 +
 +/*! \file XdxfSettingsDialog.cpp
 +*/
 +//Created by Mateusz Półrola
 +
 +#include "XdxfSettingsDialog.h"
 +#include <QDebug>
 +
 +XdxfSettingsDialog::XdxfSettingsDialog(XdxfPlugin *plugin, QWidget *parent) :
 +    QDialog(parent)
 +{
 +    this->plugin = plugin;
-     verticalLayout = new QVBoxLayout(this);
++    verticalLayout = new QVBoxLayout();
 +       setLayout(verticalLayout);
 +
 +    setWindowTitle(tr("XDXF Settings"));
 +
 +
 +    infoLabel = new QLabel(this);
 +
 +    infoLabel->setText(tr("Plugin: ") + plugin->type().toUpper() +"\n" +
 +                   tr("From: ") + plugin->langFrom() + "\n" +
 +                   tr("To: ") + plugin->langTo() + "\n" +
 +                   tr("Description: ") + plugin->name());
 +
 +    verticalLayout->addWidget(infoLabel);
 +
-     browseLayout = new QHBoxLayout(this);
++    browseLayout = new QHBoxLayout();
 +    verticalLayout->addLayout(browseLayout);
 +
-     browseButton =  new QPushButton(tr("Browse"),this);
++    browseButton =  new QPushButton(tr("Browse"));
 +    browseLabel = new QLabel(tr("Dictionary file: ") +
-                              plugin->settings()->value("path"),this);
++                             plugin->settings()->value("path"));
 +
 +    browseLayout->addWidget(browseLabel);
 +    browseLayout->addWidget(browseButton,0, Qt::AlignRight);
 +
 +
-     cacheLayout = new QHBoxLayout(this);
++    cacheLayout = new QHBoxLayout();
 +    verticalLayout->insertLayout(-1,cacheLayout,0);
 +    accentsCheckBox = new QCheckBox(tr("Strip accents \n(searching takes more time, "
 +                 "but spelling don't have to be exact)"));
 +    verticalLayout->addWidget(accentsCheckBox);
 +
 +    if(plugin->settings()->value("strip_accents") == "true")
 +        accentsCheckBox->setChecked(true);
 +    else
 +        accentsCheckBox->setChecked(false);
 +
 +    cacheCheckBox = new QCheckBox(tr("Optimize for quicker searches (may take some time)"),this);
 +    if(plugin->settings()->value("cached") == "true") {
 +        cacheCheckBox->setChecked(true);
 +        _generateCache = true;
 +    }
 +    else {
 +        cacheCheckBox->setChecked(false);
 +        _generateCache = false;
 +    }
 +
 +    cacheLayout->addWidget(cacheCheckBox);
 +
-     saveButton = new QPushButton(tr("Save settings"),this);
++    saveButton = new QPushButton(tr("Save settings"));
 +
 +    verticalLayout->addWidget(saveButton);
 +
 +    setModal(true);
 +
 +    connect(browseButton, SIGNAL(clicked()),
 +            this, SLOT(selectFile()));
 +
 +    connect(saveButton, SIGNAL(clicked()),
 +            this, SLOT(accept()));
 +
 +    connect(cacheCheckBox, SIGNAL(toggled(bool)),
 +            SLOT(setGenerateCache(bool)));
 +
 +    _dicitonaryFilePath = plugin->settings()->value("path");
 +}
 +
 +void XdxfSettingsDialog::setGenerateCache(bool generate) {
 +    _generateCache = generate;
 +}
 +
 +bool XdxfSettingsDialog::generateCache() {
 +    return _generateCache;
 +}
 +
 +void XdxfSettingsDialog::selectFile() {
 +    QString fileName = QFileDialog::getOpenFileName(this,
 +                                     tr("Select dictionary file"),
 +                                     "",
 +                                     tr("XDXF Files (*.xdxf)"),
 +                                     NULL,
 +                                     NULL);
 +    if (!fileName.isEmpty()) {
 +        browseLabel->setText(tr("Dictionary file: ") + fileName);
 +        _dicitonaryFilePath = fileName;
 +    }    
 +}
 +
 +QString XdxfSettingsDialog::dicitonaryFilePath() {
 +    return _dicitonaryFilePath;
 +}
 +
 +Settings* XdxfSettingsDialog::getSettings(XdxfPlugin *plugin,
 +                                          QWidget *parent) {
 +    XdxfSettingsDialog settingsDialog(plugin, parent);
 +
 +
 +    if(settingsDialog.exec()==QDialog::Accepted) {
 +        Settings* settings = new Settings;
 +        foreach(QString key, plugin->settings()->keys())
 +            settings->setValue(key, plugin->settings()->value(key));
 +        settings->setValue("path", settingsDialog.dicitonaryFilePath());
 +
 +        if(settingsDialog.generateCache()) {
 +            settings->setValue("generateCache", "true");
 +        }
 +        else {
 +            settings->setValue("generateCache", "false");
 +        }
 +
 +        if(settingsDialog.accentsCheckBox->isChecked())
 +            settings->setValue("strip_accents", "true");
 +        else
 +            settings->setValue("strip_accents", "false");
 +
 +        plugin->setSettings(settings);
++        delete settings;
 +        return 0;
 +    }
 +
 +    return 0;
 +}
 +
 +
index ba143b9,0000000..9a29f8a
mode 100644,000000..100644
--- /dev/null
@@@ -1,591 -1,0 +1,613 @@@
 +/*******************************************************************************
 +
 +    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.
 +
 +*******************************************************************************/
 +
 +/*! \file xdxfplugin.cpp
 +\author Jakub Jaszczynski <j.j.jaszczynski@gmail.com>
 +*/
 +
 +#include "xdxfplugin.h"
 +#include <QDebug>
 +#include "../../common/Notify.h"
 +
 +XdxfPlugin::XdxfPlugin(QObject *parent) : CommonDictInterface(parent),
 +                    _langFrom(""), _langTo(""),_name(""), _infoNote("") {
 +    _settings = new Settings();
 +    _dictDialog = new XdxfDictDialog(this);
 +    cachingDialog = new XdxfCachingDialog(this);
 +
 +    _settings->setValue("type","xdxf");
 +    _icon = QIcon(":/icons/xdxf.png");
 +    _wordsCount = -1;
 +    stopped = false;
 +
 +    connect(cachingDialog, SIGNAL(cancelCaching()),
 +            this, SLOT(stop()));
 +    connect(this, SIGNAL(updateCachingProgress(int,int)),
 +            cachingDialog, SLOT(updateCachingProgress(int,int)));
 +    initAccents();
 +}
 +
 +
 +XdxfPlugin::~XdxfPlugin() {
 +    delete _settings;
 +    delete cachingDialog;
++    delete _dictDialog;
 +}
 +
 +
 +QString XdxfPlugin::langFrom() const {   
 +    return _langFrom;
 +}
 +
 +
 +QString XdxfPlugin::langTo() const {
 +    return  _langTo;
 +}
 +
 +
 +QString XdxfPlugin::name() const {
 +    return  _name;
 +}
 +
 +
 +QString XdxfPlugin::type() const {
 +    return QString("xdxf");
 +}
 +
 +
 +QString XdxfPlugin::infoNote() const {
 +    return  _infoNote;
 +}
 +
 +
 +QList<Translation*> XdxfPlugin::searchWordList(QString word, int limit) {
 +    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) {
 +    int i=0;
 +    QSet<Translation*> translations;
 +    QString cacheFilePath = _settings->value("cache_path");
 +
- //  QSqlDatabase::removeDatabase(cacheFilePath);
 +    db.setDatabaseName(cacheFilePath);
 +    if(!QFile::exists(cacheFilePath) || !db.open()) {
 +        qDebug() << "Database error" << db.lastError().text() << endl;
 +        Q_EMIT notify(Notify::Warning, QString(tr("Cache database cannot be "
 +                "opened for %1 dictionary. Searching in XDXF file. "
 +                "You may want to recache.").arg(name())));
 +        _settings->setValue("cached","false");
 +        return searchWordListFile(word, limit);
 +    }
 +    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;
 +        }
 +        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) {
 +    QSet<Translation*> translations;
 +    QFile dictionaryFile(_settings->value("path"));
 +    word = word.toLower();
 +    stopped = false;
 +
 +    QRegExp regWord(word);
 +    regWord.setCaseSensitivity(Qt::CaseInsensitive);
 +    regWord.setPatternSyntax(QRegExp::Wildcard);
 +
 +    /*check xdxf file exist*/
 +    if(!QFile::exists(_settings->value("path"))
 +                || !dictionaryFile.open(QFile::ReadOnly | QFile::Text)) {
 +        qDebug()<<"Error: could not open file";
 +        Q_EMIT notify(Notify::Warning,
 +                QString(tr("XDXF file cannot be read for %1").arg(name())));
 +        return translations.toList();
 +    }
 +
 +    QXmlStreamReader reader(&dictionaryFile);
 +    QString readKey;
 +    int i=0;
 +
 +    /*search words list*/
 +    while(!reader.atEnd() && !stopped){
 +        reader.readNextStartElement();
 +        if(reader.name()=="ar") {
 +            while(reader.name()!="k" && !reader.atEnd())
 +                reader.readNextStartElement();
 +            if(!reader.atEnd())
 +                readKey = reader.readElementText();
 +            if((regWord.exactMatch(readKey)
 +                    || regWord.exactMatch(removeAccents(readKey)))
 +                    && (i<limit || limit==0)) {
 +                bool ok=true;
 +                Translation *tran;
 +                foreach(tran,translations) {
 +                    if(tran->key().toLower()==readKey.toLower())
 +                        ok=false; /*if key is in the dictionary more that one */
 +                }
 +                if(ok) {  /*add key word to list*/
 +                    translations<<(new TranslationXdxf(readKey.toLower(),
 +                                    _infoNote,this));
 +                    i++;
 +                }
 +                if(i>=limit && limit!=0)
 +                    break;
 +            }
 +        }
 +        this->thread()->yieldCurrentThread();
 +    }
 +    stopped=false;
 +    dictionaryFile.close();
 +    return translations.toList();
 +}
 +
 +
 +QString XdxfPlugin::search(QString key) {
 +    if(isCached())
 +        return searchCache(key);
 +    return searchFile(key);
 +}
 +
 +
 +QString XdxfPlugin::searchCache(QString key) {
 +    QString result("");
 +    QString cacheFilePath = _settings->value("cache_path");
 +    db.setDatabaseName(cacheFilePath);
 +    key = key.toLower();
 +
 +    if(!QFile::exists(cacheFilePath) || !db.open()) {
 +        qDebug() << "Database error" << db.lastError().text() << endl;
 +        Q_EMIT notify(Notify::Warning, QString(tr("Cache database cannot be "
 +                "opened for %1 dictionary. Searching in XDXF file. "
 +                "You may want to recache.").arg(name())));
 +        _settings->setValue("cached","false");
 +        return searchFile(key);
 +    }
 +
 +    QSqlQuery cur(db);
 +
 +    cur.prepare("select translation from dict where word like ?");
 +    cur.addBindValue(key);
 +    cur.exec();
 +    while(cur.next())
 +        result += cur.value(0).toString();
 +
 +    db.close();
 +
 +    return result;
 +
 +}
 +
 +
 +QString XdxfPlugin::searchFile(QString key) {
 +    QFile dictionaryFile(_settings->value("path"));
 +    QString resultString("");
 +    key = key.toLower();
 +
 +    /*check xdxf file exist*/
 +    if(!QFile::exists(_settings->value("path"))
 +                || !dictionaryFile.open(QFile::ReadOnly | QFile::Text)) {
 +        Q_EMIT notify(Notify::Warning,
 +                QString(tr("XDXF file cannot be read for %1").arg(name())));
 +        qDebug()<<"Error: could not open file";
 +        return "";
 +    }
 +
 +    QXmlStreamReader reader(&dictionaryFile);
 +    QString readKey;
 +    bool match =false;
 +    stopped = false;
 +
 +    /*search translations for word*/
 +    while (!reader.atEnd()&& !stopped) {
 +        reader.readNext();
 +        if(reader.tokenType() == QXmlStreamReader::StartElement) {
 +            if(reader.name()=="k") {
 +                readKey = reader.readElementText();
 +                if(readKey.toLower()==key.toLower())
 +                    match = true;
 +            }
 +        }
 +        if(match) {
 +            QString temp("");
 +            while(reader.name()!="ar" && !reader.atEnd()) {
 +                if(reader.name()!="" && reader.name()!="k") {
 +                    if(reader.tokenType()==QXmlStreamReader::EndElement)
 +                        temp+="</";
 +                    if(reader.tokenType()==QXmlStreamReader::StartElement)
 +                        temp+="<";
 +                    temp+=reader.name().toString();
 +                    if(reader.name().toString()=="c" &&
 +                            reader.tokenType()==QXmlStreamReader::StartElement)
 +                       temp= temp + " c=\"" + reader.attributes().
 +                               value("c").toString() + "\"";
 +                    temp+=">";
 +                }
 +                temp+= reader.text().toString().replace("<","&lt;").
 +                        replace(">","&gt;");
 +                reader.readNext();
 +            }
 +            if(temp.at(0)==QChar('\n'))
 +                temp.remove(0,1);
 +            resultString+="<key>" + readKey +"</key>";
 +            resultString+="<t>" + temp + "</t>";
 +            match=false;
 +        }
 +        this->thread()->yieldCurrentThread();
 +    }
 +    stopped=false;
 +    dictionaryFile.close();
 +    return resultString;
 +}
 +
 +
 +void XdxfPlugin::stop() {
 +    stopped=true;
 +}
 +
 +
 +DictDialog* XdxfPlugin::dictDialog() {
 +     return _dictDialog;
 +}
 +
 +
 +CommonDictInterface* XdxfPlugin::getNew(const Settings *settings) const {
++
++    qDebug()<<"tu";
 +    XdxfPlugin *plugin = new XdxfPlugin();
++    qDebug()<<"tu2";
 +    if(settings){
++            qDebug()<<"tu3";
 +        plugin->setSettings(settings);
 +    }
 +    return  plugin;
 +}
 +
 +
 +bool XdxfPlugin::isAvailable() const {
 +    return true;
 +}
 +
 +
 +void XdxfPlugin::setHash(uint _hash) {
 +    this->_hash=_hash;
 +}
 +
 +
 +uint XdxfPlugin::hash() const {
 +   return _hash;
 +}
 +
 +
 +Settings* XdxfPlugin::settings() {
++/*
++    Settings *returnSettings=new Settings;
++    QStringList list = _settings->keys();
++    foreach(QString key, list)
++            returnSettings->setValue(key,_settings->value(key));
++    return returnSettings;
++*/
 +    return _settings;
 +}
 +
 +
 +bool XdxfPlugin::isCached() {
 +    if(_settings->value("cached") == "true")
 +        return true;
 +    return false;
 +}
 +
 +
 +void XdxfPlugin::setSettings(const Settings *settings) {
++    qDebug()<<"tu4";
 +    if(settings) {
++        qDebug()<<"tu5";
 +        bool isPathChange=false;
 +        QString oldPath = _settings->value("path");
 +        if(oldPath != settings->value("path")) {
 +            if(oldPath!="" && _settings->value("cache_path")!="")
 +                clean();
 +            isPathChange=true;
 +        }
 +
 +        foreach(QString key, settings->keys()) {
 +           if(key != "generateCache")
 +               _settings->setValue(key, settings->value(key));
 +        }
 +
 +        if(isPathChange) {
 +            _wordsCount=0;
-             if(oldPath!="") {
++            if(oldPath!="")
 +                _settings->setValue("cached","false");
-                 QSqlDatabase::removeDatabase(db_name);
++            if(_settings->value("cached")=="true"
++                    && _settings->value("cache_path")!="") {
++                db_name = _settings->value("type")
++                        + _settings->value("cache_path");
++                db = QSqlDatabase::addDatabase("QSQLITE",db_name);
 +            }
-             db_name = _settings->value("type") + _settings->value("path");
-             db = QSqlDatabase::addDatabase("QSQLITE",db_name);
 +        }
 +
 +        if((_settings->value("cached") == "false" ||
 +            _settings->value("cached").isEmpty()) &&
 +            settings->value("generateCache") == "true") {
 +            clean();
 +            makeCache("");
 +        }
 +
 +        else if (settings->value("generateCache") == "false") {
 +            _settings->setValue("cached", "false");
 +        }
 +
 +        getDictionaryInfo();
 +    }
 +    Q_EMIT settingsChanged();
 +}
 +
 +
 +void XdxfPlugin::getDictionaryInfo() {
 +    QFile dictionaryFile(_settings->value("path"));
 +    if(!QFile::exists(_settings->value("path"))
 +                || !dictionaryFile.open(QFile::ReadOnly | QFile::Text)) {
 +       Q_EMIT notify(Notify::Warning,
 +               QString(tr("XDXF dictionary cannot be read from file")));
 +        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();
 +
 +    QString format = "png";
 +    QString initialPath = QDir::currentPath() + "/xdxf." + format;
 +
 +    _infoNote="path=\""+initialPath+"\"> \n" + _name + " [" + _langFrom + "-"
 +                + _langTo + "] ( xdxf )";
 +    dictionaryFile.close();
 +}
 +
 +
 +QIcon* XdxfPlugin::icon() {
 +    return &_icon;
 +}
 +
 +
 +int XdxfPlugin::countWords() {
 +    if(_wordsCount>0)
 +        return _wordsCount;
 +    QFile dictionaryFile(_settings->value("path"));
 +    if(!QFile::exists(_settings->value("path"))
 +                || !dictionaryFile.open(QFile::ReadOnly | QFile::Text)) {
 +        Q_EMIT notify(Notify::Warning,
 +                QString(tr("XDXF file cannot be read for %1 dictionary")
 +                .arg(name())));
 +        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) {
 +    cachingDialog->setVisible(true);
 +    QCoreApplication::processEvents();
 +    QFileInfo dictFileN(_settings->value("path"));
 +    QString cachePathN;
 +    stopped = false;
 +
 +    /*create cache file name*/
 +    int i=0;
 +    do {
 +        cachePathN = QDir::homePath() + "/.mdictionary/"
 +                                      + dictFileN.completeBaseName()+"."
 +                                      +QString::number(i) + ".cache";
 +        i++;
 +    } while(QFile::exists(cachePathN));
 +
++    db_name = _settings->value("type") + cachePathN;
++    db = QSqlDatabase::addDatabase("QSQLITE",db_name);
++
++    qDebug()<<QSqlDatabase::connectionNames().size();
++    foreach(QString name,QSqlDatabase::connectionNames())
++        qDebug()<<name;
 +    /*checke errors (File open and db open)*/
 +    QFile dictionaryFile(dictFileN.filePath());
 +    if (!QFile::exists(_settings->value("path"))
 +                || !dictionaryFile.open(QFile::ReadOnly | QFile::Text)) {
 +        Q_EMIT updateCachingProgress(100, 0);
 +        Q_EMIT notify(Notify::Warning,
 +                QString(tr("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(tr("Cache database cannot be "
 +                "opened for %1 dictionary. Searching in XDXF file. "
 +                "You may want to recache.").arg(name())));
 +        return false;
 +    }
 +
 +    /*inicial sqlQuery*/
 +    QCoreApplication::processEvents();
 +    QSqlQuery cur(db);
 +    cur.exec("PRAGMA synchronous = 0");
 +    cur.exec("drop table dict");
 +    QCoreApplication::processEvents();
 +    cur.exec("create table dict(word text, normalized text ,translation text)");
 +    int counter = 0;
 +    cur.exec("BEGIN;");
 +
 +    QString readKey;
 +    bool match = false;
 +    QTime timer;
 +    timer.start();
 +    countWords();
 +    int lastProg = -1;
-     settings()->setValue("strip_accents", "true");
++    _settings->setValue("strip_accents", "true");
 +    counter=0;
 +
 +    /*add all words to db*/
 +    while (!reader.atEnd() && !stopped) {
 +        QCoreApplication::processEvents();
 +        reader.readNext();
 +        if(reader.tokenType() == QXmlStreamReader::StartElement) {
 +            if(reader.name()=="k"){
 +                readKey = 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+="</";
 +                    if(reader.tokenType()==QXmlStreamReader::StartElement)
 +                        temp+="<";
 +                    temp+=reader.name().toString();
 +                    if(reader.name().toString()=="c"
 +                        && reader.tokenType()==QXmlStreamReader::StartElement) {
 +                        temp= temp + " c=\""
 +                                   + reader.attributes().value("c").toString()
 +                                   + "\"";
 +                    }
 +                    temp+=">";
 +                }
 +                temp+= reader.text().toString().replace("<","&lt;").replace(">"
 +                              ,"&gt;");
 +                reader.readNext();
 +            }
 +            if(temp.at(0)==QChar('\n'))
 +                temp.remove(0,1);
 +            temp="<key>" + readKey + "</key>" + "<t>" + temp+ "</t>";
 +            match=false;
 +            cur.prepare("insert into dict values(?,?,?)");
 +            cur.addBindValue(readKey);
 +            cur.addBindValue(removeAccents(readKey));
 +            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");
 +    cachingDialog->setVisible(false);
 +
 +    /*checke errors (wrong number of added words)*/
 +    countWords();
 +    if(!cur.next() || countWords() != cur.value(0).toInt()) {
 +        Q_EMIT updateCachingProgress(100, timer.restart());
 +        Q_EMIT notify(Notify::Warning,
 +                QString(tr("Database caching error, please try againg.")));
 +        db.close();
 +        return false;
 +    }
 +
 +    _settings->setValue("cache_path", cachePathN);
 +    _settings->setValue("cached", "true");
 +
 +    db.close();
 +    return true;
 +}
 +
 +
 +void XdxfPlugin::clean() {
-     if(QFile::exists(_settings->value("cache_path")))
++    if(QFile::exists(_settings->value("cache_path"))) {
 +        QFile(_settings->value("cache_path")).remove();
++        QSqlDatabase::removeDatabase(db_name);
++    }
 +}
 +
 +
 +Q_EXPORT_PLUGIN2(xdxf, XdxfPlugin)
index 429b135,0000000..f7bfed6
mode 100644,000000..100644
--- /dev/null
@@@ -1,403 -1,0 +1,415 @@@
 +/*******************************************************************************
 +
 +    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 "test.h"
 +#include <QSignalSpy>
 +
 +void XdxfTest::getNew() {
 +
 +    XdxfPlugin xdxfPluginB(this);
 +    Settings *settings=new Settings;
 +    settings->setValue("path","../tests/dict.xdxf");
 +    CommonDictInterface *xdxfPlugin = xdxfPluginB.getNew(settings);
++    delete settings;
 +
 +    QList<Translation*> te6=xdxfPlugin->searchWordList("*",8);
 +    QCOMPARE(te6.size(),8);
 +
 +    xdxfPlugin->clean();
 +    delete xdxfPlugin;
 +}
 +
 +void XdxfTest::searchFile() {
 +
 +    XdxfPlugin xdxfPluginB(this);
 +    Settings *settings=new Settings;
 +    settings->setValue("path","../tests/dict.xdxf");
 +    CommonDictInterface *xdxfPlugin = xdxfPluginB.getNew(settings);
++    delete settings;
 +
 +    QCOMPARE(xdxfPlugin->search("."), QString("<key>.</key><t>kropka</t>"));
 +    QCOMPARE(xdxfPlugin->search("1"), QString("<key>1</key><t>one</t>"));
 +    QCOMPARE(xdxfPlugin->search("test"), QString("<key>test</key><t><c c=\"FF00FF\">kro</c>test01<pos>krowa</pos></t>"));
 +
 +    xdxfPlugin->clean();
 +    delete xdxfPlugin;
 +}
 +
 +void XdxfTest::makeCache()
 +{
 +    XdxfPlugin xdxfPluginB(this);
 +    Settings *settings=new Settings;
 +    settings->setValue("path","../tests/dict.xdxf");
 +    settings->setValue("generateCache", "true");
 +    CommonDictInterface *xdxfPlugin = xdxfPluginB.getNew(settings);
++    delete settings;
++
 +    QCOMPARE(xdxfPlugin->settings()->value("cached"),tr("true"));
 +
 +    xdxfPlugin->clean();
 +    delete xdxfPlugin;
 +}
 +
 +void XdxfTest::searchCache() {
 +    XdxfPlugin xdxfPluginB(this);
 +    Settings *settings=new Settings;
 +    settings->setValue("path","../tests/dict.xdxf");
 +    settings->setValue("generateCache", "true");
 +    CommonDictInterface *xdxfPlugin = xdxfPluginB.getNew(settings);
++    delete settings;
 +
 +    QCOMPARE(xdxfPlugin->settings()->value("cached"),tr("true"));
 +    QCOMPARE(xdxfPlugin->search("."), QString("<key>.</key><t>kropka</t>"));
 +    QCOMPARE(xdxfPlugin->search("1"), QString("<key>1</key><t>one</t>"));
 +    QCOMPARE(xdxfPlugin->search("test"), QString("<key>test</key><t><c c=\"FF00FF\">kro</c>test01<pos>krowa</pos></t>"));
 +
 +    xdxfPlugin->clean();
 +    delete xdxfPlugin;
 +}
 +
 +void XdxfTest::searchWordListCache(){
 +    XdxfPlugin xdxfPluginB(this);
 +    Settings *settings=new Settings;
 +    settings->setValue("path","../tests/dict.xdxf");
 +    settings->setValue("generateCache", "true");
 +    CommonDictInterface *xdxfPlugin = xdxfPluginB.getNew(settings);
++    delete settings;
 +
 +    QList<Translation*> te = xdxfPlugin->searchWordList(".", 10);
 +    if(te.size()>0)
 +        QCOMPARE(te.size(), 1);
 +    QList<Translation*> te2 = xdxfPlugin->searchWordList("1",10);
 +    QCOMPARE(te2.size(), 5);
 +
 +    QList<Translation*> te3 = xdxfPlugin->searchWordList("1", 2);
 +        QCOMPARE(te3.size(), 2);
 +
 +    QList<Translation*> te4 = xdxfPlugin->searchWordList("ho*SE", 10);
 +        QCOMPARE(te4.at(0)->key(), QString("house"));
 +
 +    QList<Translation*> te5 = xdxfPlugin->searchWordList("*");
 +        QCOMPARE(te5.size(), 9);
 +
 +    QList<Translation*> te6 = xdxfPlugin->searchWordList("*", 8);
 +        QCOMPARE(te6.size(), 8);
 +
 +    QList<Translation*> te7 = xdxfPlugin->searchWordList("*ou*");
 +        QCOMPARE(te7.at(0)->key(), QString("house"));
 +
 +    QList<Translation*> te8 = xdxfPlugin->searchWordList("1?");
 +        QCOMPARE(te8.at(0)->key(), QString("10"));
 +
 +    QList<Translation*> te9 = xdxfPlugin->searchWordList("1???");
 +        QCOMPARE(te9.at(0)->key(), QString("1000"));
 +
 +    QList<Translation*> te10 = xdxfPlugin->searchWordList("1????*");
 +        QCOMPARE(te10.at(0)->key(), QString("1 000 000"));
 +
 +    QList<Translation*> te11 = xdxfPlugin->searchWordList("h**?*?**e");
 +        QCOMPARE(te11.at(0)->key(), QString("house"));
 +
 +    xdxfPlugin->clean();
 +    delete xdxfPlugin;
 +}
 +
 +void XdxfTest::searchWordListFile() {
 +
 +    XdxfPlugin xdxfPluginB(this);
 +    Settings *settings=new Settings;
 +    settings->setValue("path","../tests/dict.xdxf");
 +    CommonDictInterface *xdxfPlugin = xdxfPluginB.getNew(settings);
++    delete settings;
 +
 +    QList<Translation*> te = xdxfPlugin->searchWordList(".", 10);
 +    if(te.size()>0)
 +        QCOMPARE(te.size(), 1);
 +    QList<Translation*> te2 = xdxfPlugin->searchWordList("1",10);
 +    QCOMPARE(te2.size(), 5);
 +
 +    QList<Translation*> te3 = xdxfPlugin->searchWordList("1", 2);
 +        QCOMPARE(te3.size(), 2);
 +
 +    QList<Translation*> te4 = xdxfPlugin->searchWordList("ho*SE", 10);
 +        QCOMPARE(te4.at(0)->key(), QString("house"));
 +
 +    QList<Translation*> te5 = xdxfPlugin->searchWordList("*");
 +        QCOMPARE(te5.size(), 9);
 +
 +    QList<Translation*> te6 = xdxfPlugin->searchWordList("*", 8);
 +        QCOMPARE(te6.size(), 8);
 +
 +    QList<Translation*> te7 = xdxfPlugin->searchWordList("*ou*");
 +        QCOMPARE(te7.at(0)->key(), QString("house"));
 +
 +    QList<Translation*> te8 = xdxfPlugin->searchWordList("1?");
 +        QCOMPARE(te8.at(0)->key(), QString("10"));
 +
 +    QList<Translation*> te9 = xdxfPlugin->searchWordList("1???");
 +        QCOMPARE(te9.at(0)->key(), QString("1000"));
 +
 +    QList<Translation*> te10 = xdxfPlugin->searchWordList("1????*");
 +        QCOMPARE(te10.at(0)->key(), QString("1 000 000"));
 +
 +    QList<Translation*> te11 = xdxfPlugin->searchWordList("h**?*?**e");
 +        QCOMPARE(te11.at(0)->key(), QString("house"));
 +
 +    xdxfPlugin->clean();
 +    delete xdxfPlugin;
 +}
 +
 +void XdxfTest::stop() {
 +
 +    XdxfPlugin xdxfPluginB(this);
 +    Settings *settings=new Settings;
 +    settings->setValue("path","../tests/dict.xdxf");
 +    CommonDictInterface *xdxfPlugin = xdxfPluginB.getNew(settings);
++    delete settings;
 +
 +    QString string("*");
 +    QFuture<QList<Translation*> > future = QtConcurrent::run(xdxfPlugin,
 +                        &CommonDictInterface::searchWordList, string, 10);
 +    QList<Translation*> te5 = future.result();
 +    QCOMPARE(te5.size(), 9);
 +
 +    xdxfPlugin->clean();
 +    delete xdxfPlugin;
 +}
 +
 +
 +void XdxfTest::langFrom() {
 +    XdxfPlugin xdxfPluginB(this);
 +    Settings *settings=new Settings;
 +    settings->setValue("path","../tests/dict.xdxf");
 +    CommonDictInterface *xdxfPlugin = xdxfPluginB.getNew(settings);
++    delete settings;
 +
 +    QCOMPARE(xdxfPlugin->langFrom(), QString("ENG"));
 +
 +    xdxfPlugin->clean();
 +    delete xdxfPlugin;
 +}
 +
 +void XdxfTest::timeCache() {
 +    QTime timer;
 +    QDate date;
 +    QFile File("../tests/time.xml");
 +    if(!File.open(QFile::ReadWrite | QFile::Text)) {
 +        qDebug()<<"Error: could not open file";
 +        return;
 +    }
 +    QTextStream out(&File);
 +    while(!out.atEnd())
 +        out.seek(out.pos()+1);
 +
 +    timer.start();
 +    XdxfPlugin xdxfPluginB(this);
 +    Settings *settings=new Settings;
 +    settings->setValue("path","../../../../../../dict.xdxf");
 +    settings->setValue("generateCache", "true");
 +    CommonDictInterface *xdxfPlugin = xdxfPluginB.getNew(settings);
++    delete settings;
 +
 +    out<<"\n<date>" + date.currentDate().toString("dd.MM.yyyy") +" ";
 +    out<<timer.currentTime().toString(Qt::TextDate) + "</date>";
 +    out<<"\n<type> Cache </type> <time>" << timer.elapsed();
 +    out<<"</time>";
 +
 +    timer.start();
 +    xdxfPlugin->search("Bantu");
 +    out<<"\n<type> SearchCache-begin </type> <time>" << timer.elapsed();
 +    out<< "</time>";
 +
 +    timer.start();
 +    xdxfPlugin->search("level");
 +    out<<"\n<type> SearchCache-midle </type> <time>" << timer.elapsed();
 +    out<< "</time>";
 +
 +    timer.start();
 +    xdxfPlugin->search("zoril");
 +    out<<"\n<type> SearchCache-end </type> <time>" << timer.elapsed();
 +    out<< "</time>";
 +
 +    timer.start();
 +    xdxfPlugin->searchWordList("level");
 +    out<<"\n<type> SearchWorlListCache </type> <time>" << timer.elapsed();
 +    out<< "</time>";
 +
 +    File.close();
 +    xdxfPlugin->clean();
 +    delete xdxfPlugin;
 +}
 +
 +void XdxfTest::timeFile() {
 +    QTime timer;
 +    QDate date;
 +    QFile File("../tests/time.xml");
 +    if(!File.open(QFile::ReadWrite | QFile::Text)) {
 +        qDebug()<<"Error: could not open file";
 +        return;
 +    }
 +    QTextStream out(&File);
 +    while(!out.atEnd())
 +        out.seek(out.pos()+1);
 +
 +    XdxfPlugin xdxfPluginB(this);
 +    Settings *settings=new Settings;
 +    settings->setValue("path","../../../../../../dict.xdxf");
 +    CommonDictInterface *xdxfPlugin = xdxfPluginB.getNew(settings);
++    delete settings;
 +
 +    timer.start();
 +    xdxfPlugin->search("Bantu");
 +    out<<"\n<type> SearchFile-begin </type> <time>" << timer.elapsed();
 +    out << "</time>";
 +
 +    timer.start();
 +    xdxfPlugin->search("level");
 +    out<<"\n<type> SearchFile-midle </type> <time>" << timer.elapsed();
 +    out << "</time>";
 +
 +    timer.start();
 +    xdxfPlugin->search("zoril");
 +    out<<"\n<type> SearchFile-end </type> <time>" << timer.elapsed();
 +    out << "</time>";
 +
 +    timer.start();
 +    xdxfPlugin->searchWordList("level");
 +    out<<"\n<type> SearchWordListFile </type> <time>" << timer.elapsed();
 +    out<< "</time>";
 +
 +    File.close();
 +    xdxfPlugin->clean();
 +    delete xdxfPlugin;
 +}
 +
 +void  XdxfTest::timeCacheNormalize() {
 +    QTime timer;
 +    QDate date;
 +    QFile File("../tests/time.xml");
 +    if(!File.open(QFile::ReadWrite | QFile::Text)) {
 +        qDebug()<<"Error: could not open file";
 +        return;
 +    }
 +    QTextStream out(&File);
 +    while(!out.atEnd())
 +        out.seek(out.pos()+1);
 +
 +    timer.start();
 +    XdxfPlugin xdxfPluginB(this);
 +    Settings *settings=new Settings;
 +    settings->setValue("path","../../../../../../dict.xdxf");
 +    settings->setValue("generateCache", "true");
 +    settings->setValue("strip_accents", "true");
 +    CommonDictInterface *xdxfPlugin = xdxfPluginB.getNew(settings);
++    delete settings;
 +
 +    out<<"\n<type> Cache with strip accent </type> <time>" << timer.elapsed();
 +    out<<"</time>";
 +
 +    timer.start();
 +    xdxfPlugin->search("Bantu");
 +    out<<"\n<type> SearchCache-begin with strip accent </type> <time>" << timer.elapsed();
 +    out<< "</time>";
 +
 +    timer.start();
 +    xdxfPlugin->search("level");
 +    out<<"\n<type> SearchCache-midle with strip accent </type> <time>" << timer.elapsed();
 +    out<< "</time>";
 +
 +    timer.start();
 +    xdxfPlugin->search("zoril");
 +    out<<"\n<type> SearchCache-end with strip accent </type> <time>" << timer.elapsed();
 +    out<< "</time>";
 +
 +    timer.start();
 +    xdxfPlugin->searchWordList("level");
 +    out<<"\n<type> SearchWorlListCache with strip accent </type> <time>" << timer.elapsed();
 +    out<< "</time>";
 +
 +    File.close();
 +    xdxfPlugin->clean();
 +    delete xdxfPlugin;
 +}
 +
 +void  XdxfTest::removeAccents() {
 +
 +    XdxfPluginSub xdxf;
 +    xdxf.settings()->setValue(QString("strip_accents"), QString("true"));
++
 +    QCOMPARE(xdxf.getRemoveAccents(QString::fromUtf8("nóżka")), QString("nozka"));
 +    QCOMPARE(xdxf.getRemoveAccents(QString::fromUtf8("motor")), QString("motor"));
 +    QCOMPARE(xdxf.getRemoveAccents(QString::fromUtf8("nÓżKa")), QString("nozka"));
 +    QCOMPARE(xdxf.getRemoveAccents(QString::fromUtf8("ławka")), QString("lawka"));
 +    QCOMPARE(xdxf.getRemoveAccents(QString::fromUtf8("éàèùâêîôûëïüÿäöüç")), QString("eaeuaeioueiuyaouc"));
 +    QCOMPARE(xdxf.getRemoveAccents(QString::fromUtf8("íőűúó")), QString("iouuo"));
 +    QCOMPARE(xdxf.getRemoveAccents(QString::fromUtf8("-ę")), QString("-e"));
 +    QCOMPARE(xdxf.getRemoveAccents(QString::fromUtf8("\"e\"")), QString("\"e\""));
 +    QCOMPARE(xdxf.getRemoveAccents(QString::fromUtf8("'e'")), QString("'e'"));
 +    QCOMPARE(xdxf.getRemoveAccents(QString::fromUtf8("\\e")), QString("e"));
 +    QCOMPARE(xdxf.getRemoveAccents(QString::fromUtf8("\\")), QString(""));
 +}
 +
 +void XdxfTest::timeFileNormalize(){
 +    QTime timer;
 +    QDate date;
 +    QFile File("../tests/time.xml");
 +    if(!File.open(QFile::ReadWrite | QFile::Text)) {
 +        qDebug()<<"Error: could not open file";
 +        return;
 +    }
 +    QTextStream out(&File);
 +    while(!out.atEnd())
 +        out.seek(out.pos()+1);
 +
 +    XdxfPlugin xdxfPluginB(this);
 +    Settings *settings=new Settings;
 +    settings->setValue("path","../../../../../../dict.xdxf");
 +    settings->setValue("strip_accents", "true");
 +    CommonDictInterface *xdxfPlugin = xdxfPluginB.getNew(settings);
++    delete settings;
 +
 +    timer.start();
 +    xdxfPlugin->search("Bantu");
 +    out<<"\n<type> SearchFile-begin with strip accent </type> <time>" << timer.elapsed();
 +    out << "</time>";
 +
 +    timer.start();
 +    xdxfPlugin->search("level");
 +    out<<"\n<type> SearchFile-midle with strip accent </type> <time>" << timer.elapsed();
 +    out << "</time>";
 +
 +    timer.start();
 +    xdxfPlugin->search("zoril");
 +    out<<"\n<type> SearchFile-end with strip accent </type> <time>" << timer.elapsed();
 +    out << "</time>";
 +
 +    timer.start();
 +    xdxfPlugin->searchWordList("level");
 +    out<<"\n<type> SearchWordListFile with strip accent </type> <time>" << timer.elapsed();
 +    out<< "</time>\n";
 +
 +    File.close();
 +    xdxfPlugin->clean();
 +    delete xdxfPlugin;
 +}
 +
 +QTEST_MAIN(XdxfTest)
 +//#include "testqstring.moc"