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