Salome HOME
Issue #2344: Fix cleared selection on Cancel of Undo/Redo command
[modules/shaper.git] / src / XGUI / XGUI_DataModel.cpp
index 9a78e665b3ab089003d4f42118ee2e0cfaced54e..d428a2c501986816457ec569efff57f10207b880 100644 (file)
@@ -36,6 +36,7 @@
 #include <ModelAPI_ResultField.h>
 #include <ModelAPI_Tools.h>
 #include <ModelAPI_Folder.h>
+#include <ModelAPI_AttributeReference.h>
 
 #include <Config_FeatureMessage.h>
 #include <Config_DataModelReader.h>
@@ -74,7 +75,10 @@ ResultPartPtr getPartResult(ModelAPI_Object* theObj)
 /// Returns pointer on document if the given object is document object
 ModelAPI_Document* getSubDocument(void* theObj)
 {
-  ModelAPI_Document* aDoc = dynamic_cast<ModelAPI_Document*>((ModelAPI_Entity*)theObj);
+  ModelAPI_Document* aDoc = 0;
+  try {
+    aDoc = dynamic_cast<ModelAPI_Document*>((ModelAPI_Entity*)theObj);
+  } catch(...) {}
   return aDoc;
 }
 
@@ -216,8 +220,8 @@ void XGUI_DataModel::processEvent(const std::shared_ptr<Events_Message>& theMess
     for (aIt = aGroups.begin(); aIt != aGroups.end(); ++aIt) {
       std::string aGroup = (*aIt);
       if (aDoc == aRootDoc) {  // If root objects
-        int aRow = aRootDoc->size(aGroup);
-        if (aGroup == aRootType) {
+        int aRow = aRootDoc->size(aGroup, true);
+        if ((aGroup == aRootType) || (aGroup == ModelAPI_Folder::group())) {
           // Process root folder
           removeRow(aRow + aNbFolders);
           rebuildBranch(aNbFolders, aRow);
@@ -233,7 +237,7 @@ void XGUI_DataModel::processEvent(const std::shared_ptr<Events_Message>& theMess
         // Check that some folders could erased
         QStringList aNotEmptyFolders = listOfShowNotEmptyFolders();
         foreach (QString aNotEmptyFolder, aNotEmptyFolders) {
-          if ((aNotEmptyFolder.toStdString() == aGroup) && (aRootDoc->size(aGroup) == 0)) {
+          if ((aNotEmptyFolder.toStdString() == aGroup) && (aRootDoc->size(aGroup, true) == 0)) {
             // Appears first object in folder which can not be shown empty
             removeRow(myXMLReader->rootFolderId(aGroup));
             removeShownFolder(aRootDoc, aNotEmptyFolder);
@@ -245,9 +249,9 @@ void XGUI_DataModel::processEvent(const std::shared_ptr<Events_Message>& theMess
         // Remove row for sub-document
         QModelIndex aDocRoot = findDocumentRootIndex(aDoc.get(), 0);
         if (aDocRoot.isValid()) {
-          int aRow = aDoc->size(aGroup);
+          int aRow = aDoc->size(aGroup, true);
           int aNbSubFolders = foldersCount(aDoc.get());
-          if (aGroup == aSubType) {
+          if ((aGroup == aSubType) || (aGroup == ModelAPI_Folder::group())) {
             // List of objects under document root
             removeRow(aRow + aNbSubFolders, aDocRoot);
             rebuildBranch(aNbSubFolders, aRow, aDocRoot);
@@ -262,7 +266,7 @@ void XGUI_DataModel::processEvent(const std::shared_ptr<Events_Message>& theMess
           }
           // Check that some folders could disappear
           QStringList aNotEmptyFolders = listOfShowNotEmptyFolders(false);
-          int aSize = aDoc->size(aGroup);
+          int aSize = aDoc->size(aGroup, true);
           foreach (QString aNotEmptyFolder, aNotEmptyFolders) {
             if ((aNotEmptyFolder.toStdString() == aGroup) && (aSize == 0)) {
               // Appears first object in folder which can not be shown empty
@@ -284,7 +288,6 @@ void XGUI_DataModel::processEvent(const std::shared_ptr<Events_Message>& theMess
     std::set<ObjectPtr> aObjects = aUpdMsg->objects();
 
     std::set<ObjectPtr>::const_iterator aIt;
-    std::string aObjType;
     for (aIt = aObjects.begin(); aIt != aObjects.end(); ++aIt) {
       ObjectPtr aObject = (*aIt);
       if (aObject->data()->isValid()) {
@@ -296,9 +299,13 @@ void XGUI_DataModel::processEvent(const std::shared_ptr<Events_Message>& theMess
             QModelIndex aIndex = objectIndex(aResult, 0);
             removeRows(0, aResult->stepsSize(), aIndex);
         } else {
-          QModelIndex aIndex = objectIndex(aObject, 0);
-          if (aIndex.isValid()) {
-            emit dataChanged(aIndex, aIndex);
+          if (aObject->groupName() == ModelAPI_Folder::group()) {
+            rebuildDataTree();
+          } else {
+            QModelIndex aIndex = objectIndex(aObject, 0);
+            if (aIndex.isValid()) {
+              emit dataChanged(aIndex, aIndex);
+            }
           }
         }
       } else {
@@ -398,6 +405,10 @@ QModelIndex XGUI_DataModel::objectIndex(const ObjectPtr theObject, int theColumn
           }
         }
       }
+      int aFRow = -1;
+      FolderPtr aFolder = aDoc->findContainingFolder(aFeature, aFRow);
+      if (aFolder.get())
+        aRow = aFRow;
     } else {
       ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
       if (aResult.get()) {
@@ -620,6 +631,9 @@ int XGUI_DataModel::rowCount(const QModelIndex& theParent) const
         ModelAPI_ResultField* aFieldRes = dynamic_cast<ModelAPI_ResultField*>(aObj);
         if (aFieldRes)
           return aFieldRes->stepsSize();
+        ModelAPI_Folder* aFolder = dynamic_cast<ModelAPI_Folder*>(aObj);
+        if (aFolder)
+          return getNumberOfFolderItems(aFolder);
       }
     }
   }
@@ -710,6 +724,11 @@ QModelIndex XGUI_DataModel::index(int theRow, int theColumn, const QModelIndex &
                 dynamic_cast<ModelAPI_ResultField*>(aParentObj);
               if (aFieldRes) {
                 aIndex = createIndex(theRow, theColumn, aFieldRes->step(theRow));
+              } else {
+                ModelAPI_Folder* aFolder = dynamic_cast<ModelAPI_Folder*>(aParentObj);
+                ObjectPtr aObj = getObjectInFolder(aFolder, theRow);
+                if (aObj.get())
+                  aIndex = objectIndex(aObj, theColumn);
               }
             }
           }
@@ -740,7 +759,7 @@ QModelIndex XGUI_DataModel::parent(const QModelIndex& theIndex) const
     }
     ObjectPtr aObj = object(theIndex);
     if (!aObj.get()) {
-      // It can b e a step of a field
+      // It can be a step of a field
       ModelAPI_ResultField::ModelAPI_FieldStep* aStep =
         dynamic_cast<ModelAPI_ResultField::ModelAPI_FieldStep*>
         ((ModelAPI_Entity*)theIndex.internalPointer());
@@ -766,6 +785,11 @@ QModelIndex XGUI_DataModel::parent(const QModelIndex& theIndex) const
       if (aCompFea.get()) {
         return objectIndex(aCompFea);
       }
+      DocumentPtr aDoc = aFeature->document();
+      int aRow;
+      FolderPtr aFolder = aDoc->findContainingFolder(aFeature, aRow);
+      if (aFolder.get())
+        return objectIndex(aFolder);
     }
     ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(aObj);
     if (aResult.get()) {
@@ -918,7 +942,7 @@ QModelIndex
       }
     }
   } else { // If document is attached to feature
-    int aNb = aRootDoc->size(ModelAPI_Feature::group());
+    int aNb = aRootDoc->size(ModelAPI_Feature::group(), true);
     ObjectPtr aObj;
     ResultPartPtr aPartRes;
     for (int i = 0; i < aNb; i++) {
@@ -1095,6 +1119,8 @@ XGUI_DataModel::VisibilityState
 
   ObjectPtr aObj = object(theIndex);
   if (aObj.get()) {
+    if (aObj->groupName() == ModelAPI_ResultParameter::group())
+      return NoneState;
     ResultPtr aResObj = std::dynamic_pointer_cast<ModelAPI_Result>(aObj);
     if (aResObj.get()) {
       XGUI_Displayer* aDisplayer = myWorkshop->displayer();
@@ -1123,3 +1149,45 @@ XGUI_DataModel::VisibilityState
   }
   return NoneState;
 }
+
+
+int XGUI_DataModel::getNumberOfFolderItems(const ModelAPI_Folder* theFolder) const
+{
+  DocumentPtr aDoc = theFolder->document();
+
+  FeaturePtr aFirstFeatureInFolder;
+  AttributeReferencePtr aFirstFeatAttr =
+      theFolder->data()->reference(ModelAPI_Folder::FIRST_FEATURE_ID());
+  if (aFirstFeatAttr)
+    aFirstFeatureInFolder = ModelAPI_Feature::feature(aFirstFeatAttr->value());
+  if (!aFirstFeatureInFolder.get())
+    return 0;
+
+  FeaturePtr aLastFeatureInFolder;
+  AttributeReferencePtr aLastFeatAttr =
+      theFolder->data()->reference(ModelAPI_Folder::LAST_FEATURE_ID());
+  if (aLastFeatAttr)
+    aLastFeatureInFolder = ModelAPI_Feature::feature(aLastFeatAttr->value());
+  if (!aLastFeatureInFolder.get())
+    return 0;
+
+  int aFirst = aDoc->index(aFirstFeatureInFolder);
+  int aLast = aDoc->index(aLastFeatureInFolder);
+  return aLast - aFirst + 1;
+}
+
+ObjectPtr XGUI_DataModel::getObjectInFolder(const ModelAPI_Folder* theFolder, int theId) const
+{
+  DocumentPtr aDoc = theFolder->document();
+
+  FeaturePtr aFirstFeatureInFolder;
+  AttributeReferencePtr aFirstFeatAttr =
+      theFolder->data()->reference(ModelAPI_Folder::FIRST_FEATURE_ID());
+  if (aFirstFeatAttr)
+    aFirstFeatureInFolder = ModelAPI_Feature::feature(aFirstFeatAttr->value());
+  if (!aFirstFeatureInFolder.get())
+    return ObjectPtr();
+
+  int aFirst = aDoc->index(aFirstFeatureInFolder);
+  return aDoc->object(ModelAPI_Feature::group(), aFirst + theId);
+}