From: vsv Date: Tue, 28 Nov 2017 10:59:20 +0000 (+0300) Subject: Implement folder operations for sub document X-Git-Tag: V_2.10.0RC~123^2~9 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=8259f38e8a93b8a65d5c4ec88a39c211c7ae9c4d;p=modules%2Fshaper.git Implement folder operations for sub document --- diff --git a/src/XGUI/XGUI_ContextMenuMgr.cpp b/src/XGUI/XGUI_ContextMenuMgr.cpp index cb60a464d..b25bb04eb 100644 --- a/src/XGUI/XGUI_ContextMenuMgr.cpp +++ b/src/XGUI/XGUI_ContextMenuMgr.cpp @@ -47,7 +47,8 @@ #include #include #include -#include "ModelAPI_Folder.h" +#include +#include #include @@ -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 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(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")); diff --git a/src/XGUI/XGUI_ContextMenuMgr.h b/src/XGUI/XGUI_ContextMenuMgr.h index 280792cdd..97a8584df 100644 --- a/src/XGUI/XGUI_ContextMenuMgr.h +++ b/src/XGUI/XGUI_ContextMenuMgr.h @@ -144,6 +144,7 @@ signals: QAction* mySeparator1; QAction* mySeparator2; + QAction* mySeparator3; }; #endif diff --git a/src/XGUI/XGUI_DataModel.cpp b/src/XGUI/XGUI_DataModel.cpp index df1eeb932..49d973ddd 100644 --- a/src/XGUI/XGUI_DataModel.cpp +++ b/src/XGUI/XGUI_DataModel.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -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_Entity*)theObj); + ModelAPI_Document* aDoc = 0; + try { + aDoc = dynamic_cast((ModelAPI_Entity*)theObj); + } catch(...) {} return aDoc; } @@ -284,7 +288,6 @@ void XGUI_DataModel::processEvent(const std::shared_ptr& theMess std::set aObjects = aUpdMsg->objects(); std::set::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& 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(theObject); if (aResult.get()) { @@ -620,6 +631,9 @@ int XGUI_DataModel::rowCount(const QModelIndex& theParent) const ModelAPI_ResultField* aFieldRes = dynamic_cast(aObj); if (aFieldRes) return aFieldRes->stepsSize(); + ModelAPI_Folder* aFolder = dynamic_cast(aObj); + if (aFolder) + return getNumberOfFolderItems(aFolder); } } } @@ -710,6 +724,11 @@ QModelIndex XGUI_DataModel::index(int theRow, int theColumn, const QModelIndex & dynamic_cast(aParentObj); if (aFieldRes) { aIndex = createIndex(theRow, theColumn, aFieldRes->step(theRow)); + } else { + ModelAPI_Folder* aFolder = dynamic_cast(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_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(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); +} diff --git a/src/XGUI/XGUI_DataModel.h b/src/XGUI/XGUI_DataModel.h index 53e910980..d20679f79 100644 --- a/src/XGUI/XGUI_DataModel.h +++ b/src/XGUI/XGUI_DataModel.h @@ -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) diff --git a/src/XGUI/XGUI_SelectionMgr.cpp b/src/XGUI/XGUI_SelectionMgr.cpp index eebb23d22..38cb1d325 100755 --- a/src/XGUI/XGUI_SelectionMgr.cpp +++ b/src/XGUI/XGUI_SelectionMgr.cpp @@ -220,3 +220,18 @@ void XGUI_SelectionMgr::convertToObjectBrowserSelection( } } } + +std::list XGUI_SelectionMgr::getSelectedFeatures() +{ + std::list aFeatures; + QObjectPtrList aObjects = selection()->selectedObjects(); + if (aObjects.isEmpty()) + return aFeatures; + + foreach(ObjectPtr aObj, aObjects) { + FeaturePtr aFeature = std::dynamic_pointer_cast(aObj); + if (aFeature.get()) + aFeatures.push_back(aFeature); + } + return aFeatures; +} \ No newline at end of file diff --git a/src/XGUI/XGUI_SelectionMgr.h b/src/XGUI/XGUI_SelectionMgr.h index 25bb95d85..b6829da0a 100644 --- a/src/XGUI/XGUI_SelectionMgr.h +++ b/src/XGUI/XGUI_SelectionMgr.h @@ -24,6 +24,7 @@ #include "XGUI.h" #include #include +#include #include #include @@ -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 getSelectedFeatures(); + signals: //! Emited when selection in a one of viewers was changed void selectionChanged(); diff --git a/src/XGUI/XGUI_Workshop.cpp b/src/XGUI/XGUI_Workshop.cpp index 7556e1042..ab4b9b109 100755 --- a/src/XGUI/XGUI_Workshop.cpp +++ b/src/XGUI/XGUI_Workshop.cpp @@ -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 aFeatures; - foreach(ObjectPtr aObj, aObjects) { - FeaturePtr aFeature = std::dynamic_pointer_cast(aObj); - if (aFeature.get()) - aFeatures.push_back(aFeature); - } + std::list 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 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 diff --git a/src/XGUI/XGUI_Workshop.h b/src/XGUI/XGUI_Workshop.h index b5d181f2e..8a96cfa80 100755 --- a/src/XGUI/XGUI_Workshop.h +++ b/src/XGUI/XGUI_Workshop.h @@ -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.