From ba217660962bdbe171b923ab110fd7e498ef182f Mon Sep 17 00:00:00 2001 From: wmayer Date: Mon, 16 Nov 2015 15:24:36 +0100 Subject: [PATCH] + property editor handles case when dynamic property is removed --- src/App/Application.h | 11 +++++++++ src/App/DynamicProperty.cpp | 4 +++ src/Gui/PropertyView.cpp | 30 +++++++++++++++++++++++ src/Gui/PropertyView.h | 4 +++ src/Gui/propertyeditor/PropertyEditor.cpp | 21 ++++++++++++++++ src/Gui/propertyeditor/PropertyEditor.h | 3 +++ src/Gui/propertyeditor/PropertyItem.cpp | 15 +++++++++++- src/Gui/propertyeditor/PropertyItem.h | 2 ++ src/Gui/propertyeditor/PropertyModel.cpp | 21 ++++++++++++++++ src/Gui/propertyeditor/PropertyModel.h | 4 +++ 10 files changed, 114 insertions(+), 1 deletion(-) diff --git a/src/App/Application.h b/src/App/Application.h index e87c20c8a..9b6048fd1 100644 --- a/src/App/Application.h +++ b/src/App/Application.h @@ -141,6 +141,17 @@ public: boost::signal signalActivatedObject; //@} + /** @name Signals of property changes + * These signals are emitted on property additions or removal. + * The changed object can be any sub-class of PropertyContainer. + */ + //@{ + /// signal on adding a dynamic property + boost::signal signalAppendDynamicProperty; + /// signal on about removing a dynamic property + boost::signal signalRemoveDynamicProperty; + //@} + /** @name methods for parameter handling */ //@{ diff --git a/src/App/DynamicProperty.cpp b/src/App/DynamicProperty.cpp index 310444f44..af5be4b89 100644 --- a/src/App/DynamicProperty.cpp +++ b/src/App/DynamicProperty.cpp @@ -29,6 +29,7 @@ #include "DynamicProperty.h" #include "Property.h" #include "PropertyContainer.h" +#include "Application.h" #include #include #include @@ -242,6 +243,8 @@ Property* DynamicProperty::addDynamicProperty(const char* type, const char* name data.hidden = hidden; props[ObjectName] = data; + GetApplication().signalAppendDynamicProperty(*pcProperty); + return pcProperty; } @@ -249,6 +252,7 @@ bool DynamicProperty::removeDynamicProperty(const char* name) { std::map::iterator it = props.find(name); if (it != props.end()) { + GetApplication().signalRemoveDynamicProperty(*it->second.property); delete it->second.property; props.erase(it); return true; diff --git a/src/Gui/PropertyView.cpp b/src/Gui/PropertyView.cpp index e126cd075..6834daf70 100644 --- a/src/Gui/PropertyView.cpp +++ b/src/Gui/PropertyView.cpp @@ -99,12 +99,20 @@ PropertyView::PropertyView(QWidget *parent) this->connectPropView = Gui::Application::Instance->signalChangedObject.connect(boost::bind (&PropertyView::slotChangePropertyView, this, _1, _2)); + this->connectPropAppend = + App::GetApplication().signalAppendDynamicProperty.connect(boost::bind + (&PropertyView::slotAppendDynamicProperty, this, _1)); + this->connectPropRemove = + App::GetApplication().signalRemoveDynamicProperty.connect(boost::bind + (&PropertyView::slotRemoveDynamicProperty, this, _1)); } PropertyView::~PropertyView() { this->connectPropData.disconnect(); this->connectPropView.disconnect(); + this->connectPropAppend.disconnect(); + this->connectPropRemove.disconnect(); } void PropertyView::slotChangePropertyData(const App::DocumentObject&, const App::Property& prop) @@ -117,6 +125,28 @@ void PropertyView::slotChangePropertyView(const Gui::ViewProvider&, const App::P propertyEditorView->updateProperty(prop); } +void PropertyView::slotAppendDynamicProperty(const App::Property& prop) +{ + App::PropertyContainer* parent = prop.getContainer(); + if (parent && parent->isDerivedFrom(App::DocumentObject::getClassTypeId())) { + propertyEditorData->appendProperty(prop); + } + else if (parent && parent->isDerivedFrom(Gui::ViewProvider::getClassTypeId())) { + propertyEditorView->appendProperty(prop); + } +} + +void PropertyView::slotRemoveDynamicProperty(const App::Property& prop) +{ + App::PropertyContainer* parent = prop.getContainer(); + if (parent && parent->isDerivedFrom(App::DocumentObject::getClassTypeId())) { + propertyEditorData->removeProperty(prop); + } + else if (parent && parent->isDerivedFrom(Gui::ViewProvider::getClassTypeId())) { + propertyEditorView->removeProperty(prop); + } +} + struct PropertyView::PropInfo { std::string propName; diff --git a/src/Gui/PropertyView.h b/src/Gui/PropertyView.h index 383d58c30..20fa14737 100644 --- a/src/Gui/PropertyView.h +++ b/src/Gui/PropertyView.h @@ -76,6 +76,8 @@ private: void onSelectionChanged(const SelectionChanges& msg); void slotChangePropertyData(const App::DocumentObject&, const App::Property&); void slotChangePropertyView(const Gui::ViewProvider&, const App::Property&); + void slotAppendDynamicProperty(const App::Property&); + void slotRemoveDynamicProperty(const App::Property&); private: struct PropInfo; @@ -83,6 +85,8 @@ private: typedef boost::BOOST_SIGNALS_NAMESPACE::connection Connection; Connection connectPropData; Connection connectPropView; + Connection connectPropAppend; + Connection connectPropRemove; QTabWidget* tabs; }; diff --git a/src/Gui/propertyeditor/PropertyEditor.cpp b/src/Gui/propertyeditor/PropertyEditor.cpp index 5dce1e6a1..d1e29a7da 100644 --- a/src/Gui/propertyeditor/PropertyEditor.cpp +++ b/src/Gui/propertyeditor/PropertyEditor.cpp @@ -143,6 +143,8 @@ void PropertyEditor::buildUp(const PropertyModel::PropertyList& props) QModelIndex index = propertyModel->propertyIndexFromPath(this->selectedProperty); this->setCurrentIndex(index); } + + propList = props; } void PropertyEditor::updateProperty(const App::Property& prop) @@ -152,4 +154,23 @@ void PropertyEditor::updateProperty(const App::Property& prop) propertyModel->updateProperty(prop); } +void PropertyEditor::appendProperty(const App::Property& prop) +{ + //TODO: Find any property with the same container parent + //propertyModel->appendProperty(prop); +} + +void PropertyEditor::removeProperty(const App::Property& prop) +{ + for (PropertyModel::PropertyList::iterator it = propList.begin(); it != propList.end(); ++it) { + // find the given property in the list and remove it if it's there + std::vector::iterator pos = std::find(it->second.begin(), it->second.end(), &prop); + if (pos != it->second.end()) { + it->second.erase(pos); + propertyModel->removeProperty(prop); + break; + } + } +} + #include "moc_PropertyEditor.cpp" diff --git a/src/Gui/propertyeditor/PropertyEditor.h b/src/Gui/propertyeditor/PropertyEditor.h index 8cea30280..b23d6db30 100644 --- a/src/Gui/propertyeditor/PropertyEditor.h +++ b/src/Gui/propertyeditor/PropertyEditor.h @@ -52,6 +52,8 @@ public: /** Builds up the list view with the properties. */ void buildUp(const PropertyModel::PropertyList& props); void updateProperty(const App::Property&); + void appendProperty(const App::Property&); + void removeProperty(const App::Property&); void setAutomaticDocumentUpdate(bool); bool isAutomaticDocumentUpdate(bool) const; @@ -66,6 +68,7 @@ protected: private: PropertyModel* propertyModel; QStringList selectedProperty; + PropertyModel::PropertyList propList; bool autoupdate; bool committing; bool delaybuild; diff --git a/src/Gui/propertyeditor/PropertyItem.cpp b/src/Gui/propertyeditor/PropertyItem.cpp index e9e3568c5..64a6f90da 100644 --- a/src/Gui/propertyeditor/PropertyItem.cpp +++ b/src/Gui/propertyeditor/PropertyItem.cpp @@ -58,7 +58,7 @@ using namespace Gui::PropertyEditor; TYPESYSTEM_SOURCE(Gui::PropertyEditor::PropertyItem, Base::BaseClass); -PropertyItem::PropertyItem() : parentItem(0), readonly(false) +PropertyItem::PropertyItem() : parentItem(0), valid(true), readonly(false) { precision = Base::UnitsApi::getDecimals(); } @@ -111,6 +111,16 @@ bool PropertyItem::hasProperty(const App::Property* prop) const return false; } +void PropertyItem::removeProperty(const App::Property* prop) +{ + std::vector::const_iterator it = std::find(propertyItems.begin(), propertyItems.end(), prop); + if (it != propertyItems.end()) { + propertyItems.erase(it); + if (propertyItems.empty()) + valid = false; + } +} + App::Property* PropertyItem::getFirstProperty() { if (propertyItems.empty()) @@ -346,6 +356,9 @@ bool PropertyItem::setData (const QVariant& value) Qt::ItemFlags PropertyItem::flags(int column) const { + // An item becomes invalid if all its properties have been removed. + if (!valid) + return Qt::NoItemFlags; Qt::ItemFlags basicFlags = Qt::ItemIsEnabled | Qt::ItemIsSelectable; if (column == 1 && !isReadOnly()) return basicFlags | Qt::ItemIsEditable; diff --git a/src/Gui/propertyeditor/PropertyItem.h b/src/Gui/propertyeditor/PropertyItem.h index a3c663de9..cf7dc084e 100644 --- a/src/Gui/propertyeditor/PropertyItem.h +++ b/src/Gui/propertyeditor/PropertyItem.h @@ -63,6 +63,7 @@ public: void updateData(); const std::vector& getPropertyData() const; bool hasProperty(const App::Property*) const; + void removeProperty(const App::Property*); App::Property* getFirstProperty(); const App::Property* getFirstProperty() const; @@ -110,6 +111,7 @@ private: std::vector propertyItems; PropertyItem *parentItem; QList childItems; + bool valid; bool readonly; int precision; }; diff --git a/src/Gui/propertyeditor/PropertyModel.cpp b/src/Gui/propertyeditor/PropertyModel.cpp index 6b83f6799..1c98c1e3a 100644 --- a/src/Gui/propertyeditor/PropertyModel.cpp +++ b/src/Gui/propertyeditor/PropertyModel.cpp @@ -280,6 +280,27 @@ void PropertyModel::updateProperty(const App::Property& prop) } } +void PropertyModel::appendProperty(const App::Property& prop) +{ +} + +void PropertyModel::removeProperty(const App::Property& prop) +{ + int column = 1; + int numChild = rootItem->childCount(); + for (int row=0; rowchild(row); + if (child->hasProperty(&prop)) { + child->removeProperty(&prop); + QModelIndex data = this->index(row, column, QModelIndex()); + if (data.isValid()) { + dataChanged(data, data); + } + break; + } + } +} + 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 ea4d56d70..62ec7a76d 100644 --- a/src/Gui/propertyeditor/PropertyModel.h +++ b/src/Gui/propertyeditor/PropertyModel.h @@ -57,7 +57,11 @@ public: QVariant headerData (int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; bool setHeaderData (int section, Qt::Orientation orientation, const QVariant & value, int role = Qt::EditRole); void buildUp(const PropertyList& props); + void updateProperty(const App::Property&); + void appendProperty(const App::Property&); + void removeProperty(const App::Property&); + QStringList propertyPathFromIndex(const QModelIndex&) const; QModelIndex propertyIndexFromPath(const QStringList&) const;