Merge branch 'master' of ssh://drop.maemo.org/git/mdictionary
[mdictionary] / trunk / src / base / gui / MainWindow.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 Mateusz Półrola
23
24 #include "MainWindow.h"
25 #include "ui_MainWindow.h"
26 #include <QtGui>
27 #ifdef Q_WS_MAEMO_5
28     #include <QMaemo5InformationBox>
29 #endif
30
31
32 MainWindow::MainWindow(Backbone *backbone, QWidget *parent):
33     GUIInterface(parent),
34     ui(new Ui::MainWindow) {
35
36     this->backbone = backbone;
37
38     initializeUI();
39
40     connectBackbone();
41     connectSearchBar();
42     connectWordList();
43     connectTranslationWidget();
44     connectDictManager();
45     connectMenu();
46     connectBookmarksWidget();
47
48
49     setExactSearch(false);
50
51     setWindowTitle("mDictionary");
52
53     showMaximized();
54 }
55
56 MainWindow::~MainWindow() {
57     delete ui;
58 }
59
60
61 void MainWindow::initializeUI() {
62     ui->setupUi(this);
63
64     #ifdef Q_WS_MAEMO_5
65         setAttribute(Qt::WA_Maemo5StackedWindow);
66     #endif
67
68     searchBarWidget = new SearchBarWidget;
69
70     wordListWidget = new WordListWidget;
71
72     //translationWidget is antoher stacked window, so we don't add it to layout
73     //only create it with this widget as parent
74     translationWidget = new TranslationWidget(this);
75
76     welcomeScreenWidget = new WelcomeScreenWidget;
77
78
79     #ifdef Q_WS_MAEMO_5
80     //At start we set widget as welcome screen widget
81         ui->centralWidget->layout()->addWidget(welcomeScreenWidget);
82         QVBoxLayout* vl = (QVBoxLayout*)(ui->centralWidget->layout());
83         vl->addWidget(searchBarWidget, 0, Qt::AlignBottom);
84     #else
85         translationWidget->hide();
86         //we add to splitter word list and welcome screen
87         splitter = new QSplitter(Qt::Horizontal);
88         splitter->addWidget(wordListWidget);
89         splitter->addWidget(welcomeScreenWidget);
90         splitter->setStretchFactor(1, 150);
91         ui->centralWidget->layout()->addWidget(splitter);
92         ui->centralWidget->layout()->addWidget(searchBarWidget);
93     #endif
94
95
96
97     dictManagerWidget = new DictManagerWidget(this);
98     dictManagerWidget->hide();
99
100     settingsWidget = new SettingsWidget(this);
101     settingsWidget->hide();
102
103     bookmarksWidget = new BookmarksWidget(this);
104     bookmarksWidget->hide();
105
106     aboutWidget = new AboutWidget(this);
107     aboutWidget->hide();
108
109
110     //creating menus
111
112     #ifdef Q_WS_MAEMO_5
113         menuWidget = new MenuWidget(this);
114         menuWidget->addSubMenu(tr("Settings"), settingsWidget);
115         menuWidget->addSubMenu(tr("Dictionaries"), dictManagerWidget);
116         menuWidget->addSubMenu(tr("Bookmarks"), bookmarksWidget);
117         menuWidget->addSubMenu(tr("About"), aboutWidget);
118         ui->menuBar->addAction(menuWidget);
119     #else
120         dictionariesAction = ui->menuBar->addAction(tr("Dictionaries"));
121         connect(dictionariesAction, SIGNAL(triggered()),
122                 dictManagerWidget, SLOT(show()));
123
124         settingsAction = ui->menuBar->addAction(tr("Settings"));
125         connect(settingsAction, SIGNAL(triggered()),
126                 settingsWidget, SLOT(show()));
127
128         QMenu* m = ui->menuBar->addMenu(tr("Bookmarks"));
129         bookmarksShowAllAction = new QAction(tr("Show all"), m);
130
131         bookmarksRemoveAllAction = new QAction(tr("Remove all"), m);
132
133         m->addAction(bookmarksShowAllAction);
134         m->addAction(bookmarksRemoveAllAction);
135
136         aboutAction = ui->menuBar->addAction(tr("About"));
137         connect(aboutAction, SIGNAL(triggered()),
138                 aboutWidget, SLOT(show()));
139     #endif
140
141 }
142
143 void MainWindow::closeEvent(QCloseEvent *event) {
144     //reqest to stop all searches and close app
145         emit quit();
146         event->accept();
147 }
148
149 bool MainWindow::exactSearch() {
150     return _exactSearch;
151 }
152
153 void MainWindow::setExactSearch(bool exact) {
154     _exactSearch = exact;
155 }
156
157 void MainWindow::setSearchString(QString word) {
158     searchString = word;
159 }
160
161 void MainWindow::wordListReady() {
162     //gets results from backbone
163     QMultiHash<QString, Translation*> res = backbone->result();
164     QHash<QString, QList<Translation*> > searchResult;
165
166     #ifdef Q_WS_MAEMO_5
167     //switch welcome screen with word list
168     if(!wordListWidget->isVisible()) {
169         int i = ui->centralWidget->layout()->indexOf(welcomeScreenWidget);
170         QBoxLayout* l = (QBoxLayout*)(ui->centralWidget->layout());
171         l->removeWidget(welcomeScreenWidget);
172         welcomeScreenWidget->deleteLater();
173         l->insertWidget(0, wordListWidget);
174     }
175     #endif
176
177     //if nothing was found
178     if(res.count() == 0) {
179         #ifdef Q_WS_MAEMO_5
180         QMaemo5InformationBox::information(this,
181                             tr("Can't find any matching words"),
182                             QMaemo5InformationBox::DefaultTimeout);
183         #endif
184         //show empty list to remove results of old search
185         emit showWordList(searchResult);
186     }
187     else {
188         //find translations of the same key word
189         QMultiHash<QString, Translation*>::iterator i;
190         for(i = res.begin(); i != res.end(); i++) {
191             searchResult[i.key()].push_back(i.value());
192         }
193
194
195         if(!exactSearch()) {
196             emit showWordList(searchResult);
197         }
198         else {
199             #ifndef Q_WS_MAEMO_5
200             //on desktop we show word list in exact search
201                 emit showWordList(searchResult);
202             #endif
203             bool foundExactMatch = false;
204             QHash<QString, QList<Translation*> >::iterator j;
205             for(j = searchResult.begin(); j != searchResult.end(); j++) {
206                 if(j.key() == searchString && !foundExactMatch) {
207                     foundExactMatch = true;
208                     emit searchTranslations(j.value());
209                     break;
210                 }
211             }
212
213             if(!foundExactMatch) {
214                 #ifdef Q_WS_MAEMO_5
215                 QMaemo5InformationBox::information(this,
216                                     tr("Can't find exactly matching word"),
217                                     QMaemo5InformationBox::DefaultTimeout);
218                 #endif
219
220                 emit showWordList(searchResult);
221             }
222
223         }
224     }
225     setExactSearch(false);
226 }
227
228 void MainWindow::translationsReady() {
229     #ifndef Q_WS_MAEMO_5
230     //switch welcome screen with translation widget
231     if(!translationWidget->isVisible()) {
232         int i = ui->centralWidget->layout()->indexOf(welcomeScreenWidget);
233         QBoxLayout* l = (QBoxLayout*)(ui->centralWidget->layout());
234         QSplitter* s = (QSplitter*)((QWidgetItem*)(l->itemAt(0))->widget());
235         s->insertWidget(1,translationWidget);
236         s->setStretchFactor(1, 150);
237         welcomeScreenWidget->deleteLater();
238     }
239     #endif
240
241     emit showTranslation(backbone->htmls());
242 }
243
244 QList<CommonDictInterface*> MainWindow::getPlugins() {
245     return backbone->getPlugins();
246 }
247
248 QHash<CommonDictInterface*, bool> MainWindow::getDictionaries() {
249     return backbone->getDictionaries();
250 }
251
252 void MainWindow::searchExact(QString word) {
253     setExactSearch(true);
254     //searching with searchBar, not directly by emiting searchWordList(),
255     //because it will set search word in searchBar's edit line
256     //this function is only used by history and when searching from attributes
257     searchBarWidget->search(word);
258 }
259
260
261
262 void MainWindow::breakSearching() {
263     //make sure to unset exact search mode
264     setExactSearch(false);
265 }
266
267 void MainWindow::addToHistory(QList<Translation *> trans) {
268     if(trans.count() > 0) {
269         backbone->history()->add(trans[0]->key());
270         translationWidget->setWindowTitle(trans[0]->key());
271     }
272 }
273
274 void MainWindow::historyNext() {
275     if(backbone->history()->nextAvailable()) {
276         QString next = backbone->history()->next();
277         #ifndef Q_WS_MAEMO_5
278             setExactSearch(true);
279         #endif
280         searchBarWidget->searchDelay(next);
281     }
282 }
283
284 void MainWindow::historyPrev() {
285     if(backbone->history()->prevAvailable()) {
286         #ifndef Q_WS_MAEMO_5
287             setExactSearch(true);
288         #endif
289         QString prev = backbone->history()->previous();
290         searchBarWidget->searchDelay(prev);
291     }
292 }
293
294 void MainWindow::disableMenu() {
295     #ifdef Q_WS_MAEMO_5
296         if(ui->menuBar->actions().contains(menuWidget)) {
297               ui->menuBar->removeAction(menuWidget);
298         }
299     #else
300         ui->menuBar->setEnabled(false);
301     #endif
302 }
303
304 void MainWindow::enableMenu() {
305     #ifdef Q_WS_MAEMO_5
306         if(!ui->menuBar->actions().contains(menuWidget)) {
307             ui->menuBar->addAction(menuWidget);
308         }
309     #else
310         ui->menuBar->setEnabled(true);
311     #endif
312 }
313
314 void MainWindow::showHistory() {
315     HistoryListDialog historyDialog(backbone->history()->list(), this);
316     if(historyDialog.exec() == QDialog::Accepted) {
317         backbone->history()->setCurrentElement(historyDialog.selectedRow());
318         searchExact(historyDialog.selectedWord());
319     }
320 }
321
322 void MainWindow::setSettings(Settings *s) {
323     backbone->setSettings(s);
324 }
325
326 Settings* MainWindow::settings() {
327     return backbone->settings();
328 }
329
330 void MainWindow::connectBackbone() {
331     connect(this, SIGNAL(quit()),
332             backbone, SLOT(quit()));
333
334     connect(this, SIGNAL(searchWordList(QString)),
335             backbone, SLOT(search(QString)));
336
337     connect(this, SIGNAL(searchTranslations(QList<Translation*>)),
338             backbone, SLOT(searchHtml(QList<Translation*>)));
339
340     connect(this, SIGNAL(stopSearching()),
341             backbone, SLOT(stopSearching()));
342
343     connect(this, SIGNAL(stopSearching()),
344             this, SLOT(breakSearching()));
345
346     connect(this, SIGNAL(addNewDictionary(CommonDictInterface*)),
347             backbone, SLOT(addDictionary(CommonDictInterface*)));
348
349     connect(this, SIGNAL(removeDictionary(CommonDictInterface*)),
350             backbone, SLOT(removeDictionary(CommonDictInterface*)));
351
352     connect(this, SIGNAL(selectedDictionaries(QList<CommonDictInterface*>)),
353             backbone, SLOT(selectedDictionaries(QList<CommonDictInterface*>)));
354
355
356     connect(backbone, SIGNAL(ready()),
357             this, SIGNAL(setIdle()));
358
359     connect(backbone, SIGNAL(htmlReady()),
360             this, SIGNAL(setIdle()));
361
362
363     connect(backbone, SIGNAL(ready()),
364             this, SLOT(wordListReady()));
365
366     connect(backbone, SIGNAL(htmlReady()),
367             this, SLOT(translationsReady()));
368
369     connect(backbone, SIGNAL(searchCanceled()),
370             this, SIGNAL(setIdle()));
371
372
373
374
375     connect(this, SIGNAL(searchWordList(QString)),
376             this, SIGNAL(setBusy()));
377
378     connect(this, SIGNAL(searchTranslations(QList<Translation*>)),
379             this, SIGNAL(setBusy()));
380
381     connect(this, SIGNAL(stopSearching()),
382             this, SIGNAL(setIdle()));
383
384     connect(this, SIGNAL(searchWordList(QString)),
385             this, SLOT(setSearchString(QString)));
386
387     connect(this, SIGNAL(searchTranslations(QList<Translation*>)),
388             this, SLOT(addToHistory(QList<Translation*>)));
389
390
391 }
392
393 void MainWindow::connectSearchBar() {
394     connect(searchBarWidget, SIGNAL(searchForTranslations(QString)),
395             this, SIGNAL(searchWordList(QString)));
396
397     connect(searchBarWidget, SIGNAL(stopSearching()),
398             this, SIGNAL(stopSearching()));
399
400     connect(this, SIGNAL(setBusy()),
401             searchBarWidget, SLOT(setBusy()));
402
403     connect(this, SIGNAL(setIdle()),
404             searchBarWidget, SLOT(setIdle()));
405
406     connect(searchBarWidget, SIGNAL(historyNext()),
407             this, SLOT(historyNext()));
408
409     connect(searchBarWidget, SIGNAL(historyPrev()),
410             this, SLOT(historyPrev()));
411
412     connect(searchBarWidget, SIGNAL(historyShow()),
413             this, SLOT(showHistory()));
414
415     connect(searchBarWidget, SIGNAL(refreshHistoryButtons()),
416             backbone->history(), SLOT(refreshStatus()));
417
418     connect(backbone->history(), SIGNAL(historyChanged(bool,bool,bool)),
419             searchBarWidget, SLOT(updateHistoryButtons(bool,bool,bool)));
420 }
421
422 void MainWindow::connectWordList() {
423     connect(this,
424             SIGNAL(showWordList(QHash<QString, QList<Translation*> >)),
425             wordListWidget,
426             SLOT(showSearchResults(QHash<QString,QList<Translation*> >)));
427
428     connect(wordListWidget, SIGNAL(showTranslation(QList<Translation*>)),
429             this, SIGNAL(searchTranslations(QList<Translation*>)));
430
431
432
433
434     connect(this, SIGNAL(setBusy()),
435             wordListWidget, SLOT(lockList()));
436
437     connect(this, SIGNAL(setIdle()),
438             wordListWidget, SLOT(unlockList()));
439
440     connect(wordListWidget, SIGNAL(addBookmark(QList<Translation*>)),
441             backbone, SLOT(addBookmark(QList<Translation*>)));
442
443     connect(wordListWidget, SIGNAL(removeBookmark(QList<Translation*>)),
444             backbone, SLOT(removeBookmark(QList<Translation*>)));
445 }
446
447 void MainWindow::connectTranslationWidget() {
448     connect(this, SIGNAL(showTranslation(QStringList)),
449             translationWidget, SLOT(show(QStringList)));
450
451 }
452
453 void MainWindow::connectDictManager() {
454     connect(dictManagerWidget, SIGNAL(addDictionary(CommonDictInterface*)),
455             this, SIGNAL(addNewDictionary(CommonDictInterface*)));
456
457     connect(dictManagerWidget, SIGNAL(removeDictionary(CommonDictInterface*)),
458             this, SIGNAL(removeDictionary(CommonDictInterface*)));
459
460     connect(dictManagerWidget,
461             SIGNAL(selectedDictionaries(QList<CommonDictInterface*>)),
462             this, SIGNAL(selectedDictionaries(QList<CommonDictInterface*>)));
463 }
464
465 void MainWindow::connectMenu() {
466     connect(this, SIGNAL(setBusy()),
467             this, SLOT(disableMenu()));
468
469     connect(this, SIGNAL(setIdle()),
470             this, SLOT(enableMenu()));
471 }
472
473
474 void MainWindow::connectBookmarksWidget() {
475     #ifdef Q_WS_MAEMO_5
476         //after removing bookmarks we search for it once again to clear word list
477         connect(bookmarksWidget, SIGNAL(removeAllBookmarks()),
478                 backbone, SLOT(removeAllBookmark()));
479
480         connect(bookmarksWidget, SIGNAL(removeAllBookmarks()),
481                 backbone, SLOT(fetchBookmarks()));
482
483
484         connect(bookmarksWidget, SIGNAL(showAllBookmarks()),
485                 menuWidget, SLOT(hideMenu()));
486
487         connect(bookmarksWidget, SIGNAL(showAllBookmarks()),
488                 backbone, SLOT(fetchBookmarks()));
489
490
491     #else
492         connect(bookmarksShowAllAction, SIGNAL(triggered()),
493                 backbone, SLOT(fetchBookmarks()));
494
495         connect(bookmarksRemoveAllAction, SIGNAL(triggered()),
496                 backbone, SLOT(removeAllBookmark()));
497
498         connect(bookmarksRemoveAllAction, SIGNAL(triggered()),
499                 backbone, SLOT(fetchBookmarks()));
500     #endif
501 }