]> Shamusworld >> Repos - architektonas/blob - src/actions/actiondrawspline.cpp
9d06bf7933c7fadc999497029c3150df80497abf
[architektonas] / src / actions / actiondrawspline.cpp
1 // actiondrawspline.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  06/04/2010  Added this text. :-)
15 //
16
17 #include "actiondrawspline.h"
18
19 #include "rs_commandevent.h"
20 #include "commands.h"
21 #include "rs_dialogfactory.h"
22 #include "graphicview.h"
23 #include "rs_preview.h"
24
25 ActionDrawSpline::ActionDrawSpline(RS_EntityContainer & container, GraphicView & graphicView):
26         ActionInterface("Draw splines", container, graphicView)
27 {
28         reset();
29 #warning "!!! Need to port setAutoDelete() behaviour from Qt3 to Qt4 !!!"
30 //      history.setAutoDelete(true);
31         data = RS_SplineData(3, false);
32         //bHistory.setAutoDelete(true);
33 }
34
35 ActionDrawSpline::~ActionDrawSpline()
36 {
37 }
38
39 /*virtual*/ RS2::ActionType ActionDrawSpline::rtti()
40 {
41         return RS2::ActionDrawSpline;
42 }
43
44 void ActionDrawSpline::reset()
45 {
46         spline = NULL;
47         //start = Vector(false);
48         history.clear();
49         //bHistory.clear();
50 }
51
52 void ActionDrawSpline::init(int status)
53 {
54         ActionInterface::init(status);
55
56         reset();
57 }
58
59 void ActionDrawSpline::trigger()
60 {
61         ActionInterface::trigger();
62
63         if (spline == NULL)
64                 return;
65
66         // add the entity
67         spline->setLayerToActive();
68         spline->setPenToActive();
69         spline->update();
70         container->addEntity(spline);
71
72         // upd. undo list:
73         if (document)
74         {
75                 document->startUndoCycle();
76                 document->addUndoable(spline);
77                 document->endUndoCycle();
78         }
79
80         // upd view
81         deleteSnapper();
82         Vector r = graphicView->getRelativeZero();
83         graphicView->moveRelativeZero(Vector(0.0, 0.0));
84         graphicView->drawEntity(spline);
85         graphicView->moveRelativeZero(r);
86         drawSnapper();
87         RS_DEBUG->print("ActionDrawSpline::trigger(): spline added: %d", spline->getId());
88
89         spline = NULL;
90         //history.clear();
91 }
92
93 void ActionDrawSpline::mouseMoveEvent(QMouseEvent * e)
94 {
95         RS_DEBUG->print("ActionDrawSpline::mouseMoveEvent begin");
96
97         Vector mouse = snapPoint(e);
98
99         if (getStatus() == SetNextPoint && spline)
100         {
101                 deletePreview();
102                 clearPreview();
103
104                 RS_Spline * tmpSpline = (RS_Spline *)spline->clone();
105                 tmpSpline->addControlPoint(mouse);
106                 tmpSpline->update();
107 //              preview->addEntity(tmpSpline);
108
109                 QList<Vector> cpts = tmpSpline->getControlPoints();
110                 QList<Vector>::iterator it;
111
112 //              for(it=cpts.begin(); it!=cpts.end(); it+)
113 //                      preview->addEntity(new RS_Point(preview, RS_PointData(*it)));
114
115                 drawPreview();
116         }
117
118         RS_DEBUG->print("ActionDrawSpline::mouseMoveEvent end");
119 }
120
121 void ActionDrawSpline::mouseReleaseEvent(QMouseEvent * e)
122 {
123         if (e->button() == Qt::LeftButton)
124         {
125                 Vector ce(snapPoint(e));
126                 coordinateEvent(&ce);
127         }
128         else if (e->button() == Qt::RightButton)
129         {
130                 if (getStatus() == SetNextPoint)
131                         trigger();
132
133                 deletePreview();
134                 clearPreview();
135                 deleteSnapper();
136                 init(getStatus() - 1);
137         }
138 }
139
140 void ActionDrawSpline::coordinateEvent(Vector * e)
141 {
142         if (!e)
143                 return;
144
145         Vector mouse = *e;
146
147         switch (getStatus())
148         {
149         case SetStartpoint:
150                 history.clear();
151                 history.append(new Vector(mouse));
152
153                 if (!spline)
154                 {
155                         spline = new RS_Spline(container, data);
156                         spline->addControlPoint(mouse);
157                 }
158
159                 setStatus(SetNextPoint);
160                 graphicView->moveRelativeZero(mouse);
161                 updateMouseButtonHints();
162                 break;
163
164         case SetNextPoint:
165                 graphicView->moveRelativeZero(mouse);
166                 history.append(new Vector(mouse));
167
168                 if (spline)
169                 {
170                         spline->addControlPoint(mouse);
171                         deletePreview();
172                         clearPreview();
173                         deleteSnapper();
174                         drawSnapper();
175                 }
176
177                 updateMouseButtonHints();
178                 break;
179
180         default:
181                 break;
182         }
183 }
184
185 void ActionDrawSpline::commandEvent(RS_CommandEvent * e)
186 {
187         QString c = e->getCommand().toLower();
188
189         switch (getStatus())
190         {
191         case SetStartpoint:
192                 if (checkCommand("help", c))
193                 {
194                         RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
195                                 + getAvailableCommands().join(", "));
196                         return;
197                 }
198
199                 break;
200
201         case SetNextPoint:
202                 if (checkCommand("undo", c))
203                 {
204                         undo();
205                         updateMouseButtonHints();
206                         return;
207                 }
208
209                 break;
210
211         default:
212                 break;
213         }
214 }
215
216 QStringList ActionDrawSpline::getAvailableCommands()
217 {
218         QStringList cmd;
219
220         switch (getStatus())
221         {
222         case SetStartpoint:
223                 break;
224
225         case SetNextPoint:
226                 if (history.count() >= 2)
227                         cmd += command("undo");
228
229                 if (history.count() >= 3)
230                         cmd += command("close");
231
232                 break;
233
234         default:
235                 break;
236         }
237
238         return cmd;
239 }
240
241 void ActionDrawSpline::updateMouseButtonHints()
242 {
243         switch (getStatus())
244         {
245         case SetStartpoint:
246                 RS_DIALOGFACTORY->updateMouseWidget(tr("Specify first control point"),
247                         tr("Cancel"));
248                 break;
249
250         case SetNextPoint:
251         {
252                 QString msg = "";
253
254                 if (history.count() >= 3)
255                 {
256                         msg += RS_COMMANDS->command("close");
257                         msg += "/";
258                 }
259
260                 if (history.count() >= 2)
261                         msg += RS_COMMANDS->command("undo");
262
263                 if (history.count() >= 2)
264                         RS_DIALOGFACTORY->updateMouseWidget(
265                                 tr("Specify next control point or [%1]").arg(msg),
266                                 tr("Back"));
267                 else
268                         RS_DIALOGFACTORY->updateMouseWidget(
269                                 tr("Specify next control point"),
270                                 tr("Back"));
271         }
272                 break;
273
274         default:
275                 RS_DIALOGFACTORY->updateMouseWidget("", "");
276                 break;
277         }
278 }
279
280 void ActionDrawSpline::showOptions()
281 {
282         ActionInterface::showOptions();
283         RS_DIALOGFACTORY->requestOptions(this, true);
284 }
285
286 void ActionDrawSpline::hideOptions()
287 {
288         ActionInterface::hideOptions();
289         RS_DIALOGFACTORY->requestOptions(this, false);
290 }
291
292 void ActionDrawSpline::updateMouseCursor()
293 {
294         graphicView->setMouseCursor(RS2::CadCursor);
295 }
296
297 void ActionDrawSpline::updateToolBar()
298 {
299         if (!isFinished())
300                 RS_DIALOGFACTORY->requestToolBar(RS2::ToolBarSnap);
301         else
302                 RS_DIALOGFACTORY->requestToolBar(RS2::ToolBarMain);
303 }
304
305 void ActionDrawSpline::undo()
306 {
307         if (history.count() > 1)
308         {
309                 history.removeLast();
310                 deletePreview();
311                 clearPreview();
312
313                 if (history.last())
314                 {
315                         //point = *history.last();
316                 }
317
318                 if (spline)
319                 {
320                         spline->removeLastControlPoint();
321                         Vector * v = history.last();
322
323                         if (v)
324                                 graphicView->moveRelativeZero(*v);
325
326                         graphicView->redraw();
327                 }
328         }
329         else
330                 RS_DIALOGFACTORY->commandMessage(
331                         tr("Cannot undo: Not enough entities defined yet."));
332 }
333
334 void ActionDrawSpline::setDegree(int deg)
335 {
336         data.degree = deg;
337
338         if (spline)
339                 spline->setDegree(deg);
340 }
341
342 int ActionDrawSpline::getDegree()
343 {
344         return data.degree;
345 }
346
347 void ActionDrawSpline::setClosed(bool c)
348 {
349         data.closed = c;
350
351         if (spline)
352                 spline->setClosed(c);
353 }
354
355 bool ActionDrawSpline::isClosed()
356 {
357         return data.closed;
358 }