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
10 // JLH = James L. Hammons <jlhamm@acm.org>
13 // --- ---------- -----------------------------------------------------------
14 // JLH 05/19/2010 Added this text. :-)
17 #include "actiondrawline.h"
19 #include "actioneditundo.h"
20 #include "commandevent.h"
23 #include "dialogfactory.h"
24 #include "graphicview.h"
27 ActionDrawLine::ActionDrawLine(EntityContainer & container, GraphicView & graphicView):
28 ActionInterface("Draw lines", container, graphicView)
30 DEBUG->print("ActionDrawLine::ActionDrawLine");
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"));
36 ActionDrawLine::~ActionDrawLine()
41 /*virtual*/ RS2::ActionType ActionDrawLine::rtti()
43 return RS2::ActionDrawLine;
46 void ActionDrawLine::reset()
48 DEBUG->print("ActionDrawLine::reset");
49 data = LineData(Vector(false), Vector(false));
50 start = Vector(false);
52 DEBUG->print("ActionDrawLine::reset: OK");
55 void ActionDrawLine::init(int status)
57 DEBUG->print("ActionDrawLine::init");
58 ActionInterface::init(status);
60 DEBUG->print("ActionDrawLine::init: OK");
63 void ActionDrawLine::trigger()
65 graphicView->preview.clear();
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;
80 document->startUndoCycle();
81 document->addUndoable(line);
82 document->endUndoCycle();
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());
91 void ActionDrawLine::mouseMoveEvent(QMouseEvent * e)
93 DEBUG->print("ActionDrawLine::mouseMoveEvent begin");
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");
100 if (getStatus() == SetEndpoint && data.startpoint.valid)
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?
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);
110 // We can assume there's only one line in there, can't we?
111 Line * line = (Line *)graphicView->preview.firstEntity(RS2::ResolveNone);
115 line->setEndpoint(mouse);
119 line = new Line(&(graphicView->preview), LineData(data.startpoint, mouse));
120 graphicView->preview.addEntity(line);
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");
134 void ActionDrawLine::mouseReleaseEvent(QMouseEvent * e)
136 if (e->button() == Qt::LeftButton)
138 // Vector ce(graphicView->snapper.snapPoint(e));
139 Vector ce(graphicView->SnapPoint(e));
140 coordinateEvent(&ce);
142 else if (e->button() == Qt::RightButton)
144 init(getStatus() - 1);
147 //hm. [Seems to work OK.]
148 //shouldn't need this...
149 // graphicView->preview.clear(); // Remove entities from container
150 // graphicView->redraw();
153 void ActionDrawLine::coordinateEvent(Vector * e)
155 DEBUG->print("ActionDrawLine::coordinateEvent");
159 DEBUG->print("ActionDrawLine::coordinateEvent: event was NULL");
168 data.startpoint = mouse;
170 history.append(new Vector(mouse));
171 start = data.startpoint;
172 setStatus(SetEndpoint);
173 graphicView->moveRelativeZero(mouse);
174 updateMouseButtonHints();
178 data.endpoint = mouse;
179 history.append(new Vector(mouse));
181 data.startpoint = data.endpoint;
182 updateMouseButtonHints();
189 DEBUG->print("ActionDrawLine::coordinateEvent: OK");
192 void ActionDrawLine::commandEvent(CommandEvent * e)
194 DEBUG->print("ActionDrawLine::commandEvent");
195 QString c = e->getCommand().toLower();
201 if (checkCommand("help", c))
203 DIALOGFACTORY->commandMessage(msgAvailableCommands()
204 + getAvailableCommands().join(", "));
211 if (checkCommand("close", c))
214 updateMouseButtonHints();
218 if (checkCommand("undo", c))
221 updateMouseButtonHints();
230 DEBUG->print("ActionDrawLine::commandEvent: OK");
233 QStringList ActionDrawLine::getAvailableCommands()
244 if (history.count() >= 2)
245 cmd += command("undo");
247 if (history.count() >= 3)
248 cmd += command("close");
259 void ActionDrawLine::updateMouseButtonHints()
264 DIALOGFACTORY->updateMouseWidget(tr("Specify first point"), tr("Cancel"));
271 if (history.count() >= 3)
273 msg += COMMANDS->command("close");
277 if (history.count() >= 2)
278 msg += COMMANDS->command("undo");
280 if (history.count() >= 2)
281 DIALOGFACTORY->updateMouseWidget(tr("Specify next point or [%1]").arg(msg), tr("Back"));
283 DIALOGFACTORY->updateMouseWidget(tr("Specify next point"), tr("Back"));
288 DIALOGFACTORY->updateMouseWidget("", "");
293 void ActionDrawLine::showOptions()
295 DEBUG->print("ActionDrawLine::showOptions");
296 ActionInterface::showOptions();
297 DIALOGFACTORY->requestOptions(this, true);
298 DEBUG->print("ActionDrawLine::showOptions: OK");
301 void ActionDrawLine::hideOptions()
303 ActionInterface::hideOptions();
304 DIALOGFACTORY->requestOptions(this, false);
307 void ActionDrawLine::updateMouseCursor()
309 graphicView->setMouseCursor(RS2::CadCursor);
312 void ActionDrawLine::updateToolBar()
315 DIALOGFACTORY->requestToolBar(RS2::ToolBarSnap);
317 DIALOGFACTORY->requestToolBar(RS2::ToolBarLines);
320 void ActionDrawLine::close()
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)
326 data.endpoint = start;
328 setStatus(SetStartpoint);
329 graphicView->moveRelativeZero(start);
332 DIALOGFACTORY->commandMessage(tr("Cannot close sequence of lines: Not enough entities defined yet."));
335 void ActionDrawLine::undo()
337 //NOTE: We should grey out the "undo" button until the conditions for its use are satisfied.
338 if (history.count() > 1)
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();
348 DIALOGFACTORY->commandMessage(tr("Cannot undo: Not enough entities defined yet."));
351 void ActionDrawLine::ClearHistory(void)
353 while (!history.isEmpty())
354 delete history.takeFirst();