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