]> Shamusworld >> Repos - architektonas/blob - src/actions/actiondimlinear.cpp
In the middle of major refactoring...
[architektonas] / src / actions / actiondimlinear.cpp
1 // 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 "actiondimlinear.h"
16
17 #include "rs_commandevent.h"
18 #include "rs_constructionline.h"
19 #include "rs_dialogfactory.h"
20 #include "graphicview.h"
21 #include "rs_preview.h"
22
23 /**
24  * Constructor.
25  *
26  * @param angle Initial angle in rad.
27  * @param fixedAngle true: The user can't change the angle.
28  *                   false: The user can change the angle in a option widget.
29  */
30 ActionDimLinear::ActionDimLinear(RS_EntityContainer & container, GraphicView & graphicView, double angle, bool fixedAngle):
31         ActionDimension("Draw linear dimensions", container, graphicView)
32 {
33         edata.angle = angle;
34         this->fixedAngle = fixedAngle;
35         lastStatus = SetExtPoint1;
36         reset();
37 }
38
39 ActionDimLinear::~ActionDimLinear()
40 {
41 }
42
43 /*virtual*/ RS2::ActionType ActionDimLinear::rtti()
44 {
45         return RS2::ActionDimLinear;
46 }
47
48 void ActionDimLinear::reset()
49 {
50         ActionDimension::reset();
51         edata = RS_DimLinearData(Vector(false), Vector(false), (fixedAngle ? edata.angle : 0.0), 0.0);
52
53         if (RS_DIALOGFACTORY != NULL)
54                 RS_DIALOGFACTORY->requestOptions(this, true, true);
55 }
56
57 void ActionDimLinear::trigger()
58 {
59         ActionDimension::trigger();
60         preparePreview();
61         RS_DimLinear * dim = new RS_DimLinear(container, data, edata);
62         dim->setLayerToActive();
63         dim->setPenToActive();
64         dim->update();
65         container->addEntity(dim);
66
67         // upd. undo list:
68         if (document != NULL)
69         {
70                 document->startUndoCycle();
71                 document->addUndoable(dim);
72                 document->endUndoCycle();
73         }
74
75         deleteSnapper();
76         Vector rz = graphicView->getRelativeZero();
77         graphicView->moveRelativeZero(Vector(0.0, 0.0));
78         graphicView->drawEntity(dim);
79         graphicView->moveRelativeZero(rz);
80         drawSnapper();
81
82         RS_DEBUG->print("ActionDimLinear::trigger(): dim added: %d", dim->getId());
83 }
84
85 void ActionDimLinear::preparePreview()
86 {
87         Vector dirV;
88         dirV.setPolar(100.0, edata.angle + M_PI / 2.0);
89
90         RS_ConstructionLine cl(
91                 NULL, RS_ConstructionLineData(
92                         edata.extensionPoint2,
93                         edata.extensionPoint2 + dirV));
94
95         data.definitionPoint =
96                 cl.getNearestPointOnEntity(data.definitionPoint);
97 }
98
99 void ActionDimLinear::mouseMoveEvent(QMouseEvent * e)
100 {
101         RS_DEBUG->print("ActionDimLinear::mouseMoveEvent begin");
102
103         Vector mouse = snapPoint(e);
104
105         switch (getStatus())
106         {
107         case SetExtPoint1:
108                 break;
109
110         case SetExtPoint2:
111
112                 if (edata.extensionPoint1.valid)
113                 {
114                         deletePreview();
115                         clearPreview();
116 //                      preview->addEntity(new RS_Line(preview,
117 //                              RS_LineData(edata.extensionPoint1, 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("ActionDimLinear::mouseMoveEvent end");
141 }
142
143 void ActionDimLinear::mouseReleaseEvent(QMouseEvent * e)
144 {
145         if (e->button() == Qt::LeftButton)
146         {
147                 Vector ce(snapPoint(e));
148                 coordinateEvent(&ce);
149         }
150         else if (e->button() == Qt::RightButton)
151         {
152                 deletePreview();
153                 deleteSnapper();
154                 init(getStatus() - 1);
155         }
156 }
157
158 void 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 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 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 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 ActionDimLinear::showOptions()
306 {
307         ActionInterface::showOptions();
308
309         if (RS_DIALOGFACTORY != NULL)
310                 RS_DIALOGFACTORY->requestOptions(this, true, true);
311 }
312
313 void ActionDimLinear::hideOptions()
314 {
315         ActionInterface::hideOptions();
316
317         if (RS_DIALOGFACTORY != NULL)
318                 RS_DIALOGFACTORY->requestOptions(this, false);
319 }
320
321 double ActionDimLinear::getAngle()
322 {
323         return edata.angle;
324 }
325
326 void ActionDimLinear::setAngle(double a)
327 {
328         edata.angle = a;
329 }
330
331 bool ActionDimLinear::hasFixedAngle()
332 {
333         return fixedAngle;
334 }