+ support of adding/removing dynamic properties in property editor
This commit is contained in:
parent
ba21766096
commit
1225a7ac06
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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&);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user