--- a/src/qtgui/preview_w.cpp
+++ b/src/qtgui/preview_w.cpp
@@ -68,54 +68,130 @@
// Subclass plainToRich to add <termtag>s and anchors to the preview text
class PlainToRichQtPreview : public PlainToRich {
public:
- int lastanchor;
- PlainToRichQtPreview()
+
+ PlainToRichQtPreview()
+ : m_curanchor(1), m_lastanchor(0)
{
- lastanchor = 0;
}
- virtual ~PlainToRichQtPreview() {}
- virtual string header() {
+
+ bool haveAnchors()
+ {
+ return m_lastanchor != 0;
+ }
+
+ virtual string header()
+ {
if (m_inputhtml) {
- return snull;
+ return cstr_null;
} else {
if (prefs.previewPlainPre) {
m_eolbr = false;
return string("<qt><head><title></title></head><body>"
"<pre>");
-// Note we could also use the following for line-folding instead of <br>s
-// This would be possible without recomputing the whole text, much better perfs
-// for toggling wrap/no-wrap
-// "<pre style=\"white-space: pre-wrap\">");
+ // Note: we could also use the following for
+ // line-folding instead of <br>s This would be
+ // possible without recomputing the whole text, much
+ // better perfs for toggling wrap/no-wrap:
+ // <pre style=\"white-space: pre-wrap\">
} else {
m_eolbr = true;
return string("<qt><head><title></title></head><body>");
}
}
}
- virtual string startMatch()
+
+ virtual string startMatch(unsigned int grpidx)
{
- return string("<span style='color: ")
- + string((const char *)(prefs.qtermcolor.toUtf8()))
- + string(";font-weight: bold;")
- + string("'>");
- }
- virtual string endMatch() {return string("</span>");}
- virtual string termAnchorName(int i) {
+ LOGDEB2(("startMatch, grpidx %u\n", grpidx));
+ grpidx = m_hdata->grpsugidx[grpidx];
+ LOGDEB2(("startMatch, ugrpidx %u\n", grpidx));
+ m_groupanchors[grpidx].push_back(++m_lastanchor);
+ m_groupcuranchors[grpidx] = 0;
+ return string("<span style='color: ").
+ append((const char *)(prefs.qtermcolor.toUtf8())).
+ append(";font-weight: bold;").
+ append("'>").
+ append("<a name=\"").
+ append(termAnchorName(m_lastanchor)).
+ append("\">");
+ }
+
+ virtual string endMatch()
+ {
+ return string("</a></span>");
+ }
+
+ virtual string termAnchorName(int i) const
+ {
static const char *termAnchorNameBase = "TRM";
char acname[sizeof(termAnchorNameBase) + 20];
sprintf(acname, "%s%d", termAnchorNameBase, i);
- if (i > lastanchor)
- lastanchor = i;
return string(acname);
}
- virtual string startAnchor(int i) {
- return string("<a name=\"") + termAnchorName(i) + "\">";
- }
- virtual string endAnchor() {
- return string("</a>");
- }
- virtual string startChunk() { return "<pre>";}
+ virtual string startChunk()
+ {
+ return "<pre>";
+ }
+
+ int nextAnchorNum(int grpidx)
+ {
+ LOGDEB2(("nextAnchorNum: group %d\n", grpidx));
+ map<unsigned int, unsigned int>::iterator curit =
+ m_groupcuranchors.find(grpidx);
+ map<unsigned int, vector<int> >::iterator vecit =
+ m_groupanchors.find(grpidx);
+ if (grpidx == -1 || curit == m_groupcuranchors.end() ||
+ vecit == m_groupanchors.end()) {
+ if (m_curanchor >= m_lastanchor)
+ m_curanchor = 1;
+ else
+ m_curanchor++;
+ } else {
+ if (curit->second >= vecit->second.size() -1)
+ m_groupcuranchors[grpidx] = 0;
+ else
+ m_groupcuranchors[grpidx]++;
+ m_curanchor = vecit->second[m_groupcuranchors[grpidx]];
+ LOGDEB2(("nextAnchorNum: curanchor now %d\n", m_curanchor));
+ }
+ return m_curanchor;
+ }
+
+ int prevAnchorNum(int grpidx)
+ {
+ map<unsigned int, unsigned int>::iterator curit =
+ m_groupcuranchors.find(grpidx);
+ map<unsigned int, vector<int> >::iterator vecit =
+ m_groupanchors.find(grpidx);
+ if (grpidx == -1 || curit == m_groupcuranchors.end() ||
+ vecit == m_groupanchors.end()) {
+ if (m_curanchor <= 1)
+ m_curanchor = m_lastanchor;
+ else
+ m_curanchor--;
+ } else {
+ if (curit->second <= 0)
+ m_groupcuranchors[grpidx] = vecit->second.size() -1;
+ else
+ m_groupcuranchors[grpidx]--;
+ m_curanchor = vecit->second[m_groupcuranchors[grpidx]];
+ }
+ return m_curanchor;
+ }
+
+ QString curAnchorName() const
+ {
+ return QString::fromUtf8(termAnchorName(m_curanchor).c_str());
+ }
+
+private:
+ int m_curanchor;
+ int m_lastanchor;
+ // Lists of anchor numbers (match locations) for the term (groups)
+ // in the query (the map key is and index into HighlightData.groups).
+ map<unsigned int, vector<int> > m_groupanchors;
+ map<unsigned int, unsigned int> m_groupcuranchors;
};
void Preview::init()
@@ -141,8 +217,24 @@
QHBoxLayout *layout3 = new QHBoxLayout(0);
searchLabel = new QLabel(this);
layout3->addWidget(searchLabel);
- searchTextLine = new QLineEdit(this);
- layout3->addWidget(searchTextLine);
+
+ searchTextCMB = new QComboBox(this);
+ searchTextCMB->setEditable(true);
+ searchTextCMB->setInsertPolicy(QComboBox::NoInsert);
+ searchTextCMB->setDuplicatesEnabled(false);
+ for (unsigned int i = 0; i < m_hData.ugroups.size(); i++) {
+ QString s;
+ for (unsigned int j = 0; j < m_hData.ugroups[i].size(); j++) {
+ s.append(QString::fromUtf8(m_hData.ugroups[i][j].c_str()));
+ if (j != m_hData.ugroups[i].size()-1)
+ s.append(" ");
+ }
+ searchTextCMB->addItem(s);
+ }
+ searchTextCMB->setEditText("");
+
+ layout3->addWidget(searchTextCMB);
+
nextButton = new QPushButton(this);
nextButton->setEnabled(TRUE);
layout3->addWidget(nextButton);
@@ -160,7 +252,7 @@
resize(QSize(640, 480).expandedTo(minimumSizeHint()));
// buddies
- searchLabel->setBuddy(searchTextLine);
+ searchLabel->setBuddy(searchTextCMB);
searchLabel->setText(tr("&Search for:"));
nextButton->setText(tr("&Next"));
@@ -176,26 +268,25 @@
"RCL.SEARCH.PREVIEW");
// signals and slots connections
- connect(searchTextLine, SIGNAL(textChanged(const QString&)),
- this, SLOT(searchTextLine_textChanged(const QString&)));
+ connect(searchTextCMB, SIGNAL(activated(int)),
+ this, SLOT(searchTextFromIndex(int)));
+ connect(searchTextCMB, SIGNAL(editTextChanged(const QString&)),
+ this, SLOT(searchTextChanged(const QString&)));
connect(nextButton, SIGNAL(clicked()), this, SLOT(nextPressed()));
connect(prevButton, SIGNAL(clicked()), this, SLOT(prevPressed()));
- connect(clearPB, SIGNAL(clicked()), searchTextLine, SLOT(clear()));
+ connect(clearPB, SIGNAL(clicked()), searchTextCMB, SLOT(clearEditText()));
connect(pvTab, SIGNAL(currentChanged(QWidget *)),
this, SLOT(currentChanged(QWidget *)));
connect(bt, SIGNAL(clicked()), this, SLOT(closeCurrentTab()));
m_dynSearchActive = false;
m_canBeep = true;
- m_currentW = 0;
if (prefs.pvwidth > 100) {
resize(prefs.pvwidth, prefs.pvheight);
}
m_loading = false;
currentChanged(pvTab->currentWidget());
m_justCreated = true;
- m_haveAnchors = false;
- m_curAnchor = 1;
}
void Preview::closeEvent(QCloseEvent *e)
@@ -273,11 +364,11 @@
} else if (m_dynSearchActive) {
if (keyEvent->key() == Qt::Key_F3) {
LOGDEB2(("Preview::eventFilter: got F3\n"));
- doSearch(searchTextLine->text(), true, false);
+ doSearch(searchTextCMB->currentText(), true, false);
return true;
}
- if (target != searchTextLine)
- return QApplication::sendEvent(searchTextLine, event);
+ if (target != searchTextCMB)
+ return QApplication::sendEvent(searchTextCMB, event);
} else {
if (edit &&
(target == edit || target == edit->viewport())) {
@@ -285,7 +376,7 @@
(keyEvent->key() == Qt::Key_F &&
(keyEvent->modifiers() & Qt::ControlModifier))) {
LOGDEB2(("Preview::eventFilter: got / or C-F\n"));
- searchTextLine->setFocus();
+ searchTextCMB->setFocus();
m_dynSearchActive = true;
return true;
} else if (keyEvent->key() == Qt::Key_Space) {
@@ -307,21 +398,25 @@
return false;
}
-void Preview::searchTextLine_textChanged(const QString & text)
-{
- LOGDEB2(("search line text changed. text: '%s'\n", text.ascii()));
+void Preview::searchTextChanged(const QString & text)
+{
+ LOGDEB1(("Search line text changed. text: '%s'\n",
+ (const char *)text.toAscii()));
+ m_searchTextFromIndex = -1;
if (text.isEmpty()) {
m_dynSearchActive = false;
- // nextButton->setEnabled(false);
- // prevButton->setEnabled(false);
clearPB->setEnabled(false);
} else {
m_dynSearchActive = true;
- // nextButton->setEnabled(true);
- // prevButton->setEnabled(true);
clearPB->setEnabled(true);
doSearch(text, false, false);
}
+}
+
+void Preview::searchTextFromIndex(int idx)
+{
+ LOGDEB1(("search line from index %d\n", idx));
+ m_searchTextFromIndex = idx;
}
PreviewTextEdit *Preview::currentEditor()
@@ -351,9 +446,9 @@
void Preview::doSearch(const QString &_text, bool next, bool reverse,
bool wordOnly)
{
- LOGDEB(("Preview::doSearch: text [%s] txtlen %d next %d rev %d word %d\n",
- (const char *)_text.toUtf8(), _text.length(), int(next),
- int(reverse), int(wordOnly)));
+ LOGDEB(("Preview::doSearch: text [%s] idx %d next %d rev %d word %d\n",
+ (const char *)_text.toUtf8(), m_searchTextFromIndex, int(next),
+ int(reverse), int(wordOnly)));
QString text = _text;
bool matchCase = matchCheck->isChecked();
@@ -363,25 +458,19 @@
return;
}
- if (text.isEmpty()) {
- if (m_haveAnchors == false) {
+ if (text.isEmpty() || m_searchTextFromIndex != -1) {
+ if (!edit->m_plaintorich->haveAnchors()) {
LOGDEB(("NO ANCHORS\n"));
return;
}
+ // The combobox indices are equal to the search ugroup indices
+ // in hldata, that's how we built the list.
if (reverse) {
- if (m_curAnchor == 1)
- m_curAnchor = edit->m_plaintorich->lastanchor;
- else
- m_curAnchor--;
+ edit->m_plaintorich->prevAnchorNum(m_searchTextFromIndex);
} else {
- if (m_curAnchor == edit->m_plaintorich->lastanchor)
- m_curAnchor = 1;
- else
- m_curAnchor++;
- }
- LOGDEB(("m_curAnchor: %d\n", m_curAnchor));
- QString aname =
- QString::fromUtf8(edit->m_plaintorich->termAnchorName(m_curAnchor).c_str());
+ edit->m_plaintorich->nextAnchorNum(m_searchTextFromIndex);
+ }
+ QString aname = edit->m_plaintorich->curAnchorName();
LOGDEB(("Calling scrollToAnchor(%s)\n", (const char *)aname.toUtf8()));
edit->scrollToAnchor(aname);
// Position the cursor approximately at the anchor (top of
@@ -440,14 +529,14 @@
void Preview::nextPressed()
{
- LOGDEB2(("PreviewTextEdit::nextPressed\n"));
- doSearch(searchTextLine->text(), true, false);
+ LOGDEB2(("Preview::nextPressed\n"));
+ doSearch(searchTextCMB->currentText(), true, false);
}
void Preview::prevPressed()
{
- LOGDEB2(("PreviewTextEdit::prevPressed\n"));
- doSearch(searchTextLine->text(), true, true);
+ LOGDEB2(("Preview::prevPressed\n"));
+ doSearch(searchTextCMB->currentText(), true, true);
}
// Called when user clicks on tab
@@ -456,7 +545,6 @@
LOGDEB2(("PreviewTextEdit::currentChanged\n"));
PreviewTextEdit *edit =
tw->findChild<PreviewTextEdit*>("pvEdit");
- m_currentW = tw;
LOGDEB1(("Preview::currentChanged(). Editor: %p\n", edit));
if (edit == 0) {
@@ -470,7 +558,7 @@
connect(this, SIGNAL(printCurrentPreviewRequest()), edit, SLOT(print()));
edit->installEventFilter(this);
edit->viewport()->installEventFilter(this);
- searchTextLine->installEventFilter(this);
+ searchTextCMB->installEventFilter(this);
emit(previewExposed(this, m_searchId, edit->m_docnum));
}
@@ -507,7 +595,7 @@
void Preview::setCurTabProps(const Rcl::Doc &doc, int docnum)
{
- LOGDEB1(("PreviewTextEdit::setCurTabProps\n"));
+ LOGDEB1(("Preview::setCurTabProps\n"));
QString title;
string ctitle;
if (doc.getmeta(Rcl::Doc::keytt, &ctitle) && !ctitle.empty()) {
@@ -721,8 +809,6 @@
LoadGuard guard(&m_loading);
CancelCheck::instance().setCancel(false);
- m_haveAnchors = false;
-
setCurTabProps(idoc, docnum);
QString msg = QString("Loading: %1 (size %2 bytes)")
@@ -956,23 +1042,20 @@
// Position the editor so that the first search term is visible
- m_haveAnchors = editor->m_plaintorich->lastanchor != 0;
- if (searchTextLine->text().length() != 0) {
+ if (searchTextCMB->currentText().length() != 0) {
// If there is a current search string, perform the search
m_canBeep = true;
- doSearch(searchTextLine->text(), true, false);
+ doSearch(searchTextCMB->currentText(), true, false);
} else {
// Position to the first query term
- if (m_haveAnchors) {
- QString aname =
- QString::fromUtf8(editor->m_plaintorich->termAnchorName(1).c_str());
+ if (editor->m_plaintorich->haveAnchors()) {
+ QString aname = editor->m_plaintorich->curAnchorName();
LOGDEB2(("Call movetoanchor(%s)\n", (const char *)aname.toUtf8()));
editor->scrollToAnchor(aname);
// Position the cursor approximately at the anchor (top of
// viewport) so that searches start from here
QTextCursor cursor = editor->cursorForPosition(QPoint(0, 0));
editor->setTextCursor(cursor);
- m_curAnchor = 1;
}
}
@@ -989,14 +1072,15 @@
return true;
}
-PreviewTextEdit::PreviewTextEdit(QWidget* parent,const char* name, Preview *pv)
- : QTextEdit(parent), m_preview(pv), m_dspflds(false), m_docnum(-1)
+PreviewTextEdit::PreviewTextEdit(QWidget* parent, const char* nm, Preview *pv)
+ : QTextEdit(parent), m_preview(pv),
+ m_plaintorich(new PlainToRichQtPreview()),
+ m_dspflds(false), m_docnum(-1)
{
setContextMenuPolicy(Qt::CustomContextMenu);
- setObjectName(name);
+ setObjectName(nm);
connect(this, SIGNAL(customContextMenuRequested(const QPoint&)),
this, SLOT(createPopupMenu(const QPoint&)));
- m_plaintorich = new PlainToRichQtPreview();
}
PreviewTextEdit::~PreviewTextEdit()