]> Shamusworld >> Repos - architektonas/blob - src/actions/rs_actiondimlinear.cpp
Initial import
[architektonas] / src / actions / rs_actiondimlinear.cpp
1 // rs_actiondimlinear.cpp
2 //
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
7 //
8 // JLH = James L. Hammons <jlhamm@acm.org>
9 //
10 // Who  When        What
11 // ---  ----------  -----------------------------------------------------------
12 // JLH  05/22/2010  Added this text. :-)
13 //
14
15 #include "rs_actiondimlinear.h"
16
17 #include "rs_snapper.h"
18 #include "rs_constructionline.h"
19 #include "rs_dialogfactory.h"
20
21 /**
22  * Constructor.
23  *
24  * @param angle Initial angle in rad.
25  * @param fixedAngle true: The user can't change the angle.
26  *                   false: The user can change the angle in a option widget.
27  */
28 RS_ActionDimLinear::RS_ActionDimLinear(RS_EntityContainer& container,
29         RS_GraphicView& graphicView, double angle, bool fixedAngle):
30         RS_ActionDimension("Draw linear dimensions", container, graphicView)
31 {
32         edata.angle = angle;
33         this->fixedAngle = fixedAngle;
34
35         lastStatus = SetExtPoint1;
36
37         reset();
38 }
39
40 RS_ActionDimLinear::~RS_ActionDimLinear()
41 {
42 }
43
44 QAction * RS_ActionDimLinear::createGUIAction(RS2::ActionType type, QObject * /*parent*/)
45 {
46         QAction * action;
47
48         switch (type)
49         {
50         default:
51         case RS2::ActionDimLinear:
52                 action = new QAction(tr("&Linear"), 0);
53 //        action = new QAction(tr("Linear"), tr("&Linear"),
54 //                             QKeySequence(), NULL);
55                 action->setStatusTip(tr("Linear Dimension"));
56                 break;
57
58         case RS2::ActionDimLinearHor:
59                 action = new QAction(tr("&Horizontal"), 0);
60 //        action = new QAction(tr("Horizontal"), tr("&Horizontal"),
61 //                             QKeySequence(), NULL);
62                 action->setStatusTip(tr("Horizontal Dimension"));
63                 break;
64
65         case RS2::ActionDimLinearVer:
66                 action = new QAction(tr("&Vertical"), 0);
67 //        action = new QAction(tr("Vertical"), tr("&Vertical"),
68 //                             QKeySequence(), NULL);
69                 action->setStatusTip(tr("Vertical Dimension"));
70                 break;
71         }
72
73         return action;
74 }
75
76
77 void RS_ActionDimLinear::reset() {
78     RS_ActionDimension::reset();
79
80     edata = RS_DimLinearData(Vector(false),
81                              Vector(false),
82                              (fixedAngle ? edata.angle : 0.0), 0.0);
83
84     if (RS_DIALOGFACTORY!=NULL) {
85         RS_DIALOGFACTORY->requestOptions(this, true, true);
86     }
87 }
88
89
90
91 void RS_ActionDimLinear::trigger() {
92     RS_ActionDimension::trigger();
93
94     preparePreview();
95     RS_DimLinear* dim = new RS_DimLinear(container, data, edata);
96     dim->setLayerToActive();
97     dim->setPenToActive();
98     dim->update();
99     container->addEntity(dim);
100
101     // upd. undo list:
102     if (document!=NULL) {
103         document->startUndoCycle();
104         document->addUndoable(dim);
105         document->endUndoCycle();
106     }
107
108     deleteSnapper();
109     Vector rz = graphicView->getRelativeZero();
110     graphicView->moveRelativeZero(Vector(0.0,0.0));
111     graphicView->drawEntity(dim);
112     graphicView->moveRelativeZero(rz);
113     drawSnapper();
114
115     RS_DEBUG->print("RS_ActionDimLinear::trigger():"
116                     " dim added: %d", dim->getId());
117 }
118
119
120 void RS_ActionDimLinear::preparePreview() {
121     Vector dirV;
122     dirV.setPolar(100.0, edata.angle+M_PI/2.0);
123
124     RS_ConstructionLine cl(
125         NULL,
126         RS_ConstructionLineData(
127             edata.extensionPoint2,
128             edata.extensionPoint2+dirV));
129
130     data.definitionPoint =
131         cl.getNearestPointOnEntity(data.definitionPoint);
132
133 }
134
135
136
137 void RS_ActionDimLinear::mouseMoveEvent(QMouseEvent* e) {
138     RS_DEBUG->print("RS_ActionDimLinear::mouseMoveEvent begin");
139
140     Vector mouse = snapPoint(e);
141
142     switch (getStatus()) {
143     case SetExtPoint1:
144         break;
145
146     case SetExtPoint2:
147         if (edata.extensionPoint1.valid) {
148             deletePreview();
149             clearPreview();
150             preview->addEntity(new RS_Line(preview,
151                                            RS_LineData(edata.extensionPoint1,
152                                                        mouse)));
153             drawPreview();
154         }
155         break;
156
157     case SetDefPoint:
158         if (edata.extensionPoint1.valid && edata.extensionPoint2.valid) {
159             deletePreview();
160             clearPreview();
161             data.definitionPoint = mouse;
162
163             preparePreview();
164
165             RS_DimLinear* dim = new RS_DimLinear(preview, data, edata);
166             dim->update();
167             preview->addEntity(dim);
168             drawPreview();
169         }
170         break;
171     }
172
173     RS_DEBUG->print("RS_ActionDimLinear::mouseMoveEvent end");
174 }
175
176
177
178 void RS_ActionDimLinear::mouseReleaseEvent(QMouseEvent* e) {
179     if (RS2::qtToRsButtonState(e->button())==RS2::LeftButton) {
180         RS_CoordinateEvent ce(snapPoint(e));
181         coordinateEvent(&ce);
182     } else if (RS2::qtToRsButtonState(e->button())==RS2::RightButton) {
183         deletePreview();
184         deleteSnapper();
185         init(getStatus()-1);
186     }
187 }
188
189
190
191 void RS_ActionDimLinear::coordinateEvent(RS_CoordinateEvent* e) {
192     if (e==NULL) {
193         return;
194     }
195
196     Vector pos = e->getCoordinate();
197
198     switch (getStatus()) {
199     case SetExtPoint1:
200         edata.extensionPoint1 = pos;
201         graphicView->moveRelativeZero(pos);
202         setStatus(SetExtPoint2);
203         break;
204
205     case SetExtPoint2:
206         edata.extensionPoint2 = pos;
207         graphicView->moveRelativeZero(pos);
208         setStatus(SetDefPoint);
209         break;
210
211     case SetDefPoint:
212         data.definitionPoint = pos;
213         trigger();
214         reset();
215         setStatus(SetExtPoint1);
216         break;
217
218     default:
219         break;
220     }
221 }
222
223
224
225 void RS_ActionDimLinear::commandEvent(RS_CommandEvent* e) {
226     QString c = e->getCommand().toLower();
227
228     if (checkCommand("help", c)) {
229         if (RS_DIALOGFACTORY!=NULL) {
230             RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
231                                              + getAvailableCommands().join(", "));
232         }
233         return;
234     }
235
236     switch (getStatus()) {
237     case SetText:
238         setText(c);
239         if (RS_DIALOGFACTORY!=NULL) {
240             RS_DIALOGFACTORY->requestOptions(this, true, true);
241         }
242         graphicView->enableCoordinateInput();
243         setStatus(lastStatus);
244         break;
245
246     case SetAngle: {
247             bool ok;
248             double a = RS_Math::eval(c, &ok);
249             if (ok==true) {
250                 setAngle(RS_Math::deg2rad(a));
251             } else {
252                 if (RS_DIALOGFACTORY!=NULL) {
253                     RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
254                 }
255             }
256             if (RS_DIALOGFACTORY!=NULL) {
257                 RS_DIALOGFACTORY->requestOptions(this, true, true);
258             }
259             setStatus(lastStatus);
260         }
261         break;
262
263     default:
264         lastStatus = (Status)getStatus();
265         deleteSnapper();
266         deletePreview();
267         clearPreview();
268         if (checkCommand("text", c)) {
269             graphicView->disableCoordinateInput();
270             setStatus(SetText);
271             return;
272         } else if (!fixedAngle && (checkCommand("angle", c))) {
273             setStatus(SetAngle);
274         }
275         break;
276     }
277 }
278
279
280
281 QStringList RS_ActionDimLinear::getAvailableCommands() {
282     QStringList cmd;
283
284     switch (getStatus()) {
285     case SetExtPoint1:
286     case SetExtPoint2:
287     case SetDefPoint:
288         cmd += command("text");
289         if (!fixedAngle) {
290             cmd += command("angle");
291         }
292         break;
293
294     default:
295         break;
296     }
297
298     return cmd;
299 }
300
301
302 void RS_ActionDimLinear::updateMouseButtonHints() {
303     if (RS_DIALOGFACTORY!=NULL) {
304         switch (getStatus()) {
305         case SetExtPoint1:
306             RS_DIALOGFACTORY->updateMouseWidget(
307                 tr("Specify first extension line origin"),
308                 tr("Cancel"));
309             break;
310         case SetExtPoint2:
311             RS_DIALOGFACTORY->updateMouseWidget(
312                 tr("Specify second extension line origin"),
313                 tr("Back"));
314             break;
315         case SetDefPoint:
316             RS_DIALOGFACTORY->updateMouseWidget(
317                 tr("Specify dimension line location"),
318                 tr("Back"));
319             break;
320         case SetText:
321             RS_DIALOGFACTORY->updateMouseWidget(tr("Enter dimension text:"), "");
322             break;
323         case SetAngle:
324             RS_DIALOGFACTORY->updateMouseWidget(
325                 tr("Enter dimension line angle:"), "");
326             break;
327         default:
328             RS_DIALOGFACTORY->updateMouseWidget("", "");
329             break;
330         }
331     }
332 }
333
334
335
336 void RS_ActionDimLinear::showOptions() {
337     RS_ActionInterface::showOptions();
338
339     if (RS_DIALOGFACTORY!=NULL) {
340         RS_DIALOGFACTORY->requestOptions(this, true, true);
341     }
342 }
343
344
345
346 void RS_ActionDimLinear::hideOptions() {
347     RS_ActionInterface::hideOptions();
348
349     if (RS_DIALOGFACTORY!=NULL) {
350         RS_DIALOGFACTORY->requestOptions(this, false);
351     }
352 }
353
354
355
356 // EOF