Change of tool button
[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
50     setExactSearch(false);
51
52     setWindowTitle("mDictionary");
53
54     showMaximized();
55 }
56
57 MainWindow::~MainWindow() {
58     delete ui;
59 }
60
61
62 void MainWindow::initializeUI() {
63     ui->setupUi(this);
64
65     #ifdef Q_WS_MAEMO_5
66         setAttribute(Qt::WA_Maemo5StackedWindow);
67     #endif
68
69     searchBarWidget = new SearchBarWidget;
70
71     wordListWidget = new WordListWidget;
72
73     //translationWidget is antoher stacked window, so we don't add it to layout
74     //only create it with this widget as parent
75     translationWidget = new TranslationWidget(this);
76
77     welcomeScreenWidget = new WelcomeScreenWidget;
78
79
80     #ifdef Q_WS_MAEMO_5
81     //At start we set widget as welcome screen widget
82         ui->centralWidget->layout()->addWidget(welcomeScreenWidget);
83         QVBoxLayout* vl = (QVBoxLayout*)(ui->centralWidget->layout());
84         vl->addWidget(searchBarWidget, 0, Qt::AlignBottom);
85     #else
86         translationWidget->hide();
87         //we add to splitter word list and welcome screen
88         splitter = new QSplitter(Qt::Horizontal);
89         splitter->addWidget(wordListWidget);
90         splitter->addWidget(welcomeScreenWidget);
91         splitter->setStretchFactor(1, 150);
92         ui->centralWidget->layout()->addWidget(splitter);
93         ui->centralWidget->layout()->addWidget(searchBarWidget);
94     #endif
95
96
97
98     dictManagerWidget = new DictManagerWidget(this);
99     dictManagerWidget->hide();
100
101     settingsWidget = new SettingsWidget(this);
102     settingsWidget->hide();
103
104     bookmarksWidget = new BookmarksWidget(this);
105     bookmarksWidget->hide();
106
107     aboutWidget = new AboutWidget(this);
108     aboutWidget->hide();
109
110
111     //creating menus
112
113     #ifdef Q_WS_MAEMO_5
114         menuWidget = new MenuWidget(this);
115         menuWidget->addSubMenu(tr("Settings"), settingsWidget);
116         menuWidget->addSubMenu(tr("Dictionaries"), dictManagerWidget);
117         menuWidget->addSubMenu(tr("Bookmarks"), bookmarksWidget);
118         menuWidget->addSubMenu(tr("About"), aboutWidget);
119         ui->menuBar->addAction(menuWidget);
120     #else
121         dictionariesAction = ui->menuBar->addAction(tr("Dictionaries"));
122         connect(dictionariesAction, SIGNAL(triggered()),
123                 dictManagerWidget, SLOT(show()));
124
125         settingsAction = ui->menuBar->addAction(tr("Settings"));
126         connect(settingsAction, SIGNAL(triggered()),
127                 settingsWidget, SLOT(show()));
128
129         QMenu* m = ui->menuBar->addMenu(tr("Bookmarks"));
130         bookmarksShowAllAction = new QAction(tr("Show all"), m);
131
132         bookmarksRemoveAllAction = new QAction(tr("Remove all"), m);
133
134         m->addAction(bookmarksShowAllAction);
135         m->addAction(bookmarksRemoveAllAction);
136
137         aboutAction = ui->menuBar->addAction(tr("About"));
138         connect(aboutAction, SIGNAL(triggered()),
139                 aboutWidget, SLOT(show()));
140     #endif
141
142 }
143
144 void MainWindow::closeEvent(QCloseEvent *event) {
145     //reqest to stop all searches and close app
146         emit quit();
147         event->accept();
148 }
149
150 bool MainWindow::exactSearch() {
151     return _exactSearch;
152 }
153
154 void MainWindow::setExactSearch(bool exact) {
155     _exactSearch = exact;
156 }
157
158 void MainWindow::setSearchString(QString word) {
159     searchString = word;
160 }
161
162 void MainWindow::wordListReady() {
163     //gets results from backbone
164     QMultiHash<QString, Translation*> res = backbone->result();
165     QHash<QString, QList<Translation*> > searchResult;
166
167     #ifdef Q_WS_MAEMO_5
168     //switch welcome screen with word list
169     if(!wordListWidget->isVisible()) {
170         int i = ui->centralWidget->layout()->indexOf(welcomeScreenWidget);
171         QBoxLayout* l = (QBoxLayout*)(ui->centralWidget->layout());
172         l->removeWidget(welcomeScreenWidget);
173         welcomeScreenWidget->deleteLater();
174         l->insertWidget(0, wordListWidget);
175     }
176     #endif
177
178     //if nothing was found
179     if(res.count() == 0) {
180         showNotify(Notify::Info, tr("Can't find any matching words"));
181
182         //show empty list to remove results of old search
183         emit showWordList(searchResult);
184     }
185     else {
186         //find translations of the same key word
187         QMultiHash<QString, Translation*>::iterator i;
188         for(i = res.begin(); i != res.end(); i++) {
189             searchResult[i.key()].push_back(i.value());
190         }
191
192
193         if(!exactSearch()) {
194             emit showWordList(searchResult);
195         }
196         else {
197             #ifndef Q_WS_MAEMO_5
198             //on desktop we show word list in exact search
199                 emit showWordList(searchResult);
200             #endif
201             bool foundExactMatch = false;
202             QHash<QString, QList<Translation*> >::iterator j;
203             for(j = searchResult.begin(); j != searchResult.end(); j++) {
204                 if(j.key() == searchString && !foundExactMatch) {
205                     foundExactMatch = true;
206                     emit searchTranslations(j.value());
207                     break;
208                 }
209             }
210
211             if(!foundExactMatch) {
212                 showNotify(Notify::Info,
213                            tr("Can't find exactly matching word"));
214
215                 emit showWordList(searchResult);
216             }
217
218         }
219     }
220     setExactSearch(false);
221 }
222
223 void MainWindow::translationsReady() {
224     #ifndef Q_WS_MAEMO_5
225     //switch welcome screen with translation widget
226     if(!translationWidget->isVisible()) {
227         QBoxLayout* l = (QBoxLayout*)(ui->centralWidget->layout());
228         QSplitter* s = (QSplitter*)((QWidgetItem*)(l->itemAt(0))->widget());
229         s->insertWidget(1,translationWidget);
230         s->setStretchFactor(1, 150);
231         welcomeScreenWidget->deleteLater();
232     }
233     #endif
234
235     emit showTranslation(backbone->htmls());
236 }
237
238 QList<CommonDictInterface*> MainWindow::getPlugins() {
239     return backbone->getPlugins();
240 }
241
242 QHash<CommonDictInterface*, bool> MainWindow::getDictionaries() {
243     return backbone->getDictionaries();
244 }
245
246
247 void MainWindow::search(QString word) {
248     setExactSearch(false);
249     searchBarWidget->search(word);
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
331 void MainWindow::showNotify(Notify::NotifyType type, QString text) {
332     switch(type) {
333     case Notify::Info:
334         #ifdef Q_WS_MAEMO_5
335             QMaemo5InformationBox::information(this,
336                                 text,
337                                 QMaemo5InformationBox::DefaultTimeout);
338         #else
339             QMessageBox::information(this, "Information", text);
340         #endif
341         break;
342
343     case Notify::Warning:
344         #ifndef Q_WS_MAEMO_5
345                 QMessageBox::warning(this, "Warning", text);
346                 break;
347         #endif
348
349     case Notify::Error:
350         #ifdef Q_WS_MAEMO_5
351             QMaemo5InformationBox::information(this,
352                                 text,
353                                 QMaemo5InformationBox::NoTimeout);
354         #else
355             QMessageBox::critical(this, "Error", text);
356         #endif
357         break;
358     }
359 }
360
361 void MainWindow::connectBackbone() {
362     connect(this, SIGNAL(quit()),
363             backbone, SLOT(quit()));
364
365     connect(this, SIGNAL(searchWordList(QString)),
366             backbone, SLOT(search(QString)));
367
368     connect(this, SIGNAL(searchTranslations(QList<Translation*>)),
369             backbone, SLOT(searchHtml(QList<Translation*>)));
370
371     connect(this, SIGNAL(stopSearching()),
372             backbone, SLOT(stopSearching()));
373
374     connect(this, SIGNAL(stopSearching()),
375             this, SLOT(breakSearching()));
376
377     connect(this, SIGNAL(addNewDictionary(CommonDictInterface*)),
378             backbone, SLOT(addDictionary(CommonDictInterface*)));
379
380     connect(this, SIGNAL(removeDictionary(CommonDictInterface*)),
381             backbone, SLOT(removeDictionary(CommonDictInterface*)));
382
383     connect(this, SIGNAL(selectedDictionaries(QList<CommonDictInterface*>)),
384             backbone, SLOT(selectedDictionaries(QList<CommonDictInterface*>)));
385
386
387     connect(backbone, SIGNAL(ready()),
388             this, SIGNAL(setIdle()));
389
390     connect(backbone, SIGNAL(htmlReady()),
391             this, SIGNAL(setIdle()));
392
393
394     connect(backbone, SIGNAL(ready()),
395             this, SLOT(wordListReady()));
396
397     connect(backbone, SIGNAL(htmlReady()),
398             this, SLOT(translationsReady()));
399
400     connect(backbone, SIGNAL(searchCanceled()),
401             this, SIGNAL(setIdle()));
402
403
404
405
406     connect(this, SIGNAL(searchWordList(QString)),
407             this, SIGNAL(setBusy()));
408
409     connect(this, SIGNAL(searchTranslations(QList<Translation*>)),
410             this, SIGNAL(setBusy()));
411
412     connect(this, SIGNAL(stopSearching()),
413             this, SIGNAL(setIdle()));
414
415     connect(this, SIGNAL(searchWordList(QString)),
416             this, SLOT(setSearchString(QString)));
417
418     connect(this, SIGNAL(searchTranslations(QList<Translation*>)),
419             this, SLOT(addToHistory(QList<Translation*>)));
420
421
422 }
423
424 void MainWindow::connectSearchBar() {
425     connect(searchBarWidget, SIGNAL(searchForTranslations(QString)),
426             this, SIGNAL(searchWordList(QString)));
427
428     connect(searchBarWidget, SIGNAL(stopSearching()),
429             this, SIGNAL(stopSearching()));
430
431     connect(this, SIGNAL(setBusy()),
432             searchBarWidget, SLOT(setBusy()));
433
434     connect(this, SIGNAL(setIdle()),
435             searchBarWidget, SLOT(setIdle()));
436
437     connect(searchBarWidget, SIGNAL(historyNext()),
438             this, SLOT(historyNext()));
439
440     connect(searchBarWidget, SIGNAL(historyPrev()),
441             this, SLOT(historyPrev()));
442
443     connect(searchBarWidget, SIGNAL(historyShow()),
444             this, SLOT(showHistory()));
445
446     connect(searchBarWidget, SIGNAL(refreshHistoryButtons()),
447             backbone->history(), SLOT(refreshStatus()));
448
449     connect(backbone->history(), SIGNAL(historyChanged(bool,bool,bool)),
450             searchBarWidget, SLOT(updateHistoryButtons(bool,bool,bool)));
451 }
452
453 void MainWindow::connectWordList() {
454     connect(this,
455             SIGNAL(showWordList(QHash<QString, QList<Translation*> >)),
456             wordListWidget,
457             SLOT(showSearchResults(QHash<QString,QList<Translation*> >)));
458
459     connect(wordListWidget, SIGNAL(showTranslation(QList<Translation*>)),
460             this, SIGNAL(searchTranslations(QList<Translation*>)));
461
462
463
464
465     connect(this, SIGNAL(setBusy()),
466             wordListWidget, SLOT(lockList()));
467
468     connect(this, SIGNAL(setIdle()),
469             wordListWidget, SLOT(unlockList()));
470
471     connect(wordListWidget, SIGNAL(addBookmark(QList<Translation*>)),
472             backbone, SLOT(addBookmark(QList<Translation*>)));
473
474     connect(wordListWidget, SIGNAL(removeBookmark(QList<Translation*>)),
475             backbone, SLOT(removeBookmark(QList<Translation*>)));
476 }
477
478 void MainWindow::connectTranslationWidget() {
479     connect(this, SIGNAL(showTranslation(QStringList)),
480             translationWidget, SLOT(show(QStringList)));
481
482      #ifdef Q_WS_MAEMO_5
483         connect(translationWidget, SIGNAL(search(QString)),
484                 this, SLOT(search(QString)));
485     #else
486         connect(translationWidget, SIGNAL(search(QString)),
487                 this, SLOT(searchExact(QString)));
488     #endif
489
490
491 }
492
493 void MainWindow::connectDictManager() {
494     connect(dictManagerWidget, SIGNAL(addDictionary(CommonDictInterface*)),
495             this, SIGNAL(addNewDictionary(CommonDictInterface*)));
496
497     connect(dictManagerWidget, SIGNAL(removeDictionary(CommonDictInterface*)),
498             this, SIGNAL(removeDictionary(CommonDictInterface*)));
499
500     connect(dictManagerWidget,
501             SIGNAL(selectedDictionaries(QList<CommonDictInterface*>)),
502             this, SIGNAL(selectedDictionaries(QList<CommonDictInterface*>)));
503 }
504
505 void MainWindow::connectMenu() {
506     connect(this, SIGNAL(setBusy()),
507             this, SLOT(disableMenu()));
508
509     connect(this, SIGNAL(setIdle()),
510             this, SLOT(enableMenu()));
511 }
512
513
514 void MainWindow::connectBookmarksWidget() {
515     #ifdef Q_WS_MAEMO_5
516         //after removing bookmarks we search for it once again to clear word list
517         connect(bookmarksWidget, SIGNAL(removeAllBookmarks()),
518                 backbone, SLOT(removeAllBookmark()));
519
520         connect(bookmarksWidget, SIGNAL(removeAllBookmarks()),
521                 backbone, SLOT(fetchBookmarks()));
522
523
524         connect(bookmarksWidget, SIGNAL(showAllBookmarks()),
525                 menuWidget, SLOT(hideMenu()));
526
527         connect(bookmarksWidget, SIGNAL(showAllBookmarks()),
528                 backbone, SLOT(fetchBookmarks()));
529
530
531     #else
532         connect(bookmarksShowAllAction, SIGNAL(triggered()),
533                 backbone, SLOT(fetchBookmarks()));
534
535         connect(bookmarksRemoveAllAction, SIGNAL(triggered()),
536                 backbone, SLOT(removeAllBookmark()));
537
538         connect(bookmarksRemoveAllAction, SIGNAL(triggered()),
539                 backbone, SLOT(fetchBookmarks()));
540     #endif
541 }