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 graphicView.preview.SetVisible();
33 RS_DEBUG->print("RS_ActionDrawLine::RS_ActionDrawLine: OK");
36 RS_ActionDrawLine::~RS_ActionDrawLine()
41 /*virtual*/ RS2::ActionType RS_ActionDrawLine::rtti()
43 return RS2::ActionDrawLine;
46 void RS_ActionDrawLine::reset()
48 RS_DEBUG->print("RS_ActionDrawLine::reset");
49 data = RS_LineData(Vector(false), Vector(false));
50 start = Vector(false);
52 RS_DEBUG->print("RS_ActionDrawLine::reset: OK");
55 void RS_ActionDrawLine::init(int status)
57 RS_DEBUG->print("RS_ActionDrawLine::init");
58 RS_PreviewActionInterface::init(status);
60 RS_DEBUG->print("RS_ActionDrawLine::init: OK");
63 void RS_ActionDrawLine::trigger()
66 RS_PreviewActionInterface::trigger(); // XOR off screen, delete entities in container
68 graphicView->preview.clear();
69 // graphicView->redraw();
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("RS_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("RS_ActionDrawLine::trigger(): line added: %d", line->getId());
96 void RS_ActionDrawLine::mouseMoveEvent(QMouseEvent * e)
98 RS_DEBUG->print("RS_ActionDrawLine::mouseMoveEvent begin");
100 RS_DEBUG->print("RS_ActionDrawLine::mouseMoveEvent: snap point");
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");
108 //not needed, but without this, it doesn't draw... strange...
109 //obviously we haven't gotten our rendering path correct...
110 // deletePreview(); // XOR off of screen
111 clearPreview(); // Remove entities from the container
112 preview->addEntity(new RS_Line(preview, RS_LineData(data.startpoint, mouse)));
113 RS_DEBUG->print("RS_ActionDrawLine::mouseMoveEvent: draw preview");
114 // drawPreview(); // XOR on screen
115 xorPreview(); // XOR on screen
117 // This is lame. Creating a new Line every time the endpoint moves.
118 // Surely we can alter the line entity inside the preview, no?
119 graphicView->preview.clear(); // Remove entities from the container
120 RS_Line * line = new RS_Line(&(graphicView->preview), RS_LineData(data.startpoint, mouse));
121 //wha? Even THIS doesn't work!!! It was the container...
122 // line->setPen(RS_Pen(RS_Color(60, 255, 60), RS2::Width00, RS2::SolidLine));
123 graphicView->preview.addEntity(line);
127 //hm. [ok, this works. :-D]
128 graphicView->redraw();
129 RS_DEBUG->print("RS_ActionDrawLine::mouseMoveEvent end");
132 void RS_ActionDrawLine::mouseReleaseEvent(QMouseEvent * e)
134 if (e->button() == Qt::LeftButton)
136 Vector ce(snapPoint(e));
137 coordinateEvent(&ce);
139 else if (e->button() == Qt::RightButton)
141 if (getStatus() == 0)
143 graphicView->snapper.SetVisible(false);
144 graphicView->preview.SetVisible(false);
148 deletePreview(); // XOR off of screen
149 clearPreview(); // Remove entities from the container
152 init(getStatus() - 1);
155 //hm. [Seems to work OK.]
156 graphicView->preview.clear(); // Remove entities from container
157 graphicView->redraw();
160 void RS_ActionDrawLine::coordinateEvent(Vector * e)
162 RS_DEBUG->print("RS_ActionDrawLine::coordinateEvent");
166 RS_DEBUG->print("RS_ActionDrawLine::coordinateEvent: event was NULL");
175 data.startpoint = mouse;
177 history.append(new Vector(mouse));
178 start = data.startpoint;
179 setStatus(SetEndpoint);
180 graphicView->moveRelativeZero(mouse);
181 updateMouseButtonHints();
185 data.endpoint = mouse;
186 history.append(new Vector(mouse));
188 data.startpoint = data.endpoint;
189 updateMouseButtonHints();
196 RS_DEBUG->print("RS_ActionDrawLine::coordinateEvent: OK");
199 void RS_ActionDrawLine::commandEvent(RS_CommandEvent * e)
201 RS_DEBUG->print("RS_ActionDrawLine::commandEvent");
202 QString c = e->getCommand().toLower();
208 if (checkCommand("help", c))
210 RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
211 + getAvailableCommands().join(", "));
218 if (checkCommand("close", c))
221 updateMouseButtonHints();
225 if (checkCommand("undo", c))
228 updateMouseButtonHints();
237 RS_DEBUG->print("RS_ActionDrawLine::commandEvent: OK");
240 QStringList RS_ActionDrawLine::getAvailableCommands()
251 if (history.count() >= 2)
252 cmd += command("undo");
254 if (history.count() >= 3)
255 cmd += command("close");
266 void RS_ActionDrawLine::updateMouseButtonHints()
271 RS_DIALOGFACTORY->updateMouseWidget(tr("Specify first point"), tr("Cancel"));
278 if (history.count() >= 3)
280 msg += RS_COMMANDS->command("close");
284 if (history.count() >= 2)
285 msg += RS_COMMANDS->command("undo");
287 if (history.count() >= 2)
288 RS_DIALOGFACTORY->updateMouseWidget(tr("Specify next point or [%1]").arg(msg), tr("Back"));
290 RS_DIALOGFACTORY->updateMouseWidget(tr("Specify next point"), tr("Back"));
295 RS_DIALOGFACTORY->updateMouseWidget("", "");
300 void RS_ActionDrawLine::showOptions()
302 RS_DEBUG->print("RS_ActionDrawLine::showOptions");
303 RS_ActionInterface::showOptions();
304 RS_DIALOGFACTORY->requestOptions(this, true);
305 RS_DEBUG->print("RS_ActionDrawLine::showOptions: OK");
308 void RS_ActionDrawLine::hideOptions()
310 RS_ActionInterface::hideOptions();
311 RS_DIALOGFACTORY->requestOptions(this, false);
314 void RS_ActionDrawLine::updateMouseCursor()
316 graphicView->setMouseCursor(RS2::CadCursor);
319 void RS_ActionDrawLine::updateToolBar()
322 RS_DIALOGFACTORY->requestToolBar(RS2::ToolBarSnap);
324 RS_DIALOGFACTORY->requestToolBar(RS2::ToolBarLines);
327 void RS_ActionDrawLine::close()
329 //NOTE: We should grey out the "close" button until the conditions for its use are satisfied.
330 // Though I can see how this would be called via cmd line... So I guess it's OK
331 if (history.count() > 2 && start.valid)
333 data.endpoint = start;
335 setStatus(SetStartpoint);
336 graphicView->moveRelativeZero(start);
339 RS_DIALOGFACTORY->commandMessage(tr("Cannot close sequence of lines: Not enough entities defined yet."));
342 void RS_ActionDrawLine::undo()
344 //NOTE: We should grey out the "undo" button until the conditions for its use are satisfied.
345 if (history.count() > 1)
347 history.removeLast();
348 // deletePreview(); // XOR off of screen
349 // clearPreview(); // Delete entities in container
350 graphicView->setCurrentAction(new RS_ActionEditUndo(true, *container, *graphicView));
351 data.startpoint = *history.last();
352 graphicView->moveRelativeZero(data.startpoint);
353 graphicView->preview.clear();
354 graphicView->redraw();
357 RS_DIALOGFACTORY->commandMessage(tr("Cannot undo: Not enough entities defined yet."));
360 void RS_ActionDrawLine::ClearHistory(void)
362 while (!history.isEmpty())
363 delete history.takeFirst();