From 68ff9989edb7ae04e7aff9034abc6a5099bb097a Mon Sep 17 00:00:00 2001 From: wmayer Date: Mon, 9 Sep 2024 12:28:22 +0200 Subject: [PATCH] Core: Placement dialog + replace separate buttons with QDialogButtonBox + add convenience method setPlacementAndBindObject + use const DocumentObject --- src/Gui/Placement.cpp | 142 +++++++++++++++++++++++++++--------- src/Gui/Placement.h | 19 +++-- src/Gui/Placement.ui | 95 ++++++++++-------------- src/Gui/SelectionObject.cpp | 2 +- src/Gui/SelectionObject.h | 2 +- src/Gui/Transform.cpp | 10 +-- 6 files changed, 163 insertions(+), 107 deletions(-) diff --git a/src/Gui/Placement.cpp b/src/Gui/Placement.cpp index 896b0ff410..307727c363 100644 --- a/src/Gui/Placement.cpp +++ b/src/Gui/Placement.cpp @@ -80,7 +80,8 @@ public: return false; } - static App::PropertyPlacement* getProperty(App::DocumentObject* obj, const std::string& propertyName) + static App::PropertyPlacement* getProperty(const App::DocumentObject* obj, + const std::string& propertyName) { std::map props; obj->getPropertyMap(props); @@ -197,33 +198,37 @@ void PlacementHandler::revertTransformation() } } -std::vector PlacementHandler::getObjects(Gui::Document* document) const +std::vector PlacementHandler::getObjects(const Gui::Document* document) const { - return document->getDocument()->getObjectsOfType(App::DocumentObject::getClassTypeId()); + auto objs = document->getDocument()->getObjectsOfType(App::DocumentObject::getClassTypeId()); + std::vector list; + list.insert(list.begin(), objs.begin(), objs.end()); + return list; } -std::vector PlacementHandler::getSelectedObjects(Gui::Document* document) const +std::vector PlacementHandler::getSelectedObjects(const Gui::Document* document) const { App::Document* doc = document->getDocument(); - std::vector list; + std::vector list; list.reserve(selectionObjects.size()); for (const auto& it : selectionObjects) { const App::DocumentObject* obj = it.getObject(); if (obj && obj->getDocument() == doc) { - list.push_back(const_cast(obj)); // NOLINT + list.push_back(obj); } } - if (!list.empty()) { - return list; + if (list.empty()) { + auto objs = Gui::Selection().getObjectsOfType(App::DocumentObject::getClassTypeId(), doc->getName()); + list.insert(list.begin(), objs.begin(), objs.end()); } - return Gui::Selection().getObjectsOfType(App::DocumentObject::getClassTypeId(), doc->getName()); + return list; } void PlacementHandler::revertTransformationOfViewProviders(Gui::Document* document) { - std::vector obj = getObjects(document); + std::vector obj = getObjects(document); for (const auto & it : obj) { auto property = find_placement::getProperty(it, this->propertyName); if (property) { @@ -252,7 +257,7 @@ void PlacementHandler::applyPlacement(const Base::Placement& p, bool incremental if (!document) return; - std::vector sel = getSelectedObjects(document); + std::vector sel = getSelectedObjects(document); if (!sel.empty()) { for (const auto & it : sel) { applyPlacement(document, it, p, incremental); @@ -263,7 +268,8 @@ void PlacementHandler::applyPlacement(const Base::Placement& p, bool incremental } } -void PlacementHandler::applyPlacement(Gui::Document* document, App::DocumentObject* obj, const Base::Placement& p, bool incremental) +void PlacementHandler::applyPlacement(const Gui::Document* document, const App::DocumentObject* obj, + const Base::Placement& p, bool incremental) { auto property = find_placement::getProperty(obj, this->propertyName); if (property) { @@ -299,7 +305,7 @@ void PlacementHandler::applyPlacement(const QString& data, bool incremental) openCommandIfActive(document); } else { - std::vector sel = getSelectedObjects(document); + std::vector sel = getSelectedObjects(document); if (!sel.empty()) { openCommandIfActive(document); for (const auto & it : sel) { @@ -314,7 +320,7 @@ void PlacementHandler::applyPlacement(const QString& data, bool incremental) } } -void PlacementHandler::applyPlacement(App::DocumentObject* obj, const QString& data, bool incremental) +void PlacementHandler::applyPlacement(const App::DocumentObject* obj, const QString& data, bool incremental) { auto property = find_placement::getProperty(obj, this->propertyName); if (property) { @@ -330,7 +336,7 @@ void PlacementHandler::applyPlacement(App::DocumentObject* obj, const QString& d } } -QString PlacementHandler::getIncrementalPlacement(App::DocumentObject* obj, const QString& data) const +QString PlacementHandler::getIncrementalPlacement(const App::DocumentObject* obj, const QString& data) const { return QString::fromLatin1( R"(App.getDocument("%1").%2.%3=%4.multiply(App.getDocument("%1").%2.%3))") @@ -340,7 +346,7 @@ QString PlacementHandler::getIncrementalPlacement(App::DocumentObject* obj, cons data); } -QString PlacementHandler::getSimplePlacement(App::DocumentObject* obj, const QString& data) const +QString PlacementHandler::getSimplePlacement(const App::DocumentObject* obj, const QString& data) const { return QString::fromLatin1( "App.getDocument(\"%1\").%2.%3=%4") @@ -472,7 +478,8 @@ void Placement::setupUi() void Placement::setupConnections() { - connect(ui->applyButton, &QPushButton::clicked, + QPushButton* applyButton = ui->buttonBox->button(QDialogButtonBox::Apply); + connect(applyButton, &QPushButton::clicked, this, &Placement::onApplyButtonClicked); connect(ui->applyIncrementalPlacement, &QCheckBox::toggled, this, &Placement::onApplyIncrementalPlacementToggled); @@ -542,9 +549,7 @@ void Placement::setupRotationMethod() void Placement::showDefaultButtons(bool ok) { - ui->oKButton->setVisible(ok); - ui->closeButton->setVisible(ok); - ui->applyButton->setVisible(ok); + ui->buttonBox->setVisible(ok); ui->buttonBoxLayout->invalidate(); if (ok) { ui->buttonBoxLayout->insertSpacerItem(0, ui->buttonBoxSpacer); @@ -882,9 +887,34 @@ void Placement::setIgnoreTransactions(bool value) */ void Placement::bindObject() { - // clang-format off if (const App::DocumentObject* obj = handler.getFirstOfSelection()) { std::string propertyName = handler.getPropertyName(); + bindProperty(obj, propertyName); + } +} + +/*! + * \brief Placement::setPlacementAndBindObject + * Sets the placement, binds the spin boxes to the placement components of the passed object and + * sets the name of the placement property. + */ +void Placement::setPlacementAndBindObject(const App::DocumentObject* obj, const std::string& propertyName) +{ + if (obj) { + App::PropertyPlacement* prop = find_placement::getProperty(obj, propertyName); + if (prop) { + setPlacement(prop->getValue()); + handler.setPropertyName(propertyName); + bindProperty(obj, propertyName); + handler.setSelection({SelectionObject{obj}}); + } + } +} + +void Placement::bindProperty(const App::DocumentObject* obj, const std::string& propertyName) +{ + // clang-format off + if (obj) { App::ObjectIdentifier path = App::ObjectIdentifier::parse(obj, propertyName); if (path.getProperty()) { ui->xPos->bind(App::ObjectIdentifier::parse(obj, propertyName + std::string(".Base.x"))); @@ -1140,6 +1170,12 @@ void TaskPlacement::bindObject() widget->bindObject(); } +void TaskPlacement::setPlacementAndBindObject(const App::DocumentObject* obj, + const std::string& propertyName) +{ + widget->setPlacementAndBindObject(obj, propertyName); +} + void TaskPlacement::open() { widget->open(); @@ -1198,21 +1234,36 @@ void TaskPlacementPy::init_type() behaviors().supportGetattr(); behaviors().supportSetattr(); // clang-format off - add_varargs_method("setPropertyName",&TaskPlacementPy::setPropertyName,"setPropertyName(string)"); - add_varargs_method("setPlacement",&TaskPlacementPy::setPlacement,"setPlacement(Placement)"); - add_varargs_method("setSelection",&TaskPlacementPy::setSelection,"setSelection(list)"); - add_varargs_method("bindObject",&TaskPlacementPy::bindObject,"bindObject()"); - - add_varargs_method("setIgnoreTransactions",&TaskPlacementPy::setIgnoreTransactions, "setIgnoreTransactions(bool)"); - add_varargs_method("showDefaultButtons",&TaskPlacementPy::showDefaultButtons, "showDefaultButtons(bool)"); - add_varargs_method("accept",&TaskPlacementPy::accept,"accept()"); - add_varargs_method("reject",&TaskPlacementPy::reject,"reject()"); - add_varargs_method("clicked",&TaskPlacementPy::clicked,"clicked()"); - add_varargs_method("open",&TaskPlacementPy::open,"open()"); - add_varargs_method("isAllowedAlterDocument",&TaskPlacementPy::isAllowedAlterDocument,"isAllowedAlterDocument()"); - add_varargs_method("isAllowedAlterView",&TaskPlacementPy::isAllowedAlterView,"isAllowedAlterView()"); - add_varargs_method("isAllowedAlterSelection",&TaskPlacementPy::isAllowedAlterSelection,"isAllowedAlterSelection()"); - add_varargs_method("getStandardButtons",&TaskPlacementPy::getStandardButtons,"getStandardButtons()"); + add_varargs_method("setPropertyName", &TaskPlacementPy::setPropertyName, + "setPropertyName(string)"); + add_varargs_method("setPlacement", &TaskPlacementPy::setPlacement, + "setPlacement(Placement)"); + add_varargs_method("setSelection", &TaskPlacementPy::setSelection, + "setSelection(list)"); + add_varargs_method("bindObject", &TaskPlacementPy::bindObject, + "bindObject()"); + add_varargs_method("setPlacementAndBindObject", &TaskPlacementPy::setPlacementAndBindObject, + "setPlacementAndBindObject(obj, string)"); + add_varargs_method("setIgnoreTransactions", &TaskPlacementPy::setIgnoreTransactions, + "setIgnoreTransactions(bool)"); + add_varargs_method("showDefaultButtons", &TaskPlacementPy::showDefaultButtons, + "showDefaultButtons(bool)"); + add_varargs_method("accept", &TaskPlacementPy::accept, + "accept()"); + add_varargs_method("reject", &TaskPlacementPy::reject, + "reject()"); + add_varargs_method("clicked", &TaskPlacementPy::clicked, + "clicked()"); + add_varargs_method("open", &TaskPlacementPy::open, + "open()"); + add_varargs_method("isAllowedAlterDocument", &TaskPlacementPy::isAllowedAlterDocument, + "isAllowedAlterDocument()"); + add_varargs_method("isAllowedAlterView", &TaskPlacementPy::isAllowedAlterView, + "isAllowedAlterView()"); + add_varargs_method("isAllowedAlterSelection", &TaskPlacementPy::isAllowedAlterSelection, + "isAllowedAlterSelection()"); + add_varargs_method("getStandardButtons", &TaskPlacementPy::getStandardButtons, + "getStandardButtons()"); // clang-format on } @@ -1311,6 +1362,25 @@ Py::Object TaskPlacementPy::bindObject(const Py::Tuple& args) if (widget) { widget->bindObject(); } + + return Py::None(); +} + +Py::Object TaskPlacementPy::setPlacementAndBindObject(const Py::Tuple& args) +{ + Py::Object object = args[0]; + Py::String name = args[1]; + std::string propName = static_cast(name); + + if (PyObject_TypeCheck(object.ptr(), &App::DocumentObjectPy::Type)) { + auto py = static_cast(object.ptr()); + auto obj = py->getDocumentObjectPtr(); + + if (widget) { + widget->setPlacementAndBindObject(obj, propName); + } + } + return Py::None(); } diff --git a/src/Gui/Placement.h b/src/Gui/Placement.h index 0d99302b6e..bf6af51282 100644 --- a/src/Gui/Placement.h +++ b/src/Gui/Placement.h @@ -69,14 +69,15 @@ public: std::tuple> getSelectedPoints() const; private: - std::vector getObjects(Gui::Document*) const; - std::vector getSelectedObjects(Gui::Document*) const; + std::vector getObjects(const Gui::Document*) const; + std::vector getSelectedObjects(const Gui::Document*) const; void revertTransformationOfViewProviders(Gui::Document*); void tryRecompute(Gui::Document*); - void applyPlacement(Gui::Document*, App::DocumentObject*, const Base::Placement& p, bool incremental); - void applyPlacement(App::DocumentObject*, const QString& p, bool incremental); - QString getIncrementalPlacement(App::DocumentObject*, const QString&) const; - QString getSimplePlacement(App::DocumentObject*, const QString&) const; + void applyPlacement(const Gui::Document*, const App::DocumentObject*, + const Base::Placement& p, bool incremental); + void applyPlacement(const App::DocumentObject*, const QString& p, bool incremental); + QString getIncrementalPlacement(const App::DocumentObject*, const QString&) const; + QString getSimplePlacement(const App::DocumentObject*, const QString&) const; void setupDocument(); void slotActiveDocument(const Gui::Document&); void openCommandIfActive(Gui::Document*); @@ -122,6 +123,8 @@ public: void setPropertyName(const std::string&); void setSelection(const std::vector&); void bindObject(); + void setPlacementAndBindObject(const App::DocumentObject* obj, + const std::string& propertyName); void setIgnoreTransactions(bool value); Base::Vector3d getDirection() const; void setPlacement(const Base::Placement&); @@ -149,6 +152,7 @@ private: void setupUnits(); void setupSignalMapper(); void setupRotationMethod(); + void bindProperty(const App::DocumentObject* obj, const std::string& propertyName); bool onApply(); void setPlacementData(const Base::Placement&); @@ -198,6 +202,8 @@ public: void setSelection(const std::vector&); void clearSelection(); void bindObject(); + void setPlacementAndBindObject(const App::DocumentObject* obj, + const std::string& propertyName); bool accept() override; bool reject() override; void clicked(int id) override; @@ -238,6 +244,7 @@ public: Py::Object setPlacement(const Py::Tuple&); Py::Object setSelection(const Py::Tuple&); Py::Object bindObject(const Py::Tuple&); + Py::Object setPlacementAndBindObject(const Py::Tuple&); Py::Object setIgnoreTransactions(const Py::Tuple&); Py::Object showDefaultButtons(const Py::Tuple&); diff --git a/src/Gui/Placement.ui b/src/Gui/Placement.ui index 72a6854ec4..b50ba72e02 100644 --- a/src/Gui/Placement.ui +++ b/src/Gui/Placement.ui @@ -6,8 +6,8 @@ 0 0 - 277 - 394 + 456 + 492 @@ -233,7 +233,7 @@ - + 1 @@ -415,7 +415,7 @@ - + @@ -487,23 +487,9 @@ - - - OK - - - - - - - Close - - - - - - - Apply + + + QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok @@ -525,44 +511,9 @@ yAxis zAxis applyIncrementalPlacement - oKButton - applyButton - closeButton - - oKButton - clicked() - Gui::Dialog::Placement - accept() - - - 164 - 252 - - - 8 - 28 - - - - - closeButton - clicked() - Gui::Dialog::Placement - reject() - - - 354 - 252 - - - 291 - 179 - - - rotationInput activated(int) @@ -579,5 +530,37 @@ + + buttonBox + accepted() + Gui::Dialog::Placement + accept() + + + 310 + 469 + + + 227 + 245 + + + + + buttonBox + rejected() + Gui::Dialog::Placement + reject() + + + 310 + 469 + + + 227 + 245 + + + diff --git a/src/Gui/SelectionObject.cpp b/src/Gui/SelectionObject.cpp index f705397b18..c8450a24cf 100644 --- a/src/Gui/SelectionObject.cpp +++ b/src/Gui/SelectionObject.cpp @@ -53,7 +53,7 @@ SelectionObject::SelectionObject(const Gui::SelectionChanges& msg) } } -SelectionObject::SelectionObject(App::DocumentObject* obj) +SelectionObject::SelectionObject(const App::DocumentObject* obj) { FeatName = obj->getNameInDocument(); DocName = obj->getDocument()->getName(); diff --git a/src/Gui/SelectionObject.h b/src/Gui/SelectionObject.h index 44e8e3b6bb..cc0d618246 100644 --- a/src/Gui/SelectionObject.h +++ b/src/Gui/SelectionObject.h @@ -50,7 +50,7 @@ public: /*! Constructs a SelectionObject from the SelectionChanges structure. */ explicit SelectionObject(const SelectionChanges& msg); - explicit SelectionObject(App::DocumentObject*); + explicit SelectionObject(const App::DocumentObject*); ~SelectionObject() override; /** * The default implementation returns an instance of @ref SelectionObjectPy. diff --git a/src/Gui/Transform.cpp b/src/Gui/Transform.cpp index 2937e46784..7d3f661321 100644 --- a/src/Gui/Transform.cpp +++ b/src/Gui/Transform.cpp @@ -279,13 +279,12 @@ Transform::Transform(QWidget* parent, Qt::WindowFlags fl) { ui = new Ui_Placement(); ui->setupUi(this); - connect(ui->applyButton, &QPushButton::clicked, + QPushButton* applyButton = ui->buttonBox->button(QDialogButtonBox::Apply); + connect(applyButton, &QPushButton::clicked, this, &Transform::onApplyButtonClicked); ui->resetButton->hide(); ui->applyIncrementalPlacement->hide(); - - ui->closeButton->setText(tr("Cancel")); this->setWindowTitle(tr("Transform")); // create a signal mapper in order to have one slot to perform the change @@ -332,9 +331,7 @@ void Transform::setTransformStrategy(TransformStrategy* ts) void Transform::showStandardButtons(bool b) { - ui->closeButton->setVisible(b); - ui->oKButton->setVisible(b); - ui->applyButton->setVisible(b); + ui->buttonBox->setVisible(b); } void Transform::onTransformChanged(int) @@ -413,7 +410,6 @@ void Transform::changeEvent(QEvent *e) { if (e->type() == QEvent::LanguageChange) { ui->retranslateUi(this); - ui->closeButton->setText(tr("Cancel")); this->setWindowTitle(tr("Transform")); } else {