1 // Copyright (C) 2014-2019 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #ifndef PartSet_SketcherReentrantMgr_H
21 #define PartSet_SketcherReentrantMgr_H
25 #include <ModelAPI_Feature.h>
32 class ModuleBase_IWorkshop;
33 class ModuleBase_Operation;
34 class ModuleBase_ModelWidget;
35 class ModuleBase_IViewWindow;
37 class ModelAPI_CompositeFeature;
43 class ModuleBase_ViewerPrs;
45 class ModelAPI_Attribute;
48 /// \ingroup PartSet_SketcherReentrantMgr
49 /// It provides reentrant create operations in sketch, that is when all inputs are valid,
50 /// automatic validation of the creation and switch the created entity to edit mode
51 /// ('internal' edit operation), with the ability to simultaneously create the next entity
52 /// of same type (re-entrance of the operation).
53 /// OK valids the current edition and exits from the operation (no re-entrance).
54 /// Cancel removes (undo) the entity currently edited and
55 /// exits from the operation (no re-entrance).
56 class PARTSET_EXPORT PartSet_SketcherReentrantMgr : public QObject
60 /// Enumeration to specify the restart operation properties.
62 RM_None, /// the operation should not be restarted
63 RM_Forbided, /// the operation should not be restarted after there is no active widget
64 RM_LastFeatureUsed, /// the operation is restarted and use
65 /// the previous feature for own initialization
66 RM_EmptyFeatureUsed /// the operation is restarted and does not use the previous feature
71 /// \param theWorkshop a workshop instance
72 PartSet_SketcherReentrantMgr(ModuleBase_IWorkshop* theWorkshop);
73 virtual ~PartSet_SketcherReentrantMgr();
76 /// Return true if the current edit operation is an internal
77 bool isInternalEditActive() const;
79 /// Stop internal edit if the operation feature is invalid
80 void updateInternalEditActiveState();
82 /// if the internal flags allow it and the manager is active, it starts an internal edit operation
83 /// for the created operation.
84 /// \param thePreviousAttributeID an index of the previous active attribute
85 //bool restartOperation(const std::string& thePreviousAttributeID);
86 bool processEnter(const std::string& thePreviousAttributeID);
88 /// Resets the internal flags
89 /// \param theOperation a started operation
90 void operationStarted(ModuleBase_Operation* theOperation);
92 /// Resets the internal flags
93 /// \param theOperation a started operation
94 /// \return state whether the internal edit operation was active
95 bool operationCommitted(ModuleBase_Operation* theOperation);
97 /// Resets the internal flags
98 /// \param theOperation a started operation
99 void operationAborted(ModuleBase_Operation* theOperation);
101 /// Return true if the manager processes the mouse move event
102 /// It happens if the current operation is an internal edit operation and the first
103 /// control can be filled by the mouse move event. The operation is restarted.
104 /// \return true if operation is committed.
105 bool processMouseMoved(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent);
107 /// Return true if the manager processes the mouse press event
108 /// \return true if the current operation is an internal edit operation.
109 bool processMousePressed(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent);
111 /// Return true if the manager processes the mouse enter event
112 /// It happens if the current operation is an internal edit operation.
113 /// The operation is restarted. If the first widget of the started operation is
114 /// the point 2d, it processes this mouse event
115 /// \return true if operation is committed.
116 bool processMouseReleased(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent);
118 /// It is called by the current operation filling with the preselection.
119 /// Returns false if the reentrant mode of the operation is not empty.
120 bool canBeCommittedByPreselection();
122 /// Fills reentrant message during restarting operation
123 /// \param theMessage reentrant message
124 void setReentrantMessage(const std::shared_ptr<Events_Message>& theMessage)
125 { myReentrantMessage = theMessage; }
127 /// Returnss reentrant message
128 std::shared_ptr<Events_Message> reentrantMessage() const { return myReentrantMessage; }
130 /// Put current selection into reentrant message
131 /// \param theMessage a message of reentrant operation
132 void setReentrantPreSelection(const std::shared_ptr<Events_Message>& theMessage);
134 bool isAutoConstraints() const { return myIsAutoConstraints; }
138 /// The slot is called when user checks "Automatic constraints" button
139 /// \param isOn a state of the check box
140 void onAutoConstraints(bool isOn);
144 /// SLOT, that is called by a widget activating in the property panel
145 /// If the 'internal' edit operation is started, it activates the first widget selection
146 //void onWidgetActivated();
148 /// SLOT, that is called by no more widget signal emitted by property panel
149 /// Start an internal edit operation or, if the internal flag is forbided, commits
150 /// the current operation
151 /// \param thePreviousAttributeID an index of the previous active attribute
152 void onNoMoreWidgets(const std::string& thePreviousAttributeID);
154 /// Processing of vertex selected. Set an internal reentrant flag to forbiddent state if
155 /// the current feature is a line and there are not obligate widgets anymore
156 void onVertexSelected();
158 /// Listens to the signal about the modification of the values
159 /// have been done in the property panel. If the manager has active edit operation and
160 /// the active widget does not process the modification of value, the manager will
161 /// restart current operation and fill a new feature attribute by the value of current
163 void onAfterValuesChangedInPropertyPanel();
165 /// Deactivates selection and filters of the first operation widget if it is an internal
167 void onBeforeStopped();
170 /// Returns true if the current operation is a sketch or a nested sketch operation
171 bool isActiveMgr() const;
173 /// Sets the focus to the last control of the property panel and activates selection
174 /// of the first widget to can select first value of the next create operation
175 /// \param thePreviousAttributeID an index of the previous attribute to set focus to this widget
176 /// \return true if it is started
177 bool startInternalEdit(const std::string& thePreviousAttributeID);
179 /// Disconnects this manager from operation signals, deactivate selection of the first control
181 void beforeStopInternalEdit();
183 /// Commits the current operation and launches a new with the commited operation feature index
184 void restartOperation();
186 /// Creates an internal feature and controls to process it
187 void createInternalFeature();
189 /// A pair method for an internal creation to remove it and clear all created controls
190 void deleteInternalFeature();
192 /// Breaks sequense of automatically resterted operations
195 /// Copy some feature specific attributes from the source to a new feature
196 /// This is type for Circle and Arc features
197 /// \param theSourceFeature a source feature
198 /// \param theNewFeature a new feature
199 /// \param theSketch an active sketch
200 /// \param isTemporary is used to do not create additional features(e.g. coicidence for line)
201 /// \return true is something is copied
202 static bool copyReetntrantAttributes(const FeaturePtr& theSourceFeature,
203 const FeaturePtr& theNewFeature,
204 const std::shared_ptr<ModelAPI_CompositeFeature>& theSketch,
205 const bool isTemporary = false);
207 /// Checks whethe the feature of the given operation has kind an arc and the arc type is tangent
208 bool isTangentArc(ModuleBase_Operation* theOperation,
209 const std::shared_ptr<ModelAPI_CompositeFeature>& /*theSketch*/) const;
211 /// Accept All action is enabled if an internal edit is started.
212 /// It updates the state of the button
213 void updateAcceptAllAction();
215 /// Returns the workshop
216 XGUI_Workshop* workshop() const;
218 /// Returns the workshop module
219 PartSet_Module* module() const;
221 void setInternalActiveWidget(ModuleBase_ModelWidget* theWidget);
223 void addConstraints(const FeaturePtr& theFeature);
226 ModuleBase_IWorkshop* myWorkshop; /// the workshop
228 RestartingMode myRestartingMode; /// automatical restarting mode flag
229 bool myIsFlagsBlocked; /// true when reset of flags should not be perfromed
230 bool myIsInternalEditOperation; /// true when the 'internal' edit is started
232 FeaturePtr myPreviousFeature; /// feature of the previous operation, which is restarted
233 FeaturePtr myInternalFeature;
234 QWidget* myInternalWidget;
235 std::string myNoMoreWidgetsAttribute;
237 std::shared_ptr<Events_Message> myReentrantMessage; /// message obtained by operation restart
238 ObjectPtr mySelectedObject; /// cashed selected object
239 std::shared_ptr<ModelAPI_Attribute> mySelectedAttribute; /// cashed selected attribute
240 std::shared_ptr<GeomAPI_Pnt2d> myClickedSketchPoint; /// cashed clicked point
242 bool myIsAutoConstraints;