1 /****************************************************************************
2 ** $Id: rs_actiondrawarc.cpp 1161 2004-12-09 23:10:09Z andrew $
4 ** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
6 ** This file is part of the qcadlib Library project.
8 ** This file may be distributed and/or modified under the terms of the
9 ** GNU General Public License version 2 as published by the Free Software
10 ** Foundation and appearing in the file LICENSE.GPL included in the
11 ** packaging of this file.
13 ** Licensees holding valid qcadlib Professional Edition licenses may use
14 ** this file in accordance with the qcadlib Commercial License
15 ** Agreement provided with the Software.
17 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
18 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20 ** See http://www.ribbonsoft.com for further details.
22 ** Contact info@ribbonsoft.com if any conditions of this licensing are
25 **********************************************************************/
27 #include "rs_actiondrawarc.h"
30 #include "rs_snapper.h"
31 #include "rs_dialogfactory.h"
33 RS_ActionDrawArc::RS_ActionDrawArc(RS_EntityContainer & container, RS_GraphicView & graphicView):
34 RS_PreviewActionInterface("Draw arcs", container, graphicView)
39 RS_ActionDrawArc::~RS_ActionDrawArc()
43 QAction * RS_ActionDrawArc::createGUIAction(RS2::ActionType /*type*/, QObject * /*parent*/)
45 QAction * action = new QAction(tr("&Center, Point, Angles"), 0);
46 // QAction* action = new QAction(tr("Arc: Center, Point, Angles"),
47 // tr("&Center, Point, Angles"),
48 // QKeySequence(), NULL);
49 action->setStatusTip(tr("Draw arcs"));
53 RS2::ActionType RS_ActionDrawArc::rtti()
55 return RS2::ActionDrawArc;
58 void RS_ActionDrawArc::reset()
60 //bool rev = data.reversed;
63 data = RS_ArcData(Vector(false), 0.0, 2 * M_PI, 0.0, true);
65 data = RS_ArcData(Vector(false), 0.0, 0.0, 2 * M_PI, false);
68 void RS_ActionDrawArc::init(int status)
70 RS_PreviewActionInterface::init(status);
74 void RS_ActionDrawArc::trigger()
76 RS_PreviewActionInterface::trigger();
78 RS_Arc * arc = new RS_Arc(container, data);
79 arc->setLayerToActive();
80 arc->setPenToActive();
81 container->addEntity(arc);
86 document->startUndoCycle();
87 document->addUndoable(arc);
88 document->endUndoCycle();
92 graphicView->moveRelativeZero(Vector(0.0, 0.0));
93 graphicView->drawEntity(arc);
94 graphicView->moveRelativeZero(arc->getCenter());
100 RS_DEBUG->print("RS_ActionDrawArc::trigger(): arc added: %d", arc->getId());
103 void RS_ActionDrawArc::mouseMoveEvent(QMouseEvent * e)
105 RS_DEBUG->print("RS_ActionDrawArc::mouseMoveEvent begin");
106 Vector mouse = snapPoint(e);
115 if (data.center.valid)
117 data.radius = data.center.distanceTo(mouse);
120 preview->addEntity(new RS_Circle(preview, RS_CircleData(data.center, data.radius)));
126 data.angle1 = data.center.angleTo(mouse);
129 data.angle2 = RS_Math::correctAngle(data.angle1 - M_PI / 3);
131 data.angle2 = RS_Math::correctAngle(data.angle1 + M_PI / 3);
135 preview->addEntity(new RS_Arc(preview, data));
140 data.angle2 = data.center.angleTo(mouse);
143 preview->addEntity(new RS_Arc(preview, data));
148 data.angle2 = data.angle1 + data.center.angleTo(mouse);
151 preview->addEntity(new RS_Arc(preview, data));
157 double x = data.center.distanceTo(mouse);
158 if (fabs(x / (2 * data.radius)) <= 1.0)
160 data.angle2 = data.angle1 + asin(x / (2 * data.radius)) * 2;
163 preview->addEntity(new RS_Arc(preview, data));
174 RS_DEBUG->print("RS_ActionDrawArc::mouseMoveEvent end");
177 void RS_ActionDrawArc::mouseReleaseEvent(QMouseEvent * e)
179 if (RS2::qtToRsButtonState(e->button()) == RS2::LeftButton)
181 RS_CoordinateEvent ce(snapPoint(e));
182 coordinateEvent(&ce);
184 else if (RS2::qtToRsButtonState(e->button()) == RS2::RightButton)
188 init(getStatus() - 1);
192 void RS_ActionDrawArc::coordinateEvent(RS_CoordinateEvent * e)
197 Vector mouse = e->getCoordinate();
203 graphicView->moveRelativeZero(mouse);
205 setStatus(SetRadius);
209 if (data.center.valid)
210 data.radius = data.center.distanceTo(mouse);
212 setStatus(SetAngle1);
216 data.angle1 = data.center.angleTo(mouse);
217 setStatus(SetAngle2);
221 data.angle2 = data.center.angleTo(mouse);
226 data.angle2 = data.angle1 + data.center.angleTo(mouse);
232 double x = data.center.distanceTo(mouse);
234 if (fabs(x / (2 * data.radius)) <= 1.0)
236 data.angle2 = data.angle1 + asin(x / (2 * data.radius)) * 2;
247 void RS_ActionDrawArc::commandEvent(RS_CommandEvent * e)
249 QString c = e->getCommand().toLower();
251 if (RS_COMMANDS->checkCommand("help", c)) {
252 if (RS_DIALOGFACTORY!=NULL) {
253 RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
254 + getAvailableCommands().join(", "));
259 if (RS_COMMANDS->checkCommand("reversed", c)) {
261 setReversed(!isReversed());
263 if (RS_DIALOGFACTORY!=NULL) {
264 RS_DIALOGFACTORY->requestOptions(this, true, true);
269 switch (getStatus()) {
273 double r = RS_Math::eval(c, &ok);
276 setStatus(SetAngle1);
278 if (RS_DIALOGFACTORY!=NULL) {
279 RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
287 double a = RS_Math::eval(c, &ok);
289 data.angle1 = RS_Math::deg2rad(a);
290 setStatus(SetAngle2);
292 if (RS_DIALOGFACTORY!=NULL) {
293 RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
300 if (RS_COMMANDS->checkCommand("angle", c)) {
301 setStatus(SetIncAngle);
302 } else if (RS_COMMANDS->checkCommand("chord length", c)) {
303 setStatus(SetChordLength);
306 double a = RS_Math::eval(c, &ok);
308 data.angle2 = RS_Math::deg2rad(a);
311 if (RS_DIALOGFACTORY!=NULL) {
312 RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
321 double a = RS_Math::eval(c, &ok);
323 data.angle2 = data.angle1 + RS_Math::deg2rad(a);
326 if (RS_DIALOGFACTORY!=NULL) {
327 RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
333 case SetChordLength: {
335 double l = RS_Math::eval(c, &ok);
337 if (fabs(l/(2*data.radius))<=1.0) {
338 data.angle2 = data.angle1 + asin(l/(2*data.radius)) * 2;
341 if (RS_DIALOGFACTORY!=NULL) {
342 RS_DIALOGFACTORY->commandMessage(
343 tr("Not a valid chord length"));
347 if (RS_DIALOGFACTORY!=NULL) {
348 RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
359 QStringList RS_ActionDrawArc::getAvailableCommands()
362 cmd += RS_COMMANDS->command("reversed");
366 void RS_ActionDrawArc::updateMouseButtonHints()
368 if (RS_DIALOGFACTORY != NULL)
373 RS_DIALOGFACTORY->updateMouseWidget(tr("Specify center"), tr("Cancel"));
376 RS_DIALOGFACTORY->updateMouseWidget(tr("Specify radius"), tr("Back"));
379 RS_DIALOGFACTORY->updateMouseWidget(
380 tr("Specify start angle:"), tr("Back"));
383 RS_DIALOGFACTORY->updateMouseWidget(
384 tr("Specify end angle or [Angle/chord Length]"),
388 RS_DIALOGFACTORY->updateMouseWidget(tr("Specify included angle:"),
392 RS_DIALOGFACTORY->updateMouseWidget(tr("Specify chord length:"),
396 RS_DIALOGFACTORY->updateMouseWidget("", "");
402 void RS_ActionDrawArc::showOptions()
404 RS_ActionInterface::showOptions();
406 if (RS_DIALOGFACTORY != NULL)
407 RS_DIALOGFACTORY->requestOptions(this, true);
410 void RS_ActionDrawArc::hideOptions()
412 RS_ActionInterface::hideOptions();
414 if (RS_DIALOGFACTORY != NULL)
415 RS_DIALOGFACTORY->requestOptions(this, false);
418 void RS_ActionDrawArc::updateMouseCursor()
420 graphicView->setMouseCursor(RS2::CadCursor);
423 void RS_ActionDrawArc::updateToolBar()
425 if (RS_DIALOGFACTORY == NULL)
429 RS_DIALOGFACTORY->requestToolBar(RS2::ToolBarSnap);
431 RS_DIALOGFACTORY->requestToolBar(RS2::ToolBarArcs);
434 bool RS_ActionDrawArc::isReversed()
436 return data.reversed;
439 void RS_ActionDrawArc::setReversed(bool r)