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