diff --git a/src/Gui/PropertyView.cpp b/src/Gui/PropertyView.cpp index d0ef38aaab..1aa08e7fae 100644 --- a/src/Gui/PropertyView.cpp +++ b/src/Gui/PropertyView.cpp @@ -85,13 +85,11 @@ PropertyView::PropertyView(QWidget *parent) propertyEditorView = new Gui::PropertyEditor::PropertyEditor(); propertyEditorView->setObjectName(QStringLiteral("propertyEditorView")); propertyEditorView->setAutomaticDocumentUpdate(_GetParam()->GetBool("AutoTransactionView", false)); - propertyEditorView->setAutomaticExpand(_GetParam()->GetBool("AutoExpandView", false)); tabs->addTab(propertyEditorView, tr("View")); propertyEditorData = new Gui::PropertyEditor::PropertyEditor(); propertyEditorData->setObjectName(QStringLiteral("propertyEditorData")); propertyEditorData->setAutomaticDocumentUpdate(_GetParam()->GetBool("AutoTransactionData", true)); - propertyEditorData->setAutomaticExpand(_GetParam()->GetBool("AutoExpandData", false)); tabs->addTab(propertyEditorData, tr("Data")); int preferredTab = _GetParam()->GetInt("LastTabIndex", 1); diff --git a/src/Gui/propertyeditor/PropertyEditor.cpp b/src/Gui/propertyeditor/PropertyEditor.cpp index 26531779af..2ee9d7428b 100644 --- a/src/Gui/propertyeditor/PropertyEditor.cpp +++ b/src/Gui/propertyeditor/PropertyEditor.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -52,7 +53,7 @@ using namespace Gui::PropertyEditor; PropertyEditor::PropertyEditor(QWidget* parent) : QTreeView(parent) - , autoexpand(false) + , expansionMode(ExpansionMode::DefaultExpand) , autoupdate(false) , committing(false) , delaybuild(false) @@ -75,7 +76,7 @@ PropertyEditor::PropertyEditor(QWidget* parent) setAlternatingRowColors(true); setRootIsDecorated(false); - setExpandsOnDoubleClick(true); + setExpandsOnDoubleClick(false); #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) QStyleOptionViewItem opt = PropertyEditor::viewOptions(); @@ -118,16 +119,6 @@ PropertyEditor::~PropertyEditor() delete f; } -void PropertyEditor::setAutomaticExpand(bool v) -{ - autoexpand = v; -} - -bool PropertyEditor::isAutomaticExpand(bool) const -{ - return autoexpand; -} - void PropertyEditor::onItemExpanded(const QModelIndex& index) { auto item = static_cast(index.internalPointer()); @@ -420,6 +411,18 @@ void PropertyEditor::openEditor(const QModelIndex& index) void PropertyEditor::onItemActivated(const QModelIndex& index) { + if (!index.isValid()) { + return; + } + if (auto* prop = static_cast(index.internalPointer()); + prop && prop->isSeparator()) { + + // setExpanded() only works on column 0 + QModelIndex idxFirstColum = propertyModel->index(index.row(), 0, index.parent()); + setExpanded(idxFirstColum, !isExpanded(idxFirstColum)); + return; + } + if (index.column() != 1) { return; } @@ -712,8 +715,16 @@ void PropertyEditor::buildUp(PropertyModel::PropertyList&& props, bool _checkDoc } } - if (autoexpand) { + switch (expansionMode) { + case ExpansionMode::DefaultExpand: + // take the current expansion state + break; + case ExpansionMode::AutoExpand: expandAll(); + break; + case ExpansionMode::AutoCollapse: + collapseAll(); + break; } } @@ -769,7 +780,12 @@ void PropertyEditor::renameProperty(const App::Property& prop) enum MenuAction { + MA_AutoCollapse, MA_AutoExpand, + MA_ExpandToDefault, + MA_DefaultExpand, + MA_CollapseAll, + MA_ExpandAll, MA_ShowHidden, MA_Expression, MA_RemoveProp, @@ -788,6 +804,94 @@ enum MenuAction MA_Copy, }; +void PropertyEditor::setFirstLevelExpanded(bool doExpand) +{ + if (!propertyModel) { + return; + } + + std::function setExpanded = [&]( + const QModelIndex& index, bool doExpand) { + if (!index.isValid()) { + return; + } + + auto* item = static_cast(index.internalPointer()); + if (item == nullptr || item->childCount() <= 0) { + return; + } + + if (doExpand) { + expand(index); + } + else { + collapse(index); + } + + for (int row = 0; row < propertyModel->rowCount(index); ++row) { + setExpanded(propertyModel->index(row, 0, index), false); + } + }; + + const QModelIndex root = QModelIndex(); + for (int row = 0; row rowCount(root); ++row) { + setExpanded(propertyModel->index(row, 0, root), doExpand); + } +} + +void PropertyEditor::expandToDefault() +{ + setFirstLevelExpanded(true); +} + +void PropertyEditor::collapseAll() +{ + setFirstLevelExpanded(false); +} + +QMenu* PropertyEditor::setupExpansionSubmenu(QWidget* parent) +{ + auto* expandMenu = new QMenu(tr("Expand/Collapse Properties"), parent); + + QAction* expandToDefault = expandMenu->addAction(tr("Expand to Default")); + expandToDefault->setData(QVariant(MA_ExpandToDefault)); + QAction* expandAll = expandMenu->addAction(tr("Expand All")); + expandAll->setData(QVariant(MA_ExpandAll)); + QAction* collapseAll = expandMenu->addAction(tr("Collapse All")); + collapseAll->setData(QVariant(MA_CollapseAll)); + + auto* group = new QActionGroup(expandMenu); + group->setExclusive(true); + + QAction* defaultExpand = expandMenu->addAction(tr("Default Expand")); + defaultExpand->setData(QVariant(MA_DefaultExpand)); + + QAction* autoExpand = expandMenu->addAction(tr("Auto Expand")); + autoExpand->setData(QVariant(MA_AutoExpand)); + + QAction* autoCollapse = expandMenu->addAction(tr("Auto Collapse")); + autoCollapse->setData(QVariant(MA_AutoCollapse)); + + for (QAction* action : {defaultExpand, autoExpand, autoCollapse}) { + action->setCheckable(true); + group->addAction(action); + } + + switch (expansionMode) { + case ExpansionMode::DefaultExpand: + defaultExpand->setChecked(true); + break; + case ExpansionMode::AutoExpand: + autoExpand->setChecked(true); + break; + case ExpansionMode::AutoCollapse: + autoCollapse->setChecked(true); + break; + } + + return expandMenu; +} + static App::PropertyContainer* getSelectedPropertyContainer() { auto sels = Gui::Selection().getSelection("*"); @@ -840,8 +944,6 @@ void PropertyEditor::removeProperties(const std::unordered_set& void PropertyEditor::contextMenuEvent(QContextMenuEvent*) { QMenu menu; - QAction* autoExpand = nullptr; - auto contextIndex = currentIndex(); std::unordered_set props = acquireSelectedProperties(); @@ -898,17 +1000,16 @@ void PropertyEditor::contextMenuEvent(QContextMenuEvent*) // add a separator between adding/removing properties and the rest menu.addSeparator(); + QMenu* expandMenu = setupExpansionSubmenu(&menu); + menu.addMenu(expandMenu); + // show all QAction* showHidden = menu.addAction(tr("Show Hidden")); showHidden->setCheckable(true); showHidden->setChecked(PropertyView::showAll()); showHidden->setData(QVariant(MA_ShowHidden)); - // auto expand - autoExpand = menu.addAction(tr("Auto-Expand")); - autoExpand->setCheckable(true); - autoExpand->setChecked(autoexpand); - autoExpand->setData(QVariant(MA_AutoExpand)); + menu.addSeparator(); // expression if (props.size() == 1) { @@ -969,16 +1070,28 @@ void PropertyEditor::contextMenuEvent(QContextMenuEvent*) } switch (action->data().toInt()) { + case MA_ExpandToDefault: + expandToDefault(); + return; + case MA_CollapseAll: + collapseAll(); + return; + case MA_ExpandAll: + expandAll(); + return; + case MA_DefaultExpand: + action->setChecked(true); + expansionMode = ExpansionMode::DefaultExpand; + return; + case MA_AutoCollapse: + action->setChecked(true); + expansionMode = ExpansionMode::AutoCollapse; + collapseAll(); + return; case MA_AutoExpand: - if (autoExpand) { - // Variable autoExpand should not be null when we arrive here, but - // since we explicitly initialize the variable to nullptr, a check - // nonetheless. - autoexpand = autoExpand->isChecked(); - if (autoexpand) { - expandAll(); - } - } + action->setChecked(true); + expansionMode = ExpansionMode::AutoExpand; + expandAll(); return; case MA_ShowHidden: PropertyView::setShowAll(action->isChecked()); diff --git a/src/Gui/propertyeditor/PropertyEditor.h b/src/Gui/propertyeditor/PropertyEditor.h index f41cbbb5f3..4f5da0511d 100644 --- a/src/Gui/propertyeditor/PropertyEditor.h +++ b/src/Gui/propertyeditor/PropertyEditor.h @@ -70,6 +70,12 @@ class GuiExport PropertyEditor: public QTreeView // clang-format on public: + enum class ExpansionMode { + DefaultExpand, + AutoExpand, + AutoCollapse + }; + PropertyEditor(QWidget* parent = nullptr); ~PropertyEditor() override; @@ -79,8 +85,6 @@ public: void updateProperty(const App::Property&); void removeProperty(const App::Property&); void renameProperty(const App::Property&); - void setAutomaticExpand(bool); - bool isAutomaticExpand(bool) const; void setAutomaticDocumentUpdate(bool); bool isAutomaticDocumentUpdate(bool) const; /*! Reset the internal state of the view. */ @@ -131,6 +135,10 @@ protected: void keyPressEvent(QKeyEvent* event) override; private: + void setFirstLevelExpanded(bool doExpand); + void expandToDefault(); + QMenu* setupExpansionSubmenu(QWidget* parent); + void collapseAll(); void setEditorMode(const QModelIndex& parent, int start, int end); void closeTransaction(); void recomputeDocument(App::Document*); @@ -148,7 +156,7 @@ private: QStringList selectedProperty; PropertyModel::PropertyList propList; std::unordered_set propOwners; - bool autoexpand; + ExpansionMode expansionMode; bool autoupdate; bool committing; bool delaybuild;