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
00105                 << " child->document()=" << (m_child?m_child->document():0) << endl;
00106             return;
00107         }
00108 
00109         KoTextZoomHandler* zh = kWordDocument();
00110 
00111         // We have to define better the merning of the rect that we pass. Does it include zooming ? (yes I think)
00112         // Does it define the area to be repainted only? (no, that's the painter clip rect)
00113         // So it defines the whole area covered by the embedded document, in pixels.
00114         QRect rframe( 0, 0,
00115                       zh->zoomItX( frame->innerWidth() ),
00116                       zh->zoomItY( frame->innerHeight() ) );
00117         //kdDebug(32001) << "rframe=" << rframe << endl;
00118 
00119         double zoomX = static_cast<double>( zh->zoom() ) / 100;
00120         double zoomY = static_cast<double>( zh->zoom() ) / 100;
00121         m_child->document()->paintEverything( *painter, rframe, true, 0L, zoomX, zoomY );
00122 
00123     } //else kdDebug(32001) << "KWPartFrameSet::drawFrameContents " << this << " onlychanged=true!" << endl;
00124 }
00125 
00126 void KWPartFrameSet::updateChildGeometry()
00127 {
00128     if( m_frames.isEmpty() ) // Deleted frameset
00129         return;
00130         m_child->setGeometry( m_frames.first()->toQRect() );
00131 }
00132 
00133 void KWPartFrameSet::slotChildChanged()
00134 {
00135     // This is called when the KoDocumentChild is resized (using the KoFrame)
00136     QPtrListIterator<KWFrame> listFrame = frameIterator();
00137     KWFrame *frame = listFrame.current();
00138     if ( frame )
00139     {
00140         frame->setRect( KoRect::fromQRect( getChild()->geometry() ) );
00141 
00142         //kdDebug(32001) << "KWPartFrameSet::slotChildChanged child's geometry " << getChild()->geometry()
00143         //               << " frame set to " << *frame << endl;
00144         m_doc->frameChanged( frame );
00145         //there is just a frame
00146         if(m_cmdMoveChild)
00147             m_cmdMoveChild->listFrameMoved().newRect = frame->normalize();
00148     }
00149     else
00150         kdDebug(32001) << "Frame not found!" << endl;
00151 }
00152 
00153 QDomElement KWPartFrameSet::save( QDomElement &parentElem, bool saveFrames )
00154 {
00155     if ( m_frames.isEmpty() ) // Deleted frameset -> don't save
00156         return QDomElement();
00157     KWFrameSet::saveCommon( parentElem, saveFrames );
00158     // Ok, this one is a bit hackish. KWDocument calls us for saving our stuff into
00159     // the SETTINGS element, which it creates for us. So our save() doesn't really have
00160     // the same behaviour as a normal KWFrameSet::save()....
00161     return QDomElement();
00162 }
00163 
00164 void KWPartFrameSet::saveOasis( KoXmlWriter& writer, KoSavingContext& context, bool ) const
00165 {
00166     if ( m_frames.isEmpty() ) // Deleted frameset -> don't save
00167         return;
00168     // Save first frame with the whole contents
00169     KWFrame* frame = m_frames.getFirst();
00170     frame->startOasisFrame( writer, context.mainStyles(), name() );
00171 
00172     writer.startElement( "draw:object" );
00173     // #### let's hope name() is unique...
00174     m_child->saveOasisAttributes( writer, name() );
00175 
00176     writer.endElement(); // draw:object
00177     writer.endElement(); // draw:frame
00178 }
00179 
00180 void KWPartFrameSet::load( QDomElement &attributes, bool loadFrames )
00181 {
00182     KWFrameSet::load( attributes, loadFrames );
00183 }
00184 
00185 void KWPartFrameSet::startEditing()
00186 {
00187     // Content is protected -> can't edit. Maybe we should open part in readonly mode?
00188     if ( m_protectContent )
00189         return;
00190     kdDebug() << k_funcinfo << endl;
00191     //create undo/redo move command
00192     KWFrame* frame = m_frames.first();
00193     if (!frame)
00194         return;
00195     FrameIndex index( frame );
00196     FrameResizeStruct tmpMove( frame->normalize(), 0, KoRect() );
00197 
00198     if(!m_cmdMoveChild)
00199         m_cmdMoveChild=new KWFramePartMoveCommand( i18n("Move/Resize Frame"), index, tmpMove );
00200 }
00201 
00202 void KWPartFrameSet::endEditing()
00203 {
00204     kdDebug() << k_funcinfo << endl;
00205     if( m_cmdMoveChild && m_cmdMoveChild->frameMoved() )
00206         m_doc->addCommand(m_cmdMoveChild);
00207     else
00208         delete m_cmdMoveChild;
00209     m_cmdMoveChild=0L;
00210 
00211 }
00212 
00213 void KWPartFrameSet::moveFloatingFrame( int frameNum, const KoPoint &position )
00214 {
00215     //kdDebug()<<k_funcinfo<<" frame no="<<frameNum<<" to pos="<<position.x()<<","<<position.y()<<endl;
00216     KWFrame * frame = m_frames.at( frameNum );
00217     if ( frame )
00218     {
00219         KWFrameSet::moveFloatingFrame( frameNum, position );
00220         m_child->setGeometry( frame->toQRect(), true /* avoid circular events */ );
00221     }
00222 }
00223 
00224 KWFrameSetEdit * KWPartFrameSet::createFrameSetEdit( KWCanvas * /*canvas*/ )
00225 {
00226     return 0L; // new KWPartFrameSetEdit( this, canvas );
00227 }
00228 
00229 #ifndef NDEBUG
00230 void KWPartFrameSet::printDebug()
00231 {
00232     KWFrameSet::printDebug();
00233     kdDebug() << " +-- Object Document: " << endl;
00234     if ( getChild() )
00235     {
00236         if ( getChild()->document() )
00237             kdDebug() << "     Url : " << getChild()->document()->url().url()<<endl;
00238         else
00239             kdWarning() << "NO DOCUMENT" << endl;
00240         kdDebug() << "     Rectangle : " << getChild()->geometry().x() << "," << getChild()->geometry().y() << " " << getChild()->geometry().width() << "x" << getChild()->geometry().height() << endl;
00241     } else
00242         kdWarning() << "NO CHILD" << endl;
00243 }
00244 
00245 #endif
00246 
00247 void KWPartFrameSet::setDeleted( bool on)
00248 {
00249     m_child->setDeleted( on );
00250 }
00251 
00252 void KWPartFrameSet::deleteFrame( unsigned int _num, bool remove, bool recalc )
00253 {
00254     KWFrameSet::deleteFrame( _num, remove, recalc );
00255     if ( m_frames.isEmpty() )         // then the whole frameset and thus the child is deleted
00256         m_child->setDeleted();
00257 }
00258 
00259 void KWPartFrameSet::KWPartFrameSet::createEmptyRegion( const QRect &crect, QRegion &emptyRegion, KWViewMode *viewMode ) {
00260     Q_UNUSED(crect);
00261     Q_UNUSED(emptyRegion);
00262     Q_UNUSED(viewMode);
00263 
00264     // empty implementation since embedded parts can be transparant.
00265 }
00266 
00267 #if 0
00268 KWPartFrameSetEdit::KWPartFrameSetEdit( KWPartFrameSet * fs, KWCanvas * canvas )
00269     : KWFrameSetEdit( fs, canvas )
00270 {
00271     kdDebug(32001) << "KWPartFrameSetEdit::KWPartFrameSetEdit " << endl;
00272     m_dcop=0L;
00273     fs->startEditing();
00274     QObject::connect( m_canvas->gui()->getView(), SIGNAL( activated( bool ) ),
00275                       this, SLOT( slotChildActivated( bool ) ) );
00276 }
00277 
00278 KWPartFrameSetEdit::~KWPartFrameSetEdit()
00279 {
00280     kdDebug(32001) << "KWPartFrameSetEdit::~KWPartFrameSetEdit" << endl;
00281     delete m_dcop;
00282 }
00283 
00284 DCOPObject* KWPartFrameSetEdit::dcopObject()
00285 {
00286     if ( !m_dcop )
00287         m_dcop = new KWordPartFrameSetEditIface( this );
00288     return m_dcop;
00289 }
00290 
00291 void KWPartFrameSetEdit::slotChildActivated(bool b)
00292 {
00293     kdDebug() << "KWPartFrameSetEdit::slotChildActivated " << b << endl;
00294     //we store command when we deactivate the child.
00295     if( !b )
00296         partFrameSet()->endEditing();
00297 
00298 }
00299 #endif
00300 
00301 void KWPartFrameSet::storeInternal()
00302 {
00303     if ( getChild()->document()->storeInternal() )
00304     {
00305         KWFramePartExternalCommand* cmd =new KWFramePartExternalCommand( i18n("Make Document External"), this );
00306         m_doc->addCommand(cmd);
00307         getChild()->document()->setStoreInternal(false);
00308     }
00309     else
00310     {
00311         KWFramePartInternalCommand* cmd =new KWFramePartInternalCommand( i18n("Make Document Internal"), this );
00312         m_doc->addCommand(cmd);
00313         getChild()->document()->setStoreInternal(true);
00314     }
00315 
00316     kdDebug()<<k_funcinfo<<"url: "<<getChild()->url().url()<<" store internal="<<getChild()->document()->storeInternal()<<endl;
00317 }
00318 
00319 
00320 /******************************************************************/
00321 /* Class: KWDocumentChild                                              */
00322 /******************************************************************/
00323 
00324 KWDocumentChild::KWDocumentChild( KWDocument *_wdoc, const QRect& _rect, KoDocument *_doc )
00325     : KoDocumentChild( _wdoc, _doc, _rect ), m_partFrameSet( 0 )
00326 {
00327 }
00328 
00329 KWDocumentChild::KWDocumentChild( KWDocument *_wdoc )
00330     : KoDocumentChild( _wdoc ), m_partFrameSet( 0 )
00331 {
00332 }
00333 
00334 KWDocumentChild::~KWDocumentChild()
00335 {
00336 }
00337 
00338 void KWDocumentChild::setDocument( KoDocument *doc, const QRect &geometry )
00339 {
00340     // When hitTest returns true, we want to activate the part right away.
00341     // PartManager supports selecting parts, but not in a doc/view separated way.
00342     doc->setSelectable( false );
00343     KoDocumentChild::setDocument( doc, geometry );
00344 }
00345 
00346 KoDocument* KWDocumentChild::hitTest( const QPoint& p, const QWMatrix& _matrix )
00347 {
00348     Q_ASSERT( m_partFrameSet );
00349     if ( isDeleted() || !document() ) {
00350         return 0;
00351     }
00352 
00353 #if KDE_IS_VERSION( 3, 4, 0 )
00354     int keyState = kapp->keyboardMouseState();
00355 #else
00356     int keyState = 0;
00357     if ( kapp->keyboardModifiers() & KApplication::ControlModifier )
00358         keyState = Qt::ControlButton;
00359 #endif
00360 
00361     // Only activate when it's already selected, and when not clicking on the border.
00362     // KWFrameView and the part frame policy have that logic already.
00363     KWView* kwView = ::qt_cast<KWView *>( parentDocument()->hitTestView() );
00364     Q_ASSERT( kwView );
00365     if ( kwView ) {
00366         KWFrame* frame = m_partFrameSet->frame(0);
00367         KWFrameView* frameView = kwView->frameViewManager()->view( frame );
00368         Q_ASSERT( frameView );
00369         MouseMeaning mouseMeaning = frameView->mouseMeaning( KoPoint( p ), keyState );
00370         if ( mouseMeaning != MEANING_ACTIVATE_PART ) {
00371             return 0;
00372         }
00373     }
00374 
00375     return document()->hitTest( p, _matrix );
00376 }
00377 
00378 #include "KWPartFrameSet.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys