Core: Placement dialog

+ replace separate buttons with QDialogButtonBox
+ add convenience method setPlacementAndBindObject
+ use const DocumentObject
This commit is contained in:
wmayer
2024-09-09 12:28:22 +02:00
parent 8925b2ae4d
commit 68ff9989ed
6 changed files with 163 additions and 107 deletions

View File

@@ -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<std::string,App::Property*> props;
obj->getPropertyMap(props);
@@ -197,33 +198,37 @@ void PlacementHandler::revertTransformation()
}
}
std::vector<App::DocumentObject*> PlacementHandler::getObjects(Gui::Document* document) const
std::vector<const App::DocumentObject*> PlacementHandler::getObjects(const Gui::Document* document) const
{
return document->getDocument()->getObjectsOfType(App::DocumentObject::getClassTypeId());
auto objs = document->getDocument()->getObjectsOfType(App::DocumentObject::getClassTypeId());
std::vector<const App::DocumentObject*> list;
list.insert(list.begin(), objs.begin(), objs.end());
return list;
}
std::vector<App::DocumentObject*> PlacementHandler::getSelectedObjects(Gui::Document* document) const
std::vector<const App::DocumentObject*> PlacementHandler::getSelectedObjects(const Gui::Document* document) const
{
App::Document* doc = document->getDocument();
std::vector<App::DocumentObject*> list;
std::vector<const App::DocumentObject*> 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<App::DocumentObject*>(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<App::DocumentObject*> obj = getObjects(document);
std::vector<const App::DocumentObject*> 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<App::DocumentObject*> sel = getSelectedObjects(document);
std::vector<const App::DocumentObject*> 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<App::DocumentObject*> sel = getSelectedObjects(document);
std::vector<const App::DocumentObject*> 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<std::string>(name);
if (PyObject_TypeCheck(object.ptr(), &App::DocumentObjectPy::Type)) {
auto py = static_cast<App::DocumentObjectPy*>(object.ptr());
auto obj = py->getDocumentObjectPtr();
if (widget) {
widget->setPlacementAndBindObject(obj, propName);
}
}
return Py::None();
}

View File

@@ -69,14 +69,15 @@ public:
std::tuple<Base::Vector3d, std::vector<Base::Vector3d>> getSelectedPoints() const;
private:
std::vector<App::DocumentObject*> getObjects(Gui::Document*) const;
std::vector<App::DocumentObject*> getSelectedObjects(Gui::Document*) const;
std::vector<const App::DocumentObject*> getObjects(const Gui::Document*) const;
std::vector<const App::DocumentObject*> 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<SelectionObject>&);
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<SelectionObject>&);
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&);

View File

@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>277</width>
<height>394</height>
<width>456</width>
<height>492</height>
</rect>
</property>
<property name="windowTitle">
@@ -233,7 +233,7 @@
</item>
</widget>
</item>
<item row="1" column="0">
<item row="1" column="0">
<widget class="QStackedWidget" name="stackedWidget">
<property name="currentIndex">
<number>1</number>
@@ -415,7 +415,7 @@
<widget class="QWidget" name="page_2"/>
</widget>
</item>
</layout>
</layout>
</widget>
</item>
<item row="2" column="0" colspan="2">
@@ -487,23 +487,9 @@
</spacer>
</item>
<item>
<widget class="QPushButton" name="oKButton">
<property name="text">
<string>OK</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="closeButton">
<property name="text">
<string>Close</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="applyButton">
<property name="text">
<string>Apply</string>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
@@ -525,44 +511,9 @@
<tabstop>yAxis</tabstop>
<tabstop>zAxis</tabstop>
<tabstop>applyIncrementalPlacement</tabstop>
<tabstop>oKButton</tabstop>
<tabstop>applyButton</tabstop>
<tabstop>closeButton</tabstop>
</tabstops>
<resources/>
<connections>
<connection>
<sender>oKButton</sender>
<signal>clicked()</signal>
<receiver>Gui::Dialog::Placement</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>164</x>
<y>252</y>
</hint>
<hint type="destinationlabel">
<x>8</x>
<y>28</y>
</hint>
</hints>
</connection>
<connection>
<sender>closeButton</sender>
<signal>clicked()</signal>
<receiver>Gui::Dialog::Placement</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>354</x>
<y>252</y>
</hint>
<hint type="destinationlabel">
<x>291</x>
<y>179</y>
</hint>
</hints>
</connection>
<connection>
<sender>rotationInput</sender>
<signal>activated(int)</signal>
@@ -579,5 +530,37 @@
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>Gui::Dialog::Placement</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>310</x>
<y>469</y>
</hint>
<hint type="destinationlabel">
<x>227</x>
<y>245</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>Gui::Dialog::Placement</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>310</x>
<y>469</y>
</hint>
<hint type="destinationlabel">
<x>227</x>
<y>245</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -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();

View File

@@ -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.

View File

@@ -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 {