1 /****************************************************************************
2 **
3 ** This file is part of the LibreCAD project, a 2D CAD program
4 **
5 ** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
6 ** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
7 **
8 **
9 ** This file may be distributed and/or modified under the terms of the
10 ** GNU General Public License version 2 as published by the Free Software
11 ** Foundation and appearing in the file gpl-2.0.txt included in the
12 ** packaging of this file.
13 **
14 ** This program is distributed in the hope that it will be useful,
15 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ** GNU General Public License for more details.
18 **
19 ** You should have received a copy of the GNU General Public License
20 ** along with this program; if not, write to the Free Software
21 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 **
23 ** This copyright notice MUST APPEAR in all copies of the script!
24 **
25 **********************************************************************/
26
27 #include "rs_actiondrawlinerelangle.h"
28 #include<cmath>
29 #include <QAction>
30 #include <QMouseEvent>
31 #include "rs_dialogfactory.h"
32 #include "rs_graphicview.h"
33 #include "rs_commandevent.h"
34 #include "rs_creation.h"
35 #include "rs_line.h"
36 #include "rs_coordinateevent.h"
37 #include "rs_math.h"
38 #include "rs_preview.h"
39 #include "rs_debug.h"
40
RS_ActionDrawLineRelAngle(RS_EntityContainer & container,RS_GraphicView & graphicView,double angle,bool fixedAngle)41 RS_ActionDrawLineRelAngle::RS_ActionDrawLineRelAngle(
42 RS_EntityContainer& container,
43 RS_GraphicView& graphicView,
44 double angle,
45 bool fixedAngle)
46 :RS_PreviewActionInterface("Draw Lines with relative angles",
47 container, graphicView)
48 ,entity(nullptr)
49 , pos(new RS_Vector{})
50 ,angle(angle)
51 ,length(10.)
52 ,fixedAngle(fixedAngle)
53 {
54 }
55
56 RS_ActionDrawLineRelAngle::~RS_ActionDrawLineRelAngle() = default;
57
58
rtti() const59 RS2::ActionType RS_ActionDrawLineRelAngle::rtti() const{
60 if( fixedAngle &&
61 RS_Math::getAngleDifference(angle, M_PI_2) < RS_TOLERANCE_ANGLE)
62 return RS2::ActionDrawLineOrthogonal;
63 else
64 return RS2::ActionDrawLineRelAngle;
65 }
66
finish(bool updateTB)67 void RS_ActionDrawLineRelAngle::finish(bool updateTB) {
68 unhighlightEntity();
69 RS_PreviewActionInterface::finish(updateTB);
70 }
71
trigger()72 void RS_ActionDrawLineRelAngle::trigger() {
73 RS_PreviewActionInterface::trigger();
74
75 deletePreview();
76
77 RS_Creation creation(container, graphicView);
78 creation.createLineRelAngle(*pos,
79 entity,
80 angle,
81 length);
82
83 /*
84 if (line) {
85 RS_Entity* newEntity = nullptr;
86
87 newEntity = new RS_Line(container,
88 line->getData());
89
90 if (newEntity) {
91 newEntity->setLayerToActive();
92 newEntity->setPenToActive();
93 container->addEntity(newEntity);
94
95 // upd. undo list:
96 if (document) {
97 document->startUndoCycle();
98 document->addUndoable(newEntity);
99 document->endUndoCycle();
100 }
101 graphicView->drawEntity(newEntity);
102 setStatus(SetEntity);
103 }
104 //reset();
105 delete line;
106 line = nullptr;
107 } else {
108 RS_DEBUG->print("RS_ActionDrawLineRelAngle::trigger:"
109 " Line is nullptr\n");
110 }
111 */
112 }
113
114
115
mouseMoveEvent(QMouseEvent * e)116 void RS_ActionDrawLineRelAngle::mouseMoveEvent(QMouseEvent* e) {
117 RS_DEBUG->print("RS_ActionDrawLineRelAngle::mouseMoveEvent begin");
118
119 RS_Vector mouse(graphicView->toGraphX(e->x()),
120 graphicView->toGraphY(e->y()));
121
122 switch (getStatus()) {
123 case SetEntity:
124 entity = catchEntity(e, enTypeList, RS2::ResolveAll);
125 break;
126
127 case SetPos: {
128 //length = graphicView->toGraphDX(graphicView->getWidth());
129 //RS_Vector mouse = snapPoint(e);
130 *pos = snapPoint(e);
131
132 /*RS_Creation creation(nullptr, nullptr);
133 RS_Line* l = creation.createLineRelAngle(mouse,
134 entity,
135 angle,
136 length);*/
137
138 deletePreview();
139
140 RS_Creation creation(preview.get(), nullptr, false);
141 creation.createLineRelAngle(*pos,
142 entity,
143 angle,
144 length);
145
146 drawPreview();
147
148 /*if (l) {
149 if (line) {
150 delete line;
151 }
152 line = (RS_Line*)l->clone();
153
154 deletePreview();
155 preview->addEntity(l);
156 drawPreview();
157 }*/
158 }
159 break;
160
161 default:
162 break;
163 }
164
165 RS_DEBUG->print("RS_ActionDrawLineRelAngle::mouseMoveEvent end");
166 }
167
168
169
mouseReleaseEvent(QMouseEvent * e)170 void RS_ActionDrawLineRelAngle::mouseReleaseEvent(QMouseEvent* e) {
171
172 if (e->button()==Qt::LeftButton) {
173 switch (getStatus()) {
174 case SetEntity: {
175 RS_Entity* en = catchEntity(e, enTypeList, RS2::ResolveAll);
176 if (en) {
177 entity = en;
178
179 entity->setHighlighted(true);
180 graphicView->drawEntity(entity);
181
182 setStatus(SetPos);
183 }
184 }
185 break;
186
187 case SetPos: {
188 RS_CoordinateEvent ce(snapPoint(e));
189 coordinateEvent(&ce);
190 }
191 break;
192
193 default:
194 break;
195 }
196 } else if (e->button()==Qt::RightButton) {
197 deletePreview();
198 if (entity) {
199 entity->setHighlighted(false);
200 graphicView->drawEntity(entity);
201 }
202 init(getStatus()-1);
203 }
204 }
205
206
207
coordinateEvent(RS_CoordinateEvent * e)208 void RS_ActionDrawLineRelAngle::coordinateEvent(RS_CoordinateEvent* e) {
209 if (!e) {
210 return;
211 }
212
213 switch (getStatus()) {
214 case SetPos:
215 *pos = e->getCoordinate();
216 trigger();
217 break;
218
219 default:
220 break;
221 }
222 }
223
224
225
commandEvent(RS_CommandEvent * e)226 void RS_ActionDrawLineRelAngle::commandEvent(RS_CommandEvent* e) {
227 QString c = e->getCommand().toLower();
228
229 if (checkCommand("help", c)) {
230 RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
231 + getAvailableCommands().join(", "));
232 return;
233 }
234
235 switch (getStatus()) {
236 case SetEntity:
237 case SetPos:
238 if (!fixedAngle && checkCommand("angle", c)) {
239 deletePreview();
240 setStatus(SetAngle);
241 } else if (checkCommand("length", c)) {
242 deletePreview();
243 setStatus(SetLength);
244 }
245 break;
246
247 case SetAngle: {
248 bool ok;
249 double a = RS_Math::eval(c, &ok);
250 if (ok) {
251 e->accept();
252 angle = RS_Math::deg2rad(a);
253 } else
254 RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
255 RS_DIALOGFACTORY->requestOptions(this, true, true);
256 setStatus(SetPos);
257 }
258 break;
259
260 case SetLength: {
261 bool ok;
262 double l = RS_Math::eval(c, &ok);
263 if (ok) {
264 length = l;
265 } else
266 RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
267 RS_DIALOGFACTORY->requestOptions(this, true, true);
268 setStatus(SetPos);
269 }
270 break;
271
272 default:
273 break;
274 }
275 }
276
277
278
getAvailableCommands()279 QStringList RS_ActionDrawLineRelAngle::getAvailableCommands() {
280 QStringList cmd;
281
282 switch (getStatus()) {
283 case SetPos:
284 case SetLength:
285 if (!fixedAngle) {
286 cmd += command("angle");
287 }
288 cmd += command("length");
289 break;
290 default:
291 break;
292 }
293
294 return cmd;
295 }
296
297
updateMouseButtonHints()298 void RS_ActionDrawLineRelAngle::updateMouseButtonHints() {
299 switch (getStatus()) {
300 case SetEntity:
301 RS_DIALOGFACTORY->updateMouseWidget(tr("Select base entity"),
302 tr("Cancel"));
303 break;
304 case SetPos:
305 RS_DIALOGFACTORY->updateMouseWidget(tr("Specify position"),
306 tr("Back"));
307 break;
308 default:
309 RS_DIALOGFACTORY->updateMouseWidget();
310 break;
311 }
312 }
313
314
315
showOptions()316 void RS_ActionDrawLineRelAngle::showOptions() {
317 RS_ActionInterface::showOptions();
318
319 RS_DIALOGFACTORY->requestOptions(this, true);
320 }
321
322
323
hideOptions()324 void RS_ActionDrawLineRelAngle::hideOptions() {
325 RS_ActionInterface::hideOptions();
326
327 RS_DIALOGFACTORY->requestOptions(this, false);
328 }
329
330
331
updateMouseCursor()332 void RS_ActionDrawLineRelAngle::updateMouseCursor()
333 {
334 switch (getStatus())
335 {
336 case SetEntity:
337 graphicView->setMouseCursor(RS2::SelectCursor);
338 break;
339 case SetPos:
340 graphicView->setMouseCursor(RS2::CadCursor);
341 break;
342 default:
343 break;
344 }
345 }
346
unhighlightEntity()347 void RS_ActionDrawLineRelAngle::unhighlightEntity()
348 {
349 if (entity) {
350 entity->setHighlighted(false);
351 graphicView->drawEntity(entity);
352 }
353 }
354
355 // EOF
356