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 "rs_commandevent.h"
23 #include "rs_dialogfactory.h"
24 #include "graphicview.h"
25 #include "rs_preview.h"
27 ActionDrawLine::ActionDrawLine(RS_EntityContainer & container, GraphicView & graphicView):
28 ActionInterface("Draw lines", container, graphicView)
30 RS_DEBUG->print("ActionDrawLine::ActionDrawLine");
33 // graphicView.snapper.SetContainer(&container);
34 // graphicView.snapper.SetGraphicView(&graphicView);
35 // graphicView.snapper.SetVisible();
36 // graphicView.preview.SetVisible();
37 RS_DEBUG->print("ActionDrawLine::ActionDrawLine: OK");
40 ActionDrawLine::~ActionDrawLine()
45 /*virtual*/ RS2::ActionType ActionDrawLine::rtti()
47 return RS2::ActionDrawLine;
50 void ActionDrawLine::reset()
52 RS_DEBUG->print("ActionDrawLine::reset");
53 data = RS_LineData(Vector(false), Vector(false));
54 start = Vector(false);
56 RS_DEBUG->print("ActionDrawLine::reset: OK");
59 void ActionDrawLine::init(int status)
61 RS_DEBUG->print("ActionDrawLine::init");
62 ActionInterface::init(status);
64 RS_DEBUG->print("ActionDrawLine::init: OK");
67 void ActionDrawLine::trigger()
69 graphicView->preview.clear();
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;
84 document->startUndoCycle();
85 document->addUndoable(line);
86 document->endUndoCycle();
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());
95 void ActionDrawLine::mouseMoveEvent(QMouseEvent * e)
97 RS_DEBUG->print("ActionDrawLine::mouseMoveEvent begin");
99 RS_DEBUG->print("ActionDrawLine::mouseMoveEvent: snap point");
100 Vector mouse = graphicView->snapper.snapPoint(e);
101 RS_DEBUG->print("ActionDrawLine::mouseMoveEvent: snap point: OK");
103 if (getStatus() == SetEndpoint && data.startpoint.valid)
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?
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);
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);
118 line->setEndpoint(mouse);
122 line = new RS_Line(&(graphicView->preview), RS_LineData(data.startpoint, mouse));
123 graphicView->preview.addEntity(line);
128 //hm. [ok, this works. :-D]
129 graphicView->redraw();
130 RS_DEBUG->print("ActionDrawLine::mouseMoveEvent end");
133 void ActionDrawLine::mouseReleaseEvent(QMouseEvent * e)
135 if (e->button() == Qt::LeftButton)
137 Vector ce(graphicView->snapper.snapPoint(e));
138 coordinateEvent(&ce);
140 else if (e->button() == Qt::RightButton)
142 // if (getStatus() == 0)
144 // graphicView->snapper.SetVisible(false);
145 // graphicView->preview.SetVisible(false);
148 init(getStatus() - 1);
151 //hm. [Seems to work OK.]
152 graphicView->preview.clear(); // Remove entities from container
153 graphicView->redraw();
156 void ActionDrawLine::coordinateEvent(Vector * e)
158 RS_DEBUG->print("ActionDrawLine::coordinateEvent");
162 RS_DEBUG->print("ActionDrawLine::coordinateEvent: event was NULL");
171 data.startpoint = mouse;
173 history.append(new Vector(mouse));
174 start = data.startpoint;
175 setStatus(SetEndpoint);
176 graphicView->moveRelativeZero(mouse);
177 updateMouseButtonHints();
181 data.endpoint = mouse;
182 history.append(new Vector(mouse));
184 data.startpoint = data.endpoint;
185 updateMouseButtonHints();
192 RS_DEBUG->print("ActionDrawLine::coordinateEvent: OK");
195 void ActionDrawLine::commandEvent(RS_CommandEvent * e)
197 RS_DEBUG->print("ActionDrawLine::commandEvent");
198 QString c = e->getCommand().toLower();
204 if (checkCommand("help", c))
206 RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
207 + getAvailableCommands().join(", "));
214 if (checkCommand("close", c))
217 updateMouseButtonHints();
221 if (checkCommand("undo", c))
224 updateMouseButtonHints();
233 RS_DEBUG->print("ActionDrawLine::commandEvent: OK");
236 QStringList ActionDrawLine::getAvailableCommands()
247 if (history.count() >= 2)
248 cmd += command("undo");
250 if (history.count() >= 3)
251 cmd += command("close");
262 void ActionDrawLine::updateMouseButtonHints()
267 RS_DIALOGFACTORY->updateMouseWidget(tr("Specify first point"), tr("Cancel"));
274 if (history.count() >= 3)
276 msg += RS_COMMANDS->command("close");
280 if (history.count() >= 2)
281 msg += RS_COMMANDS->command("undo");
283 if (history.count() >= 2)
284 RS_DIALOGFACTORY->updateMouseWidget(tr("Specify next point or [%1]").arg(msg), tr("Back"));
286 RS_DIALOGFACTORY->updateMouseWidget(tr("Specify next point"), tr("Back"));
291 RS_DIALOGFACTORY->updateMouseWidget("", "");
296 void ActionDrawLine::showOptions()
298 RS_DEBUG->print("ActionDrawLine::showOptions");
299 ActionInterface::showOptions();
300 RS_DIALOGFACTORY->requestOptions(this, true);
301 RS_DEBUG->print("ActionDrawLine::showOptions: OK");
304 void ActionDrawLine::hideOptions()
306 ActionInterface::hideOptions();
307 RS_DIALOGFACTORY->requestOptions(this, false);
310 void ActionDrawLine::updateMouseCursor()
312 graphicView->setMouseCursor(RS2::CadCursor);
315 void ActionDrawLine::updateToolBar()
318 RS_DIALOGFACTORY->requestToolBar(RS2::ToolBarSnap);
320 RS_DIALOGFACTORY->requestToolBar(RS2::ToolBarLines);
323 void ActionDrawLine::close()
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)
329 data.endpoint = start;
331 setStatus(SetStartpoint);
332 graphicView->moveRelativeZero(start);
335 RS_DIALOGFACTORY->commandMessage(tr("Cannot close sequence of lines: Not enough entities defined yet."));
338 void ActionDrawLine::undo()
340 //NOTE: We should grey out the "undo" button until the conditions for its use are satisfied.
341 if (history.count() > 1)
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();
351 RS_DIALOGFACTORY->commandMessage(tr("Cannot undo: Not enough entities defined yet."));
354 void ActionDrawLine::ClearHistory(void)
356 while (!history.isEmpty())
357 delete history.takeFirst();