diff --git a/src/qtgui/plaintorich.cpp b/src/qtgui/plaintorich.cpp index 9c82a730..29e40928 100644 --- a/src/qtgui/plaintorich.cpp +++ b/src/qtgui/plaintorich.cpp @@ -1,5 +1,5 @@ #ifndef lint -static char rcsid[] = "@(#$Id: plaintorich.cpp,v 1.20 2007-01-19 15:22:50 dockes Exp $ (C) 2005 J.F.Dockes"; +static char rcsid[] = "@(#$Id: plaintorich.cpp,v 1.21 2007-05-23 09:19:48 dockes Exp $ (C) 2005 J.F.Dockes"; #endif /* * This program is free software; you can redistribute it and/or modify @@ -301,12 +301,32 @@ bool myTextSplitCB::matchGroups() return true; } -const char *firstTermAnchorName = "FIRSTTERM"; +// Setting searchable beacons in the text to walk the term list. +static const char *termAnchorNameBase = "FIRSTTERM"; +string termAnchorName(int i) +{ + char acname[sizeof(termAnchorNameBase) + 20]; + sprintf(acname, "%s%d", termAnchorNameBase, i); + return string(acname); +} #ifdef QT_SCROLL_TO_ANCHOR_BUG -const char *firstTermBeacon = "\xe2\xa0\x91\xe2\x96\x9f\x20\x01\x9a"; +// 0xcd8f is utf8 for unicode 034F COMBINING GRAPHEME JOINER +// Qt doesn't display it, but accepts to search for it. +const char *firstTermBeacon = "\xcd\x8f\xcd\x8f\xcd\x8f\xcd\x8f"; #endif +static string termBeacon(int i) +{ + return string("" +#ifdef QT_SCROLL_TO_ANCHOR_BUG + + "" + firstTermBeacon + "" +#endif + + ""; + +} + + // Fix result text for display inside the gui text window. // // To compute the term character positions in the output text, we used @@ -318,7 +338,7 @@ const char *firstTermBeacon = "\xe2\xa0\x91\xe2\x96\x9f\x20\x01\x9a"; // editor's find() function to position on it bool plaintorich(const string& in, string& out, const HiliteData& hdata, - bool noHeader, bool fft) + bool noHeader, bool) { Chrono chron; out.erase(); @@ -375,26 +395,21 @@ bool plaintorich(const string& in, string& out, Utf8Iter chariter(in); // State variable used to limitate the number of consecutive empty lines int ateol = 0; - // State variable to update the char pos only for the first of - // consecutive blank chars - int atblank = 0; + + // Stuff for numbered anchors at each term match + int anchoridx = 1; + for (string::size_type pos = 0; pos != string::npos; pos = chariter++) { if ((pos & 0xfff) == 0) { CancelCheck::instance().checkCancel(); } - // If we still have terms positions, check (byte) position + + // If we still have terms positions, check (byte) position. If + // we are at or after a term match, mark. if (tPosIt != tboffsend) { int ibyteidx = chariter.getBpos(); - - if (fft && ibyteidx == cb.m_firstTermBPos) { - out += string(" " -#ifdef QT_SCROLL_TO_ANCHOR_BUG - + " " + firstTermBeacon + " " -#endif - + ""; - } - if (ibyteidx == tPosIt->first) { + out += termBeacon(anchoridx++); out += ""; } else if (ibyteidx == tPosIt->second) { // Output end tag, then skip all highlight areas that @@ -405,6 +420,7 @@ bool plaintorich(const string& in, string& out, tPosIt++; } } + switch(*chariter) { case '\n': if (ateol < 2) { @@ -424,11 +440,8 @@ bool plaintorich(const string& in, string& out, break; default: // We don't change the eol status for whitespace, want a real line - if (*chariter == ' ' || *chariter == '\t') { - atblank = 1; - } else { + if (!(*chariter == ' ' || *chariter == '\t')) { ateol = 0; - atblank = 0; } chariter.appendchartostring(out); } diff --git a/src/qtgui/plaintorich.h b/src/qtgui/plaintorich.h index a6b895d7..319736ad 100644 --- a/src/qtgui/plaintorich.h +++ b/src/qtgui/plaintorich.h @@ -16,7 +16,7 @@ */ #ifndef _PLAINTORICH_H_INCLUDED_ #define _PLAINTORICH_H_INCLUDED_ -/* @(#$Id: plaintorich.h,v 1.12 2007-01-19 15:22:50 dockes Exp $ (C) 2004 J.F.Dockes */ +/* @(#$Id: plaintorich.h,v 1.13 2007-05-23 09:19:48 dockes Exp $ (C) 2004 J.F.Dockes */ #include @@ -46,7 +46,7 @@ extern bool plaintorich(const string &in, string &out, bool noHeader = false, bool fft = false); -extern const char *firstTermAnchorName; +extern string termAnchorName(int i); #define QT_SCROLL_TO_ANCHOR_BUG #ifdef QT_SCROLL_TO_ANCHOR_BUG diff --git a/src/qtgui/preview.ui b/src/qtgui/preview.ui index 3f505391..756e58cf 100644 --- a/src/qtgui/preview.ui +++ b/src/qtgui/preview.ui @@ -102,7 +102,7 @@ nextButton - false + true &Next @@ -116,7 +116,7 @@ prevButton - false + true &Previous diff --git a/src/qtgui/preview_w.cpp b/src/qtgui/preview_w.cpp index 05bfd0db..e853d461 100644 --- a/src/qtgui/preview_w.cpp +++ b/src/qtgui/preview_w.cpp @@ -1,5 +1,5 @@ #ifndef lint -static char rcsid[] = "@(#$Id: preview_w.cpp,v 1.17 2007-02-19 18:15:14 dockes Exp $ (C) 2005 J.F.Dockes"; +static char rcsid[] = "@(#$Id: preview_w.cpp,v 1.18 2007-05-23 09:19:48 dockes Exp $ (C) 2005 J.F.Dockes"; #endif /* * This program is free software; you can redistribute it and/or modify @@ -159,7 +159,7 @@ bool Preview::eventFilter(QObject *target, QEvent *event) if (tw) e = (QWidget *)tw->child("pvEdit"); LOGDEB1(("Widget: %p, edit %p, target %p\n", tw, e, target)); - if (e && target == tw && keyEvent->key() == Qt::Key_Slash) { + if (e && target == e && keyEvent->key() == Qt::Key_Slash) { searchTextLine->setFocus(); dynSearchActive = true; return true; @@ -174,13 +174,13 @@ void Preview::searchTextLine_textChanged(const QString & text) LOGDEB1(("search line text changed. text: '%s'\n", text.ascii())); if (text.isEmpty()) { dynSearchActive = false; - nextButton->setEnabled(false); - prevButton->setEnabled(false); + // nextButton->setEnabled(false); + // prevButton->setEnabled(false); clearPB->setEnabled(false); } else { dynSearchActive = true; - nextButton->setEnabled(true); - prevButton->setEnabled(true); + // nextButton->setEnabled(true); + // prevButton->setEnabled(true); clearPB->setEnabled(true); doSearch(text, false, false); } @@ -206,54 +206,55 @@ QTextEdit *Preview::getCurrentEditor() // current search, trying to advance and possibly wrapping around. If next is // false, the search string has been modified, we search for the new string, // starting from the current position -void Preview::doSearch(const QString &text, bool next, bool reverse, +void Preview::doSearch(const QString &_text, bool next, bool reverse, bool wordOnly) { - LOGDEB1(("Preview::doSearch: [%s] next %d rev %d\n", - (const char *)text.utf8(), int(next), int(reverse))); - if (text.isEmpty()) - return; + LOGDEB(("Preview::doSearch: [%s] next %d rev %d\n", + (const char *)_text.utf8(), int(next), int(reverse))); + QString text = _text; + if (text.isEmpty()) { +#ifdef QT_SCROLL_TO_ANCHOR_BUG + text = QString::fromUtf8(firstTermBeacon); +#endif + } QTextEdit *edit = getCurrentEditor(); if (edit == 0) { // ?? return; } - bool matchCase = matchCheck->isChecked(); - int mspara, msindex, mepara, meindex; - edit->getSelection(&mspara, &msindex, &mepara, &meindex); - if (mspara == -1) - mspara = msindex = mepara = meindex = 0; - if (next) { - // We search again, starting from the current match - if (reverse) { - // when searching backwards, have to move back one char - if (msindex > 0) - msindex --; - else if (mspara > 0) { - mspara --; - msindex = edit->paragraphLength(mspara); - } - } else { - // Forward search: start from end of selection - mspara = mepara; - msindex = meindex; - LOGDEB1(("New para: %d index %d\n", mspara, msindex)); - } + bool matchCase = matchCheck->isChecked(); + + LOGDEB(("Preview::doSearch: find: case %d word %d fw %d\n", + matchCase, wordOnly, !reverse)); + + // If the search text changed we need to reset the cursor position + // to the start of the previous match, else incremental search is + // going to look for the next occurrence instead of trying to + // lenghten the current match + if (!next) { + int ps, is, pe, ie; + edit->getSelection(&ps, &is, &pe, &ie); + if (is > 0) + is--; + else if (ps > 0) + ps--; + LOGDEB(("Setting cursor to %d %d\n", ps, is)); + edit->setCursorPosition(ps, is); } - bool found = edit->find(text, matchCase, wordOnly, - !reverse, &mspara, &msindex); - LOGDEB(("Found at para: %d index %d\n", mspara, msindex)); - - if (!found && next && true) { // need a 'canwrap' test here + bool found = edit->find(text, matchCase, wordOnly, !reverse, 0, 0); + // If not found, try to wrap around. + if (!found && next) { + LOGDEB(("Preview::doSearch: wrapping around\n")); + int mspara, msindex; if (reverse) { mspara = edit->paragraphs(); msindex = edit->paragraphLength(mspara); } else { mspara = msindex = 0; } - found = edit->find(text, matchCase, false, !reverse, &mspara, &msindex); + found = edit->find(text,matchCase, false, !reverse, &mspara, &msindex); } if (found) { @@ -622,7 +623,7 @@ bool Preview::loadFileInCurrentTab(string fn, size_t sz, const Rcl::Doc &idoc, // Create preview text: highlight search terms (if not too big): QString richTxt; - bool highlightTerms = fdoc.text.length() < 1000 *1024; + bool highlightTerms = fdoc.text.length() < 2000 * 1024; if (highlightTerms) { progress.setLabelText(tr("Creating preview text")); ToRichThread rthr(fdoc.text, m_hData, richTxt); @@ -657,7 +658,7 @@ bool Preview::loadFileInCurrentTab(string fn, size_t sz, const Rcl::Doc &idoc, } } } else { - richTxt = fdoc.text.c_str(); + richTxt = QString::fromUtf8(fdoc.text.c_str(), fdoc.text.length()); } // Load into editor @@ -708,20 +709,18 @@ bool Preview::loadFileInCurrentTab(string fn, size_t sz, const Rcl::Doc &idoc, canBeep = true; doSearch(searchTextLine->text(), true, false); } else { - QString aname = QString::fromUtf8(firstTermAnchorName); + QString aname = QString::fromUtf8(termAnchorName(1).c_str()); LOGDEB2(("Calling scrolltoanchor [%s]\n", (const char *)aname.utf8())); editor->scrollToAnchor(aname); #ifdef QT_SCROLL_TO_ANCHOR_BUG - bool wasC = matchCheck->isChecked(); - matchCheck->setChecked(false); bool ocanbeep = canBeep; canBeep = false; - doSearch(QString::fromUtf8(firstTermBeacon), 0, false, false); + QString empty; + doSearch(empty, 0, false, false); canBeep = ocanbeep; - editor->del(); - matchCheck->setChecked(wasC); #endif } + editor->setFocus(); emit(previewExposed(m_searchId, docnum)); return true; } diff --git a/src/qtgui/preview_w.h b/src/qtgui/preview_w.h index 7d3ad589..aeddfd3c 100644 --- a/src/qtgui/preview_w.h +++ b/src/qtgui/preview_w.h @@ -1,6 +1,6 @@ #ifndef _PREVIEW_W_H_INCLUDED_ #define _PREVIEW_W_H_INCLUDED_ -/* @(#$Id: preview_w.h,v 1.9 2007-02-19 18:15:14 dockes Exp $ (C) 2006 J.F.Dockes */ +/* @(#$Id: preview_w.h,v 1.10 2007-05-23 09:19:48 dockes Exp $ (C) 2006 J.F.Dockes */ /* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -39,8 +39,9 @@ class TabData { QWidget *w; // widget for setCurrent int docnum; // Index of doc in db search results. - - TabData(QWidget *wi) : w(wi) {} + TabData(QWidget *wi) + : w(wi), docnum(-1) + {} }; class QTextEdit;