From a39c44e483e20e0ac30f92d2e0a6cdce15735974 Mon Sep 17 00:00:00 2001 From: wmayer Date: Sun, 18 May 2025 10:30:55 +0200 Subject: [PATCH] Tools: Add ExpressionLineEdit to QtDesigner plugin --- src/Tools/plugins/widget/customwidgets.cpp | 62 ++++++++++++++++++++++ src/Tools/plugins/widget/customwidgets.h | 28 ++++++++++ src/Tools/plugins/widget/plugin.cpp | 51 ++++++++++++++++++ 3 files changed, 141 insertions(+) diff --git a/src/Tools/plugins/widget/customwidgets.cpp b/src/Tools/plugins/widget/customwidgets.cpp index 79836644b2..2514dbc18f 100644 --- a/src/Tools/plugins/widget/customwidgets.cpp +++ b/src/Tools/plugins/widget/customwidgets.cpp @@ -22,11 +22,13 @@ #include +#include #include #include #include #include #include +#include #include #include #include @@ -544,6 +546,66 @@ void InputField::setHistorySize(int i) // -------------------------------------------------------------------- +ExpressionLineEdit::ExpressionLineEdit(QWidget* parent) + : QLineEdit(parent) + , exactMatch {false} +{ + completer = new QCompleter(this); + connect(this, &QLineEdit::textEdited, this, &ExpressionLineEdit::slotTextChanged); +} + +void ExpressionLineEdit::setExactMatch(bool enabled) +{ + exactMatch = enabled; + if (completer) { + completer->setFilterMode(exactMatch ? Qt::MatchStartsWith : Qt::MatchContains); + } +} + +void ExpressionLineEdit::slotTextChanged(const QString& text) +{ + Q_EMIT textChanged2(text, cursorPosition()); +} + +void ExpressionLineEdit::slotCompleteText(const QString& completionPrefix, bool isActivated) +{ + Q_UNUSED(completionPrefix) + Q_UNUSED(isActivated) +} + +void ExpressionLineEdit::slotCompleteTextHighlighted(const QString& completionPrefix) +{ + slotCompleteText(completionPrefix, false); +} + +void ExpressionLineEdit::slotCompleteTextSelected(const QString& completionPrefix) +{ + slotCompleteText(completionPrefix, true); +} + +void ExpressionLineEdit::keyPressEvent(QKeyEvent* e) +{ + QLineEdit::keyPressEvent(e); +} + +void ExpressionLineEdit::contextMenuEvent(QContextMenuEvent* event) +{ + QMenu* menu = createStandardContextMenu(); + + if (completer) { + menu->addSeparator(); + QAction* match = menu->addAction(tr("Exact match")); + match->setCheckable(true); + match->setChecked(completer->filterMode() == Qt::MatchStartsWith); + QObject::connect(match, &QAction::toggled, this, &Gui::ExpressionLineEdit::setExactMatch); + } + menu->setAttribute(Qt::WA_DeleteOnClose); + + menu->popup(event->globalPos()); +} + +// -------------------------------------------------------------------- + namespace Base { diff --git a/src/Tools/plugins/widget/customwidgets.h b/src/Tools/plugins/widget/customwidgets.h index c80966b493..ed91cf2c24 100644 --- a/src/Tools/plugins/widget/customwidgets.h +++ b/src/Tools/plugins/widget/customwidgets.h @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -386,6 +387,33 @@ private: // ------------------------------------------------------------------------------ +class ExpressionLineEdit: public QLineEdit +{ + Q_OBJECT +public: + ExpressionLineEdit(QWidget* parent = nullptr); + +public Q_SLOTS: + void slotTextChanged(const QString& text); + void slotCompleteText(const QString& completionPrefix, bool isActivated); + void slotCompleteTextHighlighted(const QString& completionPrefix); + void slotCompleteTextSelected(const QString& completionPrefix); + void setExactMatch(bool enabled = true); + +protected: + void keyPressEvent(QKeyEvent* event) override; + void contextMenuEvent(QContextMenuEvent* event) override; + +Q_SIGNALS: + void textChanged2(QString text, int pos); + +private: + QCompleter* completer; + bool exactMatch; +}; + +// ------------------------------------------------------------------------------ + class QuantitySpinBoxPrivate; class QuantitySpinBox: public QAbstractSpinBox { diff --git a/src/Tools/plugins/widget/plugin.cpp b/src/Tools/plugins/widget/plugin.cpp index 62b9672fff..dee5844e13 100644 --- a/src/Tools/plugins/widget/plugin.cpp +++ b/src/Tools/plugins/widget/plugin.cpp @@ -523,6 +523,56 @@ public: } }; +class ExpressionLineEditPlugin: public QDesignerCustomWidgetInterface +{ + Q_INTERFACES(QDesignerCustomWidgetInterface) +public: + ExpressionLineEditPlugin() + {} + QWidget* createWidget(QWidget* parent) + { + return new Gui::ExpressionLineEdit(parent); + } + QString group() const + { + return QLatin1String("Input Widgets"); + } + QIcon icon() const + { + return QIcon(QPixmap(inputfield_pixmap)); + } + QString includeFile() const + { + return QLatin1String("Gui/InputField.h"); + } + QString toolTip() const + { + return QLatin1String("Expression line edit"); + } + QString whatsThis() const + { + return QLatin1String("A widget to work with expressions."); + } + bool isContainer() const + { + return false; + } + QString domXml() const + { + return "\n" + " \n" + " \n" + " \n" + " \n" + " \n" + ""; + } + QString name() const + { + return QLatin1String("Gui::ExpressionLineEdit"); + } +}; + /* XPM */ static const char* quantityspinbox_pixmap[] = {"22 22 6 1", "a c #000000", @@ -1653,6 +1703,7 @@ QList CustomWidgetPlugin::customWidgets() const cw.append(new FileChooserPlugin); cw.append(new AccelLineEditPlugin); cw.append(new ActionSelectorPlugin); + cw.append(new ExpressionLineEditPlugin); cw.append(new InputFieldPlugin); cw.append(new QuantitySpinBoxPlugin); cw.append(new CommandIconViewPlugin);