1 // rs_actiondrawline.cpp
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 "rs_actiondrawline.h"
17 #include "rs_actioneditundo.h"
18 #include "rs_commandevent.h"
20 #include "rs_dialogfactory.h"
21 #include "graphicview.h"
22 #include "rs_preview.h"
24 RS_ActionDrawLine::RS_ActionDrawLine(RS_EntityContainer & container, GraphicView & graphicView):
25 RS_PreviewActionInterface("Draw lines", container, graphicView)
27 RS_DEBUG->print("RS_ActionDrawLine::RS_ActionDrawLine");
30 graphicView.snapper.SetContainer(&container);
31 graphicView.snapper.SetGraphicView(&graphicView);
32 graphicView.snapper.SetVisible();
33 graphicView.preview.SetVisible();
34 RS_DEBUG->print("RS_ActionDrawLine::RS_ActionDrawLine: OK");
37 RS_ActionDrawLine::~RS_ActionDrawLine()
42 /*virtual*/ RS2::ActionType RS_ActionDrawLine::rtti()
44 return RS2::ActionDrawLine;
47 void RS_ActionDrawLine::reset()
49 RS_DEBUG->print("RS_ActionDrawLine::reset");
50 data = RS_LineData(Vector(false), Vector(false));
51 start = Vector(false);
53 RS_DEBUG->print("RS_ActionDrawLine::reset: OK");
56 void RS_ActionDrawLine::init(int status)
58 RS_DEBUG->print("RS_ActionDrawLine::init");
59 // RS_PreviewActionInterface::init(status);
60 RS_ActionInterface::init(status);
62 RS_DEBUG->print("RS_ActionDrawLine::init: OK");
65 void RS_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("RS_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("RS_ActionDrawLine::trigger(): line added: %d", line->getId());
93 void RS_ActionDrawLine::mouseMoveEvent(QMouseEvent * e)
95 RS_DEBUG->print("RS_ActionDrawLine::mouseMoveEvent begin");
97 RS_DEBUG->print("RS_ActionDrawLine::mouseMoveEvent: snap point");
98 Vector mouse = graphicView->snapper.snapPoint(e);
99 RS_DEBUG->print("RS_ActionDrawLine::mouseMoveEvent: snap point: OK");
101 if (getStatus() == SetEndpoint && data.startpoint.valid)
103 RS_DEBUG->print("RS_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("RS_ActionDrawLine::mouseMoveEvent end");
131 void RS_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 RS_ActionDrawLine::coordinateEvent(Vector * e)
156 RS_DEBUG->print("RS_ActionDrawLine::coordinateEvent");
160 RS_DEBUG->print("RS_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("RS_ActionDrawLine::coordinateEvent: OK");
193 void RS_ActionDrawLine::commandEvent(RS_CommandEvent * e)
195 RS_DEBUG->print("RS_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("RS_ActionDrawLine::commandEvent: OK");
234 QStringList RS_ActionDrawLine::getAvailableCommands()
245 if (history.count() >= 2)
246 cmd += command("undo");
248 if (history.count() >= 3)
249 cmd += command("close");
260 void RS_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 RS_ActionDrawLine::showOptions()
296 RS_DEBUG->print("RS_ActionDrawLine::showOptions");
297 RS_ActionInterface::showOptions();
298 RS_DIALOGFACTORY->requestOptions(this, true);
299 RS_DEBUG->print("RS_ActionDrawLine::showOptions: OK");
302 void RS_ActionDrawLine::hideOptions()
304 RS_ActionInterface::hideOptions();
305 RS_DIALOGFACTORY->requestOptions(this, false);
308 void RS_ActionDrawLine::updateMouseCursor()
310 graphicView->setMouseCursor(RS2::CadCursor);
313 void RS_ActionDrawLine::updateToolBar()
316 RS_DIALOGFACTORY->requestToolBar(RS2::ToolBarSnap);
318 RS_DIALOGFACTORY->requestToolBar(RS2::ToolBarLines);
321 void RS_ActionDrawLine::close()
323 //NOTE: We should grey out the "close" button until the conditions for its use are satisfied.
324 // Though I can see how this would be called via cmd line... So I guess it's OK
325 if (history.count() > 2 && start.valid)
327 data.endpoint = start;
329 setStatus(SetStartpoint);
330 graphicView->moveRelativeZero(start);
333 RS_DIALOGFACTORY->commandMessage(tr("Cannot close sequence of lines: Not enough entities defined yet."));
336 void RS_ActionDrawLine::undo()
338 //NOTE: We should grey out the "undo" button until the conditions for its use are satisfied.
339 if (history.count() > 1)
341 history.removeLast();
342 graphicView->setCurrentAction(new RS_ActionEditUndo(true, *container, *graphicView));
343 data.startpoint = *history.last();
344 graphicView->moveRelativeZero(data.startpoint);
345 graphicView->preview.clear();
346 graphicView->redraw();
349 RS_DIALOGFACTORY->commandMessage(tr("Cannot undo: Not enough entities defined yet."));
352 void RS_ActionDrawLine::ClearHistory(void)
354 while (!history.isEmpty())
355 delete history.takeFirst();