diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiObjectHandle.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiObjectHandle.h index dafde3f076..fdd4960608 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiObjectHandle.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiObjectHandle.h @@ -63,6 +63,7 @@ protected: /// Fill up the uiOrdering object with groups and field references to create the gui structure /// If the uiOrdering is empty, it is interpreted as meaning all fields w/o grouping. virtual void defineUiOrdering(QString uiConfigName, PdmUiOrdering& uiOrdering) {} + friend class PdmUiTreeViewModel; /// 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 diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewModel.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewModel.cpp index df931ad556..c1a2f7b32f 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewModel.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewModel.cpp @@ -37,6 +37,8 @@ #include "cafPdmUiTreeViewModel.h" +#include "cafPdmChildArrayField.h" +#include "cafPdmChildField.h" #include "cafPdmField.h" #include "cafPdmObject.h" #include "cafPdmUiTreeItemEditor.h" @@ -70,28 +72,42 @@ void PdmUiTreeViewModel::setPdmItemRoot(PdmUiItem* rootItem) return; } - PdmUiTreeOrdering* newRoot = NULL; - PdmUiFieldHandle* field = dynamic_cast (rootItem); + PdmUiTreeOrdering* invisibleRoot = NULL; + if (rootItem) + { + std::vector visibleItems; + findFirstVisibleUiItemInAllBranches(rootItem, visibleItems, m_uiConfigName); - if (field) - { - newRoot = new PdmUiTreeOrdering(field->fieldHandle()); - PdmUiObjectHandle::expandUiTree(newRoot, m_uiConfigName); - } - else - { - PdmUiObjectHandle * obj = dynamic_cast (rootItem); - if (obj) + if (visibleItems.size() > 0) { - newRoot = obj->uiTreeOrdering(m_uiConfigName); + invisibleRoot = new PdmUiTreeOrdering("Invisible Tree Root", ""); + + for (size_t i = 0; i < visibleItems.size(); i++) + { + PdmUiTreeOrdering* nextTreeOrdering = NULL; + + PdmUiFieldHandle* field = dynamic_cast (visibleItems[i]); + if (field) + { + nextTreeOrdering = new PdmUiTreeOrdering(field->fieldHandle()); + PdmUiObjectHandle::expandUiTree(nextTreeOrdering, m_uiConfigName); + } + else + { + PdmUiObjectHandle * obj = dynamic_cast (visibleItems[i]); + if (obj) + { + nextTreeOrdering = obj->uiTreeOrdering(m_uiConfigName); + } + } + + assert(nextTreeOrdering); + invisibleRoot->appendChild(nextTreeOrdering); + } } } - assert( newRoot || rootItem == NULL ); // Only fields, objects or NULL is allowed. - - if (newRoot) newRoot->debugDump(0); - - this->resetTree(newRoot); + this->resetTree(invisibleRoot); } //-------------------------------------------------------------------------------------------------- @@ -689,5 +705,78 @@ QVariant PdmUiTreeViewModel::headerData(int section, Qt::Orientation orientation return QVariant(); } +//-------------------------------------------------------------------------------------------------- +/// Do a search recursively to find the first visible object of all child branches +/// If the incoming object is visible, this is the only object returned +/// defineUiTreeOrdering is used to +//-------------------------------------------------------------------------------------------------- +void PdmUiTreeViewModel::findFirstVisibleUiItemInAllBranches(PdmUiItem* uiItem, std::vector& visibleItems, const QString& uiConfigName) +{ + if (!uiItem) return; + + if (!uiItem->isUiHidden(uiConfigName)) + { + visibleItems.push_back(uiItem); + } + else + { + // Check if ui tree ordering is defined in the data model + PdmUiObjectHandle* uiObjectHandle = dynamic_cast (uiItem); + if (uiObjectHandle) + { + PdmUiTreeOrdering treeOrderingDefinedByApplication("", ""); + uiObjectHandle->defineUiTreeOrdering(treeOrderingDefinedByApplication, uiConfigName); + if (treeOrderingDefinedByApplication.childCount() > 0) + { + for (int i = 0; i < treeOrderingDefinedByApplication.childCount(); i++) + { + // The referenced objects in uiOrdering might be set as hidden + // Do a recursive search from the referenced objects to find first visible ui item + findFirstVisibleUiItemInAllBranches(treeOrderingDefinedByApplication.child(i)->activeItem(), visibleItems, uiConfigName); + } + + return; + } + } + + if (uiItem->isUiChildrenHidden(uiConfigName)) + { + return; + } + + PdmUiFieldHandle* field = dynamic_cast (uiItem); + if (field) + { + std::vector children; + field->fieldHandle()->childObjects(&children); + + for (size_t i = 0; i < children.size(); i++) + { + findFirstVisibleUiItemInAllBranches(uiObj(children[i]), visibleItems, uiConfigName); + } + } + + if (uiObjectHandle) + { + std::vector fields; + uiObjectHandle->owner()->fields(fields); + + for (size_t i = 0; i < fields.size(); i++) + { + if (dynamic_cast(fields[i])) + { + // Always show a container object, even if the container is empty + findFirstVisibleUiItemInAllBranches(fields[i]->uiCapability(), visibleItems, uiConfigName); + } + else if (fields[i]->hasChildObjects()) + { + // Show a child object only if an object is present + findFirstVisibleUiItemInAllBranches(fields[i]->uiCapability(), visibleItems, uiConfigName); + } + } + } + } +} + } // end namespace caf diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewModel.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewModel.h index 5b144361ba..9e1e50731d 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewModel.h +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewModel.h @@ -83,6 +83,8 @@ private: void updateEditorsForSubTree(PdmUiTreeOrdering* root); static int findChildItemIndex(const PdmUiTreeOrdering * parent, const PdmUiItem* pdmItemToFindInChildren); + static void findFirstVisibleUiItemInAllBranches(PdmUiItem* uiItem, std::vector& visibleItems, const QString& uiConfigName); + PdmUiTreeOrdering* m_treeOrderingRoot; QStringList m_columnHeaders; QString m_uiConfigName;