00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <math.h>
00021
00022 #include <qcursor.h>
00023 #include <qlabel.h>
00024
00025 #include <klocale.h>
00026 #include <KoPoint.h>
00027 #include <KoRect.h>
00028
00029 #include <karbon_part.h>
00030 #include <karbon_view.h>
00031
00032 #include <render/vpainter.h>
00033 #include <render/vpainterfactory.h>
00034 #include <visitors/vselectnodes.h>
00035 #include <commands/vtransformcmd.h>
00036 #include <visitors/vdrawselection.h>
00037 #include <core/vselection.h>
00038 #include <core/vcursor.h>
00039 #include "vselectnodestool.h"
00040 #include <vtransformnodes.h>
00041 #include <commands/vdeletenodescmd.h>
00042 #include <widgets/vcanvas.h>
00043
00044 #include <kdebug.h>
00045
00046 VSelectNodesTool::VSelectNodesTool( KarbonView* view )
00047 : VTool( view, "tool_select_nodes" ), m_state( normal ), m_select( true )
00048 {
00049 registerTool( this );
00050 }
00051
00052 VSelectNodesTool::~VSelectNodesTool()
00053 {
00054 }
00055
00056 void
00057 VSelectNodesTool::activate()
00058 {
00059 if( view() )
00060 {
00061 view()->setCursor( VCursor::needleArrow() );
00062 view()->part()->document().selection()->showHandle( false );
00063 view()->part()->document().selection()->setSelectObjects( false );
00064
00065 view()->part()->document().selection()->selectNodes( false );
00066 view()->repaintAll( view()->part()->document().selection()->boundingBox() );
00067 }
00068 VTool::activate();
00069 }
00070
00071 QString
00072 VSelectNodesTool::statusText()
00073 {
00074 if( m_state == normal )
00075 return i18n( "Editing Nodes" );
00076 else
00077 return QString( "" );
00078 }
00079
00080 void
00081 VSelectNodesTool::draw()
00082 {
00083 VPainter *painter = view()->painterFactory()->editpainter();
00084 painter->setZoomFactor( view()->zoom() );
00085 painter->setRasterOp( Qt::NotROP );
00086
00087 VSelection* selection = view()->part()->document().selection();
00088
00089 KoRect selrect = calcSelRect( last() );
00090
00091 QPtrList<VSegment> segments = selection->getSegments( selrect );
00092 if( selection->objects().count() > 0 &&
00093 m_state != dragging && ( m_state >= moving || segments.count() > 0 ) )
00094 {
00095 if( m_state == normal )
00096 {
00097 if( segments.count() == 1 && !selrect.contains( segments.at( 0 )->knot() ) )
00098 {
00099 if( selrect.contains( segments.at( 0 )->point( 1 ) ) )
00100
00101 {
00102 m_state = movingbezier1;
00103 segments.at( 0 )->selectPoint( 1, false );
00104 }
00105 else
00106 {
00107 m_state = movingbezier2;
00108 segments.at( 0 )->selectPoint( 0, false );
00109 }
00110 selection->append( selrect.normalize(), false, true );
00111 }
00112 else
00113 {
00114 m_state = moving;
00115 selection->append( selrect.normalize(), false, false );
00116 }
00117
00118 recalc();
00119 }
00120
00121 VDrawSelection op( m_objects, painter, true, selection->handleSize() );
00122 VObjectListIterator itr = m_objects;
00123 for( ; itr.current(); ++itr )
00124 op.visit( *( itr.current() ) );
00125 }
00126 else
00127 {
00128 painter->setPen( Qt::DotLine );
00129 painter->newPath();
00130 painter->moveTo( KoPoint( first().x(), first().y() ) );
00131 painter->lineTo( KoPoint( m_current.x(), first().y() ) );
00132 painter->lineTo( KoPoint( m_current.x(), m_current.y() ) );
00133 painter->lineTo( KoPoint( first().x(), m_current.y() ) );
00134 painter->lineTo( KoPoint( first().x(), first().y() ) );
00135 painter->strokePath();
00136
00137 m_state = dragging;
00138 }
00139 }
00140
00141 void
00142 VSelectNodesTool::setCursor() const
00143 {
00144 if( m_state == moving ) return;
00145
00146 KoRect selrect = calcSelRect( last() );
00147
00148 QPtrList<VSegment> segments = view()->part()->document().selection()->getSegments( selrect );
00149 if( segments.count() > 0 &&
00150 ( segments.at( 0 )->knotIsSelected() ||
00151 segments.at( 0 )->pointIsSelected( 0 ) ||
00152 segments.at( 0 )->pointIsSelected( 1 ) ||
00153 selrect.contains( segments.at( 0 )->knot() ) ) )
00154 {
00155 view()->setCursor( VCursor::needleMoveArrow() );
00156 }
00157 else
00158 view()->setCursor( VCursor::needleArrow() );
00159 }
00160
00161 void
00162 VSelectNodesTool::mouseButtonPress()
00163 {
00164 m_current = first();
00165
00166 m_state = normal;
00167 m_select = true;
00168
00169 recalc();
00170
00171 view()->part()->document().selection()->setState( VObject::edit );
00172 view()->repaintAll( view()->part()->document().selection()->boundingBox() );
00173 view()->part()->document().selection()->setState( VObject::selected );
00174
00175 draw();
00176 }
00177
00178 void
00179 VSelectNodesTool::rightMouseButtonPress()
00180 {
00181 m_current = first();
00182
00183 m_state = normal;
00184 m_select = false;
00185
00186 recalc();
00187
00188 view()->part()->document().selection()->setState( VObject::edit );
00189 view()->repaintAll( view()->part()->document().selection()->boundingBox() );
00190 view()->part()->document().selection()->setState( VObject::selected );
00191
00192 draw();
00193 }
00194
00195 bool
00196 VSelectNodesTool::keyReleased( Qt::Key key )
00197 {
00198
00199 VSelection* selection = view()->part()->document().selection();
00200
00201 switch( key )
00202 {
00203
00204 case Qt::Key_I:
00205 {
00206 uint handleSize = selection->handleSize();
00207 if( shiftPressed() )
00208 selection->setHandleSize( ++handleSize );
00209 else if( handleSize > 1 )
00210 selection->setHandleSize( --handleSize );
00211 }
00212 break;
00213 case Qt::Key_Delete:
00214 if( selection->objects().count() > 0 )
00215 view()->part()->addCommand( new VDeleteNodeCmd( &view()->part()->document() ), true );
00216 break;
00217 default: return false;
00218 }
00219
00220 if( view() )
00221 view()->repaintAll( selection->boundingBox() );
00222
00223 return true;
00224 }
00225
00226 void
00227 VSelectNodesTool::mouseButtonRelease()
00228 {
00229
00230 draw();
00231
00232 VSelection* selection = view()->part()->document().selection();
00233
00234 KoRect selrect = calcSelRect( last() );
00235
00236 if( ctrlPressed() )
00237 selection->append( selrect.normalize(), false, false );
00238 else
00239 selection->append( selrect.normalize(), false, true );
00240
00241 view()->selectionChanged();
00242 view()->part()->repaintAllViews();
00243 m_state = normal;
00244 }
00245
00246 void
00247 VSelectNodesTool::rightMouseButtonRelease()
00248 {
00249
00250 draw();
00251
00252 VSelection* selection = view()->part()->document().selection();
00253
00254 KoRect selrect = calcSelRect( last() );
00255
00256 selection->take( selrect.normalize(), false, false );
00257
00258 view()->selectionChanged();
00259 view()->part()->repaintAllViews();
00260 m_state = normal;
00261 }
00262
00263 void
00264 VSelectNodesTool::mouseDrag()
00265 {
00266 draw();
00267
00268 recalc();
00269
00270 draw();
00271 }
00272
00273 void
00274 VSelectNodesTool::mouseDragRelease()
00275 {
00276 if( m_state >= moving )
00277 {
00278 view()->part()->document().selection()->setState( VObject::selected );
00279 VCommand *cmd;
00280 QPtrList<VSegment> segments;
00281 if( m_state == movingbezier1 || m_state == movingbezier2 )
00282 {
00283 KoRect selrect = calcSelRect( first() );
00284 segments = view()->part()->document().selection()->getSegments( selrect );
00285 cmd = new VTranslateBezierCmd( &view()->part()->document(), segments.at( 0 ),
00286 qRound( ( last().x() - first().x() ) ),
00287 qRound( ( last().y() - first().y() ) ),
00288 m_state == movingbezier2 );
00289 }
00290 else
00291 {
00292 cmd = new VTranslatePointCmd(
00293 &view()->part()->document(),
00294 qRound( ( last().x() - first().x() ) ),
00295 qRound( ( last().y() - first().y() ) ) );
00296 }
00297 view()->part()->addCommand( cmd, true );
00298 m_state = normal;
00299 }
00300 else
00301 {
00302 KoPoint fp = first();
00303 KoPoint lp = last();
00304
00305 if ( (fabs(lp.x() - fp.x()) + fabs(lp.y()-fp.y())) < 3.0 )
00306 {
00307
00308 fp = last() - KoPoint(8.0, 8.0);
00309 lp = last() + KoPoint(8.0, 8.0);
00310 }
00311
00312
00313 draw();
00314
00315 if( m_select )
00316 {
00317 view()->part()->document().selection()->append();
00318 view()->part()->document().selection()->append(
00319 KoRect( fp.x(), fp.y(), lp.x() - fp.x(), lp.y() - fp.y() ).normalize(),
00320 false );
00321 }
00322 else
00323 {
00324 view()->part()->document().selection()->take(
00325 KoRect( fp.x(), fp.y(), lp.x() - fp.x(), lp.y() - fp.y() ).normalize(),
00326 false, false );
00327 }
00328 view()->selectionChanged();
00329 view()->part()->repaintAllViews();
00330 m_state = normal;
00331 }
00332 }
00333
00334 void
00335 VSelectNodesTool::cancel()
00336 {
00337
00338 if ( isDragging() )
00339 {
00340 draw();
00341 m_state = normal;
00342 view()->repaintAll( view()->part()->document().selection()->boundingBox() );
00343 }
00344 }
00345
00346 void
00347 VSelectNodesTool::recalc()
00348 {
00349 if( m_state == dragging )
00350 {
00351 m_current = last();
00352 }
00353 else if( m_state == moving || m_state == movingbezier1 || m_state == movingbezier2 )
00354 {
00355 KoPoint _last = view()->canvasWidget()->snapToGrid( last() );
00356 double distx = _last.x() - first().x();
00357 double disty = _last.y() - first().y();
00358
00359 QWMatrix mat;
00360 mat.translate( distx, disty );
00361
00362
00363 m_objects.clear();
00364 VObject* copy;
00365
00366 VTransformNodes op( mat );
00367
00368 VObjectListIterator itr = view()->part()->document().selection()->objects();
00369 for ( ; itr.current() ; ++itr )
00370 {
00371 if( itr.current()->state() != VObject::deleted )
00372 {
00373 copy = itr.current()->clone();
00374 copy->setState( VObject::edit );
00375 op.visit( *copy );
00376 m_objects.append( copy );
00377 }
00378 }
00379 }
00380 }
00381
00382 void
00383 VSelectNodesTool::setup( KActionCollection *collection )
00384 {
00385 m_action = static_cast<KRadioAction *>(collection -> action( name() ) );
00386
00387 if( m_action == 0 )
00388 {
00389 m_action = new KRadioAction( i18n( "Select Nodes Tool" ), "14_selectnodes", Qt::SHIFT+Qt::Key_H, this, SLOT( activate() ), collection, name() );
00390 m_action->setToolTip( i18n( "Select Nodes" ) );
00391 m_action->setExclusiveGroup( "select" );
00392
00393 }
00394 }
00395
00396 KoRect
00397 VSelectNodesTool::calcSelRect( const KoPoint &pos ) const
00398 {
00399 double tolerance = view()->part()->document().selection()->handleSize() / view()->zoom();
00400 return KoRect( pos.x() - tolerance, pos.y() - tolerance, 2 * tolerance + 1.0, 2 * tolerance + 1.0 );
00401 }