Skip to content

Commit

Permalink
Gui: several fixes for expression search box:
Browse files Browse the repository at this point in the history
+ 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
  • Loading branch information
wwmayer committed Sep 13, 2020
1 parent d6748a0 commit 2c74426
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 22 deletions.
2 changes: 1 addition & 1 deletion src/Gui/DlgPropertyLink.cpp
Expand Up @@ -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);
Expand Down
106 changes: 90 additions & 16 deletions src/Gui/ExpressionCompleter.cpp
@@ -1,10 +1,12 @@
#include "PreCompiled.h"

#ifndef _PreComp_
#include <QContextMenuEvent>
#include <QStandardItem>
#include <QStandardItemModel>
#include <QLineEdit>
#include <QAbstractItemView>
#include <QMenu>
#include <QTextBlock>
#endif

Expand Down Expand Up @@ -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&)));
}

Expand All @@ -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)));
Expand All @@ -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
}

Expand Down Expand Up @@ -615,26 +614,51 @@ 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
}


///////////////////////////////////////////////////////////////////////

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
}

Expand All @@ -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);
Expand Down Expand Up @@ -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"
17 changes: 13 additions & 4 deletions src/Gui/ExpressionCompleter.h
Expand Up @@ -68,19 +68,20 @@ class GuiExport ExpressionLineEdit : public QLineEdit {
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:
void slotTextChanged(const QString & text);
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 {
Expand All @@ -90,9 +91,10 @@ class GuiExport ExpressionTextEdit : public QPlainTextEdit {
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:
Expand All @@ -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;
};

}
Expand Down
2 changes: 1 addition & 1 deletion src/Gui/Tree.cpp
Expand Up @@ -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);
Expand Down

0 comments on commit 2c74426

Please sign in to comment.