1 /****************************************************************************
2 ** $Id: rs_selection.cpp 1888 2004-06-12 23:34:44Z andrew $
4 ** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
6 ** This file is part of the qcadlib Library project.
8 ** This file may be distributed and/or modified under the terms of the
9 ** GNU General Public License version 2 as published by the Free Software
10 ** Foundation and appearing in the file LICENSE.GPL included in the
11 ** packaging of this file.
13 ** Licensees holding valid qcadlib Professional Edition licenses may use
14 ** this file in accordance with the qcadlib Commercial License
15 ** Agreement provided with the Software.
17 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
18 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20 ** See http://www.ribbonsoft.com for further details.
22 ** Contact info@ribbonsoft.com if any conditions of this licensing are
25 **********************************************************************/
27 #include "rs_selection.h"
29 #include "rs_information.h"
30 #include "rs_polyline.h"
31 #include "rs_entity.h"
32 #include "rs_graphic.h"
37 * Default constructor.
39 * @param container The container to which we will add
40 * entities. Usually that's an RS_Graphic entity but
41 * it can also be a polyline, text, ...
43 RS_Selection::RS_Selection(RS_EntityContainer& container,
44 RS_GraphicView* graphicView) {
45 this->container = &container;
46 this->graphicView = graphicView;
47 graphic = container.getGraphic();
53 * Selects or deselects the given entitiy.
55 void RS_Selection::selectSingle(RS_Entity* e) {
56 if (e!=NULL && (e->getLayer()==NULL || e->getLayer()->isLocked()==false)) {
58 if (graphicView!=NULL) {
59 graphicView->deleteEntity(e);
64 if (graphicView!=NULL) {
65 graphicView->drawEntity(e);
73 * Selects all entities on visible layers.
75 void RS_Selection::selectAll(bool select) {
76 if (graphicView!=NULL) {
77 //graphicView->deleteEntity(container);
80 //container->setSelected(select);
81 for (RS_Entity* e=container->firstEntity();
83 e=container->nextEntity()) {
84 //for (uint i=0; i<container->count(); ++i) {
85 //RS_Entity* e = container->entityAt(i);
87 if (e!=NULL && e->isVisible()) {
88 e->setSelected(select);
92 if (graphicView!=NULL) {
93 //graphicView->drawEntity(container);
94 graphicView->redraw();
101 * Selects all entities on visible layers.
103 void RS_Selection::invertSelection() {
104 if (graphicView!=NULL) {
105 //graphicView->deleteEntity(container);
108 for (RS_Entity* e=container->firstEntity(); e!=NULL;
109 e=container->nextEntity()) {
110 //for (uint i=0; i<container->count(); ++i) {
111 //RS_Entity* e = container->entityAt(i);
113 if (e!=NULL && e->isVisible()) {
118 if (graphicView!=NULL) {
119 //graphicView->drawEntity(container);
120 graphicView->redraw();
127 * Selects all entities that are completely in the given window.
129 * @param v1 First corner of the window to select.
130 * @param v2 Second corner of the window to select.
131 * @param select true: select, false: deselect
133 void RS_Selection::selectWindow(const Vector& v1, const Vector& v2,
134 bool select, bool cross) {
136 //if (graphicView!=NULL) {
137 // graphicView->drawWindow(v1, v2, true);
140 container->selectWindow(v1, v2, select, cross);
142 if (graphicView!=NULL) {
143 //graphicView->drawWindow(v1, v2);
144 graphicView->redraw();
151 * Selects all entities that are intersected by the given line.
153 * @param v1 Startpoint of line.
154 * @param v2 Endpoint of line.
155 * @param select true: select, false: deselect
157 void RS_Selection::selectIntersected(const Vector& v1, const Vector& v2,
160 RS_Line line(NULL, RS_LineData(v1, v2));
163 for (RS_Entity* e=container->firstEntity(); e!=NULL;
164 e=container->nextEntity()) {
165 //for (uint i=0; i<container->count(); ++i) {
166 //RS_Entity* e = container->entityAt(i);
168 if (e!=NULL && e->isVisible()) {
172 // select containers / groups:
173 if (e->isContainer()) {
174 RS_EntityContainer* ec = (RS_EntityContainer*)e;
176 for (RS_Entity* e2=ec->firstEntity(RS2::ResolveAll); e2!=NULL;
177 e2=ec->nextEntity(RS2::ResolveAll)) {
179 VectorSolutions sol =
180 RS_Information::getIntersection(&line, e2, true);
182 if (sol.hasValid()) {
188 VectorSolutions sol =
189 RS_Information::getIntersection(&line, e, true);
191 if (sol.hasValid()) {
197 if (graphicView!=NULL) {
198 graphicView->deleteEntity(e);
201 e->setSelected(select);
203 if (graphicView!=NULL) {
204 graphicView->drawEntity(e);
215 * Selects all entities that are connected to the given entity.
217 * @param e The entity where the algorithm starts. Must be an atomic entity.
219 void RS_Selection::selectContour(RS_Entity* e) {
225 if (!e->isAtomic()) {
229 bool select = !e->isSelected();
230 RS_AtomicEntity* ae = (RS_AtomicEntity*)e;
231 Vector p1 = ae->getStartpoint();
232 Vector p2 = ae->getEndpoint();
235 // (de)select 1st entity:
236 if (graphicView!=NULL) {
237 graphicView->deleteEntity(e);
239 e->setSelected(select);
240 if (graphicView!=NULL) {
241 graphicView->drawEntity(e);
247 for (RS_Entity* en=container->firstEntity(); en!=NULL;
248 en=container->nextEntity()) {
249 //for (uint i=0; i<container->count(); ++i) {
250 //RS_Entity* en = container->entityAt(i);
252 if (en!=NULL && en->isVisible() &&
253 en->isAtomic() && en->isSelected()!=select &&
254 (en->getLayer()==NULL || en->getLayer()->isLocked()==false)) {
256 ae = (RS_AtomicEntity*)en;
259 // startpoint connects to 1st point
260 if (ae->getStartpoint().distanceTo(p1)<1.0e-4) {
262 p1 = ae->getEndpoint();
265 // endpoint connects to 1st point
266 else if (ae->getEndpoint().distanceTo(p1)<1.0e-4) {
268 p1 = ae->getStartpoint();
271 // startpoint connects to 2nd point
272 else if (ae->getStartpoint().distanceTo(p2)<1.0e-4) {
274 p2 = ae->getEndpoint();
277 // endpoint connects to 1st point
278 else if (ae->getEndpoint().distanceTo(p2)<1.0e-4) {
280 p2 = ae->getStartpoint();
284 if (graphicView!=NULL) {
285 graphicView->deleteEntity(ae);
287 ae->setSelected(select);
288 if (graphicView!=NULL) {
289 graphicView->drawEntity(ae);
301 * Selects all entities on the given layer.
303 void RS_Selection::selectLayer(RS_Entity* e) {
309 bool select = !e->isSelected();
311 RS_Layer* layer = e->getLayer(true);
316 RS_String layerName = layer->getName();
317 selectLayer(layerName, select);
323 * Selects all entities on the given layer.
325 void RS_Selection::selectLayer(const RS_String& layerName, bool select) {
327 for (RS_Entity* en=container->firstEntity(); en!=NULL;
328 en=container->nextEntity()) {
330 if (en!=NULL && en->isVisible() &&
331 en->isSelected()!=select &&
332 (en->getLayer()==NULL || en->getLayer()->isLocked()==false)) {
334 RS_Layer* l = en->getLayer(true);
336 if (l!=NULL && l->getName()==layerName) {
337 if (graphicView!=NULL) {
338 graphicView->deleteEntity(en);
340 en->setSelected(select);
341 if (graphicView!=NULL) {
342 graphicView->drawEntity(en);