karbon

vselectobjects.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2002, The Karbon Developers
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18*/
19
20
21#include "vselectobjects.h"
22#include "vlayer.h"
23#include "vdocument.h"
24#include "vsegment.h"
25#include <kdebug.h>
26
27void
29{
30 // Never select a deleted, locked or hidden object.
31 if( composite.state() > VObject::normal &&
32 composite.state() < VObject::selected )
33 return;
34
35 if( m_rectMode && m_rect.isEmpty() ) // in this mode everything is selected
36 {
37 visitVObject( composite );
38 return;
39 }
40
41 bool selected = false;
42
43 if( m_rectMode )
44 {
45 // Check if composite is completely inside the selection rectangle.
46 // This test should be the first test since it's the less expensive one.
47 if( m_rect.contains( composite.boundingBox() ) )
48 {
49 selected = true;
50 }
51
52 // Check if any of the rectangle corners is inside the composite.
53 // This test should be done before the intersect test since it covers many
54 // intersection cases.
55 if( !selected )
56 {
57 if(
58 composite.pointIsInside( m_rect.topLeft() ) ||
59 composite.pointIsInside( m_rect.topRight() ) ||
60 composite.pointIsInside( m_rect.bottomRight() ) ||
61 composite.pointIsInside( m_rect.bottomLeft() ) )
62 {
63 selected = true;
64 }
65 }
66
67 // Check if selection rectangle intersects the composite.
68 if( !selected )
69 {
70 // Path for holding a helper segment.
71 VSubpath path( 0L );
72
73 path.moveTo( m_rect.topLeft() );
74 path.lineTo( m_rect.topRight() );
75
76 if( composite.intersects( *path.getLast() ) )
77 {
78 selected = true;
79 }
80 else
81 {
82 path.getFirst()->setKnot( m_rect.bottomRight() );
83
84 if( composite.intersects( *path.getLast() ) )
85 {
86 selected = true;
87 }
88 else
89 {
90 path.getLast()->setKnot( m_rect.bottomLeft() );
91
92 if( composite.intersects( *path.getLast() ) )
93 {
94 selected = true;
95 }
96 else
97 {
98 path.getFirst()->setKnot( m_rect.topLeft() );
99
100 if( composite.intersects( *path.getLast() ) )
101 {
102 selected = true;
103 }
104 }
105 }
106 }
107 }
108 }
109 else
110 {
111 if( composite.pointIsInside( m_point ) )
112 selected = true;
113 }
114
115 if( selected )
116 {
117 if( m_select )
118 {
119 composite.setState( VObject::selected );
120 if( ! m_selection.containsRef( &composite ) )
121 m_selection.append( &composite );
122 }
123 else
124 {
125 composite.setState( VObject::normal );
126 m_selection.remove( &composite );
127 }
128
129 setSuccess();
130 }
131}
132
133void
134VSelectObjects::visitVObject( VObject& object )
135{
136 // Never select a deleted, locked or hidden object.
137 if( object.state() > VObject::normal &&
138 object.state() < VObject::selected )
139 return;
140
141 // selection by selection rectangle
142 if( m_rectMode )
143 {
144 if( !m_rect.isEmpty() )
145 {
146 if( m_select )
147 {
148 if( m_rect.intersects( object.boundingBox() ) )
149 {
150 object.setState( VObject::selected );
151 if( ! m_selection.containsRef( &object ) )
152 m_selection.append( &object );
153 setSuccess();
154 }
155 }
156 else
157 {
158 if( m_rect.intersects( object.boundingBox() ) )
159 {
160 object.setState( VObject::normal );
161 m_selection.remove( &object );
162 setSuccess();
163 }
164 }
165 }
166 else
167 {
168 if( m_select )
169 {
170 object.setState( VObject::selected );
171 if( ! m_selection.containsRef( &object ) )
172 m_selection.append( &object );
173 setSuccess();
174 }
175 else
176 {
177 object.setState( VObject::normal );
178 m_selection.remove( &object );
179 setSuccess();
180 }
181 }
182 }
183 // selection by point
184 else
185 {
186 if( object.boundingBox().contains( m_point ) )
187 {
188 if( m_select )
189 {
190 object.setState( VObject::selected );
191 if( ! m_selection.containsRef( &object ) )
192 m_selection.append( &object );
193 }
194 else
195 {
196 object.setState( VObject::normal );
197 m_selection.remove( &object );
198 }
199 setSuccess();
200 }
201 }
202
203}
204
205void
207{
208 VDocument* doc = (VDocument*)layer.parent();
209 if ( ( layer.state() != VObject::deleted ) &&
210 ( ( doc->selectionMode() == VDocument::AllLayers ) ||
211 ( doc->selectionMode() == VDocument::VisibleLayers && ( layer.state() == VObject::normal || layer.state() == VObject::normal_locked ) ) ||
212 ( doc->selectionMode() == VDocument::SelectedLayers && layer.selected() ) ||
213 ( doc->selectionMode() == VDocument::ActiveLayer && doc->activeLayer() == &layer ) ) )
214 {
215 VObjectListIterator itr( layer.objects() );
216 for( ; itr.current(); ++itr )
217 itr.current()->accept( *this );
218 }
219}
220
221void
223{
224 // Never select a deleted, locked or hidden object.
225 if( text.state() > VObject::normal &&
226 text.state() < VObject::selected )
227 return;
228
229 int deselectedGlyphs = 0;
230
231 VPathListIterator itr( text.glyphs() );
232 for( ; itr.current(); ++itr )
233 {
234 VPath c( 0L );
235 c.combine( *itr.current() );
236 visitVPath( c );
237 if( m_select && c.state() == VObject::selected )
238 {
239 kdDebug(38000) << "selected: " << itr.current() << endl;
240 m_selection.remove( &c );
241 text.setState( VObject::selected );
242 if( ! m_selection.containsRef( &text ) )
243 m_selection.append( &text );
244 return;
245 }
246 else if( c.state() == VObject::normal )
247 {
248 kdDebug(38000) << "deselected: " << itr.current() << endl;
249 deselectedGlyphs++;
250 }
251 }
252 if( deselectedGlyphs >= 0 && uint( deselectedGlyphs ) == text.glyphs().count() )
253 {
254 text.setState( VObject::normal );
255 m_selection.remove( &text );
256 }
257}
258
259void
261{
262 // Never select a deleted, locked or hidden object.
263 if( group.state() > VObject::normal &&
264 group.state() < VObject::selected )
265 return;
266
267 if( ! m_insideGroups )
268 visitVObject( group );
269 else
270 {
271 VVisitor::visitVGroup( group );
272 }
273}
All non-visual, static doc info is in here.
Definition vdocument.h:53
VLayer * activeLayer() const
Returns a pointer to the active layer.
Definition vdocument.h:212
@ AllLayers
selection within all layers
Definition vdocument.h:60
@ ActiveLayer
selection within the active layer
Definition vdocument.h:57
@ VisibleLayers
selection within all visible layers
Definition vdocument.h:58
@ SelectedLayers
selection within all selected layers
Definition vdocument.h:59
VSelectionMode selectionMode()
Returns the selection mode.
Definition vdocument.h:246
Base class for all sort of VObject conglomerats.
Definition vgroup.h:35
const VObjectList & objects() const
Read only access to the grouped objects.
Definition vgroup.h:110
VLayer manages a set of vobjects.
Definition vlayer.h:37
bool selected()
Returns the selection state of the layer.
Definition vlayer.h:115
The base class for all karbon objects.
Definition vobject.h:50
virtual void setState(const VState state)
Sets the state to a specified new state.
Definition vobject.h:163
VObject * parent() const
Returns pointer to current parent object.
Definition vobject.h:147
@ normal_locked
visible, but locked (r/o)
Definition vobject.h:55
@ selected
visible, active and can be manipulated by tools
Definition vobject.h:61
@ deleted
deleted, nearly dead
Definition vobject.h:58
@ normal
visible, not active
Definition vobject.h:54
VState state() const
Get the state the object is in.
Definition vobject.h:154
A composite path consists of one or many subpaths.
Definition vcomposite.h:48
void combine(const VPath &path)
Combines two composite paths.
bool pointIsInside(const KoPoint &p) const
Returns true if point p is located inside the composite.
bool intersects(const VSegment &segment) const
Returns true if the segment intersects this composite.
virtual const KoRect & boundingBox() const
Calculates the tightest bounding box around the object.
void setKnot(const KoPoint &p)
Sets the knot.
Definition vsegment.h:164
virtual void visitVGroup(VGroup &group)
Visit method for a VGroup.
virtual void visitVLayer(VLayer &layer)
Visit method for a VLayer.
virtual void visitVPath(VPath &composite)
Visit method for a VPath.
virtual void visitVText(VText &text)
Visit method for a VText.
VSubpath provides a sophisticated list of VSegment.
Definition vpath.h:43
virtual void visitVGroup(VGroup &group)
Visit method for a VGroup.
Definition vvisitor.cpp:52
void setSuccess(bool success=true)
Set the success property.
Definition vvisitor.h:142