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. :-)
15 // JLH 09/17/2010 Fixed preview/snapper rendering.
18 #include "actiondrawarc.h"
20 #include "commandevent.h"
23 #include "dialogfactory.h"
24 #include "graphicview.h"
27 ActionDrawArc::ActionDrawArc(EntityContainer & container, GraphicView & graphicView):
28 ActionInterface("Draw arcs", container, graphicView)
33 ActionDrawArc::~ActionDrawArc()
37 RS2::ActionType ActionDrawArc::rtti()
39 return RS2::ActionDrawArc;
42 void ActionDrawArc::reset()
45 data = ArcData(Vector(false), 0.0, 2 * M_PI, 0.0, true);
47 data = ArcData(Vector(false), 0.0, 0.0, 2 * M_PI, false);
50 void ActionDrawArc::init(int status)
52 ActionInterface::init(status);
56 void ActionDrawArc::trigger()
58 ActionInterface::trigger();
60 Arc * arc = new Arc(container, data);
61 arc->setLayerToActive();
62 arc->setPenToActive();
63 container->addEntity(arc);
68 document->startUndoCycle();
69 document->addUndoable(arc);
70 document->endUndoCycle();
73 graphicView->moveRelativeZero(arc->getCenter());
74 graphicView->redraw(); //hm.
78 DEBUG->print("ActionDrawArc::trigger(): arc added: %d", arc->getId());
81 void ActionDrawArc::mouseMoveEvent(QMouseEvent * e)
83 DEBUG->print("ActionDrawArc::mouseMoveEvent begin");
84 Vector mouse = snapPoint(e);
94 if (data.center.valid)
96 data.radius = data.center.distanceTo(mouse);
97 graphicView->preview.clear();
98 graphicView->preview.addEntity(new Circle(&(graphicView->preview), CircleData(data.center, data.radius)));
103 data.angle1 = data.center.angleTo(mouse);
106 data.angle2 = Math::correctAngle(data.angle1 - M_PI / 3);
108 data.angle2 = Math::correctAngle(data.angle1 + M_PI / 3);
110 graphicView->preview.clear();
111 graphicView->preview.addEntity(new Arc(&(graphicView->preview), data));
115 data.angle2 = data.center.angleTo(mouse);
116 graphicView->preview.clear();
117 graphicView->preview.addEntity(new Arc(&(graphicView->preview), data));
121 data.angle2 = data.angle1 + data.center.angleTo(mouse);
122 graphicView->preview.clear();
123 graphicView->preview.addEntity(new Arc(&(graphicView->preview), data));
128 double x = data.center.distanceTo(mouse);
130 if (fabs(x / (2 * data.radius)) <= 1.0)
132 data.angle2 = data.angle1 + asin(x / (2 * data.radius)) * 2;
133 graphicView->preview.clear();
134 graphicView->preview.addEntity(new Arc(&(graphicView->preview), data));
143 graphicView->redraw();
144 DEBUG->print("ActionDrawArc::mouseMoveEvent end");
147 void ActionDrawArc::mouseReleaseEvent(QMouseEvent * e)
149 if (e->button() == Qt::LeftButton)
151 Vector ce(snapPoint(e));
152 coordinateEvent(&ce);
154 else if (e->button() == Qt::RightButton)
158 init(getStatus() - 1);
159 graphicView->redraw(); //hm.
163 void ActionDrawArc::coordinateEvent(Vector * e)
174 graphicView->moveRelativeZero(mouse);
176 setStatus(SetRadius);
181 if (data.center.valid)
182 data.radius = data.center.distanceTo(mouse);
184 setStatus(SetAngle1);
188 data.angle1 = data.center.angleTo(mouse);
189 setStatus(SetAngle2);
193 data.angle2 = data.center.angleTo(mouse);
198 data.angle2 = data.angle1 + data.center.angleTo(mouse);
204 double x = data.center.distanceTo(mouse);
206 if (fabs(x / (2 * data.radius)) <= 1.0)
208 data.angle2 = data.angle1 + asin(x / (2 * data.radius)) * 2;
219 void ActionDrawArc::commandEvent(CommandEvent * e)
221 QString c = e->getCommand().toLower();
223 if (COMMANDS->checkCommand("help", c))
225 if (DIALOGFACTORY != NULL)
226 DIALOGFACTORY->commandMessage(msgAvailableCommands()
227 + getAvailableCommands().join(", "));
231 if (COMMANDS->checkCommand("reversed", c))
234 setReversed(!isReversed());
236 if (DIALOGFACTORY != NULL)
237 DIALOGFACTORY->requestOptions(this, true, true);
246 double r = Math::eval(c, &ok);
251 setStatus(SetAngle1);
253 else if (DIALOGFACTORY)
254 DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
261 double a = Math::eval(c, &ok);
265 data.angle1 = Math::deg2rad(a);
266 setStatus(SetAngle2);
268 else if (DIALOGFACTORY)
269 DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
275 if (COMMANDS->checkCommand("angle", c))
276 setStatus(SetIncAngle);
277 else if (COMMANDS->checkCommand("chord length", c))
278 setStatus(SetChordLength);
282 double a = Math::eval(c, &ok);
286 data.angle2 = Math::deg2rad(a);
289 else if (DIALOGFACTORY)
290 DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
297 double a = Math::eval(c, &ok);
301 data.angle2 = data.angle1 + Math::deg2rad(a);
304 else if (DIALOGFACTORY)
305 DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
312 double l = Math::eval(c, &ok);
316 if (fabs(l / (2 * data.radius)) <= 1.0)
318 data.angle2 = data.angle1 + asin(l / (2 * data.radius)) * 2;
321 else if (DIALOGFACTORY)
322 DIALOGFACTORY->commandMessage(tr("Not a valid chord length"));
325 else if (DIALOGFACTORY)
326 DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
335 QStringList ActionDrawArc::getAvailableCommands()
338 cmd += COMMANDS->command("reversed");
342 void ActionDrawArc::updateMouseButtonHints()
349 DIALOGFACTORY->updateMouseWidget(tr("Specify center"), tr("Cancel"));
353 DIALOGFACTORY->updateMouseWidget(tr("Specify radius"), tr("Back"));
357 DIALOGFACTORY->updateMouseWidget(
358 tr("Specify start angle:"), tr("Back"));
362 DIALOGFACTORY->updateMouseWidget(
363 tr("Specify end angle or [Angle/chord Length]"),
368 DIALOGFACTORY->updateMouseWidget(tr("Specify included angle:"),
373 DIALOGFACTORY->updateMouseWidget(tr("Specify chord length:"),
378 DIALOGFACTORY->updateMouseWidget("", "");
384 void ActionDrawArc::showOptions()
386 ActionInterface::showOptions();
389 DIALOGFACTORY->requestOptions(this, true);
392 void ActionDrawArc::hideOptions()
394 ActionInterface::hideOptions();
397 DIALOGFACTORY->requestOptions(this, false);
400 void ActionDrawArc::updateMouseCursor()
402 graphicView->setMouseCursor(RS2::CadCursor);
405 void ActionDrawArc::updateToolBar()
411 DIALOGFACTORY->requestToolBar(RS2::ToolBarSnap);
413 DIALOGFACTORY->requestToolBar(RS2::ToolBarArcs);
416 bool ActionDrawArc::isReversed()
418 return data.reversed;
421 void ActionDrawArc::setReversed(bool r)