Added documentation
[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     #ifdef Q_WS_MAEMO_5
37         setAttribute(Qt::WA_Maemo5StackedWindow);
38     #endif
39
40     this->backbone = backbone;
41
42     initializeUI();
43
44     connectBackbone();
45     connectSearchBar();
46     connectWordList();
47     connectTranslationWidget();
48     connectDictManager();
49     connectMenu();
50     connectBookmarksWidget();
51
52
53     setExactSearch(false);
54
55     setWindowTitle("mDictionary");
56
57     showMaximized();
58 }
59
60 MainWindow::~MainWindow() {
61     delete ui;
62 }
63
64
65 void MainWindow::initializeUI() {
66     ui->setupUi(this);
67
68     //showFullScreen();
69     //sets attribute to maemo's stacked window
70
71
72
73     searchBarWidget = new SearchBarWidget;
74
75     wordListWidget = new WordListWidget;
76
77     //translationWidget is antoher stacked window, so we don't add it to layout
78     //only create it with this widget as parent
79     translationWidget = new TranslationWidget(this);
80
81     welcomeScreenWidget = new WelcomeScreenWidget;
82
83     #ifdef Q_WS_MAEMO_5
84         ui->centralWidget->layout()->addWidget(welcomeScreenWidget);
85         QVBoxLayout* vl = (QVBoxLayout*)(ui->centralWidget->layout());
86         vl->addWidget(searchBarWidget, 0, Qt::AlignBottom);
87     #else
88         translationWidget->hide();
89         splitter = new QSplitter(Qt::Horizontal);
90         splitter->addWidget(wordListWidget);
91         splitter->addWidget(welcomeScreenWidget);
92         splitter->setStretchFactor(1, 150);
93         ui->centralWidget->layout()->addWidget(splitter);
94         ui->centralWidget->layout()->addWidget(searchBarWidget);
95     #endif
96
97
98
99     dictManagerWidget = new DictManagerWidget(this);
100     dictManagerWidget->hide();
101
102     settingsWidget = new SettingsWidget(this);
103     settingsWidget->hide();
104
105     bookmarksWidget = new BookmarksWidget(this);
106     bookmarksWidget->hide();
107
108     aboutWidget = new AboutWidget(this);
109     aboutWidget->hide();
110
111
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     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         qDebug()<<"changed";
175     }
176     #endif
177
178     //if nothing was found
179     if(res.count() == 0) {
180         #ifdef Q_WS_MAEMO_5
181         QMaemo5InformationBox::information(this,
182                             tr("Can't find any matching words"),
183                             QMaemo5InformationBox::DefaultTimeout);
184         #endif
185         //show empty list to remove results of old search
186         emit showWordList(searchResult);
187     }
188     else {
189         //find translations of the same key word
190         QMultiHash<QString, Translation*>::iterator i;
191         for(i = res.begin(); i != res.end(); i++) {
192             searchResult[i.key()].push_back(i.value());
193         }
194
195
196         if(!exactSearch()) {
197             emit showWordList(searchResult);
198         }
199         else {
200             #ifndef Q_WS_MAEMO_5
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     if(!translationWidget->isVisible()) {
231         int i = ui->centralWidget->layout()->indexOf(welcomeScreenWidget);
232         QBoxLayout* l = (QBoxLayout*)(ui->centralWidget->layout());
233         QSplitter* s = (QSplitter*)((QWidgetItem*)(l->itemAt(0))->widget());
234         s->insertWidget(1,translationWidget);
235         s->setStretchFactor(1, 150);
236         welcomeScreenWidget->deleteLater();
237         qDebug()<<"changed";
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::showAllBookmarks() {
475     #ifdef Q_WS_MAEMO_5
476         menuWidget->hideMenu();
477     #endif
478     backbone->fetchBookmarks();
479 }
480
481 void MainWindow::connectBookmarksWidget() {
482     #ifdef Q_WS_MAEMO_5
483         connect(bookmarksWidget, SIGNAL(removeAllBookmarks()),
484                 backbone, SLOT(removeAllBookmark()));
485
486         connect(bookmarksWidget, SIGNAL(showAllBookmarks()),
487                 this, SLOT(showAllBookmarks()));
488
489         connect(bookmarksWidget, SIGNAL(removeAllBookmarks()),
490                 backbone, SLOT(fetchBookmarks()));
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 }