fac9d25d45e2cc2149ff3e9f9b928efc4a67bfa1
[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
253 void MainWindow::search(QString word) {
254     setExactSearch(false);
255     searchBarWidget->search(word);
256 }
257
258 void MainWindow::searchExact(QString word) {
259     setExactSearch(true);
260     //searching with searchBar, not directly by emiting searchWordList(),
261     //because it will set search word in searchBar's edit line
262     //this function is only used by history and when searching from attributes
263     searchBarWidget->search(word);
264 }
265
266
267
268 void MainWindow::breakSearching() {
269     //make sure to unset exact search mode
270     setExactSearch(false);
271 }
272
273 void MainWindow::addToHistory(QList<Translation *> trans) {
274     if(trans.count() > 0) {
275         backbone->history()->add(trans[0]->key());
276         translationWidget->setWindowTitle(trans[0]->key());
277     }
278 }
279
280 void MainWindow::historyNext() {
281     if(backbone->history()->nextAvailable()) {
282         QString next = backbone->history()->next();
283         #ifndef Q_WS_MAEMO_5
284             setExactSearch(true);
285         #endif
286         searchBarWidget->searchDelay(next);
287     }
288 }
289
290 void MainWindow::historyPrev() {
291     if(backbone->history()->prevAvailable()) {
292         #ifndef Q_WS_MAEMO_5
293             setExactSearch(true);
294         #endif
295         QString prev = backbone->history()->previous();
296         searchBarWidget->searchDelay(prev);
297     }
298 }
299
300 void MainWindow::disableMenu() {
301     #ifdef Q_WS_MAEMO_5
302         if(ui->menuBar->actions().contains(menuWidget)) {
303               ui->menuBar->removeAction(menuWidget);
304         }
305     #else
306         ui->menuBar->setEnabled(false);
307     #endif
308 }
309
310 void MainWindow::enableMenu() {
311     #ifdef Q_WS_MAEMO_5
312         if(!ui->menuBar->actions().contains(menuWidget)) {
313             ui->menuBar->addAction(menuWidget);
314         }
315     #else
316         ui->menuBar->setEnabled(true);
317     #endif
318 }
319
320 void MainWindow::showHistory() {
321     HistoryListDialog historyDialog(backbone->history()->list(), this);
322     if(historyDialog.exec() == QDialog::Accepted) {
323         backbone->history()->setCurrentElement(historyDialog.selectedRow());
324         searchExact(historyDialog.selectedWord());
325     }
326 }
327
328 void MainWindow::setSettings(Settings *s) {
329     backbone->setSettings(s);
330 }
331
332 Settings* MainWindow::settings() {
333     return backbone->settings();
334 }
335
336 void MainWindow::connectBackbone() {
337     connect(this, SIGNAL(quit()),
338             backbone, SLOT(quit()));
339
340     connect(this, SIGNAL(searchWordList(QString)),
341             backbone, SLOT(search(QString)));
342
343     connect(this, SIGNAL(searchTranslations(QList<Translation*>)),
344             backbone, SLOT(searchHtml(QList<Translation*>)));
345
346     connect(this, SIGNAL(stopSearching()),
347             backbone, SLOT(stopSearching()));
348
349     connect(this, SIGNAL(stopSearching()),
350             this, SLOT(breakSearching()));
351
352     connect(this, SIGNAL(addNewDictionary(CommonDictInterface*)),
353             backbone, SLOT(addDictionary(CommonDictInterface*)));
354
355     connect(this, SIGNAL(removeDictionary(CommonDictInterface*)),
356             backbone, SLOT(removeDictionary(CommonDictInterface*)));
357
358     connect(this, SIGNAL(selectedDictionaries(QList<CommonDictInterface*>)),
359             backbone, SLOT(selectedDictionaries(QList<CommonDictInterface*>)));
360
361
362     connect(backbone, SIGNAL(ready()),
363             this, SIGNAL(setIdle()));
364
365     connect(backbone, SIGNAL(htmlReady()),
366             this, SIGNAL(setIdle()));
367
368
369     connect(backbone, SIGNAL(ready()),
370             this, SLOT(wordListReady()));
371
372     connect(backbone, SIGNAL(htmlReady()),
373             this, SLOT(translationsReady()));
374
375     connect(backbone, SIGNAL(searchCanceled()),
376             this, SIGNAL(setIdle()));
377
378
379
380
381     connect(this, SIGNAL(searchWordList(QString)),
382             this, SIGNAL(setBusy()));
383
384     connect(this, SIGNAL(searchTranslations(QList<Translation*>)),
385             this, SIGNAL(setBusy()));
386
387     connect(this, SIGNAL(stopSearching()),
388             this, SIGNAL(setIdle()));
389
390     connect(this, SIGNAL(searchWordList(QString)),
391             this, SLOT(setSearchString(QString)));
392
393     connect(this, SIGNAL(searchTranslations(QList<Translation*>)),
394             this, SLOT(addToHistory(QList<Translation*>)));
395
396
397 }
398
399 void MainWindow::connectSearchBar() {
400     connect(searchBarWidget, SIGNAL(searchForTranslations(QString)),
401             this, SIGNAL(searchWordList(QString)));
402
403     connect(searchBarWidget, SIGNAL(stopSearching()),
404             this, SIGNAL(stopSearching()));
405
406     connect(this, SIGNAL(setBusy()),
407             searchBarWidget, SLOT(setBusy()));
408
409     connect(this, SIGNAL(setIdle()),
410             searchBarWidget, SLOT(setIdle()));
411
412     connect(searchBarWidget, SIGNAL(historyNext()),
413             this, SLOT(historyNext()));
414
415     connect(searchBarWidget, SIGNAL(historyPrev()),
416             this, SLOT(historyPrev()));
417
418     connect(searchBarWidget, SIGNAL(historyShow()),
419             this, SLOT(showHistory()));
420
421     connect(searchBarWidget, SIGNAL(refreshHistoryButtons()),
422             backbone->history(), SLOT(refreshStatus()));
423
424     connect(backbone->history(), SIGNAL(historyChanged(bool,bool,bool)),
425             searchBarWidget, SLOT(updateHistoryButtons(bool,bool,bool)));
426 }
427
428 void MainWindow::connectWordList() {
429     connect(this,
430             SIGNAL(showWordList(QHash<QString, QList<Translation*> >)),
431             wordListWidget,
432             SLOT(showSearchResults(QHash<QString,QList<Translation*> >)));
433
434     connect(wordListWidget, SIGNAL(showTranslation(QList<Translation*>)),
435             this, SIGNAL(searchTranslations(QList<Translation*>)));
436
437
438
439
440     connect(this, SIGNAL(setBusy()),
441             wordListWidget, SLOT(lockList()));
442
443     connect(this, SIGNAL(setIdle()),
444             wordListWidget, SLOT(unlockList()));
445
446     connect(wordListWidget, SIGNAL(addBookmark(QList<Translation*>)),
447             backbone, SLOT(addBookmark(QList<Translation*>)));
448
449     connect(wordListWidget, SIGNAL(removeBookmark(QList<Translation*>)),
450             backbone, SLOT(removeBookmark(QList<Translation*>)));
451 }
452
453 void MainWindow::connectTranslationWidget() {
454     connect(this, SIGNAL(showTranslation(QStringList)),
455             translationWidget, SLOT(show(QStringList)));
456
457      #ifdef Q_WS_MAEMO_5
458         connect(translationWidget, SIGNAL(search(QString)),
459                 this, SLOT(search(QString)));
460     #else
461         connect(translationWidget, SIGNAL(search(QString)),
462                 this, SLOT(searchExact(QString)));
463     #endif
464
465
466 }
467
468 void MainWindow::connectDictManager() {
469     connect(dictManagerWidget, SIGNAL(addDictionary(CommonDictInterface*)),
470             this, SIGNAL(addNewDictionary(CommonDictInterface*)));
471
472     connect(dictManagerWidget, SIGNAL(removeDictionary(CommonDictInterface*)),
473             this, SIGNAL(removeDictionary(CommonDictInterface*)));
474
475     connect(dictManagerWidget,
476             SIGNAL(selectedDictionaries(QList<CommonDictInterface*>)),
477             this, SIGNAL(selectedDictionaries(QList<CommonDictInterface*>)));
478 }
479
480 void MainWindow::connectMenu() {
481     connect(this, SIGNAL(setBusy()),
482             this, SLOT(disableMenu()));
483
484     connect(this, SIGNAL(setIdle()),
485             this, SLOT(enableMenu()));
486 }
487
488
489 void MainWindow::connectBookmarksWidget() {
490     #ifdef Q_WS_MAEMO_5
491         //after removing bookmarks we search for it once again to clear word list
492         connect(bookmarksWidget, SIGNAL(removeAllBookmarks()),
493                 backbone, SLOT(removeAllBookmark()));
494
495         connect(bookmarksWidget, SIGNAL(removeAllBookmarks()),
496                 backbone, SLOT(fetchBookmarks()));
497
498
499         connect(bookmarksWidget, SIGNAL(showAllBookmarks()),
500                 menuWidget, SLOT(hideMenu()));
501
502         connect(bookmarksWidget, SIGNAL(showAllBookmarks()),
503                 backbone, SLOT(fetchBookmarks()));
504
505
506     #else
507         connect(bookmarksShowAllAction, SIGNAL(triggered()),
508                 backbone, SLOT(fetchBookmarks()));
509
510         connect(bookmarksRemoveAllAction, SIGNAL(triggered()),
511                 backbone, SLOT(removeAllBookmark()));
512
513         connect(bookmarksRemoveAllAction, SIGNAL(triggered()),
514                 backbone, SLOT(fetchBookmarks()));
515     #endif
516 }