]> Shamusworld >> Repos - architektonas/blob - src/actions/actiondrawline.cpp
Bugfixes related to removing Snapper class.
[architektonas] / src / actions / actiondrawline.cpp
1 // actiondrawline.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  05/19/2010  Added this text. :-)
15 //
16
17 #include "actiondrawline.h"
18
19 #include "actioneditundo.h"
20 #include "commandevent.h"
21 #include "commands.h"
22 #include "debug.h"
23 #include "dialogfactory.h"
24 #include "graphicview.h"
25 #include "preview.h"
26
27 ActionDrawLine::ActionDrawLine(EntityContainer & container, GraphicView & graphicView):
28         ActionInterface("Draw lines", container, graphicView)
29 {
30         DEBUG->print("ActionDrawLine::ActionDrawLine");
31         reset();
32         DEBUG->print("ActionDrawLine::ActionDrawLine: OK");
33 //printf("ActionDrawLine(): preview is%s visible, snapper is%s visible...\n", (graphicView.preview.Visible() ? "" : " NOT"), (graphicView.snapper.Visible() ? "" : " NOT"));
34 }
35
36 ActionDrawLine::~ActionDrawLine()
37 {
38         ClearHistory();
39 }
40
41 /*virtual*/ RS2::ActionType ActionDrawLine::rtti()
42 {
43         return RS2::ActionDrawLine;
44 }
45
46 void ActionDrawLine::reset()
47 {
48         DEBUG->print("ActionDrawLine::reset");
49         data = LineData(Vector(false), Vector(false));
50         start = Vector(false);
51         ClearHistory();
52         DEBUG->print("ActionDrawLine::reset: OK");
53 }
54
55 void ActionDrawLine::init(int status)
56 {
57         DEBUG->print("ActionDrawLine::init");
58         ActionInterface::init(status);
59         reset();
60         DEBUG->print("ActionDrawLine::init: OK");
61 }
62
63 void ActionDrawLine::trigger()
64 {
65         graphicView->preview.clear();
66
67         Line * line = new Line(container, data);
68         line->setLayerToActive();
69         line->setPenToActive();
70         container->addEntity(line);
71 //std::cout << container;
72 //printf("ActionDrawLine::trigger(): new line is %f,%f to %f,%f\n", data.startpoint.x, data.startpoint.y, data.endpoint.x, data.endpoint.y);
73 //This makes it come back as "Unknown Entity"
74 //std::cout << *((Entity *)container);
75 //std::cout << *container;
76
77         // Update undo list:
78         if (document)
79         {
80                 document->startUndoCycle();
81                 document->addUndoable(line);
82                 document->endUndoCycle();
83         }
84
85         graphicView->moveRelativeZero(line->getEndpoint());
86         //hm. [OK, it just moves the relative zero tho. Overkill. And remove preview, so OK.]
87         graphicView->redraw();
88         DEBUG->print("ActionDrawLine::trigger(): line added: %d", line->getId());
89 }
90
91 void ActionDrawLine::mouseMoveEvent(QMouseEvent * e)
92 {
93         DEBUG->print("ActionDrawLine::mouseMoveEvent begin");
94
95         DEBUG->print("ActionDrawLine::mouseMoveEvent: snap point");
96 //      Vector mouse = graphicView->snapper.snapPoint(e);
97         Vector mouse = graphicView->SnapPoint(e);
98         DEBUG->print("ActionDrawLine::mouseMoveEvent: snap point: OK");
99
100         if (getStatus() == SetEndpoint && data.startpoint.valid)
101         {
102                 DEBUG->print("ActionDrawLine::mouseMoveEvent: update preview");
103                 // This is lame. Creating a new Line every time the endpoint moves.
104                 // Surely we can alter the line entity inside the preview, no?
105 #if 0
106                 graphicView->preview.clear();                   // Remove entities from the container
107                 Line * line = new Line(&(graphicView->preview), LineData(data.startpoint, mouse));
108                 graphicView->preview.addEntity(line);
109 #else
110                 // We can assume there's only one line in there, can't we?
111                 Line * line = (Line *)graphicView->preview.firstEntity(RS2::ResolveNone);
112
113                 if (line)
114                 {
115                         line->setEndpoint(mouse);
116                 }
117                 else
118                 {
119                         line = new Line(&(graphicView->preview), LineData(data.startpoint, mouse));
120                         graphicView->preview.addEntity(line);
121                 }
122 #endif
123         }
124
125 //OK, snapper & preview are set as NOT visible... why???
126 //becuz other things are created in the meantime which turn this stuff off, treating
127 //it like it isn't a shared resource which it is...
128 //printf("ActionDrawLine::mouseMoveEvent(): preview is%s visible, snapper is%s visible...\n", (graphicView->preview.Visible() ? "" : " NOT"), (graphicView->snapper.Visible() ? "" : " NOT"));
129         //hm. [ok, this works. :-D]
130         graphicView->redraw();
131         DEBUG->print("ActionDrawLine::mouseMoveEvent end");
132 }
133
134 void ActionDrawLine::mouseReleaseEvent(QMouseEvent * e)
135 {
136         if (e->button() == Qt::LeftButton)
137         {
138 //              Vector ce(graphicView->snapper.snapPoint(e));
139                 Vector ce(graphicView->SnapPoint(e));
140                 coordinateEvent(&ce);
141         }
142         else if (e->button() == Qt::RightButton)
143         {
144                 init(getStatus() - 1);
145         }
146
147         //hm. [Seems to work OK.]
148         //shouldn't need this...
149 //      graphicView->preview.clear();                           // Remove entities from container
150 //      graphicView->redraw();
151 }
152
153 void ActionDrawLine::coordinateEvent(Vector * e)
154 {
155         DEBUG->print("ActionDrawLine::coordinateEvent");
156
157         if (!e)
158         {
159                 DEBUG->print("ActionDrawLine::coordinateEvent: event was NULL");
160                 return;
161         }
162
163         Vector mouse = *e;
164
165         switch (getStatus())
166         {
167         case SetStartpoint:
168                 data.startpoint = mouse;
169                 ClearHistory();
170                 history.append(new Vector(mouse));
171                 start = data.startpoint;
172                 setStatus(SetEndpoint);
173                 graphicView->moveRelativeZero(mouse);
174                 updateMouseButtonHints();
175                 break;
176
177         case SetEndpoint:
178                 data.endpoint = mouse;
179                 history.append(new Vector(mouse));
180                 trigger();
181                 data.startpoint = data.endpoint;
182                 updateMouseButtonHints();
183                 break;
184
185         default:
186                 break;
187         }
188
189         DEBUG->print("ActionDrawLine::coordinateEvent: OK");
190 }
191
192 void ActionDrawLine::commandEvent(CommandEvent * e)
193 {
194         DEBUG->print("ActionDrawLine::commandEvent");
195         QString c = e->getCommand().toLower();
196
197         switch (getStatus())
198         {
199         case SetStartpoint:
200
201                 if (checkCommand("help", c))
202                 {
203                         DIALOGFACTORY->commandMessage(msgAvailableCommands()
204                                 + getAvailableCommands().join(", "));
205                         return;
206                 }
207                 break;
208
209         case SetEndpoint:
210
211                 if (checkCommand("close", c))
212                 {
213                         close();
214                         updateMouseButtonHints();
215                         return;
216                 }
217
218                 if (checkCommand("undo", c))
219                 {
220                         undo();
221                         updateMouseButtonHints();
222                         return;
223                 }
224                 break;
225
226         default:
227                 break;
228         }
229
230         DEBUG->print("ActionDrawLine::commandEvent: OK");
231 }
232
233 QStringList ActionDrawLine::getAvailableCommands()
234 {
235         QStringList cmd;
236
237         switch (getStatus())
238         {
239         case SetStartpoint:
240                 break;
241
242         case SetEndpoint:
243
244                 if (history.count() >= 2)
245                         cmd += command("undo");
246
247                 if (history.count() >= 3)
248                         cmd += command("close");
249
250                 break;
251
252         default:
253                 break;
254         }
255
256         return cmd;
257 }
258
259 void ActionDrawLine::updateMouseButtonHints()
260 {
261         switch (getStatus())
262         {
263         case SetStartpoint:
264                 DIALOGFACTORY->updateMouseWidget(tr("Specify first point"), tr("Cancel"));
265                 break;
266
267         case SetEndpoint:
268         {
269                 QString msg = "";
270
271                 if (history.count() >= 3)
272                 {
273                         msg += COMMANDS->command("close");
274                         msg += "/";
275                 }
276
277                 if (history.count() >= 2)
278                         msg += COMMANDS->command("undo");
279
280                 if (history.count() >= 2)
281                         DIALOGFACTORY->updateMouseWidget(tr("Specify next point or [%1]").arg(msg), tr("Back"));
282                 else
283                         DIALOGFACTORY->updateMouseWidget(tr("Specify next point"), tr("Back"));
284         }
285                 break;
286
287         default:
288                 DIALOGFACTORY->updateMouseWidget("", "");
289                 break;
290         }
291 }
292
293 void ActionDrawLine::showOptions()
294 {
295         DEBUG->print("ActionDrawLine::showOptions");
296         ActionInterface::showOptions();
297         DIALOGFACTORY->requestOptions(this, true);
298         DEBUG->print("ActionDrawLine::showOptions: OK");
299 }
300
301 void ActionDrawLine::hideOptions()
302 {
303         ActionInterface::hideOptions();
304         DIALOGFACTORY->requestOptions(this, false);
305 }
306
307 void ActionDrawLine::updateMouseCursor()
308 {
309         graphicView->setMouseCursor(RS2::CadCursor);
310 }
311
312 void ActionDrawLine::updateToolBar()
313 {
314         if (!isFinished())
315                 DIALOGFACTORY->requestToolBar(RS2::ToolBarSnap);
316         else
317                 DIALOGFACTORY->requestToolBar(RS2::ToolBarLines);
318 }
319
320 void ActionDrawLine::close()
321 {
322 //NOTE: We should grey out the "close" button until the conditions for its use are satisfied.
323 //      Though I can see how this would be called via cmd line... So I guess it's OK
324         if (history.count() > 2 && start.valid)
325         {
326                 data.endpoint = start;
327                 trigger();
328                 setStatus(SetStartpoint);
329                 graphicView->moveRelativeZero(start);
330         }
331         else
332                 DIALOGFACTORY->commandMessage(tr("Cannot close sequence of lines: Not enough entities defined yet."));
333 }
334
335 void ActionDrawLine::undo()
336 {
337 //NOTE: We should grey out the "undo" button until the conditions for its use are satisfied.
338         if (history.count() > 1)
339         {
340                 history.removeLast();
341                 graphicView->setCurrentAction(new ActionEditUndo(true, *container, *graphicView));
342                 data.startpoint = *history.last();
343                 graphicView->moveRelativeZero(data.startpoint);
344                 graphicView->preview.clear();
345                 graphicView->redraw();
346         }
347         else
348                 DIALOGFACTORY->commandMessage(tr("Cannot undo: Not enough entities defined yet."));
349 }
350
351 void ActionDrawLine::ClearHistory(void)
352 {
353         while (!history.isEmpty())
354                 delete history.takeFirst();
355 }