[KLF Backend][KLF Tools][KLF Home]
KLatexFormula Project
klfiteratorsearchable.h
Go to the documentation of this file.
1/***************************************************************************
2 * file klfiteratorsearchable.h
3 * This file is part of the KLatexFormula Project.
4 * Copyright (C) 2011 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#ifndef KLF_ITERATORSEARCHABLE_H
25#define KLF_ITERATORSEARCHABLE_H
26
27#include <QDebug>
28#include <QObject>
29#include <QString>
30#include <QApplication>
31#include <QTime>
32#include <QEvent>
33#include <QLineEdit>
34
35#include <klfdefs.h>
36#include <klfsearchbar.h>
37
38
40
72template<class Iter>
74{
75public:
77 {
78 }
79
81 {
82 }
83
84 typedef Iter SearchIterator;
85
86
87 // FUNCTIONS TO ACCESS SEARCHABLE DATA (REIMPLEMENT TO FIT YOUR NEEDS)
88
92
97
100 virtual SearchIterator searchIterAdvance(const SearchIterator& pos, bool forward) = 0;
101
103 inline SearchIterator searchIterNext(const SearchIterator& pos) { return searchIterAdvance(pos, true); }
104
106 inline SearchIterator searchIterPrev(const SearchIterator& pos) { return searchIterAdvance(pos, false); }
107
116 { Q_UNUSED(forward); return searchIterEnd(); }
117
123 virtual bool searchIterMatches(const SearchIterator& pos, const QString& queryString) = 0;
124
125
134 virtual void searchPerformed(const SearchIterator& resultMatchPosition, bool found, const QString& queryString)
135 { Q_UNUSED(resultMatchPosition); Q_UNUSED(found); Q_UNUSED(queryString); }
136
140 virtual void searchMoveToIterPos(const SearchIterator& pos)
141 { Q_UNUSED(pos); }
142
147 virtual void searchPerformed(const SearchIterator& resultMatchPosition)
148 { Q_UNUSED(resultMatchPosition); }
149
150
151 /* Aborts the search.
152 *
153 * If you reimplement this function to perform additional actions when aborting searches, make sure you
154 * call the base class implementation, since searchAbort() may be called by the event loop while
155 * refreshing the GUI during an active search, in which case the base implementation of this function
156 * tells the search to stop.
157 */
158 virtual void searchAborted()
159 {
161 }
162
163
164
165 // REIMPLEMENTATIONS THAT TRANSLATE POS OBJECTS TO ITERATORS
166 // ... don't reimplement unless really necessary.
167
168 virtual Pos searchStartFrom(bool forward)
169 {
171 return posForIterator(searchIterStartFrom(forward));
172 }
173
176 virtual void searchPerformed(const QString& queryString, bool found, const Pos& pos)
177 {
178 searchPerformed(iteratorForPos(pos), found, queryString);
179 searchPerformed(iteratorForPos(pos));
180 }
181
182 virtual void searchMoveToPos(const Pos& pos)
183 {
184 searchMoveToIterPos(iteratorForPos(pos));
185 }
186
187
188 // FUNCTIONS THAT PERFORM THE SEARCH
189 // ... don't reimplement unless _ABSOLUTELY_ necessary.
190
192
201 virtual SearchIterator searchIterFind(const SearchIterator& startPos, const QString& queryString, bool forward)
202 {
204 Q_UNUSED(queryString) ;
205 klfDbg( " s="<<queryString<<" from "<<startPos<<" forward="<<forward
206 <<"; searchQueryString()="<<searchQueryString() ) ;
207 pCurPos = startPos;
208 SearchIterator it = searchIterFindNext(forward);
209 return it;
210 }
211
213
218 virtual SearchIterator searchIterFindNext(bool forward)
219 {
221
222 if (searchQueryString().isEmpty()) {
223 klfDbg("empty search query string.") ;
224 return tee_notify_search_result(searchIterEnd());
225 }
226
227 QTime t;
228
229 bool found = false;
230 while ( ! found ) {
231 klfDbg("advancing iterator in search... pCurPos="<<pCurPos) ;
232 // advance iterator.
233
234 pCurPos = safe_cycl_advance_iterator(pCurPos, forward);
235
236 klfDbg("advanced. pCurPos="<<pCurPos) ;
237
238 // stop if we reached the end
239 if (pCurPos == searchIterEnd())
240 break;
241
242 // at this point pCurPos points on something valid
243
244 if ( searchIterMatches(pCurPos, searchQueryString()) ) {
245 found = true;
246 break;
247 }
248
249 // call application's processEvents() from time to time to prevent GUI from freezing
250 if (t.elapsed() > 150) {
251 qApp->processEvents();
253 klfDbg("interrupting...") ;
254 break;
255 }
256 t.restart();
257 }
258 }
259 if (found) {
260 klfDbg( "found "<<searchQueryString()<<" at "<<pCurPos ) ;
261 return tee_notify_search_result(pCurPos);
262 }
263
264 // not found
265 return tee_notify_search_result(searchIterEnd());
266 }
267
268
269 // reimplemented from KLFPosSearchable (do not reimplement)
270
271 virtual Pos searchFind(const QString& queryString, const Pos& fromPos, bool forward)
272 {
274 klfDbg("queryString="<<queryString<<"; searchQueryString="<<searchQueryString()) ;
275 SearchIterator startit = iteratorForPos(fromPos);
276 SearchIterator matchit = searchIterFind(startit, queryString, forward);
277 return posForIterator(matchit);
278 }
279
280
293 {
294 if (n == 0)
295 return it;
296 bool forward = (n>0);
297 if (n < 0)
298 n = -n;
299 // 'n' is number of steps (positive) to perform in direction 'forward'
300 SearchIterator a = it;
301 while (n--)
302 a = safe_cycl_advance_iterator(a, forward);
303
304 return a;
305 }
306
310 SearchIterator searchAdvanceIteratorCycle(const SearchIterator& it, int n = 1, bool skipEnd = false)
311 {
312 bool forward = (n >= 0);
313 if (!forward)
314 n = -n;
315 SearchIterator it2 = it;
316 while (n--) {
317 it2 = safe_cycl_advance_iterator(it2, forward);
318 if (it2 == searchIterEnd() && skipEnd)
319 it2 = safe_cycl_advance_iterator(it2, forward);
320 }
321 return it2;
322 }
323
324protected:
325
326 inline SearchIterator searchCurrentIterPos() const { return pCurPos; }
327
328private:
330 SearchIterator pCurPos;
331
332
333 struct IterPosData : public KLFPosSearchable::Pos::PosData {
334 IterPosData(Iter iterator) : it(iterator) { }
335
336 Iter it;
337
338 virtual bool equals(KLFPosSearchable::Pos::PosData * other) const
339 {
340 IterPosData * itpd = dynamic_cast<IterPosData*>(other);
341 KLF_ASSERT_NOT_NULL(itpd, "posdata of pos ptr `other' is NULL!", return false; ) ;
342 return (it == itpd->it) ;
343 }
344 };
345
346 SearchIterator iteratorForPos(const KLFPosSearchable::Pos& p)
347 {
349 if (!p.valid())
350 return searchIterEnd();
351 IterPosData *itpd = p.data<IterPosData>();
352 KLF_ASSERT_NOT_NULL(itpd, "posdata of pos `p' is NULL!", return searchIterEnd() ) ;
353 return itpd->it;
354 }
355 KLFPosSearchable::Pos posForIterator(const SearchIterator& it)
356 {
358 Pos p = Pos();
359 if (it == searchIterEnd())
360 return p; // an invalid pos
361 p.posdata = new IterPosData(it);
362 return p;
363 }
364
365 inline SearchIterator tee_notify_search_result(const SearchIterator& iter)
366 {
367 searchPerformed(iter);
368 return iter;
369 }
370
371 inline SearchIterator safe_cycl_advance_iterator(const SearchIterator& it, bool forward)
372 {
373 if (forward) {
374 if (it == searchIterEnd())
375 return searchIterBegin();
376 return searchIterNext(it);
377 } else {
378 if (it == searchIterBegin())
379 return searchIterEnd();
380 return searchIterPrev(it);
381 }
382 }
383};
384
385
386
387#endif
A Searchable object interface based on iterative searching.
SearchIterator searchAdvanceIteratorSafe(const SearchIterator &it, int n=1)
virtual SearchIterator searchIterFind(const SearchIterator &startPos, const QString &queryString, bool forward)
Find occurence of a search string.
virtual SearchIterator searchIterAdvance(const SearchIterator &pos, bool forward)=0
SearchIterator searchIterNext(const SearchIterator &pos)
virtual void searchPerformed(const QString &queryString, bool found, const Pos &pos)
virtual void searchMoveToIterPos(const SearchIterator &pos)
virtual SearchIterator searchIterStartFrom(bool forward)
SearchIterator searchCurrentIterPos() const
virtual SearchIterator searchIterBegin()=0
virtual void searchMoveToPos(const Pos &pos)
virtual void searchPerformed(const SearchIterator &resultMatchPosition)
virtual Pos searchFind(const QString &queryString, const Pos &fromPos, bool forward)
SearchIterator searchIterPrev(const SearchIterator &pos)
virtual SearchIterator searchIterFindNext(bool forward)
Find the next occurence of previous search string.
SearchIterator searchAdvanceIteratorCycle(const SearchIterator &it, int n=1, bool skipEnd=false)
virtual bool searchIterMatches(const SearchIterator &pos, const QString &queryString)=0
virtual Pos searchStartFrom(bool forward)
virtual SearchIterator searchIterEnd()=0
virtual void searchPerformed(const SearchIterator &resultMatchPosition, bool found, const QString &queryString)
An object that can be searched with a KLFSearchBar.
Definition: klfsearchbar.h:74
virtual bool searchHasInterruptRequested()
Definition: klfsearchbar.h:286
virtual QString searchQueryString() const
The current query string.
Definition: klfsearchbar.h:279
virtual void searchPerformed(const QString &queryString, bool found, const Pos &pos)
Definition: klfsearchbar.h:262
virtual void setSearchInterruptRequested(bool on)
#define KLF_DEBUG_TIME_BLOCK(msg)
Utility to time the execution of a block.
#define KLF_DEBUG_BLOCK(msg)
Utility to debug the execution of a block.
#define KLF_ASSERT_NOT_NULL(ptr, msg, failaction)
Asserting Non-NULL pointers (NON-FATAL)
#define KLF_FUNC_NAME
#define klfDbg(streamableItems)
print debug stream items
Base declarations for klatexformula and some utilities.
#define KLF_EXPORT
Definition: klfdefs.h:41
int elapsed() const
int restart()
A Base class for storing abstract position data.
Definition: klfsearchbar.h:124
An abstract position in a searchable object.
Definition: klfsearchbar.h:97
TT * data() const
A shorthand for retrieving the posdata cast into the custom type.
Definition: klfsearchbar.h:212

Generated by doxygen 1.9.6