]> Shamusworld >> Repos - architektonas/blob - src/actions/rs_actiondrawline.cpp
ce6ccdf8fdbe9078bb531800404ce9ab4d7ed41e
[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 //[DONE]#warning "!!! Need to port setAutoDelete() behaviour from Qt3 to Qt4 !!!"
29 //      history.setAutoDelete(true);
30         RS_DEBUG->print("RS_ActionDrawLine::RS_ActionDrawLine: OK");
31 }
32
33 RS_ActionDrawLine::~RS_ActionDrawLine()
34 {
35         ClearHistory();
36 }
37
38 /*virtual*/ RS2::ActionType RS_ActionDrawLine::rtti()
39 {
40         return RS2::ActionDrawLine;
41 }
42
43 void RS_ActionDrawLine::reset()
44 {
45         RS_DEBUG->print("RS_ActionDrawLine::reset");
46         data = RS_LineData(Vector(false), Vector(false));
47         start = Vector(false);
48 //      history.clear();
49         ClearHistory();
50         RS_DEBUG->print("RS_ActionDrawLine::reset: OK");
51 }
52
53 void RS_ActionDrawLine::init(int status)
54 {
55         RS_DEBUG->print("RS_ActionDrawLine::init");
56         RS_PreviewActionInterface::init(status);
57
58         reset();
59         RS_DEBUG->print("RS_ActionDrawLine::init: OK");
60 }
61
62 void RS_ActionDrawLine::trigger()
63 {
64         RS_PreviewActionInterface::trigger();
65
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;
75
76         // Update undo list:
77         if (document != NULL)
78         {
79                 document->startUndoCycle();
80                 document->addUndoable(line);
81                 document->endUndoCycle();
82         }
83
84         deleteSnapper();
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();
91         RS_DEBUG->print("RS_ActionDrawLine::trigger(): line added: %d", line->getId());
92 }
93
94 void RS_ActionDrawLine::mouseMoveEvent(QMouseEvent * e)
95 {
96         RS_DEBUG->print("RS_ActionDrawLine::mouseMoveEvent begin");
97
98         RS_DEBUG->print("RS_ActionDrawLine::mouseMoveEvent: snap point");
99         Vector mouse = snapPoint(e);
100         RS_DEBUG->print("RS_ActionDrawLine::mouseMoveEvent: snap point: OK");
101
102         if (getStatus() == SetEndpoint && data.startpoint.valid)
103         {
104                 RS_DEBUG->print("RS_ActionDrawLine::mouseMoveEvent: update preview");
105                 deletePreview();
106                 clearPreview();
107                 preview->addEntity(new RS_Line(preview, RS_LineData(data.startpoint, mouse)));
108                 RS_DEBUG->print("RS_ActionDrawLine::mouseMoveEvent: draw preview");
109                 drawPreview();
110         }
111
112         RS_DEBUG->print("RS_ActionDrawLine::mouseMoveEvent end");
113 }
114
115 void RS_ActionDrawLine::mouseReleaseEvent(QMouseEvent * e)
116 {
117         if (e->button() == Qt::LeftButton)
118         {
119                 Vector ce(snapPoint(e));
120                 coordinateEvent(&ce);
121         }
122         else if (e->button() == Qt::RightButton)
123         {
124                 deletePreview();
125                 clearPreview();
126                 deleteSnapper();
127                 init(getStatus() - 1);
128         }
129 }
130
131 void RS_ActionDrawLine::coordinateEvent(Vector * e)
132 {
133         RS_DEBUG->print("RS_ActionDrawLine::coordinateEvent");
134
135         if (e == NULL)
136         {
137                 RS_DEBUG->print("RS_ActionDrawLine::coordinateEvent: event was NULL");
138                 return;
139         }
140
141         Vector mouse = *e;
142
143         switch (getStatus())
144         {
145         case SetStartpoint:
146                 data.startpoint = mouse;
147 //              history.clear();
148                 ClearHistory();
149                 history.append(new Vector(mouse));
150                 start = data.startpoint;
151                 setStatus(SetEndpoint);
152                 graphicView->moveRelativeZero(mouse);
153                 updateMouseButtonHints();
154                 break;
155
156         case SetEndpoint:
157                 data.endpoint = mouse;
158                 history.append(new Vector(mouse));
159                 trigger();
160                 data.startpoint = data.endpoint;
161                 updateMouseButtonHints();
162                 break;
163
164         default:
165                 break;
166         }
167
168         RS_DEBUG->print("RS_ActionDrawLine::coordinateEvent: OK");
169 }
170
171 void RS_ActionDrawLine::commandEvent(RS_CommandEvent * e)
172 {
173         RS_DEBUG->print("RS_ActionDrawLine::commandEvent");
174         QString c = e->getCommand().toLower();
175
176         switch (getStatus())
177         {
178         case SetStartpoint:
179
180                 if (checkCommand("help", c))
181                 {
182                         RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
183                                 + getAvailableCommands().join(", "));
184                         return;
185                 }
186                 break;
187
188         case SetEndpoint:
189
190                 if (checkCommand("close", c))
191                 {
192                         close();
193                         updateMouseButtonHints();
194                         return;
195                 }
196
197                 if (checkCommand("undo", c))
198                 {
199                         undo();
200                         updateMouseButtonHints();
201                         return;
202                 }
203                 break;
204
205         default:
206                 break;
207         }
208
209         RS_DEBUG->print("RS_ActionDrawLine::commandEvent: OK");
210 }
211
212 QStringList RS_ActionDrawLine::getAvailableCommands()
213 {
214         QStringList cmd;
215
216         switch (getStatus())
217         {
218         case SetStartpoint:
219                 break;
220
221         case SetEndpoint:
222
223                 if (history.count() >= 2)
224                         cmd += command("undo");
225
226                 if (history.count() >= 3)
227                         cmd += command("close");
228
229                 break;
230
231         default:
232                 break;
233         }
234
235         return cmd;
236 }
237
238 void RS_ActionDrawLine::updateMouseButtonHints()
239 {
240         switch (getStatus())
241         {
242         case SetStartpoint:
243                 RS_DIALOGFACTORY->updateMouseWidget(tr("Specify first point"), tr("Cancel"));
244                 break;
245
246         case SetEndpoint:
247         {
248                 QString msg = "";
249
250                 if (history.count() >= 3)
251                 {
252                         msg += RS_COMMANDS->command("close");
253                         msg += "/";
254                 }
255
256                 if (history.count() >= 2)
257                         msg += RS_COMMANDS->command("undo");
258
259                 if (history.count() >= 2)
260                         RS_DIALOGFACTORY->updateMouseWidget(tr("Specify next point or [%1]").arg(msg), tr("Back"));
261                 else
262                         RS_DIALOGFACTORY->updateMouseWidget(tr("Specify next point"), tr("Back"));
263         }
264         break;
265
266         default:
267                 RS_DIALOGFACTORY->updateMouseWidget("", "");
268                 break;
269         }
270 }
271
272 void RS_ActionDrawLine::showOptions()
273 {
274         RS_DEBUG->print("RS_ActionDrawLine::showOptions");
275         RS_ActionInterface::showOptions();
276
277         RS_DIALOGFACTORY->requestOptions(this, true);
278         RS_DEBUG->print("RS_ActionDrawLine::showOptions: OK");
279 }
280
281 void RS_ActionDrawLine::hideOptions()
282 {
283         RS_ActionInterface::hideOptions();
284
285         RS_DIALOGFACTORY->requestOptions(this, false);
286 }
287
288 void RS_ActionDrawLine::updateMouseCursor()
289 {
290         graphicView->setMouseCursor(RS2::CadCursor);
291 }
292
293 void RS_ActionDrawLine::updateToolBar()
294 {
295         if (!isFinished())
296                 RS_DIALOGFACTORY->requestToolBar(RS2::ToolBarSnap);
297         else
298                 RS_DIALOGFACTORY->requestToolBar(RS2::ToolBarLines);
299 }
300
301 void RS_ActionDrawLine::close()
302 {
303         if (history.count() > 2 && start.valid)
304         {
305                 data.endpoint = start;
306                 trigger();
307                 setStatus(SetStartpoint);
308                 graphicView->moveRelativeZero(start);
309         }
310         else
311                 RS_DIALOGFACTORY->commandMessage(tr("Cannot close sequence of lines: Not enough entities defined yet."));
312 }
313
314 void RS_ActionDrawLine::undo()
315 {
316         if (history.count() > 1)
317         {
318                 history.removeLast();
319                 deletePreview();
320                 clearPreview();
321                 graphicView->setCurrentAction(new RS_ActionEditUndo(true, *container, *graphicView));
322                 data.startpoint = *history.last();
323                 graphicView->moveRelativeZero(data.startpoint);
324         }
325         else
326                 RS_DIALOGFACTORY->commandMessage(tr("Cannot undo: Not enough entities defined yet."));
327 }
328
329 void RS_ActionDrawLine::ClearHistory(void)
330 {
331         while (!history.isEmpty())
332                 delete history.takeFirst();
333 }
334