diff --git a/src/qtgui/ssearch_w.cpp b/src/qtgui/ssearch_w.cpp index 225a047d..bd8cc0c3 100644 --- a/src/qtgui/ssearch_w.cpp +++ b/src/qtgui/ssearch_w.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include "debuglog.h" #include "guiutils.h" @@ -58,6 +59,8 @@ void SSearch::init() connect(searchTypCMB, SIGNAL(activated(int)), this, SLOT(searchTypeChanged(int))); queryText->installEventFilter(this); + queryText->view()->installEventFilter(this); + m_displayingCompletions = false; m_escape = false; } @@ -261,9 +264,9 @@ void SSearch::completion() return; } // Extract last word in text - string txt = (const char *)queryText->currentText().toUtf8(); - string::size_type cs = txt.find_last_of(" "); - if (cs == string::npos) + QString txt = queryText->currentText(); + int cs = txt.lastIndexOf(" "); + if (cs == -1) cs = 0; else cs++; @@ -271,10 +274,10 @@ void SSearch::completion() QApplication::beep(); return; } - string s = txt.substr(cs) + "*"; - LOGDEB(("Completing: [%s]\n", s.c_str())); - // Query database + // Query database for completions + string s = qs2utf8s(txt.right(txt.size() - cs)) + "*"; + const int max = 100; Rcl::TermMatchResult tmres; @@ -286,37 +289,62 @@ void SSearch::completion() return; } if (tmres.entries.size() == (unsigned int)max) { - QMessageBox::warning(0, "Recoll", tr("Too many completions")); + QMessageBox *warning = new QMessageBox; + warning->setWindowTitle(tr("Recoll")); + warning->setText(tr("Too many completions")); + warning->show(); + QTimer::singleShot(500, warning, SLOT(close())); return; } - // If list from db is single word, insert it, else ask user to select - QString res; - bool ok = false; + // If list from db is single word, insert it, else popup the listview if (tmres.entries.size() == 1) { - res = QString::fromUtf8(tmres.entries.begin()->term.c_str()); - ok = true; + QString res = QString::fromUtf8(tmres.entries.begin()->term.c_str()); + txt.truncate(cs); + txt.append(res); + queryText->setEditText(txt); } else { QStringList lst; for (vector::iterator it = tmres.entries.begin(); it != tmres.entries.end(); it++) { lst.push_back(QString::fromUtf8(it->term.c_str())); } - res = QInputDialog::getItem (this, tr("Completions"), - tr("Select an item:"), - lst, 0, false, &ok); - } - // Insert result - if (ok) { - txt.erase(cs); - txt.append((const char *)res.toUtf8()); - queryText->setEditText(QString::fromUtf8(txt.c_str())); - } else { - return; + m_savedEditText = queryText->currentText(); + m_displayingCompletions = true; + m_chosenCompletion.clear(); + m_completedWordStart = cs; + + queryText->clear(); + queryText->addItems(lst); + queryText->showPopup(); + + connect(queryText, SIGNAL(activated(const QString&)), this, + SLOT(completionTermChosen(const QString&))); + } } +void SSearch::completionTermChosen(const QString& text) +{ + m_chosenCompletion = text; +} + +void SSearch::wrapupCompletion() +{ + queryText->clear(); + queryText->addItems(prefs.ssearchHistory); + if (!m_chosenCompletion.isEmpty()) { + m_savedEditText.truncate(m_completedWordStart); + m_savedEditText.append(m_chosenCompletion); + } + queryText->setEditText(m_savedEditText); + m_savedEditText.clear(); + m_chosenCompletion.clear(); + disconnect(queryText, SIGNAL(activated(const QString&)), this, + SLOT(completionTermChosen(const QString&))); +} + #undef SHOWEVENTS #if defined(SHOWEVENTS) const char *eventTypeToStr(int tp) @@ -458,7 +486,7 @@ const char *eventTypeToStr(int tp) } #endif -bool SSearch::eventFilter(QObject *, QEvent *event) +bool SSearch::eventFilter(QObject *target, QEvent *event) { #if defined(SHOWEVENTS) if (event->type() == QEvent::Timer || @@ -470,6 +498,18 @@ bool SSearch::eventFilter(QObject *, QEvent *event) eventTypeToStr(event->type()))); #endif + if (target == queryText->view()) { + if (event->type() == QEvent::Hide) { + // List was closed. If we were displaying completions, need + // to reset state. + if (m_displayingCompletions) { + QTimer::singleShot(0, this, SLOT(wrapupCompletion())); + m_displayingCompletions = false; + } + } + return false; + } + if (event->type() == QEvent::KeyPress) { QKeyEvent *ke = (QKeyEvent *)event; LOGDEB1(("SSearch::eventFilter: keyPress (m_escape %d) key %d\n", diff --git a/src/qtgui/ssearch_w.h b/src/qtgui/ssearch_w.h index 16176c39..cc8b66f1 100644 --- a/src/qtgui/ssearch_w.h +++ b/src/qtgui/ssearch_w.h @@ -51,11 +51,17 @@ public slots: virtual void startSimpleSearch(); virtual void addTerm(QString); virtual void onWordReplace(const QString&, const QString&); + virtual void completionTermChosen(const QString& text); + virtual void wrapupCompletion(); signals: void startSearch(RefCntr); void clearSearch(); private: bool m_escape; + bool m_displayingCompletions; + QString m_chosenCompletion; + QString m_savedEditText; + unsigned int m_completedWordStart; };