Add confirmation dialog when deleting all bookmarks
[mdictionary] / trunk / src / base / backbone / backbone.h
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 /*! /file backbone.cpp
23 \brief Backbone/core main header \see Backbone
24
25
26 \author Bartosz Szatkowski <bulislaw@linux.com>
27 */
28
29 #ifndef BACKBONE_H
30 #define BACKBONE_H
31
32 #include <QObject>
33 #include <QList>
34 #include <QHash>
35 #include <QPluginLoader>
36 #include <QFuture>
37 #include <QtConcurrentRun>
38 #include <QtConcurrentMap>
39 #include <QFutureIterator>
40 #include <QTimer>
41 #include <QTime>
42 #include <QDir>
43 #include <QThread>
44 #include <QSettings>
45 #include <QFutureWatcher>
46 #include "../../includes/CommonDictInterface.h"
47 #include "../../includes/settings.h"
48 #include "../../includes/translation.h"
49 #include "../../includes/History.h"
50 #include "../../includes/Notify.h"
51 #include "Bookmarks.h"
52
53
54 /*! Inner part of dictionary - glues together GUI and plugins, also kind of
55     GoF facade (for GUI) cover few classes \see Bookmarks \see History
56
57   Backbone is responsible for managing plugins and dictionaries, starting
58   new searches and threads, merging search results from multiple dictionaries.
59
60   Each plugin may live in multiple instances - each with its own dictionary,
61   backbone must provide way to create them at start (with specific Settings) and
62   distinguich each ditionary.
63
64   Backbone also manage bookmarks and history: providing interface to gui
65
66   Backbone is also responsible for saving and spawning session via configs
67   file (stored in ~/.mdictionary) -> configs are kind of tricky because
68   mDictionary is delivered with two simple dicts -> its necessary to separate default
69   configs from user configs (updating/reinstaling app results in overwriten
70   default config file), moreover config file there is general mdictionary
71   configuration (aparto from dictionaries and plugin ones).
72
73   Other modules may set some internal backbone behaviour via \see setSettings():
74   Settings object with option given:
75      * history_size - int, size of stored searches
76      * search_limit - int, how many different word may each dictionary returns
77      * search_dictionaries - true/false, whether search in dictionaries
78      * search_bookmarks - true/false, whether search in bookmarks
79
80     Searching schema:
81         First GUI should ask for list of words matching given pattern
82         then eatch Translation object is capable of finging it own final translation
83
84       List of word:
85         - Gui call search(...)
86         - Backbone call plugins searchWordList(...) in idealThreadCount()+1 threads
87         - Backbone sets  the FutureWatcher to be notifed when plugins are done
88         - Backbone fetch results from Future<..> and formats it for gui then
89            emits ready()
90         - Gui calls result()
91
92       Final translation:
93          - Gui call searchHtml()
94          - Backbone starts for eatch translation object toHtml in separate threads
95          - Backbone sets FutureWatcher to be notified after last toHtml returns
96          - Backbone fetch translation from Future<...> objects and calls
97              htmlReady()
98          - gui calls htmlResult()
99
100 */
101 class Backbone : public QObject
102 {
103     Q_OBJECT
104
105 public:
106     /*!\param pluginPath path to plugins (leave blank for default)
107       \param configPath path to folder with configuration files
108       \param dry dry run is mode without paying attention to configuration etc
109           mainly for testing
110       */
111     Backbone(QString pluginPath="", QString configPath="",
112              bool dry = 0, QObject *parent = 0);
113     ~Backbone();
114     Backbone(const Backbone& b);
115
116     //! \return all loadded dictionaries with activity state flag
117     QHash<CommonDictInterface*, bool> getDictionaries();
118
119     //! \return all loadded plugins
120     QList<CommonDictInterface*> getPlugins();
121
122     //! \return history of performed searches
123     History* history();
124
125     //! \return return search fesult
126     QMultiHash<QString, Translation*> result();
127
128     //! \return maximum number of word that plugin could find
129     int searchLimit() const;
130
131     //! \return final translation (after searching for html)
132     QStringList htmls();
133
134     /*! maximum number of translation that each plugin may return; it must be
135         public static becouse of QtConcurent::mapped restrictions about
136         what kind of function may be used there see Qt docs */
137     static int _searchLimit;
138
139
140
141 public Q_SLOTS:
142     //! stops all current searches and emiting searchCanceled signal
143     void stopSearching();
144
145     /*! search for a word translation
146        \param word to be translated
147       */
148     void search(QString word);
149
150     /*! sets active dictionaries (searches are performed only in active dicts
151        \param List of dictionaris to be activated
152       */
153     void selectedDictionaries(QList<CommonDictInterface* >);
154
155     /*! adds new dictionary and activate it
156       \param dict dictionary to be added
157       \param active decides whether searches are perfomed in given dictionaries
158       */
159     void addDictionary(CommonDictInterface* dict, bool active = 1);
160
161
162     //! stops all current activity - emiting signal \see closeOk
163     void quit();
164
165
166     /*! Fired by FutureWatcher when list of words is ready (after calling search)
167         fetch Future<...> to final result
168       */
169     void translationReady();
170
171     /*! Fired by FutureWatcher when search result is ready, fetch Future to
172         final result
173       */
174     void htmlTranslationReady();
175
176     /*! Removes given dictionary
177         \param dict dictionary to be deleted
178       */
179     void removeDictionary(CommonDictInterface* dict);
180
181     /*! saves plugins new state/configuration after each change */
182     void dictUpdated();
183
184     /*! Performs search for final translation (html/xml) form
185       \param list of Translation* to be searched for
186       */
187     void searchHtml(QList<Translation*>);
188
189
190     /*! add bookmarks to given translations (translation object is fetched and
191       added to bookmarks data base (key and translation stored in db)
192       \param translation translation object  to be stored in db
193       */
194     void addBookmark(QList<Translation*> translations) {
195         foreach(Translation* translation, translations)
196             //_bookmarks.add(translation);
197             QtConcurrent::run(_bookmarks, &Bookmarks::add, translation);
198     }
199
200
201     /*! Remove bookmarks to given translatios
202       \param translation remove bookmark to this translation
203       */
204     void removeBookmark(QList<Translation*> translations) {
205         foreach(Translation* translation, translations)
206             _bookmarks.remove(translation);
207     }
208
209
210
211     /*! Remove all bookmarks
212       */
213     void removeAllBookmarks(){
214         _bookmarks.clear();
215     }
216
217
218    /*! Searching for list of bookmarks may take some time, so i moved it to
219        new thread (to avoid gui blocking), futher its consistent with ordinary
220        searching for list of word (\see search)
221        */
222    void fetchBookmarks() {
223         _result.clear();
224
225         stopped = false;
226         dictFin = 1;
227         bookmarkFin = 0;
228
229         if(_searchBookmarks) {
230            _innerBookmarks = QtConcurrent::run(_bookmarks,
231                    &Bookmarks::searchWordList, QString("*"));
232            _bookmarkSearchWatcher.setFuture(_innerBookmarks);
233         }
234    }
235
236
237
238    /*! Sets settings for backbone: history_size, search_limit,
239        searching backends (search_bookmarks, search_dictionaries)
240        \param settings settings object with opitons set
241        */
242     void setSettings(Settings* settings);
243
244
245     /*! \return coresponding settings object with history_size, search_limit,
246        searching backends (search_bookmarks, search_dictionaries)
247        */
248     Settings* settings();
249
250
251
252
253
254
255 Q_SIGNALS:
256     /*! emmited when backbone is ready to close - after getting stop signal it
257         should kill all threads and so on */
258     void closeOk();
259
260     //! emitted when there are search result ready to fetch
261     void ready();
262
263     //! emitted when html result is ready to fetch
264     void htmlReady();
265
266     //! throwed when searches are stopped
267     void searchCanceled();
268
269     //! emmited when bookmark list is ready to fetch
270     void bookmarksReady();
271
272     /*! emited by direct connection to plugins notifying signals
273         \param Notify::NotifyType gui my dacide to show different typet in
274             different ways
275         \param QString text of the notification
276     */
277     void notify(Notify::NotifyType, QString);
278
279 private Q_SLOTS:
280     void bookmarksListReady();
281
282
283 private:
284     QHash<CommonDictInterface*, bool> _dicts; // List of dictionaries
285     QList<CommonDictInterface*> _plugins;  // List of plugins
286
287
288     QFuture<QList<Translation*> > _innerResult; //Res of concurent word search
289     QFuture<QString> _innerHtmlResult;  // Result of html search
290     QFuture<QList<Translation*> > _innerBookmarks; //Res of search in bookmarks
291     QFuture<QList<Translation*> > _innerListBookmarks; //Res of search in bookmarks
292     QFuture<QStringList> _innerHtmlBookmarks; //Html result of bookmarks search
293
294     QMultiHash<QString, Translation*> _result; //Final result of word search
295     QStringList _htmlResult; // Final result of html search
296     QList<Translation*> _bookmarksResult; // Final result of search in bookmarks
297
298
299     // Keeps track of concurent computations
300     QFutureWatcher<QList<Translation*> > _resultWatcher;
301     QFutureWatcher<QList<Translation*> > _bookmarkWatcher;
302     QFutureWatcher<QList<Translation*> > _bookmarkSearchWatcher;
303     QFutureWatcher<QString> _htmlResultWatcher;
304
305
306     QString _pluginPath, _defaultPluginPath;
307     QString _configPath;
308     QString _defaultConfigPath;
309     int _defaultSearchLimit;
310     int _historyLen, _defaultHistoryLen;
311
312     bool dryRun; // mainly for testing - when true then dosent bother configs etc
313     bool stopped; // true when user stops searching/fetching
314     bool bookmarkFin, dictFin; // inform whether givent search type is ready
315     bool _searchDicts, _searchBookmarks; // whether perform search in given source
316
317     Bookmarks _bookmarks;
318
319
320     void init();
321
322     QStringList getFilesFromDir(QString dir, QStringList nameFilter);
323     void loadPlugins(); //< locate and load plugins
324     void loadPrefs(QString fileName);
325     void loadDicts(QString fileName, bool _default=false);
326
327     void saveState(QSettings*, Settings*, bool, uint);
328     void addInternalDictionary(CommonDictInterface*, bool);
329     void savePrefs(QSettings*);
330     void saveDefaultPrefs(QSettings*);
331
332     CommonDictInterface* plugin(QString type); // search for given type plugin
333     QList<CommonDictInterface*> activeDicts();
334     bool containsDict(uint hash) const;
335     int _dictNum;
336
337     History* _history;
338
339     friend class BackboneTest;
340
341 };
342
343 #endif // BACKBONE_H