]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Issue #394 Undo-ing a Sketch element
authornds <natalia.donis@opencascade.com>
Fri, 13 Feb 2015 07:46:10 +0000 (10:46 +0300)
committernds <natalia.donis@opencascade.com>
Fri, 13 Feb 2015 07:46:10 +0000 (10:46 +0300)
Update Undo/Redo action enable state.

src/ModuleBase/ModuleBase_IModule.cpp
src/ModuleBase/ModuleBase_IModule.h
src/PartSet/PartSet_Module.cpp
src/PartSet/PartSet_Module.h
src/PartSet/PartSet_SketcherMgr.cpp
src/PartSet/PartSet_SketcherMgr.h
src/PartSet/PartSet_WidgetPoint2d.h
src/PartSet/PartSet_WidgetPoint2dDistance.h
src/XGUI/XGUI_Workshop.cpp

index f7637f9d77128f8c720878d0d6a274720e97ea64..315be91780a0db0180dafdbfb6879b70d77ce351 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <ModelAPI_Events.h>
 #include <ModelAPI_CompositeFeature.h>
+#include <ModelAPI_Session.h>
 
 #include <Config_PointerMessage.h>
 #include <Config_WidgetReader.h>
@@ -116,6 +117,18 @@ bool ModuleBase_IModule::canDisplayObject(const ObjectPtr& theObject) const
   return anOperation && anOperation->hasObject(theObject);
 }
 
+bool ModuleBase_IModule::canUndo() const
+{
+  SessionPtr aMgr = ModelAPI_Session::get();
+  return aMgr->hasModuleDocument() && aMgr->canUndo() && !aMgr->isOperation();
+}
+
+bool ModuleBase_IModule::canRedo() const
+{
+  SessionPtr aMgr = ModelAPI_Session::get();
+  return aMgr->hasModuleDocument() && aMgr->canRedo() && !aMgr->isOperation();
+}
+
 void ModuleBase_IModule::onFeatureTriggered()
 {
   QAction* aCmd = dynamic_cast<QAction*>(sender());
index b500dd6f82ae3f97b4dbcb1498eabbf87925f4cc..3c3d33878f7462ccc7db2fcf54b4d2b2705d7dbb 100644 (file)
@@ -100,6 +100,12 @@ class MODULEBASE_EXPORT ModuleBase_IModule : public QObject
   /// It is called as on clearing of property panel as on filling with new widgets\r
   virtual void propertyPanelDefined(ModuleBase_Operation* theOperation) {}\r
 \r
+  //! Returns True if there are available Undos and there is not an active operation\r
+  virtual bool canUndo() const;\r
+\r
+  //! Returns True if there are available Redos and there is not an active operation\r
+  virtual bool canRedo() const;\r
+\r
   /// Returns whether the object can be displayed at the bounds of the active operation.\r
   /// Display only current operation results\r
   /// \param theObject a model object\r
@@ -127,9 +133,9 @@ protected slots:
 \r
   /// Register selection filters for this module\r
   virtual void registerFilters() {}\r
-
-  /// Register properties of this module
-  virtual void registerProperties() {}
+\r
+  /// Register properties of this module\r
+  virtual void registerProperties() {}\r
 \r
   /// Returns new instance of operation object (used in createOperation for customization)\r
   virtual ModuleBase_Operation* getNewOperation(const std::string& theFeatureId);\r
index f3ccdf4f7d2dc0c570b1778f5f1d737252b2cfc4..05409232e51619b6b55f2f601d56f2cf0abb850b 100644 (file)
@@ -209,6 +209,30 @@ void PartSet_Module::operationStopped(ModuleBase_Operation* theOperation)
   myWorkshop->viewer()->removeSelectionFilter(myDocumentShapeFilter);
 }
 
+bool PartSet_Module::canUndo() const
+{
+  bool aCanUndo = false;
+  SessionPtr aMgr = ModelAPI_Session::get();
+  if (aMgr->hasModuleDocument() && aMgr->canUndo()) {
+    aCanUndo = !aMgr->isOperation();
+    if (!aCanUndo) // check the enable state additionally by sketch manager
+      aCanUndo = aMgr->canUndo();
+  }
+  return aCanUndo;
+}
+
+bool PartSet_Module::canRedo() const
+{
+  bool aCanRedo = false;
+  SessionPtr aMgr = ModelAPI_Session::get();
+  if (aMgr->hasModuleDocument() && aMgr->canRedo()) {
+    aCanRedo = !aMgr->isOperation();
+    if (!aCanRedo) // check the enable state additionally by sketch manager
+      aCanRedo = aMgr->canRedo();
+  }
+  return aCanRedo;
+}
+
 bool PartSet_Module::canDisplayObject(const ObjectPtr& theObject) const
 {
   bool aCanDisplay = false;
index 13cfba1d9ac4cdf3a8fd61ffea08028e68911db8..e8ad83d7f5f07545a906dd8de34fe80cf01f1221 100644 (file)
@@ -80,6 +80,14 @@ public:
   /// \param theOperation a stopped operation
   virtual void operationStopped(ModuleBase_Operation* theOperation);
 
+  /// Returns True if there are available Undos and the sketch manager allows undo
+  /// \return the boolean result
+  virtual bool canUndo() const;
+
+  //! Returns True if there are available Redos and the sketch manager allows redo
+  /// \return the boolean result
+  virtual bool canRedo() const;
+
   /// Returns whether the object can be displayed at the bounds of the active operation.
   /// Display only current operation results for usual operation and ask the sketcher manager
   /// if it is a sketch operation
index 6ce573b0d4eab30014dfcd8a3fcac194a4adda92..2bbd22d09d9ba5544659187896ca4eb7cc28c312 100644 (file)
@@ -7,6 +7,7 @@
 #include "PartSet_SketcherMgr.h"
 #include "PartSet_Module.h"
 #include "PartSet_WidgetPoint2d.h"
+#include "PartSet_WidgetPoint2dDistance.h"
 #include "PartSet_Tools.h"
 
 #include <XGUI_ModuleConnector.h>
@@ -109,7 +110,7 @@ void fillFeature2Attribute(const QList<ModuleBase_ViewerPrs>& theList,
 
 PartSet_SketcherMgr::PartSet_SketcherMgr(PartSet_Module* theModule)
   : QObject(theModule), myModule(theModule), myIsDragging(false), myDragDone(false),
-     myIsMouseOverWindow(false), myIsPropertyPanelValueChanged(false)
+    myIsPropertyPanelValueChanged(false), myIsMouseOverViewProcessed(true)
 {
   ModuleBase_IWorkshop* anIWorkshop = myModule->workshop();
   ModuleBase_IViewer* aViewer = anIWorkshop->viewer();
@@ -141,31 +142,45 @@ PartSet_SketcherMgr::~PartSet_SketcherMgr()
 
 void PartSet_SketcherMgr::onMouseMoveOverWindow(bool theOverWindow)
 {
-  ModuleBase_Operation* aOperation = myModule->workshop()->currentOperation();
-  if (!aOperation || aOperation->isEditOperation())
+  if (!isNestedCreateOperation() || theOverWindow)
     return;
-
-  myIsMouseOverWindow = theOverWindow;
-  if (theOverWindow)
+  // 1. if the mouse over window, update the next flag. Do not perform update visibility of
+  // created feature because it should be done in onMouseMove(). Some widgets watch
+  // the mouse move and use the cursor position to update own values. If the presentaion is
+  // redisplayed before this update, the feature presentation jumps from reset value to current.
+  if (theOverWindow) {
     myIsPropertyPanelValueChanged = false;
-  else {
-    ModuleBase_IPropertyPanel* aPanel = aOperation->propertyPanel();
-    ModuleBase_ModelWidget* aActiveWgt = aPanel->activeWidget();
-    if(aActiveWgt) {
-      aActiveWgt->reset();
-    }
-  }  
+    return;
+  }
+  myIsMouseOverViewProcessed = false;
+
+  // 2. if the mouse IS NOT over window, reset the active widget value and hide the presentation
+  ModuleBase_IWorkshop* aWorkshop = myModule->workshop();
+  XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(aWorkshop);
+  XGUI_Displayer* aDisplayer = aConnector->workshop()->displayer();
+  // disable the viewer update in order to avoid visualization of redisplayed feature in viewer
+  // obtained after reset value
+  bool isEnableUpdateViewer = aDisplayer->enableUpdateViewer(false);
+  ModuleBase_Operation* aOperation = myModule->workshop()->currentOperation();
+  ModuleBase_IPropertyPanel* aPanel = aOperation->propertyPanel();
+  ModuleBase_ModelWidget* aActiveWgt = aPanel->activeWidget();
+  if (aActiveWgt) {
+    aActiveWgt->reset();
+  }
+  aDisplayer->enableUpdateViewer(isEnableUpdateViewer);
+
+  // hides the presentation of the current operation feature
+  myIsPropertyPanelValueChanged = false;
   updateVisibilityOfCreatedFeature();
 }
 
 void PartSet_SketcherMgr::onValuesChangedInPropertyPanel()
 {
-  ModuleBase_Operation* aOperation = myModule->workshop()->currentOperation();
-  if (!aOperation || aOperation->isEditOperation())
+  if (!isNestedCreateOperation())
     return;
 
+  // visualize the current operation feature
   myIsPropertyPanelValueChanged = true;
-
   updateVisibilityOfCreatedFeature();
 }
 
@@ -293,6 +308,26 @@ void PartSet_SketcherMgr::onMouseReleased(ModuleBase_IViewWindow* theWnd, QMouse
 
 void PartSet_SketcherMgr::onMouseMoved(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent)
 {
+  if (isNestedCreateOperation() && !myIsMouseOverViewProcessed) {
+    myIsMouseOverViewProcessed = true;
+    // 1. perform the widget mouse move functionality and display the presentation
+    ModuleBase_Operation* aOperation = myModule->workshop()->currentOperation();
+    ModuleBase_IPropertyPanel* aPanel = aOperation->propertyPanel();
+    ModuleBase_ModelWidget* anActiveWdg = aPanel->activeWidget();
+    // the mouse move should be processed in the widget, if it can in order to visualize correct
+    // presentation. These widgets correct the feature attribute according to the mouse position
+    PartSet_WidgetPoint2D* aPoint2DWdg = dynamic_cast<PartSet_WidgetPoint2D*>(anActiveWdg);
+    if (aPoint2DWdg) {
+      aPoint2DWdg->onMouseMove(theWnd, theEvent);
+    }
+    PartSet_WidgetPoint2dDistance* aDistanceWdg = dynamic_cast<PartSet_WidgetPoint2dDistance*>
+                                                                (anActiveWdg);
+    if (aDistanceWdg) {
+      aDistanceWdg->onMouseMove(theWnd, theEvent);
+    }
+    updateVisibilityOfCreatedFeature();
+  }
+
   myClickedPoint.clear();
 
   if (myIsDragging) {
@@ -608,11 +643,38 @@ void PartSet_SketcherMgr::startNestedSketch(ModuleBase_Operation* )
 void PartSet_SketcherMgr::stopNestedSketch(ModuleBase_Operation* )
 {
   connectToPropertyPanel(false);
+  myIsPropertyPanelValueChanged = false;
+  myIsMouseOverViewProcessed = true;
+}
+
+bool PartSet_SketcherMgr::canUndo() const
+{
+  return isNestedCreateOperation();
+}
+
+bool PartSet_SketcherMgr::canRedo() const
+{
+  return isNestedCreateOperation();
 }
 
 bool PartSet_SketcherMgr::canDisplayObject(const ObjectPtr& theObject) const
 {
-  return myIsMouseOverWindow || myIsPropertyPanelValueChanged;
+  bool aCanDisplay = true;
+  if (!isNestedCreateOperation())
+    return aCanDisplay;
+
+  // during a nested create operation, the feature is redisplayed only if the mouse over view
+  // of there was a value modified in the property panel after the mouse left the view
+  aCanDisplay = myIsPropertyPanelValueChanged;
+  if (!aCanDisplay) {
+    ModuleBase_IWorkshop* anIWorkshop = myModule->workshop();
+    XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(anIWorkshop);
+    XGUI_Workshop* aWorkshop = aConnector->workshop();
+    AppElements_MainWindow* aMainWindow = aWorkshop->mainWindow();
+
+    aCanDisplay = aMainWindow->isMouseOverWindow();
+  }
+  return aCanDisplay;
 }
 
 void PartSet_SketcherMgr::onPlaneSelected(const std::shared_ptr<GeomAPI_Pln>& thePln)
@@ -758,6 +820,12 @@ void PartSet_SketcherMgr::connectToPropertyPanel(const bool isToConnect)
   }
 }
 
+bool PartSet_SketcherMgr::isNestedCreateOperation() const
+{
+  ModuleBase_Operation* aOperation = myModule->workshop()->currentOperation();
+  return aOperation && !aOperation->isEditOperation() && isNestedSketchOperation(aOperation);
+}
+
 void PartSet_SketcherMgr::updateVisibilityOfCreatedFeature()
 {
   ModuleBase_IWorkshop* aWorkshop = myModule->workshop();
@@ -779,4 +847,4 @@ void PartSet_SketcherMgr::updateVisibilityOfCreatedFeature()
     }
   }
   aDisplayer->updateViewer();
-}
\ No newline at end of file
+}
index a08cf394162255f2f5aa3e2caf9c8fa076b644fb..59ed0f8fb1723ae34d4f825669b5c5a26e57ccb5 100644 (file)
@@ -110,6 +110,14 @@ public:
   /// Stops sketch operation
   void stopNestedSketch(ModuleBase_Operation* );
 
+  /// Returns True if there are available Undos and the sketch manager allows undo
+  /// \return the boolean result
+  bool canUndo() const;
+
+  //! Returns True if there are available Redos and the sketch manager allows redo
+  /// \return the boolean result
+  bool canRedo() const;
+
   /// Returns whether the object can be displayed at the bounds of the active operation.
   /// Display only current operation results for usual operation and ask the sketcher manager
   /// if it is a sketch operation
@@ -193,6 +201,16 @@ private:
   /// \param isToConnect a boolean value whether connect or disconnect
   void connectToPropertyPanel(const bool isToConnect);
 
+  /// Returns true if the created feature is visible
+  /// \param 
+  bool isVisibleCreatedFeature() const;
+
+  /// Returns true if the current operation is create a nested feature
+  //// \return boolean value
+  bool isNestedCreateOperation() const;
+
+  /// Erase or display the feature of the current operation. If the mouse over the active view or
+  /// a current value is changed by property panel, the feature is displayed otherwise it is hidden
   void updateVisibilityOfCreatedFeature();
 
 private:
@@ -201,8 +219,8 @@ private:
   bool myPreviousSelectionEnabled; // the previous selection enabled state in the viewer
   bool myIsDragging;
   bool myDragDone;
-  bool myIsMouseOverWindow; /// the state that mouse is over view
   bool myIsPropertyPanelValueChanged; /// the state that value in the property panel is changed
+  bool myIsMouseOverViewProcessed; /// the state whether the over view state is processed by mouseMove method
   Point myCurrentPoint;
   Point myClickedPoint;
 
index b976abf182ee8d3beb487cdb20b9d0f511964976..de3ab120ddc92db4f75006dd9b28c3e59eefc2d2 100644 (file)
@@ -98,16 +98,17 @@ signals:
   /// Signal about selection of an existing vertex from an object
   void vertexSelected();
 
-protected slots:
-  /// Process mouse release event
+public slots:
+  /// Process mouse move event
   /// \param theWnd a view window
   /// \param theEvent a mouse event
-  void onMouseRelease(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent);
+  void onMouseMove(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent);
 
-  /// Process mouse move event
+protected slots:
+  /// Process mouse release event
   /// \param theWnd a view window
   /// \param theEvent a mouse event
-  void onMouseMove(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent);
+  void onMouseRelease(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent);
 
 protected:
   /// Saves the internal parameters to the given feature
index 5ebfb4d1cac02cc51750fcef5edc3105cafbeede..7d6a497c6058f55a89af09552decfa518f6ce373 100644 (file)
@@ -66,16 +66,17 @@ Q_OBJECT
   /// Set sketch instance
   void setSketch(CompositeFeaturePtr theSketch) { mySketch = theSketch; }
 
- protected slots:
-   /// Process of mouse release
+public slots:
+   /// Process of mouse move
    /// \param theWnd a pointer to a window
    /// \param theEvent a mouse event
-  void onMouseRelease(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent);
+  void onMouseMove(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent);
 
-   /// Process of mouse move
+  protected slots:
+   /// Process of mouse release
    /// \param theWnd a pointer to a window
    /// \param theEvent a mouse event
-  void onMouseMove(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent);
+  void onMouseRelease(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent);
 
 protected:
   /// The methiod called when widget is activated
index f7b254deab7591aa2fa15b72d38409f8bff8c459..b6ba2aa7101640473a22f93e0e2022c20c4173a2 100644 (file)
@@ -1058,8 +1058,8 @@ void XGUI_Workshop::updateCommandStatus()
         // Enable all commands
         aCmd->setEnabled(true);
     }
-    aUndoCmd->setEnabled(aMgr->canUndo() && !aMgr->isOperation());
-    aRedoCmd->setEnabled(aMgr->canRedo() && !aMgr->isOperation());
+    aUndoCmd->setEnabled(myModule->canUndo());
+    aRedoCmd->setEnabled(myModule->canRedo());
 
     updateHistory();