3636#include < App/PropertyUnits.h>
3737#include < App/PropertyFile.h>
3838#include < App/PropertyGeo.h>
39+ #include < App/PropertyPythonObject.h>
3940#include < Base/Tools.h>
4041
4142#include " Dialogs/DlgAddProperty.h"
@@ -275,25 +276,42 @@ void DlgAddProperty::initializeGroup()
275276 );
276277}
277278
278- std::vector<Base::Type> DlgAddProperty::getSupportedTypes ()
279+ DlgAddProperty::SupportedTypes DlgAddProperty::getSupportedTypes ()
279280{
280- std::vector<Base::Type> supportedTypes;
281+ std::vector<Base::Type> commonTypes = {
282+ App::PropertyLength::getClassTypeId (),
283+ App::PropertyAngle::getClassTypeId (),
284+ App::PropertyFloat::getClassTypeId (),
285+ App::PropertyInteger::getClassTypeId (),
286+ App::PropertyBool::getClassTypeId (),
287+ App::PropertyString::getClassTypeId (),
288+ App::PropertyEnumeration::getClassTypeId (),
289+ };
290+
291+ std::vector<Base::Type> otherTypes;
281292 std::vector<Base::Type> allTypes;
282293 Base::Type::getAllDerivedFrom (Base::Type::fromName (" App::Property" ), allTypes);
283294
284- std::ranges::copy_if (allTypes, std::back_inserter (supportedTypes), [&](const Base::Type& type) {
285- return type.canInstantiate () && isTypeWithEditor (type);
295+ const auto isCommonType = [&commonTypes](const Base::Type& type) {
296+ return std::ranges::find (commonTypes, type) != commonTypes.end ();
297+ };
298+
299+ std::ranges::copy_if (allTypes, std::back_inserter (otherTypes), [&](const Base::Type& type) {
300+ return type.canInstantiate () && !isExcluded (type) && !isCommonType (type);
286301 });
287302
288- std::ranges::sort (supportedTypes , [](Base::Type a, Base::Type b) {
303+ std::ranges::sort (otherTypes , [](Base::Type a, Base::Type b) {
289304 return strcmp (a.getName (), b.getName ()) < 0 ;
290305 });
291306
292- return supportedTypes ;
307+ return {. commonTypes = std::move (commonTypes), . otherTypes = std::move (otherTypes)} ;
293308}
294309
295310void DlgAddProperty::initializeTypes ()
296311{
312+ auto * model = new TypeItemModel (this );
313+ ui->comboBoxType ->setModel (model);
314+
297315 auto paramGroup = App::GetApplication ().GetParameterGroupByPath (
298316 " User parameter:BaseApp/Preferences/PropertyView"
299317 );
@@ -304,14 +322,27 @@ void DlgAddProperty::initializeTypes()
304322 lastType = App::PropertyLength::getClassTypeId ();
305323 }
306324
307- std::vector<Base::Type> types = getSupportedTypes ();
325+ const auto [commonTypes, otherTypes] = getSupportedTypes ();
308326
309- for (const auto & type : types) {
310- ui->comboBoxType ->addItem (QString::fromLatin1 (type.getName ()));
311- if (type == lastType) {
312- ui->comboBoxType ->setCurrentIndex (ui->comboBoxType ->count () - 1 );
327+ const auto addTypes = [this , &lastType](const std::vector<Base::Type>& types) {
328+ for (const auto & type : types) {
329+ ui->comboBoxType ->addItem (QString::fromLatin1 (type.getName ()));
330+ if (type == lastType) {
331+ ui->comboBoxType ->setCurrentIndex (ui->comboBoxType ->count () - 1 );
332+ }
313333 }
314- }
334+ };
335+
336+
337+ const auto addSeparator = [this ]() {
338+ ui->comboBoxType ->addItem (" ──────────────────────" );
339+ const int idx = ui->comboBoxType ->count () - 1 ;
340+ ui->comboBoxType ->setItemData (idx, true , TypeItemModel::SeparatorRole);
341+ };
342+
343+ addTypes (commonTypes);
344+ addSeparator ();
345+ addTypes (otherTypes);
315346
316347 completerType.setModel (ui->comboBoxType ->model ());
317348 completerType.setCaseSensitivity (Qt::CaseInsensitive);
@@ -362,11 +393,7 @@ void DlgAddProperty::addNormalEditor(PropertyItem* propertyItem)
362393
363394void DlgAddProperty::addEditor (PropertyItem* propertyItem)
364395{
365- if (isSubLinkPropertyItem ()) {
366- // Since sublinks need the 3D view to select an object and the dialog
367- // is modal, we do not provide an editor for sublinks. It is possible
368- // to create a property of this type though and the property can be set
369- // in the property view later which does give access to the 3D view.
396+ if (!isTypeWithEditor (propertyItem)) {
370397 return ;
371398 }
372399
@@ -401,7 +428,43 @@ void DlgAddProperty::addEditor(PropertyItem* propertyItem)
401428 removeSelectionEditor ();
402429}
403430
404- bool DlgAddProperty::isTypeWithEditor (const Base::Type& type)
431+ bool DlgAddProperty::isExcluded (const Base::Type& type) const
432+ {
433+ // These properties are excluded because you cannot give them a value in
434+ // the property view.
435+ static const std::initializer_list<Base::Type> excludedTypes = {
436+ App::PropertyBoolList::getClassTypeId (),
437+ App::PropertyColorList::getClassTypeId (),
438+ App::PropertyExpressionEngine::getClassTypeId (),
439+ App::PropertyIntegerSet::getClassTypeId (),
440+ App::PropertyMap::getClassTypeId (),
441+ App::PropertyMaterial::getClassTypeId (),
442+ App::PropertyPlacementList::getClassTypeId (),
443+ App::PropertyPythonObject::getClassTypeId (),
444+ App::PropertyUUID::getClassTypeId ()
445+ };
446+
447+ std::string_view name (type.getName ());
448+ return !name.starts_with (" App::Property" )
449+ || std::ranges::find (excludedTypes, type) != excludedTypes.end ();
450+ }
451+
452+ bool DlgAddProperty::isTypeWithEditor (PropertyItem* propertyItem) const
453+ {
454+ if (propertyItem == nullptr ) {
455+ return false ;
456+ }
457+
458+ App::Property* prop = propertyItem->getFirstProperty ();
459+ if (prop == nullptr ) {
460+ return false ;
461+ }
462+
463+ const Base::Type type = prop->getTypeId ();
464+ return isTypeWithEditor (type);
465+ }
466+
467+ bool DlgAddProperty::isTypeWithEditor (const Base::Type& type) const
405468{
406469 static const std::initializer_list<Base::Type> subTypesWithEditor = {
407470 // These types and their subtypes have editors.
@@ -414,19 +477,22 @@ bool DlgAddProperty::isTypeWithEditor(const Base::Type& type)
414477
415478 static const std::initializer_list<Base::Type> typesWithEditor = {
416479 // These types have editors but not necessarily their subtypes.
480+
481+ // Although sublink properties have editors, they need the 3D view to
482+ // select an object. Because the dialog is modal, it is not possible
483+ // to make use of the 3D view, hence we do not provide an editor for
484+ // sublinks and their lists. It is possible to create a property of
485+ // this type though and the property can be set in the property view
486+ // later which does give access to the 3D view.
417487 App::PropertyEnumeration::getClassTypeId (),
418488 App::PropertyFile::getClassTypeId (),
419489 App::PropertyFloatList::getClassTypeId (),
420490 App::PropertyFont::getClassTypeId (),
421491 App::PropertyIntegerList::getClassTypeId (),
422492 App::PropertyLink::getClassTypeId (),
423- App::PropertyLinkSub::getClassTypeId (),
424493 App::PropertyLinkList::getClassTypeId (),
425- App::PropertyLinkSubList::getClassTypeId (),
426494 App::PropertyXLink::getClassTypeId (),
427- App::PropertyXLinkSub::getClassTypeId (),
428495 App::PropertyXLinkList::getClassTypeId (),
429- App::PropertyXLinkSubList::getClassTypeId (),
430496 App::PropertyMaterialList::getClassTypeId (),
431497 App::PropertyPath::getClassTypeId (),
432498 App::PropertyString::getClassTypeId (),
@@ -442,7 +508,7 @@ bool DlgAddProperty::isTypeWithEditor(const Base::Type& type)
442508 || std::ranges::any_of (subTypesWithEditor, isDerivedFromType);
443509}
444510
445- bool DlgAddProperty::isTypeWithEditor (const std::string& type)
511+ bool DlgAddProperty::isTypeWithEditor (const std::string& type) const
446512{
447513 Base::Type propType
448514 = Base::Type::getTypeIfDerivedFrom (type.c_str (), App::Property::getClassTypeId (), true );
@@ -458,7 +524,7 @@ static PropertyItem* createPropertyItem(App::Property* prop)
458524 return PropertyItemFactory::instance ().createPropertyItem (editor);
459525}
460526
461- void DlgAddProperty::createEditorForType (const Base::Type& type)
527+ void DlgAddProperty::createSupportDataForType (const Base::Type& type)
462528{
463529 // Temporarily create a property for two reasons:
464530 // - to acquire the editor name from the instance, and
@@ -496,10 +562,9 @@ void DlgAddProperty::initializeValue()
496562 return ;
497563 }
498564
499- if (isTypeWithEditor (propType)) {
500- createEditorForType (propType);
501- }
502- else {
565+ createSupportDataForType (propType);
566+ if (!isTypeWithEditor (propType)) {
567+ // remove the editor from a previous add
503568 removeEditor ();
504569 }
505570}
@@ -644,20 +709,6 @@ bool DlgAddProperty::isEnumPropertyItem() const
644709 == QString::fromLatin1 (App::PropertyEnumeration::getClassTypeId ().getName ());
645710}
646711
647- bool DlgAddProperty::isSubLinkPropertyItem () const
648- {
649- const QString type = ui->comboBoxType ->currentText ();
650- static const std::array<const char *, 4 > sublinkTypes = {
651- App::PropertyLinkSub::getClassTypeId ().getName (),
652- App::PropertyLinkSubList::getClassTypeId ().getName (),
653- App::PropertyXLinkSub::getClassTypeId ().getName (),
654- App::PropertyXLinkSubList::getClassTypeId ().getName ()
655- };
656- return std::ranges::any_of (sublinkTypes, [&type](const char * subLinkType) {
657- return type == QString::fromLatin1 (subLinkType);
658- });
659- }
660-
661712QVariant DlgAddProperty::getEditorData () const
662713{
663714 if (isEnumPropertyItem ()) {
0 commit comments