diff --git a/src/Gui/PropertyView.cpp b/src/Gui/PropertyView.cpp index f79e80b58..5b23b74a8 100644 --- a/src/Gui/PropertyView.cpp +++ b/src/Gui/PropertyView.cpp @@ -29,7 +29,6 @@ #endif /// Here the FreeCAD includes sorted by Base,App,Gui...... - #include #include #include @@ -78,6 +77,23 @@ PropertyView::~PropertyView() { } +struct PropertyView::PropInfo +{ + std::string propName; + int propId; + std::vector propList; +}; + +struct PropertyView::PropFind { + const PropInfo& item; + PropFind(const PropInfo& item) : item(item) {} + bool operator () (const PropInfo& elem) const + { + return (elem.propId == item.propId) && + (elem.propName == item.propName); + } +}; + void PropertyView::onSelectionChanged(const SelectionChanges& msg) { if (msg.Type != SelectionChanges::AddSelection && @@ -85,44 +101,67 @@ void PropertyView::onSelectionChanged(const SelectionChanges& msg) msg.Type != SelectionChanges::SetSelection && msg.Type != SelectionChanges::ClrSelection) return; + // group the properties by - std::map, std::vector > propDataMap; - std::map, std::vector > propViewMap; + std::vector propDataMap; + std::vector propViewMap; std::vector array = Gui::Selection().getCompleteSelection(); for (std::vector::const_iterator it = array.begin(); it != array.end(); ++it) { App::DocumentObject *ob=0; ViewProvider *vp=0; - std::map dataMap; - std::map viewMap; + std::vector dataList; + std::map viewList; if ((*it).pObject) { - (*it).pObject->getPropertyMap(dataMap); + (*it).pObject->getPropertyList(dataList); ob = (*it).pObject; // get also the properties of the associated view provider Gui::Document* doc = Gui::Application::Instance->getDocument(it->pDoc); vp = doc->getViewProvider((*it).pObject); if(!vp) continue; - vp->getPropertyMap(viewMap); + // get the properties as map here because it doesn't matter to have them sorted alphabetically + vp->getPropertyMap(viewList); } // store the properties with as key in a map - std::map::iterator pt; + std::vector::iterator pt; if (ob) { - for (pt = dataMap.begin(); pt != dataMap.end(); ++pt) { - std::pair nameType = std::make_pair - (pt->first, pt->second->getTypeId().getKey()); - if (!ob->isHidden(pt->second) && !pt->second->StatusBits.test(3)) - propDataMap[nameType].push_back(pt->second); + for (pt = dataList.begin(); pt != dataList.end(); ++pt) { + PropInfo nameType; + nameType.propName = ob->getName(*pt); + nameType.propId = (*pt)->getTypeId().getKey(); + + if (!ob->isHidden(*pt) && !(*pt)->StatusBits.test(3)) { + std::vector::iterator pi = std::find_if(propDataMap.begin(), propDataMap.end(), PropFind(nameType)); + if (pi != propDataMap.end()) { + pi->propList.push_back(*pt); + } + else { + nameType.propList.push_back(*pt); + propDataMap.push_back(nameType); + } + } } } // the same for the view properties if (vp) { - for(pt = viewMap.begin(); pt != viewMap.end(); ++pt) { - std::pair nameType = std::make_pair - ( pt->first, pt->second->getTypeId().getKey()); - if (!vp->isHidden(pt->second) && !pt->second->StatusBits.test(3)) - propViewMap[nameType].push_back(pt->second); + std::map::iterator pt; + for (pt = viewList.begin(); pt != viewList.end(); ++pt) { + PropInfo nameType; + nameType.propName = pt->first; + nameType.propId = pt->second->getTypeId().getKey(); + + if (!vp->isHidden(pt->second) && !pt->second->StatusBits.test(3)) { + std::vector::iterator pi = std::find_if(propViewMap.begin(), propViewMap.end(), PropFind(nameType)); + if (pi != propViewMap.end()) { + pi->propList.push_back(pt->second); + } + else { + nameType.propList.push_back(pt->second); + propViewMap.push_back(nameType); + } + } } } } @@ -130,20 +169,19 @@ void PropertyView::onSelectionChanged(const SelectionChanges& msg) // the property must be part of each selected object, i.e. the number // of selected objects is equal to the number of properties with same // name and id - std::map, std::vector > - ::const_iterator it; - std::map > dataProps; + std::vector::const_iterator it; + PropertyModel::PropertyList dataProps; for (it = propDataMap.begin(); it != propDataMap.end(); ++it) { - if (it->second.size() == array.size()) { - dataProps[it->first.first] = it->second; + if (it->propList.size() == array.size()) { + dataProps.push_back(std::make_pair(it->propName, it->propList)); } } propertyEditorData->buildUp(dataProps); - std::map > viewProps; + PropertyModel::PropertyList viewProps; for (it = propViewMap.begin(); it != propViewMap.end(); ++it) { - if (it->second.size() == array.size()) { - viewProps[it->first.first] = it->second; + if (it->propList.size() == array.size()) { + viewProps.push_back(std::make_pair(it->propName, it->propList)); } } propertyEditorView->buildUp(viewProps); diff --git a/src/Gui/PropertyView.h b/src/Gui/PropertyView.h index 0b87cd115..532ef0fc9 100644 --- a/src/Gui/PropertyView.h +++ b/src/Gui/PropertyView.h @@ -69,6 +69,8 @@ private: void onSelectionChanged(const SelectionChanges& msg); private: + struct PropInfo; + struct PropFind; QTabWidget* tabs; }; diff --git a/src/Gui/propertyeditor/PropertyEditor.cpp b/src/Gui/propertyeditor/PropertyEditor.cpp index 92180f7ca..1640c0f43 100644 --- a/src/Gui/propertyeditor/PropertyEditor.cpp +++ b/src/Gui/propertyeditor/PropertyEditor.cpp @@ -89,7 +89,7 @@ void PropertyEditor::commitData (QWidget * editor) committing = false; if (delaybuild) { delaybuild = false; - propertyModel->buildUp(std::map >()); + propertyModel->buildUp(PropertyModel::PropertyList()); } } @@ -126,7 +126,7 @@ void PropertyEditor::drawBranches(QPainter *painter, const QRect &rect, const QM //painter->setPen(savedPen); } -void PropertyEditor::buildUp(const std::map >& props) +void PropertyEditor::buildUp(const PropertyModel::PropertyList& props) { if (committing) { Base::Console().Warning("While committing the data to the property the selection has changed.\n"); diff --git a/src/Gui/propertyeditor/PropertyEditor.h b/src/Gui/propertyeditor/PropertyEditor.h index aa9c89587..53f004b20 100644 --- a/src/Gui/propertyeditor/PropertyEditor.h +++ b/src/Gui/propertyeditor/PropertyEditor.h @@ -31,6 +31,7 @@ #include #include "PropertyItem.h" +#include "PropertyModel.h" namespace App { class Property; @@ -49,7 +50,7 @@ public: ~PropertyEditor(); /** Builds up the list view with the properties. */ - void buildUp(const std::map >& props); + void buildUp(const PropertyModel::PropertyList& props); void setAutomaticDocumentUpdate(bool); bool isAutomaticDocumentUpdate(bool) const; diff --git a/src/Gui/propertyeditor/PropertyModel.cpp b/src/Gui/propertyeditor/PropertyModel.cpp index 05c9e06a5..c1d6dbfad 100644 --- a/src/Gui/propertyeditor/PropertyModel.cpp +++ b/src/Gui/propertyeditor/PropertyModel.cpp @@ -199,15 +199,14 @@ QModelIndex PropertyModel::propertyIndexFromPath(const QStringList& path) const return parent; } -void PropertyModel::buildUp(const std::map >& props) +void PropertyModel::buildUp(const PropertyModel::PropertyList& props) { // fill up the listview with the properties rootItem->reset(); // sort the properties into their groups std::map > > propGroup; - std::map > - ::const_iterator jt; + PropertyModel::PropertyList::const_iterator jt; for (jt = props.begin(); jt != props.end(); ++jt) { App::Property* prop = jt->second.front(); const char* group = prop->getGroup(); diff --git a/src/Gui/propertyeditor/PropertyModel.h b/src/Gui/propertyeditor/PropertyModel.h index aeb57a6da..9d7282112 100644 --- a/src/Gui/propertyeditor/PropertyModel.h +++ b/src/Gui/propertyeditor/PropertyModel.h @@ -41,6 +41,8 @@ class PropertyModel : public QAbstractItemModel Q_OBJECT public: + typedef std::vector< std::pair< std::string, std::vector > > PropertyList; + PropertyModel(QObject* parent); virtual ~PropertyModel(); @@ -54,7 +56,7 @@ public: int rowCount (const QModelIndex & parent = QModelIndex()) const; 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 std::map >& props); + void buildUp(const PropertyList& props); QStringList propertyPathFromIndex(const QModelIndex&) const; QModelIndex propertyIndexFromPath(const QStringList&) const;