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

Generated by: LCOV version 1.10