karbon

vselectobjects.cc

00001 /* This file is part of the KDE project
00002    Copyright (C) 2002, The Karbon Developers
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License as published by the Free Software Foundation; either
00007    version 2 of the License, or (at your option) any later version.
00008 
00009    This library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public License
00015    along with this library; see the file COPYING.LIB.  If not, write to
00016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  * Boston, MA 02110-1301, USA.
00018 */
00019 
00020 
00021 #include "vselectobjects.h"
00022 #include "vlayer.h"
00023 #include "vdocument.h"
00024 #include "vsegment.h"
00025 #include <kdebug.h>
00026 
00027 void
00028 VSelectObjects::visitVPath( VPath& composite )
00029 {
00030     // Never select a deleted, locked or hidden object.
00031     if( composite.state() > VObject::normal &&
00032         composite.state() < VObject::selected )
00033         return;
00034 
00035     if( m_rectMode && m_rect.isEmpty() ) // in this mode everything is selected
00036     {
00037         visitVObject( composite );
00038         return;
00039     }
00040 
00041     bool selected = false;
00042 
00043     if( m_rectMode )
00044     {
00045         // Check if composite is completely inside the selection rectangle.
00046         // This test should be the first test since it's the less expensive one.
00047         if( m_rect.contains( composite.boundingBox() ) )
00048         {
00049             selected = true;
00050         }
00051     
00052         // Check if any of the rectangle corners is inside the composite.
00053         // This test should be done before the intersect test since it covers many
00054         // intersection cases.
00055         if( !selected )
00056         {
00057             if(
00058                 composite.pointIsInside( m_rect.topLeft() ) ||
00059                 composite.pointIsInside( m_rect.topRight() ) ||
00060                 composite.pointIsInside( m_rect.bottomRight() ) ||
00061                 composite.pointIsInside( m_rect.bottomLeft() ) )
00062             {
00063                 selected = true;
00064             }
00065         }
00066     
00067         // Check if selection rectangle intersects the composite.
00068         if( !selected )
00069         {
00070             // Path for holding a helper segment.
00071             VSubpath path( 0L );
00072     
00073             path.moveTo( m_rect.topLeft() );
00074             path.lineTo( m_rect.topRight() );
00075     
00076             if( composite.intersects( *path.getLast() ) )
00077             {
00078                 selected = true;
00079             }
00080             else
00081             {
00082                 path.getFirst()->setKnot( m_rect.bottomRight() );
00083     
00084                 if( composite.intersects( *path.getLast() ) )
00085                 {
00086                     selected = true;
00087                 }
00088                 else
00089                 {
00090                     path.getLast()->setKnot( m_rect.bottomLeft() );
00091     
00092                     if( composite.intersects( *path.getLast() ) )
00093                     {
00094                         selected = true;
00095                     }
00096                     else
00097                     {
00098                         path.getFirst()->setKnot( m_rect.topLeft() );
00099     
00100                         if( composite.intersects( *path.getLast() ) )
00101                         {
00102                             selected = true;
00103                         }
00104                     }
00105                 }
00106             }
00107         }
00108     }
00109     else
00110     {
00111         if( composite.pointIsInside( m_point ) )
00112             selected = true;
00113     }
00114 
00115     if( selected )
00116     {
00117         if( m_select )
00118         {
00119             composite.setState( VObject::selected );
00120             if( ! m_selection.containsRef( &composite ) )
00121                 m_selection.append( &composite );
00122         }
00123         else
00124         {
00125             composite.setState( VObject::normal );
00126             m_selection.remove( &composite );
00127         }
00128 
00129         setSuccess();
00130     }
00131 }
00132 
00133 void
00134 VSelectObjects::visitVObject( VObject& object )
00135 {
00136     // Never select a deleted, locked or hidden object.
00137     if( object.state() > VObject::normal &&
00138         object.state() < VObject::selected )
00139         return;
00140 
00141     // selection by selection rectangle
00142     if( m_rectMode )
00143     {
00144         if( !m_rect.isEmpty() )
00145         {
00146             if( m_select )
00147             {
00148                 if( m_rect.intersects( object.boundingBox() ) )
00149                 {
00150                     object.setState( VObject::selected );
00151                     if( ! m_selection.containsRef( &object ) )
00152                         m_selection.append( &object );
00153                     setSuccess();
00154                 }
00155             }
00156             else
00157             {
00158                 if( m_rect.intersects( object.boundingBox() ) )
00159                 {
00160                     object.setState( VObject::normal );
00161                     m_selection.remove( &object );
00162                     setSuccess();
00163                 }
00164             }
00165         }
00166         else
00167         {
00168             if( m_select )
00169             {
00170                 object.setState( VObject::selected );
00171                 if( ! m_selection.containsRef( &object ) )
00172                     m_selection.append( &object );
00173                 setSuccess();
00174             }
00175             else
00176             {
00177                 object.setState( VObject::normal );
00178                 m_selection.remove( &object );
00179                 setSuccess();
00180             }
00181         }
00182     }
00183     // selection by point
00184     else
00185     {
00186         if( object.boundingBox().contains( m_point ) )
00187         {
00188             if( m_select )
00189             {
00190                 object.setState( VObject::selected );
00191                 if( ! m_selection.containsRef( &object ) )
00192                     m_selection.append( &object );
00193             }
00194             else
00195             {
00196                 object.setState( VObject::normal );
00197                 m_selection.remove( &object );
00198             }
00199             setSuccess();
00200         }
00201     }
00202 
00203 }
00204 
00205 void
00206 VSelectObjects::visitVLayer( VLayer& layer )
00207 {
00208     VDocument* doc = (VDocument*)layer.parent();
00209     if ( ( layer.state() != VObject::deleted ) &&
00210          ( ( doc->selectionMode() == VDocument::AllLayers ) ||
00211            ( doc->selectionMode() == VDocument::VisibleLayers && ( layer.state() == VObject::normal || layer.state() == VObject::normal_locked ) ) ||
00212            ( doc->selectionMode() == VDocument::SelectedLayers && layer.selected() ) ||
00213            ( doc->selectionMode() == VDocument::ActiveLayer && doc->activeLayer() == &layer ) ) )
00214     {
00215         VObjectListIterator itr( layer.objects() );
00216         for( ; itr.current(); ++itr )
00217             itr.current()->accept( *this );
00218     }
00219 }
00220 
00221 void 
00222 VSelectObjects::visitVText( VText& text )
00223 {
00224     // Never select a deleted, locked or hidden object.
00225     if( text.state() > VObject::normal &&
00226         text.state() < VObject::selected )
00227         return;
00228 
00229     int deselectedGlyphs = 0;
00230 
00231     VPathListIterator itr( text.glyphs() );
00232     for( ; itr.current(); ++itr )
00233     {
00234         VPath c( 0L );
00235         c.combine( *itr.current() );
00236         visitVPath( c );
00237         if( m_select && c.state() == VObject::selected )
00238         {
00239             kdDebug(38000) << "selected: " << itr.current() << endl;
00240             m_selection.remove( &c );
00241             text.setState( VObject::selected );
00242             if( ! m_selection.containsRef( &text ) )
00243                 m_selection.append( &text );
00244             return;
00245         }
00246         else if( c.state() == VObject::normal )
00247         {
00248             kdDebug(38000) << "deselected: " << itr.current() << endl;
00249             deselectedGlyphs++;
00250         }
00251     }
00252     if( deselectedGlyphs >= 0 && uint( deselectedGlyphs ) == text.glyphs().count() )
00253     {
00254         text.setState( VObject::normal );
00255         m_selection.remove( &text );
00256     }
00257 }
00258 
00259 void 
00260 VSelectObjects::visitVGroup( VGroup& group )
00261 { 
00262     // Never select a deleted, locked or hidden object.
00263     if( group.state() > VObject::normal &&
00264         group.state() < VObject::selected )
00265         return;
00266 
00267     if( ! m_insideGroups )
00268         visitVObject( group );
00269     else
00270     {
00271         VVisitor::visitVGroup( group );
00272     }
00273 }
KDE Home | KDE Accessibility Home | Description of Access Keys