]> Shamusworld >> Repos - architektonas/blob - src/base/dimradial.cpp
Fixed problem with MDI activation.
[architektonas] / src / base / dimradial.cpp
1 // dimradial.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 // Portions copyright (C) 2001-2003 RibbonSoft
7 // Copyright (C) 2010 Underground Software
8 // See the README and GPLv2 files for licensing and warranty information
9 //
10 // JLH = James L. Hammons <jlhamm@acm.org>
11 //
12 // Who  When        What
13 // ---  ----------  -----------------------------------------------------------
14 // JLH  05/28/2010  Added this text. :-)
15 //
16
17 #include "dimradial.h"
18
19 #include "drawing.h"
20 #include "solid.h"
21 #include "text.h"
22 #include "units.h"
23
24 /**
25  * Constructor.
26  *
27  * @para parent Parent Entity Container.
28  * @para d Common dimension geometrical data.
29  * @para ed Extended geometrical data for radial dimension.
30  */
31 DimRadial::DimRadial(EntityContainer * parent, const DimensionData & d,
32         const DimRadialData & ed): Dimension(parent, d), edata(ed)
33 {
34 }
35
36 /*virtual*/ DimRadial::~DimRadial()
37 {
38 }
39
40 /*virtual*/ Entity * DimRadial::clone()
41 {
42         DimRadial * d = new DimRadial(*this);
43 #warning "!!! Need to deal with setAutoDelete() Qt3->Qt4 !!!"
44 //      d->entities.setAutoDelete(entities.autoDelete());
45         d->initId();
46         d->detach();
47         return d;
48 }
49
50 /**     @return RS2::EntityDimRadial */
51 /*virtual*/ RS2::EntityType DimRadial::rtti() const
52 {
53         return RS2::EntityDimRadial;
54 }
55
56 /**
57  * @return Copy of data that defines the radial dimension.
58  * @see getData()
59  */
60 DimRadialData DimRadial::getEData() const
61 {
62         return edata;
63 }
64
65 /**
66  * @return Automatically created label for the default
67  * measurement of this dimension.
68  */
69 QString DimRadial::getMeasuredLabel()
70 {
71         // Definitive dimension line:
72         double dist = data.definitionPoint.distanceTo(edata.definitionPoint);
73         Drawing * drawing = GetDrawing();
74
75         if (drawing)
76                 return Units::formatLinear(dist, drawing->getUnit(),
77                         drawing->getLinearFormat(), drawing->getLinearPrecision());
78
79         return QString("%1").arg(dist);
80 }
81
82
83 VectorSolutions DimRadial::getRefPoints()
84 {
85         return VectorSolutions(edata.definitionPoint,
86                 data.definitionPoint, data.middleOfText);
87 }
88
89 /**
90  * Updates the sub entities of this dimension. Called when the
91  * dimension or the position, alignment, .. changes.
92  *
93  * @param autoText Automatically reposition the text label
94  */
95 void DimRadial::update(bool autoText)
96 {
97     DEBUG->print("DimRadial::update");
98
99     clear();
100
101     if (isUndone()) {
102         return;
103     }
104
105     // dimension line:
106     //updateCreateDimensionLine(data.definitionPoint, edata.definitionPoint,
107     //false, true);
108
109     Vector p1 = data.definitionPoint;
110     Vector p2 = edata.definitionPoint;
111     double angle = p1.angleTo(p2);
112
113     // text height (DIMTXT)
114     double dimtxt = getTextHeight();
115     // text distance to line (DIMGAP)
116     double dimgap = getDimensionLineGap();
117
118     // length of dimension line:
119     double length = p1.distanceTo(p2);
120
121     TextData textData;
122
123     textData = TextData(Vector(0.0,0.0),
124                            dimtxt, 30.0,
125                            RS2::VAlignMiddle,
126                            RS2::HAlignCenter,
127                            RS2::LeftToRight,
128                            RS2::Exact,
129                            1.0,
130                            getLabel(),
131                            "standard",
132                            0.0);
133
134     Text* text = new Text(this, textData);
135     double textWidth = text->getSize().x;
136
137     // do we have to put the arrow / text outside of the arc?
138     bool outsideArrow = (length<getArrowSize()*2+textWidth);
139     double arrowAngle;
140
141     if (outsideArrow) {
142         length += getArrowSize()*2 + textWidth;
143         arrowAngle = angle+M_PI;
144     } else {
145         arrowAngle = angle;
146     }
147
148     // create arrow:
149     SolidData sd;
150     Solid* arrow;
151
152     arrow = new Solid(this, sd);
153     arrow->shapeArrow(p2,
154                       arrowAngle,
155                       getArrowSize());
156     arrow->setPen(Pen(RS2::FlagInvalid));
157     arrow->setLayer(NULL);
158     addEntity(arrow);
159
160     Vector p3;
161     p3.setPolar(length, angle);
162     p3 += p1;
163
164     // Create dimension line:
165     Line* dimensionLine = new Line(this, LineData(p1, p3));
166     dimensionLine->setPen(Pen(RS2::FlagInvalid));
167     dimensionLine->setLayer(NULL);
168     addEntity(dimensionLine);
169
170     Vector distV;
171     double textAngle;
172
173     // rotate text so it's readable from the bottom or right (ISO)
174     // quadrant 1 & 4
175     if (angle>M_PI/2.0*3.0+0.001 ||
176             angle<M_PI/2.0+0.001) {
177
178         distV.setPolar(dimgap + dimtxt/2.0, angle+M_PI/2.0);
179         textAngle = angle;
180     }
181     // quadrant 2 & 3
182     else {
183         distV.setPolar(dimgap + dimtxt/2.0, angle-M_PI/2.0);
184         textAngle = angle+M_PI;
185     }
186
187     // move text label:
188     Vector textPos;
189
190     if (data.middleOfText.valid && !autoText) {
191         textPos = data.middleOfText;
192     } else {
193         if (outsideArrow) {
194             textPos.setPolar(length-textWidth/2.0-getArrowSize(), angle);
195         } else {
196             textPos.setPolar(length/2.0, angle);
197         }
198         textPos+=p1;
199         // move text away from dimension line:
200         textPos += distV;
201         data.middleOfText = textPos;
202     }
203
204     text->rotate(Vector(0.0,0.0), textAngle);
205     text->move(textPos);
206
207     text->setPen(Pen(RS2::FlagInvalid));
208     text->setLayer(NULL);
209     addEntity(text);
210
211     calculateBorders();
212 }
213
214 Vector DimRadial::getDefinitionPoint()
215 {
216         return edata.definitionPoint;
217 }
218
219 double DimRadial::getLeader()
220 {
221         return edata.leader;
222 }
223
224 void DimRadial::move(Vector offset)
225 {
226     Dimension::move(offset);
227
228     edata.definitionPoint.move(offset);
229     update();
230 }
231
232 void DimRadial::rotate(Vector center, double angle)
233 {
234     Dimension::rotate(center, angle);
235
236     edata.definitionPoint.rotate(center, angle);
237     update();
238 }
239
240
241
242 void DimRadial::scale(Vector center, Vector factor) {
243     Dimension::scale(center, factor);
244
245     edata.definitionPoint.scale(center, factor);
246     edata.leader*=factor.x;
247     update();
248 }
249
250
251
252 void DimRadial::mirror(Vector axisPoint1, Vector axisPoint2) {
253     Dimension::mirror(axisPoint1, axisPoint2);
254
255     edata.definitionPoint.mirror(axisPoint1, axisPoint2);
256     update();
257 }
258
259
260 void DimRadial::moveRef(const Vector& ref, const Vector& offset) {
261
262     if (ref.distanceTo(edata.definitionPoint)<1.0e-4) {
263                 double d = data.definitionPoint.distanceTo(edata.definitionPoint);
264                 double a = data.definitionPoint.angleTo(edata.definitionPoint + offset);
265
266                 Vector v;
267                 v.setPolar(d, a);
268         edata.definitionPoint = data.definitionPoint + v;
269                 update(true);
270     }
271         else if (ref.distanceTo(data.middleOfText)<1.0e-4) {
272         data.middleOfText.move(offset);
273                 update(false);
274     }
275 }
276
277 /**
278  * Dumps the point's data to stdout.
279  */
280 std::ostream& operator << (std::ostream& os, const DimRadial& d) {
281     os << " DimRadial: " << d.getData() << "\n" << d.getEData() << "\n";
282     return os;
283 }
284
285