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