Skip to content

Commit b173365

Browse files
pieterhijmachennes
andauthored
Gui: Add common types to Add Property dialog (FreeCAD#26765)
* Gui: Add common types to Add Property dialog Add a preselection of commonly used types in the Add Property dialog. The dialog supports now all properties that have an editor. This doesn't necessarily mean that the editor is shown in the Add Property dialog; some properties should not show their editor in the Add Property dialog, such as vector and placement. * Gui: Make Add Property dialog Qt 6 compatible This change stops using a Qt 6.10 feature and makes it compatible with all of Qt 6. * Update src/Gui/Dialogs/DlgAddProperty.cpp --------- Co-authored-by: Chris Hennes <chennes@pioneerlibrarysystem.org>
1 parent a628391 commit b173365

File tree

2 files changed

+129
-47
lines changed

2 files changed

+129
-47
lines changed

src/Gui/Dialogs/DlgAddProperty.cpp

Lines changed: 93 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
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

295310
void 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

363394
void 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-
661712
QVariant DlgAddProperty::getEditorData() const
662713
{
663714
if (isEnumPropertyItem()) {

src/Gui/Dialogs/DlgAddProperty.h

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include <QDialog>
3131
#include <QComboBox>
3232
#include <QFormLayout>
33+
#include <QStandardItemModel>
3334

3435
#include <FCGlobal.h>
3536

@@ -85,6 +86,29 @@ class EditFinishedComboBox: public QComboBox
8586

8687
class Ui_DlgAddProperty;
8788

89+
class TypeItemModel: public QStandardItemModel
90+
{
91+
Q_OBJECT
92+
public:
93+
static constexpr int SeparatorRole = Qt::UserRole + 1;
94+
95+
explicit TypeItemModel(QObject* parent = nullptr)
96+
: QStandardItemModel(parent)
97+
{}
98+
99+
Qt::ItemFlags flags(const QModelIndex& index) const override
100+
{
101+
Qt::ItemFlags flags = QStandardItemModel::flags(index);
102+
if (index.isValid()) {
103+
QVariant isSeparator = index.data(SeparatorRole);
104+
if (isSeparator.isValid() && isSeparator.toBool()) {
105+
return flags & ~(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
106+
}
107+
}
108+
return flags;
109+
}
110+
};
111+
88112
class GuiExport DlgAddProperty: public QDialog
89113
{
90114
Q_OBJECT
@@ -126,26 +150,33 @@ public Q_SLOTS:
126150
Type
127151
};
128152

153+
struct SupportedTypes
154+
{
155+
std::vector<Base::Type> commonTypes;
156+
std::vector<Base::Type> otherTypes;
157+
};
158+
129159
DlgAddProperty(QWidget* parent, App::PropertyContainer* container, ViewProviderVarSet* viewProvider);
130160

131161
void setupMacroRedirector();
132162

133163
void initializeGroup();
134164

135-
std::vector<Base::Type> getSupportedTypes();
165+
SupportedTypes getSupportedTypes();
136166
void initializeTypes();
137167

138168
void removeSelectionEditor();
139169
QVariant getEditorData() const;
140170
void setEditorData(const QVariant& data);
141-
bool isSubLinkPropertyItem() const;
142171
bool isEnumPropertyItem() const;
143172
void addEnumEditor(PropertyEditor::PropertyItem* propertyItem);
144173
void addNormalEditor(PropertyEditor::PropertyItem* propertyItem);
145174
void addEditor(PropertyEditor::PropertyItem* propertyItem);
146-
bool isTypeWithEditor(const Base::Type& type);
147-
bool isTypeWithEditor(const std::string& type);
148-
void createEditorForType(const Base::Type& type);
175+
bool isExcluded(const Base::Type& type) const;
176+
bool isTypeWithEditor(PropertyEditor::PropertyItem* propertyItem) const;
177+
bool isTypeWithEditor(const Base::Type& type) const;
178+
bool isTypeWithEditor(const std::string& type) const;
179+
void createSupportDataForType(const Base::Type& type);
149180
void initializeValue();
150181

151182
void setTitle();

0 commit comments

Comments
 (0)