00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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() );
00053
00054 m_showhandle = true;
00055 m_selectObjects = selection.m_selectObjects;
00056 }
00057
00058 VSelection::~VSelection()
00059 {
00060
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
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
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
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
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
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
00205
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
00222 const KoRect& rect = boundingBox();
00223
00224
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
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
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
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
00276
00277
00278
00279
00280 m_boundingBox = KoRect();
00281
00282 VObjectListIterator itr = m_objects;
00283 for( ; itr.current(); ++itr )
00284 m_boundingBox |= itr.current()->boundingBox();
00285
00286
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