Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef KLF_ITERATORSEARCHABLE_H
00025 #define KLF_ITERATORSEARCHABLE_H
00026
00027 #include <QDebug>
00028 #include <QObject>
00029 #include <QString>
00030 #include <QApplication>
00031 #include <QTime>
00032 #include <QEvent>
00033 #include <QLineEdit>
00034
00035 #include <klfdefs.h>
00036 #include <klfsearchbar.h>
00037
00038
00040
00072 template<class Iter>
00073 class KLF_EXPORT KLFIteratorSearchable : public KLFPosSearchable
00074 {
00075 public:
00076 KLFIteratorSearchable() : KLFPosSearchable()
00077 {
00078 }
00079
00080 virtual ~KLFIteratorSearchable()
00081 {
00082 }
00083
00084 typedef Iter SearchIterator;
00085
00086
00087
00088
00091 virtual SearchIterator searchIterBegin() = 0;
00092
00096 virtual SearchIterator searchIterEnd() = 0;
00097
00100 virtual SearchIterator searchIterAdvance(const SearchIterator& pos, bool forward) = 0;
00101
00103 inline SearchIterator searchIterNext(const SearchIterator& pos) { return searchIterAdvance(pos, true); }
00104
00106 inline SearchIterator searchIterPrev(const SearchIterator& pos) { return searchIterAdvance(pos, false); }
00107
00115 virtual SearchIterator searchIterStartFrom(bool forward)
00116 { Q_UNUSED(forward); return searchIterEnd(); }
00117
00123 virtual bool searchIterMatches(const SearchIterator& pos, const QString& queryString) = 0;
00124
00125
00134 virtual void searchPerformed(const SearchIterator& resultMatchPosition, bool found, const QString& queryString)
00135 { Q_UNUSED(resultMatchPosition); Q_UNUSED(found); Q_UNUSED(queryString); }
00136
00140 virtual void searchMoveToIterPos(const SearchIterator& pos)
00141 { Q_UNUSED(pos); }
00142
00147 virtual void searchPerformed(const SearchIterator& resultMatchPosition)
00148 { Q_UNUSED(resultMatchPosition); }
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158 virtual void searchAborted()
00159 {
00160 setSearchInterruptRequested(true);
00161 }
00162
00163
00164
00165
00166
00167
00168 virtual Pos searchStartFrom(bool forward)
00169 {
00170 KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
00171 return posForIterator(searchIterStartFrom(forward));
00172 }
00173
00176 virtual void searchPerformed(const QString& queryString, bool found, const Pos& pos)
00177 {
00178 searchPerformed(iteratorForPos(pos), found, queryString);
00179 searchPerformed(iteratorForPos(pos));
00180 }
00181
00182 virtual void searchMoveToPos(const Pos& pos)
00183 {
00184 searchMoveToIterPos(iteratorForPos(pos));
00185 }
00186
00187
00188
00189
00190
00192
00201 virtual SearchIterator searchIterFind(const SearchIterator& startPos, const QString& queryString, bool forward)
00202 {
00203 KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
00204 Q_UNUSED(queryString) ;
00205 klfDbg( " s="<<queryString<<" from "<<startPos<<" forward="<<forward
00206 <<"; searchQueryString()="<<searchQueryString() ) ;
00207 pCurPos = startPos;
00208 SearchIterator it = searchIterFindNext(forward);
00209 return it;
00210 }
00211
00213
00218 virtual SearchIterator searchIterFindNext(bool forward)
00219 {
00220 KLF_DEBUG_TIME_BLOCK(KLF_FUNC_NAME) ;
00221
00222 if (searchQueryString().isEmpty()) {
00223 klfDbg("empty search query string.") ;
00224 return tee_notify_search_result(searchIterEnd());
00225 }
00226
00227 QTime t;
00228
00229 bool found = false;
00230 while ( ! found ) {
00231 klfDbg("advancing iterator in search... pCurPos="<<pCurPos) ;
00232
00233
00234 pCurPos = safe_cycl_advance_iterator(pCurPos, forward);
00235
00236 klfDbg("advanced. pCurPos="<<pCurPos) ;
00237
00238
00239 if (pCurPos == searchIterEnd())
00240 break;
00241
00242
00243
00244 if ( searchIterMatches(pCurPos, searchQueryString()) ) {
00245 found = true;
00246 break;
00247 }
00248
00249
00250 if (t.elapsed() > 150) {
00251 qApp->processEvents();
00252 if (searchHasInterruptRequested()) {
00253 klfDbg("interrupting...") ;
00254 break;
00255 }
00256 t.restart();
00257 }
00258 }
00259 if (found) {
00260 klfDbg( "found "<<searchQueryString()<<" at "<<pCurPos ) ;
00261 return tee_notify_search_result(pCurPos);
00262 }
00263
00264
00265 return tee_notify_search_result(searchIterEnd());
00266 }
00267
00268
00269
00270
00271 virtual Pos searchFind(const QString& queryString, const Pos& fromPos, bool forward)
00272 {
00273 KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
00274 klfDbg("queryString="<<queryString<<"; searchQueryString="<<searchQueryString()) ;
00275 SearchIterator startit = iteratorForPos(fromPos);
00276 SearchIterator matchit = searchIterFind(startit, queryString, forward);
00277 return posForIterator(matchit);
00278 }
00279
00280
00292 SearchIterator searchAdvanceIteratorSafe(const SearchIterator& it, int n = 1)
00293 {
00294 if (n == 0)
00295 return it;
00296 bool forward = (n>0);
00297 if (n < 0)
00298 n = -n;
00299
00300 SearchIterator a = it;
00301 while (n--)
00302 a = safe_cycl_advance_iterator(a, forward);
00303
00304 return a;
00305 }
00306
00310 SearchIterator searchAdvanceIteratorCycle(const SearchIterator& it, int n = 1, bool skipEnd = false)
00311 {
00312 bool forward = (n >= 0);
00313 if (!forward)
00314 n = -n;
00315 SearchIterator it2 = it;
00316 while (n--) {
00317 it2 = safe_cycl_advance_iterator(it2, forward);
00318 if (it2 == searchIterEnd() && skipEnd)
00319 it2 = safe_cycl_advance_iterator(it2, forward);
00320 }
00321 return it2;
00322 }
00323
00324 protected:
00325
00326 inline SearchIterator searchCurrentIterPos() const { return pCurPos; }
00327
00328 private:
00330 SearchIterator pCurPos;
00331
00332
00333 struct IterPosData : public KLFPosSearchable::Pos::PosData {
00334 IterPosData(Iter iterator) : it(iterator) { }
00335
00336 Iter it;
00337
00338 virtual bool equals(KLFPosSearchable::Pos::PosData * other) const
00339 {
00340 IterPosData * itpd = dynamic_cast<IterPosData*>(other);
00341 KLF_ASSERT_NOT_NULL(itpd, "posdata of pos ptr `other' is NULL!", return false; ) ;
00342 return (it == itpd->it) ;
00343 }
00344 };
00345
00346 SearchIterator iteratorForPos(const KLFPosSearchable::Pos& p)
00347 {
00348 KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
00349 if (!p.valid())
00350 return searchIterEnd();
00351 IterPosData *itpd = p.data<IterPosData>();
00352 KLF_ASSERT_NOT_NULL(itpd, "posdata of pos `p' is NULL!", return searchIterEnd() ) ;
00353 return itpd->it;
00354 }
00355 KLFPosSearchable::Pos posForIterator(const SearchIterator& it)
00356 {
00357 KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
00358 Pos p = Pos();
00359 if (it == searchIterEnd())
00360 return p;
00361 p.posdata = new IterPosData(it);
00362 return p;
00363 }
00364
00365 inline SearchIterator tee_notify_search_result(const SearchIterator& iter)
00366 {
00367 searchPerformed(iter);
00368 return iter;
00369 }
00370
00371 inline SearchIterator safe_cycl_advance_iterator(const SearchIterator& it, bool forward)
00372 {
00373 if (forward) {
00374 if (it == searchIterEnd())
00375 return searchIterBegin();
00376 return searchIterNext(it);
00377 } else {
00378 if (it == searchIterBegin())
00379 return searchIterEnd();
00380 return searchIterPrev(it);
00381 }
00382 }
00383 };
00384
00385
00386
00387 #endif