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