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