1 // rs_actiondrawline.cpp
3 // Originally part of QCad Community Edition by Andrew Mustun
4 // Extensively rewritten and refactored by James L. Hammons
5 // (C) 2010 Underground Software
7 // JLH = James L. Hammons <jlhamm@acm.org>
10 // --- ---------- -----------------------------------------------------------
11 // JLH 05/19/2010 Added this text. :-)
14 #include "rs_actiondrawline.h"
16 #include "rs_actioneditundo.h"
17 #include "rs_commandevent.h"
19 #include "rs_dialogfactory.h"
20 #include "graphicview.h"
21 #include "rs_preview.h"
23 RS_ActionDrawLine::RS_ActionDrawLine(RS_EntityContainer & container, GraphicView & graphicView):
24 RS_PreviewActionInterface("Draw lines", container, graphicView)
26 RS_DEBUG->print("RS_ActionDrawLine::RS_ActionDrawLine");
28 RS_DEBUG->print("RS_ActionDrawLine::RS_ActionDrawLine: OK");
31 RS_ActionDrawLine::~RS_ActionDrawLine()
36 /*virtual*/ RS2::ActionType RS_ActionDrawLine::rtti()
38 return RS2::ActionDrawLine;
41 void RS_ActionDrawLine::reset()
43 RS_DEBUG->print("RS_ActionDrawLine::reset");
44 data = RS_LineData(Vector(false), Vector(false));
45 start = Vector(false);
47 RS_DEBUG->print("RS_ActionDrawLine::reset: OK");
50 void RS_ActionDrawLine::init(int status)
52 RS_DEBUG->print("RS_ActionDrawLine::init");
53 RS_PreviewActionInterface::init(status);
55 RS_DEBUG->print("RS_ActionDrawLine::init: OK");
58 void RS_ActionDrawLine::trigger()
60 RS_PreviewActionInterface::trigger(); // XOR off screen, delete entities in container
62 RS_Line * line = new RS_Line(container, data);
63 line->setLayerToActive();
64 line->setPenToActive();
65 container->addEntity(line);
66 //std::cout << container;
67 //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);
68 //This makes it come back as "Unknown Entity"
69 //std::cout << *((RS_Entity *)container);
70 //std::cout << *container;
75 document->startUndoCycle();
76 document->addUndoable(line);
77 document->endUndoCycle();
80 deleteSnapper(); // XOR off of screen
81 graphicView->moveRelativeZero(Vector(0.0, 0.0));
82 //This is unnecessary, because we added this to the container...
83 //#warning "!!! Here's the trouble... Trying to draw direct !!!"
84 // graphicView->drawEntity(line);
85 graphicView->moveRelativeZero(line->getEndpoint());
86 drawSnapper(); // XOR on screen
87 RS_DEBUG->print("RS_ActionDrawLine::trigger(): line added: %d", line->getId());
90 void RS_ActionDrawLine::mouseMoveEvent(QMouseEvent * e)
92 RS_DEBUG->print("RS_ActionDrawLine::mouseMoveEvent begin");
94 RS_DEBUG->print("RS_ActionDrawLine::mouseMoveEvent: snap point");
95 Vector mouse = snapPoint(e);
96 RS_DEBUG->print("RS_ActionDrawLine::mouseMoveEvent: snap point: OK");
98 if (getStatus() == SetEndpoint && data.startpoint.valid)
100 RS_DEBUG->print("RS_ActionDrawLine::mouseMoveEvent: update preview");
101 //not needed, but without this, it doesn't draw... strange...
102 //obviously we haven't gotten our rendering path correct...
103 // deletePreview(); // XOR off of screen
104 clearPreview(); // Remove entities from the container
105 preview->addEntity(new RS_Line(preview, RS_LineData(data.startpoint, mouse)));
106 RS_DEBUG->print("RS_ActionDrawLine::mouseMoveEvent: draw preview");
107 // drawPreview(); // XOR on screen
108 xorPreview(); // XOR on screen
111 RS_DEBUG->print("RS_ActionDrawLine::mouseMoveEvent end");
114 void RS_ActionDrawLine::mouseReleaseEvent(QMouseEvent * e)
116 if (e->button() == Qt::LeftButton)
118 Vector ce(snapPoint(e));
119 coordinateEvent(&ce);
121 else if (e->button() == Qt::RightButton)
123 deletePreview(); // XOR off of screen
124 clearPreview(); // Remove entities from the container
125 deleteSnapper(); // XOR off of screen
126 init(getStatus() - 1);
130 void RS_ActionDrawLine::coordinateEvent(Vector * e)
132 RS_DEBUG->print("RS_ActionDrawLine::coordinateEvent");
136 RS_DEBUG->print("RS_ActionDrawLine::coordinateEvent: event was NULL");
145 data.startpoint = mouse;
147 history.append(new Vector(mouse));
148 start = data.startpoint;
149 setStatus(SetEndpoint);
150 graphicView->moveRelativeZero(mouse);
151 updateMouseButtonHints();
155 data.endpoint = mouse;
156 history.append(new Vector(mouse));
158 data.startpoint = data.endpoint;
159 updateMouseButtonHints();
166 RS_DEBUG->print("RS_ActionDrawLine::coordinateEvent: OK");
169 void RS_ActionDrawLine::commandEvent(RS_CommandEvent * e)
171 RS_DEBUG->print("RS_ActionDrawLine::commandEvent");
172 QString c = e->getCommand().toLower();
178 if (checkCommand("help", c))
180 RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
181 + getAvailableCommands().join(", "));
188 if (checkCommand("close", c))
191 updateMouseButtonHints();
195 if (checkCommand("undo", c))
198 updateMouseButtonHints();
207 RS_DEBUG->print("RS_ActionDrawLine::commandEvent: OK");
210 QStringList RS_ActionDrawLine::getAvailableCommands()
221 if (history.count() >= 2)
222 cmd += command("undo");
224 if (history.count() >= 3)
225 cmd += command("close");
236 void RS_ActionDrawLine::updateMouseButtonHints()
241 RS_DIALOGFACTORY->updateMouseWidget(tr("Specify first point"), tr("Cancel"));
248 if (history.count() >= 3)
250 msg += RS_COMMANDS->command("close");
254 if (history.count() >= 2)
255 msg += RS_COMMANDS->command("undo");
257 if (history.count() >= 2)
258 RS_DIALOGFACTORY->updateMouseWidget(tr("Specify next point or [%1]").arg(msg), tr("Back"));
260 RS_DIALOGFACTORY->updateMouseWidget(tr("Specify next point"), tr("Back"));
265 RS_DIALOGFACTORY->updateMouseWidget("", "");
270 void RS_ActionDrawLine::showOptions()
272 RS_DEBUG->print("RS_ActionDrawLine::showOptions");
273 RS_ActionInterface::showOptions();
274 RS_DIALOGFACTORY->requestOptions(this, true);
275 RS_DEBUG->print("RS_ActionDrawLine::showOptions: OK");
278 void RS_ActionDrawLine::hideOptions()
280 RS_ActionInterface::hideOptions();
281 RS_DIALOGFACTORY->requestOptions(this, false);
284 void RS_ActionDrawLine::updateMouseCursor()
286 graphicView->setMouseCursor(RS2::CadCursor);
289 void RS_ActionDrawLine::updateToolBar()
292 RS_DIALOGFACTORY->requestToolBar(RS2::ToolBarSnap);
294 RS_DIALOGFACTORY->requestToolBar(RS2::ToolBarLines);
297 void RS_ActionDrawLine::close()
299 //NOTE: We should grey out the "close" button until the conditions for its use are satisfied.
300 // Though I can see how this would be called via cmd line... So I guess it's OK
301 if (history.count() > 2 && start.valid)
303 data.endpoint = start;
305 setStatus(SetStartpoint);
306 graphicView->moveRelativeZero(start);
309 RS_DIALOGFACTORY->commandMessage(tr("Cannot close sequence of lines: Not enough entities defined yet."));
312 void RS_ActionDrawLine::undo()
314 //NOTE: We should grey out the "undo" button until the conditions for its use are satisfied.
315 if (history.count() > 1)
317 history.removeLast();
318 deletePreview(); // XOR off of screen
319 clearPreview(); // Delete entities in container
320 graphicView->setCurrentAction(new RS_ActionEditUndo(true, *container, *graphicView));
321 data.startpoint = *history.last();
322 graphicView->moveRelativeZero(data.startpoint);
325 RS_DIALOGFACTORY->commandMessage(tr("Cannot undo: Not enough entities defined yet."));
328 void RS_ActionDrawLine::ClearHistory(void)
330 while (!history.isEmpty())
331 delete history.takeFirst();