LCOV - code coverage report
Current view: top level - libreoffice/sw/source/core/ole - ndole.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 192 417 46.0 %
Date: 2012-12-17 Functions: 33 52 63.5 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10