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 <QAction>
28 #include <QMouseEvent>
29 #include "rs_actiondrawcirclecr.h"
30 
31 #include "rs_dialogfactory.h"
32 #include "rs_graphicview.h"
33 #include "rs_commandevent.h"
34 #include "rs_circle.h"
35 #include "rs_coordinateevent.h"
36 #include "rs_math.h"
37 #include "rs_preview.h"
38 #include "rs_debug.h"
39 
40 /**
41  * Constructor.
42  */
RS_ActionDrawCircleCR(RS_EntityContainer & container,RS_GraphicView & graphicView)43 RS_ActionDrawCircleCR::RS_ActionDrawCircleCR(RS_EntityContainer& container,
44         RS_GraphicView& graphicView)
45         :RS_PreviewActionInterface("Draw circles CR",
46 						   container, graphicView)
47 		,data(new RS_CircleData())
48 {
49 	actionType=RS2::ActionDrawCircleCR;
50 
51     reset();
52 }
53 
54 
55 
56 RS_ActionDrawCircleCR::~RS_ActionDrawCircleCR() = default;
57 
58 
reset()59 void RS_ActionDrawCircleCR::reset() {
60 	data.reset(new RS_CircleData{RS_Vector{false}, 0.0});
61 }
62 
63 
64 
init(int status)65 void RS_ActionDrawCircleCR::init(int status) {
66     RS_PreviewActionInterface::init(status);
67 }
68 
69 
70 
trigger()71 void RS_ActionDrawCircleCR::trigger() {
72     RS_PreviewActionInterface::trigger();
73 
74     RS_Circle* circle = new RS_Circle(container,
75 									  *data);
76     circle->setLayerToActive();
77     circle->setPenToActive();
78 
79     switch(getStatus()) {
80     	case SetCenter:
81     		container->addEntity(circle);
82 		graphicView->moveRelativeZero(circle->getCenter());
83 		break;
84 	case SetRadius:
85 		break;
86     }
87 
88     // upd. undo list:
89     if (document) {
90         document->startUndoCycle();
91         document->addUndoable(circle);
92         document->endUndoCycle();
93     }
94         graphicView->redraw(RS2::RedrawDrawing);
95 
96     setStatus(SetCenter);
97 
98     RS_DEBUG->print("RS_ActionDrawCircleCR::trigger(): circle added: %d",
99                     circle->getId());
100 }
101 
setRadius(double r)102 void RS_ActionDrawCircleCR::setRadius(double r)
103 {
104     if(r>RS_TOLERANCE){
105 		data->radius=r;
106     }else{
107         RS_DIALOGFACTORY->commandMessage(tr("radius=%1 is invalid").arg(r));
108     }
109 }
110 
111 
mouseMoveEvent(QMouseEvent * e)112 void RS_ActionDrawCircleCR::mouseMoveEvent(QMouseEvent* e) {
113     RS_DEBUG->print("RS_ActionDrawCircleCR::mouseMoveEvent begin");
114 
115     RS_Vector mouse = snapPoint(e);
116     switch (getStatus()) {
117     case SetCenter:
118 		data->center = mouse;
119         deletePreview();
120 		preview->addEntity(new RS_Circle(preview.get(),
121 										 *data));
122         drawPreview();
123         break;
124     }
125 
126     RS_DEBUG->print("RS_ActionDrawCircleCR::mouseMoveEvent end");
127 }
128 
129 
130 
mouseReleaseEvent(QMouseEvent * e)131 void RS_ActionDrawCircleCR::mouseReleaseEvent(QMouseEvent* e) {
132     if (e->button()==Qt::LeftButton) {
133         RS_CoordinateEvent ce(snapPoint(e));
134         coordinateEvent(&ce);
135     } else if (e->button()==Qt::RightButton) {
136         deletePreview();
137         init(getStatus()-1);
138     }
139 }
140 
141 
142 
coordinateEvent(RS_CoordinateEvent * e)143 void RS_ActionDrawCircleCR::coordinateEvent(RS_CoordinateEvent* e) {
144     if (e==NULL) {
145         return;
146     }
147 
148     RS_Vector mouse = e->getCoordinate();
149 
150     switch (getStatus()) {
151     case SetCenter:
152 		data->center = mouse;
153         trigger();
154         break;
155 
156     default:
157         break;
158     }
159 }
160 
161 
162 
commandEvent(RS_CommandEvent * e)163 void RS_ActionDrawCircleCR::commandEvent(RS_CommandEvent* e) {
164     QString c = e->getCommand().toLower();
165 
166     if (checkCommand("help", c)) {
167         RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
168                                          + getAvailableCommands().join(", "));
169         return;
170     }
171 
172     switch (getStatus()) {
173     case SetCenter:
174         if (checkCommand("radius", c)) {
175             deletePreview();
176             setStatus(SetRadius);
177         }
178         break;
179 
180     case SetRadius: {
181             bool ok;
182             double r = RS_Math::eval(c, &ok);
183 			if (ok) {
184 				data->radius = r;
185                 e->accept();
186                 trigger();
187             } else {
188                 RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
189             }
190             RS_DIALOGFACTORY->requestOptions(this, true, true);
191         }
192         break;
193 
194     default:
195         break;
196     }
197 }
198 
199 
200 
getAvailableCommands()201 QStringList RS_ActionDrawCircleCR::getAvailableCommands() {
202     QStringList cmd;
203 
204     switch (getStatus()) {
205     case SetCenter:
206         cmd += command("radius");
207         break;
208     default:
209         break;
210     }
211 
212     return cmd;
213 }
214 
updateMouseButtonHints()215 void RS_ActionDrawCircleCR::updateMouseButtonHints() {
216     switch (getStatus()) {
217     case SetCenter:
218         RS_DIALOGFACTORY->updateMouseWidget(tr("Specify circle center"),
219                                             tr("Cancel"));
220         break;
221     case SetRadius:
222         RS_DIALOGFACTORY->updateMouseWidget(tr("Specify circle radius"),
223                                             tr("Back"));
224         break;
225     default:
226 		RS_DIALOGFACTORY->updateMouseWidget();
227         break;
228     }
229 }
230 
231 
232 
showOptions()233 void RS_ActionDrawCircleCR::showOptions() {
234     RS_ActionInterface::showOptions();
235 
236     RS_DIALOGFACTORY->requestOptions(this, true);
237 }
238 
239 
240 
hideOptions()241 void RS_ActionDrawCircleCR::hideOptions() {
242     RS_ActionInterface::hideOptions();
243 
244     RS_DIALOGFACTORY->requestOptions(this, false);
245 }
246 
247 
248 
updateMouseCursor()249 void RS_ActionDrawCircleCR::updateMouseCursor() {
250     graphicView->setMouseCursor(RS2::CadCursor);
251 }
252 
253 
getRadius() const254 double RS_ActionDrawCircleCR::getRadius() const{
255 	return data->radius;
256 }
257 // EOF
258 
259