diff --git a/src/Gui/Dialogs/DlgExpressionInput.cpp b/src/Gui/Dialogs/DlgExpressionInput.cpp index a568f9d6d2..ebc83d90d8 100644 --- a/src/Gui/Dialogs/DlgExpressionInput.cpp +++ b/src/Gui/Dialogs/DlgExpressionInput.cpp @@ -40,6 +40,7 @@ #include #include #include +#include #include "Dialogs/DlgExpressionInput.h" #include "ui_DlgExpressionInput.h" @@ -64,7 +65,6 @@ DlgExpressionInput::DlgExpressionInput(const App::ObjectIdentifier & _path, , path(_path) , discarded(false) , impliedUnit(_impliedUnit) - , minimumWidth(10) , varSetsVisible(false) , comboBoxGroup(this) { @@ -114,7 +114,11 @@ DlgExpressionInput::DlgExpressionInput(const App::ObjectIdentifier & _path, setAttribute(Qt::WA_TranslucentBackground, true); } else { + ui->expression->setMinimumWidth(300); ui->expression->setMinimumHeight(50); + ui->msg->setWordWrap(true); + ui->msg->setMaximumHeight(200); + ui->msg->setMinimumWidth(280); ui->horizontalSpacer_3->changeSize(0, 2); ui->verticalLayout->setContentsMargins(9, 9, 9, 9); this->adjustSize(); @@ -348,12 +352,12 @@ void DlgExpressionInput::checkExpression(const QString& text) } numberRange.throwIfOutOfRange(value); - - ui->msg->setText(msg); + message = msg.toStdString(); } else { - ui->msg->setText(QString::fromStdString(result->toString())); + message = result->toString(); } + setMsgText(); } } @@ -382,7 +386,8 @@ void DlgExpressionInput::textChanged() } } catch (Base::Exception & e) { - ui->msg->setText(QString::fromUtf8(e.what())); + message = e.what(); + setMsgText(); QPalette p(ui->msg->palette()); p.setColor(QPalette::WindowText, Qt::red); ui->msg->setPalette(p); @@ -396,19 +401,6 @@ void DlgExpressionInput::setDiscarded() reject(); } -void DlgExpressionInput::setExpressionInputSize(int width, int height) -{ - if (ui->expression->minimumHeight() < height) { - ui->expression->setMinimumHeight(height); - } - - if (ui->expression->minimumWidth() < width) { - ui->expression->setMinimumWidth(width); - } - - minimumWidth = width; -} - void DlgExpressionInput::mouseReleaseEvent(QMouseEvent* event) { Q_UNUSED(event); @@ -926,4 +918,42 @@ bool DlgExpressionInput::needReportOnVarSet() return reportGroup(comboBoxGroup.currentText()) || reportName(); } +void DlgExpressionInput::resizeEvent(QResizeEvent *event) +{ + // When the dialog is resized, message text may need to be re-wrapped + if (!this->message.empty() && event->size() != event->oldSize()) { + setMsgText(); + } + QDialog::resizeEvent(event); +} + +void DlgExpressionInput::setMsgText() +{ + if (!this->message.size()) { + return; + } + + const QFontMetrics msgFontMetrics{ ui->msg->font() }; + + // find words longer than length of msg widget + // then insert newline to wrap it + std::string wrappedMsg{}; + static constexpr int msgContentMargins = 50; + const int maxWordLength = (ui->msg->width() - msgContentMargins) / msgFontMetrics.averageCharWidth(); + + const auto wrappableWordPattern = std::regex{ "\\S{" + std::to_string(maxWordLength) + "}" }; + auto it = std::sregex_iterator{ this->message.cbegin(), this->message.cend(), wrappableWordPattern }; + const auto itEnd = std::sregex_iterator{}; + + int lastPos = 0; + for (; it != itEnd; ++it) { + wrappedMsg += this->message.substr(lastPos, it->position() - lastPos); + wrappedMsg += it->str() + "\n"; + lastPos = it->position() + it->length(); + } + wrappedMsg += this->message.substr(lastPos); + + ui->msg->setText(QString::fromStdString(wrappedMsg)); +} + #include "moc_DlgExpressionInput.cpp" diff --git a/src/Gui/Dialogs/DlgExpressionInput.h b/src/Gui/Dialogs/DlgExpressionInput.h index 90b6c1760a..0bc88fdda9 100644 --- a/src/Gui/Dialogs/DlgExpressionInput.h +++ b/src/Gui/Dialogs/DlgExpressionInput.h @@ -77,7 +77,6 @@ public: bool discardedFormula() const { return discarded; } QPoint expressionPosition() const; - void setExpressionInputSize(int width, int height); public Q_SLOTS: void show(); @@ -86,6 +85,7 @@ public Q_SLOTS: protected: void mouseReleaseEvent(QMouseEvent* event) override; void mousePressEvent(QMouseEvent* event) override; + void resizeEvent(QResizeEvent* event) override; private: Base::Type getTypePath(); @@ -109,6 +109,7 @@ private: const App::DocumentObject* obj, QString& message) const; bool isGroupNameValid(const QString& nameGroup, QString& message) const; + void setMsgText(); private Q_SLOTS: void textChanged(); @@ -127,7 +128,7 @@ private: const Base::Unit impliedUnit; NumberRange numberRange; - int minimumWidth; + std::string message; bool varSetsVisible; QPushButton* okBtn = nullptr; diff --git a/src/Gui/Dialogs/DlgExpressionInput.ui b/src/Gui/Dialogs/DlgExpressionInput.ui index 3d5dc2f374..3e21e2a85d 100644 --- a/src/Gui/Dialogs/DlgExpressionInput.ui +++ b/src/Gui/Dialogs/DlgExpressionInput.ui @@ -18,7 +18,7 @@ - 300 + 350 0 @@ -48,7 +48,7 @@ - + 0 0 @@ -71,6 +71,12 @@ + + + 0 + 0 + + Result @@ -78,6 +84,12 @@ + + + 0 + 0 + + @@ -130,6 +142,9 @@ Qt::Orientation::Horizontal + + QSizePolicy::Policy::Fixed + 0 @@ -145,7 +160,7 @@ - + 0 0 diff --git a/src/Gui/QuantitySpinBox.cpp b/src/Gui/QuantitySpinBox.cpp index b7febd34e6..9f380120d8 100644 --- a/src/Gui/QuantitySpinBox.cpp +++ b/src/Gui/QuantitySpinBox.cpp @@ -618,7 +618,6 @@ void QuantitySpinBox::openFormulaDialog() QPoint pos = mapToGlobal(QPoint(0,0)); box->move(pos-box->expressionPosition()); - box->setExpressionInputSize(width(), height()); Gui::adjustDialogPosition(box); Q_EMIT showFormulaDialog(true); diff --git a/src/Gui/SpinBox.cpp b/src/Gui/SpinBox.cpp index 89287b4f54..2fd840fecc 100644 --- a/src/Gui/SpinBox.cpp +++ b/src/Gui/SpinBox.cpp @@ -206,7 +206,6 @@ void ExpressionSpinBox::openFormulaDialog() QPoint pos = spinbox->mapToGlobal(QPoint(0,0)); box->move(pos-box->expressionPosition()); - box->setExpressionInputSize(spinbox->width(), spinbox->height()); Gui::adjustDialogPosition(box); } diff --git a/src/Gui/Widgets.cpp b/src/Gui/Widgets.cpp index 17d1b1a397..a4d1f1505e 100644 --- a/src/Gui/Widgets.cpp +++ b/src/Gui/Widgets.cpp @@ -1606,7 +1606,6 @@ void ExpLineEdit::openFormulaDialog() QPoint pos = mapToGlobal(QPoint(0,0)); box->move(pos-box->expressionPosition()); - box->setExpressionInputSize(width(), height()); Gui::adjustDialogPosition(box); }