]> Shamusworld >> Repos - architektonas/blob - src/actions/actiondrawline.cpp
ecb5b1c5c2a0e6d3648ca5e12794708833be5607
[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 "rs_commandevent.h"
21 #include "commands.h"
22 #include "rs_dialogfactory.h"
23 #include "graphicview.h"
24 #include "rs_preview.h"
25
26 ActionDrawLine::ActionDrawLine(RS_EntityContainer & container, GraphicView & graphicView):
27         ActionInterface("Draw lines", container, graphicView)
28 {
29         RS_DEBUG->print("ActionDrawLine::ActionDrawLine");
30         reset();
31         //hm.
32         graphicView.snapper.SetContainer(&container);
33         graphicView.snapper.SetGraphicView(&graphicView);
34         graphicView.snapper.SetVisible();
35         graphicView.preview.SetVisible();
36         RS_DEBUG->print("ActionDrawLine::ActionDrawLine: OK");
37 }
38
39 ActionDrawLine::~ActionDrawLine()
40 {
41         ClearHistory();
42 }
43
44 /*virtual*/ RS2::ActionType ActionDrawLine::rtti()
45 {
46         return RS2::ActionDrawLine;
47 }
48
49 void ActionDrawLine::reset()
50 {
51         RS_DEBUG->print("ActionDrawLine::reset");
52         data = RS_LineData(Vector(false), Vector(false));
53         start = Vector(false);
54         ClearHistory();
55         RS_DEBUG->print("ActionDrawLine::reset: OK");
56 }
57
58 void ActionDrawLine::init(int status)
59 {
60         RS_DEBUG->print("ActionDrawLine::init");
61 //      ActionInterface::init(status);
62         ActionInterface::init(status);
63         reset();
64         RS_DEBUG->print("ActionDrawLine::init: OK");
65 }
66
67 void ActionDrawLine::trigger()
68 {
69         graphicView->preview.clear();
70
71         RS_Line * line = new RS_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 << *((RS_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         RS_DEBUG->print("ActionDrawLine::trigger(): line added: %d", line->getId());
93 }
94
95 void ActionDrawLine::mouseMoveEvent(QMouseEvent * e)
96 {
97         RS_DEBUG->print("ActionDrawLine::mouseMoveEvent begin");
98
99         RS_DEBUG->print("ActionDrawLine::mouseMoveEvent: snap point");
100         Vector mouse = graphicView->snapper.snapPoint(e);
101         RS_DEBUG->print("ActionDrawLine::mouseMoveEvent: snap point: OK");
102
103         if (getStatus() == SetEndpoint && data.startpoint.valid)
104         {
105                 RS_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                 RS_Line * line = new RS_Line(&(graphicView->preview), RS_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                 RS_Line * line = (RS_Line *)graphicView->preview.firstEntity(RS2::ResolveNone);
115
116                 if (line)
117                 {
118                         line->setEndpoint(mouse);
119                 }
120                 else
121                 {
122                         line = new RS_Line(&(graphicView->preview), RS_LineData(data.startpoint, mouse));
123                         graphicView->preview.addEntity(line);
124                 }
125 #endif
126         }
127
128         //hm. [ok, this works. :-D]
129         graphicView->redraw();
130         RS_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         RS_DEBUG->print("ActionDrawLine::coordinateEvent");
159
160         if (!e)
161         {
162                 RS_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         RS_DEBUG->print("ActionDrawLine::coordinateEvent: OK");
193 }
194
195 void ActionDrawLine::commandEvent(RS_CommandEvent * e)
196 {
197         RS_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                         RS_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         RS_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                 RS_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 += RS_COMMANDS->command("close");
277                         msg += "/";
278                 }
279
280                 if (history.count() >= 2)
281                         msg += RS_COMMANDS->command("undo");
282
283                 if (history.count() >= 2)
284                         RS_DIALOGFACTORY->updateMouseWidget(tr("Specify next point or [%1]").arg(msg), tr("Back"));
285                 else
286                         RS_DIALOGFACTORY->updateMouseWidget(tr("Specify next point"), tr("Back"));
287         }
288                 break;
289
290         default:
291                 RS_DIALOGFACTORY->updateMouseWidget("", "");
292                 break;
293         }
294 }
295
296 void ActionDrawLine::showOptions()
297 {
298         RS_DEBUG->print("ActionDrawLine::showOptions");
299 //      ActionInterface::showOptions();
300         ActionInterface::showOptions();
301         RS_DIALOGFACTORY->requestOptions(this, true);
302         RS_DEBUG->print("ActionDrawLine::showOptions: OK");
303 }
304
305 void ActionDrawLine::hideOptions()
306 {
307 //      ActionInterface::hideOptions();
308         ActionInterface::hideOptions();
309         RS_DIALOGFACTORY->requestOptions(this, false);
310 }
311
312 void ActionDrawLine::updateMouseCursor()
313 {
314         graphicView->setMouseCursor(RS2::CadCursor);
315 }
316
317 void ActionDrawLine::updateToolBar()
318 {
319         if (!isFinished())
320                 RS_DIALOGFACTORY->requestToolBar(RS2::ToolBarSnap);
321         else
322                 RS_DIALOGFACTORY->requestToolBar(RS2::ToolBarLines);
323 }
324
325 void ActionDrawLine::close()
326 {
327 //NOTE: We should grey out the "close" button until the conditions for its use are satisfied.
328 //      Though I can see how this would be called via cmd line... So I guess it's OK
329         if (history.count() > 2 && start.valid)
330         {
331                 data.endpoint = start;
332                 trigger();
333                 setStatus(SetStartpoint);
334                 graphicView->moveRelativeZero(start);
335         }
336         else
337                 RS_DIALOGFACTORY->commandMessage(tr("Cannot close sequence of lines: Not enough entities defined yet."));
338 }
339
340 void ActionDrawLine::undo()
341 {
342 //NOTE: We should grey out the "undo" button until the conditions for its use are satisfied.
343         if (history.count() > 1)
344         {
345                 history.removeLast();
346                 graphicView->setCurrentAction(new ActionEditUndo(true, *container, *graphicView));
347                 data.startpoint = *history.last();
348                 graphicView->moveRelativeZero(data.startpoint);
349                 graphicView->preview.clear();
350                 graphicView->redraw();
351         }
352         else
353                 RS_DIALOGFACTORY->commandMessage(tr("Cannot undo: Not enough entities defined yet."));
354 }
355
356 void ActionDrawLine::ClearHistory(void)
357 {
358         while (!history.isEmpty())
359                 delete history.takeFirst();
360 }