App/Gui: allow change dynamic property group and documentation
Exposed as PropertyContainerPy.setGroup/DocumentationOfProperty. Added a menu action to property view for rename dynamic property group.
This commit is contained in:
@@ -297,6 +297,18 @@ DynamicProperty::PropData DynamicProperty::getDynamicPropertyData(const Property
|
||||
return PropData();
|
||||
}
|
||||
|
||||
bool DynamicProperty::changeDynamicProperty(const Property *prop, const char *group, const char *doc) {
|
||||
auto &index = props.get<1>();
|
||||
auto it = index.find(const_cast<Property*>(prop));
|
||||
if (it == index.end())
|
||||
return false;
|
||||
if(group)
|
||||
it->group = group;
|
||||
if(doc)
|
||||
it->doc = doc;
|
||||
return true;
|
||||
}
|
||||
|
||||
const char *DynamicProperty::getPropertyName(const Property *prop) const
|
||||
{
|
||||
auto &index = props.get<1>();
|
||||
|
||||
@@ -149,8 +149,8 @@ public:
|
||||
Property* property;
|
||||
std::string name;
|
||||
const char *pName;
|
||||
std::string group;
|
||||
std::string doc;
|
||||
mutable std::string group;
|
||||
mutable std::string doc;
|
||||
short attr;
|
||||
bool readonly;
|
||||
bool hidden;
|
||||
@@ -168,6 +168,8 @@ public:
|
||||
|
||||
PropData getDynamicPropertyData(const Property* prop) const;
|
||||
|
||||
bool changeDynamicProperty(const Property *prop, const char *group, const char *doc);
|
||||
|
||||
private:
|
||||
std::string getUniquePropertyName(PropertyContainer &pc, const char *Name) const;
|
||||
|
||||
|
||||
@@ -200,6 +200,10 @@ public:
|
||||
return dynamicProps.getDynamicPropertyData(prop);
|
||||
}
|
||||
|
||||
bool changeDynamicProperty(const Property *prop, const char *group, const char *doc) {
|
||||
return dynamicProps.changeDynamicProperty(prop,group,doc);
|
||||
}
|
||||
|
||||
virtual bool removeDynamicProperty(const char* name) {
|
||||
return dynamicProps.removeDynamicProperty(name);
|
||||
}
|
||||
|
||||
@@ -68,6 +68,11 @@ If the list contains 'Hidden' then the item even doesn't appear in the property
|
||||
<UserDocu>Return the name of the group which the property belongs to in this class. The properties sorted in different named groups for convenience.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="setGroupOfProperty">
|
||||
<Documentation>
|
||||
<UserDocu>Set the name of the group of a dynamic property.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="setPropertyStatus">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
@@ -97,6 +102,11 @@ text names of the status.
|
||||
<UserDocu>Return the documentation string of the property of this class.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="setDocumentationOfProperty">
|
||||
<Documentation>
|
||||
<UserDocu>Set the documentation string of a dynamic property of this class.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="getEnumerationsOfProperty">
|
||||
<Documentation>
|
||||
<UserDocu>Return all enumeration strings of the property of this class or None if not a PropertyEnumeration.</UserDocu>
|
||||
|
||||
@@ -339,6 +339,25 @@ PyObject* PropertyContainerPy::getGroupOfProperty(PyObject *args)
|
||||
return Py::new_reference_to(Py::String(""));
|
||||
}
|
||||
|
||||
PyObject* PropertyContainerPy::setGroupOfProperty(PyObject *args)
|
||||
{
|
||||
char *pstr;
|
||||
char *group;
|
||||
if (!PyArg_ParseTuple(args, "ss", &pstr, &group)) // convert args: Python->C
|
||||
return NULL; // NULL triggers exception
|
||||
|
||||
PY_TRY {
|
||||
Property* prop = getPropertyContainerPtr()->getDynamicPropertyByName(pstr);
|
||||
if (!prop) {
|
||||
PyErr_Format(PyExc_AttributeError, "Property container has no dynamic property '%s'", pstr);
|
||||
return 0;
|
||||
}
|
||||
prop->getContainer()->changeDynamicProperty(prop,group,0);
|
||||
Py_Return;
|
||||
} PY_CATCH
|
||||
}
|
||||
|
||||
|
||||
PyObject* PropertyContainerPy::getDocumentationOfProperty(PyObject *args)
|
||||
{
|
||||
char *pstr;
|
||||
@@ -358,6 +377,24 @@ PyObject* PropertyContainerPy::getDocumentationOfProperty(PyObject *args)
|
||||
return Py::new_reference_to(Py::String(""));
|
||||
}
|
||||
|
||||
PyObject* PropertyContainerPy::setDocumentationOfProperty(PyObject *args)
|
||||
{
|
||||
char *pstr;
|
||||
char *doc;
|
||||
if (!PyArg_ParseTuple(args, "ss", &pstr, &doc)) // convert args: Python->C
|
||||
return NULL; // NULL triggers exception
|
||||
|
||||
PY_TRY {
|
||||
Property* prop = getPropertyContainerPtr()->getDynamicPropertyByName(pstr);
|
||||
if (!prop) {
|
||||
PyErr_Format(PyExc_AttributeError, "Property container has no dynamic property '%s'", pstr);
|
||||
return 0;
|
||||
}
|
||||
prop->getContainer()->changeDynamicProperty(prop,0,doc);
|
||||
Py_Return;
|
||||
} PY_CATCH
|
||||
}
|
||||
|
||||
PyObject* PropertyContainerPy::getEnumerationsOfProperty(PyObject *args)
|
||||
{
|
||||
char *pstr;
|
||||
|
||||
@@ -31,8 +31,11 @@
|
||||
# include <QDialog>
|
||||
# include <QMessageBox>
|
||||
# include <QCheckBox>
|
||||
# include <QInputDialog>
|
||||
#endif
|
||||
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
|
||||
#include <Base/Console.h>
|
||||
#include <Base/Tools.h>
|
||||
#include <App/Application.h>
|
||||
@@ -57,6 +60,7 @@ PropertyEditor::PropertyEditor(QWidget *parent)
|
||||
, committing(false)
|
||||
, delaybuild(false)
|
||||
, binding(false)
|
||||
, checkDocument(false)
|
||||
{
|
||||
propertyModel = new PropertyModel(this);
|
||||
setModel(propertyModel);
|
||||
@@ -362,8 +366,10 @@ void PropertyEditor::drawBranches(QPainter *painter, const QRect &rect, const QM
|
||||
//painter->setPen(savedPen);
|
||||
}
|
||||
|
||||
void PropertyEditor::buildUp(PropertyModel::PropertyList &&props, bool checkDocument)
|
||||
void PropertyEditor::buildUp(PropertyModel::PropertyList &&props, bool _checkDocument)
|
||||
{
|
||||
checkDocument = _checkDocument;
|
||||
|
||||
if (committing) {
|
||||
Base::Console().Warning("While committing the data to the property the selection has changed.\n");
|
||||
delaybuild = true;
|
||||
@@ -493,6 +499,7 @@ enum MenuAction {
|
||||
MA_Expression,
|
||||
MA_RemoveProp,
|
||||
MA_AddProp,
|
||||
MA_EditPropGroup,
|
||||
MA_Transient,
|
||||
MA_Output,
|
||||
MA_NoRecompute,
|
||||
@@ -532,8 +539,20 @@ void PropertyEditor::contextMenuEvent(QContextMenuEvent *) {
|
||||
}
|
||||
}
|
||||
|
||||
if(props.size())
|
||||
if(props.size()) {
|
||||
menu.addAction(tr("Add property"))->setData(QVariant(MA_AddProp));
|
||||
unsigned count = 0;
|
||||
for(auto prop : props) {
|
||||
if(prop->testStatus(App::Property::PropDynamic)
|
||||
&& !boost::starts_with(prop->getName(),prop->getGroup()))
|
||||
{
|
||||
++count;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
if(count == props.size())
|
||||
menu.addAction(tr("Rename property group"))->setData(QVariant(MA_EditPropGroup));
|
||||
}
|
||||
|
||||
bool canRemove = !props.empty();
|
||||
unsigned long propType = 0;
|
||||
@@ -645,6 +664,22 @@ void PropertyEditor::contextMenuEvent(QContextMenuEvent *) {
|
||||
dlg.exec();
|
||||
return;
|
||||
}
|
||||
case MA_EditPropGroup: {
|
||||
// This operation is not undoable yet.
|
||||
const char *groupName = (*props.begin())->getGroup();
|
||||
if(!groupName)
|
||||
groupName = "Base";
|
||||
QString res = QInputDialog::getText(Gui::getMainWindow(),
|
||||
tr("Rename property group"), tr("Group name:"),
|
||||
QLineEdit::Normal, QString::fromUtf8(groupName));
|
||||
if(res.size()) {
|
||||
std::string group = res.toUtf8().constData();
|
||||
for(auto prop : props)
|
||||
prop->getContainer()->changeDynamicProperty(prop,group.c_str(),0);
|
||||
buildUp(PropertyModel::PropertyList(propList),checkDocument);
|
||||
}
|
||||
return;
|
||||
}
|
||||
case MA_RemoveProp: {
|
||||
App::AutoTransaction committer("Remove property");
|
||||
for(auto prop : props) {
|
||||
|
||||
@@ -124,6 +124,7 @@ private:
|
||||
bool committing;
|
||||
bool delaybuild;
|
||||
bool binding;
|
||||
bool checkDocument;
|
||||
|
||||
int transactionID = 0;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user