]> Shamusworld >> Repos - architektonas/blob - src/base/rs_leader.cpp
Changed RS_Graphic to Drawing; this is less confusing as a drawing is
[architektonas] / src / base / rs_leader.cpp
1 // rs_leader.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  06/01/2010  Added this text. :-)
13 //
14
15 #include "rs_leader.h"
16
17 #include "rs_debug.h"
18 #include "rs_line.h"
19 #include "rs_solid.h"
20
21 /**
22  * Constructor.
23  */
24 RS_Leader::RS_Leader(RS_EntityContainer * parent): RS_EntityContainer(parent)
25 {
26     empty = true;
27 }
28
29 /**
30  * Constructor.
31  * @param d Leader data
32  */
33 RS_Leader::RS_Leader(RS_EntityContainer * parent, const RS_LeaderData & d):
34         RS_EntityContainer(parent), data(d)
35 {
36     empty = true;
37 }
38
39 /**
40  * Destructor
41  */
42 RS_Leader::~RS_Leader()
43 {
44 }
45
46 /*virtual*/ RS_Entity * RS_Leader::clone()
47 {
48         RS_Leader * p = new RS_Leader(*this);
49 #warning "!!! Need to deal with setAutoDelete() Qt3->Qt4 !!!"
50 //      p->entities.setAutoDelete(entities.autoDelete());
51         p->initId();
52         p->detach();
53         return p;
54 }
55
56 /**     @return RS2::EntityDimLeader */
57 /*virtual*/ RS2::EntityType RS_Leader::rtti() const
58 {
59         return RS2::EntityDimLeader;
60 }
61
62 /**
63  * Implementation of update. Updates the arrow.
64  */
65 void RS_Leader::update()
66 {
67         // find and delete arrow:
68         for(RS_Entity * e=firstEntity(); e!=NULL; e=nextEntity())
69         {
70                 if (e->rtti() == RS2::EntitySolid)
71                 {
72                         removeEntity(e);
73                         break;
74                 }
75         }
76
77         if (isUndone())
78         {
79                 setVisible(false);
80                 return;
81         }
82
83         RS_Entity * fe = firstEntity();
84
85         if (fe != NULL && fe->isAtomic())
86         {
87                 Vector p1 = ((RS_AtomicEntity *)fe)->getStartpoint();
88                 Vector p2 = ((RS_AtomicEntity *)fe)->getEndpoint();
89
90                 // first entity must be the line which gets the arrow:
91                 if (hasArrowHead())
92                 {
93                         RS_Solid * s = new RS_Solid(this, RS_SolidData());
94                         s->shapeArrow(p1, p2.angleTo(p1), getGraphicVariableDouble("$DIMASZ", 2.5));
95                         s->setPen(RS_Pen(RS2::FlagInvalid));
96                         s->setLayer(NULL);
97                         RS_EntityContainer::addEntity(s);
98                 }
99         }
100 }
101
102 /** @return Copy of data that defines the leader. */
103 RS_LeaderData RS_Leader::getData() const
104 {
105         return data;
106 }
107
108 /** @return true: if this leader has an arrow at the beginning. */
109 bool RS_Leader::hasArrowHead()
110 {
111         return data.arrowHead;
112 }
113
114 /**
115  * Adds a vertex from the endpoint of the last element or
116  * sets the startpoint to the point 'v'.
117  *
118  * The very first vertex added is the starting point.
119  *
120  * @param v vertex coordinate
121  *
122  * @return Pointer to the entity that was addded or NULL if this
123  *         was the first vertex added.
124  */
125 RS_Entity * RS_Leader::addVertex(const Vector & v)
126 {
127         RS_Entity * entity = NULL;
128         static Vector last = Vector(false);
129
130         if (empty)
131         {
132                 last = v;
133                 empty = false;
134         }
135         else
136         {
137                 // add line to the leader:
138                 entity = new RS_Line(this, RS_LineData(last, v));
139                 entity->setPen(RS_Pen(RS2::FlagInvalid));
140                 entity->setLayer(NULL);
141                 RS_EntityContainer::addEntity(entity);
142
143                 if (count() == 1 && hasArrowHead())
144                         update();
145
146                 last = v;
147         }
148
149         return entity;
150 }
151
152 /**
153  * Reimplementation of the addEntity method for a normal container.
154  * This reimplementation deletes the given entity!
155  *
156  * To add entities use addVertex() instead.
157  */
158 void RS_Leader::addEntity(RS_Entity * entity)
159 {
160         RS_DEBUG->print(RS_Debug::D_WARNING, "RS_Leader::addEntity: should never be called");
161
162         if (entity == NULL)
163                 return;
164
165         delete entity;
166 }
167
168 /*virtual*/ double RS_Leader::getLength()
169 {
170         return -1.0;
171 }
172
173 void RS_Leader::move(Vector offset)
174 {
175         RS_EntityContainer::move(offset);
176         update();
177 }
178
179 void RS_Leader::rotate(Vector center, double angle)
180 {
181         RS_EntityContainer::rotate(center, angle);
182         update();
183 }
184
185 void RS_Leader::scale(Vector center, Vector factor)
186 {
187         RS_EntityContainer::scale(center, factor);
188         update();
189 }
190
191 void RS_Leader::mirror(Vector axisPoint1, Vector axisPoint2)
192 {
193         RS_EntityContainer::mirror(axisPoint1, axisPoint2);
194         update();
195 }
196
197 void RS_Leader::stretch(Vector firstCorner, Vector secondCorner, Vector offset)
198 {
199         RS_EntityContainer::stretch(firstCorner, secondCorner, offset);
200         update();
201 }
202
203 /**
204  * Dumps the leader's data to stdout.
205  */
206 std::ostream & operator<<(std::ostream & os, const RS_Leader & l)
207 {
208         os << " Leader: " << l.getData() << " {\n";
209         os << (RS_EntityContainer &)l;
210         os << "\n}\n";
211
212         return os;
213 }