]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Issue #355 Delete: elements of sketch and constraints
authornds <natalia.donis@opencascade.com>
Mon, 19 Jan 2015 04:56:07 +0000 (07:56 +0300)
committersbh <sergey.belash@opencascade.com>
Fri, 30 Jan 2015 08:26:43 +0000 (11:26 +0300)
src/Model/Model_Document.cpp
src/ModuleBase/ModuleBase_IModule.h
src/PartSet/PartSet_Module.cpp
src/PartSet/PartSet_Module.h
src/XGUI/XGUI_ContextMenuMgr.cpp
src/XGUI/XGUI_ContextMenuMgr.h
src/XGUI/XGUI_Workshop.cpp
src/XGUI/XGUI_Workshop.h

index 67339fdf3bf8361575550d1e8768f54ad2c18657..d9905674765c0b51a5160b603ac36c6f21124c49 100644 (file)
@@ -579,17 +579,35 @@ void Model_Document::refsToFeature(FeaturePtr theFeature,
                                    const bool isSendError)
 {
   // check the feature: it must have no depended objects on it
+  // the dependencies can be in the feature results
   std::list<ResultPtr>::const_iterator aResIter = theFeature->results().cbegin();
   for(; aResIter != theFeature->results().cend(); aResIter++) {
     ResultPtr aResult = (*aResIter);
     std::shared_ptr<Model_Data> aData = 
       std::dynamic_pointer_cast<Model_Data>(aResult->data());
-    if (aData && !aData->refsToMe().empty()) {
-      FeaturePtr aFeature = ModelAPI_Feature::feature(aResult);
-      if (aFeature.get() != NULL)
-        theRefs.insert(aFeature);
+    if (aData.get() != NULL) {
+      const std::set<AttributePtr>& aRefs = aData->refsToMe();
+      std::set<AttributePtr>::const_iterator aRefIt = aRefs.begin(), aRefLast = aRefs.end();
+      for(; aRefIt != aRefLast; aRefIt++) {
+        FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>((*aRefIt)->owner());
+        if (aFeature.get() != NULL)
+          theRefs.insert(aFeature);
+      }
+
+      if (!aRefs.empty()) {
+        FeaturePtr aFeature = ModelAPI_Feature::feature(aResult);
+        if (aFeature.get() != NULL)
+          theRefs.insert(aFeature);
+      }
     }
   }
+  // the dependencies can be in the feature itself
+  std::shared_ptr<Model_Data> aData = 
+      std::dynamic_pointer_cast<Model_Data>(theFeature->data());
+  if (aData && !aData->refsToMe().empty()) {
+    theRefs.insert(theFeature);
+  }
+
   if (!theRefs.empty() && isSendError) {
     Events_Error::send(
       "Feature '" + theFeature->data()->name() + "' is used and can not be deleted");
index 9420d1e74d8818724ca2547c8e02fb9a9a5213a4..88fa049d45e5549396bffe806882ffa4b77b1530 100644 (file)
@@ -17,6 +17,7 @@
 class QAction;\r
 class QMouseEvent;\r
 class QKeyEvent;\r
+class QMenu;\r
 class Config_WidgetAPI;\r
 class ModuleBase_ModelWidget;\r
 class ModuleBase_Operation;\r
@@ -68,6 +69,17 @@ class MODULEBASE_EXPORT ModuleBase_IModule : public QObject
   /// Realizes some functionality by an operation abort\r
   virtual void operationAborted(ModuleBase_Operation* theOperation) {}\r
 \r
+  /// Add menu atems for viewer into the given menu\r
+  /// \param theMenu a popup menu to be shown in the viewer\r
+  virtual void addViewerItems(QMenu* theMenu) const {}\r
+\r
+  /// Add menu atems for object browser into the given menu\r
+  /// \param theMenu a popup menu to be shown in the object browser\r
+  virtual void addObjectBrowserItems(QMenu* theMenu) const {};\r
+\r
+  /// Called when it is necessary to update a command state (enable or disable it)\r
+  //virtual bool isFeatureEnabled(const QString& theCmdId) const = 0;\r
+\r
   /// Creates custom widgets for property panel\r
   /// \param theType a type of widget\r
   /// \param theParent the parent object\r
index b05715c3847463a83df72c4fdda44ae894ae3c8d..df5d23f1ee0a0d52afeb7f68a0edc74c8bff1c07 100644 (file)
@@ -63,6 +63,8 @@
 #include <QString>
 #include <QTimer>
 #include <QApplication>
+#include <QMessageBox>
+#include <QMainWindow>
 
 #include <GeomAlgoAPI_FaceBuilder.h>
 #include <GeomDataAPI_Dir.h>
@@ -95,6 +97,8 @@ PartSet_Module::PartSet_Module(ModuleBase_IWorkshop* theWshop)
   ModuleBase_IViewer* aViewer = theWshop->viewer();
   connect(aViewer, SIGNAL(keyRelease(ModuleBase_IViewWindow*, QKeyEvent*)),
           this, SLOT(onKeyRelease(ModuleBase_IViewWindow*, QKeyEvent*)));
+
+  createActions();
 }
 
 PartSet_Module::~PartSet_Module()
@@ -206,6 +210,25 @@ bool PartSet_Module::canDisplayObject(const ObjectPtr& theObject) const
     aCanDisplay = ModuleBase_IModule::canDisplayObject(theObject);
   }
   return aCanDisplay;
+
+void PartSet_Module::addViewerItems(QMenu* theMenu) const
+{
+  if (isSketchOperationActive()) {
+    ModuleBase_ISelection* aSelection = myWorkshop->selection();
+    QObjectPtrList aObjects = aSelection->selectedPresentations();
+    if (aObjects.size() > 0) {
+      bool hasFeature = false;
+      foreach(ObjectPtr aObject, aObjects)
+      {
+        FeaturePtr aFeature = ModelAPI_Feature::feature(aObject);
+        if (aFeature.get() != NULL) {
+          hasFeature = true;
+        }
+      }
+      if (hasFeature)
+        theMenu->addAction(action("DELETE_PARTSET_CMD"));
+    }
+  }
 }
 
 void PartSet_Module::propertyPanelDefined(ModuleBase_Operation* theOperation)
@@ -308,30 +331,20 @@ void PartSet_Module::onEnterReleased()
 void PartSet_Module::onOperationActivatedByPreselection()
 {
   ModuleBase_Operation* aOperation = myWorkshop->currentOperation();
-  if (!aOperation)
-    return;
-
-  // Set final definitions if they are necessary
-  //propertyPanelDefined(aOperation);
+  if(aOperation && isSketchOperationActive()) {
+    // Set final definitions if they are necessary
+    //propertyPanelDefined(aOperation);
 
-  /// Commit sketcher operations automatically
-  FeaturePtr aFeature = aOperation->feature();
-  std::shared_ptr<SketchPlugin_Feature> aSPFeature = 
-            std::dynamic_pointer_cast<SketchPlugin_Feature>(aFeature);
-  if (aSPFeature) {
+    /// Commit sketcher operations automatically
     aOperation->commit();
   }
 }
 
 void PartSet_Module::onNoMoreWidgets()
 {
-  ModuleBase_Operation* aOperation = myWorkshop->currentOperation();
-  if (aOperation) {
-    /// Restart sketcher operations automatically
-    FeaturePtr aFeature = aOperation->feature();
-    std::shared_ptr<SketchPlugin_Feature> aSPFeature = 
-              std::dynamic_pointer_cast<SketchPlugin_Feature>(aFeature);
-    if (aSPFeature) {
+  if (isSketchOperationActive()) {
+    ModuleBase_Operation* aOperation = myWorkshop->currentOperation();
+    if (aOperation) {
       if (myRestartingMode != RM_Forbided)
         myRestartingMode = RM_LastFeatureUsed;
       aOperation->commit();
@@ -404,3 +417,136 @@ QWidget* PartSet_Module::createWidgetByType(const std::string& theType, QWidget*
     return 0;
 }
 
+bool PartSet_Module::isSketchOperationActive() const
+{
+  bool isCurrentSketchOp = false;
+  ModuleBase_Operation* aOperation = myWorkshop->currentOperation();
+  if (aOperation) {
+    FeaturePtr aFeature = aOperation->feature();
+    std::shared_ptr<SketchPlugin_Feature> aSPFeature = 
+              std::dynamic_pointer_cast<SketchPlugin_Feature>(aFeature);
+    isCurrentSketchOp = aSPFeature.get() != NULL;
+  }
+  return isCurrentSketchOp;
+}
+
+void PartSet_Module::createActions()
+{
+  QAction* aAction = new QAction(QIcon(":pictures/delete.png"), tr("Delete"), this);
+  addAction("DELETE_PARTSET_CMD", aAction);
+}
+
+QAction* PartSet_Module::action(const QString& theId) const
+{
+  if (myActions.contains(theId))
+    return myActions[theId];
+  return 0;
+}
+
+void PartSet_Module::addAction(const QString& theId, QAction* theAction)
+{
+  if (myActions.contains(theId))
+    qCritical("A command with Id = '%s' already defined!", qPrintable(theId));
+  theAction->setData(theId);
+  connect(theAction, SIGNAL(triggered(bool)), this, SLOT(onAction(bool)));
+  myActions[theId] = theAction;
+}
+
+void PartSet_Module::onAction(bool isChecked)
+{
+  QAction* aAction = static_cast<QAction*>(sender());
+  QString anId = aAction->data().toString();
+
+  if (anId == "DELETE_PARTSET_CMD") {
+    deleteObjects();
+  }
+}
+
+void PartSet_Module::deleteObjects()
+{
+  if (!isSketchOperationActive())
+    return;
+
+  XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(workshop());
+  XGUI_Workshop* aWorkshop = aConnector->workshop();
+
+  XGUI_OperationMgr* anOpMgr = aWorkshop->operationMgr();
+  if(anOpMgr->canAbortOperation()) {
+    ModuleBase_Operation* aCurrentOp = anOpMgr->currentOperation();
+    if (aCurrentOp) {
+      bool isSketchOp = aCurrentOp->id().toStdString() == SketchPlugin_Sketch::ID();
+      if (!isSketchOp)
+        aCurrentOp->abort();
+    }
+  }
+
+  ModuleBase_ISelection* aSel = aConnector->selection();
+  QObjectPtrList aSelectedObj = aSel->selectedPresentations();
+
+  std::set<FeaturePtr> aRefFeatures;
+  foreach (ObjectPtr aObj, aSelectedObj)
+  {
+    //ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(aObj);
+    //if (aPart) {
+      // TODO: check for what there is this condition. It is placed here historicaly because
+      // ther is this condition during remove features.
+    //} else {
+    FeaturePtr aFeature = ModelAPI_Feature::feature(aObj);
+    if (aFeature.get() != NULL) {
+      aObj->document()->refsToFeature(aFeature, aRefFeatures, false);
+    }
+    //}
+  }
+
+  if (!aRefFeatures.empty()) {
+    QStringList aRefNames;
+    std::set<FeaturePtr>::const_iterator anIt = aRefFeatures.begin(),
+                                         aLast = aRefFeatures.end();
+    for (; anIt != aLast; anIt++) {
+      FeaturePtr aFeature = (*anIt);
+      std::string aFName = aFeature->data()->name().c_str();
+      std::string aName = (*anIt)->name().c_str();
+      aRefNames.append((*anIt)->name().c_str());
+    }
+    QString aNames = aRefNames.join(", ");
+
+    QMainWindow* aDesktop = aWorkshop->desktop();
+    QMessageBox::StandardButton aRes = QMessageBox::warning(
+        aDesktop, tr("Delete features"),
+        QString(tr("Selected features are used in the following features: %1.\
+These features will be deleted also. Would you like to continue?")).arg(aNames),
+        QMessageBox::No | QMessageBox::Yes, QMessageBox::No);
+    if (aRes != QMessageBox::Yes)
+      return;
+  }
+
+  SessionPtr aMgr = ModelAPI_Session::get();
+  aMgr->startOperation();
+  std::set<FeaturePtr>::const_iterator anIt = aRefFeatures.begin(),
+                                       aLast = aRefFeatures.end();
+  for (; anIt != aLast; anIt++) {
+    FeaturePtr aRefFeature = (*anIt);
+    DocumentPtr aDoc = aRefFeature->document();
+    aDoc->removeFeature(aRefFeature);
+   }
+
+  foreach (ObjectPtr aObj, aSelectedObj)
+  {
+    DocumentPtr aDoc = aObj->document();
+    //ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(aObj);
+    //if (aPart) {
+    //  if (aDoc == aMgr->activeDocument()) {
+    //    aDoc->close();
+    //  }
+    //} else {
+      //FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aObj);
+    FeaturePtr aFeature = ModelAPI_Feature::feature(aObj);
+    if (aFeature.get() != NULL) {
+      aDoc->removeFeature(aFeature);
+    }
+    //}
+  }
+  aWorkshop->displayer()->updateViewer();
+  //myDisplayer->updateViewer();
+  aMgr->finishOperation();
+}
index 326866c9fd16917a5163ffec8ba13394046375d6..f58c4738bf6c0efa5fb0d7aef17c5888162aaff8 100644 (file)
@@ -17,6 +17,7 @@
 #include <TopoDS_Shape.hxx>
 
 #include <QMap>
+#include <QMenu>
 #include <QObject>
 
 #include <string>
@@ -26,6 +27,8 @@
 class ModuleBase_Operation;
 class ModuleBase_IViewWindow;
 
+class QAction;
+
 /**
 * \ingroup Modules
 * Implementation of Partset module
@@ -82,12 +85,19 @@ public:
   /// if it is a sketch operation
   /// \param theObject a model object
   virtual bool canDisplayObject(const ObjectPtr& theObject) const;
+  /// Add menu atems for viewer into the given menu
+  /// \param theMenu a popup menu to be shown in the viewer
+  virtual void addViewerItems(QMenu* theMenu) const;
 
 public slots:
   /// SLOT, that is called by no more widget signal emitted by property panel
   /// Set a specific flag to restart the sketcher operation
   void onNoMoreWidgets();
 
+  /// Processes the context menu action click
+  /// \param isChecked a state of toggle if the action is checkable
+  void onAction(bool isChecked);
+
 protected slots:
   /// Called when previous operation is finished
   virtual void onSelectionChanged();
@@ -121,6 +131,26 @@ protected slots:
   /// Breaks sequense of automatically resterted operations
   void breakOperationSequence();
 
+  /// Check whether there is active opeation and it is the sketch one
+  /// \return boolean result
+  bool isSketchOperationActive() const;
+
+  /// Create all actions for context menus. It is called on creation of module
+  /// Put the created actions into an internal map
+  void createActions();
+
+  /// Returns action according to the given ID
+  /// \param theId an action identifier, it should be uniqued in the bounds of the module
+  QAction* action(const QString& theId) const;
+
+  /// Add action to the internal map
+  /// \param theId - string ID of the item
+  /// \param theAction - action to add
+  void addAction(const QString& theId, QAction* theAction);
+
+  //! Delete features
+  void deleteObjects();
+
  private:
    QString myLastOperationId;
    FeaturePtr myLastFeature;
@@ -132,6 +162,8 @@ protected slots:
   Handle(PartSet_GlobalFilter) myDocumentShapeFilter;
 
   PartSet_SketcherMgr* mySketchMgr;
+
+  QMap<QString, QAction*> myActions; // the popup menu actions
 };
 
 #endif
index 8a794d7810522816e25eb11140ccafa87fe4a25b..b4fa78dabe741599dcb8f55684cd1f7d26e25d28 100644 (file)
@@ -19,6 +19,8 @@
 #include <ModelAPI_Session.h>
 #include <ModelAPI_ResultGroup.h>
 
+#include <ModuleBase_IModule.h>
+
 #include <QAction>
 #include <QContextMenuEvent>
 #include <QMenu>
@@ -181,6 +183,11 @@ QMenu* XGUI_ContextMenuMgr::objectBrowserMenu() const
   }
   aMenu->addSeparator();
   aMenu->addActions(myWorkshop->objectBrowser()->actions());
+
+  ModuleBase_IModule* aModule = myWorkshop->module();
+  if (aModule)
+    aModule->addObjectBrowserItems(aMenu);
+
   if (aMenu->actions().size() > 0) {
     return aMenu;
   }
@@ -244,23 +251,9 @@ void XGUI_ContextMenuMgr::addViewerItems(QMenu* theMenu) const
     }
   }
 
-  aObjects.clear();
-  aObjects = aSelMgr->selection()->selectedPresentations();
-  if (aObjects.size() > 0) {
-    bool hasFeature = true;//false;
-    foreach(ObjectPtr aObject, aObjects)
-    {
-      ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(aObject);
-      if (aRes) {
-        hasFeature = true;
-      }
-      //FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aObject);
-      //if (aFeature)
-      //  hasFeature = true;
-    }
-    if (hasFeature)
-      theMenu->addAction(action("DELETE_CMD"));
-  }
+  ModuleBase_IModule* aModule = myWorkshop->module();
+  if (aModule)
+    aModule->addViewerItems(theMenu);
 }
 
 void XGUI_ContextMenuMgr::connectObjectBrowser() const
index bb620cd7379412c2251ef8dbb4191562b90f6894..7fc3d6bfa9a45f4655fc92f6c805c6983e2cc6b6 100644 (file)
@@ -46,7 +46,7 @@ Q_OBJECT
   void connectViewer() const;
 
   /// Add menu atems for viewer into the given menu (used in SALOME mode)
-  /// \param theMenu a menu instance
+  /// \param a popup menu to be shown in the viewer
   void addViewerItems(QMenu* theMenu) const;
 
 signals:
index 4eae595781c199d3aa7d6eb02c24abd02ad7c6f6..2ed8c86f53518e09c160c5ed5b4ae455ed77f916 100644 (file)
@@ -444,6 +444,11 @@ void XGUI_Workshop::processEvent(const std::shared_ptr<Events_Message>& theMessa
   }
 }
 
+//******************************************************
+QMainWindow* XGUI_Workshop::desktop() const
+{
+  return isSalomeMode() ? salomeConnector()->desktop() : myMainWindow;
+}
 
 //******************************************************
 void XGUI_Workshop::onStartWaiting()
@@ -1269,7 +1274,7 @@ void XGUI_Workshop::deleteObjects(const QObjectPtrList& theList)
       // ther is this condition during remove features.
     } else {
       FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aObj);
-      if (aFeature) {
+      if (aFeature.get() != NULL) {
         aObj->document()->refsToFeature(aFeature, aRefFeatures, false);
       }
     }
@@ -1298,6 +1303,15 @@ These features will be deleted also. Would you like to continue?")).arg(aNames),
 
   SessionPtr aMgr = ModelAPI_Session::get();
   aMgr->startOperation();
+  std::set<FeaturePtr>::const_iterator anIt = aRefFeatures.begin(),
+                                       aLast = aRefFeatures.end();
+  for (; anIt != aLast; anIt++) {
+    FeaturePtr aRefFeature = (*anIt);
+    DocumentPtr aDoc = aRefFeature->document();
+    aDoc->removeFeature(aRefFeature);
+   }
+
+
   foreach (ObjectPtr aObj, theList)
   {
     DocumentPtr aDoc = aObj->document();
@@ -1313,6 +1327,7 @@ These features will be deleted also. Would you like to continue?")).arg(aNames),
       }
     }
   }
+
   myDisplayer->updateViewer();
   aMgr->finishOperation();
 }
index 34ce06b91568e4483d9c0d03e458429d644d9bd4..80aa6d2f8358d405b313f1a48f18a8b770feae1f 100644 (file)
@@ -41,6 +41,7 @@ class Config_PointerMessage;
 
 class QWidget;
 class QDockWidget;
+class QMainWindow;
 
 class ModelAPI_ObjectUpdatedMessage;
 class ModelAPI_ObjectDeletedMessage;
@@ -149,6 +150,10 @@ Q_OBJECT
     return myModuleConnector;
   }
 
+  /// Returns a desktop
+  /// \return a desktop instance
+  QMainWindow* desktop() const;
+
   //! Returns icon name according to feature
   static QIcon featureIcon(const FeaturePtr& theFeature);
 
@@ -333,9 +338,9 @@ signals:
   /// \param theOpertion an aborted operation
   void onOperationAborted(ModuleBase_Operation* theOperation);
 
-  /// Process context menu command
-  /// \param theId id of the command
-  /// \param isChecked is checked flag
+  /// Slot, which reacts to the context popup menu call
+  /// \param theId the data value of the clicked action
+  /// \param isChecked a state of toggle if the action is checkable
   void onContextMenuCommand(const QString& theId, bool isChecked);
 
   /// Processing of values changed in model widget