1 // Copyright (C) 2013-2016 CEA/DEN, EDF R&D, OPEN CASCADE
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include "GraphicsView_ViewPort.h"
22 #include "GraphicsView_Object.h"
23 #include "GraphicsView_Scene.h"
24 #include "GraphicsView_ViewTransformer.h"
26 #include "SUIT_ResourceMgr.h"
27 #include "SUIT_Session.h"
30 #include <QGraphicsSceneMouseEvent>
31 #include <QGridLayout>
35 #include <QRubberBand>
42 #define FOREGROUND_Z_VALUE -2
43 #define GRID_Z_VALUE -1
44 #define SKETCH_Z_VALUE 3000
46 int GraphicsView_ViewPort::nCounter = 0;
47 QCursor* GraphicsView_ViewPort::defCursor = 0;
48 QCursor* GraphicsView_ViewPort::handCursor = 0;
49 QCursor* GraphicsView_ViewPort::panCursor = 0;
50 QCursor* GraphicsView_ViewPort::panglCursor = 0;
51 QCursor* GraphicsView_ViewPort::zoomCursor = 0;
52 QCursor* GraphicsView_ViewPort::sketchCursor = 0;
54 //=======================================================================
55 // Name : GraphicsView_ViewPort::ViewLabel
56 // Purpose : Wrapper for label, which can ignore move events sent from
57 // QGraphicsView::scrollContentsBy() method, which,
58 // in its turn, called from GraphicsView_ViewPort::pan()
59 //=======================================================================
60 class GraphicsView_ViewPort::ViewLabel : public QLabel
63 ViewLabel( QWidget* theParent )
64 : QLabel( theParent ),
65 myAcceptMoveEvents( false )
70 void setAcceptMoveEvents( bool theFlag )
72 myAcceptMoveEvents = theFlag;
76 virtual void moveEvent( QMoveEvent* theEvent )
78 if( myAcceptMoveEvents )
79 QLabel::moveEvent( theEvent );
80 else // return the label to the initial position
82 myAcceptMoveEvents = true;
83 move( theEvent->oldPos() );
84 myAcceptMoveEvents = false;
89 bool myAcceptMoveEvents;
92 //================================================================
93 // Function : createCursors
95 //================================================================
96 void GraphicsView_ViewPort::createCursors ()
98 defCursor = new QCursor( Qt::ArrowCursor );
99 handCursor = new QCursor( Qt::PointingHandCursor );
100 panCursor = new QCursor( Qt::SizeAllCursor );
101 panglCursor = new QCursor( Qt::CrossCursor );
103 SUIT_ResourceMgr* rmgr = SUIT_Session::session()->resourceMgr();
104 zoomCursor = new QCursor( rmgr->loadPixmap( "GraphicsView", tr( "ICON_GV_CURSOR_ZOOM" ) ) );
106 sketchCursor = new QCursor( Qt::CrossCursor );
109 //================================================================
110 // Function : destroyCursors
112 //================================================================
113 void GraphicsView_ViewPort::destroyCursors()
115 delete defCursor; defCursor = 0;
116 delete handCursor; handCursor = 0;
117 delete panCursor; panCursor = 0;
118 delete panglCursor; panglCursor = 0;
119 delete zoomCursor; zoomCursor = 0;
120 delete sketchCursor; sketchCursor = 0;
123 //=======================================================================
124 // Name : GraphicsView_ViewPort
125 // Purpose : Constructor
126 //=======================================================================
127 GraphicsView_ViewPort::GraphicsView_ViewPort( QWidget* theParent )
128 : QGraphicsView( theParent ),
129 myInteractionFlags( 0 ),
131 myViewLabelPosition( VLP_None ),
132 myViewLabelLayout( 0 ),
133 myIsMousePositionEnabled( false ),
134 myForegroundItem( 0 ),
136 myIsTransforming( false ),
137 myHighlightedObject( 0 ),
140 myIsHighlighting( false ),
141 mySelectionIterator( 0 ),
143 myAreSelectionPointsInitialized( false ),
144 mySketchingItem( 0 ),
145 myIsPrepareToSketch( false ),
146 myIsSketching( false ),
147 myIsSketchingByPath( false ),
148 myIsDragging( false ),
149 myIsDragPositionInitialized( false ),
150 myIsPulling( false ),
151 myPullingObject( 0 ),
152 myStoredCursor( Qt::ArrowCursor ),
156 myScene = new GraphicsView_Scene( this );
163 setInteractionFlags( EditFlags );
164 //setInteractionFlag( TraceBoundingRect );
165 //setInteractionFlag( DraggingByMiddleButton );
166 //setInteractionFlag( ImmediateContextMenu );
167 //setInteractionFlag( ImmediateSelection );
168 //setInteractionFlag( Sketching );
171 setBackgroundBrush( QBrush( Qt::white ) );
174 myIsForegroundEnabled = false;
175 myForegroundSize = QSizeF( 100, 30 );
176 myForegroundMargin = 0.0;
177 myForegroundColor = Qt::white;
178 myForegroundFrameColor = Qt::black;
179 myForegroundFrameLineWidth = 1.0;
182 myIsGridEnabled = false;
183 myGridCellSize = 100;
184 myGridLineStyle = Qt::DotLine;
185 myGridLineColor = Qt::darkGray;
187 // default index method (BspTreeIndex) leads to
188 // crashes in QGraphicsView::paintEvent() method
189 myScene->setItemIndexMethod( QGraphicsScene::NoIndex );
191 // render hints (default - TextAntialiasing only)
192 setRenderHints( QPainter::Antialiasing |
193 QPainter::TextAntialiasing |
194 QPainter::SmoothPixmapTransform |
195 QPainter::HighQualityAntialiasing );
197 connect( myScene, SIGNAL( gsKeyEvent( QKeyEvent* ) ),
198 this, SLOT( onKeyEvent( QKeyEvent* ) ) );
199 connect( myScene, SIGNAL( gsMouseEvent( QGraphicsSceneMouseEvent* ) ),
200 this, SLOT( onMouseEvent( QGraphicsSceneMouseEvent* ) ) );
201 connect( myScene, SIGNAL( gsWheelEvent( QGraphicsSceneWheelEvent* ) ),
202 this, SLOT( onWheelEvent( QGraphicsSceneWheelEvent* ) ) );
203 connect( myScene, SIGNAL( gsContextMenuEvent( QGraphicsSceneContextMenuEvent* ) ),
204 this, SLOT( onContextMenuEvent( QGraphicsSceneContextMenuEvent* ) ) );
206 connect( myScene, SIGNAL( gsBoundingRectChanged() ),
207 this, SLOT( onBoundingRectChanged() ) );
212 //=======================================================================
213 // Name : GraphicsView_ViewPort
214 // Purpose : Destructor
215 //=======================================================================
216 GraphicsView_ViewPort::~GraphicsView_ViewPort()
227 //================================================================
228 // Function : initialize
230 //================================================================
231 void GraphicsView_ViewPort::initialize()
233 if ( nCounter++ == 0 )
236 setMouseTracking( true );
237 setFocusPolicy( Qt::StrongFocus );
240 //================================================================
241 // Function : cleanup
243 //================================================================
244 void GraphicsView_ViewPort::cleanup()
246 if ( --nCounter == 0 )
250 //================================================================
251 // Function : addItem
253 //================================================================
254 void GraphicsView_ViewPort::addItem( QGraphicsItem* theItem )
256 if( GraphicsView_Object* anObject = dynamic_cast<GraphicsView_Object*>( theItem ) )
258 int aPriority = anObject->getPriority();
259 GraphicsView_ObjectList::iterator anIter, anIterEnd = myObjects.end();
260 for( anIter = myObjects.begin(); anIter != anIterEnd; anIter++ )
262 if( GraphicsView_Object* anObjectRef = *anIter )
264 if( anObjectRef->getPriority() > aPriority )
268 myObjects.insert( anIter, anObject );
269 anObject->setViewTransform( transform() );
270 anObject->addTo( this );
273 myScene->addItem( theItem );
274 onBoundingRectChanged();
277 //================================================================
278 // Function : isItemAdded
280 //================================================================
281 bool GraphicsView_ViewPort::isItemAdded( QGraphicsItem* theItem )
283 if( GraphicsView_Object* anObject = dynamic_cast<GraphicsView_Object*>( theItem ) )
285 for( GraphicsView_ObjectList::iterator anIter = myObjects.begin(); anIter != myObjects.end(); anIter++ )
286 if( theItem == *anIter )
290 for( int i = 0; i < myScene->items().size(); i++ )
291 if( theItem == myScene->items().at(i) )
297 //================================================================
298 // Function : removeItem
300 //================================================================
301 void GraphicsView_ViewPort::removeItem( QGraphicsItem* theItem )
303 if( GraphicsView_Object* anObject = dynamic_cast<GraphicsView_Object*>( theItem ) )
305 if( myHighlightedObject == anObject )
306 myHighlightedObject = 0;
307 mySelectedObjects.removeAll( anObject );
308 myObjects.removeAll( anObject );
309 anObject->removeFrom( this );
312 myScene->removeItem( theItem );
313 onBoundingRectChanged();
316 void GraphicsView_ViewPort::clearItems()
318 myHighlightedObject = 0;
319 mySelectedObjects.clear();
322 onBoundingRectChanged();
325 //================================================================
326 // Function : getObjects
328 //================================================================
329 GraphicsView_ObjectList GraphicsView_ViewPort::getObjects( SortType theSortType ) const
331 if( theSortType == SelectedFirst )
333 // to append selected objects after their non-selected siblings with similar priority
334 int aCurrentPriority = -1;
335 GraphicsView_ObjectList aSelectedObjects;
336 GraphicsView_ObjectList aTopmostObjects;
338 GraphicsView_ObjectList aList;
339 GraphicsView_ObjectListIterator anIter( myObjects );
340 while( anIter.hasNext() )
342 if( GraphicsView_Object* anObject = anIter.next() )
344 if( anObject->isOnTop() )
346 aTopmostObjects.append( anObject );
350 int aPriority = anObject->getPriority();
351 if( aPriority > aCurrentPriority )
353 if( !aSelectedObjects.isEmpty() )
355 aList.append( aSelectedObjects );
356 aSelectedObjects.clear();
358 aCurrentPriority = aPriority;
361 if( anObject->isSelected() )
362 aSelectedObjects.append( anObject );
364 aList.append( anObject );
368 // for selected objects with highest priority,
369 // which were not pushed to the result list yet
370 if( !aSelectedObjects.isEmpty() )
372 aList.append( aSelectedObjects );
373 aSelectedObjects.clear();
376 aList.append( aTopmostObjects );
381 if( theSortType == SortByZLevel ) // double loop, needs to be optimized
383 GraphicsView_ObjectList aList;
385 GraphicsView_ObjectListIterator anIter( myObjects );
386 while( anIter.hasNext() )
388 if( GraphicsView_Object* anObject = anIter.next() )
390 double aZValue = anObject->zValue();
391 GraphicsView_ObjectList::iterator anIter1, anIter1End = aList.end();
392 for( anIter1 = aList.begin(); anIter1 != anIter1End; anIter1++ )
393 if( GraphicsView_Object* anObjectRef = *anIter1 )
394 if( anObjectRef->zValue() > aZValue )
396 aList.insert( anIter1, anObject );
402 return myObjects; // theSortType == NoSorting
405 //================================================================
406 // Function : objectsBoundingRect
408 //================================================================
409 QRectF GraphicsView_ViewPort::objectsBoundingRect( bool theOnlyVisible ) const
412 QListIterator<QGraphicsItem*> anIter( items() );
413 while( anIter.hasNext() )
415 if( GraphicsView_Object* anObject = dynamic_cast<GraphicsView_Object*>( anIter.next() ) )
417 if( theOnlyVisible && !anObject->isVisible() )
420 QRectF anObjectRect = anObject->getRect();
421 if( !anObjectRect.isNull() )
424 aRect = anObject->getRect();
426 aRect |= anObject->getRect();
433 //================================================================
434 // Function : dumpView
436 //================================================================
437 QImage GraphicsView_ViewPort::dumpView( bool theWholeScene,
440 if( !theWholeScene ) // just grab the view contents
442 QPixmap aPixmap = QPixmap::grabWindow( viewport()->winId() );
443 return aPixmap.toImage();
446 // get a bounding rect of all presented objects
447 // (itemsBoundingRect() method is unsuitable)
448 QRectF aRect = objectsBoundingRect();
452 QRectF aTargetRect( 0, 0, aRect.width(), aRect.height() );
453 if( theSize.isValid() )
455 double aRatioX = theSize.width() / aTargetRect.width();
456 double aRatioY = theSize.height() / aTargetRect.height();
457 double aRatio = qMin( aRatioX, aRatioY );
458 aTargetRect.setWidth( aTargetRect.width() * aRatio );
459 aTargetRect.setHeight( aTargetRect.height() * aRatio );
462 // render the scene to an image
463 QImage anImage( aTargetRect.toRect().size(), QImage::Format_RGB32 );
464 QPainter aPainter( &anImage );
465 aPainter.setRenderHints( renderHints() );
467 myScene->render( &aPainter, aTargetRect, aRect );
472 bool GraphicsView_ViewPort::dumpViewToPSFormat(const QString& fileName)
474 QPrinter printer(QPrinter::ScreenResolution);
475 printer.setOutputFormat(QPrinter::PostScriptFormat);
476 printer.setOutputFileName(fileName);
478 if (!painter.begin(&printer))
481 QRect view( 0, 0, printer.pageRect().width(), printer.paperRect().height() );
482 QRectF bounds = myScene->itemsBoundingRect();
484 if( !view.isEmpty() && !bounds.isEmpty() )
486 float SCALE = 0.5;//qMin( view.width()/bounds.width(), view.height()/bounds.height() );
487 painter.setViewport( view );
488 painter.scale( SCALE, SCALE );
490 myScene->render( &painter, QRectF( view ), bounds );
497 //================================================================
498 // Function : setSceneGap
500 //================================================================
501 void GraphicsView_ViewPort::setSceneGap( double theSceneGap )
503 mySceneGap = theSceneGap;
504 onBoundingRectChanged();
507 //================================================================
508 // Function : setFitAllGap
510 //================================================================
511 void GraphicsView_ViewPort::setFitAllGap( double theFitAllGap )
513 myFitAllGap = theFitAllGap;
516 //================================================================
517 // Function : interactionFlags
519 //================================================================
520 int GraphicsView_ViewPort::interactionFlags() const
522 return myInteractionFlags;
525 //================================================================
526 // Function : hasInteractionFlag
528 //================================================================
529 bool GraphicsView_ViewPort::hasInteractionFlag( InteractionFlag theFlag )
531 return ( interactionFlags() & theFlag ) == theFlag;
534 //================================================================
535 // Function : setInteractionFlag
537 //================================================================
538 void GraphicsView_ViewPort::setInteractionFlag( InteractionFlag theFlag,
542 setInteractionFlags( myInteractionFlags | theFlag );
544 setInteractionFlags( myInteractionFlags & ~theFlag );
547 //================================================================
548 // Function : setInteractionFlags
550 //================================================================
551 void GraphicsView_ViewPort::setInteractionFlags( InteractionFlags theFlags )
553 myInteractionFlags = theFlags;
556 //================================================================
557 // Function : setViewLabelPosition
559 //================================================================
560 void GraphicsView_ViewPort::setViewLabelPosition( ViewLabelPosition thePosition,
563 if( theIsForced && !myViewLabel )
564 myViewLabel = new ViewLabel( viewport() );
569 if( thePosition == VLP_None )
571 myViewLabel->setVisible( false );
575 if( myViewLabelLayout )
576 delete myViewLabelLayout;
578 myViewLabelLayout = new QGridLayout( viewport() );
579 myViewLabelLayout->setMargin( 10 );
580 myViewLabelLayout->setSpacing( 0 );
582 int aRow = 0, aColumn = 0;
583 switch( thePosition )
585 case VLP_TopLeft: aRow = 0; aColumn = 0; break;
586 case VLP_TopRight: aRow = 0; aColumn = 1; break;
587 case VLP_BottomLeft: aRow = 1; aColumn = 0; break;
588 case VLP_BottomRight: aRow = 1; aColumn = 1; break;
592 myViewLabelLayout->addWidget( myViewLabel, aRow, aColumn );
593 myViewLabelLayout->setRowStretch( 1 - aRow, 1 );
594 myViewLabelLayout->setColumnStretch( 1 - aColumn, 1 );
596 myViewLabel->setVisible( true );
599 //================================================================
600 // Function : setViewLabelText
602 //================================================================
603 void GraphicsView_ViewPort::setViewLabelText( const QString& theText )
606 myViewLabel->setText( theText );
609 //================================================================
610 // Function : setMousePositionEnabled
612 //================================================================
613 void GraphicsView_ViewPort::setMousePositionEnabled( bool theState )
615 myIsMousePositionEnabled = theState;
619 setViewLabelPosition( VLP_BottomLeft, true );
621 int aMouseX = 0, aMouseY = 0;
622 setViewLabelText( QString( "(%1, %2)" ).arg( aMouseX ).arg( aMouseY ) );
625 setViewLabelPosition( VLP_None );
628 //================================================================
629 // Function : backgroundColor
631 //================================================================
632 QColor GraphicsView_ViewPort::backgroundColor() const
634 return backgroundBrush().color();
637 //================================================================
638 // Function : setBackgroundColor
640 //================================================================
641 void GraphicsView_ViewPort::setBackgroundColor( const QColor& theColor )
643 setBackgroundBrush( QBrush( theColor ) );
646 //================================================================
647 // Function : setForegroundEnabled
649 //================================================================
650 void GraphicsView_ViewPort::setForegroundEnabled( bool theState )
652 myIsForegroundEnabled = theState;
655 //================================================================
656 // Function : setForegroundSize
658 //================================================================
659 void GraphicsView_ViewPort::setForegroundSize( const QSizeF& theSize )
661 myForegroundSize = theSize;
664 //================================================================
665 // Function : setForegroundMargin
667 //================================================================
668 void GraphicsView_ViewPort::setForegroundMargin( double theMargin )
670 myForegroundMargin = theMargin;
673 //================================================================
674 // Function : setForegroundColor
676 //================================================================
677 void GraphicsView_ViewPort::setForegroundColor( const QColor& theColor )
679 myForegroundColor = theColor;
682 //================================================================
683 // Function : setForegroundFrameColor
685 //================================================================
686 void GraphicsView_ViewPort::setForegroundFrameColor( const QColor& theColor )
688 myForegroundFrameColor = theColor;
691 //================================================================
692 // Function : setForegroundFrameLineWidth
694 //================================================================
695 void GraphicsView_ViewPort::setForegroundFrameLineWidth( double theLineWidth )
697 myForegroundFrameLineWidth = theLineWidth;
700 //================================================================
701 // Function : updateForeground
703 //================================================================
704 void GraphicsView_ViewPort::updateForeground()
706 if( myIsForegroundEnabled )
708 if( !myForegroundItem )
709 myForegroundItem = myScene->addRect( QRectF(), QPen(), QBrush( Qt::white ) );
710 myForegroundItem->setZValue( FOREGROUND_Z_VALUE );
712 QPointF aPoint = QPointF();
713 QRectF aRect( aPoint, myForegroundSize );
714 aRect.adjust( -myForegroundMargin, -myForegroundMargin,
715 myForegroundMargin, myForegroundMargin );
716 myForegroundItem->setRect( aRect );
718 QBrush aBrush = myForegroundItem->brush();
719 aBrush.setColor( myForegroundColor );
720 myForegroundItem->setBrush( aBrush );
722 QPen aPen = myForegroundItem->pen();
723 aPen.setColor( myForegroundFrameColor );
724 aPen.setWidthF( myForegroundFrameLineWidth );
725 myForegroundItem->setPen( aPen );
727 myForegroundItem->setVisible( true );
729 myScene->setSceneRect( aRect.adjusted( -mySceneGap, -mySceneGap, mySceneGap, mySceneGap ) );
733 if( myForegroundItem )
734 myForegroundItem->setVisible( false );
737 updateGrid(); // foreground size could be changed
740 //================================================================
741 // Function : setGridEnabled
743 //================================================================
744 void GraphicsView_ViewPort::setGridEnabled( bool theState )
746 myIsGridEnabled = theState;
749 //================================================================
750 // Function : setGridCellSize
752 //================================================================
753 void GraphicsView_ViewPort::setGridCellSize( int theCellSize )
755 myGridCellSize = theCellSize;
758 //================================================================
759 // Function : setGridLineStyle
761 //================================================================
762 void GraphicsView_ViewPort::setGridLineStyle( int theLineStyle )
764 myGridLineStyle = theLineStyle;
767 //================================================================
768 // Function : setGridLineColor
770 //================================================================
771 void GraphicsView_ViewPort::setGridLineColor( const QColor& theLineColor )
773 myGridLineColor = theLineColor;
776 //================================================================
777 // Function : updateGrid
779 //================================================================
780 void GraphicsView_ViewPort::updateGrid()
782 if( myIsGridEnabled )
785 myGridItem = myScene->addPath( QPainterPath() );
786 myGridItem->setZValue( GRID_Z_VALUE );
788 double aWidth = myForegroundSize.width();
789 double aHeight = myForegroundSize.height();
791 int aGridNbX = int( aWidth / myGridCellSize ) + 1;
792 int aGridNbY = int( aHeight / myGridCellSize ) + 1;
796 for( anIndex = 0; anIndex < aGridNbX; anIndex++ )
798 double x = myGridCellSize * (double)anIndex;
799 aPath.moveTo( x, 0 );
800 aPath.lineTo( x, aHeight );
802 for( anIndex = 0; anIndex < aGridNbY; anIndex++ )
804 double y = myGridCellSize * (double)anIndex;
805 aPath.moveTo( 0, y );
806 aPath.lineTo( aWidth, y );
808 myGridItem->setPath( aPath );
810 QPen aPen = myGridItem->pen();
811 aPen.setStyle( (Qt::PenStyle)myGridLineStyle );
812 aPen.setColor( myGridLineColor );
813 myGridItem->setPen( aPen );
815 myGridItem->setVisible( true );
820 myGridItem->setVisible( false );
824 //================================================================
827 //================================================================
828 void GraphicsView_ViewPort::reset()
833 //================================================================
836 //================================================================
837 void GraphicsView_ViewPort::pan( double theDX, double theDY )
839 myIsTransforming = true;
842 myViewLabel->setAcceptMoveEvents( false );
844 if( QScrollBar* aHBar = horizontalScrollBar() )
845 aHBar->setValue( aHBar->value() - theDX );
846 if( QScrollBar* aVBar = verticalScrollBar() )
847 aVBar->setValue( aVBar->value() + theDY );
850 myViewLabel->setAcceptMoveEvents( true );
852 myIsTransforming = false;
857 //================================================================
858 // Function : setCenter
860 //================================================================
861 void GraphicsView_ViewPort::setCenter( double theX, double theY )
863 myIsTransforming = true;
865 setTransform( myCurrentTransform );
866 centerOn( theX, theY );
868 myIsTransforming = false;
873 //================================================================
876 //================================================================
877 void GraphicsView_ViewPort::zoom( double theX1, double theY1, double theX2, double theY2 )
879 myIsTransforming = true;
881 double aDX = theX2 - theX1;
882 double aDY = theY2 - theY1;
883 double aZoom = sqrt( aDX * aDX + aDY * aDY ) / 100 + 1;
884 aZoom = ( aDX > 0 ) ? aZoom : 1 / aZoom;
886 QTransform aTransform = transform();
887 aTransform.scale( aZoom, aZoom );
888 double aM11 = aTransform.m11();
889 double aM22 = aTransform.m22();
890 // increasing of diagonal coefficients (>300) leads to a crash sometimes
891 // at the values of 100 some primitives are drawn incorrectly
892 if( myZoomCoeff < 0 || qMax( aM11, aM22 ) < myZoomCoeff )
893 setTransform( aTransform );
895 myIsTransforming = false;
900 //================================================================
901 // Function : fitRect
903 //================================================================
904 void GraphicsView_ViewPort::fitRect( const QRectF& theRect )
906 myIsTransforming = true;
908 fitInView( theRect, Qt::KeepAspectRatio );
910 myIsTransforming = false;
915 //================================================================
916 // Function : fitSelect
918 //================================================================
919 void GraphicsView_ViewPort::fitSelect()
921 myIsTransforming = true;
924 for( initSelected(); moreSelected(); nextSelected() )
926 if( GraphicsView_Object* aMovingObject = selectedObject() )
928 QRectF aRect = aMovingObject->getRect();
929 if( aGlobalRect.isNull() )
932 aGlobalRect |= aRect;
936 if( !aGlobalRect.isNull() )
938 double aGap = qMax( aGlobalRect.width(), aGlobalRect.height() ) / 5;
939 aGlobalRect.adjust( -aGap, -aGap, aGap, aGap );
940 fitInView( aGlobalRect, Qt::KeepAspectRatio );
943 myIsTransforming = false;
948 //================================================================
951 //================================================================
952 void GraphicsView_ViewPort::fitAll( bool theKeepScale )
954 myIsTransforming = true;
957 myCurrentTransform = transform();
959 double aGap = myFitAllGap;
960 QRectF aRect = objectsBoundingRect( true );
961 fitInView( aRect.adjusted( -aGap, -aGap, aGap, aGap ), Qt::KeepAspectRatio );
963 myIsTransforming = false;
968 //================================================================
969 // Function : fitWidth
971 //================================================================
972 void GraphicsView_ViewPort::fitWidth()
974 myIsTransforming = true;
976 double aGap = myFitAllGap;
977 QRectF aRect = objectsBoundingRect( true );
979 double aTop = aRect.top();
980 double aLeft = aRect.left();
983 aRect.setY( aRect.center().y() );
984 aRect.setHeight( aMargin );
986 fitInView( aRect.adjusted( -aGap, -aGap, aGap, aGap ), Qt::KeepAspectRatio );
987 ensureVisible( aLeft, aTop, aMargin, aMargin, 0, aGap );
989 myIsTransforming = false;
994 //================================================================
995 // Function : applyTransform
997 //================================================================
998 void GraphicsView_ViewPort::applyTransform()
1000 GraphicsView_ObjectListIterator anIter( getObjects() );
1001 while( anIter.hasNext() )
1002 if( GraphicsView_Object* anObject = anIter.next() )
1003 anObject->setViewTransform( transform() );
1006 //================================================================
1007 // Function : setZoomCoeff
1009 //================================================================
1010 void GraphicsView_ViewPort::setZoomCoeff( const int& theZoomCoeff )
1012 myZoomCoeff = theZoomCoeff;
1015 //================================================================
1016 // Function : currentBlock
1018 //================================================================
1019 GraphicsView_ViewPort::BlockStatus GraphicsView_ViewPort::currentBlock()
1021 if( isDragging() && !myDragPosition.isNull() )
1022 return BlockStatus( BS_Selection );
1024 if( myAreSelectionPointsInitialized && ( myFirstSelectionPoint != myLastSelectionPoint ) )
1025 return BlockStatus( BS_Selection );
1028 return BlockStatus( BS_Selection );
1033 //================================================================
1034 // Function : highlight
1036 //================================================================
1037 void GraphicsView_ViewPort::highlight( double theX, double theY )
1039 myIsHighlighting = true;
1040 myHighlightX = theX;
1041 myHighlightY = theY;
1043 bool anIsHighlighted = false;
1044 bool anIsOnObject = false;
1046 GraphicsView_Object* aPreviousHighlightedObject = myHighlightedObject;
1047 GraphicsView_Object* aHighlightedObject = 0;
1051 GraphicsView_ObjectList aList = getObjects( SortByZLevel );
1052 GraphicsView_ObjectListIterator anIter( aList );
1053 anIter.toBack(); // objects with higher priority have to be checked earlier
1054 while( anIter.hasPrevious() )
1056 if( GraphicsView_Object* anObject = anIter.previous() )
1058 if( anObject->isVisible() && anObject->isSelectable() )
1060 if( anObject->checkHighlight( theX, theY, aCursor ) )
1062 anIsOnObject = true;
1063 anIsHighlighted = anObject->highlight( theX, theY );
1066 if( anIsHighlighted )
1068 aHighlightedObject = anObject;
1075 setCursor( aCursor );
1080 while( anIter.hasNext() )
1081 if( GraphicsView_Object* anObject = anIter.next() )
1082 anObject->unhighlight();
1084 myHighlightedObject = 0;
1087 else if( !myHighlightedObject && anIsHighlighted )
1089 myHighlightedObject = aHighlightedObject;
1091 else if( myHighlightedObject && !anIsHighlighted )
1093 myHighlightedObject->unhighlight();
1094 myHighlightedObject = 0;
1096 else if( myHighlightedObject && anIsHighlighted )
1098 myHighlightedObject->highlight( theX, theY );
1099 if( myHighlightedObject != aHighlightedObject )
1101 myHighlightedObject->unhighlight();
1102 myHighlightedObject = aHighlightedObject;
1107 //================================================================
1108 // Function : clearHighlighted
1110 //================================================================
1111 void GraphicsView_ViewPort::clearHighlighted()
1113 if( myHighlightedObject )
1115 myHighlightedObject->unhighlight();
1116 myHighlightedObject = 0;
1120 //================================================================
1121 // Function : select
1123 //================================================================
1124 int GraphicsView_ViewPort::select( const QRectF& theRect, bool theIsAppend )
1126 if( !myIsHighlighting )
1127 return GVSS_NoChanged;
1129 GV_SelectionStatus aStatus = GVSS_Invalid;
1130 if( theRect.isNull() ) // point selection
1132 if( myHighlightedObject )
1134 if( mySelectedObjects.count() == 1 &&
1135 mySelectedObjects.first() == myHighlightedObject )
1136 aStatus = GVSS_LocalChanged;
1140 GraphicsView_ObjectListIterator anIter( mySelectedObjects );
1141 while( anIter.hasNext() )
1142 if( GraphicsView_Object* anObject = anIter.next() )
1143 if( myHighlightedObject != anObject )
1144 anObject->unselect();
1146 if( !mySelectedObjects.isEmpty() && aStatus == GVSS_Invalid )
1147 aStatus = GVSS_GlobalChanged;
1148 mySelectedObjects.clear();
1150 else if( myHighlightedObject->isSelected() && aStatus != GVSS_LocalChanged )
1152 mySelectedObjects.removeAll( myHighlightedObject );
1153 myHighlightedObject->unselect();
1155 if( !mySelectedObjects.isEmpty() && aStatus == GVSS_Invalid )
1156 aStatus = GVSS_GlobalChanged;
1161 if( myHighlightedObject->select( myHighlightX, myHighlightY, QRectF() ) &&
1162 mySelectedObjects.indexOf( myHighlightedObject ) == -1 )
1164 mySelectedObjects.append( myHighlightedObject );
1165 if( aStatus == GVSS_Invalid )
1166 aStatus = GVSS_GlobalChanged;
1168 else if( aStatus == GVSS_LocalChanged )
1169 aStatus = GVSS_GlobalChanged;
1174 if( !myHighlightedObject )
1178 GraphicsView_ObjectListIterator anIter( mySelectedObjects );
1179 while( anIter.hasNext() )
1180 if( GraphicsView_Object* anObject = anIter.next() )
1181 if( myHighlightedObject != anObject )
1182 anObject->unselect();
1184 if( !mySelectedObjects.isEmpty() )
1185 aStatus = GVSS_GlobalChanged;
1186 mySelectedObjects.clear();
1191 return GVSS_NoChanged;
1193 else // rectangle selection
1195 aStatus = GVSS_NoChanged;
1197 bool updateAll = false;
1200 if( !mySelectedObjects.isEmpty() )
1201 aStatus = GVSS_GlobalChanged;
1203 GraphicsView_ObjectListIterator anIter( mySelectedObjects );
1204 while( anIter.hasNext() )
1205 if( GraphicsView_Object* anObject = anIter.next() )
1206 if( myHighlightedObject != anObject )
1207 anObject->unselect();
1208 mySelectedObjects.clear();
1211 QListIterator<QGraphicsItem*> anIter( items() );
1212 while( anIter.hasNext() )
1214 if( GraphicsView_Object* anObject = dynamic_cast<GraphicsView_Object*>( anIter.next() ) )
1216 if( anObject->isVisible() && anObject->isSelectable() )
1218 bool anIsSelected = false;
1219 QRectF aRect = anObject->getRect();
1220 if( theRect.contains( aRect ) && myIsHighlighting )
1221 anIsSelected = anObject->select( myHighlightX, myHighlightY, theRect );
1223 if( anIsSelected && mySelectedObjects.indexOf( anObject ) == -1 )
1225 mySelectedObjects.append( anObject );
1226 aStatus = GVSS_GlobalChanged;
1235 //================================================================
1236 // Function : clearSelected
1238 //================================================================
1239 void GraphicsView_ViewPort::clearSelected()
1241 GraphicsView_ObjectListIterator anIter( mySelectedObjects );
1242 while( anIter.hasNext() )
1243 if( GraphicsView_Object* anObject = anIter.next() )
1244 anObject->unselect();
1245 mySelectedObjects.clear();
1248 //================================================================
1249 // Function : setSelected
1251 //================================================================
1252 void GraphicsView_ViewPort::setSelected( GraphicsView_Object* theObject )
1256 theObject->setSelected( true );
1257 mySelectedObjects.append( theObject );
1261 //================================================================
1262 // Function : nbSelected
1264 //================================================================
1265 int GraphicsView_ViewPort::nbSelected() const
1267 return mySelectedObjects.count();
1270 //================================================================
1271 // Function : initSelected
1273 //================================================================
1274 void GraphicsView_ViewPort::initSelected()
1276 mySelectionIterator = 0;
1279 //================================================================
1280 // Function : moreSelected
1282 //================================================================
1283 bool GraphicsView_ViewPort::moreSelected()
1285 return mySelectionIterator < nbSelected();
1288 //================================================================
1289 // Function : nextSelected
1291 //================================================================
1292 bool GraphicsView_ViewPort::nextSelected()
1294 if( mySelectionIterator >= 0 && mySelectionIterator < nbSelected() )
1296 mySelectionIterator++;
1302 //================================================================
1303 // Function : selectedObject
1305 //================================================================
1306 GraphicsView_Object* GraphicsView_ViewPort::selectedObject()
1308 if( mySelectionIterator >= 0 && mySelectionIterator < nbSelected() )
1309 return mySelectedObjects[ mySelectionIterator ];
1313 //================================================================
1314 // Function : startSelectByRect
1316 //================================================================
1317 void GraphicsView_ViewPort::startSelectByRect( int x, int y )
1319 if( !myAreSelectionPointsInitialized )
1321 myFirstSelectionPoint = QPoint( x, y );
1322 myLastSelectionPoint = QPoint( x, y );
1323 myAreSelectionPointsInitialized = true;
1328 myRectBand = new QRubberBand( QRubberBand::Rectangle, this );
1330 palette.setColor( myRectBand->foregroundRole(), Qt::white );
1331 myRectBand->setPalette( palette );
1336 //================================================================
1337 // Function : drawSelectByRect
1339 //================================================================
1340 void GraphicsView_ViewPort::drawSelectByRect( int x, int y )
1342 if( myAreSelectionPointsInitialized )
1346 myLastSelectionPoint.setX( x );
1347 myLastSelectionPoint.setY( y );
1349 QRect aRect = selectionRect();
1350 myRectBand->setGeometry( aRect );
1351 myRectBand->setVisible( aRect.isValid() );
1355 //================================================================
1356 // Function : isSelectByRect
1358 //================================================================
1359 bool GraphicsView_ViewPort::isSelectByRect() const
1361 return myAreSelectionPointsInitialized;
1364 //================================================================
1365 // Function : finishSelectByRect
1367 //================================================================
1368 void GraphicsView_ViewPort::finishSelectByRect()
1370 if( myAreSelectionPointsInitialized )
1379 myAreSelectionPointsInitialized = false;
1383 //================================================================
1384 // Function : selectionRect
1386 //================================================================
1387 QRect GraphicsView_ViewPort::selectionRect()
1390 if( myAreSelectionPointsInitialized )
1392 aRect.setLeft( qMin( myFirstSelectionPoint.x(), myLastSelectionPoint.x() ) );
1393 aRect.setTop( qMin( myFirstSelectionPoint.y(), myLastSelectionPoint.y() ) );
1394 aRect.setRight( qMax( myFirstSelectionPoint.x(), myLastSelectionPoint.x() ) );
1395 aRect.setBottom( qMax( myFirstSelectionPoint.y(), myLastSelectionPoint.y() ) );
1400 //================================================================
1401 // Function : prepareToSketch
1403 //================================================================
1404 void GraphicsView_ViewPort::prepareToSketch( bool theStatus )
1406 myIsPrepareToSketch = theStatus;
1408 setCursor( *getSketchCursor() );
1411 //================================================================
1412 // Function : isPrepareToSketch
1414 //================================================================
1415 bool GraphicsView_ViewPort::isPrepareToSketch()
1417 return myIsPrepareToSketch;
1420 //================================================================
1421 // Function : startSketching
1423 //================================================================
1424 void GraphicsView_ViewPort::startSketching( const QPointF& thePoint,
1427 prepareToSketch( false );
1429 if( !mySketchingItem )
1431 mySketchingItem = new QGraphicsPathItem();
1432 mySketchingItem->setZValue( SKETCH_Z_VALUE );
1434 QPen aPen = mySketchingItem->pen();
1435 aPen.setStyle( Qt::DotLine );
1436 mySketchingItem->setPen( aPen );
1438 addItem( mySketchingItem );
1441 mySketchingPoint = thePoint;
1444 aPath.moveTo( mySketchingPoint );
1445 mySketchingItem->setPath( aPath );
1446 mySketchingItem->setVisible( true );
1448 myIsSketching = true;
1449 myIsSketchingByPath = theIsPath;
1452 //================================================================
1453 // Function : drawSketching
1455 //================================================================
1456 void GraphicsView_ViewPort::drawSketching( const QPointF& thePoint )
1458 bool anIsPath = false;
1459 if( mySketchingItem && isSketching( &anIsPath ) )
1461 QPainterPath aPath = mySketchingItem->path();
1462 if( anIsPath ) // arbitrary path
1463 aPath.lineTo( thePoint );
1466 // make a valid rectangle
1467 double x1 = mySketchingPoint.x(), y1 = mySketchingPoint.y();
1468 double x2 = thePoint.x(), y2 = thePoint.y();
1469 QPointF aPoint1( qMin( x1, x2 ), qMin( y1, y2 ) );
1470 QPointF aPoint2( qMax( x1, x2 ), qMax( y1, y2 ) );
1471 QRectF aRect( aPoint1, aPoint2 );
1473 aPath = QPainterPath();
1474 aPath.addRect( aRect );
1476 mySketchingItem->setPath( aPath );
1480 //================================================================
1481 // Function : finishSketching
1483 //================================================================
1484 void GraphicsView_ViewPort::finishSketching( bool theStatus )
1486 prepareToSketch( false );
1488 mySketchingItem->setVisible( false );
1489 myIsSketching = false;
1491 setCursor( *getDefaultCursor() );
1495 QPainterPath aPath = mySketchingItem->path();
1496 emit vpSketchingFinished( aPath );
1500 //================================================================
1501 // Function : isSketching
1503 //================================================================
1504 bool GraphicsView_ViewPort::isSketching( bool* theIsPath ) const
1507 *theIsPath = myIsSketchingByPath;
1508 return myIsSketching;
1511 //================================================================
1512 // Function : dragObjects
1514 //================================================================
1515 void GraphicsView_ViewPort::dragObjects( QGraphicsSceneMouseEvent* e )
1517 GraphicsView_Object* anObject = getHighlightedObject();
1519 if( myDragPosition.isNull() )
1521 myDragPosition = e->scenePos();
1525 GraphicsView_ObjectList anObjectsToMove;
1526 if( anObject && anObject->isMovable() && ( e->buttons() & Qt::LeftButton ) )
1528 if( anObject->isSelected() )
1530 for( initSelected(); moreSelected(); nextSelected() )
1531 if( GraphicsView_Object* aMovingObject = selectedObject() )
1532 if( aMovingObject->isMovable() )
1533 anObjectsToMove.append( aMovingObject );
1536 anObjectsToMove.append( anObject );
1538 else if( hasInteractionFlag( DraggingByMiddleButton ) &&
1539 nbSelected() && ( e->buttons() & Qt::MidButton ) )
1541 for( initSelected(); moreSelected(); nextSelected() )
1542 if( GraphicsView_Object* aMovingObject = selectedObject() )
1543 if( aMovingObject->isMovable() )
1544 anObjectsToMove.append( aMovingObject );
1547 if( anObjectsToMove.isEmpty() )
1550 double aDX = e->scenePos().x() - myDragPosition.x();
1551 double aDY = e->scenePos().y() - myDragPosition.y();
1553 bool anIsMovingByXAllowed = true, anIsMovingByYAllowed = true;
1554 GraphicsView_ObjectListIterator anIter( anObjectsToMove );
1555 while( anIter.hasNext() )
1556 if( GraphicsView_Object* aMovingObject = anIter.next() )
1558 if( !aMovingObject->isMovingByXAllowed( aDX ) )
1559 anIsMovingByXAllowed = false;
1560 if( !aMovingObject->isMovingByYAllowed( aDY ) )
1561 anIsMovingByYAllowed = false;
1564 if( !anIsMovingByXAllowed && !anIsMovingByYAllowed )
1565 return; // myDragPosition shouldn't be changed
1567 if( !anIsMovingByXAllowed )
1570 if( !anIsMovingByYAllowed )
1573 anIter = anObjectsToMove;
1574 while( anIter.hasNext() )
1575 if( GraphicsView_Object* aMovingObject = anIter.next() )
1576 aMovingObject->move( aDX, aDY );
1578 if( anIsMovingByXAllowed )
1579 myDragPosition.setX( e->scenePos().x() );
1581 if( anIsMovingByYAllowed )
1582 myDragPosition.setY( e->scenePos().y() );
1585 //================================================================
1586 // Function : startPulling
1588 //================================================================
1589 bool GraphicsView_ViewPort::startPulling( const QPointF& thePoint )
1591 QListIterator<QGraphicsItem*> anIter( items() );
1592 while( anIter.hasNext() )
1594 if( GraphicsView_Object* anObject = dynamic_cast<GraphicsView_Object*>( anIter.next() ) )
1596 QRectF aRect = anObject->getPullingRect();
1597 if( aRect.contains( thePoint ) && anObject->startPulling( thePoint ) )
1600 myPullingObject = anObject;
1601 //setCursor( *getHandCursor() ); // testing ImageViewer
1609 //================================================================
1610 // Function : drawPulling
1612 //================================================================
1613 void GraphicsView_ViewPort::drawPulling( const QPointF& thePoint )
1615 GraphicsView_Object* aLockedObject = 0;
1617 QListIterator<QGraphicsItem*> anIter( items() );
1618 while( anIter.hasNext() )
1620 if( GraphicsView_Object* anObject = dynamic_cast<GraphicsView_Object*>( anIter.next() ) )
1622 if( !anObject->isVisible() )
1625 QRectF aRect = anObject->getPullingRect();
1626 if( aRect.contains( thePoint ) && anObject->portContains( thePoint ) )
1628 aLockedObject = anObject;
1634 myPullingObject->pull( thePoint, aLockedObject, getSelectedObjects() );
1637 //================================================================
1638 // Function : finishPulling
1640 //================================================================
1641 void GraphicsView_ViewPort::finishPulling( bool theStatus )
1643 myIsPulling = false;
1644 myPullingObject->finishPulling( theStatus, getSelectedObjects() );
1645 setCursor( *getDefaultCursor() );
1648 //================================================================
1649 // Function : cancelCurrentOperation
1651 //================================================================
1652 bool GraphicsView_ViewPort::cancelCurrentOperation()
1654 myIsHighlighting = false;
1658 for( initSelected(); moreSelected(); nextSelected() )
1659 if( GraphicsView_Object* aMovingObject = selectedObject() )
1660 aMovingObject->finishMove( false );
1662 if( GraphicsView_Object* aMovingObject = getHighlightedObject() )
1663 aMovingObject->finishMove( false );
1665 myIsDragging = false;
1666 myDragPosition = QPointF();
1667 //setCursor( myStoredCursor );
1668 setCursor( *getDefaultCursor() );
1675 finishPulling( false );
1679 if( isSketching() || isPrepareToSketch() )
1681 finishSketching( false );
1688 //================================================================
1689 // Function : onBoundingRectChanged
1691 //================================================================
1692 void GraphicsView_ViewPort::onBoundingRectChanged()
1694 if( hasInteractionFlag( TraceBoundingRect ) )
1696 QRectF aRect = objectsBoundingRect( true );
1697 myScene->setSceneRect( aRect.adjusted( -mySceneGap, -mySceneGap, mySceneGap, mySceneGap ) );
1701 //================================================================
1702 // Function : onKeyEvent
1704 //================================================================
1705 void GraphicsView_ViewPort::onKeyEvent( QKeyEvent* e )
1707 emit vpKeyEvent( e );
1710 //================================================================
1711 // Function : onMouseEvent
1713 //================================================================
1714 void GraphicsView_ViewPort::onMouseEvent( QGraphicsSceneMouseEvent* e )
1716 emit vpMouseEvent( e );
1718 bool anIsHandled = false;
1721 case QEvent::GraphicsSceneMousePress:
1723 if( hasInteractionFlag( EditFlags ) && nbSelected() )
1724 for( initSelected(); moreSelected() && !anIsHandled; nextSelected() )
1725 if( GraphicsView_Object* anObject = selectedObject() )
1726 anIsHandled = anObject->handleMousePress( e );
1728 if( !anIsHandled && hasInteractionFlag( Dragging ) )
1730 bool anAccel = e->modifiers() & GraphicsView_ViewTransformer::accelKey();
1731 if( ( getHighlightedObject() &&
1732 getHighlightedObject()->isMovable() &&
1733 !( anAccel || e->button() != Qt::LeftButton ) ) ||
1734 ( hasInteractionFlag( DraggingByMiddleButton ) &&
1735 nbSelected() && !anAccel && e->button() == Qt::MidButton ) )
1737 myIsDragging = true;
1738 myStoredCursor = cursor();
1739 setCursor( Qt::ClosedHandCursor );
1744 case QEvent::GraphicsSceneMouseMove:
1746 if( hasInteractionFlag( EditFlags ) && nbSelected() )
1747 for( initSelected(); moreSelected() && !anIsHandled; nextSelected() )
1748 if( GraphicsView_Object* anObject = selectedObject() )
1749 anIsHandled = anObject->handleMouseMove( e );
1751 if( !anIsHandled && !isPulling() && myIsDragging )
1755 case QEvent::GraphicsSceneMouseRelease:
1757 if( hasInteractionFlag( EditFlags ) && nbSelected() )
1758 for( initSelected(); moreSelected() && !anIsHandled; nextSelected() )
1759 if( GraphicsView_Object* anObject = selectedObject() )
1760 anIsHandled = anObject->handleMouseRelease( e );
1762 if( !anIsHandled && !isPulling() && myIsDragging )
1764 emit vpObjectBeforeMoving();
1766 bool anIsMoved = false;
1767 for( initSelected(); moreSelected(); nextSelected() )
1768 if( GraphicsView_Object* aMovingObject = selectedObject() )
1769 anIsMoved = aMovingObject->finishMove( true ) || anIsMoved;
1771 if( GraphicsView_Object* aMovingObject = getHighlightedObject() )
1772 anIsMoved = aMovingObject->finishMove( true ) || anIsMoved;
1774 myIsDragging = false;
1775 myDragPosition = QPointF();
1776 setCursor( myStoredCursor );
1778 emit vpObjectAfterMoving( anIsMoved );
1782 case QEvent::GraphicsSceneMouseDoubleClick:
1783 break; // do nothing, just emit the signal
1788 if( myIsMousePositionEnabled )
1790 int aMouseX = (int)e->scenePos().x();
1791 int aMouseY = (int)e->scenePos().y();
1792 setViewLabelText( QString( "(%1, %2)" ).arg( aMouseX ).arg( aMouseY ) );
1796 //================================================================
1797 // Function : onWheelEvent
1799 //================================================================
1800 void GraphicsView_ViewPort::onWheelEvent( QGraphicsSceneWheelEvent* e )
1802 emit vpWheelEvent( e );
1805 //================================================================
1806 // Function : onContextMenuEvent
1808 //================================================================
1809 void GraphicsView_ViewPort::onContextMenuEvent( QGraphicsSceneContextMenuEvent* e )
1811 emit vpContextMenuEvent( e );
1814 //================================================================
1815 // Function : scrollContentsBy
1817 //================================================================
1818 void GraphicsView_ViewPort::scrollContentsBy( int theDX, int theDY )
1821 myViewLabel->setAcceptMoveEvents( false );
1823 QGraphicsView::scrollContentsBy( theDX, theDY );
1826 myViewLabel->setAcceptMoveEvents( true );