]> Shamusworld >> Repos - architektonas/blob - src/actions/rs_actiondrawline.cpp
1c1860af04f88143cb0a84b63d1590c1a1f6b484
[architektonas] / src / actions / rs_actiondrawline.cpp
1 // rs_actiondrawline.cpp
2 //
3 // Originally part of QCad Community Edition by Andrew Mustun
4 // Extensively rewritten and refactored by James L. Hammons
5 // (C) 2010 Underground Software
6 //
7 // JLH = James L. Hammons <jlhamm@acm.org>
8 //
9 // Who  When        What
10 // ---  ----------  -----------------------------------------------------------
11 // JLH  05/19/2010  Added this text. :-)
12 //
13
14 #include "rs_actiondrawline.h"
15
16 #include "rs_actioneditundo.h"
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_ActionDrawLine::RS_ActionDrawLine(RS_EntityContainer & container, GraphicView & graphicView):
24         RS_PreviewActionInterface("Draw lines", container, graphicView)
25 {
26         RS_DEBUG->print("RS_ActionDrawLine::RS_ActionDrawLine");
27         reset();
28         //hm.
29         graphicView.snapper.SetContainer(&container);
30         graphicView.snapper.SetGraphicView(&graphicView);
31         graphicView.snapper.SetVisible();
32         RS_DEBUG->print("RS_ActionDrawLine::RS_ActionDrawLine: OK");
33 }
34
35 RS_ActionDrawLine::~RS_ActionDrawLine()
36 {
37         ClearHistory();
38 }
39
40 /*virtual*/ RS2::ActionType RS_ActionDrawLine::rtti()
41 {
42         return RS2::ActionDrawLine;
43 }
44
45 void RS_ActionDrawLine::reset()
46 {
47         RS_DEBUG->print("RS_ActionDrawLine::reset");
48         data = RS_LineData(Vector(false), Vector(false));
49         start = Vector(false);
50         ClearHistory();
51         RS_DEBUG->print("RS_ActionDrawLine::reset: OK");
52 }
53
54 void RS_ActionDrawLine::init(int status)
55 {
56         RS_DEBUG->print("RS_ActionDrawLine::init");
57         RS_PreviewActionInterface::init(status);
58         reset();
59         RS_DEBUG->print("RS_ActionDrawLine::init: OK");
60 }
61
62 void RS_ActionDrawLine::trigger()
63 {
64         RS_PreviewActionInterface::trigger();   // XOR off screen, delete entities in container
65
66         RS_Line * line = new RS_Line(container, data);
67         line->setLayerToActive();
68         line->setPenToActive();
69         container->addEntity(line);
70 //std::cout << container;
71 //printf("RS_ActionDrawLine::trigger(): new line is %f,%f to %f,%f\n", data.startpoint.x, data.startpoint.y, data.endpoint.x, data.endpoint.y);
72 //This makes it come back as "Unknown Entity"
73 //std::cout << *((RS_Entity *)container);
74 //std::cout << *container;
75
76         // Update undo list:
77         if (document)
78         {
79                 document->startUndoCycle();
80                 document->addUndoable(line);
81                 document->endUndoCycle();
82         }
83
84 //      deleteSnapper();                        // XOR off of screen
85 //      graphicView->moveRelativeZero(Vector(0.0, 0.0));
86 //This is unnecessary, because we added this to the container...
87 //#warning "!!! Here's the trouble... Trying to draw direct !!!"
88 //      graphicView->drawEntity(line);
89         graphicView->moveRelativeZero(line->getEndpoint());
90 //      drawSnapper();                          // XOR on screen
91         RS_DEBUG->print("RS_ActionDrawLine::trigger(): line added: %d", line->getId());
92 }
93
94 void RS_ActionDrawLine::mouseMoveEvent(QMouseEvent * e)
95 {
96         RS_DEBUG->print("RS_ActionDrawLine::mouseMoveEvent begin");
97
98         RS_DEBUG->print("RS_ActionDrawLine::mouseMoveEvent: snap point");
99 //This used to draw the snapper, but now that's defunct... so, !!! FIX !!!
100 //      Vector mouse = snapPoint(e);
101         Vector mouse = graphicView->snapper.snapPoint(e);
102         RS_DEBUG->print("RS_ActionDrawLine::mouseMoveEvent: snap point: OK");
103
104         if (getStatus() == SetEndpoint && data.startpoint.valid)
105         {
106                 RS_DEBUG->print("RS_ActionDrawLine::mouseMoveEvent: update preview");
107 //not needed, but without this, it doesn't draw... strange...
108 //obviously we haven't gotten our rendering path correct...
109 //              deletePreview();                // XOR off of screen
110                 clearPreview();                 // Remove entities from the container
111                 preview->addEntity(new RS_Line(preview, RS_LineData(data.startpoint, mouse)));
112                 RS_DEBUG->print("RS_ActionDrawLine::mouseMoveEvent: draw preview");
113 //              drawPreview();                  // XOR on screen
114                 xorPreview();                   // XOR on screen
115         }
116
117         //hm.
118         graphicView->redraw();
119         RS_DEBUG->print("RS_ActionDrawLine::mouseMoveEvent end");
120 }
121
122 void RS_ActionDrawLine::mouseReleaseEvent(QMouseEvent * e)
123 {
124         if (e->button() == Qt::LeftButton)
125         {
126                 Vector ce(snapPoint(e));
127                 coordinateEvent(&ce);
128         }
129         else if (e->button() == Qt::RightButton)
130         {
131                 deletePreview();                // XOR off of screen
132                 clearPreview();                 // Remove entities from the container
133 //              deleteSnapper();                // XOR off of screen
134                 init(getStatus() - 1);
135         }
136 }
137
138 void RS_ActionDrawLine::coordinateEvent(Vector * e)
139 {
140         RS_DEBUG->print("RS_ActionDrawLine::coordinateEvent");
141
142         if (!e)
143         {
144                 RS_DEBUG->print("RS_ActionDrawLine::coordinateEvent: event was NULL");
145                 return;
146         }
147
148         Vector mouse = *e;
149
150         switch (getStatus())
151         {
152         case SetStartpoint:
153                 data.startpoint = mouse;
154                 ClearHistory();
155                 history.append(new Vector(mouse));
156                 start = data.startpoint;
157                 setStatus(SetEndpoint);
158                 graphicView->moveRelativeZero(mouse);
159                 updateMouseButtonHints();
160                 break;
161
162         case SetEndpoint:
163                 data.endpoint = mouse;
164                 history.append(new Vector(mouse));
165                 trigger();
166                 data.startpoint = data.endpoint;
167                 updateMouseButtonHints();
168                 break;
169
170         default:
171                 break;
172         }
173
174         RS_DEBUG->print("RS_ActionDrawLine::coordinateEvent: OK");
175 }
176
177 void RS_ActionDrawLine::commandEvent(RS_CommandEvent * e)
178 {
179         RS_DEBUG->print("RS_ActionDrawLine::commandEvent");
180         QString c = e->getCommand().toLower();
181
182         switch (getStatus())
183         {
184         case SetStartpoint:
185
186                 if (checkCommand("help", c))
187                 {
188                         RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
189                                 + getAvailableCommands().join(", "));
190                         return;
191                 }
192                 break;
193
194         case SetEndpoint:
195
196                 if (checkCommand("close", c))
197                 {
198                         close();
199                         updateMouseButtonHints();
200                         return;
201                 }
202
203                 if (checkCommand("undo", c))
204                 {
205                         undo();
206                         updateMouseButtonHints();
207                         return;
208                 }
209                 break;
210
211         default:
212                 break;
213         }
214
215         RS_DEBUG->print("RS_ActionDrawLine::commandEvent: OK");
216 }
217
218 QStringList RS_ActionDrawLine::getAvailableCommands()
219 {
220         QStringList cmd;
221
222         switch (getStatus())
223         {
224         case SetStartpoint:
225                 break;
226
227         case SetEndpoint:
228
229                 if (history.count() >= 2)
230                         cmd += command("undo");
231
232                 if (history.count() >= 3)
233                         cmd += command("close");
234
235                 break;
236
237         default:
238                 break;
239         }
240
241         return cmd;
242 }
243
244 void RS_ActionDrawLine::updateMouseButtonHints()
245 {
246         switch (getStatus())
247         {
248         case SetStartpoint:
249                 RS_DIALOGFACTORY->updateMouseWidget(tr("Specify first point"), tr("Cancel"));
250                 break;
251
252         case SetEndpoint:
253         {
254                 QString msg = "";
255
256                 if (history.count() >= 3)
257                 {
258                         msg += RS_COMMANDS->command("close");
259                         msg += "/";
260                 }
261
262                 if (history.count() >= 2)
263                         msg += RS_COMMANDS->command("undo");
264
265                 if (history.count() >= 2)
266                         RS_DIALOGFACTORY->updateMouseWidget(tr("Specify next point or [%1]").arg(msg), tr("Back"));
267                 else
268                         RS_DIALOGFACTORY->updateMouseWidget(tr("Specify next point"), tr("Back"));
269         }
270         break;
271
272         default:
273                 RS_DIALOGFACTORY->updateMouseWidget("", "");
274                 break;
275         }
276 }
277
278 void RS_ActionDrawLine::showOptions()
279 {
280         RS_DEBUG->print("RS_ActionDrawLine::showOptions");
281         RS_ActionInterface::showOptions();
282         RS_DIALOGFACTORY->requestOptions(this, true);
283         RS_DEBUG->print("RS_ActionDrawLine::showOptions: OK");
284 }
285
286 void RS_ActionDrawLine::hideOptions()
287 {
288         RS_ActionInterface::hideOptions();
289         RS_DIALOGFACTORY->requestOptions(this, false);
290 }
291
292 void RS_ActionDrawLine::updateMouseCursor()
293 {
294         graphicView->setMouseCursor(RS2::CadCursor);
295 }
296
297 void RS_ActionDrawLine::updateToolBar()
298 {
299         if (!isFinished())
300                 RS_DIALOGFACTORY->requestToolBar(RS2::ToolBarSnap);
301         else
302                 RS_DIALOGFACTORY->requestToolBar(RS2::ToolBarLines);
303 }
304
305 void RS_ActionDrawLine::close()
306 {
307 //NOTE: We should grey out the "close" button until the conditions for its use are satisfied.
308 //      Though I can see how this would be called via cmd line... So I guess it's OK
309         if (history.count() > 2 && start.valid)
310         {
311                 data.endpoint = start;
312                 trigger();
313                 setStatus(SetStartpoint);
314                 graphicView->moveRelativeZero(start);
315         }
316         else
317                 RS_DIALOGFACTORY->commandMessage(tr("Cannot close sequence of lines: Not enough entities defined yet."));
318 }
319
320 void RS_ActionDrawLine::undo()
321 {
322 //NOTE: We should grey out the "undo" button until the conditions for its use are satisfied.
323         if (history.count() > 1)
324         {
325                 history.removeLast();
326                 deletePreview();                // XOR off of screen
327                 clearPreview();                 // Delete entities in container
328                 graphicView->setCurrentAction(new RS_ActionEditUndo(true, *container, *graphicView));
329                 data.startpoint = *history.last();
330                 graphicView->moveRelativeZero(data.startpoint);
331         }
332         else
333                 RS_DIALOGFACTORY->commandMessage(tr("Cannot undo: Not enough entities defined yet."));
334 }
335
336 void RS_ActionDrawLine::ClearHistory(void)
337 {
338         while (!history.isEmpty())
339                 delete history.takeFirst();
340 }