3 // Part of the Architektonas Project
4 // Originally part of QCad Community Edition by Andrew Mustun
5 // Extensively rewritten and refactored by James L. Hammons
6 // (C) 2010 Underground Software
8 // JLH = James L. Hammons <jlhamm@acm.org>
11 // --- ---------- -----------------------------------------------------------
12 // JLH 06/03/2010 Added this text. :-)
15 #include "actiondrawarc.h"
17 #include "rs_commandevent.h"
19 #include "rs_dialogfactory.h"
20 #include "graphicview.h"
21 #include "rs_preview.h"
23 ActionDrawArc::ActionDrawArc(RS_EntityContainer & container, GraphicView & graphicView):
24 ActionInterface("Draw arcs", container, graphicView)
29 ActionDrawArc::~ActionDrawArc()
33 RS2::ActionType ActionDrawArc::rtti()
35 return RS2::ActionDrawArc;
38 void ActionDrawArc::reset()
41 data = RS_ArcData(Vector(false), 0.0, 2 * M_PI, 0.0, true);
43 data = RS_ArcData(Vector(false), 0.0, 0.0, 2 * M_PI, false);
46 void ActionDrawArc::init(int status)
48 ActionInterface::init(status);
52 void ActionDrawArc::trigger()
54 ActionInterface::trigger();
56 RS_Arc * arc = new RS_Arc(container, data);
57 arc->setLayerToActive();
58 arc->setPenToActive();
59 container->addEntity(arc);
64 document->startUndoCycle();
65 document->addUndoable(arc);
66 document->endUndoCycle();
70 graphicView->moveRelativeZero(Vector(0.0, 0.0));
71 graphicView->drawEntity(arc);
72 graphicView->moveRelativeZero(arc->getCenter());
78 RS_DEBUG->print("ActionDrawArc::trigger(): arc added: %d", arc->getId());
81 void ActionDrawArc::mouseMoveEvent(QMouseEvent * e)
83 RS_DEBUG->print("ActionDrawArc::mouseMoveEvent begin");
84 Vector mouse = snapPoint(e);
94 if (data.center.valid)
96 data.radius = data.center.distanceTo(mouse);
99 // preview->addEntity(new RS_Circle(preview, RS_CircleData(data.center, data.radius)));
105 data.angle1 = data.center.angleTo(mouse);
108 data.angle2 = RS_Math::correctAngle(data.angle1 - M_PI / 3);
110 data.angle2 = RS_Math::correctAngle(data.angle1 + M_PI / 3);
114 // preview->addEntity(new RS_Arc(preview, data));
119 data.angle2 = data.center.angleTo(mouse);
122 // preview->addEntity(new RS_Arc(preview, data));
127 data.angle2 = data.angle1 + data.center.angleTo(mouse);
130 // preview->addEntity(new RS_Arc(preview, data));
136 double x = data.center.distanceTo(mouse);
138 if (fabs(x / (2 * data.radius)) <= 1.0)
140 data.angle2 = data.angle1 + asin(x / (2 * data.radius)) * 2;
143 // preview->addEntity(new RS_Arc(preview, data));
153 RS_DEBUG->print("ActionDrawArc::mouseMoveEvent end");
156 void ActionDrawArc::mouseReleaseEvent(QMouseEvent * e)
158 if (e->button() == Qt::LeftButton)
160 Vector ce(snapPoint(e));
161 coordinateEvent(&ce);
163 else if (e->button() == Qt::RightButton)
167 init(getStatus() - 1);
171 void ActionDrawArc::coordinateEvent(Vector * e)
182 graphicView->moveRelativeZero(mouse);
184 setStatus(SetRadius);
189 if (data.center.valid)
190 data.radius = data.center.distanceTo(mouse);
192 setStatus(SetAngle1);
196 data.angle1 = data.center.angleTo(mouse);
197 setStatus(SetAngle2);
201 data.angle2 = data.center.angleTo(mouse);
206 data.angle2 = data.angle1 + data.center.angleTo(mouse);
212 double x = data.center.distanceTo(mouse);
214 if (fabs(x / (2 * data.radius)) <= 1.0)
216 data.angle2 = data.angle1 + asin(x / (2 * data.radius)) * 2;
227 void ActionDrawArc::commandEvent(RS_CommandEvent * e)
229 QString c = e->getCommand().toLower();
231 if (RS_COMMANDS->checkCommand("help", c))
233 if (RS_DIALOGFACTORY != NULL)
234 RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
235 + getAvailableCommands().join(", "));
239 if (RS_COMMANDS->checkCommand("reversed", c))
242 setReversed(!isReversed());
244 if (RS_DIALOGFACTORY != NULL)
245 RS_DIALOGFACTORY->requestOptions(this, true, true);
253 double r = RS_Math::eval(c, &ok);
258 setStatus(SetAngle1);
260 else if (RS_DIALOGFACTORY != NULL)
261 RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
268 double a = RS_Math::eval(c, &ok);
272 data.angle1 = RS_Math::deg2rad(a);
273 setStatus(SetAngle2);
275 else if (RS_DIALOGFACTORY != NULL)
276 RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
283 if (RS_COMMANDS->checkCommand("angle", c))
284 setStatus(SetIncAngle);
285 else if (RS_COMMANDS->checkCommand("chord length", c))
286 setStatus(SetChordLength);
290 double a = RS_Math::eval(c, &ok);
294 data.angle2 = RS_Math::deg2rad(a);
297 else if (RS_DIALOGFACTORY != NULL)
298 RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
305 double a = RS_Math::eval(c, &ok);
309 data.angle2 = data.angle1 + RS_Math::deg2rad(a);
312 else if (RS_DIALOGFACTORY != NULL)
313 RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
318 case SetChordLength: {
320 double l = RS_Math::eval(c, &ok);
324 if (fabs(l / (2 * data.radius)) <= 1.0)
326 data.angle2 = data.angle1 + asin(l / (2 * data.radius)) * 2;
329 else if (RS_DIALOGFACTORY != NULL)
330 RS_DIALOGFACTORY->commandMessage(
331 tr("Not a valid chord length"));
334 else if (RS_DIALOGFACTORY != NULL)
335 RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
345 QStringList ActionDrawArc::getAvailableCommands()
348 cmd += RS_COMMANDS->command("reversed");
352 void ActionDrawArc::updateMouseButtonHints()
354 if (RS_DIALOGFACTORY != NULL)
359 RS_DIALOGFACTORY->updateMouseWidget(tr("Specify center"), tr("Cancel"));
363 RS_DIALOGFACTORY->updateMouseWidget(tr("Specify radius"), tr("Back"));
367 RS_DIALOGFACTORY->updateMouseWidget(
368 tr("Specify start angle:"), tr("Back"));
372 RS_DIALOGFACTORY->updateMouseWidget(
373 tr("Specify end angle or [Angle/chord Length]"),
378 RS_DIALOGFACTORY->updateMouseWidget(tr("Specify included angle:"),
383 RS_DIALOGFACTORY->updateMouseWidget(tr("Specify chord length:"),
388 RS_DIALOGFACTORY->updateMouseWidget("", "");
394 void ActionDrawArc::showOptions()
396 ActionInterface::showOptions();
398 if (RS_DIALOGFACTORY)
399 RS_DIALOGFACTORY->requestOptions(this, true);
402 void ActionDrawArc::hideOptions()
404 ActionInterface::hideOptions();
406 if (RS_DIALOGFACTORY)
407 RS_DIALOGFACTORY->requestOptions(this, false);
410 void ActionDrawArc::updateMouseCursor()
412 graphicView->setMouseCursor(RS2::CadCursor);
415 void ActionDrawArc::updateToolBar()
417 if (!RS_DIALOGFACTORY)
421 RS_DIALOGFACTORY->requestToolBar(RS2::ToolBarSnap);
423 RS_DIALOGFACTORY->requestToolBar(RS2::ToolBarArcs);
426 bool ActionDrawArc::isReversed()
428 return data.reversed;
431 void ActionDrawArc::setReversed(bool r)