1 /*******************************************************************************
3 This file is part of mDictionary.
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.
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.
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/>.
18 Copyright 2010 Comarch S.A.
20 *******************************************************************************/
22 //! \file MainWindow.cpp
23 //! \author Mateusz Półrola <mateusz.polrola@comarch.pl>
25 #include "MainWindow.h"
28 #include <QMaemo5InformationBox>
32 MainWindow::MainWindow(Backbone *backbone, QWidget *parent):
33 GUIInterface(parent) {
35 this->backbone = backbone;
43 connectTranslationWidget();
46 connectBookmarksWidget();
48 setExactSearch(false);
50 setMinimumSize(750, 400);
54 searchBarWidget->setFocus();
57 MainWindow::~MainWindow() {
61 void MainWindow::initializeUI() {
64 setAttribute(Qt::WA_Maemo5StackedWindow);
68 /*translationWidget is another stacked window, so we don't add it to
69 layout, only create it with this widget as parent
70 it must be created as first object in main window, otherwise sometimes
71 when app starts in maemo, when trying to set stacked window attribute
73 translationWidget = new TranslationWidget(this);
78 setWindowIcon(QIcon(":/icons/64x64/mdictionary.png"));
79 setWindowTitle("mDictionary");
81 mainLayout = new QVBoxLayout();
82 QWidget* w = new QWidget();
83 w->setLayout(mainLayout);
86 menuBar = new QMenuBar();
89 notifyManager = new NotifyManager(this);
91 initializeSearchWidgets();
96 void MainWindow::initializeSearchWidgets() {
97 searchBarWidget = new SearchBarWidget();
99 wordListWidget = new WordListWidget();
101 welcomeScreenWidget = new WelcomeScreenWidget();
104 //At start we set widget as welcome screen widget
105 mainLayout->addWidget(welcomeScreenWidget);
106 mainLayout->addWidget(searchBarWidget, 0, Qt::AlignBottom);
108 translationWidget->hide();
109 //we add word list and welcome screen to splitter
110 splitter = new QSplitter(Qt::Horizontal);
111 splitter->addWidget(wordListWidget);
112 splitter->addWidget(welcomeScreenWidget);
113 splitter->setStretchFactor(1, 150);
115 mainLayout->addWidget(splitter, 1);
116 mainLayout->addWidget(searchBarWidget, 0, Qt::AlignBottom);
120 void MainWindow::initializeMenu() {
121 initializeMenuWidgets();
124 menuWidget = new MenuWidget(this);
126 menuWidget->addSubMenu(tr("Settings"), settingsWidget);
127 menuWidget->addSubMenu(tr("Dictionaries"), dictManagerWidget);
128 menuWidget->addSubMenu(tr("Bookmarks"), bookmarksWidget);
129 menuWidget->addSubMenu(tr("About"), aboutWidget);
131 menuBar->addAction(menuWidget);
133 connect(menuWidget, SIGNAL(setApplicationMenu(QWidget*)),
134 notifyManager, SLOT(setMenu(QWidget*)));
136 dictionariesAction = menuBar->addAction(tr("&Dictionaries"));
137 connect(dictionariesAction, SIGNAL(triggered()),
138 dictManagerWidget, SLOT(show()));
140 settingsAction = menuBar->addAction(tr("&Settings"));
141 connect(settingsAction, SIGNAL(triggered()),
142 settingsWidget, SLOT(show()));
144 QMenu* m = menuBar->addMenu(tr("&Bookmarks"));
145 bookmarksShowAllAction = new QAction(tr("Show all"), m);
147 bookmarksRemoveAllAction = new QAction(tr("Remove all"), m);
149 m->addAction(bookmarksShowAllAction);
150 m->addAction(bookmarksRemoveAllAction);
152 aboutAction = menuBar->addAction(tr("&About"));
153 connect(aboutAction, SIGNAL(triggered()),
154 aboutWidget, SLOT(show()));
159 void MainWindow::initializeMenuWidgets() {
160 dictManagerWidget = new DictManagerWidget(this);
161 dictManagerWidget->hide();
163 settingsWidget = new SettingsWidget(this);
164 settingsWidget->hide();
166 connect(settingsWidget, SIGNAL(notify(Notify::NotifyType,QString)),
167 this, SLOT(showNotification(Notify::NotifyType,QString)));
169 bookmarksWidget = new BookmarksWidget(this);
170 bookmarksWidget->hide();
172 aboutWidget = new AboutWidget(this);
176 void MainWindow::closeEvent(QCloseEvent *event) {
177 //request to stop all searches and close app
182 bool MainWindow::isInExactSearch() {
186 void MainWindow::setExactSearch(bool exact) {
187 _exactSearch = exact;
190 void MainWindow::setExactSearchString(QString word) {
194 void MainWindow::wordListReady() {
195 //gets results from backbone
196 QMultiHash<QString, Translation*> backboneResult = backbone->result();
197 QHash<QString, QList<Translation*> > searchResult;
203 //if nothing was found
204 if(backboneResult.count() == 0) {
205 showNotification(Notify::Info, tr("Can't find any matching words"));
207 //show empty list to remove results of old search
208 Q_EMIT showWordList(searchResult);
211 //find translations of the same key word
212 QMultiHash<QString, Translation*>::iterator i;
213 for(i = backboneResult.begin(); i != backboneResult.end(); i++) {
214 searchResult[i.key()].push_back(i.value());
217 //show search results
218 Q_EMIT showWordList(searchResult);
221 if(isInExactSearch()) {
222 QList<Translation*> exactTranslation;
223 if(checkExactSearch(searchResult, exactTranslation)) {
224 Q_EMIT searchTranslations(exactTranslation);
227 showNotification(Notify::Info,
228 tr("Can't find exactly matching word"));
231 setExactSearch(false);
236 bool MainWindow::checkExactSearch(
237 QHash<QString, QList<Translation *> > searchResult,
238 QList<Translation *> &found) {
240 bool foundExactMatch = false;
241 QHash<QString, QList<Translation*> >::iterator j;
242 for(j = searchResult.begin(); j != searchResult.end(); j++) {
243 if(j.key().toLower() == searchString.toLower()
244 && !foundExactMatch) {
252 void MainWindow::translationsReady() {
257 Q_EMIT showTranslation(backbone->htmls());
259 notifyManager->screenChanged();
264 void MainWindow::hideWelcomeScreen() {
266 //switch welcome screen with word list
267 if(!wordListWidget->isVisible()) {
268 mainLayout->removeWidget(welcomeScreenWidget);
269 welcomeScreenWidget->deleteLater();
271 mainLayout->insertWidget(0, wordListWidget);
274 //switch welcome screen with translation widget
275 if(!translationWidget->isVisible()) {
276 splitter->insertWidget(1,translationWidget);
277 splitter->setStretchFactor(1, 150);
278 welcomeScreenWidget->deleteLater();
283 QList<CommonDictInterface*> MainWindow::getPlugins() {
284 return backbone->getPlugins();
287 QHash<CommonDictInterface*, bool> MainWindow::getDictionaries() {
288 return backbone->getDictionaries();
292 void MainWindow::search(QString word) {
293 setExactSearch(false);
294 searchBarWidget->search(word);
297 void MainWindow::searchExact(QString word) {
298 setExactSearch(true);
299 searchBarWidget->search(word);
302 void MainWindow::searchDelay(QString word) {
303 searchBarWidget->searchDelay(word);
310 void MainWindow::searchingInterrupted() {
311 //make sure to unset exact search mode
312 setExactSearch(false);
315 void MainWindow::addToHistory(QList<Translation *> trans) {
316 if(trans.count() > 0) {
317 backbone->history()->add(trans[0]->key());
321 void MainWindow::historyNext() {
322 if(backbone->history()->nextAvailable()) {
323 QString next = backbone->history()->next();
325 setExactSearch(true);
331 void MainWindow::historyPrev() {
332 if(backbone->history()->prevAvailable()) {
334 setExactSearch(true);
336 QString prev = backbone->history()->previous();
341 void MainWindow::disableMenu() {
343 if(menuBar->actions().contains(menuWidget)) {
344 menuBar->removeAction(menuWidget);
347 menuBar->setEnabled(false);
351 void MainWindow::enableMenu() {
353 if(!menuBar->actions().contains(menuWidget)) {
354 menuBar->addAction(menuWidget);
357 menuBar->setEnabled(true);
361 void MainWindow::showHistory(QPoint p) {
363 HistoryListDialog historyDialog(backbone->history()->list(), searchBarWidget);
366 QPoint newPos = mapFromGlobal(p);
367 newPos.setY(searchBarWidget->pos().y() -
368 historyDialog.sizeHint().height());
369 newPos.setX(width() - historyDialog.sizeHint().width());
371 historyDialog.move(newPos);
374 if(historyDialog.exec() == QDialog::Accepted) {
375 backbone->history()->setCurrentElement(historyDialog.selectedRow());
376 searchExact(historyDialog.selectedWord());
380 void MainWindow::setSettings(Settings *s) {
381 backbone->setSettings(s);
384 Settings* MainWindow::settings() {
385 return backbone->settings();
389 void MainWindow::showNotification(Notify::NotifyType type, QString text) {
390 notifyManager->showNotification(type, text);
393 void MainWindow::connectBackbone() {
395 connect(this, SIGNAL(searchWordList(QString)),
396 this, SIGNAL(setBusy()));
398 connect(this, SIGNAL(searchTranslations(QList<Translation*>)),
399 this, SIGNAL(setBusy()));
401 connect(this, SIGNAL(stopSearching()),
402 this, SIGNAL(setIdle()));
404 connect(this, SIGNAL(searchWordList(QString)),
405 this, SLOT(setExactSearchString(QString)));
407 connect(this, SIGNAL(searchTranslations(QList<Translation*>)),
408 this, SLOT(addToHistory(QList<Translation*>)));
412 connect(this, SIGNAL(quit()),
413 backbone, SLOT(quit()));
415 connect(this, SIGNAL(searchWordList(QString)),
416 backbone, SLOT(search(QString)));
418 connect(this, SIGNAL(searchTranslations(QList<Translation*>)),
419 backbone, SLOT(searchHtml(QList<Translation*>)));
421 connect(this, SIGNAL(stopSearching()),
422 backbone, SLOT(stopSearching()));
424 connect(this, SIGNAL(stopSearching()),
425 this, SLOT(searchingInterrupted()));
427 connect(this, SIGNAL(addNewDictionary(CommonDictInterface*)),
428 backbone, SLOT(addDictionary(CommonDictInterface*)));
430 connect(this, SIGNAL(removeDictionary(CommonDictInterface*)),
431 backbone, SLOT(removeDictionary(CommonDictInterface*)));
433 connect(this, SIGNAL(selectedDictionaries(QList<CommonDictInterface*>)),
434 backbone, SLOT(selectedDictionaries(QList<CommonDictInterface*>)));
437 connect(backbone, SIGNAL(ready()),
438 this, SIGNAL(setIdle()));
440 connect(backbone, SIGNAL(htmlReady()),
441 this, SIGNAL(setIdle()));
444 connect(backbone, SIGNAL(ready()),
445 this, SLOT(wordListReady()));
447 connect(backbone, SIGNAL(htmlReady()),
448 this, SLOT(translationsReady()));
450 connect(backbone, SIGNAL(searchCanceled()),
451 this, SIGNAL(setIdle()));
453 connect(backbone, SIGNAL(notify(Notify::NotifyType,QString)),
454 this, SLOT(showNotification(Notify::NotifyType,QString)));
456 connect(backbone, SIGNAL(closeOk()),
457 this, SLOT(close()));
460 void MainWindow::connectSearchBar() {
461 connect(searchBarWidget, SIGNAL(searchForTranslations(QString)),
462 this, SIGNAL(searchWordList(QString)));
464 connect(searchBarWidget, SIGNAL(stopSearching()),
465 this, SIGNAL(stopSearching()));
467 connect(this, SIGNAL(setBusy()),
468 searchBarWidget, SLOT(setBusy()));
470 connect(this, SIGNAL(setIdle()),
471 searchBarWidget, SLOT(setIdle()));
473 connect(searchBarWidget, SIGNAL(historyNext()),
474 this, SLOT(historyNext()));
476 connect(searchBarWidget, SIGNAL(historyPrev()),
477 this, SLOT(historyPrev()));
479 connect(searchBarWidget, SIGNAL(historyShow(QPoint)),
480 this, SLOT(showHistory(QPoint)));
482 connect(searchBarWidget, SIGNAL(refreshHistoryButtons()),
483 backbone->history(), SLOT(refreshStatus()));
485 connect(backbone->history(), SIGNAL(historyChanged(bool,bool,bool)),
486 searchBarWidget, SLOT(updateHistoryButtons(bool,bool,bool)));
489 void MainWindow::connectWordList() {
491 SIGNAL(showWordList(QHash<QString, QList<Translation*> >)),
493 SLOT(showSearchResults(QHash<QString,QList<Translation*> >)));
495 connect(wordListWidget, SIGNAL(showTranslation(QList<Translation*>)),
496 this, SIGNAL(searchTranslations(QList<Translation*>)));
501 connect(this, SIGNAL(setBusy()),
502 wordListWidget, SLOT(lockList()));
504 connect(this, SIGNAL(setIdle()),
505 wordListWidget, SLOT(unlockList()));
507 connect(wordListWidget, SIGNAL(addBookmark(QList<Translation*>)),
508 backbone, SLOT(addBookmark(QList<Translation*>)));
510 connect(wordListWidget, SIGNAL(removeBookmark(QList<Translation*>)),
511 backbone, SLOT(removeBookmark(QList<Translation*>)));
514 void MainWindow::connectTranslationWidget() {
515 connect(this, SIGNAL(showTranslation(QStringList)),
516 translationWidget, SLOT(show(QStringList)));
519 connect(translationWidget, SIGNAL(search(QString)),
520 this, SLOT(search(QString)));
522 connect(translationWidget, SIGNAL(search(QString)),
523 this, SLOT(searchExact(QString)));
529 void MainWindow::connectDictManager() {
530 connect(dictManagerWidget, SIGNAL(addDictionary(CommonDictInterface*)),
531 this, SIGNAL(addNewDictionary(CommonDictInterface*)));
533 connect(dictManagerWidget, SIGNAL(removeDictionary(CommonDictInterface*)),
534 this, SIGNAL(removeDictionary(CommonDictInterface*)));
536 connect(dictManagerWidget,
537 SIGNAL(selectedDictionaries(QList<CommonDictInterface*>)),
538 this, SIGNAL(selectedDictionaries(QList<CommonDictInterface*>)));
541 void MainWindow::connectMenu() {
542 connect(this, SIGNAL(setBusy()),
543 this, SLOT(disableMenu()));
545 connect(this, SIGNAL(setIdle()),
546 this, SLOT(enableMenu()));
550 void MainWindow::connectBookmarksWidget() {
552 //after removing bookmarks we search for them once again to clear the words list
553 connect(bookmarksWidget, SIGNAL(removeAllBookmarks()),
554 this, SLOT(removeBookmarks()));
557 connect(bookmarksWidget, SIGNAL(showAllBookmarks()),
558 menuWidget, SLOT(hideMenu()));
560 connect(bookmarksWidget, SIGNAL(showAllBookmarks()),
561 backbone, SLOT(fetchBookmarks()));
565 connect(bookmarksRemoveAllAction, SIGNAL(triggered()),
566 this, SLOT(removeBookmarks()));
567 connect(bookmarksShowAllAction, SIGNAL(triggered()),
568 backbone, SLOT(fetchBookmarks()));
574 void MainWindow::removeBookmarks() {
577 par = bookmarksWidget;
581 if(QMessageBox::question(par, tr("Delete all bookmarks"),
582 tr("Do you want to delete all bookmarks? (This action cannot be revoked, and will clear current word list)"),
583 QMessageBox::Yes, QMessageBox::Cancel) == QMessageBox::Yes) {
584 backbone->removeAllBookmarks();
585 ((WordListWidget*)wordListWidget)->clear();