Salome HOME
#2084 invalid sketch after trim: control of reentrant trim is filled only by message...
[modules/shaper.git] / src / PartSet / PartSet_SketcherReentrantMgr.h
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
2
3 #ifndef PartSet_SketcherReentrantMgr_H
4 #define PartSet_SketcherReentrantMgr_H
5
6 #include "PartSet.h"
7
8 #include <ModelAPI_Feature.h>
9
10 #include <string>
11 #include <memory>
12
13 #include <QObject>
14
15 class ModuleBase_IWorkshop;
16 class ModuleBase_Operation;
17 class ModuleBase_ModelWidget;
18 class ModuleBase_IViewWindow;
19
20 class ModelAPI_CompositeFeature;
21
22 class QMouseEvent;
23
24 class XGUI_Workshop;
25 class PartSet_Module;
26 class ModuleBase_ViewerPrs;
27 class Events_Message;
28 class ModelAPI_Attribute;
29 class GeomAPI_Pnt2d;
30
31 /// \ingroup PartSet_SketcherReentrantMgr
32 /// It provides reentrant create operations in sketch, that is when all inputs are valid,
33 /// automatic validation of the creation and switch the created entity to edit mode
34 /// ('internal' edit operation), with the ability to simultaneously create the next entity
35 /// of same type (re-entrance of the operation).
36 /// OK valids the current edition and exits from the operation (no re-entrance).
37 /// Cancel removes (undo) the entity currently edited and
38 /// exits from the operation (no re-entrance).
39 class PARTSET_EXPORT PartSet_SketcherReentrantMgr : public QObject
40 {
41 Q_OBJECT
42
43 /// Enumeration to specify the restart operation properties.
44 enum RestartingMode {
45   RM_None, /// the operation should not be restarted
46   RM_Forbided, /// the operation should not be restarted after there is no active widget
47   RM_LastFeatureUsed, /// the operation is restarted and use
48                       /// the previous feature for own initialization
49   RM_EmptyFeatureUsed /// the operation is restarted and does not use the previous feature
50 };
51
52 public:
53   /// Constructor
54   /// \param theWorkshop a workshop instance
55   PartSet_SketcherReentrantMgr(ModuleBase_IWorkshop* theWorkshop);
56   virtual ~PartSet_SketcherReentrantMgr();
57
58 public:
59   /// Returns a first widget of the current opeation if the internal edit operation is active
60   /// or return null. If the current widget of the operation is a viewer selector, it returns null.
61   ModuleBase_ModelWidget* internalActiveWidget() const;
62
63   /// Return true if the current edit operation is an internal
64   bool isInternalEditActive() const;
65
66   /// Stop internal edit if the operation feature is invalid
67   void updateInternalEditActiveState();
68
69   /// if the internal flags allow it and the manager is active, it starts an internal edit operation
70   /// for the created operation.
71   /// \param thePreviousAttributeID an index of the previous active attribute
72   //bool restartOperation(const std::string& thePreviousAttributeID);
73   bool processEnter(const std::string& thePreviousAttributeID);
74
75   /// Resets the internal flags
76   /// \param theOperation a started operation
77   void operationStarted(ModuleBase_Operation* theOperation);
78
79   /// Resets the internal flags
80   /// \param theOperation a started operation
81   /// \return state whether the internal edit operation was active
82   bool operationCommitted(ModuleBase_Operation* theOperation);
83
84   /// Resets the internal flags
85   /// \param theOperation a started operation
86   void operationAborted(ModuleBase_Operation* theOperation);
87
88   /// Return true if the manager processes the mouse move event
89   /// It happens if the current operation is an internal edit operation and the first
90   /// control can be filled by the mouse move event. The operation is restarted.
91   /// \return true if operation is committed.
92   bool processMouseMoved(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent);
93
94   /// Return true if the manager processes the mouse press event
95   /// \return true if the current operation is an internal edit operation.
96   bool processMousePressed(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent);
97
98   /// Return true if the manager processes the mouse enter event
99   /// It happens if the current operation is an internal edit operation.
100   /// The operation is restarted. If the first widget of the started operation is
101   /// the point 2d, it processes this mouse event
102   /// \return true if operation is committed.
103   bool processMouseReleased(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent);
104
105   /// It is called by the current operation filling with the preselection.
106   /// Returns false if the reentrant mode of the operation is not empty.
107   bool canBeCommittedByPreselection();
108
109   /// Fills reentrant message during restarting operation
110   /// \param theMessage reentrant message
111   void setReentrantMessage(const std::shared_ptr<Events_Message>& theMessage)
112   { myReentrantMessage = theMessage; }
113
114   /// Returnss reentrant message
115   std::shared_ptr<Events_Message> reentrantMessage() const { return myReentrantMessage; }
116
117   /// Put current selection into reentrant message
118   /// \param theMessage a message of reentrant operation
119   void setReentrantPreSelection(const std::shared_ptr<Events_Message>& theMessage);
120
121 private slots:
122   /// SLOT, that is called by a widget activating in the property panel
123   /// If the 'internal' edit operation is started, it activates the first widget selection
124   void onWidgetActivated();
125
126   /// SLOT, that is called by no more widget signal emitted by property panel
127   /// Start an internal edit operation or, if the internal flag is forbided, commits
128   /// the current operation
129   /// \param thePreviousAttributeID an index of the previous active attribute
130   void onNoMoreWidgets(const std::string& thePreviousAttributeID);
131
132   /// Processing of vertex selected. Set an internal reentrant flag to forbiddent state if
133   /// the current feature is a line and there are not obligate widgets anymore
134   void onVertexSelected();
135
136   /// Listens to the signal about the modification of the values
137   /// have been done in the property panel. If the manager has active edit operation and
138   /// the active widget does not process the modification of value, the manager will
139   /// restart current operation and fill a new feature attribute by the value of current
140   /// widget
141   void onAfterValuesChangedInPropertyPanel();
142
143   /// Deactivates selection and filters of the first operation widget if it is an internal
144   /// 'edit' operation
145   void onBeforeStopped();
146
147 private:
148   /// Returns true if the current operation is a sketch or a nested sketch operation
149   bool isActiveMgr() const;
150
151   /// Sets the focus to the last control of the property panel and activates selection
152   /// of the first widget to can select first value of the next create operation
153   /// \param thePreviousAttributeID an index of the previous attribute to set focus to this widget
154   /// \return true if it is started
155   bool startInternalEdit(const std::string& thePreviousAttributeID);
156
157   /// Disconnects this manager from operation signals, deactivate selection of the first control
158   /// in the viewer.
159   void beforeStopInternalEdit();
160
161   /// Commits the current operation and launches a new with the commited operation feature index
162   void restartOperation();
163
164   /// Creates an internal feature and controls to process it
165   void createInternalFeature();
166
167   /// A pair method for an internal creation to remove it and clear all created controls
168   void deleteInternalFeature();
169
170   /// Breaks sequense of automatically resterted operations
171   void resetFlags();
172
173   /// Copy some feature specific attributes from the source to a new feature
174   /// This is type for Circle and Arc features
175   /// \param theSourceFeature a source feature
176   /// \param theNewFeature a new feature
177   /// \param theSketch an active sketch
178   /// \param isTemporary is used to do not create additional features(e.g. coicidence for line)
179   /// \return true is something is copied
180   static bool copyReetntrantAttributes(const FeaturePtr& theSourceFeature,
181                                       const FeaturePtr& theNewFeature,
182                                       const std::shared_ptr<ModelAPI_CompositeFeature>& theSketch,
183                                       const bool isTemporary = false);
184
185   /// Checks whethe the feature of the given operation has kind an arc and the arc type is tangent
186   bool isTangentArc(ModuleBase_Operation* theOperation,
187                     const std::shared_ptr<ModelAPI_CompositeFeature>& /*theSketch*/) const;
188
189   /// Accept All action is enabled if an internal edit is started.
190   /// It updates the state of the button
191   void updateAcceptAllAction();
192
193   /// Returns the workshop
194   XGUI_Workshop* workshop() const;
195
196   /// Returns the workshop module
197   PartSet_Module* module() const;
198
199 private:
200   ModuleBase_IWorkshop* myWorkshop; /// the workshop
201
202   RestartingMode myRestartingMode;  /// automatical restarting mode flag
203   bool myIsFlagsBlocked; /// true when reset of flags should not be perfromed
204   bool myIsInternalEditOperation; /// true when the 'internal' edit is started
205
206   FeaturePtr myPreviousFeature; /// feature of the previous operation, which is restarted
207   FeaturePtr myInternalFeature;
208   QWidget* myInternalWidget;
209   ModuleBase_ModelWidget* myInternalActiveWidget;
210   std::string myNoMoreWidgetsAttribute;
211
212   std::shared_ptr<Events_Message> myReentrantMessage; /// message obtained by operation restart
213   ObjectPtr mySelectedObject; /// cashed selected object
214   std::shared_ptr<ModelAPI_Attribute> mySelectedAttribute; /// cashed selected attribute
215   std::shared_ptr<GeomAPI_Pnt2d> myClickedSketchPoint; /// cashed clicked point
216 };
217
218 #endif