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