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"
20 #include "rs_entity.h"
21 #include "graphicview.h"
22 #include "rs_information.h"
23 #include "rs_polyline.h"
26 * Default constructor.
28 * @param container The container to which we will add
29 * entities. Usually that's an Drawing entity but
30 * it can also be a polyline, text, ...
32 RS_Selection::RS_Selection(RS_EntityContainer & container, GraphicView * graphicView)
34 this->container = &container;
35 this->graphicView = graphicView;
36 graphic = container.getGraphic();
40 * Selects or deselects the given entitiy.
42 void RS_Selection::selectSingle(RS_Entity * e)
44 if (e && (e->getLayer() == NULL || e->getLayer()->isLocked() == false))
46 // Same problem as below...
47 //[WAS]#warning "!!! This is causing a segfault in the draw code !!!"
48 // if (graphicView != NULL)
49 // graphicView->deleteEntity(e);
53 //Most likely because while the painter is valid, the QPainter is not...
54 //[WAS]#warning "!!! This is causing a segfault in the draw code !!!"
55 if (graphicView != NULL)
56 // graphicView->drawEntity(e);
57 graphicView->redraw();
62 * Selects all entities on visible layers.
64 void RS_Selection::selectAll(bool select)
66 if (graphicView != NULL)
68 //graphicView->deleteEntity(container);
71 //container->setSelected(select);
72 for(RS_Entity * e=container->firstEntity(); e!=NULL; e=container->nextEntity())
74 //for (uint i=0; i<container->count(); ++i) {
75 //RS_Entity* e = container->entityAt(i);
77 if (e != NULL && e->isVisible())
78 e->setSelected(select);
81 if (graphicView!=NULL)
82 //graphicView->drawEntity(container);
83 graphicView->redraw();
86 void RS_Selection::deselectAll()
92 * Selects all entities on visible layers.
94 void RS_Selection::invertSelection()
96 if (graphicView != NULL)
98 //graphicView->deleteEntity(container);
101 for(RS_Entity * e=container->firstEntity(); e!=NULL; e=container->nextEntity())
103 //for (uint i=0; i<container->count(); ++i) {
104 //RS_Entity* e = container->entityAt(i);
106 if (e != NULL && e->isVisible())
110 if (graphicView != NULL)
111 //graphicView->drawEntity(container);
112 graphicView->redraw();
116 * Selects all entities that are completely in the given window.
118 * @param v1 First corner of the window to select.
119 * @param v2 Second corner of the window to select.
120 * @param select true: select, false: deselect
122 void RS_Selection::selectWindow(const Vector & v1, const Vector & v2, bool select, bool cross)
124 //if (graphicView!=NULL) {
125 // graphicView->drawWindow(v1, v2, true);
128 container->selectWindow(v1, v2, select, cross);
130 if (graphicView != NULL)
131 //graphicView->drawWindow(v1, v2);
132 graphicView->redraw();
135 void RS_Selection::deselectWindow(const Vector & v1, const Vector & v2)
137 selectWindow(v1, v2, false);
141 * Selects all entities that are intersected by the given line.
143 * @param v1 Startpoint of line.
144 * @param v2 Endpoint of line.
145 * @param select true: select, false: deselect
147 void RS_Selection::selectIntersected(const Vector & v1, const Vector & v2, bool select)
149 RS_Line line(NULL, RS_LineData(v1, v2));
152 for (RS_Entity* e=container->firstEntity(); e!=NULL;
153 e=container->nextEntity()) {
154 //for (uint i=0; i<container->count(); ++i) {
155 //RS_Entity* e = container->entityAt(i);
157 if (e!=NULL && e->isVisible()) {
161 // select containers / groups:
162 if (e->isContainer()) {
163 RS_EntityContainer* ec = (RS_EntityContainer*)e;
165 for (RS_Entity* e2=ec->firstEntity(RS2::ResolveAll); e2!=NULL;
166 e2=ec->nextEntity(RS2::ResolveAll)) {
168 VectorSolutions sol =
169 RS_Information::getIntersection(&line, e2, true);
171 if (sol.hasValid()) {
177 VectorSolutions sol =
178 RS_Information::getIntersection(&line, e, true);
180 if (sol.hasValid()) {
186 if (graphicView!=NULL) {
187 graphicView->deleteEntity(e);
190 e->setSelected(select);
192 if (graphicView!=NULL) {
193 graphicView->drawEntity(e);
200 void RS_Selection::deselectIntersected(const Vector & v1, const Vector & v2)
202 selectIntersected(v1, v2, false);
206 * Selects all entities that are connected to the given entity.
208 * @param e The entity where the algorithm starts. Must be an atomic entity.
210 void RS_Selection::selectContour(RS_Entity * e)
212 if (e == NULL || !e->isAtomic())
215 bool select = !e->isSelected();
216 RS_AtomicEntity* ae = (RS_AtomicEntity*)e;
217 Vector p1 = ae->getStartpoint();
218 Vector p2 = ae->getEndpoint();
221 // (de)select 1st entity:
222 if (graphicView!=NULL) {
223 graphicView->deleteEntity(e);
225 e->setSelected(select);
226 if (graphicView!=NULL) {
227 graphicView->drawEntity(e);
233 for (RS_Entity* en=container->firstEntity(); en!=NULL;
234 en=container->nextEntity()) {
235 //for (uint i=0; i<container->count(); ++i) {
236 //RS_Entity* en = container->entityAt(i);
238 if (en!=NULL && en->isVisible() &&
239 en->isAtomic() && en->isSelected()!=select &&
240 (en->getLayer()==NULL || en->getLayer()->isLocked()==false)) {
242 ae = (RS_AtomicEntity*)en;
245 // startpoint connects to 1st point
246 if (ae->getStartpoint().distanceTo(p1)<1.0e-4) {
248 p1 = ae->getEndpoint();
251 // endpoint connects to 1st point
252 else if (ae->getEndpoint().distanceTo(p1)<1.0e-4) {
254 p1 = ae->getStartpoint();
257 // startpoint connects to 2nd point
258 else if (ae->getStartpoint().distanceTo(p2)<1.0e-4) {
260 p2 = ae->getEndpoint();
263 // endpoint connects to 1st point
264 else if (ae->getEndpoint().distanceTo(p2)<1.0e-4) {
266 p2 = ae->getStartpoint();
270 if (graphicView!=NULL) {
271 graphicView->deleteEntity(ae);
273 ae->setSelected(select);
274 if (graphicView!=NULL) {
275 graphicView->drawEntity(ae);
285 * Selects all entities on the given layer.
287 void RS_Selection::selectLayer(RS_Entity * e)
292 bool select = !e->isSelected();
294 RS_Layer * layer = e->getLayer(true);
299 QString layerName = layer->getName();
300 selectLayer(layerName, select);
304 * Selects all entities on the given layer.
306 void RS_Selection::selectLayer(const QString & layerName, bool select)
308 for(RS_Entity * en=container->firstEntity(); en!=NULL; en=container->nextEntity())
310 if (en != NULL && en->isVisible() && en->isSelected() != select
311 && (en->getLayer() == NULL || en->getLayer()->isLocked() == false))
313 RS_Layer * l = en->getLayer(true);
315 if (l != NULL && l->getName() == layerName)
317 if (graphicView != NULL)
318 graphicView->deleteEntity(en);
320 en->setSelected(select);
322 if (graphicView != NULL)
323 graphicView->drawEntity(en);
329 void RS_Selection::deselectLayer(QString & layerName)
331 selectLayer(layerName, false);