LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/sw/source/core/ole - ndole.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 200 428 46.7 %
Date: 2013-07-09 Functions: 35 54 64.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
      21             : #include <com/sun/star/container/XChild.hpp>
      22             : #include <com/sun/star/embed/XEmbedPersist.hpp>
      23             : #include <com/sun/star/embed/XLinkageSupport.hpp>
      24             : #include <com/sun/star/embed/Aspects.hpp>
      25             : #include <com/sun/star/embed/EmbedMisc.hpp>
      26             : #include <com/sun/star/embed/EmbedStates.hpp>
      27             : #include <com/sun/star/util/XCloseable.hpp>
      28             : #include <com/sun/star/util/XModifiable.hpp>
      29             : #include <com/sun/star/document/XEventBroadcaster.hpp>
      30             : #include <com/sun/star/chart2/XChartDocument.hpp>   // #i119941
      31             : #include <cppuhelper/implbase1.hxx>
      32             : 
      33             : #include <cppuhelper/implbase2.hxx>
      34             : #include <toolkit/helper/vclunohelper.hxx>
      35             : #include <hintids.hxx>
      36             : #include <sfx2/docfile.hxx>
      37             : #include <sfx2/app.hxx>
      38             : #include <sfx2/linkmgr.hxx>
      39             : #include <unotools/configitem.hxx>
      40             : #include <vcl/outdev.hxx>
      41             : #include <fmtanchr.hxx>
      42             : #include <frmfmt.hxx>
      43             : #include <doc.hxx>
      44             : #include <docsh.hxx>
      45             : #include <pam.hxx>
      46             : #include <section.hxx>
      47             : #include <cntfrm.hxx>
      48             : #include <frmatr.hxx>
      49             : #include <ndole.hxx>
      50             : 
      51             : #include <comphelper/classids.hxx>
      52             : #include <vcl/graph.hxx>
      53             : #include <sot/formats.hxx>
      54             : #include <unotools/ucbstreamhelper.hxx>
      55             : #include <vcl/graphicfilter.hxx>
      56             : #include <comcore.hrc>
      57             : 
      58             : using namespace utl;
      59             : using namespace com::sun::star::uno;
      60             : using namespace com::sun::star;
      61             : 
      62         142 : class SwOLELRUCache
      63             :     : private utl::ConfigItem
      64             : {
      65             : private:
      66             :     typedef std::deque<SwOLEObj *> OleObjects_t;
      67             :     OleObjects_t m_OleObjects;
      68             :     sal_Int32 m_nLRU_InitSize;
      69             :     uno::Sequence< OUString > GetPropertyNames();
      70             : 
      71             : public:
      72             :     SwOLELRUCache();
      73             : 
      74             :     virtual void Notify( const uno::Sequence<
      75             :                                 OUString>& aPropertyNames );
      76             :     virtual void Commit();
      77             :     void Load();
      78             : 
      79             :     void InsertObj( SwOLEObj& rObj );
      80             :     void RemoveObj( SwOLEObj& rObj );
      81             : 
      82             :     void RemovePtr( SwOLEObj* pObj )
      83             :     {
      84             :         OleObjects_t::iterator const it =
      85             :             std::find(m_OleObjects.begin(), m_OleObjects.end(), pObj);
      86             :         if (it != m_OleObjects.end())
      87             :         {
      88             :             m_OleObjects.erase(it);
      89             :         }
      90             :     }
      91             : };
      92             : 
      93             : SwOLELRUCache* pOLELRU_Cache = 0;
      94             : 
      95         324 : class SwOLEListener_Impl : public ::cppu::WeakImplHelper1< embed::XStateChangeListener >
      96             : {
      97             :     SwOLEObj* mpObj;
      98             : public:
      99             :     SwOLEListener_Impl( SwOLEObj* pObj );
     100             :     void Release();
     101             :     virtual void SAL_CALL changingState( const lang::EventObject& aEvent, ::sal_Int32 nOldState, ::sal_Int32 nNewState ) throw (embed::WrongStateException, uno::RuntimeException);
     102             :     virtual void SAL_CALL stateChanged( const lang::EventObject& aEvent, ::sal_Int32 nOldState, ::sal_Int32 nNewState ) throw (uno::RuntimeException);
     103             :     virtual void SAL_CALL disposing( const lang::EventObject& aEvent ) throw (uno::RuntimeException);
     104             : };
     105             : 
     106         162 : SwOLEListener_Impl::SwOLEListener_Impl( SwOLEObj* pObj )
     107         162 : : mpObj( pObj )
     108             : {
     109         162 :     if ( mpObj->IsOleRef() && mpObj->GetOleRef()->getCurrentState() == embed::EmbedStates::RUNNING )
     110             :     {
     111         151 :         pOLELRU_Cache->InsertObj( *mpObj );
     112             :     }
     113         162 : }
     114             : 
     115           6 : void SAL_CALL SwOLEListener_Impl::changingState( const lang::EventObject&, ::sal_Int32 , ::sal_Int32 ) throw (embed::WrongStateException, uno::RuntimeException)
     116             : {
     117           6 : }
     118             : 
     119           3 : void SAL_CALL SwOLEListener_Impl::stateChanged( const lang::EventObject&, ::sal_Int32 nOldState, ::sal_Int32 nNewState ) throw (uno::RuntimeException)
     120             : {
     121           3 :     if ( mpObj && nOldState == embed::EmbedStates::LOADED && nNewState == embed::EmbedStates::RUNNING )
     122             :     {
     123           0 :         if( !pOLELRU_Cache )
     124           0 :             pOLELRU_Cache = new SwOLELRUCache;
     125           0 :         pOLELRU_Cache->InsertObj( *mpObj );
     126             :     }
     127           3 :     else if ( mpObj && nNewState == embed::EmbedStates::LOADED && nOldState == embed::EmbedStates::RUNNING )
     128             :     {
     129           1 :         if ( pOLELRU_Cache )
     130           1 :             pOLELRU_Cache->RemoveObj( *mpObj );
     131             :     }
     132           3 : }
     133             : 
     134         162 : void SwOLEListener_Impl::Release()
     135             : {
     136         162 :     if ( mpObj && pOLELRU_Cache )
     137         150 :         pOLELRU_Cache->RemoveObj( *mpObj );
     138         162 :     mpObj=0;
     139         162 :     release();
     140         162 : }
     141             : 
     142           0 : void SAL_CALL SwOLEListener_Impl::disposing( const lang::EventObject& ) throw (uno::RuntimeException)
     143             : {
     144           0 :     if ( mpObj && pOLELRU_Cache )
     145           0 :         pOLELRU_Cache->RemoveObj( *mpObj );
     146           0 : }
     147             : 
     148             : // --------------------
     149             : // SwEmbedObjectLink
     150             : // --------------------
     151             : // TODO/LATER: actually SwEmbedObjectLink should be used here, but because different objects are used to control
     152             : //             embedded object different link objects with the same functionality had to be implemented
     153             : 
     154             : class SwEmbedObjectLink : public sfx2::SvBaseLink
     155             : {
     156             :     SwOLENode*          pOleNode;
     157             : 
     158             : public:
     159             :                         SwEmbedObjectLink(SwOLENode* pNode);
     160             :     virtual             ~SwEmbedObjectLink();
     161             : 
     162             :     virtual void        Closed();
     163             :     virtual ::sfx2::SvBaseLink::UpdateResult DataChanged(
     164             :         const String& rMimeType, const ::com::sun::star::uno::Any & rValue );
     165             : 
     166           0 :     bool            Connect() { return GetRealObject() != NULL; }
     167             : };
     168             : 
     169             : // -----------------------------------------------------------------------------
     170             : 
     171           0 : SwEmbedObjectLink::SwEmbedObjectLink(SwOLENode* pNode):
     172             :     ::sfx2::SvBaseLink( ::sfx2::LINKUPDATE_ONCALL, SOT_FORMATSTR_ID_SVXB ),
     173           0 :     pOleNode(pNode)
     174             : {
     175           0 :     SetSynchron( sal_False );
     176           0 : }
     177             : 
     178             : // -----------------------------------------------------------------------------
     179             : 
     180           0 : SwEmbedObjectLink::~SwEmbedObjectLink()
     181             : {
     182           0 : }
     183             : 
     184             : // -----------------------------------------------------------------------------
     185             : 
     186           0 : ::sfx2::SvBaseLink::UpdateResult SwEmbedObjectLink::DataChanged(
     187             :     const String&, const uno::Any& )
     188             : {
     189           0 :     if ( !pOleNode->UpdateLinkURL_Impl() )
     190             :     {
     191             :         // the link URL was not changed
     192           0 :         uno::Reference< embed::XEmbeddedObject > xObject = pOleNode->GetOLEObj().GetOleRef();
     193             :         OSL_ENSURE( xObject.is(), "The object must exist always!\n" );
     194           0 :         if ( xObject.is() )
     195             :         {
     196             :             // let the object reload the link
     197             :             // TODO/LATER: reload call could be used for this case
     198             : 
     199             :             try
     200             :             {
     201           0 :                 sal_Int32 nState = xObject->getCurrentState();
     202           0 :                 if ( nState != embed::EmbedStates::LOADED )
     203             :                 {
     204             :                     // in some cases the linked file probably is not locked so it could be changed
     205           0 :                     xObject->changeState( embed::EmbedStates::LOADED );
     206           0 :                     xObject->changeState( nState );
     207             :                 }
     208             :             }
     209           0 :             catch ( uno::Exception& )
     210             :             {
     211             :             }
     212           0 :         }
     213             :     }
     214             : 
     215           0 :     pOleNode->GetNewReplacement();
     216           0 :     return SUCCESS;
     217             : }
     218             : 
     219             : // -----------------------------------------------------------------------------
     220             : 
     221           0 : void SwEmbedObjectLink::Closed()
     222             : {
     223           0 :     pOleNode->BreakFileLink_Impl();
     224           0 :     SvBaseLink::Closed();
     225           0 : }
     226             : 
     227             : 
     228             : // --------------------
     229             : // SwOLENode
     230             : // --------------------
     231             : 
     232         151 : SwOLENode::SwOLENode( const SwNodeIndex &rWhere,
     233             :                     const svt::EmbeddedObjectRef& xObj,
     234             :                     SwGrfFmtColl *pGrfColl,
     235             :                     SwAttrSet* pAutoAttr ) :
     236             :     SwNoTxtNode( rWhere, ND_OLENODE, pGrfColl, pAutoAttr ),
     237             :     aOLEObj( xObj ),
     238             :     pGraphic(0),
     239             :     bOLESizeInvalid( sal_False ),
     240         151 :     mpObjectLink( NULL )
     241             : {
     242         151 :     aOLEObj.SetNode( this );
     243         151 : }
     244             : 
     245          11 : SwOLENode::SwOLENode( const SwNodeIndex &rWhere,
     246             :                     const String &rString,
     247             :                     sal_Int64 nAspect,
     248             :                     SwGrfFmtColl *pGrfColl,
     249             :                     SwAttrSet* pAutoAttr ) :
     250             :     SwNoTxtNode( rWhere, ND_OLENODE, pGrfColl, pAutoAttr ),
     251             :     aOLEObj( rString, nAspect ),
     252             :     pGraphic(0),
     253             :     bOLESizeInvalid( sal_False ),
     254          11 :     mpObjectLink( NULL )
     255             : {
     256          11 :     aOLEObj.SetNode( this );
     257          11 : }
     258             : 
     259         486 : SwOLENode::~SwOLENode()
     260             : {
     261         162 :     DisconnectFileLink_Impl();
     262         162 :     delete pGraphic;
     263         324 : }
     264             : 
     265          40 : const Graphic* SwOLENode::GetGraphic()
     266             : {
     267          40 :     if ( aOLEObj.GetOleRef().is() )
     268          40 :         return aOLEObj.xOLERef.GetGraphic();
     269           0 :     return pGraphic;
     270             : }
     271             : 
     272           0 : SwCntntNode *SwOLENode::SplitCntntNode( const SwPosition & )
     273             : {
     274             :     // OLE-Objecte vervielfaeltigen ??
     275             :     OSL_FAIL( "OleNode: can't split." );
     276           0 :     return this;
     277             : }
     278             : 
     279             : // Laden eines in den Undo-Bereich verschobenen OLE-Objekts
     280             : 
     281           0 : sal_Bool SwOLENode::RestorePersistentData()
     282             : {
     283             :     OSL_ENSURE( aOLEObj.GetOleRef().is(), "No object to restore!" );
     284           0 :     if ( aOLEObj.xOLERef.is() )
     285             :     {
     286             :         // Falls bereits eine SvPersist-Instanz existiert, nehmen wir diese
     287           0 :         SfxObjectShell* p = GetDoc()->GetPersist();
     288           0 :         if( !p )
     289             :         {
     290             :             // TODO/LATER: reicht hier nicht ein EmbeddedObjectContainer? Was passiert mit
     291             :             // diesem Dokument?
     292             :             OSL_ENSURE( !this, "warum wird hier eine DocShell angelegt?" );
     293           0 :             p = new SwDocShell( GetDoc(), SFX_CREATE_MODE_INTERNAL );
     294           0 :             p->DoInitNew( NULL );
     295             :         }
     296             : 
     297           0 :         uno::Reference < container::XChild > xChild( aOLEObj.xOLERef.GetObject(), uno::UNO_QUERY );
     298           0 :         if ( xChild.is() )
     299           0 :             xChild->setParent( p->GetModel() );
     300             : 
     301             :         OSL_ENSURE( aOLEObj.aName.Len(), "No object name!" );
     302           0 :         OUString aObjName;
     303           0 :         if ( !p->GetEmbeddedObjectContainer().InsertEmbeddedObject( aOLEObj.xOLERef.GetObject(), aObjName ) )
     304             :         {
     305           0 :             if ( xChild.is() )
     306           0 :                 xChild->setParent( 0 );
     307             :             OSL_FAIL( "InsertObject failed" );
     308             :         }
     309             :         else
     310             :         {
     311           0 :             aOLEObj.aName = aObjName;
     312           0 :             aOLEObj.xOLERef.AssignToContainer( &p->GetEmbeddedObjectContainer(), aObjName );
     313           0 :             CheckFileLink_Impl();
     314           0 :         }
     315             :     }
     316             : 
     317           0 :     return sal_True;
     318             : }
     319             : 
     320             : // OLE object is transported into UNDO area
     321           1 : sal_Bool SwOLENode::SavePersistentData()
     322             : {
     323           1 :     if( aOLEObj.xOLERef.is() )
     324             :     {
     325           1 :         comphelper::EmbeddedObjectContainer* pCnt = aOLEObj.xOLERef.GetContainer();
     326             : 
     327             : #if OSL_DEBUG_LEVEL > 0
     328             :         SfxObjectShell* p = GetDoc()->GetPersist();
     329             :         OSL_ENSURE( p, "No document!" );
     330             :         if( p )
     331             :         {
     332             :             comphelper::EmbeddedObjectContainer& rCnt = p->GetEmbeddedObjectContainer();
     333             :             OSL_ENSURE( !pCnt || &rCnt == pCnt, "The helper is assigned to unexpected container!\n" );
     334             :         }
     335             : #endif
     336             : 
     337           1 :         if ( pCnt && pCnt->HasEmbeddedObject( aOLEObj.aName ) )
     338             :         {
     339           1 :             uno::Reference < container::XChild > xChild( aOLEObj.xOLERef.GetObject(), uno::UNO_QUERY );
     340           1 :             if ( xChild.is() )
     341           1 :                 xChild->setParent( 0 );
     342             : 
     343             :           // pCnt->RemoveEmbeddedObject( aOLEObj.aName, sal_False );
     344             :            /* #i119941: When cut or move the chart, SwUndoFlyBase::DelFly will call SaveSection to store the comtent to strorage.
     345             :            In this step, chart filter functions will be called. And chart filter will call chart core functions to create the chart again.
     346             :            Then chart core function will call the class ExplicitCategoryProvider to create data source.
     347             :            In this step, when SW data source provider create the data source, it will create a new SwFlyFrm.
     348             :            But later in SwUndoFlyBase::DelFly, it will clear anchor related attributes of SwFlyFrm. Then finally null pointer occur.
     349             :            Resolution:
     350             :            In pCnt->RemoveEmbeddedObject in SaveSection process of table chart, only remove the object from the object container,
     351             :            without removing it's storage and graphic stream. The chart already removed from formatter.> */
     352           1 :            sal_Bool bChartWithInternalProvider = sal_False;
     353           1 :            sal_Bool bKeepObjectToTempStorage = sal_True;
     354           2 :            uno::Reference < embed::XEmbeddedObject > xIP = GetOLEObj().GetOleRef();
     355           1 :            if ( svt::EmbeddedObjectRef::TryRunningState( xIP ) )
     356             :            {
     357           1 :                uno::Reference< chart2::XChartDocument > xChart( xIP->getComponent(), UNO_QUERY );
     358           1 :                if ( xChart.is() && xChart->hasInternalDataProvider() )
     359           1 :                    bChartWithInternalProvider = sal_True;
     360             :            }
     361             : 
     362           1 :            if ( IsChart() && sChartTblName.Len() && !bChartWithInternalProvider )
     363           0 :                bKeepObjectToTempStorage = sal_False;
     364           1 :            pCnt->RemoveEmbeddedObject( aOLEObj.aName, sal_False, bKeepObjectToTempStorage );
     365             :            // modify end
     366             : 
     367             : 
     368             :             // TODO/LATER: aOLEObj.aName has no meaning here, since the undo container contains the object
     369             :             // by different name, in future it might makes sence that the name is transported here.
     370           1 :             aOLEObj.xOLERef.AssignToContainer( 0, aOLEObj.aName );
     371             :             try
     372             :             {
     373             :                 // "unload" object
     374           1 :                 aOLEObj.xOLERef->changeState( embed::EmbedStates::LOADED );
     375             :             }
     376           0 :             catch ( uno::Exception& )
     377             :             {
     378           1 :             }
     379             :         }
     380             :     }
     381             : 
     382           1 :     DisconnectFileLink_Impl();
     383             : 
     384           1 :     return sal_True;
     385             : }
     386             : 
     387             : 
     388         151 : SwOLENode * SwNodes::MakeOLENode( const SwNodeIndex & rWhere,
     389             :                     const svt::EmbeddedObjectRef& xObj,
     390             :                                     SwGrfFmtColl* pGrfColl,
     391             :                                     SwAttrSet* pAutoAttr )
     392             : {
     393             :     OSL_ENSURE( pGrfColl,"SwNodes::MakeOLENode: Formatpointer ist 0." );
     394             : 
     395             :     SwOLENode *pNode =
     396         151 :         new SwOLENode( rWhere, xObj, pGrfColl, pAutoAttr );
     397             : 
     398             :     // set parent if XChild is supported
     399             :     //!! needed to supply Math objects with a valid reference device
     400         151 :     uno::Reference< container::XChild > xChild( pNode->GetOLEObj().GetObject().GetObject(), UNO_QUERY );
     401         151 :     if (xChild.is())
     402             :     {
     403         151 :         SwDocShell *pDocSh = GetDoc()->GetDocShell();
     404         151 :         if (pDocSh)
     405         151 :             xChild->setParent( pDocSh->GetModel() );
     406             :     }
     407             : 
     408         151 :     return pNode;
     409             : }
     410             : 
     411             : 
     412          11 : SwOLENode * SwNodes::MakeOLENode( const SwNodeIndex & rWhere,
     413             :     const String &rName, sal_Int64 nAspect, SwGrfFmtColl* pGrfColl, SwAttrSet* pAutoAttr )
     414             : {
     415             :     OSL_ENSURE( pGrfColl,"SwNodes::MakeOLENode: Formatpointer ist 0." );
     416             : 
     417             :     SwOLENode *pNode =
     418          11 :         new SwOLENode( rWhere, rName, nAspect, pGrfColl, pAutoAttr );
     419             : 
     420             :     // set parent if XChild is supported
     421             :     //!! needed to supply Math objects with a valid reference device
     422          11 :     uno::Reference< container::XChild > xChild( pNode->GetOLEObj().GetObject().GetObject(), UNO_QUERY );
     423          11 :     if (xChild.is())
     424             :     {
     425           3 :         SwDocShell *pDocSh= GetDoc()->GetDocShell();
     426           3 :         if (pDocSh)
     427           3 :             xChild->setParent( pDocSh->GetModel() );
     428             :     }
     429             : 
     430          11 :     return pNode;
     431             : }
     432             : 
     433         104 : Size SwOLENode::GetTwipSize() const
     434             : {
     435         104 :     MapMode aMapMode( MAP_TWIP );
     436         104 :     return ((SwOLENode*)this)->aOLEObj.GetObject().GetSize( &aMapMode );
     437             : }
     438             : 
     439           0 : SwCntntNode* SwOLENode::MakeCopy( SwDoc* pDoc, const SwNodeIndex& rIdx ) const
     440             : {
     441             :     // Falls bereits eine SvPersist-Instanz existiert, nehmen wir diese
     442           0 :     SfxObjectShell* pPersistShell = pDoc->GetPersist();
     443           0 :     if( !pPersistShell )
     444             :     {
     445             :         // TODO/LATER: is EmbeddedObjectContainer not enough?
     446             :         // the created document will be closed by pDoc ( should use SfxObjectShellLock )
     447           0 :         pPersistShell = new SwDocShell( pDoc, SFX_CREATE_MODE_INTERNAL );
     448           0 :         pDoc->SetTmpDocShell( pPersistShell );
     449           0 :         pPersistShell->DoInitNew( NULL );
     450             :     }
     451             : 
     452             :     // Wir hauen das Ding auf SvPersist-Ebene rein
     453             :     // TODO/LATER: check if using the same naming scheme for all apps works here
     454           0 :     OUString aNewName/*( Sw3Io::UniqueName( p->GetStorage(), "Obj" ) )*/;
     455           0 :     SfxObjectShell* pSrc = GetDoc()->GetPersist();
     456             : 
     457           0 :     pPersistShell->GetEmbeddedObjectContainer().CopyAndGetEmbeddedObject(
     458           0 :         pSrc->GetEmbeddedObjectContainer(),
     459           0 :         pSrc->GetEmbeddedObjectContainer().GetEmbeddedObject( aOLEObj.aName ),
     460           0 :         aNewName );
     461             : 
     462           0 :     SwOLENode* pOLENd = pDoc->GetNodes().MakeOLENode( rIdx, aNewName, GetAspect(),
     463           0 :                                     (SwGrfFmtColl*)pDoc->GetDfltGrfFmtColl(),
     464           0 :                                     (SwAttrSet*)GetpSwAttrSet() );
     465             : 
     466           0 :     pOLENd->SetChartTblName( GetChartTblName() );
     467           0 :     pOLENd->SetTitle( GetTitle() );
     468           0 :     pOLENd->SetDescription( GetDescription() );
     469           0 :     pOLENd->SetContour( HasContour(), HasAutomaticContour() );
     470           0 :     pOLENd->SetAspect( GetAspect() ); // the replacement image must be already copied
     471             : 
     472           0 :     pOLENd->SetOLESizeInvalid( sal_True );
     473           0 :     pDoc->SetOLEPrtNotifyPending();
     474             : 
     475           0 :     return pOLENd;
     476             : }
     477             : 
     478           0 : sal_Bool SwOLENode::IsInGlobalDocSection() const
     479             : {
     480             :     // suche den "Body Anchor"
     481           0 :     sal_uLong nEndExtraIdx = GetNodes().GetEndOfExtras().GetIndex();
     482           0 :     const SwNode* pAnchorNd = this;
     483           0 :     do {
     484           0 :         SwFrmFmt* pFlyFmt = pAnchorNd->GetFlyFmt();
     485           0 :         if( !pFlyFmt )
     486           0 :             return sal_False;
     487             : 
     488           0 :         const SwFmtAnchor& rAnchor = pFlyFmt->GetAnchor();
     489           0 :         if( !rAnchor.GetCntntAnchor() )
     490           0 :             return sal_False;
     491             : 
     492           0 :         pAnchorNd = &rAnchor.GetCntntAnchor()->nNode.GetNode();
     493           0 :     } while( pAnchorNd->GetIndex() < nEndExtraIdx );
     494             : 
     495           0 :     const SwSectionNode* pSectNd = pAnchorNd->FindSectionNode();
     496           0 :     if( !pSectNd )
     497           0 :         return sal_False;
     498             : 
     499           0 :     while( pSectNd )
     500             :     {
     501           0 :         pAnchorNd = pSectNd;
     502           0 :         pSectNd = pAnchorNd->StartOfSectionNode()->FindSectionNode();
     503             :     }
     504             : 
     505             :     // in pAnchorNd steht der zuletzt gefundene Section Node. Der muss
     506             :     // jetzt die Bedingung fuers GlobalDoc erfuellen.
     507           0 :     pSectNd = (SwSectionNode*)pAnchorNd;
     508           0 :     return FILE_LINK_SECTION == pSectNd->GetSection().GetType() &&
     509           0 :             pSectNd->GetIndex() > nEndExtraIdx;
     510             : }
     511             : 
     512           0 : sal_Bool SwOLENode::IsOLEObjectDeleted() const
     513             : {
     514           0 :     sal_Bool bRet = sal_False;
     515           0 :     if( aOLEObj.xOLERef.is() )
     516             :     {
     517           0 :         SfxObjectShell* p = GetDoc()->GetPersist();
     518           0 :         if( p )     // muss da sein
     519             :         {
     520           0 :             return !p->GetEmbeddedObjectContainer().HasEmbeddedObject( aOLEObj.aName );
     521             :         }
     522             :     }
     523           0 :     return bRet;
     524             : }
     525             : 
     526           0 : void SwOLENode::GetNewReplacement()
     527             : {
     528           0 :     if ( aOLEObj.xOLERef.is() )
     529           0 :         aOLEObj.xOLERef.UpdateReplacement();
     530           0 : }
     531             : 
     532           0 : sal_Bool SwOLENode::UpdateLinkURL_Impl()
     533             : {
     534           0 :     sal_Bool bResult = sal_False;
     535             : 
     536           0 :     if ( mpObjectLink )
     537             :     {
     538           0 :         String aNewLinkURL;
     539           0 :         GetDoc()->GetLinkManager().GetDisplayNames( mpObjectLink, 0, &aNewLinkURL, 0, 0 );
     540           0 :         if ( !aNewLinkURL.EqualsIgnoreCaseAscii( maLinkURL ) )
     541             :         {
     542           0 :             if ( !aOLEObj.xOLERef.is() )
     543           0 :                 aOLEObj.GetOleRef();
     544             : 
     545           0 :             uno::Reference< embed::XEmbeddedObject > xObj = aOLEObj.xOLERef.GetObject();
     546           0 :             uno::Reference< embed::XCommonEmbedPersist > xPersObj( xObj, uno::UNO_QUERY );
     547             :             OSL_ENSURE( xPersObj.is(), "The object must exist!\n" );
     548           0 :             if ( xPersObj.is() )
     549             :             {
     550             :                 try
     551             :                 {
     552           0 :                     sal_Int32 nCurState = xObj->getCurrentState();
     553           0 :                     if ( nCurState != embed::EmbedStates::LOADED )
     554           0 :                         xObj->changeState( embed::EmbedStates::LOADED );
     555             : 
     556             :                     // TODO/LATER: there should be possible to get current mediadescriptor settings from the object
     557           0 :                     uno::Sequence< beans::PropertyValue > aArgs( 1 );
     558           0 :                     aArgs[0].Name = OUString( "URL" );
     559           0 :                     aArgs[0].Value <<= OUString( aNewLinkURL );
     560           0 :                     xPersObj->reload( aArgs, uno::Sequence< beans::PropertyValue >() );
     561             : 
     562           0 :                     maLinkURL = aNewLinkURL;
     563           0 :                     bResult = sal_True;
     564             : 
     565           0 :                     if ( nCurState != embed::EmbedStates::LOADED )
     566           0 :                         xObj->changeState( nCurState );
     567             :                 }
     568           0 :                 catch( uno::Exception& )
     569             :                 {}
     570             :             }
     571             : 
     572             :             if ( !bResult )
     573             :             {
     574             :                 // TODO/LATER: return the old name to the link manager, is it possible?
     575           0 :             }
     576           0 :         }
     577             :     }
     578             : 
     579           0 :     return bResult;
     580             : }
     581             : 
     582           0 : void SwOLENode::BreakFileLink_Impl()
     583             : {
     584           0 :     SfxObjectShell* pPers = GetDoc()->GetPersist();
     585             : 
     586           0 :     if ( pPers )
     587             :     {
     588           0 :         uno::Reference< embed::XStorage > xStorage = pPers->GetStorage();
     589           0 :         if ( xStorage.is() )
     590             :         {
     591             :             try
     592             :             {
     593           0 :                 uno::Reference< embed::XLinkageSupport > xLinkSupport( aOLEObj.GetOleRef(), uno::UNO_QUERY_THROW );
     594           0 :                 xLinkSupport->breakLink( xStorage, aOLEObj.GetCurrentPersistName() );
     595           0 :                 DisconnectFileLink_Impl();
     596           0 :                 maLinkURL = String();
     597             :             }
     598           0 :             catch( uno::Exception& )
     599             :             {
     600             :             }
     601           0 :         }
     602             :     }
     603           0 : }
     604             : 
     605         163 : void SwOLENode::DisconnectFileLink_Impl()
     606             : {
     607         163 :     if ( mpObjectLink )
     608             :     {
     609           0 :         GetDoc()->GetLinkManager().Remove( mpObjectLink );
     610           0 :         mpObjectLink = NULL;
     611             :     }
     612         163 : }
     613             : 
     614         162 : void SwOLENode::CheckFileLink_Impl()
     615             : {
     616         162 :     if ( aOLEObj.xOLERef.GetObject().is() && !mpObjectLink )
     617             :     {
     618             :         try
     619             :         {
     620         162 :             uno::Reference< embed::XLinkageSupport > xLinkSupport( aOLEObj.xOLERef.GetObject(), uno::UNO_QUERY_THROW );
     621         154 :             if ( xLinkSupport->isLink() )
     622             :             {
     623           0 :                 String aLinkURL = xLinkSupport->getLinkURL();
     624           0 :                 if ( aLinkURL.Len() )
     625             :                 {
     626             :                     // this is a file link so the model link manager should handle it
     627           0 :                     mpObjectLink = new SwEmbedObjectLink( this );
     628           0 :                     maLinkURL = aLinkURL;
     629           0 :                     GetDoc()->GetLinkManager().InsertFileLink( *mpObjectLink, OBJECT_CLIENT_OLE, aLinkURL, NULL, NULL );
     630           0 :                     mpObjectLink->Connect();
     631           0 :                 }
     632         154 :             }
     633             :         }
     634           8 :         catch( uno::Exception& )
     635             :         {
     636             :         }
     637             :     }
     638         162 : }
     639             : 
     640             : // #i99665#
     641           1 : bool SwOLENode::IsChart() const
     642             : {
     643           1 :     bool bIsChart( false );
     644             : 
     645             :     const uno::Reference< embed::XEmbeddedObject > xEmbObj =
     646           1 :                             const_cast<SwOLEObj&>(GetOLEObj()).GetOleRef();
     647           1 :     if ( xEmbObj.is() )
     648             :     {
     649           1 :         SvGlobalName aClassID( xEmbObj->getClassID() );
     650           1 :         bIsChart = SotExchange::IsChart( aClassID );
     651             :     }
     652             : 
     653           1 :     return bIsChart;
     654             : }
     655             : 
     656         151 : SwOLEObj::SwOLEObj( const svt::EmbeddedObjectRef& xObj ) :
     657             :     pOLENd( 0 ),
     658             :     pListener( 0 ),
     659         151 :     xOLERef( xObj )
     660             : {
     661         151 :     xOLERef.Lock( sal_True );
     662         151 :     if ( xObj.is() )
     663             :     {
     664         151 :         pListener = new SwOLEListener_Impl( this );
     665         151 :         pListener->acquire();
     666         151 :         xObj->addStateChangeListener( pListener );
     667             :     }
     668         151 : }
     669             : 
     670             : 
     671          11 : SwOLEObj::SwOLEObj( const String &rString, sal_Int64 nAspect ) :
     672             :     pOLENd( 0 ),
     673             :     pListener( 0 ),
     674          11 :     aName( rString )
     675             : {
     676          11 :     xOLERef.Lock( sal_True );
     677          11 :     xOLERef.SetViewAspect( nAspect );
     678          11 : }
     679             : 
     680             : 
     681         324 : SwOLEObj::~SwOLEObj()
     682             : {
     683         162 :     if( pListener )
     684             :     {
     685         162 :         if ( xOLERef.is() )
     686         162 :             xOLERef->removeStateChangeListener( pListener );
     687         162 :         pListener->Release();
     688             :     }
     689             : 
     690         162 :     if( pOLENd && !pOLENd->GetDoc()->IsInDtor() )
     691             :     {
     692             :         // if the model is not currently in destruction it means that this object should be removed from the model
     693           0 :         comphelper::EmbeddedObjectContainer* pCnt = xOLERef.GetContainer();
     694             : 
     695             : #if OSL_DEBUG_LEVEL > 0
     696             :         SfxObjectShell* p = pOLENd->GetDoc()->GetPersist();
     697             :         OSL_ENSURE( p, "No document!" );
     698             :         if( p )
     699             :         {
     700             :             comphelper::EmbeddedObjectContainer& rCnt = p->GetEmbeddedObjectContainer();
     701             :             OSL_ENSURE( !pCnt || &rCnt == pCnt, "The helper is assigned to unexpected container!\n" );
     702             :         }
     703             : #endif
     704             : 
     705           0 :         if ( pCnt && pCnt->HasEmbeddedObject( aName ) )
     706             :         {
     707           0 :             uno::Reference < container::XChild > xChild( xOLERef.GetObject(), uno::UNO_QUERY );
     708           0 :             if ( xChild.is() )
     709           0 :                 xChild->setParent( 0 );
     710             : 
     711             :             // not already removed by deleting the object
     712           0 :             xOLERef.AssignToContainer( 0, aName );
     713             : 
     714             :             // unlock object so that object can be closed in RemoveEmbeddedObject
     715             :             // successful closing of the object will automatically clear the reference then
     716           0 :             xOLERef.Lock(sal_False);
     717             : 
     718             :             // Always remove object from conteiner it is connected to
     719             :             try
     720             :             {
     721           0 :                 pCnt->RemoveEmbeddedObject( aName );
     722             :             }
     723           0 :             catch ( uno::Exception& )
     724             :             {
     725           0 :             }
     726             :         }
     727             : 
     728             :     }
     729             : 
     730         162 :     if ( xOLERef.is() )
     731             :         // in case the object wasn't closed: release it
     732             :         // in case the object was not in the container: it's still locked, try to close
     733         162 :         xOLERef.Clear();
     734         162 : }
     735             : 
     736             : 
     737         162 : void SwOLEObj::SetNode( SwOLENode* pNode )
     738             : {
     739         162 :     pOLENd = pNode;
     740         162 :     if ( !aName.Len() )
     741             :     {
     742         151 :         SwDoc* pDoc = pNode->GetDoc();
     743             : 
     744             :         // Falls bereits eine SvPersist-Instanz existiert, nehmen wir diese
     745         151 :         SfxObjectShell* p = pDoc->GetPersist();
     746         151 :         if( !p )
     747             :         {
     748             :             // TODO/LATER: reicht hier nicht ein EmbeddedObjectContainer? Was passiert mit
     749             :             // diesem Dokument?
     750             :             OSL_ENSURE( !this, "warum wird hier eine DocShell angelegt?" );
     751           0 :             p = new SwDocShell( pDoc, SFX_CREATE_MODE_INTERNAL );
     752           0 :             p->DoInitNew( NULL );
     753             :         }
     754             : 
     755         151 :         OUString aObjName;
     756         302 :         uno::Reference < container::XChild > xChild( xOLERef.GetObject(), uno::UNO_QUERY );
     757         151 :         if ( xChild.is() && xChild->getParent() != p->GetModel() )
     758             :             // it is possible that the parent was set already
     759           1 :             xChild->setParent( p->GetModel() );
     760         151 :         if (!p->GetEmbeddedObjectContainer().InsertEmbeddedObject( xOLERef.GetObject(), aObjName ) )
     761             :         {
     762             :             OSL_FAIL( "InsertObject failed" );
     763           0 :         if ( xChild.is() )
     764           0 :             xChild->setParent( 0 );
     765             :         }
     766             :         else
     767         151 :             xOLERef.AssignToContainer( &p->GetEmbeddedObjectContainer(), aObjName );
     768             : 
     769         151 :         ( (SwOLENode*)pOLENd )->CheckFileLink_Impl(); // for this notification nonconst access is required
     770             : 
     771         302 :         aName = aObjName;
     772             :     }
     773         162 : }
     774             : 
     775         484 : sal_Bool SwOLEObj::IsOleRef() const
     776             : {
     777         484 :     return xOLERef.is();
     778             : }
     779             : 
     780        1247 : const uno::Reference < embed::XEmbeddedObject > SwOLEObj::GetOleRef()
     781             : {
     782        1247 :     if( !xOLERef.is() )
     783             :     {
     784          11 :         SfxObjectShell* p = pOLENd->GetDoc()->GetPersist();
     785             :         OSL_ENSURE( p, "kein SvPersist vorhanden" );
     786             : 
     787          11 :         uno::Reference < embed::XEmbeddedObject > xObj = p->GetEmbeddedObjectContainer().GetEmbeddedObject( aName );
     788             :         OSL_ENSURE( !xOLERef.is(), "rekursiver Aufruf von GetOleRef() ist nicht erlaubt" );
     789             : 
     790          11 :         if ( !xObj.is() )
     791             :         {
     792             :             //Das Teil konnte nicht geladen werden (wahrsch. Kaputt).
     793           0 :             Rectangle aArea;
     794           0 :             SwFrm *pFrm = pOLENd->getLayoutFrm(0);
     795           0 :             if ( pFrm )
     796             :             {
     797           0 :                 Size aSz( pFrm->Frm().SSize() );
     798           0 :                 const MapMode aSrc ( MAP_TWIP );
     799           0 :                 const MapMode aDest( MAP_100TH_MM );
     800           0 :                 aSz = OutputDevice::LogicToLogic( aSz, aSrc, aDest );
     801           0 :                 aArea.SetSize( aSz );
     802             :             }
     803             :             else
     804           0 :                 aArea.SetSize( Size( 5000,  5000 ) );
     805             :             // TODO/LATER: set replacement graphic for dead object
     806             :             // It looks as if it should work even without the object, because the replace will be generated automatically
     807           0 :             OUString aTmpName;
     808           0 :             xObj = p->GetEmbeddedObjectContainer().CreateEmbeddedObject( SvGlobalName( SO3_DUMMY_CLASSID ).GetByteSequence(), aTmpName );
     809             :         }
     810             :         // else
     811             :         {
     812          11 :             xOLERef.Assign( xObj, xOLERef.GetViewAspect() );
     813          11 :             xOLERef.AssignToContainer( &p->GetEmbeddedObjectContainer(), aName );
     814          11 :             pListener = new SwOLEListener_Impl( this );
     815          11 :             pListener->acquire();
     816          11 :             xObj->addStateChangeListener( pListener );
     817             :         }
     818             : 
     819          11 :         ( (SwOLENode*)pOLENd )->CheckFileLink_Impl(); // for this notification nonconst access is required
     820             :     }
     821        1236 :     else if ( xOLERef->getCurrentState() == embed::EmbedStates::RUNNING )
     822             :     {
     823             :         // move object to first position in cache
     824        1121 :         if( !pOLELRU_Cache )
     825          71 :             pOLELRU_Cache = new SwOLELRUCache;
     826        1121 :         pOLELRU_Cache->InsertObj( *this );
     827             :     }
     828             : 
     829        1247 :     return xOLERef.GetObject();
     830             : }
     831             : 
     832         731 : svt::EmbeddedObjectRef& SwOLEObj::GetObject()
     833             : {
     834         731 :     GetOleRef();
     835         731 :     return xOLERef;
     836             : }
     837             : 
     838           0 : sal_Bool SwOLEObj::UnloadObject()
     839             : {
     840           0 :     sal_Bool bRet = sal_True;
     841           0 :     if ( pOLENd )
     842             :     {
     843           0 :         const SwDoc* pDoc = pOLENd->GetDoc();
     844           0 :         bRet = UnloadObject( xOLERef.GetObject(), pDoc, xOLERef.GetViewAspect() );
     845             :     }
     846             : 
     847           0 :     return bRet;
     848             : }
     849             : 
     850           0 : sal_Bool SwOLEObj::UnloadObject( uno::Reference< embed::XEmbeddedObject > xObj, const SwDoc* pDoc, sal_Int64 nAspect )
     851             : {
     852           0 :     if ( !pDoc )
     853           0 :         return sal_False;
     854             : 
     855           0 :     sal_Bool bRet = sal_True;
     856           0 :        sal_Int32 nState = xObj.is() ? xObj->getCurrentState() : embed::EmbedStates::LOADED;
     857           0 :        bool bIsActive = ( nState != embed::EmbedStates::LOADED && nState != embed::EmbedStates::RUNNING );
     858           0 :     sal_Int64 nMiscStatus = xObj->getStatus( nAspect );
     859             : 
     860           0 :        if( nState != embed::EmbedStates::LOADED && !pDoc->IsInDtor() && !bIsActive &&
     861           0 :         embed::EmbedMisc::MS_EMBED_ALWAYSRUN != ( nMiscStatus & embed::EmbedMisc::MS_EMBED_ALWAYSRUN ) &&
     862           0 :         embed::EmbedMisc::EMBED_ACTIVATEIMMEDIATELY != ( nMiscStatus & embed::EmbedMisc::EMBED_ACTIVATEIMMEDIATELY ) )
     863             :     {
     864           0 :         SfxObjectShell* p = pDoc->GetPersist();
     865           0 :         if( p )
     866             :         {
     867           0 :             if( pDoc->get(IDocumentSettingAccess::PURGE_OLE) )
     868             :             {
     869             :                 try
     870             :                 {
     871           0 :                     uno::Reference < util::XModifiable > xMod( xObj->getComponent(), uno::UNO_QUERY );
     872           0 :                     if( xMod.is() && xMod->isModified() )
     873             :                     {
     874           0 :                         uno::Reference < embed::XEmbedPersist > xPers( xObj, uno::UNO_QUERY );
     875           0 :                         if ( xPers.is() )
     876           0 :                             xPers->storeOwn();
     877             :                         else {
     878             :                             OSL_FAIL("Modified object without persistance in cache!");
     879           0 :                         }
     880             :                     }
     881             : 
     882             :                     // setting object to loaded state will remove it from cache
     883           0 :                     xObj->changeState( embed::EmbedStates::LOADED );
     884             :                 }
     885           0 :                 catch ( uno::Exception& )
     886             :                 {
     887           0 :                     bRet = sal_False;
     888             :                 }
     889             :             }
     890             :             else
     891           0 :                 bRet = sal_False;
     892             :         }
     893             :     }
     894             : 
     895           0 :     return bRet;
     896             : }
     897             : 
     898           1 : String SwOLEObj::GetDescription()
     899             : {
     900           1 :     String aResult;
     901           2 :     uno::Reference< embed::XEmbeddedObject > xEmbObj = GetOleRef();
     902           1 :     if ( xEmbObj.is() )
     903             :     {
     904           1 :         SvGlobalName aClassID( xEmbObj->getClassID() );
     905           1 :         if ( SotExchange::IsMath( aClassID ) )
     906           0 :             aResult = SW_RESSTR(STR_MATH_FORMULA);
     907           1 :         else if ( SotExchange::IsChart( aClassID ) )
     908           1 :             aResult = SW_RESSTR(STR_CHART);
     909             :         else
     910           0 :             aResult = SW_RESSTR(STR_OLE);
     911             :     }
     912             : 
     913           2 :     return aResult;
     914             : }
     915             : 
     916             : 
     917          71 : SwOLELRUCache::SwOLELRUCache()
     918             :     : utl::ConfigItem(OUString("Office.Common/Cache"))
     919          71 :     , m_nLRU_InitSize( 20 )
     920             : {
     921          71 :     EnableNotification( GetPropertyNames() );
     922          71 :     Load();
     923          71 : }
     924             : 
     925         142 : uno::Sequence< OUString > SwOLELRUCache::GetPropertyNames()
     926             : {
     927         142 :     Sequence< OUString > aNames( 1 );
     928         142 :     OUString* pNames = aNames.getArray();
     929         142 :     pNames[0] = OUString("Writer/OLE_Objects");
     930         142 :     return aNames;
     931             : }
     932             : 
     933           0 : void SwOLELRUCache::Notify( const uno::Sequence< OUString>&  )
     934             : {
     935           0 :     Load();
     936           0 : }
     937             : 
     938           0 : void SwOLELRUCache::Commit()
     939             : {
     940           0 : }
     941             : 
     942          71 : void SwOLELRUCache::Load()
     943             : {
     944          71 :     Sequence< OUString > aNames( GetPropertyNames() );
     945         142 :     Sequence< Any > aValues = GetProperties( aNames );
     946          71 :     const Any* pValues = aValues.getConstArray();
     947             :     OSL_ENSURE( aValues.getLength() == aNames.getLength(), "GetProperties failed" );
     948          71 :     if( aValues.getLength() == aNames.getLength() && pValues->hasValue() )
     949             :     {
     950          71 :         sal_Int32 nVal = 0;
     951          71 :         *pValues >>= nVal;
     952             : 
     953             :         {
     954          71 :             if (nVal < m_nLRU_InitSize)
     955             :             {
     956             :                 // size of cache has been changed
     957           0 :                 sal_Int32 nCount = m_OleObjects.size();
     958           0 :                 sal_Int32 nPos = nCount;
     959             : 
     960             :                 // try to remove the last entries until new maximum size is reached
     961           0 :                 while( nCount > nVal )
     962             :                 {
     963           0 :                     SwOLEObj *const pObj = m_OleObjects[ --nPos ];
     964           0 :                     if ( pObj->UnloadObject() )
     965           0 :                         nCount--;
     966           0 :                     if ( !nPos )
     967           0 :                         break;
     968             :                 }
     969             :             }
     970             :         }
     971             : 
     972          71 :         m_nLRU_InitSize = nVal;
     973          71 :     }
     974          71 : }
     975             : 
     976        1272 : void SwOLELRUCache::InsertObj( SwOLEObj& rObj )
     977             : {
     978        1272 :     SwOLEObj* pObj = &rObj;
     979             :     OleObjects_t::iterator it =
     980        1272 :         std::find(m_OleObjects.begin(), m_OleObjects.end(), pObj);
     981        1272 :     if (it != m_OleObjects.end() && it != m_OleObjects.begin())
     982             :     {
     983             :         // object in cache but is currently not the first in cache
     984         324 :         m_OleObjects.erase(it);
     985         324 :         it = m_OleObjects.end();
     986             :     }
     987        1272 :     if (it == m_OleObjects.end())
     988             :     {
     989         475 :         m_OleObjects.push_front( pObj );
     990             : 
     991             :         // try to remove objects if necessary
     992             :         // (of course not the freshly inserted one at nPos=0)
     993         475 :         sal_Int32 nCount = m_OleObjects.size();
     994         475 :         sal_Int32 nPos = nCount-1;
     995         950 :         while (nPos && nCount > m_nLRU_InitSize)
     996             :         {
     997           0 :             pObj = m_OleObjects[ nPos-- ];
     998           0 :             if ( pObj->UnloadObject() )
     999           0 :                 nCount--;
    1000             :         }
    1001             :     }
    1002        1272 : }
    1003             : 
    1004         151 : void SwOLELRUCache::RemoveObj( SwOLEObj& rObj )
    1005             : {
    1006             :     OleObjects_t::iterator const it =
    1007         151 :         std::find(m_OleObjects.begin(), m_OleObjects.end(), &rObj);
    1008         151 :     if (it != m_OleObjects.end())
    1009             :     {
    1010         151 :         m_OleObjects.erase(it);
    1011             :     }
    1012         151 :     if (m_OleObjects.empty())
    1013             :     {
    1014          71 :         DELETEZ( pOLELRU_Cache );
    1015             :     }
    1016         250 : }
    1017             : 
    1018             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10