From 1225a7ac066d48adc79e7a614a80ecd983571723 Mon Sep 17 00:00:00 2001 From: wmayer Date: Mon, 16 Nov 2015 22:47:29 +0100 Subject: [PATCH] + support of adding/removing dynamic properties in property editor --- src/Gui/PropertyView.cpp | 3 ++ src/Gui/propertyeditor/PropertyEditor.cpp | 32 ++++++++++++++- src/Gui/propertyeditor/PropertyItem.cpp | 20 +++++---- src/Gui/propertyeditor/PropertyItem.h | 4 +- src/Gui/propertyeditor/PropertyModel.cpp | 50 +++++++++++++++++++++-- src/Gui/propertyeditor/PropertyModel.h | 2 + src/Mod/Spreadsheet/App/Sheet.cpp | 6 +-- 7 files changed, 99 insertions(+), 18 deletions(-) diff --git a/src/Gui/PropertyView.cpp b/src/Gui/PropertyView.cpp index 6834daf70..8161e20ae 100644 --- a/src/Gui/PropertyView.cpp +++ b/src/Gui/PropertyView.cpp @@ -128,6 +128,9 @@ void PropertyView::slotChangePropertyView(const Gui::ViewProvider&, const App::P void PropertyView::slotAppendDynamicProperty(const App::Property& prop) { App::PropertyContainer* parent = prop.getContainer(); + if (parent->isHidden(&prop) || prop.StatusBits.test(3)) + return; + if (parent && parent->isDerivedFrom(App::DocumentObject::getClassTypeId())) { propertyEditorData->appendProperty(prop); } diff --git a/src/Gui/propertyeditor/PropertyEditor.cpp b/src/Gui/propertyeditor/PropertyEditor.cpp index d1e29a7da..1a8194269 100644 --- a/src/Gui/propertyeditor/PropertyEditor.cpp +++ b/src/Gui/propertyeditor/PropertyEditor.cpp @@ -156,8 +156,32 @@ void PropertyEditor::updateProperty(const App::Property& prop) void PropertyEditor::appendProperty(const App::Property& prop) { - //TODO: Find any property with the same container parent - //propertyModel->appendProperty(prop); + // check if the parent object is selected + std::string editor = prop.getEditorName(); + if (editor.empty()) + return; + App::PropertyContainer* parent = prop.getContainer(); + std::string context = prop.getName(); + + bool canAddProperty = (!propList.empty()); + for (PropertyModel::PropertyList::iterator it = propList.begin(); it != propList.end(); ++it) { + if (it->second.empty() || it->second.size() > 1) { + canAddProperty = false; + break; + } + else if (it->second.front()->getContainer() != parent) { + canAddProperty = false; + break; + } + } + + if (canAddProperty) { + std::vector list; + list.push_back(const_cast(&prop)); + std::pair< std::string, std::vector > pair = std::make_pair(context, list); + propList.push_back(pair); + propertyModel->appendProperty(prop); + } } void PropertyEditor::removeProperty(const App::Property& prop) @@ -167,6 +191,10 @@ void PropertyEditor::removeProperty(const App::Property& prop) std::vector::iterator pos = std::find(it->second.begin(), it->second.end(), &prop); if (pos != it->second.end()) { it->second.erase(pos); + // if the last property of this name is removed then also remove the whole group + if (it->second.empty()) { + propList.erase(it); + } propertyModel->removeProperty(prop); break; } diff --git a/src/Gui/propertyeditor/PropertyItem.cpp b/src/Gui/propertyeditor/PropertyItem.cpp index 64a6f90da..882cf4379 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), valid(true), readonly(false) +PropertyItem::PropertyItem() : parentItem(0), readonly(false) { precision = Base::UnitsApi::getDecimals(); } @@ -111,14 +111,14 @@ bool PropertyItem::hasProperty(const App::Property* prop) const return false; } -void PropertyItem::removeProperty(const App::Property* prop) +bool 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; } + + return propertyItems.empty(); } App::Property* PropertyItem::getFirstProperty() @@ -150,6 +150,15 @@ void PropertyItem::appendChild(PropertyItem *item) childItems.append(item); } +void PropertyItem::removeChildren(int from, int to) +{ + int count = to-from+1; + for (int i=0; i& getPropertyData() const; bool hasProperty(const App::Property*) const; - void removeProperty(const App::Property*); + bool removeProperty(const App::Property*); App::Property* getFirstProperty(); const App::Property* getFirstProperty() const; @@ -76,6 +76,7 @@ public: void setParent(PropertyItem* parent); PropertyItem *parent() const; void appendChild(PropertyItem *child); + void removeChildren(int from, int to); void setReadOnly(bool); bool isReadOnly() const; @@ -111,7 +112,6 @@ 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 1c98c1e3a..7c7fd41e6 100644 --- a/src/Gui/propertyeditor/PropertyModel.cpp +++ b/src/Gui/propertyeditor/PropertyModel.cpp @@ -282,6 +282,34 @@ void PropertyModel::updateProperty(const App::Property& prop) void PropertyModel::appendProperty(const App::Property& prop) { + QString editor = QString::fromAscii(prop.getEditorName()); + if (!editor.isEmpty()) { + Base::BaseClass* item = 0; + try { + item = static_cast(Base::Type:: + createInstanceByName(prop.getEditorName(),true)); + } + catch (...) { + } + if (!item) { + qWarning("No property item for type %s found\n", prop.getEditorName()); + } + else if (item->getTypeId().isDerivedFrom(PropertyItem::getClassTypeId())) { + // notify system to add new row + int row = rootItem->childCount(); + beginInsertRows(QModelIndex(), row, row); + + PropertyItem* child = static_cast(item); + child->setParent(rootItem); + rootItem->appendChild(child); + child->setPropertyName(QString::fromAscii(prop.getName())); + std::vector data; + data.push_back(const_cast(&prop)); + child->setPropertyData(data); + + endInsertRows(); + } + } } void PropertyModel::removeProperty(const App::Property& prop) @@ -291,10 +319,8 @@ void PropertyModel::removeProperty(const App::Property& prop) 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); + if (child->removeProperty(&prop)) { + removeRow(row, QModelIndex()); } break; } @@ -320,4 +346,20 @@ void PropertyModel::updateChildren(PropertyItem* item, int column, const QModelI } } +bool PropertyModel::removeRows(int row, int count, const QModelIndex& parent) +{ + PropertyItem* item; + if (!parent.isValid()) + item = rootItem; + else + item = static_cast(parent.internalPointer()); + + int start = row; + int end = row+count-1; + beginRemoveRows(parent, start, end); + item->removeChildren(start, end); + endRemoveRows(); + return true; +} + #include "moc_PropertyModel.cpp" diff --git a/src/Gui/propertyeditor/PropertyModel.h b/src/Gui/propertyeditor/PropertyModel.h index 62ec7a76d..97b3c75c9 100644 --- a/src/Gui/propertyeditor/PropertyModel.h +++ b/src/Gui/propertyeditor/PropertyModel.h @@ -58,6 +58,8 @@ public: bool setHeaderData (int section, Qt::Orientation orientation, const QVariant & value, int role = Qt::EditRole); void buildUp(const PropertyList& props); + bool removeRows(int row, int count, const QModelIndex & parent = QModelIndex()); + void updateProperty(const App::Property&); void appendProperty(const App::Property&); void removeProperty(const App::Property&); diff --git a/src/Mod/Spreadsheet/App/Sheet.cpp b/src/Mod/Spreadsheet/App/Sheet.cpp index 8335ee3ae..0dcd7f408 100644 --- a/src/Mod/Spreadsheet/App/Sheet.cpp +++ b/src/Mod/Spreadsheet/App/Sheet.cpp @@ -509,7 +509,7 @@ Property * Sheet::setFloatProperty(CellAddress key, double value) props.removeDynamicProperty(key.toString().c_str()); propAddress.erase(prop); } - floatProp = freecad_dynamic_cast(props.addDynamicProperty("App::PropertyFloat", key.toString().c_str(), 0, 0, Prop_ReadOnly | Prop_Transient, true, true)); + floatProp = freecad_dynamic_cast(props.addDynamicProperty("App::PropertyFloat", key.toString().c_str(), 0, 0, Prop_ReadOnly | Prop_Hidden | Prop_Transient, true, true)); floatProp->StatusBits.set(3); } else @@ -541,7 +541,7 @@ Property * Sheet::setQuantityProperty(CellAddress key, double value, const Base: props.removeDynamicProperty(key.toString().c_str()); propAddress.erase(prop); } - Property * p = props.addDynamicProperty("Spreadsheet::PropertySpreadsheetQuantity", key.toString().c_str(), 0, 0, Prop_ReadOnly | Prop_Transient, true, true); + Property * p = props.addDynamicProperty("Spreadsheet::PropertySpreadsheetQuantity", key.toString().c_str(), 0, 0, Prop_ReadOnly | Prop_Hidden | Prop_Transient, true, true); quantityProp = freecad_dynamic_cast(p); quantityProp->StatusBits.set(3); } @@ -576,7 +576,7 @@ Property * Sheet::setStringProperty(CellAddress key, const std::string & value) props.removeDynamicProperty(key.toString().c_str()); propAddress.erase(prop); } - stringProp = freecad_dynamic_cast(props.addDynamicProperty("App::PropertyString", key.toString().c_str(), 0, 0, Prop_ReadOnly | Prop_Transient, true, true)); + stringProp = freecad_dynamic_cast(props.addDynamicProperty("App::PropertyString", key.toString().c_str(), 0, 0, Prop_ReadOnly | Prop_Hidden | Prop_Transient, true, true)); stringProp->StatusBits.set(3); }