karbon

vselection.cc

00001 /* This file is part of the KDE project
00002    Copyright (C) 2001, The Karbon Developers
00003    Copyright (C) 2002, The Karbon Developers
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License as published by the Free Software Foundation; either
00008    version 2 of the License, or (at your option) any later version.
00009 
00010    This library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public License
00016    along with this library; see the file COPYING.LIB.  If not, write to
00017    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018  * Boston, MA 02110-1301, USA.
00019 */
00020 
00021 
00022 #include "vdocument.h"
00023 #include "vdrawselection.h"
00024 #include "vpainter.h"
00025 #include "vselection.h"
00026 #include "vselectnodes.h"
00027 #include "vselectobjects.h"
00028 #include "vvisitor.h"
00029 #include "vcolor.h"
00030 #include "vfill.h"
00031 #include "vstroke.h"
00032 
00033 uint VSelection::m_handleNodeSize = 3;
00034 
00035 VSelection::VSelection( VObject* parent )
00036     : VObject( parent ), m_showhandle( true )
00037 {
00038     m_handleRect = new KoRect[ 10 ];
00039     setStroke( VStroke( VColor( Qt::black ) ) );
00040     setFill( VFill() );
00041 
00042     m_selectObjects = true;
00043 }
00044 
00045 VSelection::VSelection( const VSelection& selection )
00046     : VObject( selection ), VVisitor()
00047 {
00048     m_handleRect = new KoRect[ 10 ];
00049 
00050     VObjectListIterator itr = selection.m_objects;
00051     for ( ; itr.current() ; ++itr )
00052         append( itr.current() );    // Don't clone objects here.
00053 
00054     m_showhandle = true;
00055     m_selectObjects = selection.m_selectObjects;
00056 }
00057 
00058 VSelection::~VSelection()
00059 {
00060     //clear();
00061     delete[]( m_handleRect );
00062 }
00063 
00064 VSelection*
00065 VSelection::clone() const
00066 {
00067     return new VSelection( *this );
00068 }
00069 
00070 void
00071 VSelection::accept( VVisitor& visitor )
00072 {
00073     visitor.visitVSelection( *this );
00074 }
00075 
00076 void
00077 VSelection::take( VObject& object )
00078 {
00079     m_objects.removeRef( &object );
00080     if( object.state() >= selected )
00081         object.setState( normal );
00082     invalidateBoundingBox();
00083 }
00084 
00085 bool
00086 VSelection::take( const KoRect& rect, bool selectObjects, bool exclusive )
00087 {
00088     bool success = false;
00089 
00090     if( selectObjects )
00091     {
00092         VSelectObjects op( m_objects, rect, false );
00093         if( op.visit( *static_cast<VDocument*>( parent() ) ) )
00094         {
00095             selectNodes();
00096             success = true;
00097         }
00098     }
00099     else
00100     {
00101         VObjectListIterator itr( m_objects );
00102 
00103         // Try to deselect all that have at least one node contained in the rect
00104         for ( ; itr.current(); ++itr )
00105         {
00106             VSelectNodes op( rect, false, exclusive );
00107 
00108             if( op.visit( *itr.current() ) )
00109             {
00110                 success = true;
00111             }
00112         }
00113     }
00114 
00115     invalidateBoundingBox();
00116 
00117     return success;
00118 }
00119 
00120 void
00121 VSelection::append()
00122 {
00123     clear();
00124 
00125     VSelectObjects op( m_objects );
00126     op.visit( *static_cast<VDocument*>( parent() ) );
00127     selectNodes();
00128 
00129     invalidateBoundingBox();
00130 }
00131 
00132 void
00133 VSelection::append( VObject* object )
00134 {
00135     // only append if item is not deleted or not already in list
00136     if( object->state() != deleted )
00137     {
00138         if( ! m_objects.containsRef( object ) )
00139             m_objects.append( object );
00140         object->setState( selected );
00141         invalidateBoundingBox();
00142     }
00143 }
00144 
00145 void
00146 VSelection::append( const VObjectList &objects )
00147 {
00148     VObjectListIterator itr = objects;
00149     for( ; itr.current(); ++itr )
00150         append( itr.current() );
00151 }
00152 
00153 bool
00154 VSelection::append( const KoRect& rect, bool selectObjects, bool exclusive )
00155 {
00156     bool success = false;
00157 
00158     if( selectObjects )
00159     {
00160         //m_objects.clear();
00161         VSelectObjects op( m_objects, rect );
00162         if( op.visit( *static_cast<VDocument*>( parent() ) ) )
00163         {
00164             selectNodes();
00165             success = true;
00166         }
00167     }
00168     else
00169     {
00170         VObjectListIterator itr( m_objects );
00171         VObjectList notSelected;
00172 
00173         // Try to select all that have at least one node contained in the rect
00174         for ( ; itr.current(); ++itr )
00175         {
00176             VSelectNodes op( rect, true, exclusive );
00177 
00178             if( op.visit( *itr.current() ) )
00179                 success = true;
00180             else
00181                 notSelected.append( itr.current());
00182         }
00183         // Remove all that were not selected from this selection
00184         VObjectListIterator jtr( notSelected );
00185         for ( ; jtr.current(); ++jtr )
00186             take( *( jtr.current() ) );
00187     }
00188 
00189     invalidateBoundingBox();
00190 
00191     return success;
00192 }
00193 
00194 void
00195 VSelection::clear()
00196 {
00197     VSelectNodes op( true );
00198 
00199     VObjectListIterator itr = m_objects;
00200     for( ; itr.current(); ++itr )
00201     {
00202         op.visit( *itr.current() );
00203 
00204         //if( itr.current()->state() != deleted )
00205         //  itr.current()->setState( normal );
00206     }
00207 
00208     m_objects.clear();
00209     invalidateBoundingBox();
00210 }
00211 
00212 void
00213 VSelection::draw( VPainter* painter, double zoomFactor ) const
00214 {
00215     if( objects().count() == 0 || state() == VObject::edit )
00216         return;
00217 
00218     VDrawSelection op( m_objects, painter, !m_selectObjects, m_handleNodeSize );
00219     op.visitVSelection( (VSelection &)*this );
00220 
00221     // get bounding box:
00222     const KoRect& rect = boundingBox();
00223 
00224     // calculate displaycoords of big handle rect:
00225     m_handleRect[ 0 ].setCoords(    qRound( rect.left() ), qRound( rect.top() ),
00226                                     qRound( rect.right() ), qRound( rect.bottom() ) );
00227 
00228     KoPoint center = m_handleRect[ 0 ].center();
00229 
00230     double handleNodeSize = m_handleNodeSize / zoomFactor;
00231 
00232     // calculate displaycoords of nodes:
00233     m_handleRect[ node_lb ].setRect( m_handleRect[0].left() - handleNodeSize, m_handleRect[0].top() - handleNodeSize, 2 * handleNodeSize, 2 * handleNodeSize );
00234     m_handleRect[ node_mb ].setRect( center.x() - handleNodeSize, m_handleRect[0].top() - handleNodeSize, 2 * handleNodeSize, 2 * handleNodeSize );
00235     m_handleRect[ node_rb ].setRect( m_handleRect[0].right() - handleNodeSize - (1 / zoomFactor), m_handleRect[0].top() - handleNodeSize, 2 * handleNodeSize, 2 * handleNodeSize );
00236     m_handleRect[ node_rm ].setRect( m_handleRect[0].right() - handleNodeSize - (1 / zoomFactor), center.y() - handleNodeSize, 2 * handleNodeSize, 2 * handleNodeSize );
00237     m_handleRect[ node_rt ].setRect( m_handleRect[0].right() - handleNodeSize - (1 / zoomFactor) , m_handleRect[0].bottom() - handleNodeSize - (1 / zoomFactor), 2 * handleNodeSize, 2 * handleNodeSize );
00238     m_handleRect[ node_mt ].setRect( center.x() - handleNodeSize, m_handleRect[0].bottom() - handleNodeSize - (1 / zoomFactor), 2 * handleNodeSize, 2 * handleNodeSize );
00239     m_handleRect[ node_lt ].setRect( m_handleRect[0].left() - handleNodeSize, m_handleRect[0].bottom() - handleNodeSize - (1 / zoomFactor), 2 * handleNodeSize, 2 * handleNodeSize );
00240     m_handleRect[ node_lm ].setRect( m_handleRect[0].left() - handleNodeSize, center.y() - handleNodeSize, 2 * handleNodeSize, 2 * handleNodeSize );
00241 
00242     if( !m_showhandle ) return;
00243 
00244     // draw handle rect:
00245     painter->setPen( Qt::blue.light() );
00246     painter->setBrush( Qt::NoBrush );
00247 
00248     painter->drawRect( KoRect( m_handleRect[ 0 ].x() * zoomFactor, m_handleRect[ 0 ].y() * zoomFactor,
00249                               m_handleRect[ 0 ].width() * zoomFactor, m_handleRect[ 0 ].height() * zoomFactor ) );
00250     painter->setPen( Qt::blue.light() );
00251 
00252     // draw nodes:
00253     if( state() == VObject::selected )
00254     {
00255         painter->setPen( Qt::blue.light() );
00256         painter->setBrush( Qt::white );
00257 
00258         KoRect temp;
00259         for( uint i = node_lt; i <= node_rb; ++i )
00260         {
00261             if( i != node_mm )
00262             {
00263                 temp.setRect(   zoomFactor * m_handleRect[ i ].left(),
00264                                 zoomFactor * m_handleRect[ i ].top(),
00265                                 2 * m_handleNodeSize + 1, 2 * m_handleNodeSize + 1 );
00266                 painter->drawRect( temp );
00267             }
00268         }
00269     }
00270 }
00271 
00272 const KoRect&
00273 VSelection::boundingBox() const
00274 {
00275 // disable bbox caching for selection since there is no reliable
00276 // way to get notified of a bbox change:
00277 //  if( m_boundingBoxIsInvalid )
00278 //  {
00279         // clear:
00280         m_boundingBox = KoRect();
00281 
00282         VObjectListIterator itr = m_objects;
00283         for( ; itr.current(); ++itr )
00284             m_boundingBox |= itr.current()->boundingBox();
00285 
00286 //      m_boundingBoxIsInvalid = false;
00287 //  }
00288 
00289     return m_boundingBox;
00290 }
00291 
00292 
00293 VHandleNode
00294 VSelection::handleNode( const KoPoint &point ) const
00295 {
00296     for( uint i = node_lt; i <= node_rb; ++i )
00297     {
00298         if( m_handleRect[i].contains( point ) )
00299             return static_cast<VHandleNode>( i );
00300     }
00301 
00302     return node_none;
00303 }
00304 
00305 QPtrList<VSegment>
00306 VSelection::getSegments( const KoRect& rect )
00307 {
00308     VTestNodes op( rect );
00309 
00310     VObjectListIterator itr = m_objects;
00311     for( ; itr.current(); ++itr )
00312         op.visit( *itr.current() );
00313 
00314     return op.result();
00315 }
00316 
00317 void
00318 VSelection::selectNodes( bool select )
00319 {
00320     VSelectNodes op( select );
00321 
00322     VObjectListIterator itr = m_objects;
00323     for( ; itr.current(); ++itr )
00324     {
00325         op.visit( *itr.current() );
00326     }
00327 }
00328 
KDE Home | KDE Accessibility Home | Description of Access Keys