]> Shamusworld >> Repos - architektonas/blob - src/base/preview.cpp
Bugfixes related to removing Snapper class.
[architektonas] / src / base / preview.cpp
1 // preview.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/21/2010  Added this text. :-)
15 //
16
17 #include "preview.h"
18
19 #include "entitycontainer.h"
20 #include "graphicview.h"
21 #include "information.h"
22 #include "paintinterface.h"
23 #include "settings.h"
24
25 /**
26  * Constructor.
27  */
28 Preview::Preview(EntityContainer * parent): EntityContainer(parent),
29         visible(false)
30 {
31         settings.beginGroup("Appearance");
32         maxEntities = settings.value("MaxPreview", 100).toInt();
33         settings.endGroup();
34 }
35
36 /**
37  * Destructor.
38  */
39 Preview::~Preview()
40 {
41 }
42
43 /**
44  * Adds an entity to this preview and removes any attributes / layer
45  * connectsions before that.
46  */
47 void Preview::addEntity(Entity * entity)
48 {
49         if (entity == NULL || entity->isUndone())
50                 return;
51
52         // Only border preview for complex entities:
53         bool addBorder = false;
54
55         if (entity->rtti() == RS2::EntityImage || entity->rtti() == RS2::EntityHatch
56                 || entity->rtti() == RS2::EntityInsert)
57         {
58                 addBorder = true;
59         }
60         else if (entity->isContainer() && entity->rtti() != RS2::EntitySpline)
61         {
62                 if (entity->countDeep() > maxEntities - countDeep())
63                         addBorder = true;
64         }
65
66         if (addBorder)
67         {
68                 Vector min = entity->getMin();
69                 Vector max = entity->getMax();
70
71                 Line * l1 = new Line(this, LineData(Vector(min.x, min.y), Vector(max.x, min.y)));
72                 Line * l2 = new Line(this, LineData(Vector(max.x, min.y), Vector(max.x, max.y)));
73                 Line * l3 = new Line(this, LineData(Vector(max.x, max.y), Vector(min.x, max.y)));
74                 Line * l4 = new Line(this, LineData(Vector(min.x, max.y), Vector(min.x, min.y)));
75
76                 EntityContainer::addEntity(l1);
77                 EntityContainer::addEntity(l2);
78                 EntityContainer::addEntity(l3);
79                 EntityContainer::addEntity(l4);
80
81                 delete entity;
82                 entity = NULL;
83         }
84         else
85         {
86                 entity->setLayer(NULL);
87                 entity->setSelected(false);
88                 entity->reparent(this);
89                 entity->setPen(Pen(Color(255, 255, 255), RS2::Width00, RS2::SolidLine));
90                 EntityContainer::addEntity(entity);
91         }
92 }
93
94 /**
95  * Clones the given entity and adds the clone to the preview.
96  */
97 void Preview::addCloneOf(Entity * entity)
98 {
99         if (!entity)
100                 return;
101
102         Entity * clone = entity->clone();
103         addEntity(clone);
104 }
105
106 /**
107  * Adds all entities from 'container' to the preview (unselected).
108  */
109 void Preview::addAllFrom(EntityContainer & container)
110 {
111         int c = 0;
112
113         for(Entity * e=container.firstEntity(); e!=NULL; e=container.nextEntity())
114         {
115                 if (c < maxEntities)
116                 {
117                         Entity * clone = e->clone();
118                         clone->setSelected(false);
119                         clone->reparent(this);
120
121                         c += clone->countDeep();
122                         addEntity(clone);
123                         // clone might be NULL after this point
124                 }
125         }
126 }
127
128 /**
129  * Adds all selected entities from 'container' to the preview (unselected).
130  */
131 void Preview::addSelectionFrom(EntityContainer & container)
132 {
133         int c = 0;
134
135         for(Entity * e=container.firstEntity(); e!=NULL; e=container.nextEntity())
136         {
137                 if (e->isSelected() && c < maxEntities)
138                 {
139                         Entity * clone = e->clone();
140                         clone->setSelected(false);
141                         clone->reparent(this);
142
143                         c += clone->countDeep();
144                         addEntity(clone);
145                         // clone might be NULL after this point
146                 }
147         }
148 }
149
150 /**
151  * Adds all entities in the given range and those which have endpoints in the
152  * given range to the preview.
153  */
154 void Preview::addStretchablesFrom(EntityContainer & container, const Vector & v1,
155         const Vector & v2)
156 {
157         int c = 0;
158
159         for(Entity * e=container.firstEntity(); e!=NULL; e=container.nextEntity())
160         {
161                 if (e->isVisible() && e->rtti() != RS2::EntityHatch && (e->isInWindow(v1, v2)
162                         || e->hasEndpointsWithinWindow(v1, v2)) && c < maxEntities)
163                 {
164                         Entity * clone = e->clone();
165                         //clone->setSelected(false);
166                         clone->reparent(this);
167
168                         c += clone->countDeep();
169                         addEntity(clone);
170                         // clone might be NULL after this point
171                 }
172         }
173 }
174
175 void Preview::SetOffset(Vector v)
176 {
177         offset = v;
178 }
179
180 Vector Preview::Offset(void)
181 {
182         return offset;
183 }
184
185 void Preview::SetVisible(bool visibility/*= true*/)
186 {
187         visible = visibility;
188 }
189
190 bool Preview::Visible(void)
191 {
192         return visible;
193 }
194
195 void Preview::Draw(GraphicView * view, PaintInterface * painter)
196 {
197         if (isEmpty())
198                 return;
199
200         painter->setPen(Pen(Color(60, 255, 80), RS2::Width00, RS2::SolidLine));
201         painter->setOffset(offset);
202
203         // We have to traverse the container ourselves, because RS_Container::draw()
204         // uses drawEntity() instead of drawEntityPlain()...
205         for(Entity * e=firstEntity(RS2::ResolveNone); e!=NULL; e=nextEntity(RS2::ResolveNone))
206                 view->drawEntityPlain(e);
207
208         painter->setOffset(Vector(0, 0));
209 }