From b5bab48c46b27abddd3361a1fa82405c8f5fc997 Mon Sep 17 00:00:00 2001 From: wmayer Date: Thu, 4 Jul 2024 15:54:19 +0200 Subject: [PATCH 1/3] Core: In dialog to add property only list types that can be instantiated Fixes #15159: Dialog for adding properties allows property types that give exceptions --- src/Base/BaseClass.h | 2 +- src/Base/Type.cpp | 5 +++++ src/Base/Type.h | 2 ++ src/Gui/DlgAddProperty.cpp | 10 ++++++++-- 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/Base/BaseClass.h b/src/Base/BaseClass.h index d1adc97602..df658b6513 100644 --- a/src/Base/BaseClass.h +++ b/src/Base/BaseClass.h @@ -128,7 +128,7 @@ private: TYPESYSTEM_SOURCE_ABSTRACT_P(_class_) \ void _class_::init(void) \ { \ - initSubclass(_class_::classTypeId, #_class_, #_parentclass_, &(_class_::create)); \ + initSubclass(_class_::classTypeId, #_class_, #_parentclass_, nullptr); \ } // NOLINTEND(cppcoreguidelines-macro-usage) diff --git a/src/Base/Type.cpp b/src/Base/Type.cpp index f137ba55bf..51b2128c1e 100644 --- a/src/Base/Type.cpp +++ b/src/Base/Type.cpp @@ -65,6 +65,11 @@ void* Type::createInstance() return method ? (*method)() : nullptr; } +bool Type::canInstantiate() const +{ + instantiationMethod method = typedata[index]->instMethod; + return method != nullptr; +} void* Type::createInstanceByName(const char* TypeName, bool bLoadModule) { diff --git a/src/Base/Type.h b/src/Base/Type.h index ee120c7333..3f580724e2 100644 --- a/src/Base/Type.h +++ b/src/Base/Type.h @@ -89,6 +89,8 @@ public: /// creates a instance of this type void* createInstance(); + /// Checks whether this type can instantiate + bool canInstantiate() const; /// creates a instance of the named type static void* createInstanceByName(const char* TypeName, bool bLoadModule = false); static void importModule(const char* TypeName); diff --git a/src/Gui/DlgAddProperty.cpp b/src/Gui/DlgAddProperty.cpp index 088d9f2372..c1ff8f2472 100644 --- a/src/Gui/DlgAddProperty.cpp +++ b/src/Gui/DlgAddProperty.cpp @@ -54,9 +54,15 @@ DlgAddProperty::DlgAddProperty(QWidget* parent, if(defType.isBad()) defType = App::PropertyString::getClassTypeId(); + std::vector proptypes; 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; }); + Base::Type::getAllDerivedFrom(Base::Type::fromName("App::Property"), proptypes); + std::copy_if (proptypes.begin(), proptypes.end(), std::back_inserter(types), [](const Base::Type& type) { + return type.canInstantiate(); + }); + 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->comboType->addItem(QString::fromLatin1(type.getName())); From 855d3e53250df0c0f4cdc438bd79ef9762378a7a Mon Sep 17 00:00:00 2001 From: Pieter Hijma Date: Thu, 4 Jul 2024 00:07:47 +0200 Subject: [PATCH 2/3] Gui: Handle property types better in VarSet dialog This makes a distinction between types that cannot be instantiated and types without an editor (editing values can be done in the property view). It adapts to DlgAddProperty.* using the same mechanism to filter properties. --- src/Gui/DlgAddPropertyVarSet.cpp | 23 +++++++++++++++++------ src/Gui/DlgAddPropertyVarSet.h | 11 ++++++++--- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/src/Gui/DlgAddPropertyVarSet.cpp b/src/Gui/DlgAddPropertyVarSet.cpp index b3b477c3e5..d44e5a9747 100644 --- a/src/Gui/DlgAddPropertyVarSet.cpp +++ b/src/Gui/DlgAddPropertyVarSet.cpp @@ -101,6 +101,18 @@ void DlgAddPropertyVarSet::initializeGroup() comboBoxGroup.setEditText(QString::fromStdString(groupNamesSorted[0])); } +void DlgAddPropertyVarSet::getSupportedTypes(std::vector& types) +{ + std::vector proptypes; + Base::Type::getAllDerivedFrom(Base::Type::fromName("App::Property"), proptypes); + std::copy_if(proptypes.begin(), proptypes.end(), std::back_inserter(types), [](const Base::Type& type) { + return type.canInstantiate(); + }); + std::sort(types.begin(), types.end(), [](Base::Type a, Base::Type b) { + return strcmp(a.getName(), b.getName()) < 0; + }); +} + void DlgAddPropertyVarSet::initializeTypes() { auto paramGroup = App::GetApplication().GetParameterGroupByPath( @@ -112,8 +124,7 @@ void DlgAddPropertyVarSet::initializeTypes() } 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; }); + getSupportedTypes(types); for(const auto& type : types) { ui->comboBoxType->addItem(QString::fromLatin1(type.getName())); @@ -183,7 +194,6 @@ void DlgAddPropertyVarSet::clearEditors() removeEditor(); setOkEnabled(false); namePropertyToAdd.clear(); - editor = nullptr; } void DlgAddPropertyVarSet::removeEditor() @@ -191,6 +201,7 @@ void DlgAddPropertyVarSet::removeEditor() if (editor) { layout()->removeWidget(editor.get()); QWidget::setTabOrder(ui->comboBoxType, ui->checkBoxAdd); + editor = nullptr; // FC_ERR("remove editor"); // printFocusChain(ui->comboBoxType); @@ -228,9 +239,9 @@ void DlgAddPropertyVarSet::addEditor(PropertyEditor::PropertyItem* propertyItem, // printFocusChain(editor.get()); } -bool DlgAddPropertyVarSet::isSupportedType(std::string& type) +bool DlgAddPropertyVarSet::isTypeWithEditor(const std::string& type) { - return unsupportedTypes.find(type) == unsupportedTypes.end(); + return typesWithoutEditor.find(type) == typesWithoutEditor.end(); } void DlgAddPropertyVarSet::createProperty(std::string& name, std::string& group) @@ -260,7 +271,7 @@ void DlgAddPropertyVarSet::createProperty(std::string& name, std::string& group) // editors that we can reuse removeEditor(); propertyItem.reset(createPropertyItem(prop)); - if (propertyItem && isSupportedType(type)) { + if (propertyItem && isTypeWithEditor(type)) { propertyItem->setPropertyData({prop}); propertyItem->bind(*objectIdentifier); addEditor(propertyItem.get(), type); diff --git a/src/Gui/DlgAddPropertyVarSet.h b/src/Gui/DlgAddPropertyVarSet.h index d5909e14f3..5143510342 100644 --- a/src/Gui/DlgAddPropertyVarSet.h +++ b/src/Gui/DlgAddPropertyVarSet.h @@ -84,17 +84,22 @@ private: void removeEditor(); void addEditor(PropertyEditor::PropertyItem* propertyItem, std::string& type); - bool isSupportedType(std::string& type); + bool isTypeWithEditor(const std::string& type); void createProperty(std::string& name, std::string& group); void onNamePropertyDetermined(); void onGroupDetermined(); void onTypePropertyDetermined(); + void getSupportedTypes(std::vector& types); + private: - std::unordered_set unsupportedTypes = { + std::unordered_set typesWithoutEditor = { "App::PropertyVector", "App::PropertyVectorDistance", "App::PropertyMatrix", - "App::PropertyRotation", "App::PropertyPlacement", "App::PropertyEnumeration"}; + "App::PropertyRotation", "App::PropertyPlacement", "App::PropertyEnumeration", + "App::PropertyDirection", "App::PropertyPlacementList", "App::PropertyPosition", + "App::PropertyExpressionEngine", "App::PropertyIntegerSet", + "Sketcher::PropertyConstraintList"}; App::VarSet* varSet; std::unique_ptr ui; From 3a76828b1e6ed2b9f191cbb82498562b6d7a05e4 Mon Sep 17 00:00:00 2001 From: Pieter Hijma Date: Thu, 4 Jul 2024 00:34:04 +0200 Subject: [PATCH 3/3] Gui: Add font data to VarSet dialog --- src/Gui/DlgAddPropertyVarSet.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Gui/DlgAddPropertyVarSet.cpp b/src/Gui/DlgAddPropertyVarSet.cpp index d44e5a9747..f00b62c7a9 100644 --- a/src/Gui/DlgAddPropertyVarSet.cpp +++ b/src/Gui/DlgAddPropertyVarSet.cpp @@ -222,11 +222,14 @@ static PropertyEditor::PropertyItem *createPropertyItem(App::Property *prop) return item; } -void DlgAddPropertyVarSet::addEditor(PropertyEditor::PropertyItem* propertyItem, std::string& /*type*/) +void DlgAddPropertyVarSet::addEditor(PropertyEditor::PropertyItem* propertyItem, std::string& type) { editor.reset(propertyItem->createEditor(this, [this]() { this->valueChanged(); })); + if (type == "App::PropertyFont") { + propertyItem->setEditorData(editor.get(), QVariant()); + } editor->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); editor->setObjectName(QString::fromUtf8("editor")); auto formLayout = qobject_cast(layout()); @@ -274,7 +277,7 @@ void DlgAddPropertyVarSet::createProperty(std::string& name, std::string& group) if (propertyItem && isTypeWithEditor(type)) { propertyItem->setPropertyData({prop}); propertyItem->bind(*objectIdentifier); - addEditor(propertyItem.get(), type); + addEditor(propertyItem.get(), type); } setOkEnabled(true);