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