Next fix of removing bookmarks
[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 || t->isBookmark()==0) {
147
148                 onlyBookmarks = false;
149                 t->setBookmark(0);
150             }
151             else {
152                 searchResult[item.data().toString()].removeAt(searchResult[item.data().toString()].indexOf(t));
153             }
154         }
155
156         if(onlyBookmarks) {
157             searchResult.remove(item.data().toString());
158             model->removeRow(item.row());
159         }
160     }
161 }
162
163
164 void WordListWidget::mouseReleaseEvent(QMouseEvent *event) {
165
166     //firstly we normally handle this event
167     QTreeView::mouseReleaseEvent(event);
168
169     //then we check at which item user clicked
170     QModelIndex index = indexAt(event->pos());
171     if(!index.isValid()) return;
172
173     /*if there are no selected items we return, that occurs sometimes
174     on maemo, when user is scrolling list and clicks to stop the scroll,
175     system doesn't select item but emits mouseReleaseEvent*/
176     if(selectedIndexes().count() == 0) return;
177
178     //if user doesn't click either on a word or on a star, return
179     if(selectedIndexes().at(0) != index && selectedIndexes().at(1) != index)
180         return;
181
182     int c = index.column();
183     if(c==0)
184         //if column is 0 user clicked on a word
185         wordClicked(index);
186     else
187         //else user clicked on a star
188         wordChecked(index);
189 }
190
191 void WordListWidget::resizeEvent(QResizeEvent *event) {
192     resizeColumns();
193     QTreeView::resizeEvent(event);
194 }
195
196 void WordListWidget::resizeColumns() {
197     setColumnWidth(0, viewport()->width() -checkBoxWidth - 5);
198     setColumnWidth(1, checkBoxWidth);
199 }
200
201 void WordListWidget::keyPressEvent(QKeyEvent *event) {
202     QTreeView::keyPressEvent(event);
203
204     if(event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) {
205         if(selectedIndexes().count() == 0) return;
206
207         wordClicked(selectedIndexes().at(0));
208     }
209 }
210
211 void WordListWidget::lockList() {
212     setEnabled(false);
213 }
214
215 void WordListWidget::unlockList() {
216     setEnabled(true);
217 }
218
219 void WordListWidget::clear() {
220     model->clear();
221
222     QHash<QString, QList<Translation*> >::iterator i;
223     for(i = searchResult.begin(); i != searchResult.end(); i++) {
224            Translation*t;
225            foreach(t, i.value()) {
226                delete t;
227            }
228     }
229     searchResult.clear();
230 }