]> Shamusworld >> Repos - architektonas/blob - src/base/rs_selection.cpp
Changed RS_Graphic to Drawing; this is less confusing as a drawing is
[architektonas] / src / base / rs_selection.cpp
1 // rs_selection.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/02/2010  Added this text. :-)
13 //
14
15 #include "rs_selection.h"
16
17 #include "rs_information.h"
18 #include "rs_polyline.h"
19 #include "rs_entity.h"
20 #include "drawing.h"
21
22 /**
23  * Default constructor.
24  *
25  * @param container The container to which we will add
26  *        entities. Usually that's an Drawing entity but
27  *        it can also be a polyline, text, ...
28  */
29 RS_Selection::RS_Selection(RS_EntityContainer & container, RS_GraphicView * graphicView)
30 {
31         this->container = &container;
32         this->graphicView = graphicView;
33         graphic = container.getGraphic();
34 }
35
36 /**
37  * Selects or deselects the given entitiy.
38  */
39 void RS_Selection::selectSingle(RS_Entity * e)
40 {
41         if (e != NULL && (e->getLayer() == NULL || e->getLayer()->isLocked() == false))
42         {
43 // Same problem as below...
44 //[WAS]#warning "!!! This is causing a segfault in the draw code !!!"
45 //              if (graphicView != NULL)
46 //                      graphicView->deleteEntity(e);
47
48                 e->toggleSelected();
49
50 //Most likely because while the painter is valid, the QPainter is not...
51 //[WAS]#warning "!!! This is causing a segfault in the draw code !!!"
52                 if (graphicView != NULL)
53 //                      graphicView->drawEntity(e);
54                         graphicView->redraw();
55         }
56 }
57
58 /**
59  * Selects all entities on visible layers.
60  */
61 void RS_Selection::selectAll(bool select)
62 {
63         if (graphicView != NULL)
64         {
65                 //graphicView->deleteEntity(container);
66         }
67
68         //container->setSelected(select);
69         for(RS_Entity * e=container->firstEntity(); e!=NULL; e=container->nextEntity())
70         {
71         //for (uint i=0; i<container->count(); ++i) {
72                 //RS_Entity* e = container->entityAt(i);
73
74                 if (e != NULL && e->isVisible())
75                         e->setSelected(select);
76         }
77
78         if (graphicView!=NULL)
79                 //graphicView->drawEntity(container);
80                 graphicView->redraw();
81 }
82
83 void RS_Selection::deselectAll()
84 {
85         selectAll(false);
86 }
87
88 /**
89  * Selects all entities on visible layers.
90  */
91 void RS_Selection::invertSelection()
92 {
93         if (graphicView != NULL)
94         {
95                 //graphicView->deleteEntity(container);
96         }
97
98         for(RS_Entity * e=container->firstEntity(); e!=NULL; e=container->nextEntity())
99         {
100         //for (uint i=0; i<container->count(); ++i) {
101                 //RS_Entity* e = container->entityAt(i);
102
103                 if (e != NULL && e->isVisible())
104                         e->toggleSelected();
105         }
106
107         if (graphicView != NULL)
108                 //graphicView->drawEntity(container);
109                 graphicView->redraw();
110 }
111
112 /**
113  * Selects all entities that are completely in the given window.
114  *
115  * @param v1 First corner of the window to select.
116  * @param v2 Second corner of the window to select.
117  * @param select true: select, false: deselect
118  */
119 void RS_Selection::selectWindow(const Vector & v1, const Vector & v2, bool select, bool cross)
120 {
121         //if (graphicView!=NULL) {
122         //    graphicView->drawWindow(v1, v2, true);
123         //}
124
125         container->selectWindow(v1, v2, select, cross);
126
127         if (graphicView != NULL)
128                 //graphicView->drawWindow(v1, v2);
129                 graphicView->redraw();
130 }
131
132 void RS_Selection::deselectWindow(const Vector & v1, const Vector & v2)
133 {
134         selectWindow(v1, v2, false);
135 }
136
137 /**
138  * Selects all entities that are intersected by the given line.
139  *
140  * @param v1 Startpoint of line.
141  * @param v2 Endpoint of line.
142  * @param select true: select, false: deselect
143  */
144 void RS_Selection::selectIntersected(const Vector & v1, const Vector & v2, bool select)
145 {
146         RS_Line line(NULL, RS_LineData(v1, v2));
147         bool inters;
148
149         for (RS_Entity* e=container->firstEntity(); e!=NULL;
150                         e=container->nextEntity()) {
151         //for (uint i=0; i<container->count(); ++i) {
152                 //RS_Entity* e = container->entityAt(i);
153
154                 if (e!=NULL && e->isVisible()) {
155
156                         inters = false;
157
158                         // select containers / groups:
159                         if (e->isContainer()) {
160                                 RS_EntityContainer* ec = (RS_EntityContainer*)e;
161
162                                 for (RS_Entity* e2=ec->firstEntity(RS2::ResolveAll); e2!=NULL;
163                                                 e2=ec->nextEntity(RS2::ResolveAll)) {
164
165                                         VectorSolutions sol =
166                                                 RS_Information::getIntersection(&line, e2, true);
167
168                                         if (sol.hasValid()) {
169                                                 inters = true;
170                                         }
171                                 }
172                         } else {
173
174                                 VectorSolutions sol =
175                                         RS_Information::getIntersection(&line, e, true);
176
177                                 if (sol.hasValid()) {
178                                         inters = true;
179                                 }
180                         }
181
182                         if (inters) {
183                                 if (graphicView!=NULL) {
184                                         graphicView->deleteEntity(e);
185                                 }
186
187                                 e->setSelected(select);
188
189                                 if (graphicView!=NULL) {
190                                         graphicView->drawEntity(e);
191                                 }
192                         }
193                 }
194         }
195 }
196
197 void RS_Selection::deselectIntersected(const Vector & v1, const Vector & v2)
198 {
199         selectIntersected(v1, v2, false);
200 }
201
202 /**
203  * Selects all entities that are connected to the given entity.
204  *
205  * @param e The entity where the algorithm starts. Must be an atomic entity.
206  */
207 void RS_Selection::selectContour(RS_Entity * e)
208 {
209         if (e == NULL || !e->isAtomic())
210                 return;
211
212         bool select = !e->isSelected();
213         RS_AtomicEntity* ae = (RS_AtomicEntity*)e;
214         Vector p1 = ae->getStartpoint();
215         Vector p2 = ae->getEndpoint();
216         bool found = false;
217
218         // (de)select 1st entity:
219         if (graphicView!=NULL) {
220                 graphicView->deleteEntity(e);
221         }
222         e->setSelected(select);
223         if (graphicView!=NULL) {
224                 graphicView->drawEntity(e);
225         }
226
227         do {
228                 found = false;
229
230                 for (RS_Entity* en=container->firstEntity(); en!=NULL;
231                                 en=container->nextEntity()) {
232                 //for (uint i=0; i<container->count(); ++i) {
233                         //RS_Entity* en = container->entityAt(i);
234
235                         if (en!=NULL && en->isVisible() &&
236                                 en->isAtomic() && en->isSelected()!=select &&
237                                 (en->getLayer()==NULL || en->getLayer()->isLocked()==false)) {
238
239                                 ae = (RS_AtomicEntity*)en;
240                                 bool doit = false;
241
242                                 // startpoint connects to 1st point
243                                 if (ae->getStartpoint().distanceTo(p1)<1.0e-4) {
244                                         doit = true;
245                                         p1 = ae->getEndpoint();
246                                 }
247
248                                 // endpoint connects to 1st point
249                                 else if (ae->getEndpoint().distanceTo(p1)<1.0e-4) {
250                                         doit = true;
251                                         p1 = ae->getStartpoint();
252                                 }
253
254                                 // startpoint connects to 2nd point
255                                 else if (ae->getStartpoint().distanceTo(p2)<1.0e-4) {
256                                         doit = true;
257                                         p2 = ae->getEndpoint();
258                                 }
259
260                                 // endpoint connects to 1st point
261                                 else if (ae->getEndpoint().distanceTo(p2)<1.0e-4) {
262                                         doit = true;
263                                         p2 = ae->getStartpoint();
264                                 }
265
266                                 if (doit) {
267                                         if (graphicView!=NULL) {
268                                                 graphicView->deleteEntity(ae);
269                                         }
270                                         ae->setSelected(select);
271                                         if (graphicView!=NULL) {
272                                                 graphicView->drawEntity(ae);
273                                         }
274                                         found = true;
275                                 }
276                         }
277                 }
278         } while(found);
279 }
280
281 /**
282  * Selects all entities on the given layer.
283  */
284 void RS_Selection::selectLayer(RS_Entity * e)
285 {
286         if (e == NULL)
287                 return;
288
289         bool select = !e->isSelected();
290
291         RS_Layer * layer = e->getLayer(true);
292
293         if (layer == NULL)
294                 return;
295
296         QString layerName = layer->getName();
297         selectLayer(layerName, select);
298 }
299
300 /**
301  * Selects all entities on the given layer.
302  */
303 void RS_Selection::selectLayer(const QString & layerName, bool select)
304 {
305         for(RS_Entity * en=container->firstEntity(); en!=NULL; en=container->nextEntity())
306         {
307                 if (en != NULL && en->isVisible() && en->isSelected() != select
308                         && (en->getLayer() == NULL || en->getLayer()->isLocked() == false))
309                 {
310                         RS_Layer * l = en->getLayer(true);
311
312                         if (l != NULL && l->getName() == layerName)
313                         {
314                                 if (graphicView != NULL)
315                                         graphicView->deleteEntity(en);
316
317                                 en->setSelected(select);
318
319                                 if (graphicView != NULL)
320                                         graphicView->drawEntity(en);
321                         }
322                 }
323         }
324 }
325
326 void RS_Selection::deselectLayer(QString & layerName)
327 {
328         selectLayer(layerName, false);
329 }