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