[KLF Backend][KLF Tools][KLF Home]
KLatexFormula Project
klfitemviewsearchtarget.cpp
Go to the documentation of this file.
1/***************************************************************************
2 * file klfitemviewsearchtarget.cpp
3 * This file is part of the KLatexFormula Project.
4 * Copyright (C) 2012 by Philippe Faist
5 * philippe.faist at bluewin.ch
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the *
19 * Free Software Foundation, Inc., *
20 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
21 ***************************************************************************/
22/* $Id$ */
23
24#include <QList>
25#include <QMap>
26#include <QAbstractItemView>
27#include <QAbstractItemModel>
28
30#include "klfitemviewsearchtarget_p.h"
31
32
33struct KLFItemViewSearchTargetPrivate {
35 {
36 view = NULL;
37 olddelegate = NULL;
38 klfdelegate = new KLFSearchItemDelegate(K);
39 }
40
41 QAbstractItemView * view;
42
43 QAbstractItemDelegate * olddelegate;
44 KLFSearchItemDelegate * klfdelegate;
45
46 void resetDelegate();
47
48 QList<int> columnlist;
49 QMap<int,int> nextcolumn;
50 QMap<int,int> prevcolumn;
51
52 int next_valid_column(int c, bool forward = true)
53 {
54 if (columnlist.isEmpty())
55 return -1;
56
57 while (c >= 0 && c < columnlist.last() && !columnlist.contains(c))
58 c = c + (forward ? +1 : -1);
59 if (c >= columnlist.last())
60 c = -1;
61 return c;
62 }
63
64 QModelIndex advance_iter_helper(const QModelIndex& pos, bool explorechildren = true)
65 {
66 KLF_ASSERT_NOT_NULL(view, "View is NULL!", return QModelIndex(); );
67 QAbstractItemModel *model = view->model();
68 KLF_ASSERT_NOT_NULL(model, "View's model is NULL!", return QModelIndex(); );
69
70 if (columnlist.isEmpty())
71 return QModelIndex();
72
73 if (explorechildren && model->hasChildren(pos)) {
74 // explore children
75 return model->index(0, columnlist[0], pos);
76 }
77 // no children, move to next column
78 int nextcol = nextcolumn.value(next_valid_column(pos.column()), -1);
79 if (nextcol >= 0) {
80 // valid next column to move to
81 return model->index(pos.row(), nextcol, pos.parent());
82 }
83 // we're at last column, try next row
84 if (pos.row() < model->rowCount(pos.parent())) {
85 return pos.sibling(pos.row()+1, columnlist[0]);
86 }
87 // otherwise, we're at the end of (sub-?)list
88 // try parent
89 if (pos.parent() != QModelIndex()) {
90 return advance_iter_helper(pos.parent(), false); // don't re-iterate to children...
91 }
92 // we seem to be at the end of the list...
93 return QModelIndex();
94 }
95
96 QModelIndex last_child_index(const QModelIndex& pos)
97 {
98 KLF_ASSERT_NOT_NULL(view, "View is NULL!", return QModelIndex(); );
99 QAbstractItemModel *model = view->model();
100 KLF_ASSERT_NOT_NULL(model, "View's model is NULL!", return QModelIndex(); );
101
102 if (!model->hasChildren(pos))
103 return pos;
104
105 // children: return last node of last child.
106 return last_child_index(model->index(model->rowCount(pos)-1, columnlist.last(), pos));
107 }
108
109 QModelIndex advance_iter_back_helper(const QModelIndex& pos)
110 {
111 KLF_ASSERT_NOT_NULL(view, "View is NULL!", return QModelIndex(); );
112 QAbstractItemModel *model = view->model();
113 KLF_ASSERT_NOT_NULL(model, "View's model is NULL!", return QModelIndex(); );
114
115 // try to go to previous column
116 int prevcol = prevcolumn.value(next_valid_column(pos.column(), false), -1);
117 if (prevcol >= 0) {
118 return last_child_index(pos.sibling(pos.row(), prevcol));
119 }
120 if (pos.row() >= 1) {
121 // there is a previous sibling
122 return last_child_index(pos.sibling(pos.row()-1, columnlist.last()));
123 }
124 // there is no previous sibling: so we can return the parent
125 return pos.parent();
126 }
127};
128
129
132{
135}
137{
139}
140
141
142QAbstractItemView * KLFItemViewSearchTarget::view()
143{
144 return d->view;
145}
147{
148 return d->columnlist;
149}
150
151
152
153
155{
156 if (forward)
157 return d->advance_iter_helper(pos);
158 // backwards search
159 return d->advance_iter_back_helper(pos);
160}
162{
163 return d->advance_iter_helper(QModelIndex());
164}
166{
167 return QModelIndex();
168}
170{
172
174 = KLFSearchItemDelegate::matches(pos.data().toString(), queryString, false);
175 return mlist.size();
176}
177void KLFItemViewSearchTarget::searchPerformed(const QModelIndex& resultMatchPosition, bool found,
178 const QString& queryString)
179{
181
182 Q_UNUSED(resultMatchPosition);
183 Q_UNUSED(found);
184
185 // WARNING: If item properties are set in the model itself then this is seen by views/delegates as edits!
186 // KLF_ASSERT_NOT_NULL(d->view, "View is NULL!", return ; );
187 // QAbstractItemModel * model = d->view->model();
188 // KLF_ASSERT_NOT_NULL(model, "View has NULL model!!!", return ; ) ;
189 // model->setData(resultMatchPosition, QColor(128,255,255,128), Qt::BackgroundRole);
190
191 KLF_ASSERT_NOT_NULL(d->view, "View is NULL!", return ; );
192 QAbstractItemDelegate *delegate = d->view->itemDelegate();
193 KLF_ASSERT_NOT_NULL(delegate, "Delegate is NULL!", return ; );
194 if (delegate != d->klfdelegate) {
195 d->olddelegate = delegate;
196 d->view->setItemDelegate(d->klfdelegate);
197 }
198
199 d->klfdelegate->setSearchString(queryString);
200 d->view->repaint();
201}
202void KLFItemViewSearchTargetPrivate::resetDelegate()
203{
204 KLF_ASSERT_NOT_NULL(view, "View is NULL!", return ; );
205 QAbstractItemDelegate *delegate = view->itemDelegate();
206 KLF_ASSERT_NOT_NULL(delegate, "Delegate is NULL!", return ; );
207 if (delegate == klfdelegate && olddelegate != NULL) {
208 view->setItemDelegate(olddelegate);
209 }
210 view->repaint();
211}
213{
216
217 d->resetDelegate();
218}
220{
223
224 d->resetDelegate();
225}
226
228{
230
231 KLF_ASSERT_NOT_NULL(d->view, "View is NULL!", return ; );
232 d->view->setCurrentIndex(pos);
233 d->view->selectionModel()->select(pos, QItemSelectionModel::ClearAndSelect);
234}
235
236void KLFItemViewSearchTarget::setSearchView(QAbstractItemView *view)
237{
239
240 d->view = view;
241
242 if (d->columnlist.isEmpty()) {
243 // empty list means all columns
245 }
246}
247
249{
251
252 KLF_ASSERT_NOT_NULL(d->view, "View is NULL!", return ; );
253 QAbstractItemModel * model = d->view->model();
254 KLF_ASSERT_NOT_NULL(model, "View has NULL model!!!", return ; ) ;
255
256 // set-list conversion to remove duplicates, and sorted so it's nice :)
257 d->columnlist = columnList.toSet().toList();
258 qSort(d->columnlist);
259 d->nextcolumn.clear();
260 d->prevcolumn.clear();
261 if (d->columnlist.isEmpty()) {
262 for (int k = 0; k < model->columnCount(); ++k)
263 d->columnlist << k;
264 }
265 if (d->columnlist.isEmpty()) // model has no columns, don't insist
266 return;
267 int k;
268
269 for (k = 0; k < (d->columnlist.size()-1); ++k) {
270 d->nextcolumn[d->columnlist[k]] = d->columnlist[k+1];
271 d->prevcolumn[d->columnlist[k+1]] = d->columnlist[k];
272 }
273 d->nextcolumn[d->columnlist[k]] = -1;
274 d->prevcolumn[d->columnlist[0]] = -1;
275}
276
277
278
A search target (for KLFSearchBar) for standard item views.
virtual void searchMoveToIterPos(const QModelIndex &pos)
virtual QModelIndex searchIterAdvance(const QModelIndex &pos, bool forward)
virtual bool searchIterMatches(const QModelIndex &pos, const QString &queryString)
void setSearchColumns(const QList< int > &columnList)
virtual QModelIndex searchIterEnd()
void setSearchView(QAbstractItemView *view)
virtual QModelIndex searchIterBegin()
KLFItemViewSearchTarget(QAbstractItemView *view, QObject *parent=NULL)
virtual void searchPerformed(const QModelIndex &resultMatchPosition, bool found, const QString &queryString)
A Searchable object interface based on iterative searching.
virtual void searchReinitialized()
#define KLF_DEBUG_BLOCK(msg)
Utility to debug the execution of a block.
Definition klfdebug.h:152
#define KLF_ASSERT_NOT_NULL(ptr, msg, failaction)
Asserting Non-NULL pointers (NON-FATAL)
Definition klfdebug.h:210
#define KLF_FUNC_NAME
Definition klfdebug.h:194
#define KLF_PRIVATE_HEAD(ClassName)
Definition klfdefs.h:81
#define KLF_DELETE_PRIVATE
Definition klfdefs.h:96
#define KLF_INIT_PRIVATE(ClassName)
Definition klfdefs.h:94
bool contains(const T &value) const
bool isEmpty() const
T & last()
int size() const
QSet< T > toSet() const
const T value(const Key &key, const T &defaultValue) const
int column() const
QVariant data(int role) const
QModelIndex parent() const
int row() const
QModelIndex sibling(int row, int column) const
QString toString() const

Generated by doxygen 1.9.7