Fixed sigsev after searching in 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 "Bookmarks.h"
51
52
53 /*! Inner part of dictionary - glues together GUI and plugins
54
55   Backbone is responsible for managing plugins and dictionaries, starting
56   new searches and threads, merging search results from multiple dictionaries.
57
58   Each plugin may live in multiple instances - each with its own dictionary,
59   backbone must provide way to create them at start (with specific Settings) and
60   distinguich each ditionary.
61
62 */
63 class Backbone : public QObject
64 {
65     Q_OBJECT
66
67 public:
68     /*!\param pluginPath path to plugins (leave blank for default)
69       \param configPath path to folder with configuration files*/
70     Backbone(QString pluginPath="", QString configPath="",
71              bool dry = 0, QObject *parent = 0);
72     ~Backbone();
73     Backbone(const Backbone& b);
74
75     //! \return all loadded dictionaries with activity state flag
76     QHash<CommonDictInterface*, bool> getDictionaries();
77
78     //! \return all loadded plugins
79     QList<CommonDictInterface*> getPlugins();
80
81     //! \return history of performed searches
82     History* history();
83
84     //! \return return search fesult
85     QMultiHash<QString, Translation*> result();
86
87     //! \return maximum number of word that plugin could find
88     int searchLimit() const;
89
90     //! \return final translation (after searching for html)
91     QStringList htmls();
92
93
94 public Q_SLOTS:
95     //! stops all current searches
96     void stopSearching();
97
98     /*! search for a word translation
99        \param word to be translated
100       */
101     void search(QString word);
102
103     /*! sets active dictionaries (searches are performed only in active dicts
104        \param List of dictionaris to be activated
105       */
106     void selectedDictionaries(QList<CommonDictInterface* >);
107
108     /*! adds new dictionary and activate it
109       \param dict dictionary to be added
110       \param active decides whether searches are perfomed in given dictionaries
111       */
112     void addDictionary(CommonDictInterface* dict, bool active = 1);
113
114
115     //! stops all current activity - emiting signal \see closeOk
116     void quit();
117
118
119     /*! Fired with given interval during searches -
120         checking if translation is ready
121       */
122     void translationReady();
123
124     /*! Fired with given interval during html searches -
125         checking if html is ready
126       */
127     void htmlTranslationReady();
128
129     /*! Removes given dictionary
130         \param dict dictionary to be deleted
131       */
132     void removeDictionary(CommonDictInterface* dict);
133
134     /*! saves plugins new state/configuration after each change */
135     void dictUpdated();
136
137     /*! Performs search for final translation (html/xml) form
138       \param list of Translation* to be searched for
139       */
140     void searchHtml(QList<Translation*>);
141
142
143     /*! add bookmarks to given translations (translation object is fetched and
144       added to bookmarks data base (key and translation stored in db)
145       \param translation translation object  to be stored in db
146       */
147     void addBookmark(QList<Translation*> translations) {
148         foreach(Translation* translation, translations)
149             bookmarks.add(translation);
150             //QtConcurrent::run(&bookmarks, &Bookmarks::add, translation);
151     }
152
153
154     /*! Remove bookmarks to given translatios
155       \param translation remove bookmark to this translation
156       */
157     void removeBookmark(QList<Translation*> translations) {
158         foreach(Translation* translation, translations)
159             bookmarks.remove(translation);
160     }
161
162
163    /*! Searching for list of bookmarks may take some time, so i moved it to
164        new thread (to avoid gui blocking), when ready bookmarksReady is emited
165        and result is returned after calling getBookmarks()
166        */
167    void fetchBookmarks() {
168        _bookmarksResult.clear();
169        _innerListBookmarks = QtConcurrent::run(bookmarks, &Bookmarks::list);
170        _bookmarkWatcher.setFuture(_innerListBookmarks);
171    }
172
173    /*! \return list of all bookmarks
174      */
175    QList<Translation*> getBookmarks() {
176        return _bookmarksResult;
177    }
178
179
180
181 Q_SIGNALS:
182     /*! emmited when backbone is ready to close - after getting stop signal it
183         should kill all threads and so on */
184     void closeOk();
185
186     //! emitted when there are search result ready to fetch
187     void ready();
188
189     //! emitted when html result is ready to fetch
190     void htmlReady();
191
192     //! throwed when searches are stopped
193     void searchCanceled();
194
195     //! emmited when bookmark list is ready to fetch
196     void bookmarksReady();
197
198 private Q_SLOTS:
199     void bookmarksListReady();
200
201
202 private:
203     QHash<CommonDictInterface*, bool> _dicts; // List of dictionaries
204     QList<CommonDictInterface*> _plugins;  // List of plugins
205
206
207     QFuture<QList<Translation*> > _innerResult; //Res of concurent word search
208     QFuture<QString> _innerHtmlResult;  // Result of html search
209     QFuture<QList<Translation*> > _innerBookmarks; //Res of search in bookmarks
210     QFuture<QList<Translation*> > _innerListBookmarks; //Res of search in bookmarks
211     QFuture<QStringList> _innerHtmlBookmarks; //Html result of bookmarks search
212
213     QMultiHash<QString, Translation*> _result; //Final result of word search
214     QStringList _htmlResult; // Final result of html search
215     QList<Translation*> _bookmarksResult; // Final result of search in bookmarks
216
217
218     // Keeps track of concurent computations
219     QFutureWatcher<QList<Translation*> > _resultWatcher;
220     QFutureWatcher<QList<Translation*> > _bookmarkWatcher;
221     QFutureWatcher<QList<Translation*> > _bookmarkSearchWatcher;
222     QFutureWatcher<QString> _htmlResultWatcher;
223
224
225     QString _pluginPath, _defaultPluginPath;
226     QString _configPath;
227     QString _defaultConfigPath;
228     int _searchLimit, _defaultSearchLimit;
229     int _activeSearchNum;
230     int _historyLen, _defaultHistoryLen;
231     bool dryRun;
232     bool stopped;
233     bool bookmarkFin, dictFin; // inform whether givent search type is ready
234     Bookmarks bookmarks;
235
236
237     void init();
238     QStringList getFilesFromDir(QString dir, QStringList nameFilter);
239     void loadPlugins(); //< locate and load plugins
240     void loadPrefs(QString fileName);
241     void loadDicts(QString fileName, bool _default=false);
242     void saveState(QSettings*, Settings*, bool, uint);
243     void addInternalDictionary(CommonDictInterface*, bool);
244     void savePrefs(QSettings*);
245     void saveDefaultPrefs(QSettings*);
246     CommonDictInterface* plugin(QString type); //< search for given type plugin
247     QList<CommonDictInterface*> activeDicts();
248
249
250     History* _history;
251
252 };
253
254 #endif // BACKBONE_H