7e9e16de2b89a641b42bceeda984dbad269baf2b
[mdictionary] / src / mdictionary / gui / SearchBarWidget.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 /*! \file SearchBarWidget.cpp
23     \brief Displays search bar
24
25     \author Mateusz Półrola <mateusz.polrola@comarch.pl>
26 */
27
28
29 #include "SearchBarWidget.h"
30 #include <QDebug>
31 #include "../../include/DictDialog.h"
32 #include "HistoryListDialog.h"
33
34
35 SearchBarWidget::SearchBarWidget(QWidget *parent) : QWidget(parent) {
36
37     completerModel = new QStringList;
38     lineEditCompleter = new QCompleter(this);
39     lineEditCompleter->setModel(new QStringListModel(*completerModel));
40     lineEditCompleter->setCaseSensitivity(Qt::CaseInsensitive);
41     lineEditCompleter->setCompletionMode(QCompleter::InlineCompletion);
42
43 #ifndef Q_WS_MAEMO_5
44     this->setMaximumHeight(50);
45     busyTimer=new QTimer;
46
47     progressBar = new QDeclarativeView();
48     progressBar->setSource(QUrl::fromLocalFile("/usr/share/mdictionary/qml/ProgressBar.qml"));
49     progressBar->setResizeMode(QDeclarativeView::SizeRootObjectToView);
50     progressBar->setAlignment(Qt::AlignCenter);
51     progressBar->hide();
52
53     view= new QDeclarativeView();
54     ctxt = view->rootContext();
55     ctxt->setContextProperty("focusss",true);
56
57     view->setSource(QUrl::fromLocalFile("/usr/share/mdictionary/qml/SearchBarWidget.qml"));
58     view->setResizeMode(QDeclarativeView::SizeRootObjectToView);
59     view->setAlignment(Qt::AlignCenter);
60     view->show();
61
62     mainLayout = new QVBoxLayout;
63     mainLayout->addWidget(progressBar);
64     mainLayout->addWidget(view);
65     setLayout(mainLayout);
66
67     QGraphicsObject *rootObject = view->rootObject();
68     QGraphicsObject *rootObject2 = progressBar->rootObject();
69
70     connect(rootObject, SIGNAL(searchButtonClicked(QString)),
71             this, SLOT(searchButtonClicked(QString)));
72     connect(rootObject, SIGNAL(historyNextToolButtonClicked()),
73             this, SIGNAL(historyNext()));
74     connect(rootObject, SIGNAL(historyPrevToolButtonClicked()),
75             this, SIGNAL(historyPrev()));
76     connect(rootObject, SIGNAL(historyShowToolButtonClicked()),
77             this, SLOT(showHistoryButtonClicked()));
78     connect(rootObject, SIGNAL(textChange(QString)),
79             this, SLOT(textChange(QString)));
80     connect(rootObject, SIGNAL(nextCompleter()),
81             this, SLOT(nextCompleter()));
82     connect(rootObject, SIGNAL(prevCompleter()),
83             this, SLOT(prevCompleter()));
84     connect(rootObject, SIGNAL(checkFocus()),
85             this, SLOT(checkFocus()));
86     connect(rootObject, SIGNAL(nextFocus()),
87             this, SLOT(nextFocus()));
88
89     connect(this, SIGNAL(progresSetMax(QVariant)),
90             rootObject2, SLOT(setMax(QVariant)));
91     connect(this, SIGNAL(progresSetMin(QVariant)),
92             rootObject2, SLOT(setMin(QVariant)));
93     connect(this, SIGNAL(progresSetValue(QVariant)),
94             rootObject2, SLOT(setValue(QVariant)));
95     connect(this, SIGNAL(progresSetValue2(QVariant)),
96             rootObject2, SLOT(setValue2(QVariant)));
97
98     connect(this, SIGNAL(setEnableHistoryNext(QVariant)),
99             rootObject, SLOT(setEnableHistoryNext(QVariant)));
100     connect(this, SIGNAL(setEnableHistoryShow(QVariant)),
101             rootObject, SLOT(setEnableHistoryShow(QVariant)));
102     connect(this, SIGNAL(setEnableHistoryPrev(QVariant)),
103             rootObject, SLOT(setEnableHistoryPrev(QVariant)));
104     connect(this, SIGNAL(setButtonText(QVariant)),
105             rootObject, SLOT(setButtonText(QVariant)));
106     connect(this, SIGNAL(setLineEditText(QVariant)),
107             rootObject, SLOT(setLineEditText(QVariant)));
108     connect(this, SIGNAL(setLineEditEnables(QVariant)),
109             rootObject, SLOT(setEnableLineEdit(QVariant)));
110
111     connect(this, SIGNAL(setCompleterText(QVariant)),
112             rootObject, SLOT(setCompleterText(QVariant)));
113     connect(this, SIGNAL(focusOff()),
114             rootObject, SLOT(focusOff()));
115
116     connect(busyTimer, SIGNAL(timeout()),
117             this, SLOT(updateBusyTimer()));
118
119     emit setEnableHistoryNext(false);
120     emit setEnableHistoryShow(false);
121     emit setEnableHistoryPrev(false);
122
123     connect(&delayTimer, SIGNAL(timeout()),
124             this, SLOT(delaySearchTimeout()));
125
126 #else
127     initializeUI();
128     connect(searchPushButton, SIGNAL(clicked()),
129             this, SLOT(searchPushButtonClicked()));
130     connect(searchWordLineEdit, SIGNAL(returnPressed()),
131             this, SLOT(searchPushButtonClicked()));
132     connect(historyNextToolButton, SIGNAL(clicked()),
133             this, SIGNAL(historyNext()));
134     connect(historyPrevToolButton, SIGNAL(clicked()),
135             this, SIGNAL(historyPrev()));
136     connect(historyShowToolButton, SIGNAL(clicked()),
137             this, SLOT(showHistoryButtonClicked()));
138     connect(clearSearchWordToolButton, SIGNAL(clicked()),
139             this, SLOT(clearSearchWordToolButtonClicked()));
140     connect(&delayTimer, SIGNAL(timeout()),
141             this, SLOT(delaySearchTimeout()));
142
143     searchWordLineEdit->setFocus();
144 #endif
145     setFocus();
146     busy = false;
147     setEnabled(true);
148     updateHistoryButtons(false,false,false);
149 }
150
151 SearchBarWidget::~SearchBarWidget() {
152
153 }
154
155 void SearchBarWidget::checkFocus(){
156     if(focusWidget()!=QApplication::focusWidget())
157         emit focusOff();
158 }
159
160 void SearchBarWidget::nextFocus(){
161     parentWidget()->nextInFocusChain()->setFocus();
162 }
163
164 void SearchBarWidget::textChange(QString text){
165     QLineEdit line;
166     QString toSend="";
167     QString tempString;
168     actualString=text;
169     completerActualList.clear();
170
171     line.setCompleter(lineEditCompleter);
172     line.completer()->setCompletionPrefix(text);
173     for (int i = 0; lineEditCompleter->setCurrentRow(i); i++)
174         completerActualList.append(lineEditCompleter->currentCompletion());
175
176     completerActualList.sort();
177     if(completerActualList.contains(preferedCompliter)){
178         tempString = preferedCompliter;
179         toSend = tempString.remove(0,text.size());
180         emit setCompleterText(toSend);
181     }
182     else if(completerActualList.size()>0 && text.size()>0){
183         toSend = completerActualList.at(0);
184         preferedCompliter= toSend;
185         toSend=toSend.remove(0,text.size());
186         if(toSend.size()>0)
187             emit setCompleterText(toSend);
188         else if(completerActualList.size()>1){
189             toSend = completerActualList.at(1);
190             preferedCompliter= toSend;
191             toSend=toSend.remove(0,text.size());
192             emit setCompleterText(toSend);
193         }
194     }
195     else{
196         preferedCompliter="";
197         emit setCompleterText(toSend);
198     }
199 }
200
201 void SearchBarWidget::prevCompleter(){
202     QString tempString;
203     if(!preferedCompliter.isEmpty()){
204         int index = completerActualList.indexOf(preferedCompliter);
205         if(index!=-1 && completerActualList.size()>index+1){
206             preferedCompliter = completerActualList.at(index+1);
207             tempString=preferedCompliter;
208             QString toSend = tempString.remove(0,actualString.size());
209             emit setCompleterText(toSend);
210         }
211     }
212 }
213
214 void SearchBarWidget::nextCompleter(){
215     QString tempString;
216     if(!preferedCompliter.isEmpty()){
217         int index = completerActualList.indexOf(preferedCompliter);
218         if(index>0){
219             preferedCompliter = completerActualList.at(index-1);
220             tempString=preferedCompliter;
221             QString toSend = tempString.remove(0,actualString.size());
222             emit setCompleterText(toSend);
223         }
224     }
225 }
226
227
228 QIcon SearchBarWidget::generateIcon(QIcon original, qreal rotation) {
229     QPixmap p = original.pixmap(64);
230
231     if(rotation != 0) {
232         QMatrix m;
233         m.rotate(rotation);
234
235         p = p.transformed(m);
236     }
237
238     QIcon newIcon;
239     newIcon.addPixmap(p);
240
241
242     #ifdef Q_WS_MAEMO_5
243         QImage img = p.toImage();
244
245         for(int i=0; i < img.width(); i++) {
246             for(int j=0; j < img.height(); j++) {
247                 QColor c = img.pixel(i,j);
248                 if(c != QColor(0,0,0,255)) {
249                     c.setRed(c.red()/2);
250                     c.setGreen(c.green()/2);
251                     c.setBlue(c.blue()/2);
252                     img.setPixel(i, j, c.rgb());
253                 }
254             }
255         }
256         p = p.fromImage(img);
257
258         newIcon.addPixmap(p, QIcon::Disabled, QIcon::Off);
259     #endif
260
261     return newIcon;
262 }
263
264 void SearchBarWidget::setFocus() {
265 #ifndef Q_WS_MAEMO_5
266         view->setFocus();
267 #else
268         searchWordLineEdit->setFocus();
269 #endif
270 }
271
272 void SearchBarWidget::initializeUI() {
273 #ifdef Q_WS_MAEMO_5
274     setMaximumHeight(150);
275
276     horizontalLayout = new QHBoxLayout;
277     verticalLayout = new QVBoxLayout;
278
279     searchPushButton = new QPushButton(tr("Search"));
280     searchPushButton->setMinimumWidth(125);
281
282     searchWordLineEdit = new QLineEdit;
283     searchWordLineEdit->setMinimumWidth(250);
284
285     searchWordLineEdit->setCompleter(lineEditCompleter);
286
287     #ifndef Q_WS_MAEMO_5
288         searchWordLineEdit->setMinimumHeight(
289                 searchWordLineEdit->sizeHint().height()*3/2);
290     #endif
291
292     //create layout for lineEdit to have clear button on it
293     QHBoxLayout* lineEditLayout = new QHBoxLayout;
294     searchWordLineEdit->setLayout(lineEditLayout);
295
296
297     clearSearchWordToolButton = new QToolButton;
298     #ifdef Q_WS_MAEMO_5
299         clearSearchWordToolButton->setIcon(QIcon::fromTheme("general_stop"));
300         clearSearchWordToolButton->setMaximumSize(
301                 clearSearchWordToolButton->sizeHint().height()/2,
302                 clearSearchWordToolButton->sizeHint().height()/2);
303         lineEditLayout->setContentsMargins(0,0,15,0);
304     #else
305         clearSearchWordToolButton->setIcon(QIcon::fromTheme("edit-clear"));
306         clearSearchWordToolButton->setMinimumSize(
307                 searchWordLineEdit->sizeHint().height()*1.2,
308                 searchWordLineEdit->sizeHint().height()*1.2);
309         lineEditLayout->setContentsMargins(0,0,5,0);
310     #endif
311
312
313     historyNextToolButton = new QToolButton;
314     #ifdef Q_WS_MAEMO_5
315         historyNextToolButton->setIcon(
316                 generateIcon(QIcon::fromTheme("general_forward")));
317     #else
318         historyNextToolButton->setIcon(
319                 generateIcon(QIcon::fromTheme("go-next")));
320     #endif
321
322
323
324     historyPrevToolButton = new QToolButton;
325     #ifdef Q_WS_MAEMO_5
326         historyPrevToolButton->setIcon(
327                 generateIcon(QIcon::fromTheme("general_back")));
328     #else
329         historyPrevToolButton->setIcon(
330                 generateIcon(QIcon::fromTheme("go-previous")));
331     #endif
332
333
334
335     historyShowToolButton = new QToolButton;
336     #ifdef Q_WS_MAEMO_5
337         historyShowToolButton->setIcon(
338                 generateIcon(QIcon::fromTheme("general_back"), 90));
339     #else
340         historyShowToolButton->setIcon(
341                 generateIcon(QIcon::fromTheme("go-up")));
342     #endif
343
344     searchingProgressBar = new QProgressBar;
345     //progress bar has minimum and maximum values set to 0, which will effect
346     //with "I'm alive" bar
347     searchingProgressBar->setMinimum(0);
348     searchingProgressBar->setMaximum(0);
349     #ifdef Q_WS_MAEMO_5
350         searchingProgressBar->setMaximumHeight(50);
351     #endif
352     searchingProgressBar->hide();
353
354     setLayout(verticalLayout);
355
356     verticalLayout->addWidget(searchingProgressBar);
357
358     //adding widgets to layout
359     horizontalLayout->addWidget(searchWordLineEdit);
360     horizontalLayout->addWidget(searchPushButton);
361     horizontalLayout->addWidget(historyPrevToolButton);
362     horizontalLayout->addWidget(historyShowToolButton);
363     horizontalLayout->addWidget(historyNextToolButton);
364
365     //adding clear toolButton to textEdit with right alignment
366     lineEditLayout->addWidget(clearSearchWordToolButton, 0, Qt::AlignRight);
367
368     verticalLayout->addLayout(horizontalLayout);
369 #endif
370 }
371
372 void SearchBarWidget::searchButtonClicked(QString text) {
373     if(busy)
374         Q_EMIT stopSearching();
375     else
376         search(text);
377 }
378
379 void SearchBarWidget::searchPushButtonClicked() {
380 #ifdef Q_WS_MAEMO_5
381     if(busy) {
382         Q_EMIT stopSearching();
383     }
384     else {
385         search(searchWordLineEdit->text());
386     }
387 #endif
388 }
389
390 void SearchBarWidget::search(QString word) {
391     if(!busy && !word.isEmpty()) {
392         while(word.lastIndexOf(" ")==word.size()-1 && word.size()>0)
393             word=word.remove(word.size()-1,1);
394         if(!completerModel->contains(word))
395             completerModel->append(word);
396         QAbstractItemModel *temp=lineEditCompleter->model();
397         lineEditCompleter->setModel(new QStringListModel(*completerModel));
398         delete temp;
399 #ifndef Q_WS_MAEMO_5
400         emit setLineEditText(word);
401 #else
402         searchWordLineEdit->setText(word);
403 #endif
404         Q_EMIT searchForTranslations(word);
405     }
406 }
407
408 void SearchBarWidget::searchDelay(QString word) {
409     if(!busy && !word.isEmpty()) {
410         #ifndef Q_WS_MAEMO_5
411             emit setLineEditText(word);
412         #else
413             searchWordLineEdit->setText(word);
414         #endif
415             if(delayTimer.isActive())
416                 delayTimer.stop();
417             delayString = word;
418             delayTimer.start(500);
419
420     }
421 }
422
423 void SearchBarWidget::delaySearchTimeout() {
424     delayTimer.stop();
425     if(!busy) {
426         Q_EMIT searchForTranslations(delayString);
427     }
428 }
429
430 void SearchBarWidget::setEnabled(bool enabled) {
431 #ifndef Q_WS_MAEMO_5
432     emit setLineEditEnables(enabled);
433     if(!enabled) {
434         emit setEnableHistoryNext(false);
435         emit setEnableHistoryShow(false);
436         emit setEnableHistoryPrev(false);
437     }
438 #else
439     searchWordLineEdit->setEnabled(enabled);
440     if(!enabled) {
441         historyPrevToolButton->setEnabled(false);
442         historyNextToolButton->setEnabled(false);
443         historyShowToolButton->setEnabled(false);
444     }
445 #endif
446 }
447
448 void SearchBarWidget::setBusy() {
449     if(busy) return;
450
451 #ifndef Q_WS_MAEMO_5
452     busyTimer->start(50);
453     emit setButtonText(tr("Stop"));
454     this->setMaximumHeight(88);
455     progressBar->show();
456     emit progresSetMax(100);
457     emit progresSetMin(0);
458     emit progresSetValue(-1);
459     emit progresSetValue2(100);
460     progressMax=true;
461 #else
462     searchingProgressBar->show();
463     searchPushButton->setText(tr("Stop"));
464 #endif
465
466     setEnabled(false);
467     busy = true;
468 }
469
470 void SearchBarWidget::updateBusyTimer(){
471     if(progressMax==true){
472         emit progresSetValue2(0);
473         progressMax=false;
474     }
475     else{
476         emit progresSetValue2(100);
477         progressMax=true;
478     }
479     busyTimer->start(50);
480 }
481
482 void SearchBarWidget::setIdle() {
483     if(!busy) return;
484 #ifndef Q_WS_MAEMO_5
485     progressBar->hide();
486     busyTimer->stop();
487     emit progresSetValue2(0);
488     this->setMaximumHeight(50);
489     emit setButtonText(tr("Search"));
490 #else
491     searchingProgressBar->hide();
492     searchPushButton->setText(tr("Search"));
493 #endif
494     setEnabled(true);
495     busy = false;
496     Q_EMIT refreshHistoryButtons();
497 }
498
499
500 void SearchBarWidget::clearSearchWordToolButtonClicked() {
501 #ifdef Q_WS_MAEMO_5
502     searchWordLineEdit->clear();
503 #endif
504 }
505
506
507
508 void SearchBarWidget::updateHistoryButtons(bool prev, bool next, bool list) {
509     if(!busy) {
510         #ifndef Q_WS_MAEMO_5
511             emit setEnableHistoryNext(next);
512             emit setEnableHistoryShow(list);
513             emit setEnableHistoryPrev(prev);
514         #else
515             historyPrevToolButton->setEnabled(prev);
516             historyNextToolButton->setEnabled(next);
517             historyShowToolButton->setEnabled(list);
518         #endif
519     }
520 }
521
522 void SearchBarWidget::showHistoryButtonClicked() {
523 #ifndef Q_WS_MAEMO_5
524     QPoint p=view->pos(); // = historyShowToolButton->pos();
525     p=mapToGlobal(p);
526     p.setX(p.x()+view->width());
527     emit historyShow(p);
528 #else
529     emit historyShow();
530 #endif
531 }