When the current completion begins with the current input, append and select it in the lineedit to better put it in evidence
This commit is contained in:
parent
5210088e8f
commit
44a529513f
@ -151,6 +151,7 @@ void RclCompleterModel::onPartialWord(
|
||||
}
|
||||
}
|
||||
endResetModel();
|
||||
QTimer::singleShot(0, m_parent, SLOT(onCompleterShown()));
|
||||
}
|
||||
|
||||
void SSearch::init()
|
||||
@ -172,16 +173,18 @@ void SSearch::init()
|
||||
SLOT(searchTypeChanged(int)));
|
||||
|
||||
m_completermodel = new RclCompleterModel(this);
|
||||
QCompleter *completer = new QCompleter(m_completermodel, this);
|
||||
completer->setCompletionMode(QCompleter::UnfilteredPopupCompletion);
|
||||
completer->setFilterMode(Qt::MatchContains);
|
||||
completer->setCaseSensitivity(Qt::CaseInsensitive);
|
||||
completer->setMaxVisibleItems(completervisibleitems);
|
||||
queryText->setCompleter(completer);
|
||||
m_completer = new QCompleter(m_completermodel, this);
|
||||
m_completer->setCompletionMode(QCompleter::UnfilteredPopupCompletion);
|
||||
m_completer->setFilterMode(Qt::MatchContains);
|
||||
m_completer->setCaseSensitivity(Qt::CaseInsensitive);
|
||||
m_completer->setMaxVisibleItems(completervisibleitems);
|
||||
queryText->setCompleter(m_completer);
|
||||
m_completer->popup()->installEventFilter(this);
|
||||
queryText->installEventFilter(this);
|
||||
connect(this, SIGNAL(partialWord(int, const QString&, const QString&)),
|
||||
m_completermodel,
|
||||
SLOT(onPartialWord(int,const QString&,const QString&)));
|
||||
connect(completer, SIGNAL(activated(const QString&)), this,
|
||||
connect(m_completer, SIGNAL(activated(const QString&)), this,
|
||||
SLOT(onCompletionActivated(const QString&)));
|
||||
connect(historyPB, SIGNAL(clicked()), this, SLOT(onHistoryClicked()));
|
||||
}
|
||||
@ -205,6 +208,77 @@ void SSearch::clearAll()
|
||||
queryText->clear();
|
||||
}
|
||||
|
||||
void SSearch::onCompleterShown()
|
||||
{
|
||||
LOGDEB("SSearch::onCompleterShown\n");
|
||||
QCompleter *completer = queryText->completer();
|
||||
if (!completer) {
|
||||
LOGDEB0("SSearch::onCompleterShown: no completer\n");
|
||||
return;
|
||||
}
|
||||
QAbstractItemView *popup = queryText->completer()->popup();
|
||||
if (!popup) {
|
||||
LOGDEB0("SSearch::onCompleterShown: no popup\n");
|
||||
return;
|
||||
}
|
||||
QVariant data = popup->model()->data(popup->currentIndex());
|
||||
if (!data.isValid()) {
|
||||
LOGDEB0("SSearch::onCompleterShown: data not valid\n");
|
||||
return;
|
||||
}
|
||||
// Test if the completer text begins with the current input.
|
||||
QString text = data.toString();
|
||||
if (!text.lastIndexOf(queryText->text()) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOGDEB0("SSearch::onCompleterShown:" <<
|
||||
" current [" << qs2utf8s(currentText()) <<
|
||||
"] saved [" << qs2utf8s(m_savedEditText) <<
|
||||
"] popup [" << qs2utf8s(text) << "]\n");
|
||||
|
||||
// We append the completion part to the end of the current input,
|
||||
// line, and select it so that the user has a clear indication of
|
||||
// what will happen if they type Enter.
|
||||
int pos = queryText->cursorPosition();
|
||||
int len = text.size() - currentText().size();
|
||||
queryText->setText(text);
|
||||
queryText->setCursorPosition(pos);
|
||||
queryText->setSelection(pos, len);
|
||||
}
|
||||
|
||||
// This is to avoid that if the user types Backspace or Del while we
|
||||
// have inserted / selected the current completion, the lineedit text
|
||||
// goes back to what it was, the completion fires, and it looks like
|
||||
// nothing was typed. So we disable the completion if a
|
||||
bool SSearch::eventFilter(QObject *target, QEvent *event)
|
||||
{
|
||||
LOGDEB1("SSearch::eventFilter: event\n");
|
||||
if (event->type() != QEvent::KeyPress) {
|
||||
return false;
|
||||
}
|
||||
LOGDEB1("SSearch::eventFilter: KeyPress event. Target " << target <<
|
||||
" popup "<<m_completer->popup() << " lineedit "<<queryText<< "\n");
|
||||
|
||||
QKeyEvent *keyEvent = (QKeyEvent *)event;
|
||||
if (keyEvent->key() == Qt::Key_Backspace && target==m_completer->popup()) {
|
||||
LOGDEB("SSearch::eventFilter: backspace\n");
|
||||
queryText->setCompleter(nullptr);
|
||||
queryText->backspace();
|
||||
return true;
|
||||
} else if (keyEvent->key()==Qt::Key_Delete &&target==m_completer->popup()) {
|
||||
LOGDEB("SSearch::eventFilter: delete\n");
|
||||
queryText->setCompleter(nullptr);
|
||||
queryText->del();
|
||||
return true;
|
||||
} else {
|
||||
if (nullptr == queryText->completer()) {
|
||||
queryText->setCompleter(m_completer);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
@ -36,12 +36,15 @@ class QTimer;
|
||||
|
||||
struct SSearchDef;
|
||||
|
||||
class SSearch;
|
||||
class QCompleter;
|
||||
|
||||
class RclCompleterModel : public QAbstractListModel {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
RclCompleterModel(QWidget *parent = 0)
|
||||
: QAbstractListModel(parent) {
|
||||
RclCompleterModel(SSearch *parent = 0)
|
||||
: QAbstractListModel((QWidget*)parent), m_parent(parent) {
|
||||
init();
|
||||
}
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
@ -55,6 +58,7 @@ private:
|
||||
int firstfromindex;
|
||||
QPixmap clockPixmap;
|
||||
QPixmap interroPixmap;
|
||||
SSearch *m_parent{nullptr};
|
||||
};
|
||||
|
||||
class SSearch : public QWidget, public Ui::SSearchBase {
|
||||
@ -80,6 +84,7 @@ public:
|
||||
// Restore ssearch UI from saved search
|
||||
virtual bool fromXML(const SSearchDef& fxml);
|
||||
virtual QString currentText();
|
||||
virtual bool eventFilter(QObject *target, QEvent *event);
|
||||
|
||||
public slots:
|
||||
virtual void searchTypeChanged(int);
|
||||
@ -97,6 +102,7 @@ private slots:
|
||||
virtual void onCompletionActivated(const QString&);
|
||||
virtual void restoreText();
|
||||
virtual void onHistoryClicked();
|
||||
virtual void onCompleterShown();
|
||||
|
||||
signals:
|
||||
void startSearch(std::shared_ptr<Rcl::SearchData>, bool);
|
||||
@ -108,12 +114,13 @@ private:
|
||||
int getPartialWord(QString& word);
|
||||
bool startSimpleSearch(const string& q, int maxexp = -1);
|
||||
|
||||
RclCompleterModel *m_completermodel{nullptr};
|
||||
QCompleter *m_completer{nullptr};
|
||||
/* We save multiword entries because the completer replaces them with
|
||||
the completion */
|
||||
QString m_savedEditText;
|
||||
/* Saved xml version of the search, as we start it */
|
||||
std::string m_xml;
|
||||
RclCompleterModel *m_completermodel{nullptr};
|
||||
};
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user