Added Desktop/MeeGo GUI
[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 #ifdef Q_WS_MAEMO_5
27     #include <QMaemo5InformationBox>
28 #endif
29
30
31 MainWindow::MainWindow(Backbone *backbone, QWidget *parent):
32     GUIInterface(parent),
33     ui(new Ui::MainWindow) {
34
35     this->backbone = backbone;
36
37     initializeUI();
38
39     connectBackbone();
40     connectSearchBar();
41     connectWordList();
42     connectTranslationWidget();
43     connectDictManager();
44     connectMenu();
45
46     setExactSearch(false);
47
48     setWindowTitle("mDictionary");
49 }
50
51 MainWindow::~MainWindow() {
52     delete ui;
53 }
54
55
56 void MainWindow::initializeUI() {
57     ui->setupUi(this);
58
59     //sets attribute to maemo's stacked window
60     #ifdef Q_WS_MAEMO_5
61         setAttribute(Qt::WA_Maemo5StackedWindow);
62     #endif
63
64
65     searchBarWidget = new SearchBarWidget;
66     wordListWidget = new WordListWidget;
67
68     //translationWidget is antoher stacked window, so we don't add it to layout
69     //only create it with this widget as parent
70     translationWidget = new TranslationWidget(this);
71
72     #ifdef Q_WS_MAEMO_5
73         ui->centralWidget->layout()->addWidget(wordListWidget);
74     #else
75         splitter = new QSplitter(Qt::Horizontal);
76         splitter->addWidget(wordListWidget);
77         splitter->addWidget(translationWidget);
78         splitter->setStretchFactor(1, 150);
79         ui->centralWidget->layout()->addWidget(splitter);
80     #endif
81     ui->centralWidget->layout()->addWidget(searchBarWidget);
82
83
84
85     dictManagerWidget = new DictManagerWidget(this);
86     dictManagerWidget->hide();
87     #ifdef Q_WS_MAEMO_5
88         menuWidget = new MenuWidget(this);
89         menuWidget->addSubMenu(tr("Dictionaries"), dictManagerWidget);
90         menuWidget->addSubMenu(tr("Settings"), new QPushButton("Settings"));
91         menuWidget->addSubMenu(tr("About"), new QPushButton("About"));
92         ui->menuBar->addAction(menuWidget);
93     #else
94         dictionariesAction = ui->menuBar->addAction(tr("Dictionaries"));
95         connect(dictionariesAction, SIGNAL(triggered()),
96                 dictManagerWidget, SLOT(show()));
97     #endif
98
99 }
100
101 void MainWindow::closeEvent(QCloseEvent *event) {
102     //reqest to stop all searches and close app
103         emit quit();
104         event->accept();
105 }
106
107 bool MainWindow::exactSearch() {
108     return _exactSearch;
109 }
110
111 void MainWindow::setExactSearch(bool exact) {
112     _exactSearch = exact;
113 }
114
115 void MainWindow::setSearchString(QString word) {
116     searchString = word;
117 }
118
119 void MainWindow::wordListReady() {
120     //gets results from backbone
121     QMultiHash<QString, Translation*> res = backbone->result();
122     QHash<QString, QList<Translation*> > searchResult;
123
124     //if nothing was found
125     if(res.count() == 0) {
126         #ifdef Q_WS_MAEMO_5
127         QMaemo5InformationBox::information(this,
128                             tr("Can't find any matching words"),
129                             QMaemo5InformationBox::DefaultTimeout);
130         #endif
131         //show empty list to remove results of old search
132         emit showWordList(searchResult);
133     }
134     else {
135         //find translations of the same key word
136         QMultiHash<QString, Translation*>::iterator i;
137         for(i = res.begin(); i != res.end(); i++) {
138             searchResult[i.key()].push_back(i.value());
139         }
140
141
142         if(!exactSearch()) {
143             emit showWordList(searchResult);
144         }
145         else {
146
147             bool foundExactMatch = false;
148             QHash<QString, QList<Translation*> >::iterator j;
149             for(j = searchResult.begin(); j != searchResult.end(); j++) {
150                 if(j.key() == searchString && !foundExactMatch) {
151                     foundExactMatch = true;
152                     emit searchTranslations(j.value());
153                     break;
154                 }
155             }
156
157             if(!foundExactMatch) {
158                 #ifdef Q_WS_MAEMO_5
159                 QMaemo5InformationBox::information(this,
160                                     tr("Can't find exactly matching word"),
161                                     QMaemo5InformationBox::DefaultTimeout);
162                 #endif
163
164                 emit showWordList(searchResult);
165             }
166
167         }
168     }
169     setExactSearch(false);
170 }
171
172 void MainWindow::translationsReady() {
173     emit showTranslation(backbone->htmls());
174 }
175
176 QList<CommonDictInterface*> MainWindow::getPlugins() {
177     return backbone->getPlugins();
178 }
179
180 QHash<CommonDictInterface*, bool> MainWindow::getDictionaries() {
181     return backbone->getDictionaries();
182 }
183
184 void MainWindow::searchExact(QString word) {
185     setExactSearch(true);
186     //searching with searchBar, not directly by emiting searchWordList(),
187     //because it will set search word in searchBar's edit line
188     //this function is only used by history and when searching from attributes
189     searchBarWidget->search(word);
190 }
191
192
193
194 void MainWindow::breakSearching() {
195     //make sure to unset exact search mode
196     setExactSearch(false);
197 }
198
199 void MainWindow::addToHistory(QList<Translation *> trans) {
200     if(trans.count() > 0) {
201         backbone->history()->add(trans[0]->key());
202         translationWidget->setWindowTitle(trans[0]->key());
203     }
204 }
205
206 void MainWindow::historyNext() {
207     if(backbone->history()->nextAvailable()) {
208         QString next = backbone->history()->next();
209         searchBarWidget->searchDelay(next);
210     }
211 }
212
213 void MainWindow::historyPrev() {
214     if(backbone->history()->prevAvailable()) {
215         QString prev = backbone->history()->previous();
216         searchBarWidget->searchDelay(prev);
217     }
218 }
219
220 void MainWindow::disableMenu() {
221     #ifdef Q_WS_MAEMO_5
222         if(ui->menuBar->actions().contains(menuWidget)) {
223               ui->menuBar->removeAction(menuWidget);
224         }
225     #else
226         ui->menuBar->setEnabled(false);
227     #endif
228 }
229
230 void MainWindow::enableMenu() {
231     #ifdef Q_WS_MAEMO_5
232         if(!ui->menuBar->actions().contains(menuWidget)) {
233             ui->menuBar->addAction(menuWidget);
234         }
235     #else
236         ui->menuBar->setEnabled(true);
237     #endif
238 }
239
240 void MainWindow::showHistory() {
241     HistoryListDialog historyDialog(backbone->history()->list(), this);
242     if(historyDialog.exec() == QDialog::Accepted) {
243         backbone->history()->setCurrentElement(historyDialog.selectedRow());
244         searchExact(historyDialog.selectedWord());
245     }
246 }
247
248 void MainWindow::connectBackbone() {
249     connect(this, SIGNAL(quit()),
250             backbone, SLOT(quit()));
251
252     connect(this, SIGNAL(searchWordList(QString)),
253             backbone, SLOT(search(QString)));
254
255     connect(this, SIGNAL(searchTranslations(QList<Translation*>)),
256             backbone, SLOT(searchHtml(QList<Translation*>)));
257
258     connect(this, SIGNAL(stopSearching()),
259             backbone, SLOT(stopSearching()));
260
261     connect(this, SIGNAL(stopSearching()),
262             this, SLOT(breakSearching()));
263
264     connect(this, SIGNAL(addNewDictionary(CommonDictInterface*)),
265             backbone, SLOT(addDictionary(CommonDictInterface*)));
266
267     connect(this, SIGNAL(removeDictionary(CommonDictInterface*)),
268             backbone, SLOT(removeDictionary(CommonDictInterface*)));
269
270     connect(this, SIGNAL(selectedDictionaries(QList<CommonDictInterface*>)),
271             backbone, SLOT(selectedDictionaries(QList<CommonDictInterface*>)));
272
273
274     connect(backbone, SIGNAL(ready()),
275             this, SIGNAL(setIdle()));
276
277     connect(backbone, SIGNAL(htmlReady()),
278             this, SIGNAL(setIdle()));
279
280
281     connect(backbone, SIGNAL(ready()),
282             this, SLOT(wordListReady()));
283
284     connect(backbone, SIGNAL(htmlReady()),
285             this, SLOT(translationsReady()));
286
287     connect(backbone, SIGNAL(searchCanceled()),
288             this, SIGNAL(setIdle()));
289
290
291
292
293     connect(this, SIGNAL(searchWordList(QString)),
294             this, SIGNAL(setBusy()));
295
296     connect(this, SIGNAL(searchTranslations(QList<Translation*>)),
297             this, SIGNAL(setBusy()));
298
299     connect(this, SIGNAL(stopSearching()),
300             this, SIGNAL(setIdle()));
301
302     connect(this, SIGNAL(searchWordList(QString)),
303             this, SLOT(setSearchString(QString)));
304
305     connect(this, SIGNAL(searchTranslations(QList<Translation*>)),
306             this, SLOT(addToHistory(QList<Translation*>)));
307
308
309 }
310
311 void MainWindow::connectSearchBar() {
312     connect(searchBarWidget, SIGNAL(searchForTranslations(QString)),
313             this, SIGNAL(searchWordList(QString)));
314
315     connect(searchBarWidget, SIGNAL(stopSearching()),
316             this, SIGNAL(stopSearching()));
317
318     connect(this, SIGNAL(setBusy()),
319             searchBarWidget, SLOT(setBusy()));
320
321     connect(this, SIGNAL(setIdle()),
322             searchBarWidget, SLOT(setIdle()));
323
324     connect(searchBarWidget, SIGNAL(historyNext()),
325             this, SLOT(historyNext()));
326
327     connect(searchBarWidget, SIGNAL(historyPrev()),
328             this, SLOT(historyPrev()));
329
330     connect(searchBarWidget, SIGNAL(historyShow()),
331             this, SLOT(showHistory()));
332
333     connect(searchBarWidget, SIGNAL(refreshHistoryButtons()),
334             backbone->history(), SLOT(refreshStatus()));
335
336     connect(backbone->history(), SIGNAL(historyChanged(bool,bool,bool)),
337             searchBarWidget, SLOT(updateHistoryButtons(bool,bool,bool)));
338 }
339
340 void MainWindow::connectWordList() {
341     connect(this,
342             SIGNAL(showWordList(QHash<QString, QList<Translation*> >)),
343             wordListWidget,
344             SLOT(showSearchResults(QHash<QString,QList<Translation*> >)));
345
346     connect(wordListWidget, SIGNAL(showTranslation(QList<Translation*>)),
347             this, SIGNAL(searchTranslations(QList<Translation*>)));
348
349
350     connect(this, SIGNAL(setBusy()),
351             wordListWidget, SLOT(lockList()));
352
353     connect(this, SIGNAL(setIdle()),
354             wordListWidget, SLOT(unlockList()));
355 }
356
357 void MainWindow::connectTranslationWidget() {
358     connect(this, SIGNAL(showTranslation(QStringList)),
359             translationWidget, SLOT(show(QStringList)));
360
361 }
362
363 void MainWindow::connectDictManager() {
364     connect(dictManagerWidget, SIGNAL(addDictionary(CommonDictInterface*)),
365             this, SIGNAL(addNewDictionary(CommonDictInterface*)));
366
367     connect(dictManagerWidget, SIGNAL(removeDictionary(CommonDictInterface*)),
368             this, SIGNAL(removeDictionary(CommonDictInterface*)));
369
370     connect(dictManagerWidget,
371             SIGNAL(selectedDictionaries(QList<CommonDictInterface*>)),
372             this, SIGNAL(selectedDictionaries(QList<CommonDictInterface*>)));
373 }
374
375 void MainWindow::connectMenu() {
376     connect(this, SIGNAL(setBusy()),
377             this, SLOT(disableMenu()));
378
379     connect(this, SIGNAL(setIdle()),
380             this, SLOT(enableMenu()));
381 }