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);
63 ActionInterface::init(status);
65 RS_DEBUG->print("ActionDrawLine::init: OK");
68 void ActionDrawLine::trigger()
70 graphicView->preview.clear();
72 RS_Line * line = new RS_Line(container, data);
73 line->setLayerToActive();
74 line->setPenToActive();
75 container->addEntity(line);
76 //std::cout << container;
77 //printf("ActionDrawLine::trigger(): new line is %f,%f to %f,%f\n", data.startpoint.x, data.startpoint.y, data.endpoint.x, data.endpoint.y);
78 //This makes it come back as "Unknown Entity"
79 //std::cout << *((RS_Entity *)container);
80 //std::cout << *container;
85 document->startUndoCycle();
86 document->addUndoable(line);
87 document->endUndoCycle();
90 graphicView->moveRelativeZero(line->getEndpoint());
91 //hm. [OK, it just moves the relative zero tho. Overkill. And remove preview, so OK.]
92 graphicView->redraw();
93 RS_DEBUG->print("ActionDrawLine::trigger(): line added: %d", line->getId());
96 void ActionDrawLine::mouseMoveEvent(QMouseEvent * e)
98 RS_DEBUG->print("ActionDrawLine::mouseMoveEvent begin");
100 RS_DEBUG->print("ActionDrawLine::mouseMoveEvent: snap point");
101 Vector mouse = graphicView->snapper.snapPoint(e);
102 RS_DEBUG->print("ActionDrawLine::mouseMoveEvent: snap point: OK");
104 if (getStatus() == SetEndpoint && data.startpoint.valid)
106 RS_DEBUG->print("ActionDrawLine::mouseMoveEvent: update preview");
107 // This is lame. Creating a new Line every time the endpoint moves.
108 // Surely we can alter the line entity inside the preview, no?
110 graphicView->preview.clear(); // Remove entities from the container
111 RS_Line * line = new RS_Line(&(graphicView->preview), RS_LineData(data.startpoint, mouse));
112 graphicView->preview.addEntity(line);
114 // We can assume there's only one line in there, can't we?
115 RS_Line * line = (RS_Line *)graphicView->preview.firstEntity(RS2::ResolveNone);
119 line->setEndpoint(mouse);
123 line = new RS_Line(&(graphicView->preview), RS_LineData(data.startpoint, mouse));
124 graphicView->preview.addEntity(line);
129 //hm. [ok, this works. :-D]
130 graphicView->redraw();
131 RS_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 coordinateEvent(&ce);
141 else if (e->button() == Qt::RightButton)
143 if (getStatus() == 0)
145 graphicView->snapper.SetVisible(false);
146 graphicView->preview.SetVisible(false);
149 init(getStatus() - 1);
152 //hm. [Seems to work OK.]
153 graphicView->preview.clear(); // Remove entities from container
154 graphicView->redraw();
157 void ActionDrawLine::coordinateEvent(Vector * e)
159 RS_DEBUG->print("ActionDrawLine::coordinateEvent");
163 RS_DEBUG->print("ActionDrawLine::coordinateEvent: event was NULL");
172 data.startpoint = mouse;
174 history.append(new Vector(mouse));
175 start = data.startpoint;
176 setStatus(SetEndpoint);
177 graphicView->moveRelativeZero(mouse);
178 updateMouseButtonHints();
182 data.endpoint = mouse;
183 history.append(new Vector(mouse));
185 data.startpoint = data.endpoint;
186 updateMouseButtonHints();
193 RS_DEBUG->print("ActionDrawLine::coordinateEvent: OK");
196 void ActionDrawLine::commandEvent(RS_CommandEvent * e)
198 RS_DEBUG->print("ActionDrawLine::commandEvent");
199 QString c = e->getCommand().toLower();
205 if (checkCommand("help", c))
207 RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
208 + getAvailableCommands().join(", "));
215 if (checkCommand("close", c))
218 updateMouseButtonHints();
222 if (checkCommand("undo", c))
225 updateMouseButtonHints();
234 RS_DEBUG->print("ActionDrawLine::commandEvent: OK");
237 QStringList ActionDrawLine::getAvailableCommands()
248 if (history.count() >= 2)
249 cmd += command("undo");
251 if (history.count() >= 3)
252 cmd += command("close");
263 void ActionDrawLine::updateMouseButtonHints()
268 RS_DIALOGFACTORY->updateMouseWidget(tr("Specify first point"), tr("Cancel"));
275 if (history.count() >= 3)
277 msg += RS_COMMANDS->command("close");
281 if (history.count() >= 2)
282 msg += RS_COMMANDS->command("undo");
284 if (history.count() >= 2)
285 RS_DIALOGFACTORY->updateMouseWidget(tr("Specify next point or [%1]").arg(msg), tr("Back"));
287 RS_DIALOGFACTORY->updateMouseWidget(tr("Specify next point"), tr("Back"));
292 RS_DIALOGFACTORY->updateMouseWidget("", "");
297 void ActionDrawLine::showOptions()
299 RS_DEBUG->print("ActionDrawLine::showOptions");
300 // ActionInterface::showOptions();
301 ActionInterface::showOptions();
302 RS_DIALOGFACTORY->requestOptions(this, true);
303 RS_DEBUG->print("ActionDrawLine::showOptions: OK");
306 void ActionDrawLine::hideOptions()
308 // ActionInterface::hideOptions();
309 ActionInterface::hideOptions();
310 RS_DIALOGFACTORY->requestOptions(this, false);
313 void ActionDrawLine::updateMouseCursor()
315 graphicView->setMouseCursor(RS2::CadCursor);
318 void ActionDrawLine::updateToolBar()
321 RS_DIALOGFACTORY->requestToolBar(RS2::ToolBarSnap);
323 RS_DIALOGFACTORY->requestToolBar(RS2::ToolBarLines);
326 void ActionDrawLine::close()
328 //NOTE: We should grey out the "close" button until the conditions for its use are satisfied.
329 // Though I can see how this would be called via cmd line... So I guess it's OK
330 if (history.count() > 2 && start.valid)
332 data.endpoint = start;
334 setStatus(SetStartpoint);
335 graphicView->moveRelativeZero(start);
338 RS_DIALOGFACTORY->commandMessage(tr("Cannot close sequence of lines: Not enough entities defined yet."));
341 void ActionDrawLine::undo()
343 //NOTE: We should grey out the "undo" button until the conditions for its use are satisfied.
344 if (history.count() > 1)
346 history.removeLast();
347 graphicView->setCurrentAction(new ActionEditUndo(true, *container, *graphicView));
348 data.startpoint = *history.last();
349 graphicView->moveRelativeZero(data.startpoint);
350 graphicView->preview.clear();
351 graphicView->redraw();
354 RS_DIALOGFACTORY->commandMessage(tr("Cannot undo: Not enough entities defined yet."));
357 void ActionDrawLine::ClearHistory(void)
359 while (!history.isEmpty())
360 delete history.takeFirst();