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

Generated by: LCOV version 1.10