+ property editor handles case when dynamic property is removed
This commit is contained in:
parent
4f4d747968
commit
ba21766096
|
@ -141,6 +141,17 @@ public:
|
|||
boost::signal<void (const App::DocumentObject&)> 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<void (const App::Property&)> signalAppendDynamicProperty;
|
||||
/// signal on about removing a dynamic property
|
||||
boost::signal<void (const App::Property&)> signalRemoveDynamicProperty;
|
||||
//@}
|
||||
|
||||
|
||||
/** @name methods for parameter handling */
|
||||
//@{
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "DynamicProperty.h"
|
||||
#include "Property.h"
|
||||
#include "PropertyContainer.h"
|
||||
#include "Application.h"
|
||||
#include <Base/Reader.h>
|
||||
#include <Base/Writer.h>
|
||||
#include <Base/Console.h>
|
||||
|
@ -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<std::string,PropData>::iterator it = props.find(name);
|
||||
if (it != props.end()) {
|
||||
GetApplication().signalRemoveDynamicProperty(*it->second.property);
|
||||
delete it->second.property;
|
||||
props.erase(it);
|
||||
return true;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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<App::Property*>::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"
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<App::Property*>::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;
|
||||
|
|
|
@ -63,6 +63,7 @@ public:
|
|||
void updateData();
|
||||
const std::vector<App::Property*>& 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<App::Property*> propertyItems;
|
||||
PropertyItem *parentItem;
|
||||
QList<PropertyItem*> childItems;
|
||||
bool valid;
|
||||
bool readonly;
|
||||
int precision;
|
||||
};
|
||||
|
|
|
@ -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; 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);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PropertyModel::updateChildren(PropertyItem* item, int column, const QModelIndex& parent)
|
||||
{
|
||||
int numChild = item->childCount();
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user