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