+ support of adding/removing dynamic properties in property editor

This commit is contained in:
wmayer 2015-11-16 22:47:29 +01:00
parent ba21766096
commit 1225a7ac06
7 changed files with 99 additions and 18 deletions

View File

@ -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);
}

View File

@ -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<App::Property*> list;
list.push_back(const_cast<App::Property*>(&prop));
std::pair< std::string, std::vector<App::Property*> > 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<App::Property*>::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;
}

View File

@ -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<App::Property*>::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<count; i++) {
PropertyItem* child = childItems.takeAt(from);
delete child;
}
}
PropertyItem *PropertyItem::child(int row)
{
return childItems.value(row);
@ -356,9 +365,6 @@ 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;

View File

@ -63,7 +63,7 @@ public:
void updateData();
const std::vector<App::Property*>& 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<App::Property*> propertyItems;
PropertyItem *parentItem;
QList<PropertyItem*> childItems;
bool valid;
bool readonly;
int precision;
};

View File

@ -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::BaseClass*>(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<PropertyItem*>(item);
child->setParent(rootItem);
rootItem->appendChild(child);
child->setPropertyName(QString::fromAscii(prop.getName()));
std::vector<App::Property*> data;
data.push_back(const_cast<App::Property*>(&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; row<numChild; row++) {
PropertyItem* child = rootItem->child(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<PropertyItem*>(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"

View File

@ -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&);

View File

@ -509,7 +509,7 @@ Property * Sheet::setFloatProperty(CellAddress key, double value)
props.removeDynamicProperty(key.toString().c_str());
propAddress.erase(prop);
}
floatProp = freecad_dynamic_cast<PropertyFloat>(props.addDynamicProperty("App::PropertyFloat", key.toString().c_str(), 0, 0, Prop_ReadOnly | Prop_Transient, true, true));
floatProp = freecad_dynamic_cast<PropertyFloat>(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<PropertySpreadsheetQuantity>(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<PropertyString>(props.addDynamicProperty("App::PropertyString", key.toString().c_str(), 0, 0, Prop_ReadOnly | Prop_Transient, true, true));
stringProp = freecad_dynamic_cast<PropertyString>(props.addDynamicProperty("App::PropertyString", key.toString().c_str(), 0, 0, Prop_ReadOnly | Prop_Hidden | Prop_Transient, true, true));
stringProp->StatusBits.set(3);
}