]> Shamusworld >> Repos - architektonas/blob - src/actions/rs_actiondrawline.cpp
Check in prior to mucking around with preview/snapper rendering...
[architektonas] / src / actions / rs_actiondrawline.cpp
1 // rs_actiondrawline.cpp
2 //
3 // Originally part of QCad Community Edition by Andrew Mustun
4 // Extensively rewritten and refactored by James L. Hammons
5 // (C) 2010 Underground Software
6 //
7 // JLH = James L. Hammons <jlhamm@acm.org>
8 //
9 // Who  When        What
10 // ---  ----------  -----------------------------------------------------------
11 // JLH  05/19/2010  Added this text. :-)
12 //
13
14 #include "rs_actiondrawline.h"
15
16 #include "rs_actioneditundo.h"
17 #include "rs_commandevent.h"
18 #include "commands.h"
19 #include "rs_dialogfactory.h"
20 #include "graphicview.h"
21 #include "rs_preview.h"
22
23 RS_ActionDrawLine::RS_ActionDrawLine(RS_EntityContainer & container, GraphicView & graphicView):
24         RS_PreviewActionInterface("Draw lines", container, graphicView)
25 {
26         RS_DEBUG->print("RS_ActionDrawLine::RS_ActionDrawLine");
27         reset();
28         RS_DEBUG->print("RS_ActionDrawLine::RS_ActionDrawLine: OK");
29 }
30
31 RS_ActionDrawLine::~RS_ActionDrawLine()
32 {
33         ClearHistory();
34 }
35
36 /*virtual*/ RS2::ActionType RS_ActionDrawLine::rtti()
37 {
38         return RS2::ActionDrawLine;
39 }
40
41 void RS_ActionDrawLine::reset()
42 {
43         RS_DEBUG->print("RS_ActionDrawLine::reset");
44         data = RS_LineData(Vector(false), Vector(false));
45         start = Vector(false);
46         ClearHistory();
47         RS_DEBUG->print("RS_ActionDrawLine::reset: OK");
48 }
49
50 void RS_ActionDrawLine::init(int status)
51 {
52         RS_DEBUG->print("RS_ActionDrawLine::init");
53         RS_PreviewActionInterface::init(status);
54         reset();
55         RS_DEBUG->print("RS_ActionDrawLine::init: OK");
56 }
57
58 void RS_ActionDrawLine::trigger()
59 {
60         RS_PreviewActionInterface::trigger();   // XOR off screen, delete entities in container
61
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;
71
72         // Update undo list:
73         if (document)
74         {
75                 document->startUndoCycle();
76                 document->addUndoable(line);
77                 document->endUndoCycle();
78         }
79
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());
88 }
89
90 void RS_ActionDrawLine::mouseMoveEvent(QMouseEvent * e)
91 {
92         RS_DEBUG->print("RS_ActionDrawLine::mouseMoveEvent begin");
93
94         RS_DEBUG->print("RS_ActionDrawLine::mouseMoveEvent: snap point");
95         Vector mouse = snapPoint(e);
96         RS_DEBUG->print("RS_ActionDrawLine::mouseMoveEvent: snap point: OK");
97
98         if (getStatus() == SetEndpoint && data.startpoint.valid)
99         {
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
109         }
110
111         RS_DEBUG->print("RS_ActionDrawLine::mouseMoveEvent end");
112 }
113
114 void RS_ActionDrawLine::mouseReleaseEvent(QMouseEvent * e)
115 {
116         if (e->button() == Qt::LeftButton)
117         {
118                 Vector ce(snapPoint(e));
119                 coordinateEvent(&ce);
120         }
121         else if (e->button() == Qt::RightButton)
122         {
123                 deletePreview();                // XOR off of screen
124                 clearPreview();                 // Remove entities from the container
125                 deleteSnapper();                // XOR off of screen
126                 init(getStatus() - 1);
127         }
128 }
129
130 void RS_ActionDrawLine::coordinateEvent(Vector * e)
131 {
132         RS_DEBUG->print("RS_ActionDrawLine::coordinateEvent");
133
134         if (!e)
135         {
136                 RS_DEBUG->print("RS_ActionDrawLine::coordinateEvent: event was NULL");
137                 return;
138         }
139
140         Vector mouse = *e;
141
142         switch (getStatus())
143         {
144         case SetStartpoint:
145                 data.startpoint = mouse;
146                 ClearHistory();
147                 history.append(new Vector(mouse));
148                 start = data.startpoint;
149                 setStatus(SetEndpoint);
150                 graphicView->moveRelativeZero(mouse);
151                 updateMouseButtonHints();
152                 break;
153
154         case SetEndpoint:
155                 data.endpoint = mouse;
156                 history.append(new Vector(mouse));
157                 trigger();
158                 data.startpoint = data.endpoint;
159                 updateMouseButtonHints();
160                 break;
161
162         default:
163                 break;
164         }
165
166         RS_DEBUG->print("RS_ActionDrawLine::coordinateEvent: OK");
167 }
168
169 void RS_ActionDrawLine::commandEvent(RS_CommandEvent * e)
170 {
171         RS_DEBUG->print("RS_ActionDrawLine::commandEvent");
172         QString c = e->getCommand().toLower();
173
174         switch (getStatus())
175         {
176         case SetStartpoint:
177
178                 if (checkCommand("help", c))
179                 {
180                         RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
181                                 + getAvailableCommands().join(", "));
182                         return;
183                 }
184                 break;
185
186         case SetEndpoint:
187
188                 if (checkCommand("close", c))
189                 {
190                         close();
191                         updateMouseButtonHints();
192                         return;
193                 }
194
195                 if (checkCommand("undo", c))
196                 {
197                         undo();
198                         updateMouseButtonHints();
199                         return;
200                 }
201                 break;
202
203         default:
204                 break;
205         }
206
207         RS_DEBUG->print("RS_ActionDrawLine::commandEvent: OK");
208 }
209
210 QStringList RS_ActionDrawLine::getAvailableCommands()
211 {
212         QStringList cmd;
213
214         switch (getStatus())
215         {
216         case SetStartpoint:
217                 break;
218
219         case SetEndpoint:
220
221                 if (history.count() >= 2)
222                         cmd += command("undo");
223
224                 if (history.count() >= 3)
225                         cmd += command("close");
226
227                 break;
228
229         default:
230                 break;
231         }
232
233         return cmd;
234 }
235
236 void RS_ActionDrawLine::updateMouseButtonHints()
237 {
238         switch (getStatus())
239         {
240         case SetStartpoint:
241                 RS_DIALOGFACTORY->updateMouseWidget(tr("Specify first point"), tr("Cancel"));
242                 break;
243
244         case SetEndpoint:
245         {
246                 QString msg = "";
247
248                 if (history.count() >= 3)
249                 {
250                         msg += RS_COMMANDS->command("close");
251                         msg += "/";
252                 }
253
254                 if (history.count() >= 2)
255                         msg += RS_COMMANDS->command("undo");
256
257                 if (history.count() >= 2)
258                         RS_DIALOGFACTORY->updateMouseWidget(tr("Specify next point or [%1]").arg(msg), tr("Back"));
259                 else
260                         RS_DIALOGFACTORY->updateMouseWidget(tr("Specify next point"), tr("Back"));
261         }
262         break;
263
264         default:
265                 RS_DIALOGFACTORY->updateMouseWidget("", "");
266                 break;
267         }
268 }
269
270 void RS_ActionDrawLine::showOptions()
271 {
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");
276 }
277
278 void RS_ActionDrawLine::hideOptions()
279 {
280         RS_ActionInterface::hideOptions();
281         RS_DIALOGFACTORY->requestOptions(this, false);
282 }
283
284 void RS_ActionDrawLine::updateMouseCursor()
285 {
286         graphicView->setMouseCursor(RS2::CadCursor);
287 }
288
289 void RS_ActionDrawLine::updateToolBar()
290 {
291         if (!isFinished())
292                 RS_DIALOGFACTORY->requestToolBar(RS2::ToolBarSnap);
293         else
294                 RS_DIALOGFACTORY->requestToolBar(RS2::ToolBarLines);
295 }
296
297 void RS_ActionDrawLine::close()
298 {
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)
302         {
303                 data.endpoint = start;
304                 trigger();
305                 setStatus(SetStartpoint);
306                 graphicView->moveRelativeZero(start);
307         }
308         else
309                 RS_DIALOGFACTORY->commandMessage(tr("Cannot close sequence of lines: Not enough entities defined yet."));
310 }
311
312 void RS_ActionDrawLine::undo()
313 {
314 //NOTE: We should grey out the "undo" button until the conditions for its use are satisfied.
315         if (history.count() > 1)
316         {
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);
323         }
324         else
325                 RS_DIALOGFACTORY->commandMessage(tr("Cannot undo: Not enough entities defined yet."));
326 }
327
328 void RS_ActionDrawLine::ClearHistory(void)
329 {
330         while (!history.isEmpty())
331                 delete history.takeFirst();
332 }