You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
koffice/lib/kofficecore/KoView.cpp

869 lines
24 KiB

/* This file is part of the KDE project
Copyright (C) 1998, 1999 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 <KoView.h>
#include <KoDocument.h>
#include <KoMainWindow.h>
#include <KoFrame.h>
#include <KoViewIface.h>
#include <KoDocumentChild.h>
#include <tdelocale.h>
#include <tdeglobal.h>
#include <kdebug.h>
#include <tdeparts/partmanager.h>
#include <tdeparts/event.h>
#include <kcursor.h>
#include <assert.h>
#include <kstatusbar.h>
#include <tdeapplication.h>
#include <tqtimer.h>
class KoViewPrivate
{
public:
KoViewPrivate()
{
m_inOperation = false;
m_zoom = 1.0;
m_children.setAutoDelete( true );
m_manager = 0L;
m_tempActiveWidget = 0L;
m_dcopObject = 0;
m_registered=false;
m_documentDeleted=false;
}
~KoViewPrivate()
{
}
TQGuardedPtr<KoDocument> m_doc; // our KoDocument
TQGuardedPtr<KParts::PartManager> m_manager;
double m_zoom;
TQPtrList<KoViewChild> m_children;
TQWidget *m_tempActiveWidget;
KoViewIface *m_dcopObject;
bool m_registered; // are we registered at the part manager?
bool m_documentDeleted; // true when m_doc gets deleted [can't use m_doc==0
// since this only happens in ~TQObject, and views
// get deleted by ~KoDocument].
TQTimer *m_scrollTimer;
// Hmm sorry for polluting the private class with such a big inner class.
// At the beginning it was a little struct :)
class StatusBarItem {
public:
StatusBarItem() // for TQValueList
: m_widget(0), m_visible(false)
{}
StatusBarItem( TQWidget * widget, int stretch, bool permanent )
: m_widget(widget), m_stretch(stretch), m_permanent(permanent), m_visible(false)
{}
TQWidget * widget() const { return m_widget; }
void ensureItemShown( KStatusBar * sb )
{
if ( !m_visible )
{
sb->addWidget( m_widget, m_stretch, m_permanent );
m_visible = true;
m_widget->show();
}
}
void ensureItemHidden( KStatusBar * sb )
{
if ( m_visible )
{
sb->removeWidget( m_widget );
m_visible = false;
m_widget->hide();
}
}
private:
TQWidget * m_widget;
int m_stretch;
bool m_permanent;
bool m_visible; // true when the item has been added to the statusbar
};
TQValueList<StatusBarItem> m_statusBarItems; // Our statusbar items
bool m_inOperation; //in the middle of an operation (no screen refreshing)?
};
KoView::KoView( KoDocument *document, TQWidget *parent, const char *name )
: TQWidget( parent, name )
{
Q_ASSERT( document );
//kdDebug(30003) << "KoView::KoView " << this << endl;
d = new KoViewPrivate;
d->m_doc = document;
KParts::PartBase::setPartObject( TQT_TQOBJECT(this) );
setFocusPolicy( TQWidget::StrongFocus );
setMouseTracking( true );
connect( d->m_doc, TQT_SIGNAL( childChanged( KoDocumentChild * ) ),
this, TQT_SLOT( slotChildChanged( KoDocumentChild * ) ) );
connect( d->m_doc, TQT_SIGNAL( sigBeginOperation() ),
this, TQT_SLOT( beginOperation() ) );
connect( d->m_doc, TQT_SIGNAL( sigEndOperation() ),
this, TQT_SLOT( endOperation() ) );
actionCollection()->setWidget( this );
setupGlobalActions();
TDEActionCollection *coll = actionCollection();
/**** not needed anymore, according to David (Werner)
TQValueList<TDEAction*> docActions = document->actionCollection()->actions();
TQValueList<TDEAction*>::ConstIterator it = docActions.begin();
TQValueList<TDEAction*>::ConstIterator end = docActions.end();
for (; it != end; ++it )
coll->insert( *it );
*/
KStatusBar * sb = statusBar();
if ( sb ) // No statusbar in e.g. konqueror
{
coll->setHighlightingEnabled( true );
connect( coll, TQT_SIGNAL( actionStatusText( const TQString & ) ),
this, TQT_SLOT( slotActionStatusText( const TQString & ) ) );
connect( coll, TQT_SIGNAL( clearStatusText() ),
this, TQT_SLOT( slotClearStatusText() ) );
connect( d->m_doc, TQT_SIGNAL( sigStatusBarMessage( const TQString& ) ),
this, TQT_SLOT( slotActionStatusText( const TQString& ) ) );
connect( d->m_doc, TQT_SIGNAL( sigClearStatusBarMessage() ),
this, TQT_SLOT( slotClearStatusText() ) );
}
d->m_doc->setCurrent();
d->m_scrollTimer = new TQTimer( this );
connect (d->m_scrollTimer, TQT_SIGNAL( timeout() ), this, TQT_SLOT( slotAutoScroll() ) );
}
KoView::~KoView()
{
kdDebug(30003) << "KoView::~KoView " << this << endl;
delete d->m_scrollTimer;
delete d->m_dcopObject;
if (!d->m_documentDeleted)
{
if ( koDocument() && !koDocument()->isSingleViewMode() )
{
if ( d->m_manager && d->m_registered ) // if we aren't registered we mustn't unregister :)
d->m_manager->removePart( koDocument() );
d->m_doc->removeView(this);
d->m_doc->setCurrent( false );
}
}
delete d;
}
KoDocument *KoView::koDocument() const
{
return d->m_doc;
}
void KoView::setDocumentDeleted()
{
d->m_documentDeleted = true;
}
bool KoView::documentDeleted() const
{
return d->m_documentDeleted;
}
bool KoView::hasDocumentInWindow( KoDocument *doc )
{
return child( doc ) != 0L;
}
void KoView::setPartManager( KParts::PartManager *manager )
{
d->m_manager = manager;
if ( !koDocument()->isSingleViewMode() &&
manager->parts()->containsRef( koDocument() ) == 0 ) // is there another view registered?
{
d->m_registered = true; // no, so we have to register now and ungregister again in the DTOR
manager->addPart( koDocument(), false );
}
else
d->m_registered = false; // There is already another view registered for that part...
}
KParts::PartManager *KoView::partManager() const
{
return d->m_manager;
}
TDEAction *KoView::action( const TQDomElement &element ) const
{
static const TQString &attrName = TDEGlobal::staticQString( "name" );
TQString name = element.attribute( attrName );
TDEAction *act = KXMLGUIClient::action( name.utf8() );
if ( !act )
act = d->m_doc->KXMLGUIClient::action( name.utf8() );
return act;
}
KoDocument *KoView::hitTest( const TQPoint &viewPos )
{
KoViewChild *viewChild;
TQPoint pos = reverseViewTransformations( viewPos );
KoDocumentChild *docChild = selectedChild();
if ( docChild )
{
if ( ( viewChild = child( docChild->document() ) ) )
{
if ( viewChild->frameRegion().contains( pos ) )
return 0;
}
else
if ( docChild->frameRegion().contains( pos ) )
return 0;
}
docChild = activeChild();
if ( docChild )
{
if ( ( viewChild = child( docChild->document() ) ) )
{
if ( viewChild->frameRegion().contains( pos ) )
return 0;
}
else
if ( docChild->frameRegion().contains( pos ) )
return 0;
}
return koDocument()->hitTest( pos );
}
int KoView::leftBorder() const
{
return 0;
}
int KoView::rightBorder() const
{
return 0;
}
int KoView::topBorder() const
{
return 0;
}
int KoView::bottomBorder() const
{
return 0;
}
void KoView::setZoom( double zoom )
{
d->m_zoom = zoom;
update();
}
double KoView::zoom() const
{
return d->m_zoom;
}
TQWidget *KoView::canvas() const
{
//dfaure: since the view plays two roles in this method (the const means "you can modify the canvas
// but not the view", it's just coincidence that the view is the canvas by default ;)
return const_cast<KoView *>(this);
}
int KoView::canvasXOffset() const
{
return 0;
}
int KoView::canvasYOffset() const
{
return 0;
}
void KoView::canvasAddChild( KoViewChild * )
{
}
void KoView::customEvent( TQCustomEvent *ev )
{
if ( KParts::PartActivateEvent::test( ev ) )
partActivateEvent( (KParts::PartActivateEvent *)ev );
else if ( KParts::PartSelectEvent::test( ev ) )
partSelectEvent( (KParts::PartSelectEvent *)ev );
else if( KParts::GUIActivateEvent::test( ev ) )
guiActivateEvent( (KParts::GUIActivateEvent*)ev );
}
void KoView::partActivateEvent( KParts::PartActivateEvent *event )
{
if ( event->part() != (KParts::Part *)koDocument() )
{
assert( event->part()->inherits( "KoDocument" ) );
KoDocumentChild *child = koDocument()->child( (KoDocument *)event->part() );
if ( child && event->activated() )
{
if ( child->isRectangle() && !child->isTransparent() )
{
KoViewChild *viewChild = new KoViewChild( child, this );
d->m_children.append( viewChild );
TQApplication::setOverrideCursor(waitCursor);
// This is the long operation (due to toolbar layout stuff)
d->m_manager->setActivePart( child->document(), viewChild->frame()->view() );
TQApplication::restoreOverrideCursor();
// Now we can move the frame to the right place
viewChild->setInitialFrameGeometry();
}
else
{
emit regionInvalidated( child->frameRegion( matrix() ), true );
}
emit childActivated( child );
}
else if ( child )
{
emit regionInvalidated( child->frameRegion( matrix() ), true );
emit childDeactivated( child );
}
else
emit invalidated();
}
else
emit activated( event->activated() );
}
void KoView::partSelectEvent( KParts::PartSelectEvent *event )
{
if ( event->part() != (KParts::Part *)koDocument() )
{
assert( event->part()->inherits( "KoDocument" ) );
KoDocumentChild *child = koDocument()->child( (KoDocument *)event->part() );
if ( child && event->selected() )
{
TQRegion r = child->frameRegion( matrix() );
r.translate( - canvasXOffset(), - canvasYOffset() );
emit regionInvalidated( r, true );
emit childSelected( child );
}
else if ( child )
{
TQRegion r = child->frameRegion( matrix() );
r.translate( - canvasXOffset(), - canvasYOffset() );
emit regionInvalidated( r, true );
emit childUnselected( child );
}
else
emit invalidated();
}
else
emit selected( event->selected() );
}
void KoView::guiActivateEvent( KParts::GUIActivateEvent * ev )
{
showAllStatusBarItems( ev->activated() );
}
void KoView::showAllStatusBarItems( bool show )
{
KStatusBar * sb = statusBar();
if ( !sb )
return;
TQValueListIterator<KoViewPrivate::StatusBarItem> it = d->m_statusBarItems.begin();
for ( ; it != d->m_statusBarItems.end() ; ++it )
if ( show )
(*it).ensureItemShown( sb );
else
(*it).ensureItemHidden( sb );
}
void KoView::addStatusBarItem( TQWidget * widget, int stretch, bool permanent )
{
KoViewPrivate::StatusBarItem item( widget, stretch, permanent );
d->m_statusBarItems.append(item);
TQValueListIterator<KoViewPrivate::StatusBarItem> it = d->m_statusBarItems.fromLast();
KStatusBar * sb = statusBar();
Q_ASSERT(sb);
if (sb)
(*it).ensureItemShown( sb );
}
void KoView::removeStatusBarItem( TQWidget * widget )
{
KStatusBar * sb = statusBar();
TQValueListIterator<KoViewPrivate::StatusBarItem> it = d->m_statusBarItems.begin();
for ( ; it != d->m_statusBarItems.end() ; ++it )
if ( (*it).widget() == widget )
{
if ( sb )
(*it).ensureItemHidden( sb );
d->m_statusBarItems.remove( it );
break;
}
if ( it == d->m_statusBarItems.end() )
kdWarning() << "KoView::removeStatusBarItem. Widget not found : " << widget << endl;
}
KoDocumentChild *KoView::selectedChild()
{
if ( !d->m_manager )
return 0L;
KParts::Part *selectedPart = d->m_manager->selectedPart();
if ( !selectedPart || !selectedPart->inherits( "KoDocument" ) )
return 0L;
return koDocument()->child( (KoDocument *)selectedPart );
}
KoDocumentChild *KoView::activeChild()
{
if ( !d->m_manager )
return 0L;
KParts::Part *activePart = d->m_manager->activePart();
if ( !activePart || !activePart->inherits( "KoDocument" ) )
return 0L;
return koDocument()->child( (KoDocument *)activePart );
}
void KoView::enableAutoScroll( )
{
d->m_scrollTimer->start( 50 );
}
void KoView::disableAutoScroll( )
{
d->m_scrollTimer->stop();
}
void KoView::paintEverything( TQPainter &painter, const TQRect &rect, bool transparent )
{
koDocument()->paintEverything( painter, rect, transparent, this );
}
KoViewChild *KoView::child( KoView *view )
{
TQPtrListIterator<KoViewChild> it( d->m_children );
for (; it.current(); ++it )
if ( it.current()->frame()->view() == view )
return it.current();
return 0L;
}
KoViewChild *KoView::child( KoDocument *doc )
{
TQPtrListIterator<KoViewChild> it( d->m_children );
for (; it.current(); ++it )
if ( it.current()->documentChild()->document() == doc )
return it.current();
return 0L;
}
TQWMatrix KoView::matrix() const
{
TQWMatrix m;
m.scale( zoom(), zoom() );
//m.translate( canvasXOffset() , canvasYOffset() );
return m;
}
void KoView::slotChildActivated( bool a )
{
// Only interested in deactivate events
if ( a )
return;
KoViewChild* ch = child( (KoView*)sender() );
if ( !ch )
return;
KoView* view = ch->frame()->view();
TQWidget *activeWidget = view->d->m_tempActiveWidget;
if ( d->m_manager->activeWidget() )
activeWidget = d->m_manager->activeWidget();
if ( !activeWidget || !activeWidget->inherits( "KoView" ) )
return;
// Is the new active view a child of this one ?
// In this case we may not delete!
// TQObject *n = d->m_manager->activeWidget();
TQObject *n = TQT_TQOBJECT(activeWidget);
while( n )
if ( n == (TQObject *)view )
return;
else
n = n->parent();
d->m_tempActiveWidget = activeWidget;
TQApplication::setOverrideCursor(waitCursor);
d->m_manager->setActivePart( 0L );
TQGuardedPtr<KoDocumentChild> docChild = ch->documentChild();
TQGuardedPtr<KoFrame> chFrame = ch->frame();
if ( docChild && chFrame && chFrame->view() )
{
docChild->setContentsPos( chFrame->view()->canvasXOffset(),
chFrame->view()->canvasYOffset() );
docChild->document()->setViewBuildDocument( chFrame->view(), chFrame->view()->xmlguiBuildDocument() );
}
d->m_children.remove( ch );
d->m_manager->addPart( docChild->document(), false ); // the destruction of the view removed the part from the partmanager. re-add it :)
TQApplication::restoreOverrideCursor();
// #### HACK
// We want to delete as many views as possible and this
// trick is used to go upwards in the view-tree.
emit activated( FALSE );
}
void KoView::slotChildChanged( KoDocumentChild *child )
{
TQRegion region( child->oldPointArray( matrix() ) );
emit regionInvalidated( child->frameRegion( matrix(), true ).unite( region ), true );
}
int KoView::autoScrollAcceleration( int offset ) const
{
if(offset < 40)
return offset;
else
return offset*offset/40;
}
void KoView::slotAutoScroll( )
{
TQPoint scrollDistance;
bool actuallyDoScroll = false;
TQPoint pos( mapFromGlobal( TQCursor::pos() ) );
//Provide progressive scrolling depending on the mouse position
if ( pos.y() < topBorder() )
{
scrollDistance.setY ((int) - autoScrollAcceleration( - pos.y() + topBorder() ));
actuallyDoScroll = true;
}
else if ( pos.y() > height() - bottomBorder() )
{
scrollDistance.setY ((int) autoScrollAcceleration(pos.y() - height() + bottomBorder() ));
actuallyDoScroll = true;
}
if ( pos.x() < leftBorder() )
{
scrollDistance.setX ((int) - autoScrollAcceleration( - pos.x() + leftBorder() ));
actuallyDoScroll = true;
}
else if ( pos.x() > width() - rightBorder() )
{
scrollDistance.setX ((int) autoScrollAcceleration( pos.x() - width() + rightBorder() ));
actuallyDoScroll = true;
}
if ( actuallyDoScroll )
{
int state=0;
#if KDE_IS_VERSION(3,4,0)
state = kapp->keyboardMouseState();
#endif
pos = canvas()->mapFrom(this, pos);
TQMouseEvent * event = new TQMouseEvent(TQEvent::MouseMove, pos, 0, state);
TQApplication::postEvent( canvas(), event );
emit autoScroll( scrollDistance );
}
}
void KoView::setupGlobalActions() {
actionNewView = new TDEAction( i18n( "&New View" ), "window-new", 0,
TQT_TQOBJECT(this), TQT_SLOT( newView() ),
actionCollection(), "view_newview" );
}
void KoView::setupPrinter( KPrinter & )
{
kdDebug() << "KoView::setupPrinter not implemented by the application!" << endl;
}
void KoView::print( KPrinter & )
{
kdDebug() << "KoView::print not implemented by the application!" << endl;
}
void KoView::newView() {
assert( ( d!=0L && d->m_doc ) );
KoDocument *thisDocument = d->m_doc;
KoMainWindow *shell = new KoMainWindow( thisDocument->instance() );
shell->setRootDocument(thisDocument);
shell->show();
}
bool KoView::isInOperation() const
{
return d->m_inOperation;
}
void KoView::beginOperation()
{
d->m_inOperation = true;
canvas()->setUpdatesEnabled(FALSE);
}
void KoView::endOperation()
{
canvas()->setUpdatesEnabled(TRUE);
d->m_inOperation = false;
// canvas()->update();
}
KoMainWindow * KoView::shell() const
{
return dynamic_cast<KoMainWindow *>( topLevelWidget() );
}
TDEMainWindow * KoView::mainWindow() const
{
return dynamic_cast<TDEMainWindow *>( topLevelWidget() );
}
KStatusBar * KoView::statusBar() const
{
KoMainWindow *mw = shell();
return mw ? mw->statusBar() : 0L;
}
void KoView::slotActionStatusText( const TQString &text )
{
KStatusBar *sb = statusBar();
if ( sb )
sb->message( text );
}
void KoView::slotClearStatusText()
{
KStatusBar *sb = statusBar();
if ( sb )
sb->clear();
}
DCOPObject *KoView::dcopObject()
{
if ( !d->m_dcopObject )
d->m_dcopObject = new KoViewIface( this );
return d->m_dcopObject;
}
class KoViewChild::KoViewChildPrivate
{
public:
KoViewChildPrivate()
{
}
~KoViewChildPrivate()
{
}
};
KoViewChild::KoViewChild( KoDocumentChild *child, KoView *_parentView )
{
d = new KoViewChildPrivate;
m_parentView = _parentView;
m_child = child;
m_frame = new KoFrame( parentView()->canvas() );
KoView *view = child->document()->createView( m_frame );
view->setXMLGUIBuildDocument( child->document()->viewBuildDocument( view ) );
view->setPartManager( parentView()->partManager() );
// hack? (Werner)
view->setZoom( parentView()->zoom() * TQMAX(child->xScaling(), child->yScaling()) );
m_frame->setView( view );
m_frame->show();
m_frame->raise();
parentView()->canvasAddChild( this );
/*
KoViewChild has basically three geometries to keep in sync.
- The KoDocumentChild geometry (i.e. the embedded object's geometry, unzoomed)
- Its own geometry (used for hit-test etc.)
- The KoFrame geometry (the graphical widget for moving the object when active)
So we need to subtract the scrollview's offset for the frame geometry, since it's a widget.
The rules are
(R1) frameGeometry = viewGeometry(childGeometry) "+" m_frame->{left|right|top|bottom}Border() - scrollview offset,
(R2) frameGeometry = myGeometry "+" active_frame_border - scrollview offset.
So: (R3, unused) myGeometry = viewGeometry(childGeometry) "+" m_frame->{left|right|top|bottom}Border() "-" active_frame_border
Notes: active_frame_border is m_frame->border() (0 when inactive, 5 when active).
{left|right|top|bottom}Border are the borders used in kspread (0 when inactive, big when active).
"+" border means we add a border, so it's a subtraction on x, y and an addition on width, height.
viewGeometry() applies the zoom as well as any other translation the app might want to do
*/
// Setting the frameGeometry is done in setInitialFrameGeometry, which is
// also called right after activation.
connect( view, TQT_SIGNAL( activated( bool ) ),
parentView(), TQT_SLOT( slotChildActivated( bool ) ) );
}
KoViewChild::~KoViewChild()
{
if ( m_frame )
{
slotFrameGeometryChanged();
delete static_cast<KoFrame *>( m_frame );
}
delete d;
}
void KoViewChild::slotFrameGeometryChanged()
{
// Set our geometry from the frame geometry (R2 reversed)
TQRect geom = m_frame->geometry();
int b = m_frame->border();
TQRect borderRect( geom.x() + b + parentView()->canvasXOffset(),
geom.y() + b + parentView()->canvasYOffset(),
geom.width() - b * 2,
geom.height() - b * 2 );
setGeometry( borderRect );
if(m_child)
{
// Set the child geometry from the frame geometry (R1 reversed)
TQRect borderLessRect( geom.x() + m_frame->leftBorder() + parentView()->canvasXOffset(),
geom.y() + m_frame->topBorder() + parentView()->canvasYOffset(),
geom.width() - m_frame->leftBorder() - m_frame->rightBorder(),
geom.height() - m_frame->topBorder() - m_frame->bottomBorder() );
// We don't want to trigger slotDocGeometryChanged again
lock();
TQRect childGeom = parentView()->reverseViewTransformations( borderLessRect );
kdDebug() << "KoChild::slotFrameGeometryChanged child geometry "
<< ( geometry() == childGeom ? "already " : "set to " )
<< childGeom << endl;
m_child->setGeometry( childGeom );
unlock();
}
}
void KoViewChild::slotDocGeometryChanged()
{
if ( locked() )
return;
// Set frame geometry from child geometry (R1)
// The frame's resizeEvent will call slotFrameGeometryChanged.
TQRect geom = parentView()->applyViewTransformations( m_child->geometry() );
TQRect borderRect( geom.x() - m_frame->leftBorder() - parentView()->canvasXOffset(),
geom.y() - m_frame->topBorder() - parentView()->canvasYOffset(),
geom.width() + m_frame->leftBorder() + m_frame->rightBorder(),
geom.height() + m_frame->topBorder() + m_frame->bottomBorder() );
kdDebug() << "KoViewChild::slotDocGeometryChanged frame geometry "
<< ( m_frame->geometry() == borderRect ? "already " : "set to " )
<< borderRect << endl;
m_frame->setGeometry( borderRect );
}
TQPoint KoView::applyViewTransformations( const TQPoint& p ) const
{
return TQPoint( tqRound( p.x() * zoom() ), tqRound( p.y() * zoom() ) );
}
TQPoint KoView::reverseViewTransformations( const TQPoint& v ) const
{
return TQPoint( tqRound( v.x() / zoom() ), tqRound( v.y() / zoom() ) );
}
TQRect KoView::applyViewTransformations( const TQRect& r ) const
{
return TQRect( applyViewTransformations( r.topLeft() ),
applyViewTransformations( r.bottomRight() ) );
}
TQRect KoView::reverseViewTransformations( const TQRect& r ) const
{
return TQRect( reverseViewTransformations( r.topLeft() ),
reverseViewTransformations( r.bottomRight() ) );
}
void KoViewChild::setInitialFrameGeometry()
{
kdDebug() << k_funcinfo << endl;
// Connect only now, so that the GUI building doesn't move us around.
connect( m_frame, TQT_SIGNAL( geometryChanged() ),
this, TQT_SLOT( slotFrameGeometryChanged() ) );
connect( m_child, TQT_SIGNAL( changed( KoChild * ) ),
this, TQT_SLOT( slotDocGeometryChanged() ) );
// Set frameGeometry from childGeometry
slotDocGeometryChanged();
// Set myGeometry from frameGeometry
slotFrameGeometryChanged();
}
#include "KoView.moc"