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
8 // JLH = James L. Hammons <jlhamm@acm.org>
11 // --- ---------- -----------------------------------------------------------
12 // JLH 06/02/2010 Added this text. :-)
15 #include "rs_selection.h"
17 #include "rs_information.h"
18 #include "rs_polyline.h"
19 #include "rs_entity.h"
23 * Default constructor.
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, ...
29 RS_Selection::RS_Selection(RS_EntityContainer & container, GraphicView * graphicView)
31 this->container = &container;
32 this->graphicView = graphicView;
33 graphic = container.getGraphic();
37 * Selects or deselects the given entitiy.
39 void RS_Selection::selectSingle(RS_Entity * e)
41 if (e != NULL && (e->getLayer() == NULL || e->getLayer()->isLocked() == false))
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);
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();
59 * Selects all entities on visible layers.
61 void RS_Selection::selectAll(bool select)
63 if (graphicView != NULL)
65 //graphicView->deleteEntity(container);
68 //container->setSelected(select);
69 for(RS_Entity * e=container->firstEntity(); e!=NULL; e=container->nextEntity())
71 //for (uint i=0; i<container->count(); ++i) {
72 //RS_Entity* e = container->entityAt(i);
74 if (e != NULL && e->isVisible())
75 e->setSelected(select);
78 if (graphicView!=NULL)
79 //graphicView->drawEntity(container);
80 graphicView->redraw();
83 void RS_Selection::deselectAll()
89 * Selects all entities on visible layers.
91 void RS_Selection::invertSelection()
93 if (graphicView != NULL)
95 //graphicView->deleteEntity(container);
98 for(RS_Entity * e=container->firstEntity(); e!=NULL; e=container->nextEntity())
100 //for (uint i=0; i<container->count(); ++i) {
101 //RS_Entity* e = container->entityAt(i);
103 if (e != NULL && e->isVisible())
107 if (graphicView != NULL)
108 //graphicView->drawEntity(container);
109 graphicView->redraw();
113 * Selects all entities that are completely in the given window.
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
119 void RS_Selection::selectWindow(const Vector & v1, const Vector & v2, bool select, bool cross)
121 //if (graphicView!=NULL) {
122 // graphicView->drawWindow(v1, v2, true);
125 container->selectWindow(v1, v2, select, cross);
127 if (graphicView != NULL)
128 //graphicView->drawWindow(v1, v2);
129 graphicView->redraw();
132 void RS_Selection::deselectWindow(const Vector & v1, const Vector & v2)
134 selectWindow(v1, v2, false);
138 * Selects all entities that are intersected by the given line.
140 * @param v1 Startpoint of line.
141 * @param v2 Endpoint of line.
142 * @param select true: select, false: deselect
144 void RS_Selection::selectIntersected(const Vector & v1, const Vector & v2, bool select)
146 RS_Line line(NULL, RS_LineData(v1, v2));
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);
154 if (e!=NULL && e->isVisible()) {
158 // select containers / groups:
159 if (e->isContainer()) {
160 RS_EntityContainer* ec = (RS_EntityContainer*)e;
162 for (RS_Entity* e2=ec->firstEntity(RS2::ResolveAll); e2!=NULL;
163 e2=ec->nextEntity(RS2::ResolveAll)) {
165 VectorSolutions sol =
166 RS_Information::getIntersection(&line, e2, true);
168 if (sol.hasValid()) {
174 VectorSolutions sol =
175 RS_Information::getIntersection(&line, e, true);
177 if (sol.hasValid()) {
183 if (graphicView!=NULL) {
184 graphicView->deleteEntity(e);
187 e->setSelected(select);
189 if (graphicView!=NULL) {
190 graphicView->drawEntity(e);
197 void RS_Selection::deselectIntersected(const Vector & v1, const Vector & v2)
199 selectIntersected(v1, v2, false);
203 * Selects all entities that are connected to the given entity.
205 * @param e The entity where the algorithm starts. Must be an atomic entity.
207 void RS_Selection::selectContour(RS_Entity * e)
209 if (e == NULL || !e->isAtomic())
212 bool select = !e->isSelected();
213 RS_AtomicEntity* ae = (RS_AtomicEntity*)e;
214 Vector p1 = ae->getStartpoint();
215 Vector p2 = ae->getEndpoint();
218 // (de)select 1st entity:
219 if (graphicView!=NULL) {
220 graphicView->deleteEntity(e);
222 e->setSelected(select);
223 if (graphicView!=NULL) {
224 graphicView->drawEntity(e);
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);
235 if (en!=NULL && en->isVisible() &&
236 en->isAtomic() && en->isSelected()!=select &&
237 (en->getLayer()==NULL || en->getLayer()->isLocked()==false)) {
239 ae = (RS_AtomicEntity*)en;
242 // startpoint connects to 1st point
243 if (ae->getStartpoint().distanceTo(p1)<1.0e-4) {
245 p1 = ae->getEndpoint();
248 // endpoint connects to 1st point
249 else if (ae->getEndpoint().distanceTo(p1)<1.0e-4) {
251 p1 = ae->getStartpoint();
254 // startpoint connects to 2nd point
255 else if (ae->getStartpoint().distanceTo(p2)<1.0e-4) {
257 p2 = ae->getEndpoint();
260 // endpoint connects to 1st point
261 else if (ae->getEndpoint().distanceTo(p2)<1.0e-4) {
263 p2 = ae->getStartpoint();
267 if (graphicView!=NULL) {
268 graphicView->deleteEntity(ae);
270 ae->setSelected(select);
271 if (graphicView!=NULL) {
272 graphicView->drawEntity(ae);
282 * Selects all entities on the given layer.
284 void RS_Selection::selectLayer(RS_Entity * e)
289 bool select = !e->isSelected();
291 RS_Layer * layer = e->getLayer(true);
296 QString layerName = layer->getName();
297 selectLayer(layerName, select);
301 * Selects all entities on the given layer.
303 void RS_Selection::selectLayer(const QString & layerName, bool select)
305 for(RS_Entity * en=container->firstEntity(); en!=NULL; en=container->nextEntity())
307 if (en != NULL && en->isVisible() && en->isSelected() != select
308 && (en->getLayer() == NULL || en->getLayer()->isLocked() == false))
310 RS_Layer * l = en->getLayer(true);
312 if (l != NULL && l->getName() == layerName)
314 if (graphicView != NULL)
315 graphicView->deleteEntity(en);
317 en->setSelected(select);
319 if (graphicView != NULL)
320 graphicView->drawEntity(en);
326 void RS_Selection::deselectLayer(QString & layerName)
328 selectLayer(layerName, false);