diff --git a/src/Gui/PropertyView.cpp b/src/Gui/PropertyView.cpp index 5c6599750a..09b5f5ae59 100644 --- a/src/Gui/PropertyView.cpp +++ b/src/Gui/PropertyView.cpp @@ -116,6 +116,9 @@ PropertyView::PropertyView(QWidget *parent) this->connectPropRemove = App::GetApplication().signalRemoveDynamicProperty.connect(std::bind (&PropertyView::slotRemoveDynamicProperty, this, sp::_1)); + this->connectPropRename = + App::GetApplication().signalRenameDynamicProperty.connect(std::bind + (&PropertyView::slotRenameDynamicProperty, this, sp::_1, sp::_2)); this->connectPropChange = App::GetApplication().signalChangePropertyEditor.connect(std::bind (&PropertyView::slotChangePropertyEditor, this, sp::_1, sp::_2)); @@ -258,6 +261,23 @@ void PropertyView::slotRemoveDynamicProperty(const App::Property& prop) timer->start(ViewParams::instance()->getPropertyViewTimer()); } +void PropertyView::slotRenameDynamicProperty(const App::Property& prop, + const char* /*oldName*/) +{ + App::PropertyContainer* parent = prop.getContainer(); + if (propertyEditorData->propOwners.contains(parent)) { + propertyEditorData->renameProperty(prop); + } + else if (propertyEditorView->propOwners.contains(parent)) { + propertyEditorView->renameProperty(prop); + } + else { + return; + } + clearPropertyItemSelection(); + timer->start(ViewParams::instance()->getPropertyViewTimer()); +} + void PropertyView::slotChangePropertyEditor(const App::Document &, const App::Property& prop) { App::PropertyContainer* parent = prop.getContainer(); diff --git a/src/Gui/PropertyView.h b/src/Gui/PropertyView.h index a058fcd04e..6c404449b0 100644 --- a/src/Gui/PropertyView.h +++ b/src/Gui/PropertyView.h @@ -82,6 +82,7 @@ private: void slotChangePropertyView(const Gui::ViewProvider&, const App::Property&); void slotAppendDynamicProperty(const App::Property&); void slotRemoveDynamicProperty(const App::Property&); + void slotRenameDynamicProperty(const App::Property&, const char* oldName); void slotChangePropertyEditor(const App::Document&, const App::Property&); void slotRollback(); void slotActiveDocument(const Gui::Document&); @@ -99,6 +100,7 @@ private: Connection connectPropView; Connection connectPropAppend; Connection connectPropRemove; + Connection connectPropRename; Connection connectPropChange; Connection connectUndoDocument; Connection connectRedoDocument; diff --git a/src/Gui/propertyeditor/PropertyEditor.cpp b/src/Gui/propertyeditor/PropertyEditor.cpp index 3da6cf7f8e..d7b0ec5e64 100644 --- a/src/Gui/propertyeditor/PropertyEditor.cpp +++ b/src/Gui/propertyeditor/PropertyEditor.cpp @@ -694,12 +694,25 @@ void PropertyEditor::removeProperty(const App::Property& prop) } } +void PropertyEditor::renameProperty(const App::Property& prop) +{ + for (auto & it : propList) { + // find the given property in the list and rename it if it's there + auto pos = std::ranges::find(it.second, &prop); + if (pos != it.second.end()) { + propertyModel->renameProperty(prop); + break; + } + } +} + enum MenuAction { MA_AutoExpand, MA_ShowHidden, MA_Expression, MA_RemoveProp, + MA_RenameProp, MA_AddProp, MA_EditPropGroup, MA_Transient, @@ -755,6 +768,15 @@ void PropertyEditor::contextMenuEvent(QContextMenuEvent*) menu.addAction(tr("Rename Property Group"))->setData(QVariant(MA_EditPropGroup)); } + // rename property + if (props.size() == 1) { + auto prop = *props.begin(); + if (prop->testStatus(App::Property::PropDynamic) + && !prop->testStatus(App::Property::LockDynamic)) { + menu.addAction(tr("Rename property"))->setData(QVariant(MA_RenameProp)); + } + } + // remove property bool canRemove = !props.empty(); unsigned long propType = 0; @@ -911,6 +933,38 @@ void PropertyEditor::contextMenuEvent(QContextMenuEvent*) dlg.exec(); return; } + case MA_RenameProp: { + if (props.size() != 1) { + break; + } + + App::Property* prop = *props.begin(); + if (!prop->testStatus(App::Property::PropDynamic) + || prop->testStatus(App::Property::LockDynamic)) { + break; + } + + App::AutoTransaction committer("Rename property"); + const char* oldName = prop->getName(); + QString res = QInputDialog::getText(Gui::getMainWindow(), + tr("Rename property"), + tr("Property name"), + QLineEdit::Normal, + QString::fromUtf8(oldName)); + if (res.isEmpty()) { + break; + } + + std::string newName = res.toUtf8().constData(); + try { + prop->getContainer()->renameDynamicProperty(prop, newName.c_str()); + } + catch (Base::Exception& e) { + e.reportException(); + break; + } + break; + } case MA_EditPropGroup: { // This operation is not undoable yet. const char* groupName = (*props.begin())->getGroup(); diff --git a/src/Gui/propertyeditor/PropertyEditor.h b/src/Gui/propertyeditor/PropertyEditor.h index 4badc264ac..bb275f1bd4 100644 --- a/src/Gui/propertyeditor/PropertyEditor.h +++ b/src/Gui/propertyeditor/PropertyEditor.h @@ -78,6 +78,7 @@ public: bool checkDocument = false); 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); diff --git a/src/Gui/propertyeditor/PropertyItem.cpp b/src/Gui/propertyeditor/PropertyItem.cpp index 4b679d8324..4570b6b6f4 100644 --- a/src/Gui/propertyeditor/PropertyItem.cpp +++ b/src/Gui/propertyeditor/PropertyItem.cpp @@ -221,6 +221,14 @@ bool PropertyItem::removeProperty(const App::Property* prop) return propertyItems.empty(); } +bool PropertyItem::renameProperty(const App::Property* prop) +{ + setPropertyData({const_cast(prop)}); + QString name = QString::fromLatin1(prop->getName()); + setPropertyName(name, name); + return true; +} + App::Property* PropertyItem::getFirstProperty() { if (propertyItems.empty()) { diff --git a/src/Gui/propertyeditor/PropertyItem.h b/src/Gui/propertyeditor/PropertyItem.h index 1318887c7b..f7a02e6661 100644 --- a/src/Gui/propertyeditor/PropertyItem.h +++ b/src/Gui/propertyeditor/PropertyItem.h @@ -149,6 +149,7 @@ public: bool hasProperty(const App::Property*) const; virtual void assignProperty(const App::Property*); bool removeProperty(const App::Property*); + bool renameProperty(const App::Property*); App::Property* getFirstProperty(); const App::Property* getFirstProperty() const; diff --git a/src/Gui/propertyeditor/PropertyModel.cpp b/src/Gui/propertyeditor/PropertyModel.cpp index b3819eff3e..b6f1771054 100644 --- a/src/Gui/propertyeditor/PropertyModel.cpp +++ b/src/Gui/propertyeditor/PropertyModel.cpp @@ -572,6 +572,24 @@ void PropertyModel::removeProperty(const App::Property& _prop) } } +void PropertyModel::renameProperty(const App::Property& _prop) +{ + auto prop = const_cast(&_prop); + auto it = itemMap.find(prop); + if (it == itemMap.end() || !it->second) { + return; + } + + PropertyItem* item = it->second; + item->renameProperty(prop); + QModelIndex parent = this->index(item->parent()->row(), 0, QModelIndex()); + QModelIndex nameIndex = this->index(item->row(), 0, parent); + QModelIndex dataIndex = this->index(item->row(), 1, parent); + QVector roles; + roles << Qt::DisplayRole; + Q_EMIT dataChanged(nameIndex, dataIndex, roles); +} + void PropertyModel::updateChildren(PropertyItem* item, int column, const QModelIndex& parent) { int numChild = item->childCount(); diff --git a/src/Gui/propertyeditor/PropertyModel.h b/src/Gui/propertyeditor/PropertyModel.h index 0a6288f3c9..8113972f16 100644 --- a/src/Gui/propertyeditor/PropertyModel.h +++ b/src/Gui/propertyeditor/PropertyModel.h @@ -65,6 +65,7 @@ public: void updateProperty(const App::Property&); void appendProperty(const App::Property&); void removeProperty(const App::Property&); + void renameProperty(const App::Property&); QStringList propertyPathFromIndex(const QModelIndex&) const; QModelIndex propertyIndexFromPath(const QStringList&) const;