1 | /* |
2 | Copyright (c) 2009 Stephen Kelly <steveire@gmail.com> |
3 | |
4 | This library is free software; you can redistribute it and/or modify it |
5 | under the terms of the GNU Library General Public License as published by |
6 | the Free Software Foundation; either version 2 of the License, or (at your |
7 | option) any later version. |
8 | |
9 | This library is distributed in the hope that it will be useful, but WITHOUT |
10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
11 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public |
12 | License for more details. |
13 | |
14 | You should have received a copy of the GNU Library General Public License |
15 | along with this library; see the file COPYING.LIB. If not, write to the |
16 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
17 | 02110-1301, USA. |
18 | */ |
19 | |
20 | |
21 | #include "amazingcompleter.h" |
22 | |
23 | #include <kselectionproxymodel.h> |
24 | #include <qlistview.h> |
25 | |
26 | #include <kdebug.h> |
27 | |
28 | using namespace Akonadi; |
29 | |
30 | class Akonadi::AmazingCompleterPrivate |
31 | { |
32 | public: |
33 | AmazingCompleterPrivate(AmazingCompleter *completer) //, QAbstractItemModel *model) |
34 | : m_matchingRole(Qt::DisplayRole), |
35 | m_completionRole(Qt::DisplayRole), |
36 | m_minumumLength(3), |
37 | q_ptr(completer) |
38 | { |
39 | |
40 | } |
41 | |
42 | QAbstractItemModel *m_model; |
43 | KSelectionProxyModel *m_selectionProxyModel; |
44 | QItemSelectionModel *m_itemSelectionModel; |
45 | QAbstractItemView *m_view; |
46 | QWidget *m_widget; |
47 | int m_matchingRole; |
48 | int m_completionRole; |
49 | AmazingCompleter::ViewHandler m_viewHandler; |
50 | QVariant m_matchData; |
51 | int m_minumumLength; |
52 | |
53 | Q_DECLARE_PUBLIC(AmazingCompleter) |
54 | AmazingCompleter *q_ptr; |
55 | |
56 | }; |
57 | |
58 | AmazingCompleter::AmazingCompleter( /* QAbstractItemModel* model, */ QObject* parent) |
59 | : QObject(parent), d_ptr(new AmazingCompleterPrivate(this) /* ,model) */) |
60 | { |
61 | |
62 | } |
63 | |
64 | AmazingCompleter::~AmazingCompleter() |
65 | { |
66 | delete d_ptr; |
67 | } |
68 | |
69 | void AmazingCompleter::setCompletionPrefixString(const QString& matchData) |
70 | { |
71 | if (matchData.isEmpty()) |
72 | setCompletionPrefix(QVariant()); |
73 | else |
74 | setCompletionPrefix(matchData); |
75 | } |
76 | |
77 | void AmazingCompleter::setCompletionPrefix(const QVariant& matchData) |
78 | { |
79 | Q_D(AmazingCompleter); |
80 | d->m_matchData = matchData; |
81 | d->m_itemSelectionModel->clearSelection(); |
82 | |
83 | if (!matchData.isValid()) |
84 | { |
85 | d->m_view->hide(); |
86 | return; |
87 | } |
88 | |
89 | QString matchString = matchData.toString(); |
90 | if (matchString.size() < d->m_minumumLength) |
91 | { |
92 | d->m_view->hide(); |
93 | return; |
94 | } |
95 | |
96 | |
97 | QModelIndex idx = d->m_model->index(0, 0); |
98 | |
99 | if (!idx.isValid()) |
100 | return; |
101 | |
102 | QModelIndexList matchingIndexes = d->m_model->match(idx, d->m_matchingRole, matchData, -1); // StartsWith |
103 | |
104 | kDebug() << matchingIndexes.size(); |
105 | |
106 | if (matchingIndexes.size() > 0) |
107 | d->m_view->show(); |
108 | else |
109 | d->m_view->hide(); |
110 | |
111 | foreach(const QModelIndex &matchingIndex, matchingIndexes) |
112 | d->m_itemSelectionModel->select(matchingIndex, QItemSelectionModel::Select); // Put this in a queued connection? |
113 | } |
114 | |
115 | void AmazingCompleter::sourceRowsInserted(const QModelIndex &parent, int start, int end) |
116 | { |
117 | Q_UNUSED( parent ); |
118 | Q_UNUSED( start ); |
119 | Q_UNUSED( end ); |
120 | Q_D(AmazingCompleter); |
121 | if (d->m_matchData.isValid()) |
122 | setCompletionPrefix(d->m_matchData); |
123 | } |
124 | |
125 | void AmazingCompleter::setModel(QAbstractItemModel* model) |
126 | { |
127 | Q_D(AmazingCompleter); |
128 | d->m_model = model; |
129 | d->m_itemSelectionModel = new QItemSelectionModel(model, this); |
130 | d->m_selectionProxyModel = new KSelectionProxyModel(d->m_itemSelectionModel, this); |
131 | d->m_selectionProxyModel->setSourceModel(d->m_model); |
132 | |
133 | |
134 | connect(d->m_model, SIGNAL(rowsInserted(QModelIndex,int,int)), |
135 | SLOT(sourceRowsInserted(QModelIndex,int,int))); |
136 | |
137 | |
138 | } |
139 | |
140 | void AmazingCompleter::setView(QAbstractItemView* view, ViewHandler handler) |
141 | { |
142 | Q_D(AmazingCompleter); |
143 | Q_UNUSED( handler ); |
144 | |
145 | d->m_view = view; |
146 | |
147 | QSize size = d->m_widget->size(); |
148 | |
149 | size.setHeight(size.height()*10); |
150 | size.setWidth(size.width() * 2.5); |
151 | |
152 | view->move(50, 50); |
153 | view->resize(size); |
154 | |
155 | view->hide(); |
156 | |
157 | |
158 | connectModelToView(d->m_selectionProxyModel, view); |
159 | } |
160 | |
161 | void AmazingCompleter::connectModelToView(QAbstractItemModel *model, QAbstractItemView *view) |
162 | { |
163 | view->setModel(model); |
164 | } |
165 | |
166 | void AmazingCompleter::setWidget(QWidget* widget) |
167 | { |
168 | Q_D(AmazingCompleter); |
169 | d->m_widget = widget; |
170 | } |
171 | |
172 | void AmazingCompleter::setCompletionRole(int role) |
173 | { |
174 | Q_D(AmazingCompleter); |
175 | d->m_completionRole = role; |
176 | } |
177 | |
178 | void AmazingCompleter::setMatchingRole(int role) |
179 | { |
180 | Q_D(AmazingCompleter); |
181 | d->m_matchingRole = role; |
182 | } |
183 | |