25#include <tqradiobutton.h>
26#include <tqbuttongroup.h>
32#include <karbon_part.h>
33#include <karbon_view.h>
34#include <render/vpainter.h>
35#include <render/vpainterfactory.h>
36#include <core/vselection.h>
37#include "vselecttool.h"
38#include <commands/vtransformcmd.h>
39#include <visitors/vselectiondesc.h>
40#include <visitors/vselectobjects.h>
41#include <widgets/vcanvas.h>
43VSelectOptionsWidget::VSelectOptionsWidget(
KarbonPart *part )
44 : KDialogBase( 0L,
"", true, i18n(
"Selection" ), Ok | Cancel ), m_part( part )
46 TQButtonGroup *group =
new TQButtonGroup( 1, TQt::Horizontal, i18n(
"Selection Mode" ),
this );
48 new TQRadioButton( i18n(
"Select in current layer" ), group );
49 new TQRadioButton( i18n(
"Select in visible layers" ), group );
50 new TQRadioButton( i18n(
"Select in selected layers" ), group );
52 group->setRadioButtonExclusive(
true );
55 connect( group, TQ_SIGNAL( clicked(
int ) ),
this, TQ_SLOT( modeChange(
int ) ) );
57 group->setInsideMargin( 4 );
58 group->setInsideSpacing( 2 );
60 setMainWidget( group );
61 setFixedSize( baseSize() );
64void VSelectOptionsWidget::modeChange(
int mode )
69VSelectTool::VSelectTool( KarbonView *view )
70 :
VTool( view,
"tool_select" ), m_state( normal )
74 m_objects.setAutoDelete(
true );
75 m_optionsWidget =
new VSelectOptionsWidget( view->part() );
77 connect( view, TQ_SIGNAL( selectionChange() ),
this, TQ_SLOT( updateStatusBar() ) );
80VSelectTool::~VSelectTool()
82 delete m_optionsWidget;
89 view()->setCursor( TQCursor( TQt::arrowCursor ) );
94 view()->repaintAll(
view()->part()->document().selection()->boundingBox() );
101 return i18n(
"Select" );
106 TQString s = i18n(
"<qt><b>Selection tool:</b><br>" );
107 s += i18n(
"<i>Select in current layer:</i><br>The selection is made in the layer selected in the layers docker.<br><br>" );
108 s += i18n(
"<i>Select in visible layers:</i><br>The selection is made in the visible layers (eye in the layers docker).<br><br>" );
109 s += i18n(
"<i>Select in selected layers:</i><br>The selection is made in the checked layers in the layers docker.<br><br>" );
110 s += i18n(
"<i>Position using arrow keys</i><br>The selection can be positioned up, down, left and right using the corresponding arrow keys." );
117 VPainter *painter =
view()->painterFactory()->editpainter();
119 painter->setRasterOp( TQt::NotROP );
123 if( m_state != normal )
125 VObjectListIterator itr = m_objects;
126 for( ; itr.current(); ++itr )
128 itr.current()->draw( painter, &itr.current()->boundingBox() );
131 else if( m_state == normal )
133 painter->setPen( TQt::DotLine );
135 painter->moveTo( KoPoint(
first().x(),
first().y() ) );
136 painter->lineTo( KoPoint( m_current.x(),
first().y() ) );
137 painter->lineTo( KoPoint( m_current.x(), m_current.y() ) );
138 painter->lineTo( KoPoint(
first().x(), m_current.y() ) );
139 painter->lineTo( KoPoint(
first().x(),
first().y() ) );
140 painter->strokePath();
149 if( m_state != normal || !
view() )
return;
150 switch(
view()->part()->document().selection()->handleNode(
last() ) )
154 view()->setCursor( TQCursor( TQt::SizeFDiagCursor ) );
158 view()->setCursor( TQCursor( TQt::SizeBDiagCursor ) );
162 view()->setCursor( TQCursor( TQt::SizeHorCursor ) );
166 view()->setCursor( TQCursor( TQt::SizeVerCursor ) );
169 view()->setCursor( TQCursor( TQt::arrowCursor ) );
184 if( m_activeNode != node_none )
186 else if( rect.contains( m_current ) && m_state == normal )
193 view()->repaintAll( rect );
211 view()->repaintAll(
view()->part()->document().selection()->boundingBox() );
236 VObjectList newSelection;
237 VSelectObjects selector( newSelection,
first() );
238 if( selector.visit(
view()->part()->document() ) )
242 view()->selectionChanged();
246 else if(
view()->part()->document().selection()->objects().count() > 0 )
248 view()->showSelectionPopupMenu( TQCursor::pos() );
261 VObjectList newSelection;
269 VSelectObjects selector( newSelection,
first(),
true,
true );
270 if( selector.visit(
view()->part()->document() ) )
273 VObject *lastMatched = 0L;
274 VObjectListIterator it( newSelection );
275 for( ; it.current(); ++it )
277 if( oldSelection.contains( it.current() ) )
278 lastMatched = it.current();
284 if( lastMatched && lastMatched != newSelection.first() )
285 view()->part()->document().
selection()->
append( newSelection.at( newSelection.find( lastMatched )-1 ) );
297 VObjectList newSelection;
298 VSelectObjects selector( newSelection,
first() );
299 if( selector.visit(
view()->part()->document() ) )
304 view()->selectionChanged();
312 if( m_state == normal )
315 KoPoint fp =
first();
320 KoRect selRect = KoRect( fp.x(), fp.y(), lp.x() - fp.x(), lp.y() - fp.y() ).normalize();
327 else if( m_state == moving )
334 &
view()->part()->document(),
335 abs(
int( m_distx ) ) >= abs(
int( m_disty ) ) ? tqRound( m_distx ) : 0,
336 abs(
int( m_distx ) ) <= abs(
int( m_disty ) ) ? tqRound( m_disty ) : 0,
altPressed() ),
340 new VTranslateCmd( &
view()->part()->document(), tqRound( m_distx ), tqRound( m_disty ),
altPressed() ),
343 else if( m_state == scaling )
347 new VScaleCmd( &
view()->part()->document(), m_sp, m_s1, m_s2,
altPressed() ),
352 view()->selectionChanged();
358VSelectTool::arrowKeyReleased( TQt::Key key )
364 case TQt::Key_Up: dy = 10;
break;
365 case TQt::Key_Down: dy = -10;
break;
366 case TQt::Key_Right: dx = 10;
break;
367 case TQt::Key_Left: dx = -10;
break;
373 &
view()->part()->document(),
376 view()->selectionChanged();
381VSelectTool::keyReleased( TQt::Key key )
384 VSelection* selection =
view()->part()->document().
selection();
391 uint handleSize = selection->handleSize();
393 selection->setHandleSize( ++handleSize );
394 else if( handleSize > 1 )
395 selection->setHandleSize( --handleSize );
398 default:
return false;
408VSelectTool::updateStatusBar()
const
413 if( !
view()->part() )
421 double x = KoUnit::toUserValue( rect.x(),
view()->part()->unit() );
422 double y = KoUnit::toUserValue( rect.y(),
view()->part()->unit() );
423 double r = KoUnit::toUserValue( rect.right(),
view()->part()->unit() );
424 double b = KoUnit::toUserValue( rect.bottom(),
view()->part()->unit() );
427 TQString selectMessage = i18n(
"[(left,bottom), (right,top)] (actual unit)",
"Selection [(%1, %2), (%3, %4)] (%5)").arg( x, 0,
'f', 1 ).arg( y, 0,
'f', 1 ).arg( r, 0,
'f', 1 ).arg( b, 0,
'f', 1 ).arg(
view()->part()->unitName() );
429 VSelectionDescription selectionDesc;
430 selectionDesc.
visit( *
view()->part()->document().selection() );
431 selectMessage += TQString(
"(%1)" ).arg( selectionDesc.description() );
433 view()->statusMessage()->setText( selectMessage );
436 view()->statusMessage()->setText( i18n(
"No selection" ) );
479 view()->repaintAll(
view()->part()->document().selection()->boundingBox() );
486 if( m_state == normal )
493 KoPoint _first =
view()->canvasWidget()->snapToGrid(
first() );
494 KoPoint _last =
view()->canvasWidget()->snapToGrid(
last() );
497 if( m_state == moving )
499 KoPoint p( rect.x() +
last().x() -
first().x(), rect.bottom() +
last().y() -
first().y() );
500 p =
view()->canvasWidget()->snapToGrid( p );
501 m_distx = p.x() - rect.x();
502 m_disty = p.y() - rect.bottom();
504 cmd =
new VTranslateCmd( 0L, abs(
int( m_distx ) ) >= abs(
int( m_disty ) ) ? m_distx : 0,
505 abs(
int( m_distx ) ) <= abs(
int( m_disty ) ) ? m_disty : 0 );
507 cmd =
new VTranslateCmd( 0L, m_distx, m_disty );
511 if( m_activeNode == node_lb )
513 m_sp = KoPoint( rect.right(), rect.bottom() );
514 m_s1 = ( rect.right() - _last.x() ) / double( rect.width() );
515 m_s2 = ( rect.bottom() - _last.y() ) / double( rect.height() );
517 else if( m_activeNode == node_mb )
519 m_sp = KoPoint( ( ( rect.right() + rect.left() ) / 2 ), rect.bottom() );
521 m_s2 = ( rect.bottom() - _last.y() ) / double( rect.height() );
523 else if( m_activeNode == node_rb )
525 m_sp = KoPoint( rect.x(), rect.bottom() );
526 m_s1 = ( _last.x() - rect.x() ) / double( rect.width() );
527 m_s2 = ( rect.bottom() - _last.y() ) / double( rect.height() );
529 else if( m_activeNode == node_rm)
531 m_sp = KoPoint( rect.x(), ( rect.bottom() + rect.top() ) / 2 );
532 m_s1 = ( _last.x() - rect.x() ) / double( rect.width() );
535 else if( m_activeNode == node_rt )
537 m_sp = KoPoint( rect.x(), rect.y() );
538 m_s1 = ( _last.x() - rect.x() ) / double( rect.width() );
539 m_s2 = ( _last.y() - rect.y() ) / double( rect.height() );
541 else if( m_activeNode == node_mt )
543 m_sp = KoPoint( ( ( rect.right() + rect.left() ) / 2 ), rect.y() );
545 m_s2 = ( _last.y() - rect.y() ) / double( rect.height() );
547 else if( m_activeNode == node_lt )
549 m_sp = KoPoint( rect.right(), rect.y() );
550 m_s1 = ( rect.right() - _last.x() ) / double( rect.width() );
551 m_s2 = ( _last.y() - rect.y() ) / double( rect.height() );
553 else if( m_activeNode == node_lm )
555 m_sp = KoPoint( rect.right(), ( rect.bottom() + rect.top() ) / 2 );
556 m_s1 = ( rect.right() - _last.x() ) / double( rect.width() );
561 m_s1 = m_s2 = kMax( m_s1, m_s2 );
562 cmd =
new VScaleCmd( 0L, m_sp, m_s1, m_s2 );
570 for( ; itr.current() ; ++itr )
574 copy = itr.current()->
clone();
579 m_objects.append( copy );
590 return m_optionsWidget->exec() == TQDialog::Accepted;
600VSelectTool::setup( TDEActionCollection *collection )
602 m_action =
static_cast<TDERadioAction *
>(collection ->
action( name() ) );
606 m_action =
new TDERadioAction( i18n(
"Select Tool" ),
"14_select", TQt::SHIFT+TQt::Key_H,
this, TQ_SLOT(
activate() ), collection, name() );
607 m_action->setToolTip( i18n(
"Select" ) );
608 m_action->setExclusiveGroup(
"select" );
613#include "vselecttool.moc"
Keeps track of visual per document properties.
void repaintAllViews(bool repaint=true)
repaint all views attached to this koDocument
void addCommand(VCommand *cmd, bool repaint=false)
insert a command into the undo/redo-history:
VSelection * selection() const
Returns a pointer to the selection.
VSelectionMode
The different selection modes.
VSelectionMode selectionMode()
Returns the selection mode.
virtual VObject * clone() const =0
Create an exact copy of this object.
virtual void setState(const VState state)
Sets the state to a specified new state.
@ selected
visible, active and can be manipulated by tools
@ deleted
deleted, nearly dead
@ edit
visible, active and is currently manipulated by a tool
const VObjectList & objects() const
Read only access to the selected objects.
void append()
Adds all objects to the selection.
void clear()
Removes the references to all objects, not the objects themselves.
virtual void setSelectObjects(bool selectObjects=true)
Toggles selection of objects/nodes.
void showHandle(bool handle=true)
Toggle selection handles on/off.
void selectNodes(bool select=true)
Selects or deselects all nodes.
virtual const KoRect & boundingBox() const
Calculates the tightest bounding box around the object.
void take(VObject &object)
Removes the reference to the object, not the object itself.
VHandleNode handleNode(const KoPoint &point) const
Returns the handle node id, the KoPoint is inside.
virtual bool visit(VObject &object)
General visit method.