Salome HOME
Implement folder operations for sub document
authorvsv <vsv@opencascade.com>
Tue, 28 Nov 2017 10:59:20 +0000 (13:59 +0300)
committervsv <vsv@opencascade.com>
Tue, 28 Nov 2017 10:59:20 +0000 (13:59 +0300)
src/XGUI/XGUI_ContextMenuMgr.cpp
src/XGUI/XGUI_ContextMenuMgr.h
src/XGUI/XGUI_DataModel.cpp
src/XGUI/XGUI_DataModel.h
src/XGUI/XGUI_SelectionMgr.cpp
src/XGUI/XGUI_SelectionMgr.h
src/XGUI/XGUI_Workshop.cpp
src/XGUI/XGUI_Workshop.h

index cb60a464da929248870b8800ebaab162a7246196..b25bb04eb92d022a9177d7aacb61f2e29f0988e7 100644 (file)
@@ -47,7 +47,8 @@
 #include <ModelAPI_ResultBody.h>
 #include <ModelAPI_Tools.h>
 #include <ModelAPI_ResultField.h>
-#include "ModelAPI_Folder.h"
+#include <ModelAPI_Folder.h>
+#include <ModelAPI_AttributeReference.h>
 
 #include <Config_DataModelReader.h>
 
@@ -67,7 +68,7 @@
 XGUI_ContextMenuMgr::XGUI_ContextMenuMgr(XGUI_Workshop* theParent)
     : QObject(theParent),
       myWorkshop(theParent),
-      mySeparator1(0), mySeparator2(0)
+      mySeparator1(0), mySeparator2(0), mySeparator3(0)
 {
 }
 
@@ -142,6 +143,9 @@ void XGUI_ContextMenuMgr::createActions()
   mySeparator2 = ModuleBase_Tools::createAction(QIcon(), "", aDesktop);
   mySeparator2->setSeparator(true);
 
+  mySeparator3 = ModuleBase_Tools::createAction(QIcon(), "", aDesktop);
+  mySeparator3->setSeparator(true);
+
   //mySelectActions = new QActionGroup(this);
   //mySelectActions->setExclusive(true);
 
@@ -197,6 +201,14 @@ void XGUI_ContextMenuMgr::createActions()
                                            tr("Move into the next folder"), aDesktop);
   addAction("ADD_TO_FOLDER_AFTER_CMD", aAction);
 
+  aAction = ModuleBase_Tools::createAction(QIcon(),
+                                           tr("Move out before the folder"), aDesktop);
+  addAction("ADD_OUT_FOLDER_BEFORE_CMD", aAction);
+
+  aAction = ModuleBase_Tools::createAction(QIcon(),
+                                           tr("Move out after the folder"), aDesktop);
+  addAction("ADD_OUT_FOLDER_AFTER_CMD", aAction);
+
   buildObjBrowserMenu();
   buildViewerMenu();
 }
@@ -345,31 +357,79 @@ void XGUI_ContextMenuMgr::updateObjectBrowserMenu()
       QModelIndex aLastIdx = aIndexes.last();
       QModelIndex aParentIdx = aFirstIdx.parent();
 
-      if (aParentIdx == aLastIdx.parent()) {
-        // if all selected are from the same level
+      // if all selected are from the same level
+      bool isSameParent = true;
+      foreach(QModelIndex aIdx, aIndexes) {
+        if (aIdx.parent() != aParentIdx) {
+          isSameParent = false;
+          break;
+        }
+      }
+      if (isSameParent) {
+        // Check is selection continuous
         XGUI_DataModel* aModel = myWorkshop->objectBrowser()->dataModel();
-        ObjectPtr aDataObj = aModel->object(aParentIdx);
-
-        ObjectPtr aPrevObj;
-        if (aFirstIdx.row() > 0) {
-          QModelIndex aPrevIdx = aFirstIdx.sibling(aFirstIdx.row() - 1, 0);
-          aPrevObj = aModel->object(aPrevIdx);
+        DocumentPtr aDoc = aMgr->activeDocument();
+        std::list<FeaturePtr> aFeatures = aSelMgr->getSelectedFeatures();
+
+        bool isContinuos = true;
+        if (aSelected > 1) {
+          int aId = -1;
+          foreach(FeaturePtr aF, aFeatures) {
+            if (aId == -1)
+              aId = aDoc->index(aF);
+            else {
+              aId++;
+              if (aId != aDoc->index(aF)) {
+                isContinuos = false;
+                break;
+              }
+            }
+          }
         }
+        if (isContinuos) {
+          ObjectPtr aDataObj = aModel->object(aParentIdx);
 
-        ObjectPtr aNextObj;
-        if (aLastIdx.row() < (aModel->rowCount(aParentIdx) - 1)) {
-          QModelIndex aNextIdx = aFirstIdx.sibling(aLastIdx.row() + 1, 0);
-          aNextObj = aModel->object(aNextIdx);
-        }
+          ObjectPtr aPrevObj;
+          if (aFirstIdx.row() > 0) {
+            QModelIndex aPrevIdx = aFirstIdx.sibling(aFirstIdx.row() - 1, 0);
+            aPrevObj = aModel->object(aPrevIdx);
+          }
 
-        bool isPrevFolder = (aPrevObj.get() && (aPrevObj->groupName() == ModelAPI_Folder::group()));
-        bool isNextFolder = (aNextObj.get() && (aNextObj->groupName() == ModelAPI_Folder::group()));
-        bool isInFolder = (aDataObj.get() && (aDataObj->groupName() == ModelAPI_Folder::group()));
-        bool isOutsideFolder = hasFeature && (!isInFolder);
+          ObjectPtr aNextObj;
+          if (aLastIdx.row() < (aModel->rowCount(aParentIdx) - 1)) {
+            QModelIndex aNextIdx = aFirstIdx.sibling(aLastIdx.row() + 1, 0);
+            aNextObj = aModel->object(aNextIdx);
+          }
 
-        action("INSERT_FOLDER_CMD")->setEnabled(isOutsideFolder);
-        action("ADD_TO_FOLDER_BEFORE_CMD")->setEnabled(isOutsideFolder && isPrevFolder);
-        action("ADD_TO_FOLDER_AFTER_CMD")->setEnabled(isOutsideFolder && isNextFolder);
+          bool isPrevFolder = (aPrevObj.get() && (aPrevObj->groupName() == ModelAPI_Folder::group()));
+          bool isNextFolder = (aNextObj.get() && (aNextObj->groupName() == ModelAPI_Folder::group()));
+          bool isInFolder = (aDataObj.get() && (aDataObj->groupName() == ModelAPI_Folder::group()));
+          bool isOutsideFolder = !isInFolder;
+
+          bool hasFirst = false;
+          bool hasLast = false;
+          if (isInFolder) {
+            FolderPtr aFolder = std::dynamic_pointer_cast<ModelAPI_Folder>(aDataObj);
+            FeaturePtr aFirstFeatureInFolder;
+            AttributeReferencePtr aFirstFeatAttr =
+                aFolder->data()->reference(ModelAPI_Folder::FIRST_FEATURE_ID());
+            if (aFirstFeatAttr)
+              aFirstFeatureInFolder = ModelAPI_Feature::feature(aFirstFeatAttr->value());
+            hasFirst = (aFirstFeatureInFolder == aFeatures.front());
+
+            FeaturePtr aLastFeatureInFolder;
+            AttributeReferencePtr aLastFeatAttr =
+                aFolder->data()->reference(ModelAPI_Folder::LAST_FEATURE_ID());
+            if (aLastFeatAttr)
+              aLastFeatureInFolder = ModelAPI_Feature::feature(aLastFeatAttr->value());
+            hasLast = (aLastFeatureInFolder == aFeatures.back());
+          }
+          action("INSERT_FOLDER_CMD")->setEnabled(isOutsideFolder);
+          action("ADD_TO_FOLDER_BEFORE_CMD")->setEnabled(isOutsideFolder && isPrevFolder);
+          action("ADD_TO_FOLDER_AFTER_CMD")->setEnabled(isOutsideFolder && isNextFolder);
+          action("ADD_OUT_FOLDER_BEFORE_CMD")->setEnabled(isInFolder && hasFirst);
+          action("ADD_OUT_FOLDER_AFTER_CMD")->setEnabled(isInFolder && hasLast);
+        }
       }
     } // end folder management commands
 
@@ -593,6 +653,9 @@ void XGUI_ContextMenuMgr::buildObjBrowserMenu()
   aList.append(action("ADD_TO_FOLDER_BEFORE_CMD"));
   aList.append(action("ADD_TO_FOLDER_AFTER_CMD"));
   aList.append(mySeparator2);
+  aList.append(action("ADD_OUT_FOLDER_BEFORE_CMD"));
+  aList.append(action("ADD_OUT_FOLDER_AFTER_CMD"));
+  aList.append(mySeparator3);
   aList.append(action("CLEAN_HISTORY_CMD"));
   aList.append(action("DELETE_CMD"));
   myObjBrowserMenus[ModelAPI_Feature::group()] = aList;
@@ -673,6 +736,11 @@ void XGUI_ContextMenuMgr::addObjBrowserMenu(QMenu* theMenu) const
       aActions.append(action("HIDE_CMD"));
       aActions.append(action("SHOW_ONLY_CMD"));
       aActions.append(mySeparator2);
+      aActions.append(action("ADD_TO_FOLDER_BEFORE_CMD"));
+      aActions.append(action("ADD_TO_FOLDER_AFTER_CMD"));
+      aActions.append(action("ADD_OUT_FOLDER_BEFORE_CMD"));
+      aActions.append(action("ADD_OUT_FOLDER_AFTER_CMD"));
+      aActions.append(mySeparator3);
       //aActions.append(action("MOVE_CMD"));
       aActions.append(action("COLOR_CMD"));
       aActions.append(action("DEFLECTION_CMD"));
index 280792cdd720214b5fa7d510fa766118906b003d..97a8584dfe0b8e4e03f6f2048cb313eb5906e714 100644 (file)
@@ -144,6 +144,7 @@ signals:
 
   QAction* mySeparator1;
   QAction* mySeparator2;
+  QAction* mySeparator3;
 };
 
 #endif
index df1eeb932abd91568afe64fe4d0c08feebd17f2c..49d973ddd0cabdd8a733008a4961a012cccb15e7 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;
 }
 
@@ -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()) {
@@ -1123,3 +1147,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);
+}
index 53e9109801667ffbe392733c4636fb5dbbcd619d..d20679f7983742f681b4309247321b1331292581 100644 (file)
@@ -182,6 +182,9 @@ private:
   /// \param fromRoot - root document flag
   QStringList listOfShowNotEmptyFolders(bool fromRoot = true) const;
 
+  int getNumberOfFolderItems(const ModelAPI_Folder* theFolder) const;
+  ObjectPtr getObjectInFolder(const ModelAPI_Folder* theFolder, int theId) const;
+
   VisibilityState getVisibilityState(const QModelIndex& theIndex) const;
 
   void addShownFolder(DocumentPtr theDoc, QString theFolder)
index eebb23d221e1983816e69be758bfcede126ac176..38cb1d325055cb3af5b4f1dd50d9b7b3c2fe939c 100755 (executable)
@@ -220,3 +220,18 @@ void XGUI_SelectionMgr::convertToObjectBrowserSelection(
     }
   }
 }
+
+std::list<FeaturePtr> XGUI_SelectionMgr::getSelectedFeatures()
+{
+  std::list<FeaturePtr> aFeatures;
+  QObjectPtrList aObjects = selection()->selectedObjects();
+  if (aObjects.isEmpty())
+    return aFeatures;
+
+  foreach(ObjectPtr aObj, aObjects) {
+    FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aObj);
+    if (aFeature.get())
+      aFeatures.push_back(aFeature);
+  }
+  return aFeatures;
+}
\ No newline at end of file
index 25bb95d85b774d0452595435a47041cdc1f8bf53..b6829da0a39143547be5df8e9b4ee7fa62d49ca7 100644 (file)
@@ -24,6 +24,7 @@
 #include "XGUI.h"
 #include <ModuleBase_Definitions.h>
 #include <ModuleBase_ISelection.h>
+#include <ModelAPI_Feature.h>
 #include <QObject>
 #include <QModelIndexList>
 
@@ -77,6 +78,9 @@ Q_OBJECT
   /// \param thePlace a widget where selection has happened.
   void updateSelectionBy(const ModuleBase_ISelection::SelectionPlace& thePlace);
 
+  /// Returns list of selected features (ignores other selected objects)
+  std::list<FeaturePtr> getSelectedFeatures();
+
 signals:
   //! Emited when selection in a one of viewers was changed
   void selectionChanged();
index 7556e1042546333ae6e20912225efabe22d1607e..ab4b9b109dfed0dcc9d5bf806e06c0ceb2ffa002 100755 (executable)
@@ -1419,6 +1419,10 @@ void XGUI_Workshop::onContextMenuCommand(const QString& theId, bool isChecked)
     insertToFolder(true);
   } else if (theId == "ADD_TO_FOLDER_AFTER_CMD") {
     insertToFolder(false);
+  } else if (theId == "ADD_OUT_FOLDER_BEFORE_CMD") {
+    moveOutFolder(true);
+  } else if (theId == "ADD_OUT_FOLDER_AFTER_CMD") {
+    moveOutFolder(false);
   } else if (theId == "SELECT_RESULT_CMD") {
     //setViewerSelectionMode(-1);
     //IMP: an attempt to use result selection with other selection modes
@@ -2451,16 +2455,7 @@ void XGUI_Workshop::insertFeatureFolder()
 
 void XGUI_Workshop::insertToFolder(bool isBefore)
 {
-  QObjectPtrList aObjects = mySelector->selection()->selectedObjects();
-  if (aObjects.isEmpty())
-    return;
-
-  std::list<FeaturePtr> aFeatures;
-  foreach(ObjectPtr aObj, aObjects) {
-    FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aObj);
-    if (aFeature.get())
-      aFeatures.push_back(aFeature);
-  }
+  std::list<FeaturePtr> aFeatures = mySelector->getSelectedFeatures();
   if (aFeatures.empty())
     return;
 
@@ -2476,3 +2471,17 @@ void XGUI_Workshop::insertToFolder(bool isBefore)
   aDoc->moveToFolder(aFeatures, aFolder);
   aMgr->finishOperation();
 }
+
+void XGUI_Workshop::moveOutFolder(bool isBefore)
+{
+  std::list<FeaturePtr> aFeatures = mySelector->getSelectedFeatures();
+  if (aFeatures.empty())
+    return;
+
+  SessionPtr aMgr = ModelAPI_Session::get();
+  DocumentPtr aDoc = aMgr->activeDocument();
+
+  aMgr->startOperation();
+  aDoc->removeFromFolder(aFeatures, isBefore);
+  aMgr->finishOperation();
+}
\ No newline at end of file
index b5d181f2e68ee413f6e86eb40064b1effca4fdbe..8a96cfa803fd838891e70dad003e90cf6974a787 100755 (executable)
@@ -454,6 +454,9 @@ private:
   /// Insert an object to a folder above or below
   void insertToFolder(bool isBefore);
 
+  /// Insert an object to a folder above or below
+  void moveOutFolder(bool isBefore);
+
  private slots:
   /// SLOT, that is called after the operation is started. Update workshop state according to
   /// the started operation, e.g. visualizes the property panel and connect to it.