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/kword/KWPartFrameSet.cpp

379 lines
12 KiB

/* This file is part of the KDE project
Copyright (C) 2000-2005 David Faure <faure@kde.org>
Copyright (C) 2005 Thomas Zander <zander@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 "KWPartFrameSet.h"
#include "KWDocument.h"
#include "KWCommand.h"
#include "KWordPartFrameSetIface.h"
#include "KWFrameViewManager.h"
#include "KWFrameView.h"
#include "KWViewMode.h"
#include <KoOasisContext.h>
#include <KoXmlWriter.h>
#include <KoXmlNS.h>
#include <klocale.h>
#include <kapplication.h>
#include <assert.h>
KWPartFrameSet::KWPartFrameSet( KWDocument *_doc, KWDocumentChild *_child, const TQString & name )
: KWFrameSet( _doc ), m_child( 0 ), m_cmdMoveChild( 0 ), m_protectContent( false )
{
if ( _child )
setChild( _child );
kdDebug(32001) << "KWPartFrameSet::KWPartFrameSet" << endl;
if ( name.isEmpty() )
m_name = _doc->generateFramesetName( i18n( "Object %1" ) );
else
m_name = name;
}
KWPartFrameSet::KWPartFrameSet( KWDocument* doc, const TQDomElement& frameTag,
const TQDomElement& objectTag, KoOasisContext& context )
: KWFrameSet( doc ), m_child( 0 ), m_cmdMoveChild( 0 ), m_protectContent( false )
{
m_name = frameTag.attributeNS( KoXmlNS::draw, "name", TQString() );
if ( doc->frameSetByName( m_name ) ) // already exists!
m_name = doc->generateFramesetName( m_name + " %1" );
context.styleStack().save();
context.fillStyleStack( frameTag, KoXmlNS::draw, "style-name", "graphic" ); // get the style for the graphics element
KWFrame* frame = loadOasisFrame( frameTag, context );
context.styleStack().restore();
// Create a KWDocumentChild, without KoDocument inside
KWDocumentChild* child = doc->createChildDoc( frame->rect(), 0 );
setChild( child );
child->loadOasis( frameTag, objectTag );
updateChildGeometry();
// This is what loads the KoDocument
(void)child->loadOasisDocument( context.store(), context.manifestDocument() );
}
void KWPartFrameSet::setChild( KWDocumentChild* child )
{
assert( !m_child );
m_child = child;
m_child->setPartFrameSet( this );
TQObject::connect( m_child, TQT_SIGNAL( changed( KoChild * ) ),
this, TQT_SLOT( slotChildChanged() ) );
}
KWPartFrameSet::~KWPartFrameSet()
{
}
KWordFrameSetIface* KWPartFrameSet::dcopObject()
{
if ( !m_dcop )
m_dcop = new KWordPartFrameSetIface( this );
return m_dcop;
}
void KWPartFrameSet::drawFrameContents( KWFrame* frame, TQPainter * painter, const TQRect & /*crect TODO*/,
const TQColorGroup &, bool onlyChanged, bool,
KWFrameSetEdit *, KWViewMode * )
{
if (!onlyChanged)
{
if ( !m_child || !m_child->document() )
{
kdDebug(32001) << "KWPartFrameSet::drawFrameContents " << this << " aborting. child=" << m_child
<< " child->document()=" << (m_child?m_child->document():0) << endl;
return;
}
KoTextZoomHandler* zh = kWordDocument();
// We have to define better the merning of the rect that we pass. Does it include zooming ? (yes I think)
// Does it define the area to be repainted only? (no, that's the painter clip rect)
// So it defines the whole area covered by the embedded document, in pixels.
TQRect rframe( 0, 0,
zh->zoomItX( frame->innerWidth() ),
zh->zoomItY( frame->innerHeight() ) );
//kdDebug(32001) << "rframe=" << rframe << endl;
double zoomX = static_cast<double>( zh->zoom() ) / 100;
double zoomY = static_cast<double>( zh->zoom() ) / 100;
m_child->document()->paintEverything( *painter, rframe, true, 0L, zoomX, zoomY );
} //else kdDebug(32001) << "KWPartFrameSet::drawFrameContents " << this << " onlychanged=true!" << endl;
}
void KWPartFrameSet::updateChildGeometry()
{
if( m_frames.isEmpty() ) // Deleted frameset
return;
m_child->setGeometry( m_frames.first()->toTQRect() );
}
void KWPartFrameSet::slotChildChanged()
{
// This is called when the KoDocumentChild is resized (using the KoFrame)
TQPtrListIterator<KWFrame> listFrame = frameIterator();
KWFrame *frame = listFrame.current();
if ( frame )
{
frame->setRect( KoRect::fromTQRect( getChild()->tqgeometry() ) );
//kdDebug(32001) << "KWPartFrameSet::slotChildChanged child's tqgeometry " << getChild()->tqgeometry()
// << " frame set to " << *frame << endl;
m_doc->frameChanged( frame );
//there is just a frame
if(m_cmdMoveChild)
m_cmdMoveChild->listFrameMoved().newRect = frame->normalize();
}
else
kdDebug(32001) << "Frame not found!" << endl;
}
TQDomElement KWPartFrameSet::save( TQDomElement &parentElem, bool saveFrames )
{
if ( m_frames.isEmpty() ) // Deleted frameset -> don't save
return TQDomElement();
KWFrameSet::saveCommon( parentElem, saveFrames );
// Ok, this one is a bit hackish. KWDocument calls us for saving our stuff into
// the SETTINGS element, which it creates for us. So our save() doesn't really have
// the same behaviour as a normal KWFrameSet::save()....
return TQDomElement();
}
void KWPartFrameSet::saveOasis( KoXmlWriter& writer, KoSavingContext& context, bool ) const
{
if ( m_frames.isEmpty() ) // Deleted frameset -> don't save
return;
// Save first frame with the whole contents
KWFrame* frame = m_frames.getFirst();
frame->startOasisFrame( writer, context.mainStyles(), name() );
writer.startElement( "draw:object" );
// #### let's hope name() is unique...
m_child->saveOasisAttributes( writer, name() );
writer.endElement(); // draw:object
writer.endElement(); // draw:frame
}
void KWPartFrameSet::load( TQDomElement &attributes, bool loadFrames )
{
KWFrameSet::load( attributes, loadFrames );
}
void KWPartFrameSet::startEditing()
{
// Content is protected -> can't edit. Maybe we should open part in readonly mode?
if ( m_protectContent )
return;
kdDebug() << k_funcinfo << endl;
//create undo/redo move command
KWFrame* frame = m_frames.first();
if (!frame)
return;
FrameIndex index( frame );
FrameResizeStruct tmpMove( frame->normalize(), 0, KoRect() );
if(!m_cmdMoveChild)
m_cmdMoveChild=new KWFramePartMoveCommand( i18n("Move/Resize Frame"), index, tmpMove );
}
void KWPartFrameSet::endEditing()
{
kdDebug() << k_funcinfo << endl;
if( m_cmdMoveChild && m_cmdMoveChild->frameMoved() )
m_doc->addCommand(m_cmdMoveChild);
else
delete m_cmdMoveChild;
m_cmdMoveChild=0L;
}
void KWPartFrameSet::moveFloatingFrame( int frameNum, const KoPoint &position )
{
//kdDebug()<<k_funcinfo<<" frame no="<<frameNum<<" to pos="<<position.x()<<","<<position.y()<<endl;
KWFrame * frame = m_frames.at( frameNum );
if ( frame )
{
KWFrameSet::moveFloatingFrame( frameNum, position );
m_child->setGeometry( frame->toTQRect(), true /* avoid circular events */ );
}
}
KWFrameSetEdit * KWPartFrameSet::createFrameSetEdit( KWCanvas * /*canvas*/ )
{
return 0L; // new KWPartFrameSetEdit( this, canvas );
}
#ifndef NDEBUG
void KWPartFrameSet::printDebug()
{
KWFrameSet::printDebug();
kdDebug() << " +-- Object Document: " << endl;
if ( getChild() )
{
if ( getChild()->document() )
kdDebug() << " Url : " << getChild()->document()->url().url()<<endl;
else
kdWarning() << "NO DOCUMENT" << endl;
kdDebug() << " Rectangle : " << getChild()->tqgeometry().x() << "," << getChild()->tqgeometry().y() << " " << getChild()->tqgeometry().width() << "x" << getChild()->tqgeometry().height() << endl;
} else
kdWarning() << "NO CHILD" << endl;
}
#endif
void KWPartFrameSet::setDeleted( bool on)
{
m_child->setDeleted( on );
}
void KWPartFrameSet::deleteFrame( unsigned int _num, bool remove, bool recalc )
{
KWFrameSet::deleteFrame( _num, remove, recalc );
if ( m_frames.isEmpty() ) // then the whole frameset and thus the child is deleted
m_child->setDeleted();
}
void KWPartFrameSet::KWPartFrameSet::createEmptyRegion( const TQRect &crect, TQRegion &emptyRegion, KWViewMode *viewMode ) {
Q_UNUSED(crect);
Q_UNUSED(emptyRegion);
Q_UNUSED(viewMode);
// empty implementation since embedded parts can be transparant.
}
#if 0
KWPartFrameSetEdit::KWPartFrameSetEdit( KWPartFrameSet * fs, KWCanvas * canvas )
: KWFrameSetEdit( fs, canvas )
{
kdDebug(32001) << "KWPartFrameSetEdit::KWPartFrameSetEdit " << endl;
m_dcop=0L;
fs->startEditing();
TQObject::connect( m_canvas->gui()->getView(), TQT_SIGNAL( activated( bool ) ),
this, TQT_SLOT( slotChildActivated( bool ) ) );
}
KWPartFrameSetEdit::~KWPartFrameSetEdit()
{
kdDebug(32001) << "KWPartFrameSetEdit::~KWPartFrameSetEdit" << endl;
delete m_dcop;
}
DCOPObject* KWPartFrameSetEdit::dcopObject()
{
if ( !m_dcop )
m_dcop = new KWordPartFrameSetEditIface( this );
return m_dcop;
}
void KWPartFrameSetEdit::slotChildActivated(bool b)
{
kdDebug() << "KWPartFrameSetEdit::slotChildActivated " << b << endl;
//we store command when we deactivate the child.
if( !b )
partFrameSet()->endEditing();
}
#endif
void KWPartFrameSet::storeInternal()
{
if ( getChild()->document()->storeInternal() )
{
KWFramePartExternalCommand* cmd =new KWFramePartExternalCommand( i18n("Make Document External"), this );
m_doc->addCommand(cmd);
getChild()->document()->setStoreInternal(false);
}
else
{
KWFramePartInternalCommand* cmd =new KWFramePartInternalCommand( i18n("Make Document Internal"), this );
m_doc->addCommand(cmd);
getChild()->document()->setStoreInternal(true);
}
kdDebug()<<k_funcinfo<<"url: "<<getChild()->url().url()<<" store internal="<<getChild()->document()->storeInternal()<<endl;
}
/******************************************************************/
/* Class: KWDocumentChild */
/******************************************************************/
KWDocumentChild::KWDocumentChild( KWDocument *_wdoc, const TQRect& _rect, KoDocument *_doc )
: KoDocumentChild( _wdoc, _doc, _rect ), m_partFrameSet( 0 )
{
}
KWDocumentChild::KWDocumentChild( KWDocument *_wdoc )
: KoDocumentChild( _wdoc ), m_partFrameSet( 0 )
{
}
KWDocumentChild::~KWDocumentChild()
{
}
void KWDocumentChild::setDocument( KoDocument *doc, const TQRect &tqgeometry )
{
// When hitTest returns true, we want to activate the part right away.
// PartManager supports selecting parts, but not in a doc/view separated way.
doc->setSelectable( false );
KoDocumentChild::setDocument( doc, tqgeometry );
}
KoDocument* KWDocumentChild::hitTest( const TQPoint& p, const TQWMatrix& _matrix )
{
Q_ASSERT( m_partFrameSet );
if ( isDeleted() || !document() ) {
return 0;
}
#if KDE_IS_VERSION( 3, 4, 0 )
int keyState = kapp->keyboardMouseState();
#else
int keyState = 0;
if ( kapp->keyboardModifiers() & KApplication::ControlModifier )
keyState = TQt::ControlButton;
#endif
// Only activate when it's already selected, and when not clicking on the border.
// KWFrameView and the part frame policy have that logic already.
KWView* kwView = ::tqqt_cast<KWView *>( parentDocument()->hitTestView() );
Q_ASSERT( kwView );
if ( kwView ) {
KWFrame* frame = m_partFrameSet->frame(0);
KWFrameView* frameView = kwView->frameViewManager()->view( frame );
Q_ASSERT( frameView );
MouseMeaning mouseMeaning = frameView->mouseMeaning( KoPoint( p ), keyState );
if ( mouseMeaning != MEANING_ACTIVATE_PART ) {
return 0;
}
}
return document()->hitTest( p, _matrix );
}
#include "KWPartFrameSet.moc"