Gui: property view related changes
* Display property from linked object, colored green, * Change DlgPropertyLink to support external linking and sub-object selection * Improve large selection performance by using a timer * Improve TAB key behavior in property editor * Add context menu to show hidden properties, change property status, set expression on any and property, and add/remove dynamic properties * Optimize expression completer model construction, as the original implementation gets prohibitively slow for moderate number of objects.
This commit is contained in:
@@ -27,8 +27,11 @@
|
||||
# include <cfloat>
|
||||
#endif
|
||||
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
|
||||
#include "PropertyModel.h"
|
||||
#include "PropertyItem.h"
|
||||
#include "PropertyView.h"
|
||||
|
||||
using namespace Gui::PropertyEditor;
|
||||
|
||||
@@ -206,6 +209,24 @@ QModelIndex PropertyModel::propertyIndexFromPath(const QStringList& path) const
|
||||
return parent;
|
||||
}
|
||||
|
||||
struct PropItemInfo {
|
||||
const std::string &name;
|
||||
const std::vector<App::Property*> &props;
|
||||
|
||||
PropItemInfo(const std::string &n, const std::vector<App::Property*> &p)
|
||||
:name(n),props(p)
|
||||
{}
|
||||
};
|
||||
|
||||
static void setPropertyItemName(PropertyItem *item, const char *propName, QString groupName) {
|
||||
QString name = QString::fromLatin1(propName);
|
||||
if(name.size()>groupName.size()+1
|
||||
&& name.startsWith(groupName + QLatin1Char('_')))
|
||||
name = name.right(name.size()-groupName.size()-1);
|
||||
|
||||
item->setPropertyName(name);
|
||||
}
|
||||
|
||||
void PropertyModel::buildUp(const PropertyModel::PropertyList& props)
|
||||
{
|
||||
beginResetModel();
|
||||
@@ -214,42 +235,47 @@ void PropertyModel::buildUp(const PropertyModel::PropertyList& props)
|
||||
rootItem->reset();
|
||||
|
||||
// sort the properties into their groups
|
||||
std::map<std::string, std::vector<std::vector<App::Property*> > > propGroup;
|
||||
std::map<std::string, std::vector<PropItemInfo> > propGroup;
|
||||
PropertyModel::PropertyList::const_iterator jt;
|
||||
for (jt = props.begin(); jt != props.end(); ++jt) {
|
||||
App::Property* prop = jt->second.front();
|
||||
const char* group = prop->getGroup();
|
||||
bool isEmpty = (group == 0 || group[0] == '\0');
|
||||
std::string grp = isEmpty ? QT_TRANSLATE_NOOP("App::Property", "Base") : group;
|
||||
propGroup[grp].push_back(jt->second);
|
||||
propGroup[grp].emplace_back(jt->first,jt->second);
|
||||
}
|
||||
|
||||
std::map<std::string, std::vector<std::vector<App::Property*> > >
|
||||
::const_iterator kt;
|
||||
for (kt = propGroup.begin(); kt != propGroup.end(); ++kt) {
|
||||
for (auto kt = propGroup.begin(); kt != propGroup.end(); ++kt) {
|
||||
// set group item
|
||||
PropertyItem* group = static_cast<PropertyItem*>(PropertySeparatorItem::create());
|
||||
group->setParent(rootItem);
|
||||
rootItem->appendChild(group);
|
||||
group->setPropertyName(QString::fromLatin1(kt->first.c_str()));
|
||||
QString groupName = QString::fromLatin1(kt->first.c_str());
|
||||
group->setPropertyName(groupName);
|
||||
|
||||
// setup the items for the properties
|
||||
std::vector<std::vector<App::Property*> >::const_iterator it;
|
||||
for (it = kt->second.begin(); it != kt->second.end(); ++it) {
|
||||
App::Property* prop = it->front();
|
||||
QString editor = QString::fromLatin1(prop->getEditorName());
|
||||
if (!editor.isEmpty()) {
|
||||
PropertyItem* item = PropertyItemFactory::instance().createPropertyItem(prop->getEditorName());
|
||||
for (auto it = kt->second.begin(); it != kt->second.end(); ++it) {
|
||||
const auto &info = *it;
|
||||
App::Property* prop = info.props.front();
|
||||
std::string editor(prop->getEditorName());
|
||||
if(editor.empty() && PropertyView::showAll())
|
||||
editor = "Gui::PropertyEditor::PropertyItem";
|
||||
if (!editor.empty()) {
|
||||
PropertyItem* item = PropertyItemFactory::instance().createPropertyItem(editor.c_str());
|
||||
if (!item) {
|
||||
qWarning("No property item for type %s found\n", prop->getEditorName());
|
||||
qWarning("No property item for type %s found\n", editor.c_str());
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
if(boost::ends_with(info.name,"*"))
|
||||
item->setLinked(true);
|
||||
PropertyItem* child = (PropertyItem*)item;
|
||||
child->setParent(rootItem);
|
||||
rootItem->appendChild(child);
|
||||
child->setPropertyName(QString::fromLatin1(prop->getName()));
|
||||
child->setPropertyData(*it);
|
||||
|
||||
setPropertyItemName(child,prop->getName(),groupName);
|
||||
|
||||
child->setPropertyData(info.props);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -279,11 +305,13 @@ void PropertyModel::updateProperty(const App::Property& prop)
|
||||
|
||||
void PropertyModel::appendProperty(const App::Property& prop)
|
||||
{
|
||||
QString editor = QString::fromLatin1(prop.getEditorName());
|
||||
if (!editor.isEmpty()) {
|
||||
PropertyItem* item = PropertyItemFactory::instance().createPropertyItem(prop.getEditorName());
|
||||
std::string editor(prop.getEditorName());
|
||||
if(editor.empty() && PropertyView::showAll())
|
||||
editor = "Gui::PropertyEditor::PropertyItem";
|
||||
if (!editor.empty()) {
|
||||
PropertyItem* item = PropertyItemFactory::instance().createPropertyItem(editor.c_str());
|
||||
if (!item) {
|
||||
qWarning("No property item for type %s found\n", prop.getEditorName());
|
||||
qWarning("No property item for type %s found\n", editor.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -354,7 +382,8 @@ void PropertyModel::appendProperty(const App::Property& prop)
|
||||
|
||||
std::vector<App::Property*> data;
|
||||
data.push_back(const_cast<App::Property*>(&prop));
|
||||
item->setPropertyName(QString::fromLatin1(prop.getName()));
|
||||
|
||||
setPropertyItemName(item,prop.getName(),groupName);
|
||||
item->setPropertyData(data);
|
||||
|
||||
endInsertRows();
|
||||
|
||||
Reference in New Issue
Block a user