[KLF Application][KLF Tools][KLF Backend][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 603 2011-02-26 23:14:55Z phfaist $ */
23 
24 #ifndef KLF_ITERATORSEARCHABLE_H
25 #define KLF_ITERATORSEARCHABLE_H
26 
27 #include <QString>
28 #include <QTime>
29 #include <QApplication>
30 
31 #include <klfdefs.h>
32 #include <klfsearchbar.h>
33 
34 
36 
68 template<class Iter>
69 class KLF_EXPORT KLFIteratorSearchable : public KLFSearchable
70 {
71 public:
72  KLFIteratorSearchable() : KLFSearchable(), pSearchAborted(false) { }
73  virtual ~KLFIteratorSearchable() { }
74 
75  typedef Iter SearchIterator;
76 
77 
78  // FUNCTIONS TO ACCESS SEARCHABLE DATA (REIMPLEMENT TO FIT YOUR NEEDS)
79 
82  virtual SearchIterator searchIterBegin() = 0;
83 
87  virtual SearchIterator searchIterEnd() = 0;
88 
91  virtual SearchIterator searchIterAdvance(const SearchIterator& pos, bool forward) { return forward ? (pos+1) : (pos-1); }
92 
94  inline SearchIterator searchIterNext(const SearchIterator& pos) { return searchIterAdvance(pos, true); }
95 
97  inline SearchIterator searchIterPrev(const SearchIterator& pos) { return searchIterAdvance(pos, false); }
98 
107  virtual SearchIterator searchIterStartFrom(bool forward)
108  { return forward ? searchIterBegin() : searchIterEnd(); }
109 
115  virtual bool searchIterMatches(const SearchIterator& pos, const QString& queryString) = 0;
116 
117 
126  virtual void searchPerformed(const SearchIterator& resultMatchPosition) { Q_UNUSED(resultMatchPosition); }
127 
128 
129  // FUNCTIONS THAT PERFORM THE SEARCH (NO NEED TO REIMPLEMENT)
130 
132 
145  virtual SearchIterator searchIterFind(const SearchIterator& startPos, const QString& queryString, bool forward)
146  {
147  klfDbg( " s="<<queryString<<" from "<<startPos<<" forward="<<forward ) ;
148  // start searching from pCurPos _included_, but findNext() immediately increments to next position. so
149  // simply go back one position before calling findNext()
150  // however when finding reverse we are searching from pos _not inclusive_, see function dox doc
151  if (forward)
152  pCurPos = safe_cycl_advance_iterator(startPos, !forward);
153  pSearchAborted = false;
154  pQString = queryString;
155  SearchIterator it = searchIterFindNext(forward);
156  return it;
157  }
158 
160 
165  virtual SearchIterator searchIterFindNext(bool forward)
166  {
168  pSearchAborted = false;
169  if (pQString.isEmpty())
170  return tee_notify_search_result(searchIterEnd());
171 
172  QTime t;
173 
174  bool found = false;
175  while ( ! found ) {
176  // advance iterator.
177 
178  pCurPos = safe_cycl_advance_iterator(pCurPos, forward);
179 
180  // stop if we reached the end
181  if (pCurPos == searchIterEnd())
182  break;
183 
184  // at this point pCurPos points on something valid
185 
186  if ( searchIterMatches(pCurPos, pQString) ) {
187  found = true;
188  break;
189  }
190 
191  // call application's processEvents() from time to time to prevent GUI from freezing
192  if (t.elapsed() > 150) {
193  qApp->processEvents();
194  if (pSearchAborted)
195  break;
196  t.restart();
197  }
198  }
199  if (found) {
200  klfDbg( "found "<<pQString<<" at "<<pCurPos ) ;
201  return tee_notify_search_result(pCurPos);
202  }
203 
204  // not found
205  return tee_notify_search_result(searchIterEnd());
206  }
207 
208 
209  // reimplemented from KLFSearchable (do not reimplement)
210 
211  /* Calls searchIterFind() with searchIterStartFrom() as start position.
212  *
213  * This function need not be reimplemented, the default implementation should suffice for most cases. */
214  virtual bool searchFind(const QString& queryString, bool forward)
215  {
217  return KLF_DEBUG_TEE( ! (searchIterFind(searchIterStartFrom(forward), queryString, forward)
218  == searchIterEnd()) );
219  }
220 
221  /* Calls searchIterFindNext().
222  *
223  * This function need not be reimplemented, the default implementation should suffice for most cases. */
224  virtual bool searchFindNext(bool forward)
225  {
227  return KLF_DEBUG_TEE( ! (searchIterFindNext(forward) == searchIterEnd()) );
228  }
229 
230  /* Aborts the search.
231  *
232  * If you reimplement this function to perform additional actions when aborting searches, make sure you
233  * call the base class implementation, since searchAbort() may be called by the event loop while
234  * refreshing the GUI during an active search, in which case the base implementation of this function
235  * tells the search to stop.
236  *
237  * This function need not be reimplemented, the default implementation should suffice for most cases. */
238  virtual void searchAbort()
239  {
240  pSearchAborted = true;
241  }
242 
253  {
254  if (n == 0)
255  return it;
256  bool forward = (n>0);
257  if (n < 0)
258  n = -n;
259  // 'n' is number of steps (positive) to perform in direction 'forward'
260  SearchIterator a = it;
261  while (n--)
262  a = safe_cycl_advance_iterator(a, forward);
263 
264  return a;
265  }
266 
267 protected:
268 
269  inline QString searchQueryString() const { return pQString; }
270  inline SearchIterator searchCurrentIterPos() const { return pCurPos; }
271 
272 private:
273  QString pQString;
275  SearchIterator pCurPos;
277  bool pSearchAborted;
278 
279  inline SearchIterator tee_notify_search_result(const SearchIterator& iter)
280  {
281  searchPerformed(iter);
282  return iter;
283  }
284 
285  inline SearchIterator safe_cycl_advance_iterator(const SearchIterator& it, bool forward)
286  {
287  if (forward) {
288  if (it == searchIterEnd())
289  return searchIterBegin();
290  return searchIterNext(it);
291  } else {
292  if (it == searchIterBegin())
293  return searchIterEnd();
294  return searchIterPrev(it);
295  }
296  }
297 };
298 
299 
300 
301 #endif
SearchIterator searchIterPrev(const SearchIterator &pos)
virtual bool searchFind(const QString &queryString, bool forward)
An interface for objects that can be I-searched with a KLFSearchBar.
Definition: klfsearchbar.h:62
QString searchQueryString() const
#define KLF_DEBUG_TEE(expr)
virtual SearchIterator searchIterFindNext(bool forward)
Find the next occurence of previous search string.
#define klfDbg(streamableItems)
#define KLF_DEBUG_BLOCK(msg)
virtual SearchIterator searchIterAdvance(const SearchIterator &pos, bool forward)
virtual void searchPerformed(const SearchIterator &resultMatchPosition)
virtual bool searchFindNext(bool forward)
#define KLF_DEBUG_TIME_BLOCK(msg)
#define KLF_FUNC_NAME
SearchIterator searchIterNext(const SearchIterator &pos)
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 searchIterStartFrom(bool forward)
SearchIterator searchCurrentIterPos() const

Generated by doxygen 1.8.6