]> SALOME platform Git repositories - modules/shaper.git/blob - src/PartSet/PartSet_OperationEditLine.cpp
Salome HOME
561ae86e3a5718fa351629d7897f0c2a9c966ba1
[modules/shaper.git] / src / PartSet / PartSet_OperationEditLine.cpp
1 // File:        PartSet_OperationEditLine.h
2 // Created:     05 May 2014
3 // Author:      Natalia ERMOLAEVA
4
5 #include <PartSet_OperationEditLine.h>
6 #include <PartSet_Tools.h>
7 #include <PartSet_OperationSketch.h>
8
9 #include <ModuleBase_OperationDescription.h>
10
11 #include <XGUI_ViewerPrs.h>
12
13 #include <SketchPlugin_Feature.h>
14 #include <GeomDataAPI_Point2D.h>
15 #include <ModelAPI_Data.h>
16 #include <ModelAPI_Document.h>
17
18 #include <Model_Events.h>
19
20 #include <Events_Loop.h>
21
22 #include <SketchPlugin_Line.h>
23
24 #include <V3d_View.hxx>
25
26 #ifdef _DEBUG
27 #include <QDebug>
28 #endif
29
30 #include <QMouseEvent>
31
32 using namespace std;
33
34 PartSet_OperationEditLine::PartSet_OperationEditLine(const QString& theId,
35                                                   QObject* theParent,
36                                               boost::shared_ptr<ModelAPI_Feature> theFeature)
37 : PartSet_OperationSketchBase(theId, theParent), mySketch(theFeature)
38 {
39 }
40
41 PartSet_OperationEditLine::~PartSet_OperationEditLine()
42 {
43 }
44
45 bool PartSet_OperationEditLine::isGranted(ModuleBase_IOperation* theOperation) const
46 {
47   return theOperation->getDescription()->operationId().toStdString() == PartSet_OperationSketch::Type();
48 }
49
50 std::list<int> PartSet_OperationEditLine::getSelectionModes(boost::shared_ptr<ModelAPI_Feature> theFeature) const
51 {
52   return PartSet_OperationSketchBase::getSelectionModes(theFeature);
53 }
54
55 void PartSet_OperationEditLine::init(boost::shared_ptr<ModelAPI_Feature> theFeature,
56                                      const std::list<XGUI_ViewerPrs>& theSelected,
57                                      const std::list<XGUI_ViewerPrs>& theHighlighted)
58 {
59   setFeature(theFeature);
60
61   if (!theHighlighted.empty()) {
62     // if there is highlighted object, we check whether it is in the list of selected objects
63     // in that case this object is a handle of the moved lines. If there no such object in the selection,
64     // the hightlighted object should moved and the selection is skipped. The skipped selection will be
65     // deselected in the viewer by blockSelection signal in the startOperation method.
66     bool isSelected = false;
67     std::list<XGUI_ViewerPrs>::const_iterator anIt = theSelected.begin(), aLast = theSelected.end();
68     for (; anIt != aLast && !isSelected; anIt++) {
69       isSelected = (*anIt).feature() == feature();
70     }
71     if (!isSelected)
72       myFeatures = theHighlighted;
73     else
74       myFeatures = theSelected;
75   }
76   else
77     myFeatures = theSelected;
78 }
79
80 boost::shared_ptr<ModelAPI_Feature> PartSet_OperationEditLine::sketch() const
81 {
82   return mySketch;
83 }
84
85 void PartSet_OperationEditLine::mousePressed(QMouseEvent* theEvent, Handle(V3d_View) theView,
86                                              const std::list<XGUI_ViewerPrs>& /*theSelected*/,
87                                              const std::list<XGUI_ViewerPrs>& theHighlighted)
88 {
89   if (myFeatures.size() == 1)
90   {
91     boost::shared_ptr<ModelAPI_Feature> aFeature;
92     if (!theHighlighted.empty())
93       aFeature = theHighlighted.front().feature();
94
95     if (aFeature && aFeature == feature()) { // continue the feature edit
96       blockSelection(true);
97     }
98     else {
99       commit();
100       emit featureConstructed(feature(), FM_Deactivation);
101       if (aFeature) {
102         emit launchOperation(PartSet_OperationEditLine::Type(), aFeature);
103       }
104     }
105   }
106 }
107
108 void PartSet_OperationEditLine::mouseMoved(QMouseEvent* theEvent, Handle(V3d_View) theView)
109 {
110   if (!(theEvent->buttons() &  Qt::LeftButton))
111     return;
112
113   gp_Pnt aPoint = PartSet_Tools::ConvertClickToPoint(theEvent->pos(), theView);
114
115   if (myCurPoint.myIsInitialized) {
116     double aCurX, aCurY;
117     PartSet_Tools::ConvertTo2D(myCurPoint.myPoint, sketch(), theView, aCurX, aCurY);
118
119     double aX, anY;
120     PartSet_Tools::ConvertTo2D(aPoint, sketch(), theView, aX, anY);
121
122     double aDeltaX = aX - aCurX;
123     double aDeltaY = anY - aCurY;
124
125     moveLinePoint(feature(), aDeltaX, aDeltaY, LINE_ATTR_START);
126     moveLinePoint(feature(), aDeltaX, aDeltaY, LINE_ATTR_END);
127
128     std::list<XGUI_ViewerPrs>::const_iterator anIt = myFeatures.begin(), aLast = myFeatures.end();
129     for (; anIt != aLast; anIt++) {
130       boost::shared_ptr<ModelAPI_Feature> aFeature = (*anIt).feature();
131       if (!aFeature || aFeature == feature())
132         continue;
133       moveLinePoint(aFeature, aDeltaX, aDeltaY, LINE_ATTR_START);
134       moveLinePoint(aFeature, aDeltaX, aDeltaY, LINE_ATTR_END);
135     }
136   }
137   sendFeatures();
138
139   myCurPoint.setPoint(aPoint);
140 }
141
142 void PartSet_OperationEditLine::mouseReleased(QMouseEvent* theEvent, Handle(V3d_View) theView,
143                                               const std::list<XGUI_ViewerPrs>& /*theSelected*/,
144                                               const std::list<XGUI_ViewerPrs>& /*theHighlighted*/)
145 {
146   std::list<XGUI_ViewerPrs> aFeatures = myFeatures;
147   if (myFeatures.size() == 1) {
148     blockSelection(false);
149   }
150   else {
151     commit();
152     std::list<XGUI_ViewerPrs>::const_iterator anIt = aFeatures.begin(), aLast = aFeatures.end();
153     for (; anIt != aLast; anIt++) {
154       boost::shared_ptr<ModelAPI_Feature> aFeature = (*anIt).feature();
155       if (aFeature)
156         emit featureConstructed(aFeature, FM_Deactivation);
157     }
158   }
159 }
160
161 void PartSet_OperationEditLine::startOperation()
162 {
163   // do nothing in order to do not create a new feature
164   emit multiSelectionEnabled(false);
165
166   blockSelection(true);
167
168   myCurPoint.clear();
169 }
170
171 void PartSet_OperationEditLine::stopOperation()
172 {
173   emit multiSelectionEnabled(true);
174
175   blockSelection(false, myFeatures.size() > 1);
176
177   myFeatures.clear();
178 }
179
180 void PartSet_OperationEditLine::blockSelection(bool isBlocked, const bool isRestoreSelection)
181 {
182   if (isBlocked) {
183     emit setSelection(std::list<XGUI_ViewerPrs>());
184     emit stopSelection(myFeatures, true);
185   }
186   else {
187     emit stopSelection(myFeatures, false);
188     if (isRestoreSelection)
189       emit setSelection(myFeatures);
190   }
191 }
192
193 boost::shared_ptr<ModelAPI_Feature> PartSet_OperationEditLine::createFeature()
194 {
195   // do nothing in order to do not create a new feature
196   return boost::shared_ptr<ModelAPI_Feature>();
197 }
198
199 void PartSet_OperationEditLine::moveLinePoint(boost::shared_ptr<ModelAPI_Feature> theFeature,
200                                                double theDeltaX, double theDeltaY,
201                                                const std::string& theAttribute)
202 {
203   if (!theFeature || theFeature->getKind() != "SketchLine")
204     return;
205
206   boost::shared_ptr<ModelAPI_Data> aData = theFeature->data();
207   boost::shared_ptr<GeomDataAPI_Point2D> aPoint =
208         boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(theAttribute));
209
210   aPoint->setValue(aPoint->x() + theDeltaX, aPoint->y() + theDeltaY);
211 }
212
213 void PartSet_OperationEditLine::sendFeatures()
214 {
215   std::list<boost::shared_ptr<ModelAPI_Feature> > aFeatures;
216   std::list<XGUI_ViewerPrs>::const_iterator anIt = myFeatures.begin(), aLast = myFeatures.end();
217   for (; anIt != aLast; anIt++) {
218     boost::shared_ptr<ModelAPI_Feature> aFeature = (*anIt).feature();
219     if (!aFeature || aFeature == feature())
220       continue;
221   }
222
223   static Events_ID aModuleEvent = Events_Loop::eventByName("PartSetEditEvent");
224   Model_FeaturesMovedMessage aMessage;
225   aMessage.setFeatures(aFeatures);
226   Events_Loop::loop()->send(aMessage);
227 }
228