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