00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "KoContainerHandler.h"
00021 #include <KoView.h>
00022 #include <math.h>
00023 #include <kcursor.h>
00024 #include <kdebug.h>
00025
00026 KoEventHandler::KoEventHandler( QObject* target )
00027 {
00028 m_target = target;
00029
00030 m_target->installEventFilter( this );
00031 }
00032
00033 KoEventHandler::~KoEventHandler()
00034 {
00035 }
00036
00037 QObject* KoEventHandler::target()
00038 {
00039 return m_target;
00040 }
00041
00042
00043
00044 class KoPartResizeHandlerPrivate {
00045 public:
00046 KoPartResizeHandlerPrivate( const QWMatrix& matrix, KoView *view, KoChild* child,
00047 KoChild::Gadget gadget, const QPoint& point ) :
00048 m_gadget(gadget), m_view(view), m_child(child), m_parentMatrix(matrix) {
00049
00050 m_geometryStart = child->geometry();
00051 m_matrix = child->matrix() * matrix;
00052 m_invertParentMatrix = matrix.invert();
00053
00054 bool ok = true;
00055 m_invert = m_matrix.invert( &ok );
00056 Q_ASSERT( ok );
00057 m_mouseStart = m_invert.map( m_invertParentMatrix.map( point ) );
00058 }
00059 ~KoPartResizeHandlerPrivate() {}
00060
00061 KoChild::Gadget m_gadget;
00062 QPoint m_mouseStart;
00063 QRect m_geometryStart;
00064 KoView* m_view;
00065 KoChild* m_child;
00066 QWMatrix m_invert;
00067 QWMatrix m_matrix;
00068 QWMatrix m_parentMatrix;
00069 QWMatrix m_invertParentMatrix;
00070 };
00071
00072 KoPartResizeHandler::KoPartResizeHandler( QWidget* widget, const QWMatrix& matrix, KoView* view, KoChild* child,
00073 KoChild::Gadget gadget, const QPoint& point )
00074 : KoEventHandler( widget )
00075 {
00076 child->lock();
00077 d=new KoPartResizeHandlerPrivate(matrix, view, child, gadget, point);
00078 }
00079
00080 KoPartResizeHandler::~KoPartResizeHandler()
00081 {
00082 d->m_child->unlock();
00083 delete d;
00084 d=0L;
00085 }
00086
00087 void KoPartResizeHandler::repaint(QRegion &rgn)
00088 {
00089 rgn = rgn.unite( d->m_child->frameRegion( d->m_parentMatrix, true ) );
00090
00091 ((QWidget*)target())->repaint( rgn );
00092 }
00093
00094 bool KoPartResizeHandler::eventFilter( QObject*, QEvent* ev )
00095 {
00096 if ( ev->type() == QEvent::MouseButtonRelease )
00097 {
00098 delete this;
00099 return true;
00100 }
00101 else if ( ev->type() == QEvent::MouseMove )
00102 {
00103 QMouseEvent* e = (QMouseEvent*)ev;
00104 QPoint p = d->m_invert.map( d->m_invertParentMatrix.map( e->pos() ) );
00105 QRegion rgn( d->m_child->frameRegion( d->m_parentMatrix, true ) );
00106
00107 double x1_x, x1_y, x2_x, x2_y;
00108 d->m_matrix.map( double( p.x() ), 0.0, &x1_x, &x1_y );
00109 d->m_matrix.map( double( d->m_mouseStart.x() ), 0.0, &x2_x, &x2_y );
00110 double y1_x, y1_y, y2_x, y2_y;
00111 d->m_matrix.map( 0.0, double( p.y() ), &y1_x, &y1_y );
00112 d->m_matrix.map( 0.0, double( d->m_mouseStart.y() ), &y2_x, &y2_y );
00113
00114 double dx = x2_x - x1_x;
00115 double dy = x2_y - x1_y;
00116 int x = int( sqrt( dx * dx + dy * dy ) * ( d->m_mouseStart.x() < p.x() ? 1.0 : -1.0 ) );
00117
00118 dx = y2_x - y1_x;
00119 dy = y2_y - y1_y;
00120 int y = int( sqrt( dx * dx + dy * dy ) * ( d->m_mouseStart.y() < p.y() ? 1.0 : -1.0 ) );
00121
00122 switch( d->m_gadget )
00123 {
00124 case KoChild::TopLeft:
00125 {
00126 x = QMIN( d->m_geometryStart.width() - 1, x );
00127 y = QMIN( d->m_geometryStart.height() - 1, y );
00128
00129 d->m_child->setGeometry( QRect( d->m_geometryStart.x() + x, d->m_geometryStart.y() + y,
00130 d->m_geometryStart.width() - x, d->m_geometryStart.height() - y ) );
00131 repaint(rgn);
00132 }
00133 break;
00134 case KoChild::TopMid:
00135 {
00136 y = QMIN( d->m_geometryStart.height() - 1, y );
00137
00138 d->m_child->setGeometry( QRect( d->m_geometryStart.x(), d->m_geometryStart.y() + y,
00139 d->m_geometryStart.width(), d->m_geometryStart.height() - y ) );
00140 repaint(rgn);
00141 }
00142 break;
00143 case KoChild::TopRight:
00144 {
00145 x = QMAX( -d->m_geometryStart.width() + 1, x );
00146 y = QMIN( d->m_geometryStart.height() - 1, y );
00147
00148 d->m_child->setGeometry( QRect( d->m_geometryStart.x(), d->m_geometryStart.y() + y,
00149 d->m_geometryStart.width() + x, d->m_geometryStart.height() - y ) );
00150 repaint(rgn);
00151 }
00152 break;
00153 case KoChild::MidLeft:
00154 {
00155 x = QMIN( d->m_geometryStart.width() - 1, x );
00156
00157 d->m_child->setGeometry( QRect( d->m_geometryStart.x() + x, d->m_geometryStart.y(),
00158 d->m_geometryStart.width() - x, d->m_geometryStart.height() ) );
00159 repaint(rgn);
00160 }
00161 break;
00162 case KoChild::MidRight:
00163 {
00164 x = QMAX( -d->m_geometryStart.width() + 1, x );
00165
00166 d->m_child->setGeometry( QRect( d->m_geometryStart.x(), d->m_geometryStart.y(),
00167 d->m_geometryStart.width() + x, d->m_geometryStart.height() ) );
00168 repaint(rgn);
00169 }
00170 break;
00171 case KoChild::BottomLeft:
00172 {
00173 x = QMIN( d->m_geometryStart.width() - 1, x );
00174 y = QMAX( -d->m_geometryStart.height() + 1, y );
00175
00176 d->m_child->setGeometry( QRect( d->m_geometryStart.x() + x, d->m_geometryStart.y(),
00177 d->m_geometryStart.width() - x, d->m_geometryStart.height() + y ) );
00178 repaint(rgn);
00179 }
00180 break;
00181 case KoChild::BottomMid:
00182 {
00183 y = QMAX( -d->m_geometryStart.height() + 1, y );
00184
00185 d->m_child->setGeometry( QRect( d->m_geometryStart.x(), d->m_geometryStart.y(),
00186 d->m_geometryStart.width(), d->m_geometryStart.height() + y ) );
00187 repaint(rgn);
00188 }
00189 break;
00190 case KoChild::BottomRight:
00191 {
00192 x = QMAX( -d->m_geometryStart.width() + 1, x );
00193 y = QMAX( -d->m_geometryStart.height() + 1, y );
00194
00195 d->m_child->setGeometry( QRect( d->m_geometryStart.x(), d->m_geometryStart.y(),
00196 d->m_geometryStart.width() + x, d->m_geometryStart.height() + y ) );
00197 repaint(rgn);
00198 }
00199 break;
00200 default:
00201 Q_ASSERT( 0 );
00202 }
00203 return true;
00204 }
00205 return false;
00206 }
00207
00208
00209
00210 class KoPartMoveHandlerPrivate {
00211 public:
00212 KoPartMoveHandlerPrivate( const QWMatrix& matrix, KoView* view, KoChild* child,
00213 const QPoint& point) : m_view(view), m_dragChild(child),
00214 m_parentMatrix(matrix) {
00215 m_invertParentMatrix = matrix.invert();
00216 m_mouseDragStart = m_invertParentMatrix.map( point );
00217 m_geometryDragStart = m_dragChild->geometry();
00218 m_rotationDragStart = m_dragChild->rotationPoint();
00219 }
00220 ~KoPartMoveHandlerPrivate() {}
00221
00222 KoView* m_view;
00223 KoChild* m_dragChild;
00224 QPoint m_mouseDragStart;
00225 QRect m_geometryDragStart;
00226 QPoint m_rotationDragStart;
00227 QWMatrix m_invertParentMatrix;
00228 QWMatrix m_parentMatrix;
00229 };
00230
00231 KoPartMoveHandler::KoPartMoveHandler( QWidget* widget, const QWMatrix& matrix, KoView* view, KoChild* child,
00232 const QPoint& point )
00233 : KoEventHandler( widget )
00234 {
00235 child->lock();
00236 d=new KoPartMoveHandlerPrivate(matrix, view, child, point);
00237 }
00238
00239 KoPartMoveHandler::~KoPartMoveHandler()
00240 {
00241 d->m_dragChild->unlock();
00242 delete d;
00243 d=0L;
00244 }
00245
00246 bool KoPartMoveHandler::eventFilter( QObject*, QEvent* ev )
00247 {
00248 if ( ev->type() == QEvent::MouseButtonRelease )
00249 {
00250 delete this;
00251 return true;
00252 }
00253 else if ( ev->type() == QEvent::MouseMove )
00254 {
00255 QMouseEvent* e = (QMouseEvent*)ev;
00256
00257 QRegion bound = d->m_dragChild->frameRegion( d->m_parentMatrix, true );
00258 QPoint pos = d->m_invertParentMatrix.map( e->pos() );
00259 d->m_dragChild->setGeometry( QRect( d->m_geometryDragStart.x() + pos.x() - d->m_mouseDragStart.x(),
00260 d->m_geometryDragStart.y() + pos.y() - d->m_mouseDragStart.y(),
00261 d->m_geometryDragStart.width(), d->m_geometryDragStart.height() ) );
00262 d->m_dragChild->setRotationPoint( QPoint( d->m_rotationDragStart.x() + pos.x() - d->m_mouseDragStart.x(),
00263 d->m_rotationDragStart.y() + pos.y() - d->m_mouseDragStart.y() ) );
00264 bound = bound.unite( d->m_dragChild->frameRegion( d->m_parentMatrix, false ) );
00265
00266 ((QWidget*)target())->repaint( bound );
00267
00268 return true;
00269 }
00270
00271 return false;
00272 }
00273
00274
00275
00276 KoContainerHandler::KoContainerHandler( KoView* view, QWidget* widget )
00277 : KoEventHandler( widget )
00278 {
00279 m_view = view;
00280 }
00281
00282 KoContainerHandler::~KoContainerHandler()
00283 {
00284 }
00285
00286 bool KoContainerHandler::eventFilter( QObject*, QEvent* ev )
00287 {
00288 if ( ev->type() == QEvent::KeyPress )
00289 {
00290 QKeyEvent* keyEvent=(QKeyEvent*)ev;
00291
00292 KoChild* child=m_view->selectedChild();
00293
00294 if (child != 0)
00295 {
00296 if (keyEvent->key()==Qt::Key_Delete)
00297 emit deleteChild(child);
00298 }
00299 }
00300
00301 if ( ev->type() == QEvent::MouseButtonPress )
00302 {
00303 KoChild::Gadget gadget;
00304 QPoint pos;
00305 QMouseEvent *e=static_cast<QMouseEvent*>(ev);
00306 KoChild *ch=child(gadget, pos, e);
00307
00308 if ( e->button() == RightButton && gadget != KoChild::NoGadget )
00309 {
00310 emit popupMenu( ch, e->globalPos() );
00311 return true;
00312 }
00313 else if ( e->button() == LeftButton && gadget == KoChild::Move )
00314 {
00315 (void)new KoPartMoveHandler( static_cast<QWidget*>(target()), m_view->matrix(), m_view, ch, pos );
00316 return true;
00317 }
00318 else if ( e->button() == LeftButton && gadget != KoChild::NoGadget )
00319 {
00320 (void)new KoPartResizeHandler( static_cast<QWidget*>(target()), m_view->matrix(), m_view, ch, gadget, pos );
00321 return true;
00322 }
00323 return false;
00324 }
00325 else if ( ev->type() == QEvent::MouseMove )
00326 {
00327 QWidget *targetWidget = static_cast<QWidget *>( target() );
00328 KoChild::Gadget gadget;
00329 QPoint pos;
00330 QMouseEvent *e=static_cast<QMouseEvent*>(ev);
00331 child(gadget, pos, e);
00332
00333 bool retval = true;
00334 if ( gadget == KoChild::NoGadget )
00335 retval = false;
00336
00337 if ( gadget == KoChild::TopLeft || gadget == KoChild::BottomRight )
00338 targetWidget->setCursor( sizeFDiagCursor );
00339 else if ( gadget == KoChild::TopRight || gadget == KoChild::BottomLeft )
00340 targetWidget->setCursor( sizeBDiagCursor );
00341 else if ( gadget == KoChild::TopMid || gadget == KoChild::BottomMid )
00342 targetWidget->setCursor( sizeVerCursor );
00343 else if ( gadget == KoChild::MidLeft || gadget == KoChild::MidRight )
00344 targetWidget->setCursor( sizeHorCursor );
00345 else if ( gadget == KoChild::Move )
00346 targetWidget->setCursor( KCursor::handCursor() );
00347 else
00348 {
00349
00350 return false;
00351 }
00352 return retval;
00353 }
00354 return false;
00355 }
00356
00357 KoChild *KoContainerHandler::child(KoChild::Gadget &gadget, QPoint &pos, const QMouseEvent *ev) {
00358
00359 pos = ev->pos();
00360
00361 pos = m_view->reverseViewTransformations( pos );
00362
00363 KoChild *child = 0;
00364 KoDocumentChild* docChild = m_view->selectedChild();
00365 gadget = KoChild::NoGadget;
00366 if ( docChild )
00367 {
00368 KoViewChild *viewChild = m_view->child( docChild->document() );
00369
00370 if ( viewChild )
00371 child = viewChild;
00372 else
00373 child = docChild;
00374
00375 gadget = child->gadgetHitTest( pos );
00376 }
00377 if ( gadget == KoChild::NoGadget )
00378 {
00379 docChild = m_view->activeChild();
00380 if ( docChild )
00381 {
00382 KoViewChild *viewChild = m_view->child( docChild->document() );
00383
00384 if ( viewChild )
00385 child = viewChild;
00386 else
00387 child = docChild;
00388
00389 gadget = child->gadgetHitTest( pos );
00390 }
00391 }
00392 return child;
00393 }
00394
00395 #include "KoContainerHandler.moc"