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:
Zheng, Lei
2019-07-11 13:02:45 +08:00
committed by wmayer
parent ebf321fc47
commit 8b3ef8faf5
23 changed files with 2292 additions and 564 deletions

View File

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