F:/KPlato/koffice/libs/kofficecore/KoContainerHandler.cpp

Aller à la documentation de ce fichier.
00001 /* This file is part of the KDE project
00002    Copyright (C) 1998, 1999, 2000 Torben Weis <weis@kde.org>
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License as published by the Free Software Foundation; either
00007    version 2 of the License, or (at your option) any later version.
00008 
00009    This library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public License
00015    along with this library; see the file COPYING.LIB.  If not, write to
00016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  * Boston, MA 02110-1301, USA.
00018 */
00019 
00020 #include "KoContainerHandler.h"
00021 #include <KoView.h>
00022 #include <math.h>
00023 #include <kcursor.h>
00024 #include <kdebug.h>
00025 //Added by qt3to4:
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  // rgn.translate(- d->m_view->canvasXOffset(), - d->m_view->canvasYOffset());
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() /*+ QPoint(d->m_view->canvasXOffset(), d->m_view->canvasYOffset()) */ ) );
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() /* + QPoint(d->m_view->canvasXOffset(), d->m_view->canvasYOffset()) */ );
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       //  bound.translate(- d->m_view->canvasXOffset(), - d->m_view->canvasYOffset());
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 //            targetWidget->setCursor( arrowCursor );
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(); //+ QPoint(m_view->canvasXOffset(), m_view->canvasYOffset());
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"

Généré le Wed Nov 22 23:41:02 2006 pour KPlato par  doxygen 1.5.1-p1