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_actionmodifymoverotate.h"
28 
29 #include <QAction>
30 #include <QMouseEvent>
31 #include "rs_dialogfactory.h"
32 #include "rs_graphicview.h"
33 #include "rs_commandevent.h"
34 #include "rs_coordinateevent.h"
35 #include "rs_math.h"
36 #include "rs_modification.h"
37 #include "rs_preview.h"
38 #include "rs_debug.h"
39 
40 struct RS_ActionModifyMoveRotate::Points {
41 	RS_MoveRotateData data;
42 	RS_Vector targetPoint;
43 };
44 
RS_ActionModifyMoveRotate(RS_EntityContainer & container,RS_GraphicView & graphicView)45 RS_ActionModifyMoveRotate::RS_ActionModifyMoveRotate(
46     RS_EntityContainer& container,
47     RS_GraphicView& graphicView)
48         :RS_PreviewActionInterface("Move and Rotate Entities",
49 						   container, graphicView)
50 		, pPoints(new Points())
51 {
52 	actionType=RS2::ActionModifyMoveRotate;
53 }
54 
55 RS_ActionModifyMoveRotate::~RS_ActionModifyMoveRotate() = default;
56 
init(int status)57 void RS_ActionModifyMoveRotate::init(int status) {
58     RS_ActionInterface::init(status);
59 }
60 
trigger()61 void RS_ActionModifyMoveRotate::trigger() {
62 
63     RS_DEBUG->print("RS_ActionModifyMoveRotate::trigger()");
64 
65     RS_Modification m(*container, graphicView);
66 	m.moveRotate(pPoints->data);
67 
68     finish(false);
69 
70     RS_DIALOGFACTORY->updateSelectionWidget(container->countSelected(),container->totalSelectedLength());
71 }
72 
73 
74 
mouseMoveEvent(QMouseEvent * e)75 void RS_ActionModifyMoveRotate::mouseMoveEvent(QMouseEvent* e) {
76     RS_DEBUG->print("RS_ActionModifyMoveRotate::mouseMoveEvent begin");
77 
78     if (getStatus()==SetReferencePoint ||
79             getStatus()==SetTargetPoint) {
80 
81         RS_Vector mouse = snapPoint(e);
82         switch (getStatus()) {
83         case SetReferencePoint:
84 			pPoints->data.referencePoint = mouse;
85             break;
86 
87         case SetTargetPoint:
88 			if (pPoints->data.referencePoint.valid) {
89 				pPoints->targetPoint = mouse;
90 				pPoints->data.offset = pPoints->targetPoint-pPoints->data.referencePoint;
91 
92                 deletePreview();
93                 preview->addSelectionFrom(*container);
94 				preview->rotate(pPoints->data.referencePoint, pPoints->data.angle);
95 				preview->move(pPoints->data.offset);
96                 drawPreview();
97             }
98             break;
99 
100         default:
101             break;
102         }
103     }
104 
105     RS_DEBUG->print("RS_ActionModifyMoveRotate::mouseMoveEvent end");
106 }
107 
108 
109 
mouseReleaseEvent(QMouseEvent * e)110 void RS_ActionModifyMoveRotate::mouseReleaseEvent(QMouseEvent* e) {
111     if (e->button()==Qt::LeftButton) {
112         RS_CoordinateEvent ce(snapPoint(e));
113         coordinateEvent(&ce);
114     } else if (e->button()==Qt::RightButton) {
115         deletePreview();
116         init(getStatus()-1);
117     }
118 }
119 
120 
121 
coordinateEvent(RS_CoordinateEvent * e)122 void RS_ActionModifyMoveRotate::coordinateEvent(RS_CoordinateEvent* e) {
123 	if (e==nullptr) return;
124 
125     RS_Vector pos = e->getCoordinate();
126 
127     switch (getStatus()) {
128     case SetReferencePoint:
129 		pPoints->data.referencePoint = pos;
130         setStatus(SetTargetPoint);
131         break;
132 
133     case SetTargetPoint:
134 		pPoints->targetPoint = pos;
135 
136         setStatus(ShowDialog);
137 		pPoints->data.offset = pPoints->targetPoint - pPoints->data.referencePoint;
138 		if (RS_DIALOGFACTORY->requestMoveRotateDialog(pPoints->data)) {
139             trigger();
140             //finish();
141         }
142         break;
143 
144     default:
145         break;
146     }
147 }
148 
149 
commandEvent(RS_CommandEvent * e)150 void RS_ActionModifyMoveRotate::commandEvent(RS_CommandEvent* e) {
151     QString c = e->getCommand().toLower();
152 
153     if (checkCommand("help", c)) {
154         RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
155                                          + getAvailableCommands().join(", "));
156         return;
157     }
158 
159     switch (getStatus()) {
160     case SetReferencePoint:
161     case SetTargetPoint:
162                 // RVT_PORT changed from if (c==checkCommand("angle", c)) {
163         if (checkCommand("angle", c)) {
164             deletePreview();
165             lastStatus = (Status)getStatus();
166             setStatus(SetAngle);
167         }
168         break;
169 
170     case SetAngle: {
171             bool ok;
172             double a = RS_Math::eval(c, &ok);
173             if (ok) {
174                 e->accept();
175 				pPoints->data.angle = RS_Math::deg2rad(a);
176             } else {
177                 RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
178             }
179             RS_DIALOGFACTORY->requestOptions(this, true, true);
180             setStatus(lastStatus);
181         }
182         break;
183     }
184 }
185 
186 
187 
getAvailableCommands()188 QStringList RS_ActionModifyMoveRotate::getAvailableCommands() {
189     QStringList cmd;
190 
191     switch (getStatus()) {
192     case SetReferencePoint:
193     case SetTargetPoint:
194         cmd += command("angle");
195         break;
196 
197     default:
198         break;
199     }
200 
201     return cmd;
202 }
203 
204 
205 
showOptions()206 void RS_ActionModifyMoveRotate::showOptions() {
207     //std::cout << "RS_ActionModifyMoveRotate::showOptions()\n";
208 
209     RS_ActionInterface::showOptions();
210 
211     RS_DIALOGFACTORY->requestOptions(this, true);
212 }
213 
214 
215 
hideOptions()216 void RS_ActionModifyMoveRotate::hideOptions() {
217     //std::cout << "RS_ActionModifyMoveRotate::hideOptions()\n";
218 
219     RS_ActionInterface::hideOptions();
220 
221     RS_DIALOGFACTORY->requestOptions(this, false);
222 }
223 
setAngle(double a)224 void RS_ActionModifyMoveRotate::setAngle(double a) {
225 	pPoints->data.angle = a;
226 }
getAngle() const227 double RS_ActionModifyMoveRotate::getAngle() const{
228 	return pPoints->data.angle;
229 }
230 
231 
updateMouseButtonHints()232 void RS_ActionModifyMoveRotate::updateMouseButtonHints() {
233     switch (getStatus()) {
234     case SetReferencePoint:
235         RS_DIALOGFACTORY->updateMouseWidget(tr("Specify reference point"),
236                                             tr("Cancel"));
237         break;
238     case SetTargetPoint:
239         RS_DIALOGFACTORY->updateMouseWidget(tr("Specify target point"),
240                                             tr("Back"));
241         break;
242     case SetAngle:
243         RS_DIALOGFACTORY->updateMouseWidget(tr("Enter rotation angle:"),
244                                             tr("Back"));
245         break;
246     default:
247 		RS_DIALOGFACTORY->updateMouseWidget();
248         break;
249     }
250 }
251 
252 
253 
updateMouseCursor()254 void RS_ActionModifyMoveRotate::updateMouseCursor() {
255     graphicView->setMouseCursor(RS2::CadCursor);
256 }
257 
258 // EOF
259