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