From f3b6abdd8d0a128e2fdb93273190ff24f9bf0609 Mon Sep 17 00:00:00 2001 From: vsv Date: Mon, 27 Jul 2015 18:49:44 +0300 Subject: [PATCH] Implementation of XML based ObjectBrowser --- src/Config/Config_DataModelReader.cpp | 13 +- src/Config/dataModel.xml | 4 +- src/XGUI/XGUI_DataModel.cpp | 211 +++++++++++++++++--------- src/XGUI/XGUI_DataModel.h | 4 + 4 files changed, 160 insertions(+), 72 deletions(-) diff --git a/src/Config/Config_DataModelReader.cpp b/src/Config/Config_DataModelReader.cpp index 9e55a78d8..e9113e85e 100644 --- a/src/Config/Config_DataModelReader.cpp +++ b/src/Config/Config_DataModelReader.cpp @@ -74,4 +74,15 @@ int Config_DataModelReader::rootFolderId(std::string theType) const return aId; } return -1; -} \ No newline at end of file +} + +int Config_DataModelReader::subFolderId(std::string theType) const +{ + std::vector::const_iterator aIt; + int aId; + for (aIt = mySubFolderTypes.cbegin(), aId = 0; aIt != mySubFolderTypes.cend(); ++aIt, ++aId) { + if ((*aIt) == theType) + return aId; + } + return -1; +} diff --git a/src/Config/dataModel.xml b/src/Config/dataModel.xml index b0b80b719..103879bf7 100644 --- a/src/Config/dataModel.xml +++ b/src/Config/dataModel.xml @@ -1,12 +1,12 @@ - + - + diff --git a/src/XGUI/XGUI_DataModel.cpp b/src/XGUI/XGUI_DataModel.cpp index 74257d5ff..35cadb93c 100644 --- a/src/XGUI/XGUI_DataModel.cpp +++ b/src/XGUI/XGUI_DataModel.cpp @@ -7,7 +7,6 @@ #include "XGUI_DataModel.h" #include -#include #include #include #include @@ -16,6 +15,7 @@ #include #include +#include #include @@ -33,6 +33,7 @@ ResultPartPtr getPartResult(ModelAPI_Object* theObj) return ResultPartPtr(); } +/// Returns pointer on document if the given object is document object ModelAPI_Document* getSubDocument(void* theObj) { ModelAPI_Document* aDoc = dynamic_cast((ModelAPI_Entity*)theObj); @@ -40,6 +41,8 @@ ModelAPI_Document* getSubDocument(void* theObj) } + + // Constructor ************************************************* XGUI_DataModel::XGUI_DataModel(QObject* theParent) : QAbstractItemModel(theParent) { @@ -56,7 +59,9 @@ void XGUI_DataModel::processEvent(const std::shared_ptr& theMess { DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument(); std::string aRootType = myXMLReader.rootType(); + std::string aSubType = myXMLReader.subType(); int aNbFolders = myXMLReader.rootFoldersNumber(); + int aNbSubFolders = myXMLReader.subFoldersNumber(); // Created object event ******************* if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_CREATED)) { @@ -72,16 +77,33 @@ void XGUI_DataModel::processEvent(const std::shared_ptr& theMess DocumentPtr aDoc = aObject->document(); if (aDoc == aRootDoc) { int aRow = aRootDoc->size(aObjType) - 1; - if (aRow != -1) { - if (aObjType == aRootType) { - insertRow(aRow + aNbFolders); + if (aObjType == aRootType) { + insertRow(aRow + aNbFolders); + } else { + int aFolderId = myXMLReader.rootFolderId(aObjType); + if (aFolderId != -1) { + insertRow(aRow, createIndex(aFolderId, 0, -1)); + } + } + } else { + // Object created in sub-document + QModelIndex aDocRoot = findDocumentRootIndex(aDoc.get()); + if (aDocRoot.isValid()) { + int aRow = aDoc->size(aObjType) - 1; + if (aObjType == aSubType) { + insertRow(aRow + aNbSubFolders, aDocRoot); } else { - int aFolderId = myXMLReader.rootFolderId(aObjType); + int aFolderId = myXMLReader.subFolderId(aObjType); if (aFolderId != -1) { - insertRow(aRow, createIndex(aFolderId, 0, -1)); + insertRow(aRow, createIndex(aFolderId, 0, aDoc.get())); } - } + } + } +#ifdef _DEBUG + else { + Events_Error::send("Problem with Data Model definition of sub-document"); } +#endif } } // Deleted object event *********************** @@ -127,6 +149,9 @@ ObjectPtr XGUI_DataModel::object(const QModelIndex& theIndex) const if (theIndex.internalId() < 0) // this is a folder return ObjectPtr(); ModelAPI_Object* aObj = (ModelAPI_Object*)theIndex.internalPointer(); + if (getSubDocument(aObj)) // the selected index is a folder of sub-document + return ObjectPtr(); + // We can not create the ObjectPtr directly because the pointer will be deleted // with deletion of the ObjectPtr because its counter become to 0. DocumentPtr aDoc = aObj->document(); @@ -241,8 +266,8 @@ int XGUI_DataModel::rowCount(const QModelIndex& theParent) const } int aId = theParent.internalId(); - if (aId < 0) { - // this is a folder + if (aId == -1) { + // this is a folder under root int aParentPos = theParent.row(); if (aId == -1) { // first level of folders std::string aType = myXMLReader.rootFolderType(aParentPos); @@ -250,18 +275,24 @@ int XGUI_DataModel::rowCount(const QModelIndex& theParent) const } } else { // It is an object which could have children - ModelAPI_Object* aObj = (ModelAPI_Object*)theParent.internalPointer(); - - // Check for Part feature - ResultPartPtr aPartRes = getPartResult(aObj); - if (aPartRes.get()) { - DocumentPtr aSubDoc = aPartRes->partDoc(); - int aNbSubFolders = myXMLReader.subFoldersNumber(); - int aNbSubItems = 0; - std::string aSubType = myXMLReader.subType(); - if (!aSubType.empty()) - aNbSubItems = aSubDoc->size(aSubType); - return aNbSubItems + aNbSubFolders; + ModelAPI_Document* aDoc = getSubDocument(theParent.internalPointer()); + if (aDoc) { + // a folder of sub-document + std::string aType = myXMLReader.subFolderType(theParent.row()); + return aDoc->size(aType); + } else { + // Check for Part feature + ModelAPI_Object* aObj = (ModelAPI_Object*)theParent.internalPointer(); + ResultPartPtr aPartRes = getPartResult(aObj); + if (aPartRes.get()) { + DocumentPtr aSubDoc = aPartRes->partDoc(); + int aNbSubFolders = myXMLReader.subFoldersNumber(); + int aNbSubItems = 0; + std::string aSubType = myXMLReader.subType(); + if (!aSubType.empty()) + aNbSubItems = aSubDoc->size(aSubType); + return aNbSubItems + aNbSubFolders; + } } } return 0; @@ -297,8 +328,8 @@ QModelIndex XGUI_DataModel::index(int theRow, int theColumn, const QModelIndex & } } int aId = theParent.internalId(); + int aParentPos = theParent.row(); if (aId == -1) { // return object index inside of first level of folders - int aParentPos = theParent.row(); std::string aType = myXMLReader.rootFolderType(aParentPos); if (theRow < aRootDoc->size(aType)) { ObjectPtr aObj = aRootDoc->object(aType, theRow); @@ -309,15 +340,36 @@ QModelIndex XGUI_DataModel::index(int theRow, int theColumn, const QModelIndex & } } else { // It is an object which could have children - ModelAPI_Object* aParentObj = (ModelAPI_Object*)theParent.internalPointer(); - - // Check for Part feature - ResultPartPtr aPartRes = getPartResult(aParentObj); - if (aPartRes.get()) { - DocumentPtr aSubDoc = aPartRes->partDoc(); - int aNbSubFolders = myXMLReader.subFoldersNumber(); - if (theRow < aNbSubFolders) { // Create a Folder of sub-document - return createIndex(theRow, theColumn, aSubDoc.get()); + ModelAPI_Document* aDoc = getSubDocument(theParent.internalPointer()); + if (aDoc) { + // It is a folder of sub-document + std::string aType = myXMLReader.subFolderType(aParentPos); + if (theRow < aDoc->size(aType)) { + ObjectPtr aObj = aDoc->object(aType, theRow); + QModelIndex aIndex = objectIndex(aObj); + if (theColumn != 0) + return createIndex(aIndex.row(), theColumn, aIndex.internalPointer()); + return aIndex; + } + } else { + ModelAPI_Object* aParentObj = (ModelAPI_Object*)theParent.internalPointer(); + + // Check for Part feature + ResultPartPtr aPartRes = getPartResult(aParentObj); + if (aPartRes.get()) { + DocumentPtr aSubDoc = aPartRes->partDoc(); + int aNbSubFolders = myXMLReader.subFoldersNumber(); + if (theRow < aNbSubFolders) { // Create a Folder of sub-document + return createIndex(theRow, theColumn, aSubDoc.get()); + } else { + // this is an object under sub document root + std::string aType = myXMLReader.subType(); + ObjectPtr aObj = aSubDoc->object(aType, theRow - aNbSubFolders); + QModelIndex aIndex = objectIndex(aObj); + if (theColumn != 0) + return createIndex(aIndex.row(), theColumn, aIndex.internalPointer()); + return aIndex; + } } } } @@ -332,47 +384,31 @@ QModelIndex XGUI_DataModel::parent(const QModelIndex& theIndex) const ModelAPI_Document* aDoc = getSubDocument(theIndex.internalPointer()); if (aDoc) { // It is a folder of sub-document - SessionPtr aSession = ModelAPI_Session::get(); - DocumentPtr aRootDoc = aSession->moduleDocument(); - if (myXMLReader.isAttachToResult()) { // If document is attached to result - int aNb = aRootDoc->size(ModelAPI_ResultPart::group()); - ObjectPtr aObj; - ResultPartPtr aPartRes; - for (int i = 0; i < aNb; i++) { - aObj = aRootDoc->object(ModelAPI_ResultPart::group(), i); - aPartRes = std::dynamic_pointer_cast(aObj); - if (aPartRes.get() && (aPartRes->partDoc().get() == aDoc)) { - int aRow = i; - if (myXMLReader.rootType() == ModelAPI_Feature::group()) - aRow += myXMLReader.rootFoldersNumber(); - return createIndex(aRow, 0, aObj.get()); - } - } - } else { // If document is attached to feature - int aNb = aRootDoc->size(ModelAPI_Feature::group()); - ObjectPtr aObj; - ResultPartPtr aPartRes; - for (int i = 0; i < aNb; i++) { - aObj = aRootDoc->object(ModelAPI_Feature::group(), i); - aPartRes = getPartResult(aObj.get()); - if (aPartRes.get() && (aPartRes->partDoc().get() == aDoc)) { - int aRow = i; - if (myXMLReader.rootType() == ModelAPI_Feature::group()) - aRow += myXMLReader.rootFoldersNumber(); - return createIndex(aRow, 0, aObj.get()); - } - } - } + return findDocumentRootIndex(aDoc); } ModelAPI_Object* aObj = (ModelAPI_Object*) theIndex.internalPointer(); std::string aType = aObj->groupName(); - if (aType == myXMLReader.rootType()) - return QModelIndex(); - else { - // return first level of folder index - int aFolderId = myXMLReader.rootFolderId(aType); - // Items in a one row must have the same parent - return createIndex(aFolderId, 0, -1); + SessionPtr aSession = ModelAPI_Session::get(); + DocumentPtr aRootDoc = aSession->moduleDocument(); + DocumentPtr aSubDoc = aObj->document(); + if (aSubDoc == aRootDoc) { + if (aType == myXMLReader.rootType()) + return QModelIndex(); + else { + // return first level of folder index + int aFolderId = myXMLReader.rootFolderId(aType); + // Items in a one row must have the same parent + return createIndex(aFolderId, 0, -1); + } + } else { + if (aType == myXMLReader.subType()) + return findDocumentRootIndex(aSubDoc.get()); + else { + // return first level of folder index + int aFolderId = myXMLReader.subFolderId(aType); + // Items in a one row must have the same parent + return createIndex(aFolderId, 0, aSubDoc.get()); + } } } return QModelIndex(); @@ -436,3 +472,40 @@ Qt::ItemFlags XGUI_DataModel::flags(const QModelIndex& theIndex) const } return aFlags; } + +//****************************************************** +QModelIndex XGUI_DataModel::findDocumentRootIndex(ModelAPI_Document* theDoc) const +{ + SessionPtr aSession = ModelAPI_Session::get(); + DocumentPtr aRootDoc = aSession->moduleDocument(); + if (myXMLReader.isAttachToResult()) { // If document is attached to result + int aNb = aRootDoc->size(ModelAPI_ResultPart::group()); + ObjectPtr aObj; + ResultPartPtr aPartRes; + for (int i = 0; i < aNb; i++) { + aObj = aRootDoc->object(ModelAPI_ResultPart::group(), i); + aPartRes = std::dynamic_pointer_cast(aObj); + if (aPartRes.get() && (aPartRes->partDoc().get() == theDoc)) { + int aRow = i; + if (myXMLReader.rootType() == ModelAPI_Feature::group()) + aRow += myXMLReader.rootFoldersNumber(); + return createIndex(aRow, 0, aObj.get()); + } + } + } else { // If document is attached to feature + int aNb = aRootDoc->size(ModelAPI_Feature::group()); + ObjectPtr aObj; + ResultPartPtr aPartRes; + for (int i = 0; i < aNb; i++) { + aObj = aRootDoc->object(ModelAPI_Feature::group(), i); + aPartRes = getPartResult(aObj.get()); + if (aPartRes.get() && (aPartRes->partDoc().get() == theDoc)) { + int aRow = i; + if (myXMLReader.rootType() == ModelAPI_Feature::group()) + aRow += myXMLReader.rootFoldersNumber(); + return createIndex(aRow, 0, aObj.get()); + } + } + } + return QModelIndex(); +} diff --git a/src/XGUI/XGUI_DataModel.h b/src/XGUI/XGUI_DataModel.h index 88a0934b8..4f3dbd50e 100644 --- a/src/XGUI/XGUI_DataModel.h +++ b/src/XGUI/XGUI_DataModel.h @@ -10,6 +10,7 @@ #include "XGUI.h" #include +#include #include #include #include @@ -107,6 +108,9 @@ public: private: + QModelIndex findDocumentRootIndex(ModelAPI_Document* theDoc) const; + + Config_DataModelReader myXMLReader; }; -- 2.39.2