summaryrefslogtreecommitdiffstats
path: root/lib/kofficecore/KoContainerHandler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/kofficecore/KoContainerHandler.cpp')
-rw-r--r--lib/kofficecore/KoContainerHandler.cpp395
1 files changed, 395 insertions, 0 deletions
diff --git a/lib/kofficecore/KoContainerHandler.cpp b/lib/kofficecore/KoContainerHandler.cpp
new file mode 100644
index 000000000..78060592d
--- /dev/null
+++ b/lib/kofficecore/KoContainerHandler.cpp
@@ -0,0 +1,395 @@
+/* This file is part of the KDE project
+ Copyright (C) 1998, 1999, 2000 Torben Weis <weis@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#include "KoContainerHandler.h"
+#include <KoView.h>
+#include <math.h>
+#include <kcursor.h>
+#include <kdebug.h>
+
+KoEventHandler::KoEventHandler( QObject* target )
+{
+ m_target = target;
+
+ m_target->installEventFilter( this );
+}
+
+KoEventHandler::~KoEventHandler()
+{
+}
+
+QObject* KoEventHandler::target()
+{
+ return m_target;
+}
+
+// ------------------------------------------------------
+
+class KoPartResizeHandlerPrivate {
+public:
+ KoPartResizeHandlerPrivate( const QWMatrix& matrix, KoView *view, KoChild* child,
+ KoChild::Gadget gadget, const QPoint& point ) :
+ m_gadget(gadget), m_view(view), m_child(child), m_parentMatrix(matrix) {
+
+ m_geometryStart = child->geometry();
+ m_matrix = child->matrix() * matrix;
+ m_invertParentMatrix = matrix.invert();
+
+ bool ok = true;
+ m_invert = m_matrix.invert( &ok );
+ Q_ASSERT( ok );
+ m_mouseStart = m_invert.map( m_invertParentMatrix.map( point ) );
+ }
+ ~KoPartResizeHandlerPrivate() {}
+
+ KoChild::Gadget m_gadget;
+ QPoint m_mouseStart;
+ QRect m_geometryStart;
+ KoView* m_view;
+ KoChild* m_child;
+ QWMatrix m_invert;
+ QWMatrix m_matrix;
+ QWMatrix m_parentMatrix;
+ QWMatrix m_invertParentMatrix;
+};
+
+KoPartResizeHandler::KoPartResizeHandler( QWidget* widget, const QWMatrix& matrix, KoView* view, KoChild* child,
+ KoChild::Gadget gadget, const QPoint& point )
+ : KoEventHandler( widget )
+{
+ child->lock();
+ d=new KoPartResizeHandlerPrivate(matrix, view, child, gadget, point);
+}
+
+KoPartResizeHandler::~KoPartResizeHandler()
+{
+ d->m_child->unlock();
+ delete d;
+ d=0L;
+}
+
+void KoPartResizeHandler::repaint(QRegion &rgn)
+{
+ rgn = rgn.unite( d->m_child->frameRegion( d->m_parentMatrix, true ) );
+ // rgn.translate(- d->m_view->canvasXOffset(), - d->m_view->canvasYOffset());
+ ((QWidget*)target())->repaint( rgn );
+}
+
+bool KoPartResizeHandler::eventFilter( QObject*, QEvent* ev )
+{
+ if ( ev->type() == QEvent::MouseButtonRelease )
+ {
+ delete this;
+ return true;
+ }
+ else if ( ev->type() == QEvent::MouseMove )
+ {
+ QMouseEvent* e = (QMouseEvent*)ev;
+ QPoint p = d->m_invert.map( d->m_invertParentMatrix.map( e->pos() /*+ QPoint(d->m_view->canvasXOffset(), d->m_view->canvasYOffset()) */ ) );
+ QRegion rgn( d->m_child->frameRegion( d->m_parentMatrix, true ) );
+
+ double x1_x, x1_y, x2_x, x2_y;
+ d->m_matrix.map( double( p.x() ), 0.0, &x1_x, &x1_y );
+ d->m_matrix.map( double( d->m_mouseStart.x() ), 0.0, &x2_x, &x2_y );
+ double y1_x, y1_y, y2_x, y2_y;
+ d->m_matrix.map( 0.0, double( p.y() ), &y1_x, &y1_y );
+ d->m_matrix.map( 0.0, double( d->m_mouseStart.y() ), &y2_x, &y2_y );
+
+ double dx = x2_x - x1_x;
+ double dy = x2_y - x1_y;
+ int x = int( sqrt( dx * dx + dy * dy ) * ( d->m_mouseStart.x() < p.x() ? 1.0 : -1.0 ) );
+
+ dx = y2_x - y1_x;
+ dy = y2_y - y1_y;
+ int y = int( sqrt( dx * dx + dy * dy ) * ( d->m_mouseStart.y() < p.y() ? 1.0 : -1.0 ) );
+
+ switch( d->m_gadget )
+ {
+ case KoChild::TopLeft:
+ {
+ x = QMIN( d->m_geometryStart.width() - 1, x );
+ y = QMIN( d->m_geometryStart.height() - 1, y );
+
+ d->m_child->setGeometry( QRect( d->m_geometryStart.x() + x, d->m_geometryStart.y() + y,
+ d->m_geometryStart.width() - x, d->m_geometryStart.height() - y ) );
+ repaint(rgn);
+ }
+ break;
+ case KoChild::TopMid:
+ {
+ y = QMIN( d->m_geometryStart.height() - 1, y );
+
+ d->m_child->setGeometry( QRect( d->m_geometryStart.x(), d->m_geometryStart.y() + y,
+ d->m_geometryStart.width(), d->m_geometryStart.height() - y ) );
+ repaint(rgn);
+ }
+ break;
+ case KoChild::TopRight:
+ {
+ x = QMAX( -d->m_geometryStart.width() + 1, x );
+ y = QMIN( d->m_geometryStart.height() - 1, y );
+
+ d->m_child->setGeometry( QRect( d->m_geometryStart.x(), d->m_geometryStart.y() + y,
+ d->m_geometryStart.width() + x, d->m_geometryStart.height() - y ) );
+ repaint(rgn);
+ }
+ break;
+ case KoChild::MidLeft:
+ {
+ x = QMIN( d->m_geometryStart.width() - 1, x );
+
+ d->m_child->setGeometry( QRect( d->m_geometryStart.x() + x, d->m_geometryStart.y(),
+ d->m_geometryStart.width() - x, d->m_geometryStart.height() ) );
+ repaint(rgn);
+ }
+ break;
+ case KoChild::MidRight:
+ {
+ x = QMAX( -d->m_geometryStart.width() + 1, x );
+
+ d->m_child->setGeometry( QRect( d->m_geometryStart.x(), d->m_geometryStart.y(),
+ d->m_geometryStart.width() + x, d->m_geometryStart.height() ) );
+ repaint(rgn);
+ }
+ break;
+ case KoChild::BottomLeft:
+ {
+ x = QMIN( d->m_geometryStart.width() - 1, x );
+ y = QMAX( -d->m_geometryStart.height() + 1, y );
+
+ d->m_child->setGeometry( QRect( d->m_geometryStart.x() + x, d->m_geometryStart.y(),
+ d->m_geometryStart.width() - x, d->m_geometryStart.height() + y ) );
+ repaint(rgn);
+ }
+ break;
+ case KoChild::BottomMid:
+ {
+ y = QMAX( -d->m_geometryStart.height() + 1, y );
+
+ d->m_child->setGeometry( QRect( d->m_geometryStart.x(), d->m_geometryStart.y(),
+ d->m_geometryStart.width(), d->m_geometryStart.height() + y ) );
+ repaint(rgn);
+ }
+ break;
+ case KoChild::BottomRight:
+ {
+ x = QMAX( -d->m_geometryStart.width() + 1, x );
+ y = QMAX( -d->m_geometryStart.height() + 1, y );
+
+ d->m_child->setGeometry( QRect( d->m_geometryStart.x(), d->m_geometryStart.y(),
+ d->m_geometryStart.width() + x, d->m_geometryStart.height() + y ) );
+ repaint(rgn);
+ }
+ break;
+ default:
+ Q_ASSERT( 0 );
+ }
+ return true;
+ }
+ return false;
+}
+
+// --------------------------------------------------------------
+
+class KoPartMoveHandlerPrivate {
+public:
+ KoPartMoveHandlerPrivate( const QWMatrix& matrix, KoView* view, KoChild* child,
+ const QPoint& point) : m_view(view), m_dragChild(child),
+ m_parentMatrix(matrix) {
+ m_invertParentMatrix = matrix.invert();
+ m_mouseDragStart = m_invertParentMatrix.map( point );
+ m_geometryDragStart = m_dragChild->geometry();
+ m_rotationDragStart = m_dragChild->rotationPoint();
+ }
+ ~KoPartMoveHandlerPrivate() {}
+
+ KoView* m_view;
+ KoChild* m_dragChild;
+ QPoint m_mouseDragStart;
+ QRect m_geometryDragStart;
+ QPoint m_rotationDragStart;
+ QWMatrix m_invertParentMatrix;
+ QWMatrix m_parentMatrix;
+};
+
+KoPartMoveHandler::KoPartMoveHandler( QWidget* widget, const QWMatrix& matrix, KoView* view, KoChild* child,
+ const QPoint& point )
+ : KoEventHandler( widget )
+{
+ child->lock();
+ d=new KoPartMoveHandlerPrivate(matrix, view, child, point);
+}
+
+KoPartMoveHandler::~KoPartMoveHandler()
+{
+ d->m_dragChild->unlock();
+ delete d;
+ d=0L;
+}
+
+bool KoPartMoveHandler::eventFilter( QObject*, QEvent* ev )
+{
+ if ( ev->type() == QEvent::MouseButtonRelease )
+ {
+ delete this;
+ return true;
+ }
+ else if ( ev->type() == QEvent::MouseMove )
+ {
+ QMouseEvent* e = (QMouseEvent*)ev;
+
+ QRegion bound = d->m_dragChild->frameRegion( d->m_parentMatrix, true );
+ QPoint pos = d->m_invertParentMatrix.map( e->pos() /* + QPoint(d->m_view->canvasXOffset(), d->m_view->canvasYOffset()) */ );
+ d->m_dragChild->setGeometry( QRect( d->m_geometryDragStart.x() + pos.x() - d->m_mouseDragStart.x(),
+ d->m_geometryDragStart.y() + pos.y() - d->m_mouseDragStart.y(),
+ d->m_geometryDragStart.width(), d->m_geometryDragStart.height() ) );
+ d->m_dragChild->setRotationPoint( QPoint( d->m_rotationDragStart.x() + pos.x() - d->m_mouseDragStart.x(),
+ d->m_rotationDragStart.y() + pos.y() - d->m_mouseDragStart.y() ) );
+ bound = bound.unite( d->m_dragChild->frameRegion( d->m_parentMatrix, false ) );
+ // bound.translate(- d->m_view->canvasXOffset(), - d->m_view->canvasYOffset());
+ ((QWidget*)target())->repaint( bound );
+
+ return true;
+ }
+
+ return false;
+}
+
+// -------------------------------------------------------
+
+KoContainerHandler::KoContainerHandler( KoView* view, QWidget* widget )
+ : KoEventHandler( widget )
+{
+ m_view = view;
+}
+
+KoContainerHandler::~KoContainerHandler()
+{
+}
+
+bool KoContainerHandler::eventFilter( QObject*, QEvent* ev )
+{
+ if ( ev->type() == QEvent::KeyPress )
+ {
+ QKeyEvent* keyEvent=(QKeyEvent*)ev;
+
+ KoChild* child=m_view->selectedChild();
+
+ if (child != 0)
+ {
+ if (keyEvent->key()==Qt::Key_Delete)
+ emit deleteChild(child);
+ }
+ }
+
+ if ( ev->type() == QEvent::MouseButtonPress )
+ {
+ KoChild::Gadget gadget;
+ QPoint pos;
+ QMouseEvent *e=static_cast<QMouseEvent*>(ev);
+ KoChild *ch=child(gadget, pos, e);
+
+ if ( e->button() == RightButton && gadget != KoChild::NoGadget )
+ {
+ emit popupMenu( ch, e->globalPos() );
+ return true;
+ }
+ else if ( e->button() == LeftButton && gadget == KoChild::Move )
+ {
+ (void)new KoPartMoveHandler( static_cast<QWidget*>(target()), m_view->matrix(), m_view, ch, pos );
+ return true;
+ }
+ else if ( e->button() == LeftButton && gadget != KoChild::NoGadget )
+ {
+ (void)new KoPartResizeHandler( static_cast<QWidget*>(target()), m_view->matrix(), m_view, ch, gadget, pos );
+ return true;
+ }
+ return false;
+ }
+ else if ( ev->type() == QEvent::MouseMove )
+ {
+ QWidget *targetWidget = static_cast<QWidget *>( target() );
+ KoChild::Gadget gadget;
+ QPoint pos;
+ QMouseEvent *e=static_cast<QMouseEvent*>(ev);
+ child(gadget, pos, e);
+
+ bool retval = true;
+ if ( gadget == KoChild::NoGadget )
+ retval = false;
+
+ if ( gadget == KoChild::TopLeft || gadget == KoChild::BottomRight )
+ targetWidget->setCursor( sizeFDiagCursor );
+ else if ( gadget == KoChild::TopRight || gadget == KoChild::BottomLeft )
+ targetWidget->setCursor( sizeBDiagCursor );
+ else if ( gadget == KoChild::TopMid || gadget == KoChild::BottomMid )
+ targetWidget->setCursor( sizeVerCursor );
+ else if ( gadget == KoChild::MidLeft || gadget == KoChild::MidRight )
+ targetWidget->setCursor( sizeHorCursor );
+ else if ( gadget == KoChild::Move )
+ targetWidget->setCursor( KCursor::handCursor() );
+ else
+ {
+// targetWidget->setCursor( arrowCursor );
+ return false;
+ }
+ return retval;
+ }
+ return false;
+}
+
+KoChild *KoContainerHandler::child(KoChild::Gadget &gadget, QPoint &pos, const QMouseEvent *ev) {
+
+ pos = ev->pos(); //+ QPoint(m_view->canvasXOffset(), m_view->canvasYOffset());
+
+ pos = m_view->reverseViewTransformations( pos );
+
+ KoChild *child = 0;
+ KoDocumentChild* docChild = m_view->selectedChild();
+ gadget = KoChild::NoGadget;
+ if ( docChild )
+ {
+ KoViewChild *viewChild = m_view->child( docChild->document() );
+
+ if ( viewChild )
+ child = viewChild;
+ else
+ child = docChild;
+
+ gadget = child->gadgetHitTest( pos );
+ }
+ if ( gadget == KoChild::NoGadget )
+ {
+ docChild = m_view->activeChild();
+ if ( docChild )
+ {
+ KoViewChild *viewChild = m_view->child( docChild->document() );
+
+ if ( viewChild )
+ child = viewChild;
+ else
+ child = docChild;
+
+ gadget = child->gadgetHitTest( pos );
+ }
+ }
+ return child;
+}
+
+#include "KoContainerHandler.moc"