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();
|
endResetModel();
|
||||||
|
QTimer::singleShot(0, m_parent, SLOT(onCompleterShown()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSearch::init()
|
void SSearch::init()
|
||||||
@ -172,16 +173,18 @@ void SSearch::init()
|
|||||||
SLOT(searchTypeChanged(int)));
|
SLOT(searchTypeChanged(int)));
|
||||||
|
|
||||||
m_completermodel = new RclCompleterModel(this);
|
m_completermodel = new RclCompleterModel(this);
|
||||||
QCompleter *completer = new QCompleter(m_completermodel, this);
|
m_completer = new QCompleter(m_completermodel, this);
|
||||||
completer->setCompletionMode(QCompleter::UnfilteredPopupCompletion);
|
m_completer->setCompletionMode(QCompleter::UnfilteredPopupCompletion);
|
||||||
completer->setFilterMode(Qt::MatchContains);
|
m_completer->setFilterMode(Qt::MatchContains);
|
||||||
completer->setCaseSensitivity(Qt::CaseInsensitive);
|
m_completer->setCaseSensitivity(Qt::CaseInsensitive);
|
||||||
completer->setMaxVisibleItems(completervisibleitems);
|
m_completer->setMaxVisibleItems(completervisibleitems);
|
||||||
queryText->setCompleter(completer);
|
queryText->setCompleter(m_completer);
|
||||||
|
m_completer->popup()->installEventFilter(this);
|
||||||
|
queryText->installEventFilter(this);
|
||||||
connect(this, SIGNAL(partialWord(int, const QString&, const QString&)),
|
connect(this, SIGNAL(partialWord(int, const QString&, const QString&)),
|
||||||
m_completermodel,
|
m_completermodel,
|
||||||
SLOT(onPartialWord(int,const QString&,const QString&)));
|
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&)));
|
SLOT(onCompletionActivated(const QString&)));
|
||||||
connect(historyPB, SIGNAL(clicked()), this, SLOT(onHistoryClicked()));
|
connect(historyPB, SIGNAL(clicked()), this, SLOT(onHistoryClicked()));
|
||||||
}
|
}
|
||||||
@ -205,6 +208,77 @@ void SSearch::clearAll()
|
|||||||
queryText->clear();
|
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
|
// onCompletionActivated() is called when an entry is selected in the
|
||||||
// popup, but the edit text is going to be replaced in any case if
|
// 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 a current match (we can't prevent it in the signal). If
|
||||||
|
|||||||
@ -36,12 +36,15 @@ class QTimer;
|
|||||||
|
|
||||||
struct SSearchDef;
|
struct SSearchDef;
|
||||||
|
|
||||||
|
class SSearch;
|
||||||
|
class QCompleter;
|
||||||
|
|
||||||
class RclCompleterModel : public QAbstractListModel {
|
class RclCompleterModel : public QAbstractListModel {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RclCompleterModel(QWidget *parent = 0)
|
RclCompleterModel(SSearch *parent = 0)
|
||||||
: QAbstractListModel(parent) {
|
: QAbstractListModel((QWidget*)parent), m_parent(parent) {
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||||
@ -55,6 +58,7 @@ private:
|
|||||||
int firstfromindex;
|
int firstfromindex;
|
||||||
QPixmap clockPixmap;
|
QPixmap clockPixmap;
|
||||||
QPixmap interroPixmap;
|
QPixmap interroPixmap;
|
||||||
|
SSearch *m_parent{nullptr};
|
||||||
};
|
};
|
||||||
|
|
||||||
class SSearch : public QWidget, public Ui::SSearchBase {
|
class SSearch : public QWidget, public Ui::SSearchBase {
|
||||||
@ -80,6 +84,7 @@ public:
|
|||||||
// Restore ssearch UI from saved search
|
// Restore ssearch UI from saved search
|
||||||
virtual bool fromXML(const SSearchDef& fxml);
|
virtual bool fromXML(const SSearchDef& fxml);
|
||||||
virtual QString currentText();
|
virtual QString currentText();
|
||||||
|
virtual bool eventFilter(QObject *target, QEvent *event);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
virtual void searchTypeChanged(int);
|
virtual void searchTypeChanged(int);
|
||||||
@ -97,6 +102,7 @@ private slots:
|
|||||||
virtual void onCompletionActivated(const QString&);
|
virtual void onCompletionActivated(const QString&);
|
||||||
virtual void restoreText();
|
virtual void restoreText();
|
||||||
virtual void onHistoryClicked();
|
virtual void onHistoryClicked();
|
||||||
|
virtual void onCompleterShown();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void startSearch(std::shared_ptr<Rcl::SearchData>, bool);
|
void startSearch(std::shared_ptr<Rcl::SearchData>, bool);
|
||||||
@ -108,12 +114,13 @@ private:
|
|||||||
int getPartialWord(QString& word);
|
int getPartialWord(QString& word);
|
||||||
bool startSimpleSearch(const string& q, int maxexp = -1);
|
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
|
/* We save multiword entries because the completer replaces them with
|
||||||
the completion */
|
the completion */
|
||||||
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