Fixed welcome screen layout
[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     menu = new QMenu(this);
109     
110     aboutWidget = new AboutWidget(this);
111     aboutWidget->hide();
112
113
114
115     #ifdef Q_WS_MAEMO_5
116         menuWidget = new MenuWidget(this);
117         menuWidget->addSubMenu(tr("Settings"), settingsWidget);
118         menuWidget->addSubMenu(tr("Dictionaries"), dictManagerWidget);
119         menuWidget->addSubMenu(tr("Bookmarks"), bookmarksWidget);
120         menuWidget->addSubMenu(tr("About"), aboutWidget);
121         ui->menuBar->addAction(menuWidget);
122     #else
123         dictionariesAction = ui->menuBar->addAction(tr("Dictionaries"));
124         connect(dictionariesAction, SIGNAL(triggered()),
125                 dictManagerWidget, SLOT(show()));
126
127         settingsAction = ui->menuBar->addAction(tr("Settings"));
128         connect(settingsAction, SIGNAL(triggered()),
129                 settingsWidget, SLOT(show()));
130
131         bookmarksAction = ui->menuBar->addAction(tr("Bookmarks"));
132         connect(bookmarksAction, SIGNAL(triggered()),
133                 bookmarksWidget, SLOT(show()));
134         
135         aboutAction = ui->menuBar->addAction(tr("About"));
136         connect(aboutAction, SIGNAL(triggered()),
137                 aboutWidget, SLOT(show()));
138     #endif
139
140 }
141
142 void MainWindow::closeEvent(QCloseEvent *event) {
143     //reqest to stop all searches and close app
144         emit quit();
145         event->accept();
146 }
147
148 bool MainWindow::exactSearch() {
149     return _exactSearch;
150 }
151
152 void MainWindow::setExactSearch(bool exact) {
153     _exactSearch = exact;
154 }
155
156 void MainWindow::setSearchString(QString word) {
157     searchString = word;
158 }
159
160 void MainWindow::wordListReady() {
161     //gets results from backbone
162     QMultiHash<QString, Translation*> res = backbone->result();
163     QHash<QString, QList<Translation*> > searchResult;
164
165     #ifdef Q_WS_MAEMO_5
166     if(!wordListWidget->isVisible()) {
167         int i = ui->centralWidget->layout()->indexOf(welcomeScreenWidget);
168         QBoxLayout* l = (QBoxLayout*)(ui->centralWidget->layout());
169         l->removeWidget(welcomeScreenWidget);
170         welcomeScreenWidget->deleteLater();
171         l->insertWidget(0, wordListWidget);
172         qDebug()<<"changed";
173     }
174     #endif
175
176     //if nothing was found
177     if(res.count() == 0) {
178         #ifdef Q_WS_MAEMO_5
179         QMaemo5InformationBox::information(this,
180                             tr("Can't find any matching words"),
181                             QMaemo5InformationBox::DefaultTimeout);
182         #endif
183         //show empty list to remove results of old search
184         emit showWordList(searchResult);
185     }
186     else {
187         //find translations of the same key word
188         QMultiHash<QString, Translation*>::iterator i;
189         for(i = res.begin(); i != res.end(); i++) {
190             searchResult[i.key()].push_back(i.value());
191         }
192
193
194         if(!exactSearch()) {
195             emit showWordList(searchResult);
196         }
197         else {
198             #ifndef Q_WS_MAEMO_5
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                 #ifdef Q_WS_MAEMO_5
213                 QMaemo5InformationBox::information(this,
214                                     tr("Can't find exactly matching word"),
215                                     QMaemo5InformationBox::DefaultTimeout);
216                 #endif
217
218                 emit showWordList(searchResult);
219             }
220
221         }
222     }
223     setExactSearch(false);
224 }
225
226 void MainWindow::translationsReady() {
227     #ifndef Q_WS_MAEMO_5
228     if(!translationWidget->isVisible()) {
229         int i = ui->centralWidget->layout()->indexOf(welcomeScreenWidget);
230         QBoxLayout* l = (QBoxLayout*)(ui->centralWidget->layout());
231         QSplitter* s = (QSplitter*)((QWidgetItem*)(l->itemAt(0))->widget());
232         s->insertWidget(1,translationWidget);
233         s->setStretchFactor(1, 150);
234         welcomeScreenWidget->deleteLater();
235         qDebug()<<"changed";
236     }
237     #endif
238
239     emit showTranslation(backbone->htmls());
240 }
241
242 QList<CommonDictInterface*> MainWindow::getPlugins() {
243     return backbone->getPlugins();
244 }
245
246 QHash<CommonDictInterface*, bool> MainWindow::getDictionaries() {
247     return backbone->getDictionaries();
248 }
249
250 void MainWindow::searchExact(QString word) {
251     setExactSearch(true);
252     //searching with searchBar, not directly by emiting searchWordList(),
253     //because it will set search word in searchBar's edit line
254     //this function is only used by history and when searching from attributes
255     searchBarWidget->search(word);
256 }
257
258
259
260 void MainWindow::breakSearching() {
261     //make sure to unset exact search mode
262     setExactSearch(false);
263 }
264
265 void MainWindow::addToHistory(QList<Translation *> trans) {
266     if(trans.count() > 0) {
267         backbone->history()->add(trans[0]->key());
268         translationWidget->setWindowTitle(trans[0]->key());
269     }
270 }
271
272 void MainWindow::historyNext() {
273     if(backbone->history()->nextAvailable()) {
274         QString next = backbone->history()->next();
275         #ifndef Q_WS_MAEMO_5
276             setExactSearch(true);
277         #endif
278         searchBarWidget->searchDelay(next);
279     }
280 }
281
282 void MainWindow::historyPrev() {
283     if(backbone->history()->prevAvailable()) {
284         #ifndef Q_WS_MAEMO_5
285             setExactSearch(true);
286         #endif
287         QString prev = backbone->history()->previous();
288         searchBarWidget->searchDelay(prev);
289     }
290 }
291
292 void MainWindow::disableMenu() {
293     #ifdef Q_WS_MAEMO_5
294         if(ui->menuBar->actions().contains(menuWidget)) {
295               ui->menuBar->removeAction(menuWidget);
296         }
297     #else
298         ui->menuBar->setEnabled(false);
299     #endif
300 }
301
302 void MainWindow::enableMenu() {
303     #ifdef Q_WS_MAEMO_5
304         if(!ui->menuBar->actions().contains(menuWidget)) {
305             ui->menuBar->addAction(menuWidget);
306         }
307     #else
308         ui->menuBar->setEnabled(true);
309     #endif
310 }
311
312 void MainWindow::showHistory() {
313     HistoryListDialog historyDialog(backbone->history()->list(), this);
314     if(historyDialog.exec() == QDialog::Accepted) {
315         backbone->history()->setCurrentElement(historyDialog.selectedRow());
316         searchExact(historyDialog.selectedWord());
317     }
318 }
319
320 void MainWindow::setSettings(Settings *s) {
321     backbone->setSettings(s);
322 }
323
324 Settings* MainWindow::settings() {
325     return backbone->settings();
326 }
327
328 void MainWindow::connectBackbone() {
329     connect(this, SIGNAL(quit()),
330             backbone, SLOT(quit()));
331
332     connect(this, SIGNAL(searchWordList(QString)),
333             backbone, SLOT(search(QString)));
334
335     connect(this, SIGNAL(searchTranslations(QList<Translation*>)),
336             backbone, SLOT(searchHtml(QList<Translation*>)));
337
338     connect(this, SIGNAL(stopSearching()),
339             backbone, SLOT(stopSearching()));
340
341     connect(this, SIGNAL(stopSearching()),
342             this, SLOT(breakSearching()));
343
344     connect(this, SIGNAL(addNewDictionary(CommonDictInterface*)),
345             backbone, SLOT(addDictionary(CommonDictInterface*)));
346
347     connect(this, SIGNAL(removeDictionary(CommonDictInterface*)),
348             backbone, SLOT(removeDictionary(CommonDictInterface*)));
349
350     connect(this, SIGNAL(selectedDictionaries(QList<CommonDictInterface*>)),
351             backbone, SLOT(selectedDictionaries(QList<CommonDictInterface*>)));
352
353
354     connect(backbone, SIGNAL(ready()),
355             this, SIGNAL(setIdle()));
356
357     connect(backbone, SIGNAL(htmlReady()),
358             this, SIGNAL(setIdle()));
359
360
361     connect(backbone, SIGNAL(ready()),
362             this, SLOT(wordListReady()));
363
364     connect(backbone, SIGNAL(htmlReady()),
365             this, SLOT(translationsReady()));
366
367     connect(backbone, SIGNAL(searchCanceled()),
368             this, SIGNAL(setIdle()));
369
370
371
372
373     connect(this, SIGNAL(searchWordList(QString)),
374             this, SIGNAL(setBusy()));
375
376     connect(this, SIGNAL(searchTranslations(QList<Translation*>)),
377             this, SIGNAL(setBusy()));
378
379     connect(this, SIGNAL(stopSearching()),
380             this, SIGNAL(setIdle()));
381
382     connect(this, SIGNAL(searchWordList(QString)),
383             this, SLOT(setSearchString(QString)));
384
385     connect(this, SIGNAL(searchTranslations(QList<Translation*>)),
386             this, SLOT(addToHistory(QList<Translation*>)));
387
388
389 }
390
391 void MainWindow::connectSearchBar() {
392     connect(searchBarWidget, SIGNAL(searchForTranslations(QString)),
393             this, SIGNAL(searchWordList(QString)));
394
395     connect(searchBarWidget, SIGNAL(stopSearching()),
396             this, SIGNAL(stopSearching()));
397
398     connect(this, SIGNAL(setBusy()),
399             searchBarWidget, SLOT(setBusy()));
400
401     connect(this, SIGNAL(setIdle()),
402             searchBarWidget, SLOT(setIdle()));
403
404     connect(searchBarWidget, SIGNAL(historyNext()),
405             this, SLOT(historyNext()));
406
407     connect(searchBarWidget, SIGNAL(historyPrev()),
408             this, SLOT(historyPrev()));
409
410     connect(searchBarWidget, SIGNAL(historyShow()),
411             this, SLOT(showHistory()));
412
413     connect(searchBarWidget, SIGNAL(refreshHistoryButtons()),
414             backbone->history(), SLOT(refreshStatus()));
415
416     connect(backbone->history(), SIGNAL(historyChanged(bool,bool,bool)),
417             searchBarWidget, SLOT(updateHistoryButtons(bool,bool,bool)));
418 }
419
420 void MainWindow::connectWordList() {
421     connect(this,
422             SIGNAL(showWordList(QHash<QString, QList<Translation*> >)),
423             wordListWidget,
424             SLOT(showSearchResults(QHash<QString,QList<Translation*> >)));
425
426     connect(wordListWidget, SIGNAL(showTranslation(QList<Translation*>)),
427             this, SIGNAL(searchTranslations(QList<Translation*>)));
428
429
430
431
432     connect(this, SIGNAL(setBusy()),
433             wordListWidget, SLOT(lockList()));
434
435     connect(this, SIGNAL(setIdle()),
436             wordListWidget, SLOT(unlockList()));
437
438     connect(wordListWidget, SIGNAL(addBookmark(QList<Translation*>)),
439             backbone, SLOT(addBookmark(QList<Translation*>)));
440
441     connect(wordListWidget, SIGNAL(removeBookmark(QList<Translation*>)),
442             backbone, SLOT(removeBookmark(QList<Translation*>)));
443 }
444
445 void MainWindow::connectTranslationWidget() {
446     connect(this, SIGNAL(showTranslation(QStringList)),
447             translationWidget, SLOT(show(QStringList)));
448
449 }
450
451 void MainWindow::connectDictManager() {
452     connect(dictManagerWidget, SIGNAL(addDictionary(CommonDictInterface*)),
453             this, SIGNAL(addNewDictionary(CommonDictInterface*)));
454
455     connect(dictManagerWidget, SIGNAL(removeDictionary(CommonDictInterface*)),
456             this, SIGNAL(removeDictionary(CommonDictInterface*)));
457
458     connect(dictManagerWidget,
459             SIGNAL(selectedDictionaries(QList<CommonDictInterface*>)),
460             this, SIGNAL(selectedDictionaries(QList<CommonDictInterface*>)));
461 }
462
463 void MainWindow::connectMenu() {
464     connect(this, SIGNAL(setBusy()),
465             this, SLOT(disableMenu()));
466
467     connect(this, SIGNAL(setIdle()),
468             this, SLOT(enableMenu()));
469 }
470
471
472 void MainWindow::showAllBookmarks() {
473     menuWidget->hideMenu();
474     backbone->fetchBookmarks();
475 }
476
477 void MainWindow::connectBookmarksWidget() {
478     connect(bookmarksWidget, SIGNAL(removeAllBookmarks()),
479             backbone, SLOT(removeAllBookmark()));
480
481     connect(bookmarksWidget, SIGNAL(showAllBookmarks()),
482             this, SLOT(showAllBookmarks()));
483 }