]> Shamusworld >> Repos - architektonas/blob - src/actions/rs_actiondrawline.cpp
Major refactoring of actions: Moved implementation from header files
[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 "commands.h"
18 #include "rs_dialogfactory.h"
19 #include "rs_graphicview.h"
20 #include "rs_preview.h"
21
22 RS_ActionDrawLine::RS_ActionDrawLine(RS_EntityContainer & container, RS_GraphicView & graphicView):
23         RS_PreviewActionInterface("Draw lines", container, graphicView)
24 {
25         RS_DEBUG->print("RS_ActionDrawLine::RS_ActionDrawLine");
26         reset();
27 //[DONE]#warning "!!! Need to port setAutoDelete() behaviour from Qt3 to Qt4 !!!"
28 //      history.setAutoDelete(true);
29         RS_DEBUG->print("RS_ActionDrawLine::RS_ActionDrawLine: OK");
30 }
31
32 RS_ActionDrawLine::~RS_ActionDrawLine()
33 {
34         ClearHistory();
35 }
36
37 /*virtual*/ RS2::ActionType RS_ActionDrawLine::rtti()
38 {
39         return RS2::ActionDrawLine;
40 }
41
42 void RS_ActionDrawLine::reset()
43 {
44         RS_DEBUG->print("RS_ActionDrawLine::reset");
45         data = RS_LineData(Vector(false), Vector(false));
46         start = Vector(false);
47 //      history.clear();
48         ClearHistory();
49         RS_DEBUG->print("RS_ActionDrawLine::reset: OK");
50 }
51
52 void RS_ActionDrawLine::init(int status)
53 {
54         RS_DEBUG->print("RS_ActionDrawLine::init");
55         RS_PreviewActionInterface::init(status);
56
57         reset();
58         RS_DEBUG->print("RS_ActionDrawLine::init: OK");
59 }
60
61 void RS_ActionDrawLine::trigger()
62 {
63         RS_PreviewActionInterface::trigger();
64
65         RS_Line * line = new RS_Line(container, data);
66         line->setLayerToActive();
67         line->setPenToActive();
68         container->addEntity(line);
69 //std::cout << container;
70 //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);
71 //This makes it come back as "Unknown Entity"
72 //std::cout << *((RS_Entity *)container);
73 //std::cout << *container;
74
75         // Update undo list:
76         if (document != NULL)
77         {
78                 document->startUndoCycle();
79                 document->addUndoable(line);
80                 document->endUndoCycle();
81         }
82
83         deleteSnapper();
84         graphicView->moveRelativeZero(Vector(0.0, 0.0));
85 //This is unnecessary, because we added this to the container...
86 //#warning "!!! Here's the trouble... Trying to draw direct !!!"
87 //      graphicView->drawEntity(line);
88         graphicView->moveRelativeZero(line->getEndpoint());
89         drawSnapper();
90         RS_DEBUG->print("RS_ActionDrawLine::trigger(): line added: %d", line->getId());
91 }
92
93 void RS_ActionDrawLine::mouseMoveEvent(QMouseEvent * e)
94 {
95         RS_DEBUG->print("RS_ActionDrawLine::mouseMoveEvent begin");
96
97         RS_DEBUG->print("RS_ActionDrawLine::mouseMoveEvent: snap point");
98         Vector mouse = snapPoint(e);
99         RS_DEBUG->print("RS_ActionDrawLine::mouseMoveEvent: snap point: OK");
100
101         if (getStatus() == SetEndpoint && data.startpoint.valid)
102         {
103                 RS_DEBUG->print("RS_ActionDrawLine::mouseMoveEvent: update preview");
104                 deletePreview();
105                 clearPreview();
106                 preview->addEntity(new RS_Line(preview, RS_LineData(data.startpoint, mouse)));
107                 RS_DEBUG->print("RS_ActionDrawLine::mouseMoveEvent: draw preview");
108                 drawPreview();
109         }
110
111         RS_DEBUG->print("RS_ActionDrawLine::mouseMoveEvent end");
112 }
113
114 void RS_ActionDrawLine::mouseReleaseEvent(QMouseEvent * e)
115 {
116         if (RS2::qtToRsButtonState(e->button()) == RS2::LeftButton)
117         {
118                 Vector ce(snapPoint(e));
119                 coordinateEvent(&ce);
120         }
121         else if (RS2::qtToRsButtonState(e->button()) == RS2::RightButton)
122         {
123                 deletePreview();
124                 clearPreview();
125                 deleteSnapper();
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 == NULL)
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 //              history.clear();
147                 ClearHistory();
148                 history.append(new Vector(mouse));
149                 start = data.startpoint;
150                 setStatus(SetEndpoint);
151                 graphicView->moveRelativeZero(mouse);
152                 updateMouseButtonHints();
153                 break;
154
155         case SetEndpoint:
156                 data.endpoint = mouse;
157                 history.append(new Vector(mouse));
158                 trigger();
159                 data.startpoint = data.endpoint;
160                 updateMouseButtonHints();
161                 break;
162
163         default:
164                 break;
165         }
166
167         RS_DEBUG->print("RS_ActionDrawLine::coordinateEvent: OK");
168 }
169
170 void RS_ActionDrawLine::commandEvent(RS_CommandEvent * e)
171 {
172         RS_DEBUG->print("RS_ActionDrawLine::commandEvent");
173         QString c = e->getCommand().toLower();
174
175         switch (getStatus())
176         {
177         case SetStartpoint:
178
179                 if (checkCommand("help", c))
180                 {
181                         RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
182                                 + getAvailableCommands().join(", "));
183                         return;
184                 }
185                 break;
186
187         case SetEndpoint:
188
189                 if (checkCommand("close", c))
190                 {
191                         close();
192                         updateMouseButtonHints();
193                         return;
194                 }
195
196                 if (checkCommand("undo", c))
197                 {
198                         undo();
199                         updateMouseButtonHints();
200                         return;
201                 }
202                 break;
203
204         default:
205                 break;
206         }
207
208         RS_DEBUG->print("RS_ActionDrawLine::commandEvent: OK");
209 }
210
211 QStringList RS_ActionDrawLine::getAvailableCommands()
212 {
213         QStringList cmd;
214
215         switch (getStatus())
216         {
217         case SetStartpoint:
218                 break;
219
220         case SetEndpoint:
221
222                 if (history.count() >= 2)
223                         cmd += command("undo");
224
225                 if (history.count() >= 3)
226                         cmd += command("close");
227
228                 break;
229
230         default:
231                 break;
232         }
233
234         return cmd;
235 }
236
237 void RS_ActionDrawLine::updateMouseButtonHints()
238 {
239         switch (getStatus())
240         {
241         case SetStartpoint:
242                 RS_DIALOGFACTORY->updateMouseWidget(tr("Specify first point"), tr("Cancel"));
243                 break;
244
245         case SetEndpoint:
246         {
247                 QString msg = "";
248
249                 if (history.count() >= 3)
250                 {
251                         msg += RS_COMMANDS->command("close");
252                         msg += "/";
253                 }
254
255                 if (history.count() >= 2)
256                         msg += RS_COMMANDS->command("undo");
257
258                 if (history.count() >= 2)
259                         RS_DIALOGFACTORY->updateMouseWidget(tr("Specify next point or [%1]").arg(msg), tr("Back"));
260                 else
261                         RS_DIALOGFACTORY->updateMouseWidget(tr("Specify next point"), tr("Back"));
262         }
263         break;
264
265         default:
266                 RS_DIALOGFACTORY->updateMouseWidget("", "");
267                 break;
268         }
269 }
270
271 void RS_ActionDrawLine::showOptions()
272 {
273         RS_DEBUG->print("RS_ActionDrawLine::showOptions");
274         RS_ActionInterface::showOptions();
275
276         RS_DIALOGFACTORY->requestOptions(this, true);
277         RS_DEBUG->print("RS_ActionDrawLine::showOptions: OK");
278 }
279
280 void RS_ActionDrawLine::hideOptions()
281 {
282         RS_ActionInterface::hideOptions();
283
284         RS_DIALOGFACTORY->requestOptions(this, false);
285 }
286
287 void RS_ActionDrawLine::updateMouseCursor()
288 {
289         graphicView->setMouseCursor(RS2::CadCursor);
290 }
291
292 void RS_ActionDrawLine::updateToolBar()
293 {
294         if (!isFinished())
295                 RS_DIALOGFACTORY->requestToolBar(RS2::ToolBarSnap);
296         else
297                 RS_DIALOGFACTORY->requestToolBar(RS2::ToolBarLines);
298 }
299
300 void RS_ActionDrawLine::close()
301 {
302         if (history.count() > 2 && start.valid)
303         {
304                 data.endpoint = start;
305                 trigger();
306                 setStatus(SetStartpoint);
307                 graphicView->moveRelativeZero(start);
308         }
309         else
310                 RS_DIALOGFACTORY->commandMessage(tr("Cannot close sequence of lines: Not enough entities defined yet."));
311 }
312
313 void RS_ActionDrawLine::undo()
314 {
315         if (history.count() > 1)
316         {
317                 history.removeLast();
318                 deletePreview();
319                 clearPreview();
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 }
333