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