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 // Portions copyright (C) 2001-2003 RibbonSoft
7 // Copyright (C) 2010 Underground Software
8 // See the README and GPLv2 files for licensing and warranty information
10 // JLH = James L. Hammons <jlhamm@acm.org>
13 // --- ---------- -----------------------------------------------------------
14 // JLH 06/03/2010 Added this text. :-)
17 #include "actiondrawarc.h"
19 #include "rs_commandevent.h"
22 #include "rs_dialogfactory.h"
23 #include "graphicview.h"
24 #include "rs_preview.h"
26 ActionDrawArc::ActionDrawArc(RS_EntityContainer & container, GraphicView & graphicView):
27 ActionInterface("Draw arcs", container, graphicView)
32 ActionDrawArc::~ActionDrawArc()
36 RS2::ActionType ActionDrawArc::rtti()
38 return RS2::ActionDrawArc;
41 void ActionDrawArc::reset()
44 data = RS_ArcData(Vector(false), 0.0, 2 * M_PI, 0.0, true);
46 data = RS_ArcData(Vector(false), 0.0, 0.0, 2 * M_PI, false);
49 void ActionDrawArc::init(int status)
51 ActionInterface::init(status);
55 void ActionDrawArc::trigger()
57 ActionInterface::trigger();
59 RS_Arc * arc = new RS_Arc(container, data);
60 arc->setLayerToActive();
61 arc->setPenToActive();
62 container->addEntity(arc);
67 document->startUndoCycle();
68 document->addUndoable(arc);
69 document->endUndoCycle();
73 graphicView->moveRelativeZero(Vector(0.0, 0.0));
74 graphicView->drawEntity(arc);
75 graphicView->moveRelativeZero(arc->getCenter());
81 RS_DEBUG->print("ActionDrawArc::trigger(): arc added: %d", arc->getId());
84 void ActionDrawArc::mouseMoveEvent(QMouseEvent * e)
86 RS_DEBUG->print("ActionDrawArc::mouseMoveEvent begin");
87 Vector mouse = snapPoint(e);
97 if (data.center.valid)
99 data.radius = data.center.distanceTo(mouse);
102 // preview->addEntity(new RS_Circle(preview, RS_CircleData(data.center, data.radius)));
108 data.angle1 = data.center.angleTo(mouse);
111 data.angle2 = RS_Math::correctAngle(data.angle1 - M_PI / 3);
113 data.angle2 = RS_Math::correctAngle(data.angle1 + M_PI / 3);
117 // preview->addEntity(new RS_Arc(preview, data));
122 data.angle2 = data.center.angleTo(mouse);
125 // preview->addEntity(new RS_Arc(preview, data));
130 data.angle2 = data.angle1 + data.center.angleTo(mouse);
133 // preview->addEntity(new RS_Arc(preview, data));
139 double x = data.center.distanceTo(mouse);
141 if (fabs(x / (2 * data.radius)) <= 1.0)
143 data.angle2 = data.angle1 + asin(x / (2 * data.radius)) * 2;
146 // preview->addEntity(new RS_Arc(preview, data));
156 RS_DEBUG->print("ActionDrawArc::mouseMoveEvent end");
159 void ActionDrawArc::mouseReleaseEvent(QMouseEvent * e)
161 if (e->button() == Qt::LeftButton)
163 Vector ce(snapPoint(e));
164 coordinateEvent(&ce);
166 else if (e->button() == Qt::RightButton)
170 init(getStatus() - 1);
174 void ActionDrawArc::coordinateEvent(Vector * e)
185 graphicView->moveRelativeZero(mouse);
187 setStatus(SetRadius);
192 if (data.center.valid)
193 data.radius = data.center.distanceTo(mouse);
195 setStatus(SetAngle1);
199 data.angle1 = data.center.angleTo(mouse);
200 setStatus(SetAngle2);
204 data.angle2 = data.center.angleTo(mouse);
209 data.angle2 = data.angle1 + data.center.angleTo(mouse);
215 double x = data.center.distanceTo(mouse);
217 if (fabs(x / (2 * data.radius)) <= 1.0)
219 data.angle2 = data.angle1 + asin(x / (2 * data.radius)) * 2;
230 void ActionDrawArc::commandEvent(RS_CommandEvent * e)
232 QString c = e->getCommand().toLower();
234 if (RS_COMMANDS->checkCommand("help", c))
236 if (RS_DIALOGFACTORY != NULL)
237 RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
238 + getAvailableCommands().join(", "));
242 if (RS_COMMANDS->checkCommand("reversed", c))
245 setReversed(!isReversed());
247 if (RS_DIALOGFACTORY != NULL)
248 RS_DIALOGFACTORY->requestOptions(this, true, true);
256 double r = RS_Math::eval(c, &ok);
261 setStatus(SetAngle1);
263 else if (RS_DIALOGFACTORY != NULL)
264 RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
271 double a = RS_Math::eval(c, &ok);
275 data.angle1 = RS_Math::deg2rad(a);
276 setStatus(SetAngle2);
278 else if (RS_DIALOGFACTORY != NULL)
279 RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
286 if (RS_COMMANDS->checkCommand("angle", c))
287 setStatus(SetIncAngle);
288 else if (RS_COMMANDS->checkCommand("chord length", c))
289 setStatus(SetChordLength);
293 double a = RS_Math::eval(c, &ok);
297 data.angle2 = RS_Math::deg2rad(a);
300 else if (RS_DIALOGFACTORY != NULL)
301 RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
308 double a = RS_Math::eval(c, &ok);
312 data.angle2 = data.angle1 + RS_Math::deg2rad(a);
315 else if (RS_DIALOGFACTORY != NULL)
316 RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
321 case SetChordLength: {
323 double l = RS_Math::eval(c, &ok);
327 if (fabs(l / (2 * data.radius)) <= 1.0)
329 data.angle2 = data.angle1 + asin(l / (2 * data.radius)) * 2;
332 else if (RS_DIALOGFACTORY != NULL)
333 RS_DIALOGFACTORY->commandMessage(
334 tr("Not a valid chord length"));
337 else if (RS_DIALOGFACTORY != NULL)
338 RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
348 QStringList ActionDrawArc::getAvailableCommands()
351 cmd += RS_COMMANDS->command("reversed");
355 void ActionDrawArc::updateMouseButtonHints()
357 if (RS_DIALOGFACTORY != NULL)
362 RS_DIALOGFACTORY->updateMouseWidget(tr("Specify center"), tr("Cancel"));
366 RS_DIALOGFACTORY->updateMouseWidget(tr("Specify radius"), tr("Back"));
370 RS_DIALOGFACTORY->updateMouseWidget(
371 tr("Specify start angle:"), tr("Back"));
375 RS_DIALOGFACTORY->updateMouseWidget(
376 tr("Specify end angle or [Angle/chord Length]"),
381 RS_DIALOGFACTORY->updateMouseWidget(tr("Specify included angle:"),
386 RS_DIALOGFACTORY->updateMouseWidget(tr("Specify chord length:"),
391 RS_DIALOGFACTORY->updateMouseWidget("", "");
397 void ActionDrawArc::showOptions()
399 ActionInterface::showOptions();
401 if (RS_DIALOGFACTORY)
402 RS_DIALOGFACTORY->requestOptions(this, true);
405 void ActionDrawArc::hideOptions()
407 ActionInterface::hideOptions();
409 if (RS_DIALOGFACTORY)
410 RS_DIALOGFACTORY->requestOptions(this, false);
413 void ActionDrawArc::updateMouseCursor()
415 graphicView->setMouseCursor(RS2::CadCursor);
418 void ActionDrawArc::updateToolBar()
420 if (!RS_DIALOGFACTORY)
424 RS_DIALOGFACTORY->requestToolBar(RS2::ToolBarSnap);
426 RS_DIALOGFACTORY->requestToolBar(RS2::ToolBarArcs);
429 bool ActionDrawArc::isReversed()
431 return data.reversed;
434 void ActionDrawArc::setReversed(bool r)