kword

KWPartFrameSet.cpp

00001 /* This file is part of the KDE project
00002    Copyright (C) 2000-2005 David Faure <faure@kde.org>
00003    Copyright (C) 2005 Thomas Zander <zander@kde.org>
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License as published by the Free Software Foundation; either
00008    version 2 of the License, or (at your option) any later version.
00009 
00010    This library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public License
00016    along with this library; see the file COPYING.LIB.  If not, write to
00017    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018  * Boston, MA 02110-1301, USA.
00019 */
00020 
00021 #include "KWPartFrameSet.h"
00022 #include "KWDocument.h"
00023 #include "KWCommand.h"
00024 #include "KWordPartFrameSetIface.h"
00025 #include "KWFrameViewManager.h"
00026 #include "KWFrameView.h"
00027 #include "KWViewMode.h"
00028 
00029 #include <KoOasisContext.h>
00030 #include <KoXmlWriter.h>
00031 #include <KoXmlNS.h>
00032 
00033 #include <klocale.h>
00034 #include <kapplication.h>
00035 
00036 #include <assert.h>
00037 
00038 KWPartFrameSet::KWPartFrameSet( KWDocument *_doc, KWDocumentChild *_child, const QString & name )
00039     : KWFrameSet( _doc ), m_child( 0 ), m_cmdMoveChild( 0 ), m_protectContent( false )
00040 {
00041     if ( _child )
00042         setChild( _child );
00043 
00044     kdDebug(32001) << "KWPartFrameSet::KWPartFrameSet" << endl;
00045     if ( name.isEmpty() )
00046         m_name = _doc->generateFramesetName( i18n( "Object %1" ) );
00047     else
00048         m_name = name;
00049 }
00050 
00051 KWPartFrameSet::KWPartFrameSet( KWDocument* doc, const QDomElement& frameTag,
00052                                 const QDomElement& objectTag, KoOasisContext& context )
00053     : KWFrameSet( doc ), m_child( 0 ), m_cmdMoveChild( 0 ), m_protectContent( false )
00054 {
00055     m_name = frameTag.attributeNS( KoXmlNS::draw, "name", QString::null );
00056     if ( doc->frameSetByName( m_name ) ) // already exists!
00057         m_name = doc->generateFramesetName( m_name + " %1" );
00058 
00059     context.styleStack().save();
00060     context.fillStyleStack( frameTag, KoXmlNS::draw, "style-name", "graphic" ); // get the style for the graphics element
00061     KWFrame* frame = loadOasisFrame( frameTag, context );
00062     context.styleStack().restore();
00063 
00064     // Create a KWDocumentChild, without KoDocument inside
00065     KWDocumentChild* child = doc->createChildDoc( frame->rect(), 0 );
00066     setChild( child );
00067     child->loadOasis( frameTag, objectTag );
00068     updateChildGeometry();
00069 
00070     // This is what loads the KoDocument
00071     (void)child->loadOasisDocument( context.store(), context.manifestDocument() );
00072 }
00073 
00074 void KWPartFrameSet::setChild( KWDocumentChild* child )
00075 {
00076     assert( !m_child );
00077     m_child = child;
00078     m_child->setPartFrameSet( this );
00079     QObject::connect( m_child, SIGNAL( changed( KoChild * ) ),
00080                       this, SLOT( slotChildChanged() ) );
00081 }
00082 
00083 KWPartFrameSet::~KWPartFrameSet()
00084 {
00085 }
00086 
00087 KWordFrameSetIface* KWPartFrameSet::dcopObject()
00088 {
00089     if ( !m_dcop )
00090         m_dcop = new KWordPartFrameSetIface( this );
00091 
00092     return m_dcop;
00093 }
00094 
00095 
00096 void KWPartFrameSet::drawFrameContents( KWFrame* frame, QPainter * painter, const QRect & /*crect TODO*/,
00097                                         const QColorGroup &, bool onlyChanged, bool,
00098                                         KWFrameSetEdit *, KWViewMode * )
00099 {
00100     if (!onlyChanged)
00101     {
00102         if ( !m_child || !m_child->document() )
00103         {
00104             kdDebug(32001) << "KWPartFrameSet::drawFrameContents " << this << " aborting. child=" << m_child << " child->document()=" << m_child->document() << endl;
00105             return;
00106         }
00107 
00108         KoTextZoomHandler* zh = kWordDocument();
00109 
00110         // We have to define better the merning of the rect that we pass. Does it include zooming ? (yes I think)
00111         // Does it define the area to be repainted only? (no, that's the painter clip rect)
00112         // So it defines the whole area covered by the embedded document, in pixels.
00113         QRect rframe( 0, 0,
00114                       zh->zoomItX( frame->innerWidth() ),
00115                       zh->zoomItY( frame->innerHeight() ) );
00116         //kdDebug(32001) << "rframe=" << rframe << endl;
00117 
00118         double zoomX = static_cast<double>( zh->zoom() ) / 100;
00119         double zoomY = static_cast<double>( zh->zoom() ) / 100;
00120         m_child->document()->paintEverything( *painter, rframe, true, 0L, zoomX, zoomY );
00121 
00122     } //else kdDebug(32001) << "KWPartFrameSet::drawFrameContents " << this << " onlychanged=true!" << endl;
00123 }
00124 
00125 void KWPartFrameSet::updateChildGeometry()
00126 {
00127     if( m_frames.isEmpty() ) // Deleted frameset
00128         return;
00129         m_child->setGeometry( m_frames.first()->toQRect() );
00130 }
00131 
00132 void KWPartFrameSet::slotChildChanged()
00133 {
00134     // This is called when the KoDocumentChild is resized (using the KoFrame)
00135     QPtrListIterator<KWFrame> listFrame = frameIterator();
00136     KWFrame *frame = listFrame.current();
00137     if ( frame )
00138     {
00139         frame->setRect( KoRect::fromQRect( getChild()->geometry() ) );
00140 
00141         //kdDebug(32001) << "KWPartFrameSet::slotChildChanged child's geometry " << getChild()->geometry()
00142         //               << " frame set to " << *frame << endl;
00143         m_doc->frameChanged( frame );
00144         //there is just a frame
00145         if(m_cmdMoveChild)
00146             m_cmdMoveChild->listFrameMoved().newRect = frame->normalize();
00147     }
00148     else
00149         kdDebug(32001) << "Frame not found!" << endl;
00150 }
00151 
00152 QDomElement KWPartFrameSet::save( QDomElement &parentElem, bool saveFrames )
00153 {
00154     if ( m_frames.isEmpty() ) // Deleted frameset -> don't save
00155         return QDomElement();
00156     KWFrameSet::saveCommon( parentElem, saveFrames );
00157     // Ok, this one is a bit hackish. KWDocument calls us for saving our stuff into
00158     // the SETTINGS element, which it creates for us. So our save() doesn't really have
00159     // the same behaviour as a normal KWFrameSet::save()....
00160     return QDomElement();
00161 }
00162 
00163 void KWPartFrameSet::saveOasis( KoXmlWriter& writer, KoSavingContext& context, bool ) const
00164 {
00165     if ( m_frames.isEmpty() ) // Deleted frameset -> don't save
00166         return;
00167     // Save first frame with the whole contents
00168     KWFrame* frame = m_frames.getFirst();
00169     frame->startOasisFrame( writer, context.mainStyles(), name() );
00170 
00171     writer.startElement( "draw:object" );
00172     // #### let's hope name() is unique...
00173     m_child->saveOasisAttributes( writer, name() );
00174 
00175     writer.endElement(); // draw:object
00176     writer.endElement(); // draw:frame
00177 }
00178 
00179 void KWPartFrameSet::load( QDomElement &attributes, bool loadFrames )
00180 {
00181     KWFrameSet::load( attributes, loadFrames );
00182 }
00183 
00184 void KWPartFrameSet::startEditing()
00185 {
00186     // Content is protected -> can't edit. Maybe we should open part in readonly mode?
00187     if ( m_protectContent )
00188         return;
00189     kdDebug() << k_funcinfo << endl;
00190     //create undo/redo move command
00191     KWFrame* frame = m_frames.first();
00192     if (!frame)
00193         return;
00194     FrameIndex index( frame );
00195     FrameResizeStruct tmpMove( frame->normalize(), 0, KoRect() );
00196 
00197     if(!m_cmdMoveChild)
00198         m_cmdMoveChild=new KWFramePartMoveCommand( i18n("Move/Resize Frame"), index, tmpMove );
00199 }
00200 
00201 void KWPartFrameSet::endEditing()
00202 {
00203     kdDebug() << k_funcinfo << endl;
00204     if( m_cmdMoveChild && m_cmdMoveChild->frameMoved() )
00205         m_doc->addCommand(m_cmdMoveChild);
00206     else
00207         delete m_cmdMoveChild;
00208     m_cmdMoveChild=0L;
00209 
00210 }
00211 
00212 void KWPartFrameSet::moveFloatingFrame( int frameNum, const KoPoint &position )
00213 {
00214     //kdDebug()<<k_funcinfo<<" frame no="<<frameNum<<" to pos="<<position.x()<<","<<position.y()<<endl;
00215     KWFrame * frame = m_frames.at( frameNum );
00216     if ( frame )
00217     {
00218         KWFrameSet::moveFloatingFrame( frameNum, position );
00219         m_child->setGeometry( frame->toQRect(), true /* avoid circular events */ );
00220     }
00221 }
00222 
00223 KWFrameSetEdit * KWPartFrameSet::createFrameSetEdit( KWCanvas * /*canvas*/ )
00224 {
00225     return 0L; // new KWPartFrameSetEdit( this, canvas );
00226 }
00227 
00228 #ifndef NDEBUG
00229 void KWPartFrameSet::printDebug()
00230 {
00231     KWFrameSet::printDebug();
00232     kdDebug() << " +-- Object Document: " << endl;
00233     if ( getChild() )
00234     {
00235         if ( getChild()->document() )
00236             kdDebug() << "     Url : " << getChild()->document()->url().url()<<endl;
00237         else
00238             kdWarning() << "NO DOCUMENT" << endl;
00239         kdDebug() << "     Rectangle : " << getChild()->geometry().x() << "," << getChild()->geometry().y() << " " << getChild()->geometry().width() << "x" << getChild()->geometry().height() << endl;
00240     } else
00241         kdWarning() << "NO CHILD" << endl;
00242 }
00243 
00244 #endif
00245 
00246 void KWPartFrameSet::setDeleted( bool on)
00247 {
00248     m_child->setDeleted( on );
00249 }
00250 
00251 void KWPartFrameSet::deleteFrame( unsigned int _num, bool remove, bool recalc )
00252 {
00253     KWFrameSet::deleteFrame( _num, remove, recalc );
00254     if ( m_frames.isEmpty() )         // then the whole frameset and thus the child is deleted
00255         m_child->setDeleted();
00256 }
00257 
00258 void KWPartFrameSet::KWPartFrameSet::createEmptyRegion( const QRect &crect, QRegion &emptyRegion, KWViewMode *viewMode ) {
00259     Q_UNUSED(crect);
00260     Q_UNUSED(emptyRegion);
00261     Q_UNUSED(viewMode);
00262 
00263     // empty implementation since embedded parts can be transparant.
00264 }
00265 
00266 #if 0
00267 KWPartFrameSetEdit::KWPartFrameSetEdit( KWPartFrameSet * fs, KWCanvas * canvas )
00268     : KWFrameSetEdit( fs, canvas )
00269 {
00270     kdDebug(32001) << "KWPartFrameSetEdit::KWPartFrameSetEdit " << endl;
00271     m_dcop=0L;
00272     fs->startEditing();
00273     QObject::connect( m_canvas->gui()->getView(), SIGNAL( activated( bool ) ),
00274                       this, SLOT( slotChildActivated( bool ) ) );
00275 }
00276 
00277 KWPartFrameSetEdit::~KWPartFrameSetEdit()
00278 {
00279     kdDebug(32001) << "KWPartFrameSetEdit::~KWPartFrameSetEdit" << endl;
00280     delete m_dcop;
00281 }
00282 
00283 DCOPObject* KWPartFrameSetEdit::dcopObject()
00284 {
00285     if ( !m_dcop )
00286         m_dcop = new KWordPartFrameSetEditIface( this );
00287     return m_dcop;
00288 }
00289 
00290 void KWPartFrameSetEdit::slotChildActivated(bool b)
00291 {
00292     kdDebug() << "KWPartFrameSetEdit::slotChildActivated " << b << endl;
00293     //we store command when we deactivate the child.
00294     if( !b )
00295         partFrameSet()->endEditing();
00296 
00297 }
00298 #endif
00299 
00300 void KWPartFrameSet::storeInternal()
00301 {
00302     if ( getChild()->document()->storeInternal() )
00303     {
00304         KWFramePartExternalCommand* cmd =new KWFramePartExternalCommand( i18n("Make Document External"), this );
00305         m_doc->addCommand(cmd);
00306         getChild()->document()->setStoreInternal(false);
00307     }
00308     else
00309     {
00310         KWFramePartInternalCommand* cmd =new KWFramePartInternalCommand( i18n("Make Document Internal"), this );
00311         m_doc->addCommand(cmd);
00312         getChild()->document()->setStoreInternal(true);
00313     }
00314 
00315     kdDebug()<<k_funcinfo<<"url: "<<getChild()->url().url()<<" store internal="<<getChild()->document()->storeInternal()<<endl;
00316 }
00317 
00318 
00319 /******************************************************************/
00320 /* Class: KWDocumentChild                                              */
00321 /******************************************************************/
00322 
00323 KWDocumentChild::KWDocumentChild( KWDocument *_wdoc, const QRect& _rect, KoDocument *_doc )
00324     : KoDocumentChild( _wdoc, _doc, _rect ), m_partFrameSet( 0 )
00325 {
00326 }
00327 
00328 KWDocumentChild::KWDocumentChild( KWDocument *_wdoc )
00329     : KoDocumentChild( _wdoc ), m_partFrameSet( 0 )
00330 {
00331 }
00332 
00333 KWDocumentChild::~KWDocumentChild()
00334 {
00335 }
00336 
00337 void KWDocumentChild::setDocument( KoDocument *doc, const QRect &geometry )
00338 {
00339     // When hitTest returns true, we want to activate the part right away.
00340     // PartManager supports selecting parts, but not in a doc/view separated way.
00341     doc->setSelectable( false );
00342     KoDocumentChild::setDocument( doc, geometry );
00343 }
00344 
00345 KoDocument* KWDocumentChild::hitTest( const QPoint& p, const QWMatrix& _matrix )
00346 {
00347     Q_ASSERT( m_partFrameSet );
00348     if ( isDeleted() || !document() ) {
00349         return 0;
00350     }
00351 
00352 #if KDE_IS_VERSION( 3, 4, 0 )
00353     int keyState = kapp->keyboardMouseState();
00354 #else
00355     int keyState = 0;
00356     if ( kapp->keyboardModifiers() & KApplication::ControlModifier )
00357         keyState = Qt::ControlButton;
00358 #endif
00359 
00360     // Only activate when it's already selected, and when not clicking on the border.
00361     // KWFrameView and the part frame policy have that logic already.
00362     KWView* kwView = ::qt_cast<KWView *>( parentDocument()->hitTestView() );
00363     Q_ASSERT( kwView );
00364     if ( kwView ) {
00365         KWFrame* frame = m_partFrameSet->frame(0);
00366         KWFrameView* frameView = kwView->frameViewManager()->view( frame );
00367         Q_ASSERT( frameView );
00368         MouseMeaning mouseMeaning = frameView->mouseMeaning( KoPoint( p ), keyState );
00369         if ( mouseMeaning != MEANING_ACTIVATE_PART ) {
00370             return 0;
00371         }
00372     }
00373 
00374     return document()->hitTest( p, _matrix );
00375 }
00376 
00377 #include "KWPartFrameSet.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys