--- a/src/qtgui/ssearch_w.cpp
+++ b/src/qtgui/ssearch_w.cpp
@@ -62,6 +62,7 @@
queryText->view()->installEventFilter(this);
m_displayingCompletions = false;
m_escape = false;
+ m_disableAutosearch = true;
}
void SSearch::searchTextChanged(const QString& text)
@@ -69,10 +70,39 @@
if (text.isEmpty()) {
searchPB->setEnabled(false);
clearqPB->setEnabled(false);
+ queryText->setFocus();
emit clearSearch();
} else {
searchPB->setEnabled(true);
clearqPB->setEnabled(true);
+ if (prefs.autoSearchOnWS && !m_disableAutosearch) {
+ m_disableAutosearch = true;
+ LOGDEB(("Autosearch: current: [%s]\n",
+ qs2utf8s(queryText->currentText()).c_str()));
+#if 1
+ string s;
+ int cs = partialWord(s);
+ if (cs < 0) {
+ startSimpleSearch();
+ return;
+ }
+
+ // Query database for completions
+ QStringList lst;
+ const int maxcompsize = 40;
+ completionList(s, lst, maxcompsize);
+ if (lst.size() >= maxcompsize) {
+ LOGDEB(("Autosearch: completion list too big: %d\n",
+ lst.size()));
+ return;
+ }
+ s = qs2utf8s(queryText->currentText());
+ s += "*";
+ startSimpleSearch(s);
+#else
+ startSimpleSearch();
+#endif
+ }
}
}
@@ -123,12 +153,38 @@
return;
string u8 = (const char *)queryText->currentText().toUtf8();
- LOGDEB(("SSearch::startSimpleSearch: [%s]\n", u8.c_str()));
trimstring(u8);
if (u8.length() == 0)
return;
+ if (!startSimpleSearch(u8))
+ return;
+
+ LOGDEB(("startSimpleSearch: updating history\n"));
+ // Search terms history:
+ // We want to have the new text at the top and any older identical
+ // entry to be erased. There is no standard qt policy to do this ?
+ // So do it by hand.
+ QString txt = queryText->currentText();
+ int index = queryText->findText(txt);
+ if (index >= 0)
+ queryText->removeItem(index);
+ queryText->insertItem(0, txt);
+ queryText->setCurrentIndex(0);
+ m_disableAutosearch = true;
+
+ // Save the current state of the listbox list to the prefs (will
+ // go to disk)
+ prefs.ssearchHistory.clear();
+ for (int index = 0; index < queryText->count(); index++) {
+ prefs.ssearchHistory.push_back(queryText->itemText(index));
+ }
+}
+
+bool SSearch::startSimpleSearch(const string& u8)
+{
+ LOGDEB(("SSearch::startSimpleSearch(%s)\n", u8.c_str()));
string stemlang = prefs.stemlang();
SSearchType tp = (SSearchType)searchTypCMB->currentIndex();
@@ -144,13 +200,13 @@
if (sdata == 0) {
QMessageBox::warning(0, "Recoll", tr("Bad query string") + ": " +
QString::fromAscii(reason.c_str()));
- return;
+ return false;
}
} else {
sdata = new Rcl::SearchData(Rcl::SCLT_OR, stemlang);
if (sdata == 0) {
QMessageBox::warning(0, "Recoll", tr("Out of memory"));
- return;
+ return false;
}
Rcl::SearchDataClause *clp = 0;
if (tp == SST_FNM) {
@@ -175,31 +231,14 @@
prefs.ssearchAutoPhraseThreshPC / 100.0);
}
- // Search terms history
-
- // We want to have the new text at the top and any older identical
- // entry to be erased. There is no standard qt policy to do this ?
- // So do it by hand.
- QString txt = queryText->currentText();
- int index = queryText->findText(txt);
- if (index >= 0)
- queryText->removeItem(index);
- queryText->insertItem(0, txt);
- queryText->setCurrentIndex(0);
-
- // Save the current state of the listbox list to the prefs (will
- // go to disk)
- prefs.ssearchHistory.clear();
- for (int index = 0; index < queryText->count(); index++) {
- prefs.ssearchHistory.push_back(queryText->itemText(index));
- }
-
RefCntr<Rcl::SearchData> rsdata(sdata);
emit startSearch(rsdata);
+ return true;
}
void SSearch::setSearchString(const QString& txt)
{
+ m_disableAutosearch = true;
queryText->setEditText(txt);
}
@@ -234,15 +273,19 @@
QString text = queryText->currentText();
text += QString::fromLatin1(" ") + term;
queryText->setEditText(text);
+ m_disableAutosearch = true;
}
void SSearch::onWordReplace(const QString& o, const QString& n)
{
+ LOGDEB(("SSearch::onWordReplace: o [%s] n [%s]\n",
+ qs2utf8s(o).c_str(), qs2utf8s(n).c_str()));
QString txt = queryText->currentText();
QRegExp exp = QRegExp(QString("\\b") + o + QString("\\b"));
exp.setCaseSensitivity(Qt::CaseInsensitive);
txt.replace(exp, n);
queryText->setEditText(txt);
+ m_disableAutosearch = true;
Qt::KeyboardModifiers mods = QApplication::keyboardModifiers ();
if (mods == Qt::NoModifier)
startSimpleSearch();
@@ -253,16 +296,8 @@
searchTypCMB->setCurrentIndex(SST_ANY);
}
-// Complete last word in input by querying db for all possible terms.
-void SSearch::completion()
-{
- if (!rcldb)
- return;
- if (searchTypCMB->currentIndex() == SST_FNM) {
- // Filename: no completion
- QApplication::beep();
- return;
- }
+int SSearch::partialWord(string& s)
+{
// Extract last word in text
QString txt = queryText->currentText();
int cs = txt.lastIndexOf(" ");
@@ -271,24 +306,57 @@
else
cs++;
if (txt.size() == 0 || cs == txt.size()) {
+ return -1;
+ }
+ s = qs2utf8s(txt.right(txt.size() - cs));
+ return cs;
+}
+
+int SSearch::completionList(string s, QStringList& lst, int max)
+{
+ if (!rcldb)
+ return -1;
+ // Query database for completions
+ s += "*";
+ Rcl::TermMatchResult tmres;
+ if (!rcldb->termMatch(Rcl::Db::ET_WILD, "", s, tmres, max) ||
+ tmres.entries.size() == 0) {
+ return 0;
+ }
+ for (vector<Rcl::TermMatchEntry>::iterator it = tmres.entries.begin();
+ it != tmres.entries.end(); it++) {
+ lst.push_back(QString::fromUtf8(it->term.c_str()));
+ }
+ return lst.size();
+}
+
+// Complete last word in input by querying db for all possible terms.
+void SSearch::completion()
+{
+ LOGDEB(("SSearch::completion\n"));
+ if (!rcldb)
+ return;
+ if (searchTypCMB->currentIndex() == SST_FNM) {
+ // Filename: no completion
QApplication::beep();
return;
}
+ // Extract last word in text
+ string s;
+ int cs = partialWord(s);
+ if (cs < 0) {
+ QApplication::beep();
+ return;
+ }
+
// Query database for completions
- string s = qs2utf8s(txt.right(txt.size() - cs)) + "*";
-
- const int max = 100;
- Rcl::TermMatchResult tmres;
-
- string stemLang = prefs.stemlang();
-
- if (!rcldb->termMatch(Rcl::Db::ET_WILD, stemLang, s, tmres, max) ||
- tmres.entries.size() == 0) {
+ QStringList lst;
+ if (completionList(s, lst, 100) <= 0) {
QApplication::beep();
return;
}
- if (tmres.entries.size() == (unsigned int)max) {
+ if (lst.size() == 100) {
QMessageBox *warning = new QMessageBox;
warning->setWindowTitle(tr("Recoll"));
warning->setText(tr("Too many completions"));
@@ -298,18 +366,13 @@
}
// If list from db is single word, insert it, else popup the listview
- if (tmres.entries.size() == 1) {
- QString res = QString::fromUtf8(tmres.entries.begin()->term.c_str());
+ m_disableAutosearch = true;
+ if (lst.size() == 1) {
+ QString txt = queryText->currentText();
txt.truncate(cs);
- txt.append(res);
+ txt.append(lst[0]);
queryText->setEditText(txt);
} else {
- QStringList lst;
- for (vector<Rcl::TermMatchEntry>::iterator it = tmres.entries.begin();
- it != tmres.entries.end(); it++) {
- lst.push_back(QString::fromUtf8(it->term.c_str()));
- }
-
m_savedEditText = queryText->currentText();
m_displayingCompletions = true;
m_chosenCompletion.clear();
@@ -321,7 +384,6 @@
connect(queryText, SIGNAL(activated(const QString&)), this,
SLOT(completionTermChosen(const QString&)));
-
}
}
@@ -332,6 +394,7 @@
void SSearch::wrapupCompletion()
{
+ LOGDEB(("SSearch::wrapupCompletion\n"));
queryText->clear();
queryText->addItems(prefs.ssearchHistory);
if (!m_chosenCompletion.isEmpty()) {
@@ -339,8 +402,10 @@
m_savedEditText.append(m_chosenCompletion);
}
queryText->setEditText(m_savedEditText);
+ m_disableAutosearch = true;
m_savedEditText.clear();
m_chosenCompletion.clear();
+ m_displayingCompletions = false;
disconnect(queryText, SIGNAL(activated(const QString&)), this,
SLOT(completionTermChosen(const QString&)));
}
@@ -504,7 +569,6 @@
// to reset state.
if (m_displayingCompletions) {
QTimer::singleShot(0, this, SLOT(wrapupCompletion()));
- m_displayingCompletions = false;
}
}
return false;
@@ -525,10 +589,11 @@
m_escape = false;
return true;
} else if (ke->key() == Qt::Key_Space) {
- if (prefs.autoSearchOnWS)
- startSimpleSearch();
+// if (prefs.autoSearchOnWS)
+// startSimpleSearch();
}
m_escape = false;
+ m_disableAutosearch = false;
}
return false;
}