From 65d5c85eb27d0e950db2c093821ac82c71d3503d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20St=C3=B8ren?= Date: Sun, 15 Sep 2013 09:27:55 +0200 Subject: [PATCH] Caf: New Draft of Ui tree creation system. p4#: 22414 --- cafProjectDataModel/CMakeLists.txt | 3 + cafProjectDataModel/cafPdmObject.cpp | 66 +++++++++++++++ cafProjectDataModel/cafPdmObject.h | 14 +++- cafProjectDataModel/cafPdmUiTreeOrdering.cpp | 87 ++++++++++++++++++++ cafProjectDataModel/cafPdmUiTreeOrdering.h | 70 ++++++++++++++++ cafUserInterface/cafUiTreeItem.h | 5 +- 6 files changed, 242 insertions(+), 3 deletions(-) create mode 100644 cafProjectDataModel/cafPdmUiTreeOrdering.cpp create mode 100644 cafProjectDataModel/cafPdmUiTreeOrdering.h diff --git a/cafProjectDataModel/CMakeLists.txt b/cafProjectDataModel/CMakeLists.txt index 26c484498d..7c44db43b2 100644 --- a/cafProjectDataModel/CMakeLists.txt +++ b/cafProjectDataModel/CMakeLists.txt @@ -28,4 +28,7 @@ add_library( ${PROJECT_NAME} cafPdmUiObjectEditorHandle.h cafPdmUiOrdering.cpp cafPdmUiOrdering.h + cafPdmUiTreeOrdering.cpp + cafPdmUiTreeOrdering.h + ) diff --git a/cafProjectDataModel/cafPdmObject.cpp b/cafProjectDataModel/cafPdmObject.cpp index cf4aaf9117..533a6d39f6 100644 --- a/cafProjectDataModel/cafPdmObject.cpp +++ b/cafProjectDataModel/cafPdmObject.cpp @@ -26,6 +26,7 @@ #include #include "cafPdmObjectFactory.h" #include "cafPdmDocument.h" +#include "cafPdmUiTreeOrdering.h" namespace caf { @@ -363,6 +364,71 @@ PdmObject* PdmObject::deepCopy() */ } +//-------------------------------------------------------------------------------------------------- +/// This method is to be used to create a tree-representation of the object hierarchy starting at this +/// object. The caller is responsible to delete the returned PdmUiTreeOrdering +//-------------------------------------------------------------------------------------------------- +PdmUiTreeOrdering* PdmObject::uiTreeOrdering(QString uiConfigName /*= ""*/) +{ + PdmUiTreeOrdering* uiTreeOrdering = new PdmUiTreeOrdering(NULL, -1, this); + + this->defineUiTreeOrdering(*uiTreeOrdering, uiConfigName); + + if (!uiTreeOrdering->forgetRemainingFields()) + { + // Add the remaining Fields To UiConfig + + for (size_t fIdx = 0; fIdx < m_fields.size(); ++fIdx) + { + if ( (m_fields[fIdx]->hasChildObjects()) && !uiTreeOrdering->containsField(m_fields[fIdx])) + { + uiTreeOrdering->add( m_fields[fIdx]); + } + } + } + + expandUiTree(uiTreeOrdering, uiConfigName); + return uiTreeOrdering; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmObject::expandUiTree(PdmUiTreeOrdering* root, QString uiConfigName /*= "" */) +{ + if (!root) return; + + if ( root->childCount() == 0) + { + if (!root->isSubTreeDefined() && root->dataObject()) + { + + if (root->m_field) + { + std::vector fieldsChildObjects; + root->m_field->childObjects(&fieldsChildObjects); + for (size_t cIdx = 0; cIdx < fieldsChildObjects.size(); ++cIdx) + { + root->add(fieldsChildObjects[cIdx]); + } + } + else + { + root->dataObject()->defineUiTreeOrdering(*root, uiConfigName); + } + } + } + + for (int cIdx = 0; cIdx < root->childCount(); ++cIdx) + { + PdmUiTreeOrdering* child = dynamic_cast(root->child(cIdx)); + if (!child->isSubTreeDefined()) + { + expandUiTree(child); + } + } +} } //End of namespace caf diff --git a/cafProjectDataModel/cafPdmObject.h b/cafProjectDataModel/cafPdmObject.h index a805169cd1..f91bbce329 100644 --- a/cafProjectDataModel/cafPdmObject.h +++ b/cafProjectDataModel/cafPdmObject.h @@ -50,7 +50,7 @@ namespace caf class PdmFieldHandle; template < class FieldDataType > class PdmField; class PdmUiEditorAttribute; - +class PdmUiTreeOrdering; //================================================================================================== /// Macros helping in development of PDM objects //================================================================================================== @@ -146,6 +146,10 @@ public: /// supplied by the \sa defineUiOrdering method that can be reimplemented void uiOrdering(QString uiConfigName, PdmUiOrdering& uiOrdering) ; + /// Method to be called by Ui displaying a tree representation of the object hierarchy + /// Caller must delete the returned object. + PdmUiTreeOrdering* uiTreeOrdering( QString uiConfigName = ""); + /// For a specific field, return editor specific parameters used to customize the editor behavior. void editorAttribute(const PdmFieldHandle* field, QString uiConfigName, PdmUiEditorAttribute * attribute); @@ -184,6 +188,10 @@ protected: // Virtual /// If the uiOrdering is empty, it is interpreted as meaning all fields w/o grouping. virtual void defineUiOrdering(QString uiConfigName, PdmUiOrdering& uiOrdering) {} + /// Override to customize the tree representations of the object hierarchy. + /// If the PdmUiTreeOrdering is empty, it is interpreted as meaning all fields containing child objects in order + virtual void defineUiTreeOrdering(PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "" ) { } + /// Override to provide editor specific data for the field and uiConfigName virtual void defineEditorAttribute(const PdmFieldHandle* field, QString uiConfigName, PdmUiEditorAttribute * attribute) {} @@ -227,6 +235,10 @@ private: void addParentField(PdmFieldHandle* parentField); void removeParentField(PdmFieldHandle* parentField); +private: + /// Recursive function to traverse and create a Ui tree representation of the object hierarchy + static void expandUiTree( PdmUiTreeOrdering* root, QString uiConfigName = "" ); + private: std::multiset m_parentFields; std::vector m_fields; diff --git a/cafProjectDataModel/cafPdmUiTreeOrdering.cpp b/cafProjectDataModel/cafPdmUiTreeOrdering.cpp new file mode 100644 index 0000000000..0ac0cede76 --- /dev/null +++ b/cafProjectDataModel/cafPdmUiTreeOrdering.cpp @@ -0,0 +1,87 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2012 Ceetron AS +// +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +//################################################################################################## + +#include "cafPdmUiTreeOrdering.h" +#include "cafPdmField.h" + +namespace caf +{ + + + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + void PdmUiTreeOrdering::add(PdmFieldHandle * field) + { + PdmUiTreeOrdering* to = new PdmUiTreeOrdering(this, -1, field->ownerObject()); + to->m_field = field; + } + + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + void PdmUiTreeOrdering::add(PdmObject* object) + { + PdmUiTreeOrdering* to = new PdmUiTreeOrdering(this, -1, object); + } + + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + PdmUiTreeOrdering* PdmUiTreeOrdering::add(const QString & title, const QString& iconResourceName) + { + PdmUiTreeOrdering* to = new PdmUiTreeOrdering(this, -1, NULL); + to->m_uiInfo = new PdmUiItemInfo(title, QIcon(iconResourceName)); + return to; + } + + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + bool PdmUiTreeOrdering::containsField(PdmFieldHandle* field) + { + assert (field); + for (int cIdx = 0; cIdx < this->childCount(); ++cIdx) + { + PdmUiTreeOrdering* child = dynamic_cast(this->child(cIdx)); + + if (!(child->m_field == field)) + { + return true; + } + } + + return false; + } + + //-------------------------------------------------------------------------------------------------- + /// Creates an new PdmUiTreeOrdering item, and adds it to parent. If position is -1, it is added + /// at the end of parents existing child list. + //-------------------------------------------------------------------------------------------------- + PdmUiTreeOrdering::PdmUiTreeOrdering(PdmUiTreeOrdering* parent /*= NULL*/, int position /*= -1*/, PdmObject* dataObject /*= NULL*/) : UiTreeItem< PdmPointer >(parent, position, dataObject), + m_field(NULL), + m_uiInfo(NULL), + m_forgetRemainingFields(false), + m_isSubTreeDefined(false) + { + + } + +} //End of namespace caf + diff --git a/cafProjectDataModel/cafPdmUiTreeOrdering.h b/cafProjectDataModel/cafPdmUiTreeOrdering.h new file mode 100644 index 0000000000..57d71828df --- /dev/null +++ b/cafProjectDataModel/cafPdmUiTreeOrdering.h @@ -0,0 +1,70 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2012 Ceetron AS +// +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +//################################################################################################## + +#pragma once +#include +#include + +#include "cafPdmUiItem.h" +#include "../cafUserInterface/cafUiTreeItem.h" +#include "cafPdmPointer.h" + +namespace caf +{ + +class PdmObject; +class PdmFieldHandle; + +//typedef UiTreeItem > PdmUiTreeItem; + +//================================================================================================== +/// Class storing a tree structure representation of some PdmObject hierarchy to be used for tree views in the Gui +//================================================================================================== + +class PdmUiTreeOrdering : public UiTreeItem< PdmPointer > +{ + PdmUiTreeOrdering(PdmUiTreeOrdering* parent = NULL, int position = -1, PdmObject* dataObject = NULL); + + void add(PdmFieldHandle * field); + void add(PdmObject* object); + PdmUiTreeOrdering* add(const QString & title, const QString& iconResourceName ); + + /// If the rest of the fields containing children is supposed to be omitted, setForgetRemainingFileds to true. + void setForgetRemainingFields(bool val) { m_forgetRemainingFields = val; } + /// To stop the tree generation at this level, setSubTreeDefined to true + void setSubTreeDefined(bool isSubTreeDefined ) { m_isSubTreeDefined = isSubTreeDefined; } + +private: + friend class PdmObject; + bool forgetRemainingFields() const { return m_forgetRemainingFields; } + bool isSubTreeDefined() const { return m_isSubTreeDefined; } + bool containsField(PdmFieldHandle* field); + +private: + PdmFieldHandle* m_field; + PdmUiItemInfo* m_uiInfo; + + bool m_forgetRemainingFields; + bool m_isSubTreeDefined; +}; + + + +} // End of namespace caf + diff --git a/cafUserInterface/cafUiTreeItem.h b/cafUserInterface/cafUiTreeItem.h index 08382be5d8..8ee67e3072 100644 --- a/cafUserInterface/cafUiTreeItem.h +++ b/cafUserInterface/cafUiTreeItem.h @@ -19,7 +19,8 @@ #pragma once -#include +//#include +#include #include @@ -47,7 +48,7 @@ public: setDataObject(dataObject); } - ~UiTreeItem() + virtual ~UiTreeItem() { qDeleteAll(m_childItems); }