GUI ssearch: improve interaction with completer
This commit is contained in:
parent
b079f0fb94
commit
541c407033
@ -122,20 +122,19 @@ void RclCompleterModel::onPartialWord(
|
|||||||
for (int i = 0; i < prefs.ssearchHistory.count(); i++) {
|
for (int i = 0; i < prefs.ssearchHistory.count(); i++) {
|
||||||
LOGDEB1("[" << qs2u8s(prefs.ssearchHistory[i]) << "] contains [" <<
|
LOGDEB1("[" << qs2u8s(prefs.ssearchHistory[i]) << "] contains [" <<
|
||||||
qs2u8s(qtext) << "] ?\n");
|
qs2u8s(qtext) << "] ?\n");
|
||||||
|
// If there is current text, only show a limited count of
|
||||||
|
// matching entries, else show the full history.
|
||||||
if (onlyspace ||
|
if (onlyspace ||
|
||||||
prefs.ssearchHistory[i].contains(qtext, Qt::CaseInsensitive)) {
|
prefs.ssearchHistory[i].contains(qtext, Qt::CaseInsensitive)) {
|
||||||
LOGDEB1("YES\n");
|
|
||||||
currentlist.push_back(prefs.ssearchHistory[i]);
|
currentlist.push_back(prefs.ssearchHistory[i]);
|
||||||
if (!onlyspace && ++histmatch >= maxhistmatch)
|
if (!onlyspace && ++histmatch >= maxhistmatch)
|
||||||
break;
|
break;
|
||||||
} else {
|
|
||||||
LOGDEB1("NO\n");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
firstfromindex = currentlist.size();
|
firstfromindex = currentlist.size();
|
||||||
|
|
||||||
// Look for Recoll terms beginning with the partial word
|
// Look for Recoll terms beginning with the partial word
|
||||||
if (!partial.empty() && partial.compare(" ")) {
|
if (!qpartial.trimmed().isEmpty()) {
|
||||||
Rcl::TermMatchResult rclmatches;
|
Rcl::TermMatchResult rclmatches;
|
||||||
if (!rcldb->termMatch(Rcl::Db::ET_WILD, string(),
|
if (!rcldb->termMatch(Rcl::Db::ET_WILD, string(),
|
||||||
partial + "*", rclmatches, maxdbtermmatch)) {
|
partial + "*", rclmatches, maxdbtermmatch)) {
|
||||||
@ -172,16 +171,16 @@ void SSearch::init()
|
|||||||
connect(searchTypCMB, SIGNAL(activated(int)), this,
|
connect(searchTypCMB, SIGNAL(activated(int)), this,
|
||||||
SLOT(searchTypeChanged(int)));
|
SLOT(searchTypeChanged(int)));
|
||||||
|
|
||||||
RclCompleterModel *completermodel = new RclCompleterModel(this);
|
m_completermodel = new RclCompleterModel(this);
|
||||||
QCompleter *completer = new QCompleter(completermodel, this);
|
QCompleter *completer = new QCompleter(m_completermodel, this);
|
||||||
completer->setCompletionMode(QCompleter::UnfilteredPopupCompletion);
|
completer->setCompletionMode(QCompleter::UnfilteredPopupCompletion);
|
||||||
completer->setFilterMode(Qt::MatchContains);
|
completer->setFilterMode(Qt::MatchContains);
|
||||||
completer->setCaseSensitivity(Qt::CaseInsensitive);
|
completer->setCaseSensitivity(Qt::CaseInsensitive);
|
||||||
completer->setMaxVisibleItems(completervisibleitems);
|
completer->setMaxVisibleItems(completervisibleitems);
|
||||||
queryText->setCompleter(completer);
|
queryText->setCompleter(completer);
|
||||||
connect(
|
connect(this, SIGNAL(partialWord(int, const QString&, const QString&)),
|
||||||
this, SIGNAL(partialWord(int, const QString&, const QString&)),
|
m_completermodel,
|
||||||
completermodel, SLOT(onPartialWord(int,const QString&,const QString&)));
|
SLOT(onPartialWord(int,const QString&,const QString&)));
|
||||||
connect(completer, SIGNAL(activated(const QString&)), this,
|
connect(completer, SIGNAL(activated(const QString&)), this,
|
||||||
SLOT(onCompletionActivated(const QString&)));
|
SLOT(onCompletionActivated(const QString&)));
|
||||||
connect(historyPB, SIGNAL(clicked()), this, SLOT(onHistoryClicked()));
|
connect(historyPB, SIGNAL(clicked()), this, SLOT(onHistoryClicked()));
|
||||||
@ -206,28 +205,46 @@ void SSearch::clearAll()
|
|||||||
queryText->clear();
|
queryText->clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// onCompletionActivated() is called when an entry is selected in the
|
||||||
|
// popup, but the edit text is going to be replaced in any case if
|
||||||
|
// there is a current match (we can't prevent it in the signal). If
|
||||||
|
// there is no match (e.g. the user clicked the history button and
|
||||||
|
// selected an entry), the query text will not be set.
|
||||||
|
// So:
|
||||||
|
// - We set the query text to the popup activation value in all cases
|
||||||
|
// - We schedule a callback to set the text to what we want (which is the
|
||||||
|
// concatenation of the user entry before the current partial word and the
|
||||||
|
// pop up data.
|
||||||
|
// - Note that a history click will replace a current partial word,
|
||||||
|
// so that the effect is different if there is a space at the end
|
||||||
|
// of the entry or not: pure concatenation vs replacement of the
|
||||||
|
// last (partial) word.
|
||||||
void SSearch::restoreText()
|
void SSearch::restoreText()
|
||||||
{
|
{
|
||||||
queryText->setText(m_savedEditText);
|
LOGDEB("SSearch::restoreText: savedEdit: " << qs2u8s(m_savedEditText) <<
|
||||||
|
endl);
|
||||||
|
if (!m_savedEditText.trimmed().isEmpty()) {
|
||||||
|
// If the popup text begins with the saved text, just let it replace
|
||||||
|
if (currentText().lastIndexOf(m_savedEditText) != 0) {
|
||||||
|
queryText->setText(m_savedEditText.trimmed() + " " + currentText());
|
||||||
|
}
|
||||||
|
m_savedEditText = "";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSearch::onCompletionActivated(const QString& text)
|
void SSearch::onCompletionActivated(const QString& text)
|
||||||
{
|
{
|
||||||
LOGDEB1("SSearch::onCompletionActivated: current text " <<
|
LOGDEB("SSearch::onCompletionActivated: queryText [" <<
|
||||||
qs2u8s(currentText()) << endl);
|
qs2u8s(currentText()) << "] text [" << qs2u8s(text) << "]\n");
|
||||||
m_savedEditText = m_savedEditText + text;
|
queryText->setText(text);
|
||||||
QTimer::singleShot(0, this, SLOT(restoreText()));
|
QTimer::singleShot(0, this, SLOT(restoreText()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSearch::onHistoryClicked()
|
void SSearch::onHistoryClicked()
|
||||||
{
|
{
|
||||||
QKeyEvent event(QEvent::KeyPress, Qt::Key_Space, 0, " ");
|
if (m_completermodel) {
|
||||||
QApplication::sendEvent(queryText, &event);
|
m_completermodel->onPartialWord(SST_LANG, "", "");
|
||||||
event = QKeyEvent(QEvent::KeyRelease, Qt::Key_Space, 0);
|
queryText->completer()->complete();
|
||||||
QApplication::sendEvent(queryText, &event);
|
}
|
||||||
queryText->setText(" ");
|
|
||||||
QTimer::singleShot(0, queryText->completer()->popup(),
|
|
||||||
SLOT(scrollToTop()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSearch::searchTextEdited(const QString& text)
|
void SSearch::searchTextEdited(const QString& text)
|
||||||
@ -254,16 +271,12 @@ void SSearch::searchTextChanged(const QString& text)
|
|||||||
if (text.isEmpty()) {
|
if (text.isEmpty()) {
|
||||||
searchPB->setEnabled(false);
|
searchPB->setEnabled(false);
|
||||||
clearqPB->setEnabled(false);
|
clearqPB->setEnabled(false);
|
||||||
historyPB->setEnabled(true);
|
|
||||||
queryText->setFocus();
|
queryText->setFocus();
|
||||||
emit clearSearch();
|
emit clearSearch();
|
||||||
} else {
|
} else {
|
||||||
searchPB->setEnabled(true);
|
searchPB->setEnabled(true);
|
||||||
clearqPB->setEnabled(true);
|
clearqPB->setEnabled(true);
|
||||||
}
|
}
|
||||||
if (!text.trimmed().isEmpty()) {
|
|
||||||
historyPB->setEnabled(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSearch::searchTypeChanged(int typ)
|
void SSearch::searchTypeChanged(int typ)
|
||||||
@ -535,14 +548,35 @@ int SSearch::getPartialWord(QString& word)
|
|||||||
{
|
{
|
||||||
// Extract last word in text
|
// Extract last word in text
|
||||||
QString txt = currentText();
|
QString txt = currentText();
|
||||||
int cs = txt.lastIndexOf(" ");
|
if (txt.isEmpty()) {
|
||||||
if (cs == -1)
|
return -1;
|
||||||
|
}
|
||||||
|
int lstidx = txt.size()-1;
|
||||||
|
|
||||||
|
// If the input ends with a space or dquote (phrase input), or
|
||||||
|
// dquote+qualifiers, no partial word.
|
||||||
|
if (txt[lstidx] == ' ') {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
int cs = txt.lastIndexOf("\"");
|
||||||
|
if (cs > 0) {
|
||||||
|
bool dquoteToEndNoSpace{true};
|
||||||
|
for (int i = cs; i <= lstidx; i++) {
|
||||||
|
if (txt[i] == " ") {
|
||||||
|
dquoteToEndNoSpace = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (dquoteToEndNoSpace) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cs = txt.lastIndexOf(" ");
|
||||||
|
if (cs < 0)
|
||||||
cs = 0;
|
cs = 0;
|
||||||
else
|
else
|
||||||
cs++;
|
cs++;
|
||||||
if (txt.size() == 0 || cs == txt.size()) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
word = txt.right(txt.size() - cs);
|
word = txt.right(txt.size() - cs);
|
||||||
return cs;
|
return cs;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -112,6 +112,7 @@ private:
|
|||||||
QString m_savedEditText;
|
QString m_savedEditText;
|
||||||
/* Saved xml version of the search, as we start it */
|
/* Saved xml version of the search, as we start it */
|
||||||
std::string m_xml;
|
std::string m_xml;
|
||||||
|
RclCompleterModel *m_completermodel{nullptr};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user