From 0ac71c5e80bc30921354bde2748c6a91e50ec7a5 Mon Sep 17 00:00:00 2001 From: Pieter Hijma Date: Mon, 1 Sep 2025 17:06:40 +0200 Subject: [PATCH 1/2] Gui: Fix Property View copy bug The context menu of the property view shows a "Copy" action for properties with which the value of the property can be copied to the clipboard. When multiple properties are selected, this menu item appears multiple times and in that case it copies the name of one of the properties. This commit fixes this. --- src/Gui/propertyeditor/PropertyEditor.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Gui/propertyeditor/PropertyEditor.cpp b/src/Gui/propertyeditor/PropertyEditor.cpp index bb75964c74..0b0343f15a 100644 --- a/src/Gui/propertyeditor/PropertyEditor.cpp +++ b/src/Gui/propertyeditor/PropertyEditor.cpp @@ -751,6 +751,10 @@ void PropertyEditor::contextMenuEvent(QContextMenuEvent*) if (index.column() > 0) { continue; } + } + + // copy value to clipboard + if (props.size() == 1) { const QVariant valueToCopy = contextIndex.data(Qt::DisplayRole); if (valueToCopy.isValid()) { QAction* copyAction = menu.addAction(tr("Copy")); From c0f440fad4fe3acd9fd569038d80532beef31a85 Mon Sep 17 00:00:00 2001 From: Pieter Hijma Date: Mon, 1 Sep 2025 17:18:48 +0200 Subject: [PATCH 2/2] Gui: Add Property View delete key binding This commit adds a binding for the delete key to delete properties from property containers. --- src/Gui/propertyeditor/PropertyEditor.cpp | 91 +++++++++++++++++++---- src/Gui/propertyeditor/PropertyEditor.h | 4 + 2 files changed, 79 insertions(+), 16 deletions(-) diff --git a/src/Gui/propertyeditor/PropertyEditor.cpp b/src/Gui/propertyeditor/PropertyEditor.cpp index 0b0343f15a..6a6f62fad5 100644 --- a/src/Gui/propertyeditor/PropertyEditor.cpp +++ b/src/Gui/propertyeditor/PropertyEditor.cpp @@ -24,6 +24,7 @@ #include "PreCompiled.h" #ifndef _PreComp_ +#include #include #include #include @@ -222,6 +223,54 @@ bool PropertyEditor::event(QEvent* event) return QTreeView::event(event); } +bool PropertyEditor::removeSelectedDynamicProperties() +{ + std::unordered_set props = acquireSelectedProperties(); + if (props.empty()) { + return false; + } + + bool canRemove = std::ranges::all_of(props, [](auto prop) { + return prop->testStatus(App::Property::PropDynamic) + && !prop->testStatus(App::Property::LockDynamic); + }); + if (!canRemove) { + return false; + } + + removeProperties(props); + return true; +} + +void PropertyEditor::keyPressEvent(QKeyEvent* event) +{ + if (state() == QAbstractItemView::EditingState) { + QTreeView::keyPressEvent(event); + return; + } + + const auto key = event->key(); + const auto mods = event->modifiers(); + const bool allowedModifiers = + mods == Qt::NoModifier || + mods == Qt::KeypadModifier; + +#if defined(Q_OS_MACOS) || defined(Q_OS_MAC) + const bool isDeleteKey = key == Qt::Key_Backspace || key == Qt::Key_Delete; +#else + const bool isDeleteKey = key == Qt::Key_Delete; +#endif + + if (allowedModifiers && isDeleteKey) { + if (removeSelectedDynamicProperties()) { + event->accept(); + return; + } + } + + QTreeView::keyPressEvent(event); +} + void PropertyEditor::commitData(QWidget* editor) { committing = true; @@ -726,14 +775,8 @@ enum MenuAction MA_Copy, }; -void PropertyEditor::contextMenuEvent(QContextMenuEvent*) +std::unordered_set PropertyEditor::acquireSelectedProperties() const { - QMenu menu; - QAction* autoExpand = nullptr; - - auto contextIndex = currentIndex(); - - // acquiring the selected properties std::unordered_set props; const auto indexes = selectedIndexes(); for (const auto& index : indexes) { @@ -752,6 +795,30 @@ void PropertyEditor::contextMenuEvent(QContextMenuEvent*) continue; } } + return props; +} + +void PropertyEditor::removeProperties(const std::unordered_set& props) +{ + App::AutoTransaction committer("Remove property"); + for (auto prop : props) { + try { + prop->getContainer()->removeDynamicProperty(prop->getName()); + } + catch (Base::Exception& e) { + e.reportException(); + } + } +} + +void PropertyEditor::contextMenuEvent(QContextMenuEvent*) +{ + QMenu menu; + QAction* autoExpand = nullptr; + + auto contextIndex = currentIndex(); + + std::unordered_set props = acquireSelectedProperties(); // copy value to clipboard if (props.size() == 1) { @@ -990,15 +1057,7 @@ void PropertyEditor::contextMenuEvent(QContextMenuEvent*) return; } case MA_RemoveProp: { - App::AutoTransaction committer("Remove property"); - for (auto prop : props) { - try { - prop->getContainer()->removeDynamicProperty(prop->getName()); - } - catch (Base::Exception& e) { - e.reportException(); - } - } + removeProperties(props); break; } default: diff --git a/src/Gui/propertyeditor/PropertyEditor.h b/src/Gui/propertyeditor/PropertyEditor.h index bb275f1bd4..f41cbbb5f3 100644 --- a/src/Gui/propertyeditor/PropertyEditor.h +++ b/src/Gui/propertyeditor/PropertyEditor.h @@ -128,11 +128,15 @@ protected: #endif void contextMenuEvent(QContextMenuEvent* event) override; bool event(QEvent*) override; + void keyPressEvent(QKeyEvent* event) override; private: void setEditorMode(const QModelIndex& parent, int start, int end); void closeTransaction(); void recomputeDocument(App::Document*); + std::unordered_set acquireSelectedProperties() const; + void removeProperties(const std::unordered_set& props); + bool removeSelectedDynamicProperties(); // check if mouse_pos is around right or bottom side of a cell // and return the index of that cell if found