]> Shamusworld >> Repos - architektonas/blob - src/actions/rs_actiondimlinear.cpp
db10186569f96ac01a28bef35988ac8967c8772e
[architektonas] / src / actions / rs_actiondimlinear.cpp
1 // rs_actiondimlinear.cpp
2 //
3 // Part of the Architektonas Project
4 // Originally part of QCad Community Edition by Andrew Mustun
5 // Extensively rewritten and refactored by James L. Hammons
6 // (C) 2010 Underground Software
7 //
8 // JLH = James L. Hammons <jlhamm@acm.org>
9 //
10 // Who  When        What
11 // ---  ----------  -----------------------------------------------------------
12 // JLH  05/22/2010  Added this text. :-)
13 //
14
15 #include "rs_actiondimlinear.h"
16
17 #include "rs_constructionline.h"
18 #include "rs_dialogfactory.h"
19 #include "rs_graphicview.h"
20 #include "rs_preview.h"
21
22 /**
23  * Constructor.
24  *
25  * @param angle Initial angle in rad.
26  * @param fixedAngle true: The user can't change the angle.
27  *                   false: The user can change the angle in a option widget.
28  */
29 RS_ActionDimLinear::RS_ActionDimLinear(RS_EntityContainer & container, RS_GraphicView & graphicView, double angle, bool fixedAngle):
30         RS_ActionDimension("Draw linear dimensions", container, graphicView)
31 {
32         edata.angle = angle;
33         this->fixedAngle = fixedAngle;
34         lastStatus = SetExtPoint1;
35         reset();
36 }
37
38 RS_ActionDimLinear::~RS_ActionDimLinear()
39 {
40 }
41
42 /*virtual*/ RS2::ActionType RS_ActionDimLinear::rtti()
43 {
44         return RS2::ActionDimLinear;
45 }
46
47 void RS_ActionDimLinear::reset()
48 {
49         RS_ActionDimension::reset();
50         edata = RS_DimLinearData(Vector(false), Vector(false), (fixedAngle ? edata.angle : 0.0), 0.0);
51
52         if (RS_DIALOGFACTORY != NULL)
53                 RS_DIALOGFACTORY->requestOptions(this, true, true);
54 }
55
56 void RS_ActionDimLinear::trigger()
57 {
58         RS_ActionDimension::trigger();
59         preparePreview();
60         RS_DimLinear * dim = new RS_DimLinear(container, data, edata);
61         dim->setLayerToActive();
62         dim->setPenToActive();
63         dim->update();
64         container->addEntity(dim);
65
66         // upd. undo list:
67         if (document != NULL)
68         {
69                 document->startUndoCycle();
70                 document->addUndoable(dim);
71                 document->endUndoCycle();
72         }
73
74         deleteSnapper();
75         Vector rz = graphicView->getRelativeZero();
76         graphicView->moveRelativeZero(Vector(0.0, 0.0));
77         graphicView->drawEntity(dim);
78         graphicView->moveRelativeZero(rz);
79         drawSnapper();
80
81         RS_DEBUG->print("RS_ActionDimLinear::trigger(): dim added: %d", dim->getId());
82 }
83
84 void RS_ActionDimLinear::preparePreview()
85 {
86         Vector dirV;
87         dirV.setPolar(100.0, edata.angle + M_PI / 2.0);
88
89         RS_ConstructionLine cl(
90                 NULL, RS_ConstructionLineData(
91                         edata.extensionPoint2,
92                         edata.extensionPoint2 + dirV));
93
94         data.definitionPoint =
95                 cl.getNearestPointOnEntity(data.definitionPoint);
96 }
97
98 void RS_ActionDimLinear::mouseMoveEvent(QMouseEvent * e)
99 {
100         RS_DEBUG->print("RS_ActionDimLinear::mouseMoveEvent begin");
101
102         Vector mouse = snapPoint(e);
103
104         switch (getStatus())
105         {
106         case SetExtPoint1:
107                 break;
108
109         case SetExtPoint2:
110
111                 if (edata.extensionPoint1.valid)
112                 {
113                         deletePreview();
114                         clearPreview();
115                         preview->addEntity(new RS_Line(preview,
116                                         RS_LineData(edata.extensionPoint1,
117                                                 mouse)));
118                         drawPreview();
119                 }
120                 break;
121
122         case SetDefPoint:
123
124                 if (edata.extensionPoint1.valid && edata.extensionPoint2.valid)
125                 {
126                         deletePreview();
127                         clearPreview();
128                         data.definitionPoint = mouse;
129
130                         preparePreview();
131
132                         RS_DimLinear * dim = new RS_DimLinear(preview, data, edata);
133                         dim->update();
134                         preview->addEntity(dim);
135                         drawPreview();
136                 }
137                 break;
138         }
139
140         RS_DEBUG->print("RS_ActionDimLinear::mouseMoveEvent end");
141 }
142
143 void RS_ActionDimLinear::mouseReleaseEvent(QMouseEvent * e)
144 {
145         if (RS2::qtToRsButtonState(e->button()) == RS2::LeftButton)
146         {
147                 Vector ce(snapPoint(e));
148                 coordinateEvent(&ce);
149         }
150         else if (RS2::qtToRsButtonState(e->button()) == RS2::RightButton)
151         {
152                 deletePreview();
153                 deleteSnapper();
154                 init(getStatus() - 1);
155         }
156 }
157
158 void RS_ActionDimLinear::coordinateEvent(Vector * e)
159 {
160         if (e == NULL)
161                 return;
162
163         Vector pos = *e;
164
165         switch (getStatus())
166         {
167         case SetExtPoint1:
168                 edata.extensionPoint1 = pos;
169                 graphicView->moveRelativeZero(pos);
170                 setStatus(SetExtPoint2);
171                 break;
172
173         case SetExtPoint2:
174                 edata.extensionPoint2 = pos;
175                 graphicView->moveRelativeZero(pos);
176                 setStatus(SetDefPoint);
177                 break;
178
179         case SetDefPoint:
180                 data.definitionPoint = pos;
181                 trigger();
182                 reset();
183                 setStatus(SetExtPoint1);
184                 break;
185
186         default:
187                 break;
188         }
189 }
190
191 void RS_ActionDimLinear::commandEvent(RS_CommandEvent * e)
192 {
193         QString c = e->getCommand().toLower();
194
195         if (checkCommand("help", c))
196         {
197                 if (RS_DIALOGFACTORY != NULL)
198                         RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
199                                 + getAvailableCommands().join(", "));
200                 return;
201         }
202
203         switch (getStatus())
204         {
205         case SetText:
206                 setText(c);
207
208                 if (RS_DIALOGFACTORY != NULL)
209                         RS_DIALOGFACTORY->requestOptions(this, true, true);
210                 graphicView->enableCoordinateInput();
211                 setStatus(lastStatus);
212                 break;
213
214         case SetAngle: {
215                 bool ok;
216                 double a = RS_Math::eval(c, &ok);
217
218                 if (ok == true)
219                         setAngle(RS_Math::deg2rad(a));
220                 else if (RS_DIALOGFACTORY != NULL)
221                         RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
222
223                 if (RS_DIALOGFACTORY != NULL)
224                         RS_DIALOGFACTORY->requestOptions(this, true, true);
225                 setStatus(lastStatus);
226         }
227         break;
228
229         default:
230                 lastStatus = (Status)getStatus();
231                 deleteSnapper();
232                 deletePreview();
233                 clearPreview();
234
235                 if (checkCommand("text", c))
236                 {
237                         graphicView->disableCoordinateInput();
238                         setStatus(SetText);
239                         return;
240                 }
241                 else if (!fixedAngle && (checkCommand("angle", c)))
242                         setStatus(SetAngle);
243                 break;
244         }
245 }
246
247 QStringList RS_ActionDimLinear::getAvailableCommands()
248 {
249         QStringList cmd;
250
251         switch (getStatus())
252         {
253         case SetExtPoint1:
254         case SetExtPoint2:
255         case SetDefPoint:
256                 cmd += command("text");
257
258                 if (!fixedAngle)
259                         cmd += command("angle");
260                 break;
261
262         default:
263                 break;
264         }
265
266         return cmd;
267 }
268
269 void RS_ActionDimLinear::updateMouseButtonHints()
270 {
271         if (RS_DIALOGFACTORY != NULL)
272         {
273                 switch (getStatus())
274                 {
275                 case SetExtPoint1:
276                         RS_DIALOGFACTORY->updateMouseWidget(
277                                 tr("Specify first extension line origin"), tr("Cancel"));
278                         break;
279
280                 case SetExtPoint2:
281                         RS_DIALOGFACTORY->updateMouseWidget(
282                                 tr("Specify second extension line origin"), tr("Back"));
283                         break;
284
285                 case SetDefPoint:
286                         RS_DIALOGFACTORY->updateMouseWidget(
287                                 tr("Specify dimension line location"), tr("Back"));
288                         break;
289
290                 case SetText:
291                         RS_DIALOGFACTORY->updateMouseWidget(tr("Enter dimension text:"), "");
292                         break;
293
294                 case SetAngle:
295                         RS_DIALOGFACTORY->updateMouseWidget(tr("Enter dimension line angle:"), "");
296                         break;
297
298                 default:
299                         RS_DIALOGFACTORY->updateMouseWidget("", "");
300                         break;
301                 }
302         }
303 }
304
305 void RS_ActionDimLinear::showOptions()
306 {
307         RS_ActionInterface::showOptions();
308
309         if (RS_DIALOGFACTORY != NULL)
310                 RS_DIALOGFACTORY->requestOptions(this, true, true);
311 }
312
313 void RS_ActionDimLinear::hideOptions()
314 {
315         RS_ActionInterface::hideOptions();
316
317         if (RS_DIALOGFACTORY != NULL)
318                 RS_DIALOGFACTORY->requestOptions(this, false);
319 }
320
321 double RS_ActionDimLinear::getAngle()
322 {
323         return edata.angle;
324 }
325
326 void RS_ActionDimLinear::setAngle(double a)
327 {
328         edata.angle = a;
329 }
330
331 bool RS_ActionDimLinear::hasFixedAngle()
332 {
333         return fixedAngle;
334 }
335