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_actionmodifybevel.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_information.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_ActionModifyBevel::Points {
41 	RS_Vector coord1;
42 	RS_Vector coord2;
43 	RS_BevelData data;
44 };
45 
RS_ActionModifyBevel(RS_EntityContainer & container,RS_GraphicView & graphicView)46 RS_ActionModifyBevel::RS_ActionModifyBevel(RS_EntityContainer& container,
47         RS_GraphicView& graphicView)
48         :RS_PreviewActionInterface("Bevel Entities",
49 						   container, graphicView)
50 		,entity1(nullptr)
51 		,entity2(nullptr)
52 		, pPoints(new Points{})
53 		,lastStatus(SetEntity1)
54 {
55 	actionType=RS2::ActionModifyBevel;
56 }
57 
58 RS_ActionModifyBevel::~RS_ActionModifyBevel() = default;
59 
60 
init(int status)61 void RS_ActionModifyBevel::init(int status) {
62     RS_ActionInterface::init(status);
63 
64     //snapMode = RS2::SnapFree;
65     snapMode.restriction = RS2::RestrictNothing;
66 }
67 
trigger()68 void RS_ActionModifyBevel::trigger() {
69 
70     RS_DEBUG->print("RS_ActionModifyBevel::trigger()");
71 
72     if (entity1 && entity1->isAtomic() &&
73             entity2 && entity2->isAtomic()) {
74 
75         RS_Modification m(*container, graphicView);
76 		m.bevel(pPoints->coord1, (RS_AtomicEntity*)entity1,
77 				pPoints->coord2, (RS_AtomicEntity*)entity2,
78 				pPoints->data);
79 
80 		pPoints->coord1 = {};
81 		pPoints->coord2 = {};
82         entity1 = nullptr;
83         entity2 = nullptr;
84         setStatus(SetEntity1);
85 
86         RS_DIALOGFACTORY->updateSelectionWidget(container->countSelected(),container->totalSelectedLength());
87     }
88 }
89 
mouseMoveEvent(QMouseEvent * e)90 void RS_ActionModifyBevel::mouseMoveEvent(QMouseEvent* e) {
91     RS_DEBUG->print("RS_ActionModifyBevel::mouseMoveEvent begin");
92 
93     RS_Vector mouse = graphicView->toGraph(e->x(), e->y());
94     RS_Entity* se = catchEntity(e, RS2::ResolveAllButTextImage);
95 
96     switch (getStatus()) {
97     case SetEntity1:
98 		pPoints->coord1 = mouse;
99         entity1 = se;
100         break;
101 
102     case SetEntity2:
103                 if (entity1 && RS_Information::isTrimmable(entity1)) {
104 				pPoints->coord2 = mouse;
105                 entity2 = se;
106                 }
107         break;
108 
109     default:
110         break;
111     }
112 
113     RS_DEBUG->print("RS_ActionModifyBevel::mouseMoveEvent end");
114 }
115 
116 
117 
mouseReleaseEvent(QMouseEvent * e)118 void RS_ActionModifyBevel::mouseReleaseEvent(QMouseEvent* e) {
119     if (e->button()==Qt::LeftButton) {
120         switch (getStatus()) {
121         case SetEntity1:
122             if (entity1 && entity1->isAtomic()) {
123                 setStatus(SetEntity2);
124             }
125             break;
126 
127         case SetEntity2:
128             if (entity2 && entity2->isAtomic() &&
129                             RS_Information::isTrimmable(entity1, entity2)) {
130                 trigger();
131             }
132             break;
133 
134         default:
135             break;
136         }
137     } else if (e->button()==Qt::RightButton) {
138         deletePreview();
139         init(getStatus()-1);
140     }
141 }
142 
commandEvent(RS_CommandEvent * e)143 void RS_ActionModifyBevel::commandEvent(RS_CommandEvent* e) {
144     QString c = e->getCommand().toLower();
145 
146     if (checkCommand("help", c)) {
147         RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
148                                          + getAvailableCommands().join(", "));
149         return;
150     }
151 
152     switch (getStatus()) {
153     case SetEntity1:
154     case SetEntity2:
155         if (checkCommand("length1", c)) {
156             deletePreview();
157             lastStatus = (Status)getStatus();
158             setStatus(SetLength1);
159         } else if (checkCommand("length2", c)) {
160             deletePreview();
161             lastStatus = (Status)getStatus();
162             setStatus(SetLength2);
163         } else if (checkCommand("trim", c)) {
164 			pPoints->data.trim = !pPoints->data.trim;
165             RS_DIALOGFACTORY->requestOptions(this, true, true);
166         }
167         break;
168 
169     case SetLength1: {
170             bool ok;
171             double l = RS_Math::eval(c, &ok);
172             if (ok) {
173                 e->accept();
174 				pPoints->data.length1 = l;
175             } else {
176                 RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
177             }
178             RS_DIALOGFACTORY->requestOptions(this, true, true);
179             setStatus(lastStatus);
180         }
181         break;
182 
183     case SetLength2: {
184             bool ok;
185             double l = RS_Math::eval(c, &ok);
186             if (ok) {
187 				pPoints->data.length2 = l;
188             } else {
189                 RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
190             }
191             RS_DIALOGFACTORY->requestOptions(this, true, true);
192             setStatus(lastStatus);
193         }
194         break;
195 
196     default:
197         break;
198     }
199 }
200 
setLength1(double l1)201 void RS_ActionModifyBevel::setLength1(double l1) {
202 	pPoints->data.length1 = l1;
203 }
204 
getLength1() const205 double RS_ActionModifyBevel::getLength1() const{
206 	return pPoints->data.length1;
207 }
208 
setLength2(double l2)209 void RS_ActionModifyBevel::setLength2(double l2) {
210 	pPoints->data.length2 = l2;
211 }
212 
getLength2() const213 double RS_ActionModifyBevel::getLength2() const{
214 	return pPoints->data.length2;
215 }
216 
setTrim(bool t)217 void RS_ActionModifyBevel::setTrim(bool t) {
218 	pPoints->data.trim = t;
219 }
220 
isTrimOn() const221 bool RS_ActionModifyBevel::isTrimOn() const{
222 	return pPoints->data.trim;
223 }
224 
getAvailableCommands()225 QStringList RS_ActionModifyBevel::getAvailableCommands() {
226     QStringList cmd;
227     switch (getStatus()) {
228     case SetEntity1:
229     case SetEntity2:
230         cmd += command("length1");
231         cmd += command("length2");
232         cmd += command("trim");
233         break;
234     default:
235         break;
236     }
237     return cmd;
238 }
239 
showOptions()240 void RS_ActionModifyBevel::showOptions() {
241     RS_ActionInterface::showOptions();
242 
243     RS_DIALOGFACTORY->requestOptions(this, true);
244 }
245 
hideOptions()246 void RS_ActionModifyBevel::hideOptions() {
247     RS_ActionInterface::hideOptions();
248 
249     RS_DIALOGFACTORY->requestOptions(this, false);
250 }
251 
updateMouseButtonHints()252 void RS_ActionModifyBevel::updateMouseButtonHints() {
253     switch (getStatus()) {
254     case SetEntity1:
255         RS_DIALOGFACTORY->updateMouseWidget(tr("Select first entity"),
256                                             tr("Cancel"));
257         break;
258     case SetEntity2:
259         RS_DIALOGFACTORY->updateMouseWidget(tr("Select second entity"),
260                                             tr("Back"));
261         break;
262     case SetLength1:
263         RS_DIALOGFACTORY->updateMouseWidget(tr("Enter length 1:"),
264                                             tr("Back"));
265         break;
266     case SetLength2:
267         RS_DIALOGFACTORY->updateMouseWidget(tr("Enter length 2:"),
268                                             tr("Back"));
269         break;
270     default:
271 		RS_DIALOGFACTORY->updateMouseWidget();
272         break;
273     }
274 }
275 
updateMouseCursor()276 void RS_ActionModifyBevel::updateMouseCursor() {
277     graphicView->setMouseCursor(RS2::SelectCursor);
278 }
279 
280 // EOF
281