]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
refs #30 - Sketch base GUI: create, draw lines
authornds <natalia.donis@opencascade.com>
Thu, 15 May 2014 10:40:55 +0000 (14:40 +0400)
committernds <natalia.donis@opencascade.com>
Thu, 15 May 2014 10:40:55 +0000 (14:40 +0400)
Undo/Redo for a line under sketch.

13 files changed:
src/PartSet/PartSet_Listener.cpp
src/PartSet/PartSet_Module.cpp
src/PartSet/PartSet_Module.h
src/PartSet/PartSet_OperationSketch.cpp
src/PartSet/PartSet_OperationSketch.h
src/PartSet/PartSet_OperationSketchBase.cpp
src/PartSet/PartSet_OperationSketchBase.h
src/SketchPlugin/SketchPlugin_Line.cpp
src/XGUI/XGUI_Displayer.cpp
src/XGUI/XGUI_Displayer.h
src/XGUI/XGUI_OperationMgr.cpp
src/XGUI/XGUI_OperationMgr.h
src/XGUI/XGUI_Workshop.cpp

index 3e1c4886a78f352827be6aadb1a0727f45f02a33..9615dac4cf175d81bc72b4c88c2c6e8c570f0be5 100644 (file)
@@ -21,8 +21,9 @@ PartSet_Listener::PartSet_Listener(PartSet_Module* theModule)
 : myModule(theModule)
 {
   Events_Loop* aLoop = Events_Loop::loop();
-  Events_ID aFeatureUpdatedId = aLoop->eventByName(EVENT_FEATURE_UPDATED);
-  aLoop->registerListener(this, aFeatureUpdatedId);
+  aLoop->registerListener(this, aLoop->eventByName(EVENT_FEATURE_UPDATED));
+  aLoop->registerListener(this, Events_Loop::eventByName(EVENT_FEATURE_CREATED));
+  aLoop->registerListener(this, Events_Loop::eventByName(EVENT_FEATURE_DELETED));
 }
 
 PartSet_Listener::~PartSet_Listener()
@@ -32,11 +33,24 @@ PartSet_Listener::~PartSet_Listener()
 //******************************************************
 void PartSet_Listener::processEvent(const Events_Message* theMessage)
 {
-  if (QString(theMessage->eventID().eventText()) == EVENT_FEATURE_UPDATED)
+  QString aType = QString(theMessage->eventID().eventText());
+  if (aType == EVENT_FEATURE_UPDATED ||
+      aType == EVENT_FEATURE_CREATED)
   {
     const Model_FeatureUpdatedMessage* aUpdMsg = dynamic_cast<const Model_FeatureUpdatedMessage*>(theMessage);
     boost::shared_ptr<ModelAPI_Feature> aFeature = aUpdMsg->feature();
-    if (myModule->workshop()->displayer()->IsVisible(aFeature))
+    if (myModule->workshop()->displayer()->IsVisible(aFeature) ||
+        aType == EVENT_FEATURE_CREATED)
       myModule->visualizePreview(aFeature, true);
   }
+  if (aType == EVENT_FEATURE_DELETED)
+  {
+    const Model_FeatureDeletedMessage* aDelMsg = dynamic_cast<const Model_FeatureDeletedMessage*>(theMessage);
+    boost::shared_ptr<ModelAPI_Document> aDoc = aDelMsg->document();
+
+    std::string aGroup = aDelMsg->group();
+    if (aDelMsg->group().compare("Sketch") == 0) { // Update only Sketch group
+      myModule->updateCurrentPreview(aGroup);
+    }
+  }
 }
index d7a92caf5118640d66b07f755918bc2985742a8a..9e47626c8a02a42220e26e1315d41ccebdf1e15f 100644 (file)
@@ -308,3 +308,36 @@ void PartSet_Module::visualizePreview(boost::shared_ptr<ModelAPI_Feature> theFea
     aDisplayer->Erase(anOperation->feature());
   }
 }
+
+void PartSet_Module::updateCurrentPreview(const std::string& theCmdId)
+{
+  ModuleBase_Operation* anOperation = myWorkshop->operationMgr()->currentOperation();
+  if (!anOperation)
+    return;
+
+  PartSet_OperationSketchBase* aPreviewOp = dynamic_cast<PartSet_OperationSketchBase*>(anOperation);
+  if (!aPreviewOp)
+    return;
+
+  boost::shared_ptr<ModelAPI_Feature> aFeature = aPreviewOp->feature();
+  if (!aFeature || aFeature->getKind() != theCmdId)
+    return;
+
+  std::map<boost::shared_ptr<ModelAPI_Feature>, boost::shared_ptr<GeomAPI_Shape> >
+                                                                     aList = aPreviewOp->preview();
+  XGUI_Displayer* aDisplayer = myWorkshop->displayer();
+  std::list<int> aModes = aPreviewOp->getSelectionModes(aPreviewOp->feature());
+
+  std::map<boost::shared_ptr<ModelAPI_Feature>, boost::shared_ptr<GeomAPI_Shape> >::const_iterator
+                                                         anIt = aList.begin(), aLast = aList.end();
+  aDisplayer->EraseAll(false);
+  for (; anIt != aLast; anIt++) {
+    boost::shared_ptr<ModelAPI_Feature> aFeature = (*anIt).first;
+    boost::shared_ptr<GeomAPI_Shape> aPreview = (*anIt).second;
+    aDisplayer->RedisplayInLocalContext(aFeature,
+                                        aPreview ? aPreview->impl<TopoDS_Shape>() : TopoDS_Shape(),
+                                        aModes, false);
+  }
+  aDisplayer->UpdateViewer();
+}
+
index 6138a43dc6ed539da34e0daba492b97e3c84930d..14a418d01435fbb58e037a7af0e375118edf6265 100644 (file)
@@ -44,6 +44,10 @@ public:
   /// \param isDisplay the state whether the presentation should be displayed or erased
   void visualizePreview(boost::shared_ptr<ModelAPI_Feature> theFeature, bool isDisplay);
 
+  /// Updates current operation preview, if it has it.
+  /// \param theCmdId the operation name
+  void updateCurrentPreview(const std::string& theCmdId);
+
 public slots:
   void onFeatureTriggered();
   /// SLOT, that is called after the operation is stopped. Switched off the modfications performed
index e5290aa77eb9bc3cbd86ec285cb4b6afdf623019..bcbbf15719214015b0d593b40ac521c71b0f665e 100644 (file)
@@ -11,6 +11,8 @@
 
 #include <ModelAPI_Data.h>
 #include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_AttributeRefList.h>
+
 #include <GeomAlgoAPI_FaceBuilder.h>
 #include <GeomDataAPI_Point.h>
 #include <GeomDataAPI_Dir.h>
@@ -79,6 +81,29 @@ void PartSet_OperationSketch::mouseMoved(QMouseEvent* theEvent, Handle(V3d_View)
     emit launchOperation(PartSet_OperationEditLine::Type(), aFeature);
 }
 
+std::map<boost::shared_ptr<ModelAPI_Feature>, boost::shared_ptr<GeomAPI_Shape> >
+                                                        PartSet_OperationSketch::preview() const
+{
+  std::map<boost::shared_ptr<ModelAPI_Feature>, boost::shared_ptr<GeomAPI_Shape> > aPreviewMap;
+
+  boost::shared_ptr<SketchPlugin_Feature> aFeature;
+
+  boost::shared_ptr<ModelAPI_Data> aData = feature()->data();
+  boost::shared_ptr<ModelAPI_AttributeRefList> aRefList =
+        boost::dynamic_pointer_cast<ModelAPI_AttributeRefList>(aData->attribute(SKETCH_ATTR_FEATURES));
+
+  std::list<boost::shared_ptr<ModelAPI_Feature> > aFeatures = aRefList->list();
+  std::list<boost::shared_ptr<ModelAPI_Feature> >::const_iterator anIt = aFeatures.begin(),
+                                                                  aLast = aFeatures.end();
+  for (; anIt != aLast; anIt++) {
+    aFeature = boost::dynamic_pointer_cast<SketchPlugin_Feature>(*anIt);
+    boost::shared_ptr<GeomAPI_Shape> aPreview = aFeature->preview();
+    if (aPreview)
+      aPreviewMap[aFeature] = aPreview;
+  }
+  return aPreviewMap;
+}
+
 void PartSet_OperationSketch::setSketchPlane(const TopoDS_Shape& theShape)
 {
   if (theShape.IsNull())
index 227722dc7c91b9849a8227e11e76d575a40d09d8..3f8215ac953f30f081ebfbdb80720a2ac6e014b2 100644 (file)
@@ -47,6 +47,10 @@ public:
   virtual void mouseMoved(QMouseEvent* theEvent, Handle_V3d_View theView,
                           const std::list<XGUI_ViewerPrs>& theSelected);
 
+  /// Returns the map of the operation previews including the nested feature previews
+  /// \return the map of feature to the feature preview
+  virtual std::map<boost::shared_ptr<ModelAPI_Feature>, boost::shared_ptr<GeomAPI_Shape> >
+                                                                           preview() const;
 signals:
   /// signal about the sketch plane is selected
   /// \param theX the value in the X direction of the plane
index 4113c3cba83fbab23eed59174fbd7e08d98cb4a3..daa0211b1d8b0656ccaf4f0162af8357a5057598 100644 (file)
@@ -32,6 +32,12 @@ boost::shared_ptr<GeomAPI_Shape> PartSet_OperationSketchBase::preview(
   return aFeature->preview();
 }
 
+std::map<boost::shared_ptr<ModelAPI_Feature>, boost::shared_ptr<GeomAPI_Shape> >
+                                                     PartSet_OperationSketchBase::preview() const
+{
+  return std::map<boost::shared_ptr<ModelAPI_Feature>, boost::shared_ptr<GeomAPI_Shape> >();
+}
+
 boost::shared_ptr<ModelAPI_Feature> PartSet_OperationSketchBase::createFeature()
 {
   boost::shared_ptr<ModelAPI_Feature> aFeature = ModuleBase_Operation::createFeature();
index b30f29935ba303eae52adcf9576b3e45ba1de2b0..cce1c55113f1b99362c47e0bce2efdc500d42f18 100644 (file)
@@ -15,6 +15,8 @@
 #include <ModuleBase_Operation.h>
 #include <QObject>
 
+#include <map>
+
 class Handle_V3d_View;
 class QMouseEvent;
 class GeomAPI_Shape;
@@ -43,6 +45,10 @@ public:
   /// \param theFeature the feature object to obtain the preview
   boost::shared_ptr<GeomAPI_Shape> preview(boost::shared_ptr<ModelAPI_Feature> theFeature) const;
 
+  /// Returns the map of the operation previews including the nested feature previews
+  /// \return the map of feature to the feature preview
+  virtual std::map<boost::shared_ptr<ModelAPI_Feature>, boost::shared_ptr<GeomAPI_Shape> > preview() const;
+
   /// Returns the operation local selection mode
   /// \param theFeature the feature object to get the selection mode
   /// \return the selection mode
index 8462d99bdea0ca55518a41d6c8fe4efce13b118a..5c71d37791f3c65fae984a133dc9e6c91f2fff00 100644 (file)
@@ -16,6 +16,7 @@ const double PLANE_SIZE = 200;
 
 SketchPlugin_Line::SketchPlugin_Line()
 {
+  setSketch(0);
 }
 
 void SketchPlugin_Line::initAttributes()
@@ -31,17 +32,18 @@ void SketchPlugin_Line::execute()
 const boost::shared_ptr<GeomAPI_Shape>& SketchPlugin_Line::preview()
 {
   SketchPlugin_Sketch* aSketch = sketch();
-  // compute a start point in 3D view
-  boost::shared_ptr<GeomDataAPI_Point2D> aStartAttr = 
-    boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(data()->attribute(LINE_ATTR_START));
-  boost::shared_ptr<GeomAPI_Pnt> aStart(aSketch->to3D(aStartAttr->x(), aStartAttr->y()));
-  // compute an end point in 3D view
-  boost::shared_ptr<GeomDataAPI_Point2D> anEndAttr = 
-    boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(data()->attribute(LINE_ATTR_END));
-  boost::shared_ptr<GeomAPI_Pnt> anEnd(aSketch->to3D(anEndAttr->x(), anEndAttr->y()));
-  // make linear edge
-  boost::shared_ptr<GeomAPI_Shape> anEdge = GeomAlgoAPI_EdgeBuilder::line(aStart, anEnd);
-  setPreview(anEdge);
-
+  if (aSketch) {
+    // compute a start point in 3D view
+    boost::shared_ptr<GeomDataAPI_Point2D> aStartAttr = 
+      boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(data()->attribute(LINE_ATTR_START));
+    boost::shared_ptr<GeomAPI_Pnt> aStart(aSketch->to3D(aStartAttr->x(), aStartAttr->y()));
+    // compute an end point in 3D view
+    boost::shared_ptr<GeomDataAPI_Point2D> anEndAttr = 
+      boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(data()->attribute(LINE_ATTR_END));
+    boost::shared_ptr<GeomAPI_Pnt> anEnd(aSketch->to3D(anEndAttr->x(), anEndAttr->y()));
+    // make linear edge
+    boost::shared_ptr<GeomAPI_Shape> anEdge = GeomAlgoAPI_EdgeBuilder::line(aStart, anEnd);
+    setPreview(anEdge);
+  }
   return getPreview();
 }
index 20a6f721e9f38e7285b3440405e7e18a2edf67e5..2613adae6bbc9ab20b77f31e8b3f5e49b7bb6e75 100644 (file)
@@ -141,6 +141,26 @@ void XGUI_Displayer::RedisplayInLocalContext(boost::shared_ptr<ModelAPI_Feature>
     aContext->UpdateCurrentViewer();
 }
 
+void XGUI_Displayer::EraseAll(const bool isUpdateViewer)
+{
+  Handle(AIS_InteractiveContext) ic = AISContext();
+
+  AIS_ListOfInteractive aList;
+  ic->DisplayedObjects(aList);
+  AIS_ListIteratorOfListOfInteractive anIter(aList);
+  for (; anIter.More(); anIter.Next()) {
+    if ((anIter.Value()->DynamicType() == STANDARD_TYPE(AIS_Trihedron)))
+      continue;
+
+    // erase an object
+    Handle(AIS_InteractiveObject) anIO = anIter.Value();
+    ic->Erase(anIO, false);
+  }
+  myFeature2AISObjectMap.clear();
+  if (isUpdateViewer)
+    ic->UpdateCurrentViewer();
+}
+
 void XGUI_Displayer::CloseLocalContexts(const bool isUpdateViewer)
 {
   closeAllContexts(true);
@@ -156,6 +176,13 @@ void XGUI_Displayer::closeAllContexts(const bool isUpdateViewer)
   }
 }
 
+void XGUI_Displayer::UpdateViewer()
+{
+  Handle(AIS_InteractiveContext) ic = AISContext();
+  if (!ic.IsNull())
+    ic->UpdateCurrentViewer();
+}
+
 Handle(AIS_InteractiveContext) XGUI_Displayer::AISContext() const 
 { 
   return myWorkshop->viewer()->AISContext(); 
index cda9331e648489f658a302927900d3a2af8e1d3d..a8bfbe2f35d0d2364befa48b2b01163bf6deb4ea 100644 (file)
@@ -81,10 +81,17 @@ public:
   /// \param isUpdateViewer the parameter whether the viewer should be update immediatelly
   void Erase(boost::shared_ptr<ModelAPI_Feature> theFeature, const bool isUpdateViewer = true);
 
+  /// Erase all presentations
+  /// \param isUpdateViewer the parameter whether the viewer should be update immediatelly
+  void EraseAll(const bool isUpdateViewer = true);
+
   /// Deactivates selection of sub-shapes
   /// \param isUpdateViewer the parameter whether the viewer should be update immediatelly
   void CloseLocalContexts(const bool isUpdateViewer = true);
 
+  /// Updates the viewer
+  void UpdateViewer();
+
 protected:
   /// Deactivate local selection
   /// \param isUpdateViewer the state wether the viewer should be updated immediatelly
index 7119a8fa19cbf726c364190dd736e9d70cef6f74..00419c69238d19063e84d0aa1c41cb39cce61bf2 100644 (file)
@@ -46,6 +46,16 @@ bool XGUI_OperationMgr::startOperation(ModuleBase_Operation* theOperation)
   return true;
 }
 
+bool XGUI_OperationMgr::abortOperation()
+{
+  ModuleBase_Operation* aCurrentOp = currentOperation();
+  if (!aCurrentOp || !canStopOperation())
+    return false; 
+
+  aCurrentOp->abort();
+  return true;
+}
+
 void XGUI_OperationMgr::resumeOperation(ModuleBase_Operation* theOperation)
 {
   connect(theOperation, SIGNAL(stopped()), this, SLOT(onOperationStopped()));
@@ -60,10 +70,7 @@ bool XGUI_OperationMgr::canStartOperation(ModuleBase_Operation* theOperation)
   ModuleBase_Operation* aCurrentOp = currentOperation();
   if (aCurrentOp && !theOperation->isGranted())
   {
-    int anAnswer = QMessageBox::question(0, tr("Operation launch"),
-                                tr("Previous operation is not finished and will be aborted"),
-                                QMessageBox::Ok, QMessageBox::Cancel);
-    if (anAnswer == QMessageBox::Ok) {
+    if (canStopOperation()) {
       aCurrentOp->abort();
     } else {
       aCanStart = false;
@@ -72,6 +79,14 @@ bool XGUI_OperationMgr::canStartOperation(ModuleBase_Operation* theOperation)
   return aCanStart;
 }
 
+bool XGUI_OperationMgr::canStopOperation()
+{
+  int anAnswer = QMessageBox::question(0, tr("Operation launch"),
+                              tr("Previous operation is not finished and will be aborted"),
+                              QMessageBox::Ok, QMessageBox::Cancel);
+  return anAnswer == QMessageBox::Ok;
+}
+
 void XGUI_OperationMgr::onOperationStopped()
 {
   ModuleBase_Operation* aSenderOperation = dynamic_cast<ModuleBase_Operation*>(sender());
index fc6214d56748e7772dd6e86cf64935ee3243cab8..41323570ec46fc3e6fcf12566182c9c84e0e48a6 100644 (file)
@@ -43,6 +43,10 @@ public:
   /// \return the state whether the current operation is started
   bool startOperation(ModuleBase_Operation* theOperation);
 
+  /// Abort the operation and append it to the stack of operations
+  /// \return the state whether the current operation is aborted
+  bool abortOperation();
+
 signals:
   /// Signal about an operation is started. It is emitted after the start() of operation is done.
   void operationStarted();
@@ -62,6 +66,9 @@ protected:
   /// \param theOperation an operation to check
   bool canStartOperation(ModuleBase_Operation* theOperation);
 
+  /// Returns whether the operation can be stopped.
+  bool canStopOperation();
+
 protected slots:
   /// Slot that is called by an operation stop. Removes the stopped operation form the stack.
   /// If there is a suspended operation, restart it.
index aeb505f9d7cde160ff24152a6922ca618768320a..aa2318703d9da9311e7c5c0cc869d861dc718571 100644 (file)
@@ -470,6 +470,8 @@ void XGUI_Workshop::onUndo()
   objectBrowser()->setCurrentIndex(QModelIndex());
   boost::shared_ptr<ModelAPI_PluginManager> aMgr = ModelAPI_PluginManager::get();
   boost::shared_ptr<ModelAPI_Document> aDoc = aMgr->rootDocument();
+  if (!operationMgr()->abortOperation())
+    return;
   aDoc->undo();
   updateCommandStatus();
 }