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