Clean and order documentation in source files. Source ready to beta 2 release
[mdictionary] / src / mdictionary / gui / WordListWidget.cpp
1
2 /*******************************************************************************
3
4     This file is part of mDictionary.
5
6     mDictionary is free software: you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation, either version 3 of the License, or
9     (at your option) any later version.
10
11     mDictionary is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with mDictionary.  If not, see <http://www.gnu.org/licenses/>.
18
19     Copyright 2010 Comarch S.A.
20
21 *******************************************************************************/
22
23 /*! \file WordListwidget.cpp
24     \brief Displays list of words found in dictionaries
25
26     \author Mateusz Półrola <mateusz.polrola@comarch.pl>
27 */
28
29 #include "WordListWidget.h"
30 #include "WordListProxyStyle.h"
31 #include "../../include/translation.h"
32 #include <QKeyEvent>
33
34
35 WordListWidget::WordListWidget(QWidget *parent):
36     QTreeView(parent) {
37
38     //creating new model to store words and stars
39     model = new QStandardItemModel(this);
40     setModel(model);
41     setHeaderHidden(true);
42     setRootIsDecorated(false);
43     setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
44
45     //set our custom style to draw checkboxes as stars
46     proxyStyle = new WordListProxyStyle();
47     setStyle(proxyStyle);
48
49     //setting size of star in pixels, on maemo checboxes are much bigger
50     #ifdef Q_WS_MAEMO_5
51         checkBoxWidth = 70;
52     #else
53         checkBoxWidth = 25;
54     #endif
55 }
56
57
58 WordListWidget::~WordListWidget() {
59     if(proxyStyle)
60         delete proxyStyle;
61 }
62
63 void WordListWidget::addWord(QString word, int row) {
64     QStandardItem* item = new QStandardItem(word);
65
66     //we don't want to allow user to edit word
67     item->setFlags(item->flags() ^ Qt::ItemIsEditable);
68
69     QStandardItem* itemCheckBox = new QStandardItem();
70     //creating checkbox item
71     itemCheckBox->setFlags((itemCheckBox->flags() ^ Qt::ItemIsEditable) |
72                            Qt::ItemIsUserCheckable);
73
74     /*checking if word is already in bookmarks, information about that is
75     stored in its translation object (not all translations have to be in
76     bookmarks)*/
77     bool bookmark = false;
78     Translation* t;
79     foreach(t, searchResult[word]) {
80         if(t->isBookmark()) {
81             bookmark = true;
82             break;
83         }
84     }
85
86     if(bookmark)
87         itemCheckBox->setCheckState(Qt::Checked);
88     else
89         itemCheckBox->setCheckState(Qt::Unchecked);
90
91     //add item to model
92     model->setItem(row,0, item);
93     model->setItem(row,1, itemCheckBox);
94 }
95
96
97 void WordListWidget::showSearchResults(
98         QHash<QString, QList<Translation *> > result) {
99
100     clear();
101     searchResult = result;
102
103     if(searchResult.count()>0) {
104         setEnabled(true);
105         model->setColumnCount(2);
106         model->setRowCount(result.count());
107
108         int row=0;
109         QHash<QString, QList<Translation*> >::iterator i;
110         for(i = searchResult.begin(); i != searchResult.end(); i++) {
111                addWord(i.key(), row++);
112         }
113
114         model->sort(0);
115         resizeColumns();
116     }
117     else {
118         QStandardItem* item = new QStandardItem(tr("Can't find any matching words"));
119         item->setFlags(item->flags() ^ Qt::ItemIsEditable);
120         item->setTextAlignment(Qt::AlignCenter);
121         setEnabled(false);
122
123         model->setItem(0,item);
124     }
125
126     setFocus();
127 }
128
129 void WordListWidget::wordClicked(QModelIndex index) {
130     //we're getting translation based on data in index
131     Q_EMIT showTranslation(
132             searchResult[index.data().toString()]);
133 }
134
135 void WordListWidget::wordChecked(QModelIndex index) {
136
137     //save new item state
138     Qt::CheckState state =
139             Qt::CheckState(index.data(Qt::CheckStateRole).toInt());
140
141
142     //getting index of item which contains word which should be added/removed
143     //from bookmarks
144     QModelIndex item = selectedIndexes().at(0);
145     if(!item.isValid()) return;
146
147     //to shorten lag between clicking on a star and its change
148     repaint();
149
150     //depending on new state emit suitable signal
151     if(state == Qt::Checked) {
152         Q_EMIT addBookmark(searchResult[item.data().toString()]);
153     }
154     else {
155         Q_EMIT removeBookmark(searchResult[item.data().toString()]);
156
157         Translation* t;
158         bool onlyBookmarks = true;
159         foreach(t, searchResult[item.data().toString()]) {
160             if(t->isBookmark() == 1 || t->isBookmark()==0) {
161
162                 onlyBookmarks = false;
163                 t->setBookmark(0);
164             }
165             else {
166                 searchResult[item.data().toString()].removeAt(searchResult[item.data().toString()].indexOf(t));
167             }
168         }
169
170         if(onlyBookmarks) {
171             searchResult.remove(item.data().toString());
172             model->removeRow(item.row());
173         }
174     }
175 }
176
177
178 void WordListWidget::mouseReleaseEvent(QMouseEvent *event) {
179
180     //firstly we normally handle this event
181     QTreeView::mouseReleaseEvent(event);
182
183     //then we check at which item user clicked
184     QModelIndex index = indexAt(event->pos());
185     if(!index.isValid()) return;
186
187     /*if there are no selected items we return, that occurs sometimes
188     on maemo, when user is scrolling list and clicks to stop the scroll,
189     system doesn't select item but emits mouseReleaseEvent*/
190     if(selectedIndexes().count() == 0) return;
191
192     //if user doesn't click either on a word or on a star, return
193     if(selectedIndexes().at(0) != index && selectedIndexes().at(1) != index)
194         return;
195
196     int c = index.column();
197     if(c==0)
198         //if column is 0 user clicked on a word
199         wordClicked(index);
200     else
201         //else user clicked on a star
202         wordChecked(index);
203 }
204
205 void WordListWidget::resizeEvent(QResizeEvent *event) {
206     resizeColumns();
207     QTreeView::resizeEvent(event);
208 }
209
210 void WordListWidget::resizeColumns() {
211     setColumnWidth(0, viewport()->width() -checkBoxWidth - 5);
212     setColumnWidth(1, checkBoxWidth);
213 }
214
215 void WordListWidget::keyPressEvent(QKeyEvent *event) {
216     QTreeView::keyPressEvent(event);
217
218     if(event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) {
219         if(selectedIndexes().count() == 0) return;
220
221         wordClicked(selectedIndexes().at(0));
222     }
223 }
224
225 void WordListWidget::lockList() {
226     setEnabled(false);
227 }
228
229 void WordListWidget::unlockList() {
230     setEnabled(true);
231 }
232
233 void WordListWidget::clear() {
234     model->clear();
235
236     QHash<QString, QList<Translation*> >::iterator i;
237     for(i = searchResult.begin(); i != searchResult.end(); i++) {
238            Translation*t;
239            foreach(t, i.value()) {
240                delete t;
241            }
242     }
243     searchResult.clear();
244 }