Salome HOME
Merge remote-tracking branch 'remotes/origin/master' into SolveSpace
[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>& thePresentations)
57 {
58   setFeature(theFeature);
59   myFeatures = thePresentations;
60 }
61
62 boost::shared_ptr<ModelAPI_Feature> PartSet_OperationEditLine::sketch() const
63 {
64   return mySketch;
65 }
66
67 void PartSet_OperationEditLine::mousePressed(QMouseEvent* theEvent, Handle(V3d_View) theView)
68 {
69   if (!(theEvent->buttons() &  Qt::LeftButton))
70     return;
71   gp_Pnt aPoint = PartSet_Tools::ConvertClickToPoint(theEvent->pos(), theView);
72   myCurPoint.setPoint(aPoint);
73 }
74
75 void PartSet_OperationEditLine::mouseMoved(QMouseEvent* theEvent, Handle(V3d_View) theView)
76 {
77   if (!(theEvent->buttons() &  Qt::LeftButton))
78     return;
79
80   gp_Pnt aPoint = PartSet_Tools::ConvertClickToPoint(theEvent->pos(), theView);
81
82   if (myCurPoint.myIsInitialized) {
83     double aCurX, aCurY;
84     PartSet_Tools::ConvertTo2D(myCurPoint.myPoint, sketch(), theView, aCurX, aCurY);
85
86     double aX, anY;
87     PartSet_Tools::ConvertTo2D(aPoint, sketch(), theView, aX, anY);
88
89     double aDeltaX = aX - aCurX;
90     double aDeltaY = anY - aCurY;
91
92     moveLinePoint(feature(), aDeltaX, aDeltaY, LINE_ATTR_START);
93     moveLinePoint(feature(), aDeltaX, aDeltaY, LINE_ATTR_END);
94
95     std::list<XGUI_ViewerPrs>::const_iterator anIt = myFeatures.begin(), aLast = myFeatures.end();
96     for (; anIt != aLast; anIt++) {
97       boost::shared_ptr<ModelAPI_Feature> aFeature = (*anIt).feature();
98       if (!aFeature || aFeature == feature())
99         continue;
100       moveLinePoint(aFeature, aDeltaX, aDeltaY, LINE_ATTR_START);
101       moveLinePoint(aFeature, aDeltaX, aDeltaY, LINE_ATTR_END);
102     }
103   }
104   sendFeatures();
105
106   myCurPoint.setPoint(aPoint);
107 }
108
109 void PartSet_OperationEditLine::mouseReleased(QMouseEvent* theEvent, Handle(V3d_View) theView,
110                                               const std::list<XGUI_ViewerPrs>& theSelected)
111 {
112   std::list<XGUI_ViewerPrs> aFeatures = myFeatures;
113   if (myFeatures.size() == 1) {
114     if (theSelected.empty())
115       return;
116
117     boost::shared_ptr<ModelAPI_Feature> aFeature = theSelected.front().feature();
118     commit();
119     emit launchOperation(PartSet_OperationEditLine::Type(), aFeature);
120   }
121   else {
122     commit();
123     std::list<XGUI_ViewerPrs>::const_iterator anIt = aFeatures.begin(), aLast = aFeatures.end();
124     for (; anIt != aLast; anIt++) {
125       boost::shared_ptr<ModelAPI_Feature> aFeature = (*anIt).feature();
126       if (aFeature)
127         emit featureConstructed(aFeature, FM_Deactivation);
128     }
129   }
130 }
131
132 void PartSet_OperationEditLine::startOperation()
133 {
134   // do nothing in order to do not create a new feature
135   emit multiSelectionEnabled(false);
136   emit setSelection(std::list<XGUI_ViewerPrs>());
137   emit stopSelection(myFeatures, true);
138   myCurPoint.clear();
139 }
140
141 void PartSet_OperationEditLine::stopOperation()
142 {
143   emit multiSelectionEnabled(true);
144   bool isSelectFeatures = myFeatures.size() > 1;
145   emit stopSelection(myFeatures, false);
146   if (isSelectFeatures)
147     emit setSelection(myFeatures);
148
149   myFeatures.clear();
150 }
151
152 boost::shared_ptr<ModelAPI_Feature> PartSet_OperationEditLine::createFeature()
153 {
154   // do nothing in order to do not create a new feature
155   return boost::shared_ptr<ModelAPI_Feature>();
156 }
157
158 void PartSet_OperationEditLine::moveLinePoint(boost::shared_ptr<ModelAPI_Feature> theFeature,
159                                                double theDeltaX, double theDeltaY,
160                                                const std::string& theAttribute)
161 {
162   if (!theFeature || theFeature->getKind() != "SketchLine")
163     return;
164
165   boost::shared_ptr<ModelAPI_Data> aData = theFeature->data();
166   boost::shared_ptr<GeomDataAPI_Point2D> aPoint =
167         boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(theAttribute));
168
169   aPoint->setValue(aPoint->x() + theDeltaX, aPoint->y() + theDeltaY);
170 }
171
172 void PartSet_OperationEditLine::sendFeatures()
173 {
174   std::list<boost::shared_ptr<ModelAPI_Feature> > aFeatures;
175   std::list<XGUI_ViewerPrs>::const_iterator anIt = myFeatures.begin(), aLast = myFeatures.end();
176   for (; anIt != aLast; anIt++) {
177     boost::shared_ptr<ModelAPI_Feature> aFeature = (*anIt).feature();
178     if (!aFeature || aFeature == feature())
179       continue;
180   }
181
182   static Events_ID aModuleEvent = Events_Loop::eventByName("PartSetEditEvent");
183   Model_FeaturesMovedMessage aMessage;
184   aMessage.setFeatures(aFeatures);
185   Events_Loop::loop()->send(aMessage);
186 }
187