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

Generated by: LCOV version 1.11