00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
#include <handler.h>
00021
#include <koView.h>
00022
#include <math.h>
00023
#include <kcursor.h>
00024
#include <kdebug.h>
00025
00026 EventHandler::EventHandler(
QObject* target )
00027 {
00028 m_target = target;
00029
00030 m_target->installEventFilter(
this );
00031 }
00032
00033 EventHandler::~EventHandler()
00034 {
00035 }
00036
00037
QObject* EventHandler::target()
00038 {
00039
return m_target;
00040 }
00041
00042
00043
00044
class PartResizeHandlerPrivate {
00045
public:
00046 PartResizeHandlerPrivate(
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 ~PartResizeHandlerPrivate() {}
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 PartResizeHandler::PartResizeHandler(
QWidget* widget,
const QWMatrix& matrix,
KoView* view,
KoChild* child,
00073 KoChild::Gadget gadget,
const QPoint& point )
00074 :
EventHandler( widget )
00075 {
00076 child->
lock();
00077 d=
new PartResizeHandlerPrivate(matrix, view, child, gadget, point);
00078 }
00079
00080 PartResizeHandler::~PartResizeHandler()
00081 {
00082 d->m_child->unlock();
00083
delete d;
00084 d=0L;
00085 }
00086
00087
void PartResizeHandler::repaint(
QRegion &rgn)
00088 {
00089 rgn = rgn.unite( d->m_child->frameRegion( d->m_parentMatrix,
true ) );
00090 rgn.translate(- d->m_view->canvasXOffset(), - d->m_view->canvasYOffset());
00091 ((
QWidget*)target())->repaint( rgn );
00092 }
00093
00094
bool PartResizeHandler::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() +
QPoint(d->m_view->canvasXOffset(), d->m_view->canvasYOffset()) ) );
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 PartMoveHandlerPrivate {
00211
public:
00212 PartMoveHandlerPrivate(
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 ~PartMoveHandlerPrivate() {}
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 PartMoveHandler::PartMoveHandler(
QWidget* widget,
const QWMatrix& matrix,
KoView* view,
KoChild* child,
00232
const QPoint& point )
00233 :
EventHandler( widget )
00234 {
00235 child->
lock();
00236 d=
new PartMoveHandlerPrivate(matrix, view, child, point);
00237 }
00238
00239 PartMoveHandler::~PartMoveHandler()
00240 {
00241 d->m_dragChild->unlock();
00242
delete d;
00243 d=0L;
00244 }
00245
00246
bool PartMoveHandler::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() +
QPoint(d->m_view->canvasXOffset(), d->m_view->canvasYOffset()) );
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 bound.translate(- d->m_view->canvasXOffset(), - d->m_view->canvasYOffset());
00266 ((
QWidget*)target())->repaint( bound );
00267
00268
return true;
00269 }
00270
00271
return false;
00272 }
00273
00274
00275
00276 ContainerHandler::ContainerHandler(
KoView* view,
QWidget* widget )
00277 :
EventHandler( widget )
00278 {
00279 m_view = view;
00280 }
00281
00282 ContainerHandler::~ContainerHandler()
00283 {
00284 }
00285
00286
bool ContainerHandler::eventFilter(
QObject*,
QEvent* ev )
00287 {
00288
if ( ev->type() == QEvent::MouseButtonPress )
00289 {
00290 KoChild::Gadget gadget;
00291
QPoint pos;
00292
QMouseEvent *e=static_cast<QMouseEvent*>(ev);
00293
KoChild *ch=child(gadget, pos, e);
00294
00295
if ( e->button() == RightButton && gadget != KoChild::NoGadget )
00296 {
00297 emit
popupMenu( ch, e->globalPos() );
00298
return true;
00299 }
00300
else if ( e->button() == LeftButton && gadget == KoChild::Move )
00301 {
00302 (
void)
new PartMoveHandler( static_cast<QWidget*>(target()), m_view->
matrix(), m_view, ch, pos );
00303
return true;
00304 }
00305
else if ( e->button() == LeftButton && gadget != KoChild::NoGadget )
00306 {
00307 (
void)
new PartResizeHandler( static_cast<QWidget*>(target()), m_view->
matrix(), m_view, ch, gadget, pos );
00308
return true;
00309 }
00310
return false;
00311 }
00312
else if ( ev->type() == QEvent::MouseMove )
00313 {
00314
QWidget *targetWidget = static_cast<QWidget *>( target() );
00315 KoChild::Gadget gadget;
00316
QPoint pos;
00317
QMouseEvent *e=static_cast<QMouseEvent*>(ev);
00318 child(gadget, pos, e);
00319
00320
bool retval =
true;
00321
if ( gadget == KoChild::NoGadget )
00322 retval =
false;
00323
00324
if ( gadget == KoChild::TopLeft || gadget == KoChild::BottomRight )
00325 targetWidget->setCursor( sizeFDiagCursor );
00326
else if ( gadget == KoChild::TopRight || gadget == KoChild::BottomLeft )
00327 targetWidget->setCursor( sizeBDiagCursor );
00328
else if ( gadget == KoChild::TopMid || gadget == KoChild::BottomMid )
00329 targetWidget->setCursor( sizeVerCursor );
00330
else if ( gadget == KoChild::MidLeft || gadget == KoChild::MidRight )
00331 targetWidget->setCursor( sizeHorCursor );
00332
else if ( gadget == KoChild::Move )
00333 targetWidget->setCursor( KCursor::handCursor() );
00334
else
00335 {
00336 targetWidget->setCursor( arrowCursor );
00337
return false;
00338 }
00339
return retval;
00340 }
00341
return false;
00342 }
00343
00344
KoChild *ContainerHandler::child(KoChild::Gadget &gadget,
QPoint &pos,
const QMouseEvent *ev) {
00345
00346 pos = ev->pos() +
QPoint(m_view->
canvasXOffset(), m_view->
canvasYOffset());
00347
00348
KoChild *child = 0;
00349
KoDocumentChild* docChild = m_view->
selectedChild();
00350 gadget = KoChild::NoGadget;
00351
if ( docChild )
00352 {
00353
KoViewChild *viewChild = m_view->
child( docChild->
document() );
00354
00355
if ( viewChild )
00356 child = viewChild;
00357
else
00358 child = docChild;
00359
00360 gadget = child->
gadgetHitTest( pos, m_view->
matrix() );
00361 }
00362
if ( gadget == KoChild::NoGadget )
00363 {
00364 docChild = m_view->
activeChild();
00365
if ( docChild )
00366 {
00367
KoViewChild *viewChild = m_view->
child( docChild->
document() );
00368
00369
if ( viewChild )
00370 child = viewChild;
00371
else
00372 child = docChild;
00373
00374 gadget = child->
gadgetHitTest( pos, m_view->
matrix() );
00375 }
00376 }
00377
return child;
00378 }
00379
00380
#include <handler.moc>