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");
29 graphicView.snapper.SetContainer(&container);
30 graphicView.snapper.SetGraphicView(&graphicView);
31 graphicView.snapper.SetVisible();
32 RS_DEBUG->print("RS_ActionDrawLine::RS_ActionDrawLine: OK");
35 RS_ActionDrawLine::~RS_ActionDrawLine()
40 /*virtual*/ RS2::ActionType RS_ActionDrawLine::rtti()
42 return RS2::ActionDrawLine;
45 void RS_ActionDrawLine::reset()
47 RS_DEBUG->print("RS_ActionDrawLine::reset");
48 data = RS_LineData(Vector(false), Vector(false));
49 start = Vector(false);
51 RS_DEBUG->print("RS_ActionDrawLine::reset: OK");
54 void RS_ActionDrawLine::init(int status)
56 RS_DEBUG->print("RS_ActionDrawLine::init");
57 RS_PreviewActionInterface::init(status);
59 RS_DEBUG->print("RS_ActionDrawLine::init: OK");
62 void RS_ActionDrawLine::trigger()
64 RS_PreviewActionInterface::trigger(); // XOR off screen, delete entities in container
66 RS_Line * line = new RS_Line(container, data);
67 line->setLayerToActive();
68 line->setPenToActive();
69 container->addEntity(line);
70 //std::cout << container;
71 //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);
72 //This makes it come back as "Unknown Entity"
73 //std::cout << *((RS_Entity *)container);
74 //std::cout << *container;
79 document->startUndoCycle();
80 document->addUndoable(line);
81 document->endUndoCycle();
84 // deleteSnapper(); // XOR off of screen
85 // graphicView->moveRelativeZero(Vector(0.0, 0.0));
86 //This is unnecessary, because we added this to the container...
87 //#warning "!!! Here's the trouble... Trying to draw direct !!!"
88 // graphicView->drawEntity(line);
89 graphicView->moveRelativeZero(line->getEndpoint());
90 // drawSnapper(); // XOR on screen
91 RS_DEBUG->print("RS_ActionDrawLine::trigger(): line added: %d", line->getId());
94 void RS_ActionDrawLine::mouseMoveEvent(QMouseEvent * e)
96 RS_DEBUG->print("RS_ActionDrawLine::mouseMoveEvent begin");
98 RS_DEBUG->print("RS_ActionDrawLine::mouseMoveEvent: snap point");
99 //This used to draw the snapper, but now that's defunct... so, !!! FIX !!!
100 // Vector mouse = snapPoint(e);
101 Vector mouse = graphicView->snapper.snapPoint(e);
102 RS_DEBUG->print("RS_ActionDrawLine::mouseMoveEvent: snap point: OK");
104 if (getStatus() == SetEndpoint && data.startpoint.valid)
106 RS_DEBUG->print("RS_ActionDrawLine::mouseMoveEvent: update preview");
107 //not needed, but without this, it doesn't draw... strange...
108 //obviously we haven't gotten our rendering path correct...
109 // deletePreview(); // XOR off of screen
110 clearPreview(); // Remove entities from the container
111 preview->addEntity(new RS_Line(preview, RS_LineData(data.startpoint, mouse)));
112 RS_DEBUG->print("RS_ActionDrawLine::mouseMoveEvent: draw preview");
113 // drawPreview(); // XOR on screen
114 xorPreview(); // XOR on screen
118 graphicView->redraw();
119 RS_DEBUG->print("RS_ActionDrawLine::mouseMoveEvent end");
122 void RS_ActionDrawLine::mouseReleaseEvent(QMouseEvent * e)
124 if (e->button() == Qt::LeftButton)
126 Vector ce(snapPoint(e));
127 coordinateEvent(&ce);
129 else if (e->button() == Qt::RightButton)
131 deletePreview(); // XOR off of screen
132 clearPreview(); // Remove entities from the container
133 // deleteSnapper(); // XOR off of screen
134 init(getStatus() - 1);
138 void RS_ActionDrawLine::coordinateEvent(Vector * e)
140 RS_DEBUG->print("RS_ActionDrawLine::coordinateEvent");
144 RS_DEBUG->print("RS_ActionDrawLine::coordinateEvent: event was NULL");
153 data.startpoint = mouse;
155 history.append(new Vector(mouse));
156 start = data.startpoint;
157 setStatus(SetEndpoint);
158 graphicView->moveRelativeZero(mouse);
159 updateMouseButtonHints();
163 data.endpoint = mouse;
164 history.append(new Vector(mouse));
166 data.startpoint = data.endpoint;
167 updateMouseButtonHints();
174 RS_DEBUG->print("RS_ActionDrawLine::coordinateEvent: OK");
177 void RS_ActionDrawLine::commandEvent(RS_CommandEvent * e)
179 RS_DEBUG->print("RS_ActionDrawLine::commandEvent");
180 QString c = e->getCommand().toLower();
186 if (checkCommand("help", c))
188 RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
189 + getAvailableCommands().join(", "));
196 if (checkCommand("close", c))
199 updateMouseButtonHints();
203 if (checkCommand("undo", c))
206 updateMouseButtonHints();
215 RS_DEBUG->print("RS_ActionDrawLine::commandEvent: OK");
218 QStringList RS_ActionDrawLine::getAvailableCommands()
229 if (history.count() >= 2)
230 cmd += command("undo");
232 if (history.count() >= 3)
233 cmd += command("close");
244 void RS_ActionDrawLine::updateMouseButtonHints()
249 RS_DIALOGFACTORY->updateMouseWidget(tr("Specify first point"), tr("Cancel"));
256 if (history.count() >= 3)
258 msg += RS_COMMANDS->command("close");
262 if (history.count() >= 2)
263 msg += RS_COMMANDS->command("undo");
265 if (history.count() >= 2)
266 RS_DIALOGFACTORY->updateMouseWidget(tr("Specify next point or [%1]").arg(msg), tr("Back"));
268 RS_DIALOGFACTORY->updateMouseWidget(tr("Specify next point"), tr("Back"));
273 RS_DIALOGFACTORY->updateMouseWidget("", "");
278 void RS_ActionDrawLine::showOptions()
280 RS_DEBUG->print("RS_ActionDrawLine::showOptions");
281 RS_ActionInterface::showOptions();
282 RS_DIALOGFACTORY->requestOptions(this, true);
283 RS_DEBUG->print("RS_ActionDrawLine::showOptions: OK");
286 void RS_ActionDrawLine::hideOptions()
288 RS_ActionInterface::hideOptions();
289 RS_DIALOGFACTORY->requestOptions(this, false);
292 void RS_ActionDrawLine::updateMouseCursor()
294 graphicView->setMouseCursor(RS2::CadCursor);
297 void RS_ActionDrawLine::updateToolBar()
300 RS_DIALOGFACTORY->requestToolBar(RS2::ToolBarSnap);
302 RS_DIALOGFACTORY->requestToolBar(RS2::ToolBarLines);
305 void RS_ActionDrawLine::close()
307 //NOTE: We should grey out the "close" button until the conditions for its use are satisfied.
308 // Though I can see how this would be called via cmd line... So I guess it's OK
309 if (history.count() > 2 && start.valid)
311 data.endpoint = start;
313 setStatus(SetStartpoint);
314 graphicView->moveRelativeZero(start);
317 RS_DIALOGFACTORY->commandMessage(tr("Cannot close sequence of lines: Not enough entities defined yet."));
320 void RS_ActionDrawLine::undo()
322 //NOTE: We should grey out the "undo" button until the conditions for its use are satisfied.
323 if (history.count() > 1)
325 history.removeLast();
326 deletePreview(); // XOR off of screen
327 clearPreview(); // Delete entities in container
328 graphicView->setCurrentAction(new RS_ActionEditUndo(true, *container, *graphicView));
329 data.startpoint = *history.last();
330 graphicView->moveRelativeZero(data.startpoint);
333 RS_DIALOGFACTORY->commandMessage(tr("Cannot undo: Not enough entities defined yet."));
336 void RS_ActionDrawLine::ClearHistory(void)
338 while (!history.isEmpty())
339 delete history.takeFirst();