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 // (C) 2010 Underground Software
8 // JLH = James L. Hammons <jlhamm@acm.org>
11 // --- ---------- -----------------------------------------------------------
12 // JLH 05/19/2010 Added this text. :-)
15 #include "actiondrawline.h"
17 #include "actioneditundo.h"
18 #include "rs_commandevent.h"
20 #include "rs_dialogfactory.h"
21 #include "graphicview.h"
22 #include "rs_preview.h"
24 ActionDrawLine::ActionDrawLine(RS_EntityContainer & container, GraphicView & graphicView):
25 ActionInterface("Draw lines", container, graphicView)
27 RS_DEBUG->print("ActionDrawLine::ActionDrawLine");
30 graphicView.snapper.SetContainer(&container);
31 graphicView.snapper.SetGraphicView(&graphicView);
32 graphicView.snapper.SetVisible();
33 graphicView.preview.SetVisible();
34 RS_DEBUG->print("ActionDrawLine::ActionDrawLine: OK");
37 ActionDrawLine::~ActionDrawLine()
42 /*virtual*/ RS2::ActionType ActionDrawLine::rtti()
44 return RS2::ActionDrawLine;
47 void ActionDrawLine::reset()
49 RS_DEBUG->print("ActionDrawLine::reset");
50 data = RS_LineData(Vector(false), Vector(false));
51 start = Vector(false);
53 RS_DEBUG->print("ActionDrawLine::reset: OK");
56 void ActionDrawLine::init(int status)
58 RS_DEBUG->print("ActionDrawLine::init");
59 // ActionInterface::init(status);
60 ActionInterface::init(status);
62 RS_DEBUG->print("ActionDrawLine::init: OK");
65 void ActionDrawLine::trigger()
67 graphicView->preview.clear();
69 RS_Line * line = new RS_Line(container, data);
70 line->setLayerToActive();
71 line->setPenToActive();
72 container->addEntity(line);
73 //std::cout << container;
74 //printf("ActionDrawLine::trigger(): new line is %f,%f to %f,%f\n", data.startpoint.x, data.startpoint.y, data.endpoint.x, data.endpoint.y);
75 //This makes it come back as "Unknown Entity"
76 //std::cout << *((RS_Entity *)container);
77 //std::cout << *container;
82 document->startUndoCycle();
83 document->addUndoable(line);
84 document->endUndoCycle();
87 graphicView->moveRelativeZero(line->getEndpoint());
88 //hm. [OK, it just moves the relative zero tho. Overkill. And remove preview, so OK.]
89 graphicView->redraw();
90 RS_DEBUG->print("ActionDrawLine::trigger(): line added: %d", line->getId());
93 void ActionDrawLine::mouseMoveEvent(QMouseEvent * e)
95 RS_DEBUG->print("ActionDrawLine::mouseMoveEvent begin");
97 RS_DEBUG->print("ActionDrawLine::mouseMoveEvent: snap point");
98 Vector mouse = graphicView->snapper.snapPoint(e);
99 RS_DEBUG->print("ActionDrawLine::mouseMoveEvent: snap point: OK");
101 if (getStatus() == SetEndpoint && data.startpoint.valid)
103 RS_DEBUG->print("ActionDrawLine::mouseMoveEvent: update preview");
104 // This is lame. Creating a new Line every time the endpoint moves.
105 // Surely we can alter the line entity inside the preview, no?
107 graphicView->preview.clear(); // Remove entities from the container
108 RS_Line * line = new RS_Line(&(graphicView->preview), RS_LineData(data.startpoint, mouse));
109 graphicView->preview.addEntity(line);
111 // We can assume there's only one line in there, can't we?
112 RS_Line * line = (RS_Line *)graphicView->preview.firstEntity(RS2::ResolveNone);
116 line->setEndpoint(mouse);
120 line = new RS_Line(&(graphicView->preview), RS_LineData(data.startpoint, mouse));
121 graphicView->preview.addEntity(line);
126 //hm. [ok, this works. :-D]
127 graphicView->redraw();
128 RS_DEBUG->print("ActionDrawLine::mouseMoveEvent end");
131 void ActionDrawLine::mouseReleaseEvent(QMouseEvent * e)
133 if (e->button() == Qt::LeftButton)
135 Vector ce(graphicView->snapper.snapPoint(e));
136 coordinateEvent(&ce);
138 else if (e->button() == Qt::RightButton)
140 if (getStatus() == 0)
142 graphicView->snapper.SetVisible(false);
143 graphicView->preview.SetVisible(false);
146 init(getStatus() - 1);
149 //hm. [Seems to work OK.]
150 graphicView->preview.clear(); // Remove entities from container
151 graphicView->redraw();
154 void ActionDrawLine::coordinateEvent(Vector * e)
156 RS_DEBUG->print("ActionDrawLine::coordinateEvent");
160 RS_DEBUG->print("ActionDrawLine::coordinateEvent: event was NULL");
169 data.startpoint = mouse;
171 history.append(new Vector(mouse));
172 start = data.startpoint;
173 setStatus(SetEndpoint);
174 graphicView->moveRelativeZero(mouse);
175 updateMouseButtonHints();
179 data.endpoint = mouse;
180 history.append(new Vector(mouse));
182 data.startpoint = data.endpoint;
183 updateMouseButtonHints();
190 RS_DEBUG->print("ActionDrawLine::coordinateEvent: OK");
193 void ActionDrawLine::commandEvent(RS_CommandEvent * e)
195 RS_DEBUG->print("ActionDrawLine::commandEvent");
196 QString c = e->getCommand().toLower();
202 if (checkCommand("help", c))
204 RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
205 + getAvailableCommands().join(", "));
212 if (checkCommand("close", c))
215 updateMouseButtonHints();
219 if (checkCommand("undo", c))
222 updateMouseButtonHints();
231 RS_DEBUG->print("ActionDrawLine::commandEvent: OK");
234 QStringList ActionDrawLine::getAvailableCommands()
245 if (history.count() >= 2)
246 cmd += command("undo");
248 if (history.count() >= 3)
249 cmd += command("close");
260 void ActionDrawLine::updateMouseButtonHints()
265 RS_DIALOGFACTORY->updateMouseWidget(tr("Specify first point"), tr("Cancel"));
272 if (history.count() >= 3)
274 msg += RS_COMMANDS->command("close");
278 if (history.count() >= 2)
279 msg += RS_COMMANDS->command("undo");
281 if (history.count() >= 2)
282 RS_DIALOGFACTORY->updateMouseWidget(tr("Specify next point or [%1]").arg(msg), tr("Back"));
284 RS_DIALOGFACTORY->updateMouseWidget(tr("Specify next point"), tr("Back"));
289 RS_DIALOGFACTORY->updateMouseWidget("", "");
294 void ActionDrawLine::showOptions()
296 RS_DEBUG->print("ActionDrawLine::showOptions");
297 // ActionInterface::showOptions();
298 ActionInterface::showOptions();
299 RS_DIALOGFACTORY->requestOptions(this, true);
300 RS_DEBUG->print("ActionDrawLine::showOptions: OK");
303 void ActionDrawLine::hideOptions()
305 // ActionInterface::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();