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