[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: klfiteratorsearchable.h 983 2016-12-31 21:03:44Z phfaist $ */
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 
72 template<class Iter>
74 {
75 public:
77  {
78  }
79 
81  {
82  }
83 
84  typedef Iter SearchIterator;
85 
86 
87  // FUNCTIONS TO ACCESS SEARCHABLE DATA (REIMPLEMENT TO FIT YOUR NEEDS)
88 
91  virtual SearchIterator searchIterBegin() = 0;
92 
96  virtual SearchIterator searchIterEnd() = 0;
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 
115  virtual SearchIterator searchIterStartFrom(bool forward)
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 
292  SearchIterator searchAdvanceIteratorSafe(const SearchIterator& it, int n = 1)
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 
324 protected:
325 
326  inline SearchIterator searchCurrentIterPos() const { return pCurPos; }
327 
328 private:
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
virtual SearchIterator searchIterFind(const SearchIterator &startPos, const QString &queryString, bool forward)
Find occurence of a search string.
An object that can be searched with a KLFSearchBar.
Definition: klfsearchbar.h:73
virtual void setSearchInterruptRequested(bool on)
virtual Pos searchStartFrom(bool forward)
Base declarations for klatexformula and some utilities.
virtual QString searchQueryString() const
The current query string.
Definition: klfsearchbar.h:279
virtual void searchPerformed(const SearchIterator &resultMatchPosition, bool found, const QString &queryString)
A Searchable object interface based on iterative searching.
#define klfDbg(streamableItems)
print debug stream items
SearchIterator searchCurrentIterPos() const
#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)
virtual void searchMoveToIterPos(const SearchIterator &pos)
SearchIterator searchIterNext(const SearchIterator &pos)
int elapsed() const
SearchIterator searchAdvanceIteratorSafe(const SearchIterator &it, int n=1)
virtual void searchPerformed(const SearchIterator &resultMatchPosition)
virtual void searchPerformed(const QString &queryString, bool found, const Pos &pos)
Definition: klfsearchbar.h:262
virtual SearchIterator searchIterFindNext(bool forward)
Find the next occurence of previous search string.
#define KLF_EXPORT
Definition: klfdefs.h:41
virtual SearchIterator searchIterStartFrom(bool forward)
SearchIterator searchIterPrev(const SearchIterator &pos)
int restart()
virtual bool searchHasInterruptRequested()
Definition: klfsearchbar.h:286
#define KLF_DEBUG_TIME_BLOCK(msg)
Utility to time the execution of a block.
virtual Pos searchFind(const QString &queryString, const Pos &fromPos, bool forward)
KLFRefPtr< PosData > posdata
Stores the actual position data, see PosData.
Definition: klfsearchbar.h:196
#define KLF_FUNC_NAME
An abstract position in a searchable object.
Definition: klfsearchbar.h:97
SearchIterator searchAdvanceIteratorCycle(const SearchIterator &it, int n=1, bool skipEnd=false)
virtual void searchPerformed(const QString &queryString, bool found, const Pos &pos)
TT * data() const
A shorthand for retrieving the posdata cast into the custom type.
Definition: klfsearchbar.h:212
A Base class for storing abstract position data.
Definition: klfsearchbar.h:124
virtual void searchMoveToPos(const Pos &pos)

Generated by doxygen 1.8.13