Gui: several fixes for expression search box:

+ rename method setMatchExact() to setExactMatch()
+ move handling of user-defined parameters to class ExpressionParameter
+ Qt::MatchExactly is not supported by QCompleter, use Qt::MatchStartsWith instead
+ add possibility to change match behaviour via context-menu
This commit is contained in:
wmayer
2020-09-13 18:34:16 +02:00
parent d6748a030f
commit 2c744264d6
4 changed files with 105 additions and 22 deletions

View File

@@ -76,7 +76,7 @@ DlgPropertyLink::DlgPropertyLink(QWidget* parent)
ui->typeTree->hide();
ui->searchBox->installEventFilter(this);
ui->searchBox->setNoProperty(true);
ui->searchBox->setMatchExact(false);
ui->searchBox->setExactMatch(Gui::ExpressionParameter::instance()->isExactMatch());
timer = new QTimer(this);
timer->setSingleShot(true);

View File

@@ -1,10 +1,12 @@
#include "PreCompiled.h"
#ifndef _PreComp_
#include <QContextMenuEvent>
#include <QStandardItem>
#include <QStandardItemModel>
#include <QLineEdit>
#include <QAbstractItemView>
#include <QMenu>
#include <QTextBlock>
#endif
@@ -536,11 +538,8 @@ ExpressionLineEdit::ExpressionLineEdit(QWidget *parent, bool noProperty)
, completer(0)
, block(true)
, noProperty(noProperty)
, exactMatch(false)
{
auto handle = GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Expression");
matchExact = handle->GetBool("CompleterMatchExact", false);
connect(this, SIGNAL(textEdited(const QString&)), this, SLOT(slotTextChanged(const QString&)));
}
@@ -555,7 +554,7 @@ void ExpressionLineEdit::setDocumentObject(const App::DocumentObject * currentDo
completer->setWidget(this);
completer->setCaseSensitivity(Qt::CaseInsensitive);
#if QT_VERSION>=QT_VERSION_CHECK(5,2,0)
if (!matchExact)
if (!exactMatch)
completer->setFilterMode(Qt::MatchContains);
#endif
connect(completer, SIGNAL(activated(QString)), this, SLOT(slotCompleteText(QString)));
@@ -570,11 +569,11 @@ void ExpressionLineEdit::setNoProperty(bool enabled) {
completer->setNoProperty(enabled);
}
void ExpressionLineEdit::setMatchExact(bool enabled) {
matchExact = enabled;
void ExpressionLineEdit::setExactMatch(bool enabled) {
exactMatch = enabled;
#if QT_VERSION>=QT_VERSION_CHECK(5,2,0)
if (completer)
completer->setFilterMode(matchExact ? Qt::MatchExactly : Qt::MatchContains);
completer->setFilterMode(exactMatch ? Qt::MatchStartsWith : Qt::MatchContains);
#endif
}
@@ -615,6 +614,34 @@ void ExpressionLineEdit::keyPressEvent(QKeyEvent *e) {
QLineEdit::keyPressEvent(e);
}
void ExpressionLineEdit::contextMenuEvent(QContextMenuEvent *event)
{
#if QT_VERSION >= QT_VERSION_CHECK(5,2,0)
QMenu *menu = createStandardContextMenu();
menu->addSeparator();
QAction* match = menu->addAction(tr("Exact match"));
if (completer) {
match->setCheckable(true);
match->setChecked(completer->filterMode() == Qt::MatchStartsWith);
}
else {
match->setVisible(false);
}
QAction* action = menu->exec(event->globalPos());
if (completer) {
if (action == match)
setExactMatch(match->isChecked());
}
delete menu;
#else
QLineEdit::contextMenuEvent(event);
#endif
}
///////////////////////////////////////////////////////////////////////
@@ -622,19 +649,16 @@ ExpressionTextEdit::ExpressionTextEdit(QWidget *parent)
: QPlainTextEdit(parent)
, completer(0)
, block(true)
, exactMatch(false)
{
auto handle = GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Expression");
matchExact = handle->GetBool("CompleterMatchExact", false);
connect(this, SIGNAL(textChanged()), this, SLOT(slotTextChanged()));
}
void ExpressionTextEdit::setMatchExact(bool enabled) {
matchExact = enabled;
void ExpressionTextEdit::setExactMatch(bool enabled) {
exactMatch = enabled;
#if QT_VERSION>=QT_VERSION_CHECK(5,2,0)
if (completer)
completer->setFilterMode(matchExact ? Qt::MatchExactly : Qt::MatchContains);
completer->setFilterMode(exactMatch ? Qt::MatchStartsWith : Qt::MatchContains);
#endif
}
@@ -648,7 +672,7 @@ void ExpressionTextEdit::setDocumentObject(const App::DocumentObject * currentDo
if (currentDocObj != 0) {
completer = new ExpressionCompleter(currentDocObj, this);
#if QT_VERSION>=QT_VERSION_CHECK(5,2,0)
if (!matchExact)
if (!exactMatch)
completer->setFilterMode(Qt::MatchContains);
#endif
completer->setWidget(this);
@@ -697,4 +721,54 @@ void ExpressionTextEdit::keyPressEvent(QKeyEvent *e) {
QPlainTextEdit::keyPressEvent(e);
}
void ExpressionTextEdit::contextMenuEvent(QContextMenuEvent *event)
{
#if QT_VERSION >= QT_VERSION_CHECK(5,2,0)
QMenu *menu = createStandardContextMenu();
menu->addSeparator();
QAction* match = menu->addAction(tr("Exact match"));
if (completer) {
match->setCheckable(true);
match->setChecked(completer->filterMode() == Qt::MatchStartsWith);
}
else {
match->setVisible(false);
}
QAction* action = menu->exec(event->globalPos());
if (completer) {
if (action == match)
setExactMatch(match->isChecked());
}
delete menu;
#else
QPlainTextEdit::contextMenuEvent(event);
#endif
}
///////////////////////////////////////////////////////////////////////
ExpressionParameter* ExpressionParameter::instance()
{
static ExpressionParameter* inst = new ExpressionParameter();
return inst;
}
bool ExpressionParameter::isCaseSensitive() const
{
auto handle = GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Expression");
return handle->GetBool("CompleterCaseSensitive", false);
}
bool ExpressionParameter::isExactMatch() const
{
auto handle = GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Expression");
return handle->GetBool("CompleterMatchExact", false);
}
#include "moc_ExpressionCompleter.cpp"

View File

@@ -68,7 +68,7 @@ public:
bool completerActive() const;
void hideCompleter();
void setNoProperty(bool enabled=true);
void setMatchExact(bool enabled=true);
void setExactMatch(bool enabled=true);
Q_SIGNALS:
void textChanged2(QString text, int pos);
public Q_SLOTS:
@@ -76,11 +76,12 @@ public Q_SLOTS:
void slotCompleteText(const QString & completionPrefix);
protected:
void keyPressEvent(QKeyEvent * event);
void contextMenuEvent(QContextMenuEvent * event);
private:
ExpressionCompleter * completer;
bool block;
bool noProperty;
bool matchExact;
bool exactMatch;
};
class GuiExport ExpressionTextEdit : public QPlainTextEdit {
@@ -90,9 +91,10 @@ public:
void setDocumentObject(const App::DocumentObject *currentDocObj);
bool completerActive() const;
void hideCompleter();
void setMatchExact(bool enabled=true);
void setExactMatch(bool enabled=true);
protected:
void keyPressEvent(QKeyEvent * event);
void contextMenuEvent(QContextMenuEvent * event);
Q_SIGNALS:
void textChanged2(QString text, int pos);
public Q_SLOTS:
@@ -101,7 +103,14 @@ public Q_SLOTS:
private:
ExpressionCompleter * completer;
bool block;
bool matchExact;
bool exactMatch;
};
class GuiExport ExpressionParameter {
public:
static ExpressionParameter *instance();
bool isCaseSensitive() const;
bool isExactMatch() const;
};
}

View File

@@ -2838,7 +2838,7 @@ TreePanel::TreePanel(const char *name, QWidget* parent)
this, SLOT(showEditor()));
this->searchBox = new Gui::ExpressionLineEdit(this,true);
static_cast<ExpressionLineEdit*>(this->searchBox)->setMatchExact(false);
static_cast<ExpressionLineEdit*>(this->searchBox)->setExactMatch(Gui::ExpressionParameter::instance()->isExactMatch());
pLayout->addWidget(this->searchBox);
this->searchBox->hide();
this->searchBox->installEventFilter(this);