]> Shamusworld >> Repos - architektonas/blob - src/actions/actiondrawlineangle.cpp
53edc1fa723185942d31a0b61dce46ae9f5397b0
[architektonas] / src / actions / actiondrawlineangle.cpp
1 // actiondrawlineangle.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 // JLH  06/03/2010  Moved implementation from header to this file
14 //
15
16 #include "actiondrawlineangle.h"
17
18 #include "rs_commandevent.h"
19 #include "rs_dialogfactory.h"
20 #include "graphicview.h"
21 #include "rs_preview.h"
22
23 ActionDrawLineAngle::ActionDrawLineAngle(RS_EntityContainer & container, GraphicView & graphicView, double angle, bool fixedAngle):
24         ActionInterface("Draw lines with given angle",
25                 container, graphicView)
26 {
27         this->angle = angle;
28         length = 1.0;
29         snpPoint = 0;
30         this->fixedAngle = fixedAngle;
31         pos = Vector(false);
32         reset();
33 }
34
35 ActionDrawLineAngle::~ActionDrawLineAngle()
36 {
37 }
38
39 /*virtual*/ RS2::ActionType ActionDrawLineAngle::rtti()
40 {
41         return RS2::ActionDrawLineAngle;
42 }
43
44 void ActionDrawLineAngle::reset()
45 {
46         data = RS_LineData(Vector(false), Vector(false));
47 }
48
49 void ActionDrawLineAngle::init(int status)
50 {
51         ActionInterface::init(status);
52
53         reset();
54 }
55
56 void ActionDrawLineAngle::trigger()
57 {
58         ActionInterface::trigger();
59
60         preparePreview();
61         RS_Line * line = new RS_Line(container, data);
62         line->setLayerToActive();
63         line->setPenToActive();
64         container->addEntity(line);
65
66         // upd. undo list:
67         if (document)
68         {
69                 document->startUndoCycle();
70                 document->addUndoable(line);
71                 document->endUndoCycle();
72         }
73
74         deleteSnapper();
75         graphicView->moveRelativeZero(Vector(0.0, 0.0));
76         graphicView->drawEntity(line);
77         graphicView->moveRelativeZero(data.startpoint);
78         RS_DEBUG->print("ActionDrawLineAngle::trigger(): line added: %d",
79                 line->getId());
80 }
81
82 void ActionDrawLineAngle::mouseMoveEvent(QMouseEvent * e)
83 {
84         RS_DEBUG->print("ActionDrawLineAngle::mouseMoveEvent begin");
85
86         if (getStatus() == SetPos)
87         {
88                 pos = snapPoint(e);
89                 deletePreview();
90                 clearPreview();
91                 preparePreview();
92 //              preview->addEntity(new RS_Line(preview, data));
93                 drawPreview();
94         }
95
96         RS_DEBUG->print("ActionDrawLineAngle::mouseMoveEvent end");
97 }
98
99 void ActionDrawLineAngle::mouseReleaseEvent(QMouseEvent * e)
100 {
101         if (e->button() == Qt::LeftButton)
102         {
103                 if (getStatus() == SetPos)
104                 {
105                         Vector ce(snapPoint(e));
106                         coordinateEvent(&ce);
107                 }
108         }
109         else if (e->button() == Qt::RightButton)
110         {
111                 deletePreview();
112                 deleteSnapper();
113                 init(getStatus() - 1);
114         }
115 }
116
117 void ActionDrawLineAngle::preparePreview()
118 {
119         Vector p1, p2;
120
121         // End:
122         if (snpPoint == 2)
123                 p2.setPolar(length * -1, angle);
124         else
125                 p2.setPolar(length, angle);
126
127         // Middle:
128         if (snpPoint == 1)
129                 p1 = pos - (p2 / 2);
130         else
131                 p1 = pos;
132
133         p2 += p1;
134         data = RS_LineData(p1, p2);
135 }
136
137 void ActionDrawLineAngle::coordinateEvent(Vector * e)
138 {
139         if (e == NULL)
140                 return;
141
142         switch (getStatus())
143         {
144         case SetPos:
145                 pos = *e;
146                 trigger();
147                 break;
148
149         default:
150                 break;
151         }
152 }
153
154 void ActionDrawLineAngle::commandEvent(RS_CommandEvent * e)
155 {
156         QString c = e->getCommand().toLower();
157
158         if (checkCommand("help", c))
159         {
160                 RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
161                         + getAvailableCommands().join(", "));
162                 return;
163         }
164
165         switch (getStatus())
166         {
167         case SetPos:
168
169                 if (!fixedAngle && checkCommand("angle", c))
170                 {
171                         deleteSnapper();
172                         deletePreview();
173                         clearPreview();
174                         setStatus(SetAngle);
175                 }
176                 else if (checkCommand("length", c))
177                 {
178                         deleteSnapper();
179                         deletePreview();
180                         clearPreview();
181                         setStatus(SetLength);
182                 }
183                 break;
184
185         case SetAngle: {
186                 bool ok;
187                 double a = RS_Math::eval(c, &ok);
188
189                 if (ok == true)
190                         angle = RS_Math::deg2rad(a);
191                 else
192                         RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
193                 RS_DIALOGFACTORY->requestOptions(this, true, true);
194                 setStatus(SetPos);
195         }
196         break;
197
198         case SetLength: {
199                 bool ok;
200                 double l = RS_Math::eval(c, &ok);
201
202                 if (ok == true)
203                         length = l;
204                 else
205                         RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
206                 RS_DIALOGFACTORY->requestOptions(this, true, true);
207                 setStatus(SetPos);
208         }
209         break;
210
211         default:
212                 break;
213         }
214 }
215
216 QStringList ActionDrawLineAngle::getAvailableCommands()
217 {
218         QStringList cmd;
219
220         switch (getStatus())
221         {
222         case SetPos:
223
224                 if (!fixedAngle)
225                         cmd += command("angle");
226                 cmd += command("length");
227                 break;
228
229         default:
230                 break;
231         }
232
233         return cmd;
234 }
235
236 void ActionDrawLineAngle::updateMouseButtonHints()
237 {
238         switch (getStatus())
239         {
240         case SetPos:
241                 RS_DIALOGFACTORY->updateMouseWidget(tr("Specify position"),
242                         tr("Cancel"));
243                 break;
244
245         case SetAngle:
246                 RS_DIALOGFACTORY->updateMouseWidget(tr("Enter angle:"), tr("Back"));
247                 break;
248
249         case SetLength:
250                 RS_DIALOGFACTORY->updateMouseWidget(tr("Enter length:"), tr("Back"));
251                 break;
252
253         default:
254                 break;
255         }
256 }
257
258 void ActionDrawLineAngle::showOptions()
259 {
260         ActionInterface::showOptions();
261
262         RS_DIALOGFACTORY->requestOptions(this, true);
263 }
264
265 void ActionDrawLineAngle::hideOptions()
266 {
267         ActionInterface::hideOptions();
268
269         RS_DIALOGFACTORY->requestOptions(this, false);
270 }
271
272 void ActionDrawLineAngle::updateMouseCursor()
273 {
274         graphicView->setMouseCursor(RS2::CadCursor);
275 }
276
277 void ActionDrawLineAngle::updateToolBar()
278 {
279         if (!isFinished())
280                 RS_DIALOGFACTORY->requestToolBar(RS2::ToolBarSnap);
281         else
282                 RS_DIALOGFACTORY->requestToolBar(RS2::ToolBarLines);
283 }
284
285 void ActionDrawLineAngle::setSnapPoint(int sp)
286 {
287         snpPoint = sp;
288 }
289
290 int ActionDrawLineAngle::getSnapPoint()
291 {
292         return snpPoint;
293 }
294
295 void ActionDrawLineAngle::setAngle(double a)
296 {
297         angle = a;
298 }
299
300 double ActionDrawLineAngle::getAngle()
301 {
302         return angle;
303 }
304
305 void ActionDrawLineAngle::setLength(double l)
306 {
307         length = l;
308 }
309
310 double ActionDrawLineAngle::getLength()
311 {
312         return length;
313 }
314
315 bool ActionDrawLineAngle::hasFixedAngle()
316 {
317         return fixedAngle;
318 }