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
10 // JLH = James L. Hammons <jlhamm@acm.org>
13 // --- ---------- -----------------------------------------------------------
14 // JLH 06/02/2010 Added this text. :-)
17 #include "rs_selection.h"
19 #include "rs_information.h"
20 #include "rs_polyline.h"
21 #include "rs_entity.h"
25 * Default constructor.
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, ...
31 RS_Selection::RS_Selection(RS_EntityContainer & container, GraphicView * graphicView)
33 this->container = &container;
34 this->graphicView = graphicView;
35 graphic = container.getGraphic();
39 * Selects or deselects the given entitiy.
41 void RS_Selection::selectSingle(RS_Entity * e)
43 if (e != NULL && (e->getLayer() == NULL || e->getLayer()->isLocked() == false))
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);
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();
61 * Selects all entities on visible layers.
63 void RS_Selection::selectAll(bool select)
65 if (graphicView != NULL)
67 //graphicView->deleteEntity(container);
70 //container->setSelected(select);
71 for(RS_Entity * e=container->firstEntity(); e!=NULL; e=container->nextEntity())
73 //for (uint i=0; i<container->count(); ++i) {
74 //RS_Entity* e = container->entityAt(i);
76 if (e != NULL && e->isVisible())
77 e->setSelected(select);
80 if (graphicView!=NULL)
81 //graphicView->drawEntity(container);
82 graphicView->redraw();
85 void RS_Selection::deselectAll()
91 * Selects all entities on visible layers.
93 void RS_Selection::invertSelection()
95 if (graphicView != NULL)
97 //graphicView->deleteEntity(container);
100 for(RS_Entity * e=container->firstEntity(); e!=NULL; e=container->nextEntity())
102 //for (uint i=0; i<container->count(); ++i) {
103 //RS_Entity* e = container->entityAt(i);
105 if (e != NULL && e->isVisible())
109 if (graphicView != NULL)
110 //graphicView->drawEntity(container);
111 graphicView->redraw();
115 * Selects all entities that are completely in the given window.
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
121 void RS_Selection::selectWindow(const Vector & v1, const Vector & v2, bool select, bool cross)
123 //if (graphicView!=NULL) {
124 // graphicView->drawWindow(v1, v2, true);
127 container->selectWindow(v1, v2, select, cross);
129 if (graphicView != NULL)
130 //graphicView->drawWindow(v1, v2);
131 graphicView->redraw();
134 void RS_Selection::deselectWindow(const Vector & v1, const Vector & v2)
136 selectWindow(v1, v2, false);
140 * Selects all entities that are intersected by the given line.
142 * @param v1 Startpoint of line.
143 * @param v2 Endpoint of line.
144 * @param select true: select, false: deselect
146 void RS_Selection::selectIntersected(const Vector & v1, const Vector & v2, bool select)
148 RS_Line line(NULL, RS_LineData(v1, v2));
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);
156 if (e!=NULL && e->isVisible()) {
160 // select containers / groups:
161 if (e->isContainer()) {
162 RS_EntityContainer* ec = (RS_EntityContainer*)e;
164 for (RS_Entity* e2=ec->firstEntity(RS2::ResolveAll); e2!=NULL;
165 e2=ec->nextEntity(RS2::ResolveAll)) {
167 VectorSolutions sol =
168 RS_Information::getIntersection(&line, e2, true);
170 if (sol.hasValid()) {
176 VectorSolutions sol =
177 RS_Information::getIntersection(&line, e, true);
179 if (sol.hasValid()) {
185 if (graphicView!=NULL) {
186 graphicView->deleteEntity(e);
189 e->setSelected(select);
191 if (graphicView!=NULL) {
192 graphicView->drawEntity(e);
199 void RS_Selection::deselectIntersected(const Vector & v1, const Vector & v2)
201 selectIntersected(v1, v2, false);
205 * Selects all entities that are connected to the given entity.
207 * @param e The entity where the algorithm starts. Must be an atomic entity.
209 void RS_Selection::selectContour(RS_Entity * e)
211 if (e == NULL || !e->isAtomic())
214 bool select = !e->isSelected();
215 RS_AtomicEntity* ae = (RS_AtomicEntity*)e;
216 Vector p1 = ae->getStartpoint();
217 Vector p2 = ae->getEndpoint();
220 // (de)select 1st entity:
221 if (graphicView!=NULL) {
222 graphicView->deleteEntity(e);
224 e->setSelected(select);
225 if (graphicView!=NULL) {
226 graphicView->drawEntity(e);
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);
237 if (en!=NULL && en->isVisible() &&
238 en->isAtomic() && en->isSelected()!=select &&
239 (en->getLayer()==NULL || en->getLayer()->isLocked()==false)) {
241 ae = (RS_AtomicEntity*)en;
244 // startpoint connects to 1st point
245 if (ae->getStartpoint().distanceTo(p1)<1.0e-4) {
247 p1 = ae->getEndpoint();
250 // endpoint connects to 1st point
251 else if (ae->getEndpoint().distanceTo(p1)<1.0e-4) {
253 p1 = ae->getStartpoint();
256 // startpoint connects to 2nd point
257 else if (ae->getStartpoint().distanceTo(p2)<1.0e-4) {
259 p2 = ae->getEndpoint();
262 // endpoint connects to 1st point
263 else if (ae->getEndpoint().distanceTo(p2)<1.0e-4) {
265 p2 = ae->getStartpoint();
269 if (graphicView!=NULL) {
270 graphicView->deleteEntity(ae);
272 ae->setSelected(select);
273 if (graphicView!=NULL) {
274 graphicView->drawEntity(ae);
284 * Selects all entities on the given layer.
286 void RS_Selection::selectLayer(RS_Entity * e)
291 bool select = !e->isSelected();
293 RS_Layer * layer = e->getLayer(true);
298 QString layerName = layer->getName();
299 selectLayer(layerName, select);
303 * Selects all entities on the given layer.
305 void RS_Selection::selectLayer(const QString & layerName, bool select)
307 for(RS_Entity * en=container->firstEntity(); en!=NULL; en=container->nextEntity())
309 if (en != NULL && en->isVisible() && en->isSelected() != select
310 && (en->getLayer() == NULL || en->getLayer()->isLocked() == false))
312 RS_Layer * l = en->getLayer(true);
314 if (l != NULL && l->getName() == layerName)
316 if (graphicView != NULL)
317 graphicView->deleteEntity(en);
319 en->setSelected(select);
321 if (graphicView != NULL)
322 graphicView->drawEntity(en);
328 void RS_Selection::deselectLayer(QString & layerName)
330 selectLayer(layerName, false);