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