[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: klfitemviewsearchtarget.cpp 829 2012-08-20 22:45:18Z phfaist $ */
23 
24 #include <QList>
25 #include <QMap>
26 #include <QAbstractItemView>
27 #include <QAbstractItemModel>
28 
30 #include "klfitemviewsearchtarget_p.h"
31 
32 
33 struct 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 {
134  setSearchView(view);
135 }
137 {
139 }
140 
141 
142 QAbstractItemView * 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 }
177 void 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 }
202 void 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 
236 void 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 
virtual QModelIndex searchIterEnd()
#define KLF_PRIVATE_HEAD(ClassName)
Definition: klfdefs.h:81
virtual QModelIndex searchIterBegin()
A Searchable object interface based on iterative searching.
#define KLF_DEBUG_BLOCK(msg)
Utility to debug the execution of a block.
virtual void searchMoveToIterPos(const QModelIndex &pos)
QSet< T > toSet() const
int size() const
#define KLF_ASSERT_NOT_NULL(ptr, msg, failaction)
Asserting Non-NULL pointers (NON-FATAL)
virtual QModelIndex searchIterAdvance(const QModelIndex &pos, bool forward)
#define KLF_DELETE_PRIVATE
Definition: klfdefs.h:96
bool isEmpty() const
int row() const
KLFItemViewSearchTarget(QAbstractItemView *view, QObject *parent=NULL)
QModelIndex parent() const
virtual void searchReinitialized()
Definition: klfsearchbar.h:272
#define KLF_FUNC_NAME
virtual bool searchIterMatches(const QModelIndex &pos, const QString &queryString)
bool contains(const T &value) const
void setSearchColumns(const QList< int > &columnList)
virtual void searchPerformed(const QModelIndex &resultMatchPosition, bool found, const QString &queryString)
QVariant data(int role) const
QModelIndex sibling(int row, int column) const
A search target (for KLFSearchBar) for standard item views.
T & last()
virtual int columnCount(const QModelIndex &parent) const=0
int column() const
#define KLF_INIT_PRIVATE(ClassName)
Definition: klfdefs.h:94
QString toString() const
void setSearchView(QAbstractItemView *view)
const T value(const Key &key, const T &defaultValue) const

Generated by doxygen 1.8.13