KoContainerHandler.cpp
1/* This file is part of the KDE project
2 Copyright (C) 1998, 1999, 2000 Torben Weis <weis@kde.org>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18*/
19
20#include "KoContainerHandler.h"
21#include <KoView.h>
22#include <math.h>
23#include <kcursor.h>
24#include <kdebug.h>
25
26KoEventHandler::KoEventHandler( TQObject* target )
27{
28 m_target = target;
29
30 m_target->installEventFilter( this );
31}
32
33KoEventHandler::~KoEventHandler()
34{
35}
36
37TQObject* KoEventHandler::target()
38{
39 return m_target;
40}
41
42// ------------------------------------------------------
43
44class KoPartResizeHandlerPrivate {
45public:
46 KoPartResizeHandlerPrivate( const TQWMatrix& matrix, KoView *view, KoChild* child,
47 KoChild::Gadget gadget, const TQPoint& point ) :
48 m_gadget(gadget), m_view(view), m_child(child), m_parentMatrix(matrix) {
49
50 m_geometryStart = child->geometry();
51 m_matrix = child->matrix() * matrix;
52 m_invertParentMatrix = matrix.invert();
53
54 bool ok = true;
55 m_invert = m_matrix.invert( &ok );
56 Q_ASSERT( ok );
57 m_mouseStart = m_invert.map( m_invertParentMatrix.map( point ) );
58 }
59 ~KoPartResizeHandlerPrivate() {}
60
61 KoChild::Gadget m_gadget;
62 TQPoint m_mouseStart;
63 TQRect m_geometryStart;
64 KoView* m_view;
65 KoChild* m_child;
66 TQWMatrix m_invert;
67 TQWMatrix m_matrix;
68 TQWMatrix m_parentMatrix;
69 TQWMatrix m_invertParentMatrix;
70};
71
72KoPartResizeHandler::KoPartResizeHandler( TQWidget* widget, const TQWMatrix& matrix, KoView* view, KoChild* child,
73 KoChild::Gadget gadget, const TQPoint& point )
74 : KoEventHandler( widget )
75{
76 child->lock();
77 d=new KoPartResizeHandlerPrivate(matrix, view, child, gadget, point);
78}
79
80KoPartResizeHandler::~KoPartResizeHandler()
81{
82 d->m_child->unlock();
83 delete d;
84 d=0L;
85}
86
87void KoPartResizeHandler::repaint(TQRegion &rgn)
88{
89 rgn = rgn.unite( d->m_child->frameRegion( d->m_parentMatrix, true ) );
90 // rgn.translate(- d->m_view->canvasXOffset(), - d->m_view->canvasYOffset());
91 ((TQWidget*)target())->repaint( rgn );
92}
93
94bool KoPartResizeHandler::eventFilter( TQObject*, TQEvent* ev )
95{
96 if ( ev->type() == TQEvent::MouseButtonRelease )
97 {
98 delete this;
99 return true;
100 }
101 else if ( ev->type() == TQEvent::MouseMove )
102 {
103 TQMouseEvent* e = (TQMouseEvent*)ev;
104 TQPoint p = d->m_invert.map( d->m_invertParentMatrix.map( e->pos() /*+ TQPoint(d->m_view->canvasXOffset(), d->m_view->canvasYOffset()) */ ) );
105 TQRegion rgn( d->m_child->frameRegion( d->m_parentMatrix, true ) );
106
107 double x1_x, x1_y, x2_x, x2_y;
108 d->m_matrix.map( double( p.x() ), 0.0, &x1_x, &x1_y );
109 d->m_matrix.map( double( d->m_mouseStart.x() ), 0.0, &x2_x, &x2_y );
110 double y1_x, y1_y, y2_x, y2_y;
111 d->m_matrix.map( 0.0, double( p.y() ), &y1_x, &y1_y );
112 d->m_matrix.map( 0.0, double( d->m_mouseStart.y() ), &y2_x, &y2_y );
113
114 double dx = x2_x - x1_x;
115 double dy = x2_y - x1_y;
116 int x = int( sqrt( dx * dx + dy * dy ) * ( d->m_mouseStart.x() < p.x() ? 1.0 : -1.0 ) );
117
118 dx = y2_x - y1_x;
119 dy = y2_y - y1_y;
120 int y = int( sqrt( dx * dx + dy * dy ) * ( d->m_mouseStart.y() < p.y() ? 1.0 : -1.0 ) );
121
122 switch( d->m_gadget )
123 {
124 case KoChild::TopLeft:
125 {
126 x = TQMIN( d->m_geometryStart.width() - 1, x );
127 y = TQMIN( d->m_geometryStart.height() - 1, y );
128
129 d->m_child->setGeometry( TQRect( d->m_geometryStart.x() + x, d->m_geometryStart.y() + y,
130 d->m_geometryStart.width() - x, d->m_geometryStart.height() - y ) );
131 repaint(rgn);
132 }
133 break;
134 case KoChild::TopMid:
135 {
136 y = TQMIN( d->m_geometryStart.height() - 1, y );
137
138 d->m_child->setGeometry( TQRect( d->m_geometryStart.x(), d->m_geometryStart.y() + y,
139 d->m_geometryStart.width(), d->m_geometryStart.height() - y ) );
140 repaint(rgn);
141 }
142 break;
143 case KoChild::TopRight:
144 {
145 x = TQMAX( -d->m_geometryStart.width() + 1, x );
146 y = TQMIN( d->m_geometryStart.height() - 1, y );
147
148 d->m_child->setGeometry( TQRect( d->m_geometryStart.x(), d->m_geometryStart.y() + y,
149 d->m_geometryStart.width() + x, d->m_geometryStart.height() - y ) );
150 repaint(rgn);
151 }
152 break;
153 case KoChild::MidLeft:
154 {
155 x = TQMIN( d->m_geometryStart.width() - 1, x );
156
157 d->m_child->setGeometry( TQRect( d->m_geometryStart.x() + x, d->m_geometryStart.y(),
158 d->m_geometryStart.width() - x, d->m_geometryStart.height() ) );
159 repaint(rgn);
160 }
161 break;
162 case KoChild::MidRight:
163 {
164 x = TQMAX( -d->m_geometryStart.width() + 1, x );
165
166 d->m_child->setGeometry( TQRect( d->m_geometryStart.x(), d->m_geometryStart.y(),
167 d->m_geometryStart.width() + x, d->m_geometryStart.height() ) );
168 repaint(rgn);
169 }
170 break;
171 case KoChild::BottomLeft:
172 {
173 x = TQMIN( d->m_geometryStart.width() - 1, x );
174 y = TQMAX( -d->m_geometryStart.height() + 1, y );
175
176 d->m_child->setGeometry( TQRect( d->m_geometryStart.x() + x, d->m_geometryStart.y(),
177 d->m_geometryStart.width() - x, d->m_geometryStart.height() + y ) );
178 repaint(rgn);
179 }
180 break;
181 case KoChild::BottomMid:
182 {
183 y = TQMAX( -d->m_geometryStart.height() + 1, y );
184
185 d->m_child->setGeometry( TQRect( d->m_geometryStart.x(), d->m_geometryStart.y(),
186 d->m_geometryStart.width(), d->m_geometryStart.height() + y ) );
187 repaint(rgn);
188 }
189 break;
190 case KoChild::BottomRight:
191 {
192 x = TQMAX( -d->m_geometryStart.width() + 1, x );
193 y = TQMAX( -d->m_geometryStart.height() + 1, y );
194
195 d->m_child->setGeometry( TQRect( d->m_geometryStart.x(), d->m_geometryStart.y(),
196 d->m_geometryStart.width() + x, d->m_geometryStart.height() + y ) );
197 repaint(rgn);
198 }
199 break;
200 default:
201 Q_ASSERT( 0 );
202 }
203 return true;
204 }
205 return false;
206}
207
208// --------------------------------------------------------------
209
210class KoPartMoveHandlerPrivate {
211public:
212 KoPartMoveHandlerPrivate( const TQWMatrix& matrix, KoView* view, KoChild* child,
213 const TQPoint& point) : m_view(view), m_dragChild(child),
214 m_parentMatrix(matrix) {
215 m_invertParentMatrix = matrix.invert();
216 m_mouseDragStart = m_invertParentMatrix.map( point );
217 m_geometryDragStart = m_dragChild->geometry();
218 m_rotationDragStart = m_dragChild->rotationPoint();
219 }
220 ~KoPartMoveHandlerPrivate() {}
221
222 KoView* m_view;
223 KoChild* m_dragChild;
224 TQPoint m_mouseDragStart;
225 TQRect m_geometryDragStart;
226 TQPoint m_rotationDragStart;
227 TQWMatrix m_invertParentMatrix;
228 TQWMatrix m_parentMatrix;
229};
230
231KoPartMoveHandler::KoPartMoveHandler( TQWidget* widget, const TQWMatrix& matrix, KoView* view, KoChild* child,
232 const TQPoint& point )
233 : KoEventHandler( widget )
234{
235 child->lock();
236 d=new KoPartMoveHandlerPrivate(matrix, view, child, point);
237}
238
239KoPartMoveHandler::~KoPartMoveHandler()
240{
241 d->m_dragChild->unlock();
242 delete d;
243 d=0L;
244}
245
246bool KoPartMoveHandler::eventFilter( TQObject*, TQEvent* ev )
247{
248 if ( ev->type() == TQEvent::MouseButtonRelease )
249 {
250 delete this;
251 return true;
252 }
253 else if ( ev->type() == TQEvent::MouseMove )
254 {
255 TQMouseEvent* e = (TQMouseEvent*)ev;
256
257 TQRegion bound = d->m_dragChild->frameRegion( d->m_parentMatrix, true );
258 TQPoint pos = d->m_invertParentMatrix.map( e->pos() /* + TQPoint(d->m_view->canvasXOffset(), d->m_view->canvasYOffset()) */ );
259 d->m_dragChild->setGeometry( TQRect( d->m_geometryDragStart.x() + pos.x() - d->m_mouseDragStart.x(),
260 d->m_geometryDragStart.y() + pos.y() - d->m_mouseDragStart.y(),
261 d->m_geometryDragStart.width(), d->m_geometryDragStart.height() ) );
262 d->m_dragChild->setRotationPoint( TQPoint( d->m_rotationDragStart.x() + pos.x() - d->m_mouseDragStart.x(),
263 d->m_rotationDragStart.y() + pos.y() - d->m_mouseDragStart.y() ) );
264 bound = bound.unite( d->m_dragChild->frameRegion( d->m_parentMatrix, false ) );
265 // bound.translate(- d->m_view->canvasXOffset(), - d->m_view->canvasYOffset());
266 ((TQWidget*)target())->repaint( bound );
267
268 return true;
269 }
270
271 return false;
272}
273
274// -------------------------------------------------------
275
276KoContainerHandler::KoContainerHandler( KoView* view, TQWidget* widget )
277 : KoEventHandler( widget )
278{
279 m_view = view;
280}
281
282KoContainerHandler::~KoContainerHandler()
283{
284}
285
286bool KoContainerHandler::eventFilter( TQObject*, TQEvent* ev )
287{
288 if ( ev->type() == TQEvent::KeyPress )
289 {
290 TQKeyEvent* keyEvent=(TQKeyEvent*)ev;
291
292 KoChild* child=m_view->selectedChild();
293
294 if (child != 0)
295 {
296 if (keyEvent->key()==TQt::Key_Delete)
297 emit deleteChild(child);
298 }
299 }
300
301 if ( ev->type() == TQEvent::MouseButtonPress )
302 {
303 KoChild::Gadget gadget;
304 TQPoint pos;
305 TQMouseEvent *e=static_cast<TQMouseEvent*>(ev);
306 KoChild *ch=child(gadget, pos, e);
307
308 if ( e->button() == TQt::RightButton && gadget != KoChild::NoGadget )
309 {
310 emit popupMenu( ch, e->globalPos() );
311 return true;
312 }
313 else if ( e->button() == TQt::LeftButton && gadget == KoChild::Move )
314 {
315 (void)new KoPartMoveHandler( static_cast<TQWidget*>(target()), m_view->matrix(), m_view, ch, pos );
316 return true;
317 }
318 else if ( e->button() == TQt::LeftButton && gadget != KoChild::NoGadget )
319 {
320 (void)new KoPartResizeHandler( static_cast<TQWidget*>(target()), m_view->matrix(), m_view, ch, gadget, pos );
321 return true;
322 }
323 return false;
324 }
325 else if ( ev->type() == TQEvent::MouseMove )
326 {
327 TQWidget *targetWidget = static_cast<TQWidget*>( target() );
328 KoChild::Gadget gadget;
329 TQPoint pos;
330 TQMouseEvent *e=static_cast<TQMouseEvent*>(ev);
331 child(gadget, pos, e);
332
333 bool retval = true;
334 if ( gadget == KoChild::NoGadget )
335 retval = false;
336
337 if ( gadget == KoChild::TopLeft || gadget == KoChild::BottomRight )
338 targetWidget->setCursor( sizeFDiagCursor );
339 else if ( gadget == KoChild::TopRight || gadget == KoChild::BottomLeft )
340 targetWidget->setCursor( sizeBDiagCursor );
341 else if ( gadget == KoChild::TopMid || gadget == KoChild::BottomMid )
342 targetWidget->setCursor( sizeVerCursor );
343 else if ( gadget == KoChild::MidLeft || gadget == KoChild::MidRight )
344 targetWidget->setCursor( sizeHorCursor );
345 else if ( gadget == KoChild::Move )
346 targetWidget->setCursor( KCursor::handCursor() );
347 else
348 {
349// targetWidget->setCursor( arrowCursor );
350 return false;
351 }
352 return retval;
353 }
354 return false;
355}
356
357KoChild *KoContainerHandler::child(KoChild::Gadget &gadget, TQPoint &pos, const TQMouseEvent *ev) {
358
359 pos = ev->pos(); //+ TQPoint(m_view->canvasXOffset(), m_view->canvasYOffset());
360
361 pos = m_view->reverseViewTransformations( pos );
362
363 KoChild *child = 0;
364 KoDocumentChild* docChild = m_view->selectedChild();
365 gadget = KoChild::NoGadget;
366 if ( docChild )
367 {
368 KoViewChild *viewChild = m_view->child( docChild->document() );
369
370 if ( viewChild )
371 child = viewChild;
372 else
373 child = docChild;
374
375 gadget = child->gadgetHitTest( pos );
376 }
377 if ( gadget == KoChild::NoGadget )
378 {
379 docChild = m_view->activeChild();
380 if ( docChild )
381 {
382 KoViewChild *viewChild = m_view->child( docChild->document() );
383
384 if ( viewChild )
385 child = viewChild;
386 else
387 child = docChild;
388
389 gadget = child->gadgetHitTest( pos );
390 }
391 }
392 return child;
393}
394
395#include "KoContainerHandler.moc"
static TQCursor handCursor()
KoChild is an abstract base class that represents the geometry associated with an embedded document.
Definition KoChild.h:42
virtual Gadget gadgetHitTest(const TQPoint &p)
Different actions are taken depending on where a child frame is hit.
Definition KoChild.cpp:339
void lock()
Locks this child and stores the current transformation.
Definition KoChild.cpp:296
virtual TQWMatrix matrix() const
Definition KoChild.cpp:291
TQRect geometry() const
Definition KoChild.cpp:92
Gadget
The gadget generally identifies where a child has been hit (generally by the mouse pointer).
Definition KoChild.h:56
void popupMenu(KoChild *, const TQPoint &global_pos)
Emitted if the user wants to open the popup menu for some child object.
void deleteChild(KoChild *)
Emitted if the user pressed the delete key whilst a child was selected.
Holds an embedded object.
KoDocument * document() const
An abstract base class for event handlers.
Used by KoContainerHandler internally to handle moving of embedded documents.
Used by KoContainerHandler internally to handle resizing of embedded documents.
This class represents an active embedded document.
Definition KoView.h:474
This class is used to display a KoDocument.
Definition KoView.h:58
virtual TQPoint reverseViewTransformations(const TQPoint &) const
Reverse the transformations that the view makes to its contents, i.e.
Definition KoView.cpp:833
KoViewChild * child(KoView *view)
Definition KoView.cpp:485
virtual KoDocumentChild * activeChild()
Definition KoView.cpp:457
virtual KoDocumentChild * selectedChild()
Definition KoView.cpp:444
virtual TQWMatrix matrix() const TDE_DEPRECATED
Returns the matrix which is used by the view to transform the content.
Definition KoView.cpp:505