Fixed bookmarks removing bug
[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     model->setColumnCount(2);
101     model->setRowCount(result.count());
102
103     int row=0;
104     QHash<QString, QList<Translation*> >::iterator i;
105     for(i = searchResult.begin(); i != searchResult.end(); i++) {
106            addWord(i.key(), row++);
107     }
108
109     model->sort(0);
110     resizeColumns();    
111
112     setFocus();
113 }
114
115 void WordListWidget::wordClicked(QModelIndex index) {
116     //we're getting translation based on data in index
117     Q_EMIT showTranslation(
118             searchResult[index.data().toString()]);
119 }
120
121 void WordListWidget::wordChecked(QModelIndex index) {
122
123     //save new item state
124     Qt::CheckState state =
125             Qt::CheckState(index.data(Qt::CheckStateRole).toInt());
126
127
128     //getting index of item which contains word which should be added/removed
129     //from bookmarks
130     QModelIndex item = selectedIndexes().at(0);
131     if(!item.isValid()) return;
132
133     //to shorten lag between clicking on a star and its change
134     repaint();
135
136     //depending on new state emit suitable signal
137     if(state == Qt::Checked) {
138         Q_EMIT addBookmark(searchResult[item.data().toString()]);
139     }
140     else {
141         Q_EMIT removeBookmark(searchResult[item.data().toString()]);
142
143         Translation* t;
144         bool onlyBookmarks = true;
145         foreach(t, searchResult[item.data().toString()]) {
146             if(t->isBookmark() == 1) {
147                 onlyBookmarks = false;
148                 t->setBookmark(0);
149             }
150         }
151
152         if(onlyBookmarks) {
153             searchResult.remove(item.data().toString());
154             model->removeRow(item.row());
155         }
156     }
157 }
158
159
160 void WordListWidget::mouseReleaseEvent(QMouseEvent *event) {
161
162     //firstly we normally handle this event
163     QTreeView::mouseReleaseEvent(event);
164
165     //then we check at which item user clicked
166     QModelIndex index = indexAt(event->pos());
167     if(!index.isValid()) return;
168
169     /*if there are no selected items we return, that occurs sometimes
170     on maemo, when user is scrolling list and clicks to stop the scroll,
171     system doesn't select item but emits mouseReleaseEvent*/
172     if(selectedIndexes().count() == 0) return;
173
174     //if user doesn't click either on a word or on a star, return
175     if(selectedIndexes().at(0) != index && selectedIndexes().at(1) != index)
176         return;
177
178     int c = index.column();
179     if(c==0)
180         //if column is 0 user clicked on a word
181         wordClicked(index);
182     else
183         //else user clicked on a star
184         wordChecked(index);
185 }
186
187 void WordListWidget::resizeEvent(QResizeEvent *event) {
188     resizeColumns();
189     QTreeView::resizeEvent(event);
190 }
191
192 void WordListWidget::resizeColumns() {
193     setColumnWidth(0, viewport()->width() -checkBoxWidth - 5);
194     setColumnWidth(1, checkBoxWidth);
195 }
196
197 void WordListWidget::keyPressEvent(QKeyEvent *event) {
198     QTreeView::keyPressEvent(event);
199
200     if(event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) {
201         if(selectedIndexes().count() == 0) return;
202
203         wordClicked(selectedIndexes().at(0));
204     }
205 }
206
207 void WordListWidget::lockList() {
208     setEnabled(false);
209 }
210
211 void WordListWidget::unlockList() {
212     setEnabled(true);
213 }
214
215 void WordListWidget::clear() {
216     model->clear();
217
218     QHash<QString, QList<Translation*> >::iterator i;
219     for(i = searchResult.begin(); i != searchResult.end(); i++) {
220            Translation*t;
221            foreach(t, i.value()) {
222                delete t;
223            }
224     }
225     searchResult.clear();
226 }