]> Shamusworld >> Repos - architektonas/blob - src/actions/rs_actiondrawspline.cpp
ba4e6811fef276d981bcd1578f5f77a70d53b548
[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 "commands.h"
18 #include "rs_dialogfactory.h"
19 #include "rs_graphicview.h"
20 #include "rs_preview.h"
21
22 RS_ActionDrawSpline::RS_ActionDrawSpline(RS_EntityContainer & container, RS_GraphicView & graphicView):
23         RS_PreviewActionInterface("Draw splines", container, graphicView)
24 {
25         reset();
26 #warning "!!! Need to port setAutoDelete() behaviour from Qt3 to Qt4 !!!"
27 //      history.setAutoDelete(true);
28         data = RS_SplineData(3, false);
29         //bHistory.setAutoDelete(true);
30 }
31
32 RS_ActionDrawSpline::~RS_ActionDrawSpline()
33 {
34 }
35
36 /*virtual*/ RS2::ActionType RS_ActionDrawSpline::rtti()
37 {
38         return RS2::ActionDrawSpline;
39 }
40
41 void RS_ActionDrawSpline::reset()
42 {
43         spline = NULL;
44         //start = Vector(false);
45         history.clear();
46         //bHistory.clear();
47 }
48
49 void RS_ActionDrawSpline::init(int status)
50 {
51         RS_PreviewActionInterface::init(status);
52
53         reset();
54 }
55
56 void RS_ActionDrawSpline::trigger()
57 {
58         RS_PreviewActionInterface::trigger();
59
60         if (spline == NULL)
61                 return;
62
63         // add the entity
64         //RS_Spline* spline = new RS_Spline(container, data);
65         spline->setLayerToActive();
66         spline->setPenToActive();
67         spline->update();
68         container->addEntity(spline);
69
70         // upd. undo list:
71         if (document != NULL)
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("RS_ActionDrawSpline::trigger(): spline added: %d", spline->getId());
86
87         spline = NULL;
88         //history.clear();
89 }
90
91 void RS_ActionDrawSpline::mouseMoveEvent(QMouseEvent * e)
92 {
93         RS_DEBUG->print("RS_ActionDrawSpline::mouseMoveEvent begin");
94
95         Vector mouse = snapPoint(e);
96
97         if (getStatus() == SetNextPoint && spline != NULL /*&& point.valid*/)
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 //              Q3ValueList<Vector> cpts = tmpSpline->getControlPoints();
108 //              Q3ValueList<Vector>::iterator it;
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("RS_ActionDrawSpline::mouseMoveEvent end");
119 }
120
121 void RS_ActionDrawSpline::mouseReleaseEvent(QMouseEvent * e)
122 {
123         if (RS2::qtToRsButtonState(e->button()) == RS2::LeftButton)
124         {
125                 Vector ce(snapPoint(e));
126                 coordinateEvent(&ce);
127         }
128         else if (RS2::qtToRsButtonState(e->button()) == RS2::RightButton)
129         {
130                 if (getStatus() == SetNextPoint)
131                         trigger();
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