]> Shamusworld >> Repos - architektonas/blob - src/actions/rs_actiondrawlineangle.cpp
cf2540150ce9afd28ebfbb1db8fe7c2e63fe1f3b
[architektonas] / src / actions / rs_actiondrawlineangle.cpp
1 // rs_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 "rs_actiondrawlineangle.h"
17
18 #include "rs_dialogfactory.h"
19 #include "rs_graphicview.h"
20 #include "rs_preview.h"
21
22 RS_ActionDrawLineAngle::RS_ActionDrawLineAngle(RS_EntityContainer & container, RS_GraphicView & graphicView, double angle, bool fixedAngle):
23         RS_PreviewActionInterface("Draw lines with given angle",
24                 container, graphicView)
25 {
26         this->angle = angle;
27         length = 1.0;
28         snpPoint = 0;
29         this->fixedAngle = fixedAngle;
30         pos = Vector(false);
31         reset();
32 }
33
34 RS_ActionDrawLineAngle::~RS_ActionDrawLineAngle()
35 {
36 }
37
38 /*virtual*/ RS2::ActionType RS_ActionDrawLineAngle::rtti()
39 {
40         return RS2::ActionDrawLineAngle;
41 }
42
43 void RS_ActionDrawLineAngle::reset()
44 {
45         data = RS_LineData(Vector(false), Vector(false));
46 }
47
48 void RS_ActionDrawLineAngle::init(int status)
49 {
50         RS_PreviewActionInterface::init(status);
51
52         reset();
53 }
54
55 void RS_ActionDrawLineAngle::trigger()
56 {
57         RS_PreviewActionInterface::trigger();
58
59         preparePreview();
60         RS_Line * line = new RS_Line(container,
61                         data);
62         line->setLayerToActive();
63         line->setPenToActive();
64         container->addEntity(line);
65
66         // upd. undo list:
67         if (document != NULL)
68         {
69                 document->startUndoCycle();
70                 document->addUndoable(line);
71                 document->endUndoCycle();
72         }
73         deleteSnapper();
74         graphicView->moveRelativeZero(Vector(0.0, 0.0));
75         graphicView->drawEntity(line);
76         graphicView->moveRelativeZero(data.startpoint);
77         RS_DEBUG->print("RS_ActionDrawLineAngle::trigger(): line added: %d",
78                 line->getId());
79 }
80
81 void RS_ActionDrawLineAngle::mouseMoveEvent(QMouseEvent * e)
82 {
83         RS_DEBUG->print("RS_ActionDrawLineAngle::mouseMoveEvent begin");
84
85         if (getStatus() == SetPos)
86         {
87                 pos = snapPoint(e);
88                 deletePreview();
89                 clearPreview();
90                 preparePreview();
91                 preview->addEntity(new RS_Line(preview,
92                                 data));
93                 drawPreview();
94         }
95
96         RS_DEBUG->print("RS_ActionDrawLineAngle::mouseMoveEvent end");
97 }
98
99 void RS_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 RS_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 RS_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 RS_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 RS_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 RS_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 RS_ActionDrawLineAngle::showOptions()
259 {
260         RS_ActionInterface::showOptions();
261
262         RS_DIALOGFACTORY->requestOptions(this, true);
263 }
264
265 void RS_ActionDrawLineAngle::hideOptions()
266 {
267         RS_ActionInterface::hideOptions();
268
269         RS_DIALOGFACTORY->requestOptions(this, false);
270 }
271
272 void RS_ActionDrawLineAngle::updateMouseCursor()
273 {
274         graphicView->setMouseCursor(RS2::CadCursor);
275 }
276
277 void RS_ActionDrawLineAngle::updateToolBar()
278 {
279         if (!isFinished())
280                 RS_DIALOGFACTORY->requestToolBar(RS2::ToolBarSnap);
281         else
282                 RS_DIALOGFACTORY->requestToolBar(RS2::ToolBarLines);
283 }
284
285 void RS_ActionDrawLineAngle::setSnapPoint(int sp)
286 {
287         snpPoint = sp;
288 }
289
290 int RS_ActionDrawLineAngle::getSnapPoint()
291 {
292         return snpPoint;
293 }
294
295 void RS_ActionDrawLineAngle::setAngle(double a)
296 {
297         angle = a;
298 }
299
300 double RS_ActionDrawLineAngle::getAngle()
301 {
302         return angle;
303 }
304
305 void RS_ActionDrawLineAngle::setLength(double l)
306 {
307         length = l;
308 }
309
310 double RS_ActionDrawLineAngle::getLength()
311 {
312         return length;
313 }
314
315 bool RS_ActionDrawLineAngle::hasFixedAngle()
316 {
317         return fixedAngle;
318 }
319