From 0f9a8f4fef8fa8f126d8f3f472d21faf27cf6c4d Mon Sep 17 00:00:00 2001 From: Pieter Hijma Date: Wed, 27 Mar 2024 16:50:58 +0100 Subject: [PATCH 1/4] Core: Add a dialog to add properties to a VarSet --- src/Gui/CMakeLists.txt | 3 + src/Gui/DlgAddPropertyVarSet.cpp | 393 +++++++++++++++++++++++++++++++ src/Gui/DlgAddPropertyVarSet.h | 116 +++++++++ src/Gui/DlgAddPropertyVarSet.ui | 125 ++++++++++ src/Gui/ViewProviderVarSet.cpp | 23 ++ src/Gui/ViewProviderVarSet.h | 14 +- 6 files changed, 671 insertions(+), 3 deletions(-) create mode 100644 src/Gui/DlgAddPropertyVarSet.cpp create mode 100644 src/Gui/DlgAddPropertyVarSet.h create mode 100644 src/Gui/DlgAddPropertyVarSet.ui diff --git a/src/Gui/CMakeLists.txt b/src/Gui/CMakeLists.txt index 57dc5d60d8..d02326337c 100644 --- a/src/Gui/CMakeLists.txt +++ b/src/Gui/CMakeLists.txt @@ -371,6 +371,7 @@ SET(Gui_UIC_SRCS TaskElementColors.ui DlgObjectSelection.ui DlgAddProperty.ui + DlgAddPropertyVarSet.ui VectorListEditor.ui ) @@ -458,6 +459,7 @@ SET(Dialog_CPP_SRCS TaskMeasure.cpp DlgObjectSelection.cpp DlgAddProperty.cpp + DlgAddPropertyVarSet.cpp VectorListEditor.cpp ) @@ -498,6 +500,7 @@ SET(Dialog_HPP_SRCS TaskMeasure.h DlgObjectSelection.h DlgAddProperty.h + DlgAddPropertyVarSet.h VectorListEditor.h ) diff --git a/src/Gui/DlgAddPropertyVarSet.cpp b/src/Gui/DlgAddPropertyVarSet.cpp new file mode 100644 index 0000000000..8360df6316 --- /dev/null +++ b/src/Gui/DlgAddPropertyVarSet.cpp @@ -0,0 +1,393 @@ +/**************************************************************************** + * Copyright (c) 2024 Ondsel * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ****************************************************************************/ + +#include "PreCompiled.h" +#ifndef _PreComp_ +# include +# include +# include +#endif + +#include +#include +#include +#include +#include + +#include "DlgAddPropertyVarSet.h" +#include "ui_DlgAddPropertyVarSet.h" +#include "MainWindow.h" +#include "ViewProviderDocumentObject.h" +#include "ViewProviderVarSet.h" + +FC_LOG_LEVEL_INIT("DlgAddPropertyVarSet", true, true) + +using namespace Gui; +using namespace Gui::Dialog; + +const std::string DlgAddPropertyVarSet::GROUP_BASE = "Base"; + +DlgAddPropertyVarSet::DlgAddPropertyVarSet(QWidget* parent, + ViewProviderVarSet* viewProvider) + : QDialog(parent), + varSet(dynamic_cast(viewProvider->getObject())), + ui(new Ui_DlgAddPropertyVarSet), + comboBoxGroup(this), + completerType(this), + editor(nullptr) +{ + ui->setupUi(this); + + initializeWidgets(viewProvider); +} + +DlgAddPropertyVarSet::~DlgAddPropertyVarSet() = default; + +void DlgAddPropertyVarSet::initializeGroup() +{ + connect(&comboBoxGroup, &EditFinishedComboBox::editFinished, + this, &DlgAddPropertyVarSet::onGroupDetermined); + comboBoxGroup.setObjectName(QString::fromUtf8("comboBoxGroup")); + comboBoxGroup.setInsertPolicy(QComboBox::InsertAtTop); + comboBoxGroup.setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + comboBoxGroup.setEditable(true); + auto formLayout = qobject_cast(layout()); + formLayout->setWidget(1, QFormLayout::FieldRole, &comboBoxGroup); + + std::vector properties; + varSet->getPropertyList(properties); + std::unordered_set groupNames; + for (auto prop : properties) { + const char* groupName = varSet->getPropertyGroup(prop); + groupNames.insert(groupName ? groupName : GROUP_BASE); + } + std::vector groupNamesSorted(groupNames.begin(), groupNames.end()); + std::sort(groupNamesSorted.begin(), groupNamesSorted.end(), [](std::string& a, std::string& b) { + // prefer anything else other than Base, so move it to the back + if (a == GROUP_BASE) { + return false; + } + else if (b == GROUP_BASE) { + return true; + } + else { + return a < b; + } + }); + + for (const auto& groupName : groupNamesSorted) { + comboBoxGroup.addItem(QString::fromStdString(groupName)); + } + + comboBoxGroup.setEditText(QString::fromStdString(groupNamesSorted[0])); +} + +void DlgAddPropertyVarSet::initializeTypes() +{ + auto paramGroup = App::GetApplication().GetParameterGroupByPath( + "User parameter:BaseApp/Preferences/PropertyView"); + auto lastType = Base::Type::fromName( + paramGroup->GetASCII("NewPropertyType","App::PropertyLength").c_str()); + if(lastType.isBad()) { + lastType = App::PropertyLength::getClassTypeId(); + } + + std::vector types; + Base::Type::getAllDerivedFrom(Base::Type::fromName("App::Property"),types); + std::sort(types.begin(), types.end(), [](Base::Type a, Base::Type b) { return strcmp(a.getName(), b.getName()) < 0; }); + + for(const auto& type : types) { + ui->comboBoxType->addItem(QString::fromLatin1(type.getName())); + if(type == lastType) + ui->comboBoxType->setCurrentIndex(ui->comboBoxType->count()-1); + } + + completerType.setModel(ui->comboBoxType->model()); + completerType.setCaseSensitivity(Qt::CaseInsensitive); + completerType.setFilterMode(Qt::MatchContains); + ui->comboBoxType->setCompleter(&completerType); + ui->comboBoxType->setInsertPolicy(QComboBox::NoInsert); + + connect(ui->comboBoxType, qOverload(&QComboBox::currentIndexChanged), + this, &DlgAddPropertyVarSet::onTypePropertyDetermined); +} + +/* +// keep some debugging code for debugging tab order +static void printFocusChain(QWidget *widget) { + FC_ERR("Focus Chain:"); + QWidget* start = widget; + int i = 0; + do { + FC_ERR(" " << widget->objectName().toUtf8().constData()); + widget = widget->nextInFocusChain(); + i++; + } while (widget != nullptr && i < 30 && start != widget); + QWidget *currentWidget = QApplication::focusWidget(); + FC_ERR(" Current focus widget:" << (currentWidget ? currentWidget->objectName().toUtf8().constData() : "None") << std::endl << std::endl); +} +*/ + +void DlgAddPropertyVarSet::initializeWidgets(ViewProviderVarSet* viewProvider) +{ + initializeGroup(); + initializeTypes(); + + connect(this, &QDialog::finished, + this, [viewProvider](int result) { viewProvider->onFinished(result); }); + connect(ui->lineEditName, &QLineEdit::editingFinished, + this, &DlgAddPropertyVarSet::onNamePropertyDetermined); + + std::string title = "Add a property to " + varSet->getFullName(); + setWindowTitle(QString::fromStdString(title)); + + setOkEnabled(false); + + ui->lineEditName->setFocus(); + + QWidget::setTabOrder(ui->lineEditName, &comboBoxGroup); + QWidget::setTabOrder(&comboBoxGroup, ui->comboBoxType); + + // FC_ERR("Initialize widgets"); + // printFocusChain(ui->lineEditName); +} + +void DlgAddPropertyVarSet::setOkEnabled(bool enabled) +{ + QPushButton *okButton = ui->buttonBox->button(QDialogButtonBox::Ok); + okButton->setEnabled(enabled); +} + +void DlgAddPropertyVarSet::clearEditors() +{ + ui->lineEditName->clear(); + removeEditor(); + setOkEnabled(false); + namePropertyToAdd.clear(); + editor = nullptr; +} + +void DlgAddPropertyVarSet::removeEditor() +{ + if (editor) { + layout()->removeWidget(editor.get()); + QWidget::setTabOrder(ui->comboBoxType, ui->checkBoxAdd); + + // FC_ERR("remove editor"); + // printFocusChain(ui->comboBoxType); + } +} + +static PropertyEditor::PropertyItem *createPropertyItem(App::Property *prop) +{ + const char *editor = prop->getEditorName(); + if (!editor || !editor[0]) { + return nullptr; + } + auto item = static_cast( + PropertyEditor::PropertyItemFactory::instance().createPropertyItem(editor)); + if (!item) { + qWarning("No property item for type %s found\n", editor); + } + return item; +} + +void DlgAddPropertyVarSet::addEditor(PropertyEditor::PropertyItem* propertyItem, std::string& /*type*/) +{ + editor.reset(propertyItem->createEditor(this, this, SLOT(valueChanged()))); + editor->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + editor->setObjectName(QString::fromUtf8("editor")); + auto formLayout = qobject_cast(layout()); + formLayout->setWidget(3, QFormLayout::FieldRole, editor.get()); + + QWidget::setTabOrder(ui->comboBoxType, editor.get()); + QWidget::setTabOrder(editor.get(), ui->checkBoxAdd); + + // FC_ERR("add editor"); + // printFocusChain(editor.get()); +} + +bool DlgAddPropertyVarSet::isSupportedType(std::string& type) +{ + return unsupportedTypes.find(type) == unsupportedTypes.end(); +} + +void DlgAddPropertyVarSet::createProperty(std::string& name, std::string& group) +{ + std::string type = ui->comboBoxType->currentText().toUtf8().constData(); + + App::Property* prop; + try { + prop = varSet->addDynamicProperty(type.c_str(), name.c_str(), + group.c_str()); + } + catch (Base::Exception& e) { + e.ReportException(); + QMessageBox::critical(this, + QObject::tr("Add property"), + QObject::tr("Failed to add property to '%1': %2").arg( + QString::fromLatin1(varSet->getFullName().c_str()), + QString::fromUtf8(e.what()))); + clearEditors(); + return; + } + + namePropertyToAdd = name; + + objectIdentifier = std::make_unique(*prop); + // creating a propertyItem here because it has all kinds of logic for + // editors that we can reuse + removeEditor(); + propertyItem.reset(createPropertyItem(prop)); + if (propertyItem && isSupportedType(type)) { + propertyItem->setPropertyData({prop}); + propertyItem->bind(*objectIdentifier); + addEditor(propertyItem.get(), type); + } + + setOkEnabled(true); +} + +void DlgAddPropertyVarSet::onNamePropertyDetermined() +{ + if (!namePropertyToAdd.empty()) { + // we were already adding a name, so remove that property + varSet->removeDynamicProperty(namePropertyToAdd.c_str()); + } + QString nameProperty = ui->lineEditName->text(); + std::string name = nameProperty.toUtf8().constData(); + std::string group = comboBoxGroup.currentText().toUtf8().constData(); + if(name.empty() || group.empty() + || name != Base::Tools::getIdentifier(name) + || group != Base::Tools::getIdentifier(group)) { + QMessageBox::critical(getMainWindow(), + QObject::tr("Invalid name"), + QObject::tr("The property name or group name must only contain alpha numericals,\n" + "underscore, and must not start with a digit.")); + clearEditors(); + return; + } + + auto prop = varSet->getPropertyByName(name.c_str()); + if(prop && prop->getContainer() == varSet) { + QMessageBox::critical(this, + QObject::tr("Invalid name"), + QObject::tr("The property '%1' already exists in '%2'").arg( + QString::fromLatin1(name.c_str()), + QString::fromLatin1(varSet->getFullName().c_str()))); + clearEditors(); + return; + } + + App::Document* doc = varSet->getDocument(); + doc->openTransaction("Add property VarSet"); + createProperty(name, group); + + // FC_ERR("chain onNameDetermined"); + // printFocusChain(ui->lineEditName); +} + +void DlgAddPropertyVarSet::onGroupDetermined() +{ + std::string group = comboBoxGroup.currentText().toUtf8().constData(); + + if (group.empty() || group != Base::Tools::getIdentifier(group)) { + QMessageBox::critical(this, + QObject::tr("Invalid name"), + QObject::tr("The group name must only contain alpha numericals,\n" + "underscore, and must not start with a digit.")); + comboBoxGroup.setEditText(QString::fromUtf8("Base")); + return; + } + + if (!namePropertyToAdd.empty()) { + // we were already adding a property + App::Property* prop = varSet->getPropertyByName(namePropertyToAdd.c_str()); + if (prop->getGroup() != group) { + varSet->changeDynamicProperty(prop, group.c_str(), nullptr); + } + } + + // FC_ERR("chain onGroupDetermined"); + // printFocusChain(&comboBoxGroup); + ui->comboBoxType->setFocus(); +} + +void DlgAddPropertyVarSet::onTypePropertyDetermined() +{ + std::string type = ui->comboBoxType->currentText().toUtf8().constData(); + + if (!namePropertyToAdd.empty()) { + // we were already adding a name, so check this property + App::Property* prop = varSet->getPropertyByName(namePropertyToAdd.c_str()); + + if (prop->getTypeId() != Base::Type::fromName(type.c_str())) { + // the property should have a different type + std::string group = prop->getGroup(); + varSet->removeDynamicProperty(namePropertyToAdd.c_str()); + createProperty(namePropertyToAdd, group); + } + } +} + +void DlgAddPropertyVarSet::valueChanged() +{ + QWidget* editor = qobject_cast(sender()); + QVariant data; + data = propertyItem->editorData(editor); + + propertyItem->setData(data); +} + +void DlgAddPropertyVarSet::accept() +{ + App::Document* doc = varSet->getDocument(); + doc->commitTransaction(); + + if (ui->checkBoxAdd->isChecked()) { + clearEditors(); + doc->openTransaction(); + ui->lineEditName->setFocus(); + return; + } + + std::string group = comboBoxGroup.currentText().toUtf8().constData(); + std::string type = ui->comboBoxType->currentText().toUtf8().constData(); + auto paramGroup = App::GetApplication().GetParameterGroupByPath( + "User parameter:BaseApp/Preferences/PropertyView"); + paramGroup->SetASCII("NewPropertyType", type.c_str()); + paramGroup->SetASCII("NewPropertyGroup", group.c_str()); + QDialog::accept(); +} + +void DlgAddPropertyVarSet::reject() +{ + App::Document* doc = varSet->getDocument(); + // a transaction is not pending if a name has not been determined. + if (doc->hasPendingTransaction()) { + doc->abortTransaction(); + } + QDialog::reject(); +} + + +#include "moc_DlgAddPropertyVarSet.cpp" diff --git a/src/Gui/DlgAddPropertyVarSet.h b/src/Gui/DlgAddPropertyVarSet.h new file mode 100644 index 0000000000..d5909e14f3 --- /dev/null +++ b/src/Gui/DlgAddPropertyVarSet.h @@ -0,0 +1,116 @@ +/**************************************************************************** + * Copyright (c) 2024 Ondsel * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ****************************************************************************/ + +#ifndef GUI_DIALOG_DLG_ADD_PROPERTY_VARSET_H +#define GUI_DIALOG_DLG_ADD_PROPERTY_VARSET_H + +#include +#include +#include +#include +#include + +#include + +#include "propertyeditor/PropertyItem.h" + +namespace Gui { + +class ViewProviderVarSet; + +namespace Dialog { + +class EditFinishedComboBox : public QComboBox { + Q_OBJECT +public: + explicit EditFinishedComboBox(QWidget *parent = nullptr) : QComboBox(parent) {} + +Q_SIGNALS: + void editFinished(); + +protected: + void focusOutEvent(QFocusEvent *event) override { + QComboBox::focusOutEvent(event); + Q_EMIT editFinished(); + } +}; + +class Ui_DlgAddPropertyVarSet; + +class GuiExport DlgAddPropertyVarSet : public QDialog +{ + Q_OBJECT + +public: + static const std::string GROUP_BASE; + +public: + DlgAddPropertyVarSet(QWidget *parent, ViewProviderVarSet* viewProvider); + ~DlgAddPropertyVarSet() override; + + void accept() override; + void reject() override; + +public Q_SLOTS: + void valueChanged(); + +private: + void initializeGroup(); + void initializeTypes(); + void initializeWidgets(ViewProviderVarSet* viewProvider); + + void setOkEnabled(bool enabled); + void clearEditors(); + + void removeEditor(); + void addEditor(PropertyEditor::PropertyItem* propertyItem, std::string& type); + + bool isSupportedType(std::string& type); + void createProperty(std::string& name, std::string& group); + + void onNamePropertyDetermined(); + void onGroupDetermined(); + void onTypePropertyDetermined(); + +private: + std::unordered_set unsupportedTypes = { + "App::PropertyVector", "App::PropertyVectorDistance", "App::PropertyMatrix", + "App::PropertyRotation", "App::PropertyPlacement", "App::PropertyEnumeration"}; + + App::VarSet* varSet; + std::unique_ptr ui; + + EditFinishedComboBox comboBoxGroup; + QCompleter completerType; + + // state between adding properties + std::unique_ptr editor; + std::unique_ptr expressionEditor; + std::string namePropertyToAdd; + std::unique_ptr propertyItem; + std::unique_ptr objectIdentifier; +}; + +} // namespace Dialog +} // namespace Gui + +#endif // GUI_DIALOG_DLG_ADD_PROPERTY_VARSET_H diff --git a/src/Gui/DlgAddPropertyVarSet.ui b/src/Gui/DlgAddPropertyVarSet.ui new file mode 100644 index 0000000000..6b2c9f8990 --- /dev/null +++ b/src/Gui/DlgAddPropertyVarSet.ui @@ -0,0 +1,125 @@ + + + Gui::Dialog::DlgAddPropertyVarSet + + + + 0 + 0 + 418 + 223 + + + + Add property + + + + + + Name + + + + + + + + + + Group + + + + + + + Type + + + + + + + true + + + + + + + Value + + + + + + + Add another + + + + + + + Tooltip + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + lineEditName + comboBoxType + checkBoxAdd + lineEditToolTip + + + + + buttonBox + accepted() + Gui::Dialog::DlgAddPropertyVarSet + accept() + + + 199 + 99 + + + 199 + 58 + + + + + buttonBox + rejected() + Gui::Dialog::DlgAddPropertyVarSet + reject() + + + 199 + 99 + + + 199 + 58 + + + + + diff --git a/src/Gui/ViewProviderVarSet.cpp b/src/Gui/ViewProviderVarSet.cpp index bf6611548f..e65b384650 100644 --- a/src/Gui/ViewProviderVarSet.cpp +++ b/src/Gui/ViewProviderVarSet.cpp @@ -21,10 +21,17 @@ ****************************************************************************/ #include "PreCompiled.h" +#ifndef _PreComp_ +# include +#endif +#include + +#include "MainWindow.h" #include "ViewProviderVarSet.h" using namespace Gui; +using namespace Gui::Dialog; PROPERTY_SOURCE(Gui::ViewProviderVarSet, Gui::ViewProviderDocumentObject) @@ -33,4 +40,20 @@ ViewProviderVarSet::ViewProviderVarSet() sPixmap = "VarSet"; } +bool ViewProviderVarSet::doubleClicked() +{ + if (!dialog) { + dialog = std::make_unique(getMainWindow(), this); + } + dialog->show(); + dialog->raise(); + dialog->activateWindow(); + + return true; +} + +void ViewProviderVarSet::onFinished(int /*result*/) +{ + dialog = nullptr; +} diff --git a/src/Gui/ViewProviderVarSet.h b/src/Gui/ViewProviderVarSet.h index 3e0bc8cc86..715a05a438 100644 --- a/src/Gui/ViewProviderVarSet.h +++ b/src/Gui/ViewProviderVarSet.h @@ -24,21 +24,29 @@ #define GUI_ViewProviderVarSet_H #include "ViewProviderDocumentObject.h" +#include "DlgAddPropertyVarSet.h" namespace Gui { /** View provider associated with an App::VarSet */ -class GuiExport ViewProviderVarSet : public ViewProviderDocumentObject { +class GuiExport ViewProviderVarSet : public ViewProviderDocumentObject +{ PROPERTY_HEADER_WITH_OVERRIDE(Gui::ViewProviderVarSet); public: ViewProviderVarSet(); ~ViewProviderVarSet() override = default; bool isShow() const override { return true; } + + bool doubleClicked() override; + + void onFinished(int); + +private: + std::unique_ptr dialog; }; -} +} // namespace Gui #endif - From 5670777eebae8862f74a2023a84e4a3190cbbb10 Mon Sep 17 00:00:00 2001 From: Pieter Hijma Date: Wed, 27 Mar 2024 17:32:10 +0100 Subject: [PATCH 2/4] Core: Add a command to add variable sets --- src/Gui/CommandStructure.cpp | 36 +++++++++++++++++++++++++++++++++++- src/Gui/Workbench.cpp | 2 +- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/src/Gui/CommandStructure.cpp b/src/Gui/CommandStructure.cpp index fdb68d1fca..c339148dbe 100644 --- a/src/Gui/CommandStructure.cpp +++ b/src/Gui/CommandStructure.cpp @@ -34,7 +34,6 @@ #include "Document.h" #include "ViewProviderDocumentObject.h" - using namespace Gui; //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -126,6 +125,40 @@ bool StdCmdGroup::isActive() return hasActiveDocument(); } +//=========================================================================== +// Std_VarSet +//=========================================================================== +DEF_STD_CMD_A(StdCmdVarSet) + +StdCmdVarSet::StdCmdVarSet() + : Command("Std_VarSet") +{ + sGroup = "Structure"; + sMenuText = QT_TR_NOOP("Create a variable set"); + sToolTipText = QT_TR_NOOP("A Variable Set is an object that maintains a set of properties to be used as " + "variables."); + sWhatsThis = "Std_VarSet"; + sStatusTip = sToolTipText; + sPixmap = "VarSet"; +} + +void StdCmdVarSet::activated(int iMsg) +{ + Q_UNUSED(iMsg); + + openCommand(QT_TRANSLATE_NOOP("Command", "Add a variable set")); + + std::string VarSetName; + VarSetName = getUniqueObjectName("VarSet"); + doCommand(Doc,"App.activeDocument().addObject('App::VarSet','%s')",VarSetName.c_str()); + doCommand(Doc, "App.ActiveDocument.getObject('%s').ViewObject.doubleClicked()", VarSetName.c_str()); +} + +bool StdCmdVarSet::isActive() +{ + return hasActiveDocument(); +} + namespace Gui { void CreateStructureCommands() @@ -134,6 +167,7 @@ void CreateStructureCommands() rcCmdMgr.addCommand(new StdCmdPart()); rcCmdMgr.addCommand(new StdCmdGroup()); + rcCmdMgr.addCommand(new StdCmdVarSet()); } } // namespace Gui diff --git a/src/Gui/Workbench.cpp b/src/Gui/Workbench.cpp index cac301643d..d9c5dfdbeb 100644 --- a/src/Gui/Workbench.cpp +++ b/src/Gui/Workbench.cpp @@ -822,7 +822,7 @@ ToolBarItem* StdWorkbench::setupToolBars() const // Structure auto structure = new ToolBarItem( root ); structure->setCommand("Structure"); - *structure << "Std_Part" << "Std_Group" << "Std_LinkActions"; + *structure << "Std_Part" << "Std_Group" << "Std_LinkActions" << "Std_VarSet"; // Help auto help = new ToolBarItem( root ); From ec841ed6d49089fa5fa81cfc92fbdc7503bae04a Mon Sep 17 00:00:00 2001 From: Pieter Hijma Date: Sun, 19 May 2024 15:39:46 +0200 Subject: [PATCH 3/4] Core: Add VarSets to Groups If a Group is selected, add the VarSet to the group. --- src/Gui/CommandStructure.cpp | 18 +++++++++++++++++- src/Mod/PartDesign/App/Body.cpp | 5 ++++- src/Mod/PartDesign/Gui/ViewProviderBody.cpp | 4 ++++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/Gui/CommandStructure.cpp b/src/Gui/CommandStructure.cpp index c339148dbe..06093e550a 100644 --- a/src/Gui/CommandStructure.cpp +++ b/src/Gui/CommandStructure.cpp @@ -26,13 +26,15 @@ #include #endif -#include "App/Document.h" +#include +#include #include "Command.h" #include "ActiveObjectList.h" #include "Application.h" #include "Document.h" #include "ViewProviderDocumentObject.h" +#include "Selection.h" using namespace Gui; @@ -151,6 +153,20 @@ void StdCmdVarSet::activated(int iMsg) std::string VarSetName; VarSetName = getUniqueObjectName("VarSet"); doCommand(Doc,"App.activeDocument().addObject('App::VarSet','%s')",VarSetName.c_str()); + + // add the varset to a group if it is selected + auto sels = Selection().getSelectionEx(nullptr, App::DocumentObject::getClassTypeId(), + ResolveMode::OldStyleElement, true); + if (sels.size() == 1) { + App::DocumentObject *obj = sels[0].getObject(); + auto group = obj->getExtension(); + if (group) { + Gui::Document* docGui = Application::Instance->activeDocument(); + App::Document* doc = docGui->getDocument(); + group->addObject(doc->getObject(VarSetName.c_str())); + } + } + doCommand(Doc, "App.ActiveDocument.getObject('%s').ViewObject.doubleClicked()", VarSetName.c_str()); } diff --git a/src/Mod/PartDesign/App/Body.cpp b/src/Mod/PartDesign/App/Body.cpp index ff92107892..2a89ec9762 100644 --- a/src/Mod/PartDesign/App/Body.cpp +++ b/src/Mod/PartDesign/App/Body.cpp @@ -24,6 +24,7 @@ #include "PreCompiled.h" #include +#include #include #include @@ -227,10 +228,12 @@ bool Body::isAllowed(const App::DocumentObject *obj) // TODO Shouldn't we replace it with Sketcher::SketchObject? (2015-08-13, Fat-Zer) obj->isDerivedFrom() || obj->isDerivedFrom() || - obj->isDerivedFrom() + obj->isDerivedFrom() || // TODO Why this lines was here? why should we allow anything of those? (2015-08-13, Fat-Zer) //obj->isDerivedFrom() // trouble with this line on Windows!? Linker fails to find getClassTypeId() of the Part::FeaturePython... //obj->isDerivedFrom() + // allow VarSets for parameterization + obj->isDerivedFrom() ); } diff --git a/src/Mod/PartDesign/Gui/ViewProviderBody.cpp b/src/Mod/PartDesign/Gui/ViewProviderBody.cpp index 68f47a28f5..2bd054c761 100644 --- a/src/Mod/PartDesign/Gui/ViewProviderBody.cpp +++ b/src/Mod/PartDesign/Gui/ViewProviderBody.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -495,6 +496,9 @@ bool ViewProviderBody::canDropObjects() const bool ViewProviderBody::canDropObject(App::DocumentObject* obj) const { + if (obj->isDerivedFrom()) { + return true; + } if (!obj->isDerivedFrom(Part::Feature::getClassTypeId())) { return false; } From 7e0db8181d9e69ea5b55bd57afc0e35aa211856c Mon Sep 17 00:00:00 2001 From: Pieter Hijma Date: Tue, 21 May 2024 11:04:19 +0200 Subject: [PATCH 4/4] Core: Adapt to new-style editor connect() Use the new-style connect() in createEditor that has been introduced by \#14004 --- src/Gui/DlgAddPropertyVarSet.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Gui/DlgAddPropertyVarSet.cpp b/src/Gui/DlgAddPropertyVarSet.cpp index 8360df6316..b3b477c3e5 100644 --- a/src/Gui/DlgAddPropertyVarSet.cpp +++ b/src/Gui/DlgAddPropertyVarSet.cpp @@ -213,7 +213,9 @@ static PropertyEditor::PropertyItem *createPropertyItem(App::Property *prop) void DlgAddPropertyVarSet::addEditor(PropertyEditor::PropertyItem* propertyItem, std::string& /*type*/) { - editor.reset(propertyItem->createEditor(this, this, SLOT(valueChanged()))); + editor.reset(propertyItem->createEditor(this, [this]() { + this->valueChanged(); + })); editor->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); editor->setObjectName(QString::fromUtf8("editor")); auto formLayout = qobject_cast(layout()); @@ -351,10 +353,8 @@ void DlgAddPropertyVarSet::onTypePropertyDetermined() void DlgAddPropertyVarSet::valueChanged() { - QWidget* editor = qobject_cast(sender()); QVariant data; - data = propertyItem->editorData(editor); - + data = propertyItem->editorData(editor.get()); propertyItem->setData(data); }