Added configuration file handling with dynamic loading dicts
[mdictionary] / trunk / src / base / backbone / backbone.cpp
1 /*******************************************************************************
2
3     This file is part of mDictionary.
4
5     mDictionary is free software: you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation, either version 3 of the License, or
8     (at your option) any later version.
9
10     mDictionary is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14
15     You should have received a copy of the GNU General Public License
16     along with mDictionary.  If not, see <http://www.gnu.org/licenses/>.
17
18     Copyright 2010 Comarch S.A.
19
20 *******************************************************************************/
21
22 // Created by Bartosz Szatkowski
23
24 #include "backbone.h"
25 #include <QDebug>
26
27 void Backbone::init() {
28    _searchLimit = 10;
29    _interval = 250; //msec
30    if(!_pluginPath.size())
31        _pluginPath = "/usr/lib/mdictionary/";
32
33    if(!_configPath.size())
34        _configPath = QDir::homePath() + "/.mdictionary";
35    loadPlugins();
36    loadPreferences();
37
38    if(!connect(&_timer, SIGNAL(timeout()), this, SLOT(translation())))
39        qDebug() << "Timer signal not connected";
40 }
41
42 Backbone::Backbone(QString pluginPath, QString configPath, QObject *parent)
43     : QObject(parent)
44 {
45     _pluginPath = pluginPath;
46     _configPath = configPath;
47     init();
48 }
49
50
51
52 Backbone::~Backbone()
53 {
54     QListIterator<CommonDictInterface*> it(_dicts.keys());
55
56     while(it.hasNext())
57         delete it.next();
58
59     it = QListIterator<CommonDictInterface*>(_plugins);
60     while(it.hasNext())
61         delete it.next();
62
63     QHashIterator<QString, Translation*> it2(_result);
64     while(it2.hasNext())
65         delete it2.next().value();
66
67 }
68
69
70
71
72 Backbone::Backbone(const Backbone &b) :QObject(b.parent()) {
73    // init();
74     _dicts = QHash<CommonDictInterface*, bool > (b._dicts);
75     _plugins = QList<CommonDictInterface* > (b._plugins);
76     _result = QHash<QString, Translation* > (b._result);
77     _searchLimit = b.searchLimit();
78 }
79
80
81
82
83 int Backbone::searchLimit() const {
84     return _searchLimit;
85 }
86
87
88
89
90 QHash<CommonDictInterface*, bool > Backbone::getDictionaries() {
91     return _dicts;
92 }
93
94
95
96
97 QList<CommonDictInterface* > Backbone::getPlugins() {
98     return _plugins;
99 }
100
101
102
103
104 QList<QString> Backbone::getHistory() {
105     //TODO code needed
106 }
107
108
109
110
111 QMultiHash<QString, Translation*> Backbone::result() {
112     return _result;
113 }
114
115
116
117
118 void Backbone::stopSearching() {
119     _timer.stop();
120     _innerResult.clear();
121     foreach(CommonDictInterface* dict, _dicts.keys())
122         dict->stop();
123 }
124
125
126
127
128 void Backbone::search(QString word) {
129     _timer.stop();
130     _result.clear();
131     _innerResult.clear();
132
133     _timer.start(_interval);
134     foreach(CommonDictInterface* dict, _dicts.keys())
135         if(_dicts[dict] == 1) {
136             QFuture<QList<Translation*> > tr =
137                     QtConcurrent::run(dict,
138                                       &CommonDictInterface::searchWordList,word,
139                                                              searchLimit());
140             _innerResult.append(tr);
141         }
142
143 }
144
145
146
147
148  void Backbone::selectedDictionaries(QList<CommonDictInterface* > activeDicts) {
149      foreach(CommonDictInterface* dict, _dicts.keys())
150          if(activeDicts.contains(dict))
151              _dicts[dict] = 1;
152          else
153              _dicts[dict] = 0;
154  }
155
156
157
158
159  void Backbone::addDictionary(CommonDictInterface* dict) {
160      dict->setHash(_dicts.size()+1);
161      _dicts[dict] = 1;
162  }
163
164  void Backbone::removeDictionary(CommonDictInterface *dict) {
165      _dicts.remove(dict);
166
167  }
168
169
170
171  void Backbone::quit() {
172     stopSearching();
173     Q_EMIT closeOk();
174 }
175
176
177
178 int Backbone::activeSearches() const {
179     return _innerResult.size();
180 }
181
182
183
184 void Backbone::translation() {
185     foreach(QFuture<QList<Translation*> > trans, _innerResult) {
186         if(!trans.isFinished())
187             continue;
188         QList<Translation*> tList = trans.result();
189         foreach(Translation* t, tList) {
190             _result.insert(t->key().toLower(), t);
191         }
192         _innerResult.removeOne(trans);
193     }
194     if(!_innerResult.size()) {
195         _timer.stop();
196         Q_EMIT ready();
197     }
198 }
199
200 QStringList Backbone::getFilesFromDir(QString dir, QStringList nameFilter) {
201     QDir plug(QDir::toNativeSeparators(dir));
202     if(!plug.exists()) {
203         qDebug() << plug.absolutePath() << " folder dosen't exists";
204         return QStringList();
205     }
206     plug.setFilter(QDir::Files);
207     QStringList list = plug.entryList(nameFilter);
208
209     for(int i = 0; i < list.size(); i++)
210         list[i] = plug.absoluteFilePath(list.at(i));
211     return list;
212 }
213
214
215 void Backbone::loadPlugins() {
216     QStringList nameFilter;
217     nameFilter << "*.so";
218     QStringList files = getFilesFromDir(_pluginPath, nameFilter);
219
220     foreach(QString file, files) {
221         QPluginLoader loader(file);
222         if(!loader.load()) {
223             qDebug()<< file << " " << loader.errorString();
224             continue;
225         }
226         QObject *pl = loader.instance();
227
228         CommonDictInterface *plugin = qobject_cast<CommonDictInterface*>(pl);
229         _plugins.append(plugin);
230        // addDictionary(plugin->getNew(0)); //TODO change 0 to real settings
231         //Settings* set = new Settings();
232         //set->setValue("path", "dict2.xdxf");
233         //addDictionary(plugin->getNew(set));
234     }
235 }
236
237 CommonDictInterface* Backbone::plugin(QString type) {
238     foreach(CommonDictInterface* plugin, _plugins)
239         if(plugin->type() == type)
240             return plugin;
241     return 0;
242 }
243
244 void Backbone::loadPreferences() {
245     QDir confDir(_configPath);
246     if(!confDir.exists())
247         qDebug() << confDir.mkpath(_configPath);
248     QSettings set(_configPath + "/mdictionary.config", QSettings::IniFormat);
249     _pluginPath = set.value("general/path", _pluginPath).toString();
250     QStringList dicts = set.childGroups();
251     foreach(QString dict, dicts) {
252         if(!dict.contains("dictionary_"))
253             continue;
254         CommonDictInterface* plug = plugin
255                                     (set.value(dict + "/type", "").toString());
256         if(!plug) {
257             qDebug() << "Config file error: "
258                     << set.value(dict + "/type", "").toString()
259                     << " dosen't exists";
260             continue;
261         }
262         Settings* plugSet = new Settings();
263         set.beginGroup(dict);
264         QStringList items = set.childKeys();
265         foreach(QString item, items)
266             plugSet->setValue(item, set.value(item, "").toString());
267         set.endGroup();
268         addDictionary(plug->getNew(plugSet));
269     }
270 }
271
272 //saving dictionaries state
273 //saving selection state
274
275