xref: /AOO41X/main/svtools/source/misc/embedhlp.cxx (revision 5900e8ec128faec89519683efce668ccd8cc6084)
1*5900e8ecSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*5900e8ecSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*5900e8ecSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*5900e8ecSAndrew Rist  * distributed with this work for additional information
6*5900e8ecSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*5900e8ecSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*5900e8ecSAndrew Rist  * "License"); you may not use this file except in compliance
9*5900e8ecSAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11*5900e8ecSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13*5900e8ecSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*5900e8ecSAndrew Rist  * software distributed under the License is distributed on an
15*5900e8ecSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*5900e8ecSAndrew Rist  * KIND, either express or implied.  See the License for the
17*5900e8ecSAndrew Rist  * specific language governing permissions and limitations
18*5900e8ecSAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20*5900e8ecSAndrew Rist  *************************************************************/
21*5900e8ecSAndrew Rist 
22*5900e8ecSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_svtools.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include <svtools/embedhlp.hxx>
28cdf0e10cSrcweir #include <svtools/filter.hxx>
29cdf0e10cSrcweir #include <svtools/svtools.hrc>
30cdf0e10cSrcweir #include <svtools/svtdata.hxx>
31cdf0e10cSrcweir 
32cdf0e10cSrcweir #include <comphelper/embeddedobjectcontainer.hxx>
33cdf0e10cSrcweir #include <comphelper/seqstream.hxx>
34cdf0e10cSrcweir #include <toolkit/helper/vclunohelper.hxx>
35cdf0e10cSrcweir #include <unotools/ucbstreamhelper.hxx>
36cdf0e10cSrcweir #include <unotools/streamwrap.hxx>
37cdf0e10cSrcweir 
38cdf0e10cSrcweir #include <tools/globname.hxx>
39cdf0e10cSrcweir #include <sot/clsids.hxx>
40cdf0e10cSrcweir #include <com/sun/star/util/XModifyListener.hpp>
41cdf0e10cSrcweir #ifndef _COM_SUN_STAR_UTIL_XMODIFYiBLE_HPP_
42cdf0e10cSrcweir #include <com/sun/star/util/XModifiable.hpp>
43cdf0e10cSrcweir #endif
44cdf0e10cSrcweir #include <com/sun/star/embed/EmbedStates.hpp>
45cdf0e10cSrcweir #include <com/sun/star/embed/EmbedMisc.hpp>
46cdf0e10cSrcweir #include <com/sun/star/embed/XStateChangeListener.hpp>
47cdf0e10cSrcweir #include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
48cdf0e10cSrcweir #include <com/sun/star/util/XModifiable.hpp>
49cdf0e10cSrcweir #include <com/sun/star/datatransfer/XTransferable.hpp>
50cdf0e10cSrcweir #include <com/sun/star/chart2/XDefaultSizeTransmitter.hpp>
51cdf0e10cSrcweir #include <cppuhelper/implbase4.hxx>
52cdf0e10cSrcweir #include "vcl/svapp.hxx"
53cdf0e10cSrcweir #include <rtl/logfile.hxx>
54cdf0e10cSrcweir #include <vos/mutex.hxx>
55cdf0e10cSrcweir 
56cdf0e10cSrcweir using namespace com::sun::star;
57cdf0e10cSrcweir 
58cdf0e10cSrcweir namespace svt
59cdf0e10cSrcweir {
60cdf0e10cSrcweir 
61cdf0e10cSrcweir class EmbedEventListener_Impl : public ::cppu::WeakImplHelper4 < embed::XStateChangeListener,
62cdf0e10cSrcweir 																 document::XEventListener,
63cdf0e10cSrcweir                                                                  util::XModifyListener,
64cdf0e10cSrcweir 																 util::XCloseListener >
65cdf0e10cSrcweir {
66cdf0e10cSrcweir public:
67cdf0e10cSrcweir     EmbeddedObjectRef*          pObject;
68cdf0e10cSrcweir     sal_Int32                   nState;
69cdf0e10cSrcweir 
70cdf0e10cSrcweir                                 EmbedEventListener_Impl( EmbeddedObjectRef* p ) :
71cdf0e10cSrcweir                                     pObject(p)
72cdf0e10cSrcweir                                     , nState(-1)
73cdf0e10cSrcweir                                 {}
74cdf0e10cSrcweir 
75cdf0e10cSrcweir     static EmbedEventListener_Impl* Create( EmbeddedObjectRef* );
76cdf0e10cSrcweir 
77cdf0e10cSrcweir     virtual void SAL_CALL changingState( const lang::EventObject& aEvent, ::sal_Int32 nOldState, ::sal_Int32 nNewState )
78cdf0e10cSrcweir 									throw (embed::WrongStateException, uno::RuntimeException);
79cdf0e10cSrcweir     virtual void SAL_CALL stateChanged( const lang::EventObject& aEvent, ::sal_Int32 nOldState, ::sal_Int32 nNewState )
80cdf0e10cSrcweir 									throw (uno::RuntimeException);
81cdf0e10cSrcweir     virtual void SAL_CALL queryClosing( const lang::EventObject& Source, ::sal_Bool GetsOwnership )
82cdf0e10cSrcweir                                     throw (util::CloseVetoException, uno::RuntimeException);
83cdf0e10cSrcweir     virtual void SAL_CALL notifyClosing( const lang::EventObject& Source ) throw (uno::RuntimeException);
84cdf0e10cSrcweir     virtual void SAL_CALL notifyEvent( const document::EventObject& aEvent ) throw( uno::RuntimeException );
85cdf0e10cSrcweir     virtual void SAL_CALL disposing( const lang::EventObject& aEvent ) throw( uno::RuntimeException );
86cdf0e10cSrcweir     virtual void SAL_CALL modified( const ::com::sun::star::lang::EventObject& aEvent ) throw (::com::sun::star::uno::RuntimeException);
87cdf0e10cSrcweir };
88cdf0e10cSrcweir 
89cdf0e10cSrcweir EmbedEventListener_Impl* EmbedEventListener_Impl::Create( EmbeddedObjectRef* p )
90cdf0e10cSrcweir {
91cdf0e10cSrcweir     EmbedEventListener_Impl* xRet = new EmbedEventListener_Impl( p );
92cdf0e10cSrcweir     xRet->acquire();
93cdf0e10cSrcweir 
94cdf0e10cSrcweir 	if ( p->GetObject().is() )
95cdf0e10cSrcweir 	{
96cdf0e10cSrcweir         p->GetObject()->addStateChangeListener( xRet );
97cdf0e10cSrcweir 
98cdf0e10cSrcweir     	uno::Reference < util::XCloseable > xClose( p->GetObject(), uno::UNO_QUERY );
99cdf0e10cSrcweir     	DBG_ASSERT( xClose.is(), "Object does not support XCloseable!" );
100cdf0e10cSrcweir     	if ( xClose.is() )
101cdf0e10cSrcweir             xClose->addCloseListener( xRet );
102cdf0e10cSrcweir 
103cdf0e10cSrcweir     	uno::Reference < document::XEventBroadcaster > xBrd( p->GetObject(), uno::UNO_QUERY );
104cdf0e10cSrcweir     	if ( xBrd.is() )
105cdf0e10cSrcweir         	xBrd->addEventListener( xRet );
106cdf0e10cSrcweir 
107cdf0e10cSrcweir         xRet->nState = p->GetObject()->getCurrentState();
108cdf0e10cSrcweir         if ( xRet->nState == embed::EmbedStates::RUNNING )
109cdf0e10cSrcweir         {
110cdf0e10cSrcweir             uno::Reference < util::XModifiable > xMod( p->GetObject()->getComponent(), uno::UNO_QUERY );
111cdf0e10cSrcweir             if ( xMod.is() )
112cdf0e10cSrcweir                 // listen for changes in running state (update replacements in case of changes)
113cdf0e10cSrcweir                 xMod->addModifyListener( xRet );
114cdf0e10cSrcweir         }
115cdf0e10cSrcweir 	}
116cdf0e10cSrcweir 
117cdf0e10cSrcweir     return xRet;
118cdf0e10cSrcweir }
119cdf0e10cSrcweir 
120cdf0e10cSrcweir void SAL_CALL EmbedEventListener_Impl::changingState( const lang::EventObject&,
121cdf0e10cSrcweir 													::sal_Int32,
122cdf0e10cSrcweir 													::sal_Int32 )
123cdf0e10cSrcweir 	throw ( embed::WrongStateException,
124cdf0e10cSrcweir 			uno::RuntimeException )
125cdf0e10cSrcweir {
126cdf0e10cSrcweir }
127cdf0e10cSrcweir 
128cdf0e10cSrcweir void SAL_CALL EmbedEventListener_Impl::stateChanged( const lang::EventObject&,
129cdf0e10cSrcweir 													::sal_Int32 nOldState,
130cdf0e10cSrcweir 													::sal_Int32 nNewState )
131cdf0e10cSrcweir 	throw ( uno::RuntimeException )
132cdf0e10cSrcweir {
133cdf0e10cSrcweir 	::vos::OGuard aGuard( Application::GetSolarMutex() );
134cdf0e10cSrcweir     nState = nNewState;
135cdf0e10cSrcweir     if ( !pObject )
136cdf0e10cSrcweir         return;
137cdf0e10cSrcweir 
138cdf0e10cSrcweir     uno::Reference < util::XModifiable > xMod( pObject->GetObject()->getComponent(), uno::UNO_QUERY );
139cdf0e10cSrcweir     if ( nNewState == embed::EmbedStates::RUNNING )
140cdf0e10cSrcweir     {
141cdf0e10cSrcweir         // TODO/LATER: container must be set before!
142cdf0e10cSrcweir         // When is this event created? Who sets the new container when it changed?
143cdf0e10cSrcweir         if( ( pObject->GetViewAspect() != embed::Aspects::MSOLE_ICON ) && nOldState != embed::EmbedStates::LOADED && !pObject->IsChart() )
144cdf0e10cSrcweir             // get new replacement after deactivation
145cdf0e10cSrcweir             pObject->UpdateReplacement();
146cdf0e10cSrcweir 
147cdf0e10cSrcweir         if( pObject->IsChart() && nOldState == embed::EmbedStates::UI_ACTIVE )
148cdf0e10cSrcweir         {
149cdf0e10cSrcweir             //create a new metafile replacement when leaving the edit mode
150cdf0e10cSrcweir             //for buggy documents where the old image looks different from the correct one
151cdf0e10cSrcweir             if( xMod.is() && !xMod->isModified() )//in case of modification a new replacement will be requested anyhow
152cdf0e10cSrcweir                 pObject->UpdateReplacementOnDemand();
153cdf0e10cSrcweir         }
154cdf0e10cSrcweir 
155cdf0e10cSrcweir         if ( xMod.is() && nOldState == embed::EmbedStates::LOADED )
156cdf0e10cSrcweir             // listen for changes (update replacements in case of changes)
157cdf0e10cSrcweir             xMod->addModifyListener( this );
158cdf0e10cSrcweir     }
159cdf0e10cSrcweir     else if ( nNewState == embed::EmbedStates::LOADED )
160cdf0e10cSrcweir     {
161cdf0e10cSrcweir         // in loaded state we can't listen
162cdf0e10cSrcweir         if ( xMod.is() )
163cdf0e10cSrcweir             xMod->removeModifyListener( this );
164cdf0e10cSrcweir     }
165cdf0e10cSrcweir }
166cdf0e10cSrcweir 
167cdf0e10cSrcweir void SAL_CALL EmbedEventListener_Impl::modified( const lang::EventObject& ) throw (uno::RuntimeException)
168cdf0e10cSrcweir {
169cdf0e10cSrcweir 	::vos::OGuard aGuard( Application::GetSolarMutex() );
170cdf0e10cSrcweir     if ( pObject && pObject->GetViewAspect() != embed::Aspects::MSOLE_ICON )
171cdf0e10cSrcweir     {
172cdf0e10cSrcweir         if ( nState == embed::EmbedStates::RUNNING )
173cdf0e10cSrcweir         {
174cdf0e10cSrcweir             // updates only necessary in non-active states
175cdf0e10cSrcweir             if( pObject->IsChart() )
176cdf0e10cSrcweir                 pObject->UpdateReplacementOnDemand();
177cdf0e10cSrcweir             else
178cdf0e10cSrcweir                 pObject->UpdateReplacement();
179cdf0e10cSrcweir         }
180cdf0e10cSrcweir         else if ( nState == embed::EmbedStates::UI_ACTIVE || nState == embed::EmbedStates::INPLACE_ACTIVE )
181cdf0e10cSrcweir         {
182cdf0e10cSrcweir             // in case the object is inplace or UI active the replacement image should be updated on demand
183cdf0e10cSrcweir             pObject->UpdateReplacementOnDemand();
184cdf0e10cSrcweir         }
185cdf0e10cSrcweir     }
186cdf0e10cSrcweir }
187cdf0e10cSrcweir 
188cdf0e10cSrcweir void SAL_CALL EmbedEventListener_Impl::notifyEvent( const document::EventObject& aEvent ) throw( uno::RuntimeException )
189cdf0e10cSrcweir {
190cdf0e10cSrcweir 	::vos::OGuard aGuard( Application::GetSolarMutex() );
191cdf0e10cSrcweir 
192cdf0e10cSrcweir #if 0
193cdf0e10cSrcweir     if ( pObject && aEvent.EventName.equalsAscii("OnSaveDone") || aEvent.EventName.equalsAscii("OnSaveAsDone") )
194cdf0e10cSrcweir     {
195cdf0e10cSrcweir         // TODO/LATER: container must be set before!
196cdf0e10cSrcweir         // When is this event created? Who sets the new container when it changed?
197cdf0e10cSrcweir         pObject->UpdateReplacement();
198cdf0e10cSrcweir     }
199cdf0e10cSrcweir     else
200cdf0e10cSrcweir #endif
201cdf0e10cSrcweir     if ( pObject && aEvent.EventName.equalsAscii("OnVisAreaChanged") && pObject->GetViewAspect() != embed::Aspects::MSOLE_ICON && !pObject->IsChart() )
202cdf0e10cSrcweir     {
203cdf0e10cSrcweir         pObject->UpdateReplacement();
204cdf0e10cSrcweir     }
205cdf0e10cSrcweir }
206cdf0e10cSrcweir 
207cdf0e10cSrcweir void SAL_CALL EmbedEventListener_Impl::queryClosing( const lang::EventObject& Source, ::sal_Bool )
208cdf0e10cSrcweir         throw ( util::CloseVetoException, uno::RuntimeException)
209cdf0e10cSrcweir {
210cdf0e10cSrcweir     // An embedded object can be shared between several objects (f.e. for undo purposes)
211cdf0e10cSrcweir     // the object will not be closed before the last "customer" is destroyed
212cdf0e10cSrcweir     // Now the EmbeddedObjectRef helper class works like a "lock" on the object
213cdf0e10cSrcweir     if ( pObject && pObject->IsLocked() && Source.Source == pObject->GetObject() )
214cdf0e10cSrcweir         throw util::CloseVetoException();
215cdf0e10cSrcweir }
216cdf0e10cSrcweir 
217cdf0e10cSrcweir void SAL_CALL EmbedEventListener_Impl::notifyClosing( const lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException)
218cdf0e10cSrcweir {
219cdf0e10cSrcweir     if ( pObject && Source.Source == pObject->GetObject() )
220cdf0e10cSrcweir     {
221cdf0e10cSrcweir         pObject->Clear();
222cdf0e10cSrcweir         pObject = 0;
223cdf0e10cSrcweir     }
224cdf0e10cSrcweir }
225cdf0e10cSrcweir 
226cdf0e10cSrcweir void SAL_CALL EmbedEventListener_Impl::disposing( const lang::EventObject& aEvent ) throw( uno::RuntimeException )
227cdf0e10cSrcweir {
228cdf0e10cSrcweir     if ( pObject && aEvent.Source == pObject->GetObject() )
229cdf0e10cSrcweir     {
230cdf0e10cSrcweir         pObject->Clear();
231cdf0e10cSrcweir         pObject = 0;
232cdf0e10cSrcweir     }
233cdf0e10cSrcweir }
234cdf0e10cSrcweir 
235cdf0e10cSrcweir struct EmbeddedObjectRef_Impl
236cdf0e10cSrcweir {
237cdf0e10cSrcweir     EmbedEventListener_Impl*                    xListener;
238cdf0e10cSrcweir     ::rtl::OUString                             aPersistName;
239cdf0e10cSrcweir     ::rtl::OUString                             aMediaType;
240cdf0e10cSrcweir     comphelper::EmbeddedObjectContainer*        pContainer;
241cdf0e10cSrcweir     Graphic*                                    pGraphic;
242cdf0e10cSrcweir     Graphic*                                    pHCGraphic;
243cdf0e10cSrcweir     sal_Int64                                   nViewAspect;
244cdf0e10cSrcweir     sal_Bool                                        bIsLocked;
245cdf0e10cSrcweir     sal_Bool                                    bNeedUpdate;
246cdf0e10cSrcweir 
247cdf0e10cSrcweir     // #i104867#
248cdf0e10cSrcweir     sal_uInt32                                  mnGraphicVersion;
249cdf0e10cSrcweir     awt::Size                                   aDefaultSizeForChart_In_100TH_MM;//#i103460# charts do not necessaryly have an own size within ODF files, in this case they need to use the size settings from the surrounding frame, which is made available with this member
250cdf0e10cSrcweir };
251cdf0e10cSrcweir 
252cdf0e10cSrcweir void EmbeddedObjectRef::Construct_Impl()
253cdf0e10cSrcweir {
254cdf0e10cSrcweir     mpImp = new EmbeddedObjectRef_Impl;
255cdf0e10cSrcweir     mpImp->pContainer = 0;
256cdf0e10cSrcweir     mpImp->pGraphic = 0;
257cdf0e10cSrcweir     mpImp->pHCGraphic = 0;
258cdf0e10cSrcweir     mpImp->nViewAspect = embed::Aspects::MSOLE_CONTENT;
259cdf0e10cSrcweir     mpImp->bIsLocked = sal_False;
260cdf0e10cSrcweir     mpImp->bNeedUpdate = sal_False;
261cdf0e10cSrcweir     mpImp->mnGraphicVersion = 0;
262cdf0e10cSrcweir     mpImp->aDefaultSizeForChart_In_100TH_MM = awt::Size(8000,7000);
263cdf0e10cSrcweir }
264cdf0e10cSrcweir 
265cdf0e10cSrcweir EmbeddedObjectRef::EmbeddedObjectRef()
266cdf0e10cSrcweir {
267cdf0e10cSrcweir     Construct_Impl();
268cdf0e10cSrcweir }
269cdf0e10cSrcweir 
270cdf0e10cSrcweir EmbeddedObjectRef::EmbeddedObjectRef( const NS_UNO::Reference < NS_EMBED::XEmbeddedObject >& xObj, sal_Int64 nAspect )
271cdf0e10cSrcweir {
272cdf0e10cSrcweir     Construct_Impl();
273cdf0e10cSrcweir     mpImp->nViewAspect = nAspect;
274cdf0e10cSrcweir     mxObj = xObj;
275cdf0e10cSrcweir     mpImp->xListener = EmbedEventListener_Impl::Create( this );
276cdf0e10cSrcweir }
277cdf0e10cSrcweir 
278cdf0e10cSrcweir EmbeddedObjectRef::EmbeddedObjectRef( const EmbeddedObjectRef& rObj )
279cdf0e10cSrcweir {
280cdf0e10cSrcweir     mpImp = new EmbeddedObjectRef_Impl;
281cdf0e10cSrcweir     mpImp->pContainer = rObj.mpImp->pContainer;
282cdf0e10cSrcweir     mpImp->nViewAspect = rObj.mpImp->nViewAspect;
283cdf0e10cSrcweir     mpImp->bIsLocked = rObj.mpImp->bIsLocked;
284cdf0e10cSrcweir     mxObj = rObj.mxObj;
285cdf0e10cSrcweir     mpImp->xListener = EmbedEventListener_Impl::Create( this );
286cdf0e10cSrcweir     mpImp->aPersistName = rObj.mpImp->aPersistName;
287cdf0e10cSrcweir     mpImp->aMediaType = rObj.mpImp->aMediaType;
288cdf0e10cSrcweir     mpImp->bNeedUpdate = rObj.mpImp->bNeedUpdate;
289cdf0e10cSrcweir     mpImp->aDefaultSizeForChart_In_100TH_MM = rObj.mpImp->aDefaultSizeForChart_In_100TH_MM;
290cdf0e10cSrcweir 
291cdf0e10cSrcweir     if ( rObj.mpImp->pGraphic && !rObj.mpImp->bNeedUpdate )
292cdf0e10cSrcweir         mpImp->pGraphic = new Graphic( *rObj.mpImp->pGraphic );
293cdf0e10cSrcweir     else
294cdf0e10cSrcweir         mpImp->pGraphic = 0;
295cdf0e10cSrcweir 
296cdf0e10cSrcweir     mpImp->pHCGraphic = 0;
297cdf0e10cSrcweir     mpImp->mnGraphicVersion = 0;
298cdf0e10cSrcweir }
299cdf0e10cSrcweir 
300cdf0e10cSrcweir EmbeddedObjectRef::~EmbeddedObjectRef()
301cdf0e10cSrcweir {
302cdf0e10cSrcweir     delete mpImp->pGraphic;
303cdf0e10cSrcweir 	if ( mpImp->pHCGraphic )
304cdf0e10cSrcweir         DELETEZ( mpImp->pHCGraphic );
305cdf0e10cSrcweir     Clear();
306cdf0e10cSrcweir }
307cdf0e10cSrcweir /*
308cdf0e10cSrcweir EmbeddedObjectRef& EmbeddedObjectRef::operator = ( const EmbeddedObjectRef& rObj )
309cdf0e10cSrcweir {
310cdf0e10cSrcweir     DBG_ASSERT( !mxObj.is(), "Never assign an already assigned object!" );
311cdf0e10cSrcweir 
312cdf0e10cSrcweir     delete mpImp->pGraphic;
313cdf0e10cSrcweir 	if ( mpImp->pHCGraphic ) DELETEZ( mpImp->pHCGraphic );
314cdf0e10cSrcweir     Clear();
315cdf0e10cSrcweir 
316cdf0e10cSrcweir     mpImp->nViewAspect = rObj.mpImp->nViewAspect;
317cdf0e10cSrcweir     mpImp->bIsLocked = rObj.mpImp->bIsLocked;
318cdf0e10cSrcweir     mxObj = rObj.mxObj;
319cdf0e10cSrcweir     mpImp->xListener = EmbedEventListener_Impl::Create( this );
320cdf0e10cSrcweir     mpImp->pContainer = rObj.mpImp->pContainer;
321cdf0e10cSrcweir     mpImp->aPersistName = rObj.mpImp->aPersistName;
322cdf0e10cSrcweir     mpImp->aMediaType = rObj.mpImp->aMediaType;
323cdf0e10cSrcweir     mpImp->bNeedUpdate = rObj.mpImp->bNeedUpdate;
324cdf0e10cSrcweir 
325cdf0e10cSrcweir     if ( rObj.mpImp->pGraphic && !rObj.mpImp->bNeedUpdate )
326cdf0e10cSrcweir         mpImp->pGraphic = new Graphic( *rObj.mpImp->pGraphic );
327cdf0e10cSrcweir     else
328cdf0e10cSrcweir         mpImp->pGraphic = 0;
329cdf0e10cSrcweir     return *this;
330cdf0e10cSrcweir }
331cdf0e10cSrcweir */
332cdf0e10cSrcweir void EmbeddedObjectRef::Assign( const NS_UNO::Reference < NS_EMBED::XEmbeddedObject >& xObj, sal_Int64 nAspect )
333cdf0e10cSrcweir {
334cdf0e10cSrcweir     DBG_ASSERT( !mxObj.is(), "Never assign an already assigned object!" );
335cdf0e10cSrcweir 
336cdf0e10cSrcweir     Clear();
337cdf0e10cSrcweir     mpImp->nViewAspect = nAspect;
338cdf0e10cSrcweir     mxObj = xObj;
339cdf0e10cSrcweir     mpImp->xListener = EmbedEventListener_Impl::Create( this );
340cdf0e10cSrcweir 
341cdf0e10cSrcweir     //#i103460#
342cdf0e10cSrcweir     if ( IsChart() )
343cdf0e10cSrcweir     {
344cdf0e10cSrcweir         ::com::sun::star::uno::Reference < ::com::sun::star::chart2::XDefaultSizeTransmitter > xSizeTransmitter( xObj, uno::UNO_QUERY );
345cdf0e10cSrcweir         DBG_ASSERT( xSizeTransmitter.is(), "Object does not support XDefaultSizeTransmitter -> will cause #i103460#!" );
346cdf0e10cSrcweir         if( xSizeTransmitter.is() )
347cdf0e10cSrcweir             xSizeTransmitter->setDefaultSize( mpImp->aDefaultSizeForChart_In_100TH_MM );
348cdf0e10cSrcweir     }
349cdf0e10cSrcweir }
350cdf0e10cSrcweir 
351cdf0e10cSrcweir void EmbeddedObjectRef::Clear()
352cdf0e10cSrcweir {
353cdf0e10cSrcweir     if ( mxObj.is() && mpImp->xListener )
354cdf0e10cSrcweir     {
355cdf0e10cSrcweir         mxObj->removeStateChangeListener( mpImp->xListener );
356cdf0e10cSrcweir 
357cdf0e10cSrcweir         uno::Reference < util::XCloseable > xClose( mxObj, uno::UNO_QUERY );
358cdf0e10cSrcweir         if ( xClose.is() )
359cdf0e10cSrcweir             xClose->removeCloseListener( mpImp->xListener );
360cdf0e10cSrcweir 
361cdf0e10cSrcweir         uno::Reference < document::XEventBroadcaster > xBrd( mxObj, uno::UNO_QUERY );
362cdf0e10cSrcweir         if ( xBrd.is() )
363cdf0e10cSrcweir             xBrd->removeEventListener( mpImp->xListener );
364cdf0e10cSrcweir 
365cdf0e10cSrcweir         if ( mpImp->bIsLocked )
366cdf0e10cSrcweir         {
367cdf0e10cSrcweir             if ( xClose.is() )
368cdf0e10cSrcweir             {
369cdf0e10cSrcweir                 try
370cdf0e10cSrcweir                 {
371cdf0e10cSrcweir                     mxObj->changeState( embed::EmbedStates::LOADED );
372cdf0e10cSrcweir                     xClose->close( sal_True );
373cdf0e10cSrcweir                 }
374cdf0e10cSrcweir                 catch ( util::CloseVetoException& )
375cdf0e10cSrcweir                 {
376cdf0e10cSrcweir                     // there's still someone who needs the object!
377cdf0e10cSrcweir                 }
378cdf0e10cSrcweir 				catch ( uno::Exception& )
379cdf0e10cSrcweir 				{
380cdf0e10cSrcweir 					OSL_ENSURE( sal_False, "Error on switching of the object to loaded state and closing!\n" );
381cdf0e10cSrcweir 				}
382cdf0e10cSrcweir             }
383cdf0e10cSrcweir         }
384cdf0e10cSrcweir 
385cdf0e10cSrcweir         if ( mpImp->xListener )
386cdf0e10cSrcweir         {
387cdf0e10cSrcweir             mpImp->xListener->pObject = 0;
388cdf0e10cSrcweir             mpImp->xListener->release();
389cdf0e10cSrcweir             mpImp->xListener = 0;
390cdf0e10cSrcweir         }
391cdf0e10cSrcweir 
392cdf0e10cSrcweir         mxObj = 0;
393cdf0e10cSrcweir         mpImp->bNeedUpdate = sal_False;
394cdf0e10cSrcweir     }
395cdf0e10cSrcweir 
396cdf0e10cSrcweir     mpImp->pContainer = 0;
397cdf0e10cSrcweir     mpImp->bIsLocked = sal_False;
398cdf0e10cSrcweir     mpImp->bNeedUpdate = sal_False;
399cdf0e10cSrcweir }
400cdf0e10cSrcweir 
401cdf0e10cSrcweir void EmbeddedObjectRef::AssignToContainer( comphelper::EmbeddedObjectContainer* pContainer, const ::rtl::OUString& rPersistName )
402cdf0e10cSrcweir {
403cdf0e10cSrcweir     mpImp->pContainer = pContainer;
404cdf0e10cSrcweir     mpImp->aPersistName = rPersistName;
405cdf0e10cSrcweir 
406cdf0e10cSrcweir     if ( mpImp->pGraphic && !mpImp->bNeedUpdate && pContainer )
407cdf0e10cSrcweir 		SetGraphicToContainer( *mpImp->pGraphic, *pContainer, mpImp->aPersistName, ::rtl::OUString() );
408cdf0e10cSrcweir }
409cdf0e10cSrcweir 
410cdf0e10cSrcweir comphelper::EmbeddedObjectContainer* EmbeddedObjectRef::GetContainer() const
411cdf0e10cSrcweir {
412cdf0e10cSrcweir 	return mpImp->pContainer;
413cdf0e10cSrcweir }
414cdf0e10cSrcweir 
415cdf0e10cSrcweir ::rtl::OUString EmbeddedObjectRef::GetPersistName() const
416cdf0e10cSrcweir {
417cdf0e10cSrcweir 	return mpImp->aPersistName;
418cdf0e10cSrcweir }
419cdf0e10cSrcweir 
420cdf0e10cSrcweir MapUnit EmbeddedObjectRef::GetMapUnit() const
421cdf0e10cSrcweir {
422cdf0e10cSrcweir 	if ( mpImp->nViewAspect == embed::Aspects::MSOLE_CONTENT )
423cdf0e10cSrcweir 		return VCLUnoHelper::UnoEmbed2VCLMapUnit( mxObj->getMapUnit( mpImp->nViewAspect ) );
424cdf0e10cSrcweir 	else
425cdf0e10cSrcweir 		// TODO/LATER: currently only CONTENT aspect requires communication with the object
426cdf0e10cSrcweir 		return MAP_100TH_MM;
427cdf0e10cSrcweir }
428cdf0e10cSrcweir 
429cdf0e10cSrcweir sal_Int64 EmbeddedObjectRef::GetViewAspect() const
430cdf0e10cSrcweir {
431cdf0e10cSrcweir     return mpImp->nViewAspect;
432cdf0e10cSrcweir }
433cdf0e10cSrcweir 
434cdf0e10cSrcweir void EmbeddedObjectRef::SetViewAspect( sal_Int64 nAspect )
435cdf0e10cSrcweir {
436cdf0e10cSrcweir     mpImp->nViewAspect = nAspect;
437cdf0e10cSrcweir }
438cdf0e10cSrcweir 
439cdf0e10cSrcweir void EmbeddedObjectRef::Lock( sal_Bool bLock )
440cdf0e10cSrcweir {
441cdf0e10cSrcweir     mpImp->bIsLocked = bLock;
442cdf0e10cSrcweir }
443cdf0e10cSrcweir 
444cdf0e10cSrcweir sal_Bool EmbeddedObjectRef::IsLocked() const
445cdf0e10cSrcweir {
446cdf0e10cSrcweir     return mpImp->bIsLocked;
447cdf0e10cSrcweir }
448cdf0e10cSrcweir 
449cdf0e10cSrcweir void EmbeddedObjectRef::GetReplacement( sal_Bool bUpdate )
450cdf0e10cSrcweir {
451cdf0e10cSrcweir     if ( bUpdate )
452cdf0e10cSrcweir     {
453cdf0e10cSrcweir         DELETEZ( mpImp->pGraphic );
454cdf0e10cSrcweir         mpImp->aMediaType = ::rtl::OUString();
455cdf0e10cSrcweir         mpImp->pGraphic = new Graphic;
456cdf0e10cSrcweir 		if ( mpImp->pHCGraphic )
457cdf0e10cSrcweir             DELETEZ( mpImp->pHCGraphic );
458cdf0e10cSrcweir         mpImp->mnGraphicVersion++;
459cdf0e10cSrcweir     }
460cdf0e10cSrcweir     else if ( !mpImp->pGraphic )
461cdf0e10cSrcweir     {
462cdf0e10cSrcweir         mpImp->pGraphic = new Graphic;
463cdf0e10cSrcweir         mpImp->mnGraphicVersion++;
464cdf0e10cSrcweir     }
465cdf0e10cSrcweir     else
466cdf0e10cSrcweir     {
467cdf0e10cSrcweir         DBG_ERROR("No update, but replacement exists already!");
468cdf0e10cSrcweir         return;
469cdf0e10cSrcweir     }
470cdf0e10cSrcweir 
471cdf0e10cSrcweir     SvStream* pGraphicStream = GetGraphicStream( bUpdate );
472cdf0e10cSrcweir     if ( pGraphicStream )
473cdf0e10cSrcweir     {
474cdf0e10cSrcweir         GraphicFilter* pGF = GraphicFilter::GetGraphicFilter();
475cdf0e10cSrcweir         if( mpImp->pGraphic )
476cdf0e10cSrcweir             pGF->ImportGraphic( *mpImp->pGraphic, String(), *pGraphicStream, GRFILTER_FORMAT_DONTKNOW );
477cdf0e10cSrcweir         mpImp->mnGraphicVersion++;
478cdf0e10cSrcweir         delete pGraphicStream;
479cdf0e10cSrcweir     }
480cdf0e10cSrcweir }
481cdf0e10cSrcweir 
482cdf0e10cSrcweir Graphic* EmbeddedObjectRef::GetGraphic( ::rtl::OUString* pMediaType ) const
483cdf0e10cSrcweir {
484cdf0e10cSrcweir     if ( mpImp->bNeedUpdate )
485cdf0e10cSrcweir         // bNeedUpdate will be set to false while retrieving new replacement
486cdf0e10cSrcweir         const_cast < EmbeddedObjectRef* >(this)->GetReplacement( sal_True );
487cdf0e10cSrcweir     else if ( !mpImp->pGraphic )
488cdf0e10cSrcweir         const_cast < EmbeddedObjectRef* >(this)->GetReplacement( sal_False );
489cdf0e10cSrcweir 
490cdf0e10cSrcweir     if ( mpImp->pGraphic && pMediaType )
491cdf0e10cSrcweir         *pMediaType = mpImp->aMediaType;
492cdf0e10cSrcweir     return mpImp->pGraphic;
493cdf0e10cSrcweir }
494cdf0e10cSrcweir 
495cdf0e10cSrcweir Size EmbeddedObjectRef::GetSize( MapMode* pTargetMapMode ) const
496cdf0e10cSrcweir {
497cdf0e10cSrcweir 	MapMode aSourceMapMode( MAP_100TH_MM );
498cdf0e10cSrcweir 	Size aResult;
499cdf0e10cSrcweir 
500cdf0e10cSrcweir 	if ( mpImp->nViewAspect == embed::Aspects::MSOLE_ICON )
501cdf0e10cSrcweir 	{
502cdf0e10cSrcweir 		Graphic* pGraphic = GetGraphic();
503cdf0e10cSrcweir 		if ( pGraphic )
504cdf0e10cSrcweir 		{
505cdf0e10cSrcweir 			aSourceMapMode = pGraphic->GetPrefMapMode();
506cdf0e10cSrcweir 			aResult = pGraphic->GetPrefSize();
507cdf0e10cSrcweir 		}
508cdf0e10cSrcweir 		else
509cdf0e10cSrcweir 			aResult = Size( 2500, 2500 );
510cdf0e10cSrcweir 	}
511cdf0e10cSrcweir 	else
512cdf0e10cSrcweir 	{
513cdf0e10cSrcweir 		awt::Size aSize;
514cdf0e10cSrcweir 
515cdf0e10cSrcweir 		if ( mxObj.is() )
516cdf0e10cSrcweir 		{
517cdf0e10cSrcweir 			try
518cdf0e10cSrcweir 			{
519cdf0e10cSrcweir 				aSize = mxObj->getVisualAreaSize( mpImp->nViewAspect );
520cdf0e10cSrcweir 			}
521cdf0e10cSrcweir 			catch( embed::NoVisualAreaSizeException& )
522cdf0e10cSrcweir 			{
523cdf0e10cSrcweir 			}
524cdf0e10cSrcweir 			catch( uno::Exception& )
525cdf0e10cSrcweir 			{
526cdf0e10cSrcweir 				OSL_ENSURE( sal_False, "Something went wrong on getting of the size of the object!" );
527cdf0e10cSrcweir 			}
528cdf0e10cSrcweir 
529cdf0e10cSrcweir 			try
530cdf0e10cSrcweir 			{
531cdf0e10cSrcweir 				aSourceMapMode = VCLUnoHelper::UnoEmbed2VCLMapUnit( mxObj->getMapUnit( mpImp->nViewAspect ) );
532cdf0e10cSrcweir 			}
533cdf0e10cSrcweir 			catch( uno::Exception )
534cdf0e10cSrcweir 			{
535cdf0e10cSrcweir 				OSL_ENSURE( sal_False, "Can not get the map mode!" );
536cdf0e10cSrcweir 			}
537cdf0e10cSrcweir 		}
538cdf0e10cSrcweir 
539cdf0e10cSrcweir 		if ( !aSize.Height && !aSize.Width )
540cdf0e10cSrcweir 		{
541cdf0e10cSrcweir 			aSize.Width = 5000;
542cdf0e10cSrcweir 			aSize.Height = 5000;
543cdf0e10cSrcweir 		}
544cdf0e10cSrcweir 
545cdf0e10cSrcweir 		aResult = Size( aSize.Width, aSize.Height );
546cdf0e10cSrcweir 	}
547cdf0e10cSrcweir 
548cdf0e10cSrcweir 	if ( pTargetMapMode )
549cdf0e10cSrcweir 		aResult = OutputDevice::LogicToLogic( aResult, aSourceMapMode, *pTargetMapMode );
550cdf0e10cSrcweir 
551cdf0e10cSrcweir 	return aResult;
552cdf0e10cSrcweir }
553cdf0e10cSrcweir 
554cdf0e10cSrcweir Graphic* EmbeddedObjectRef::GetHCGraphic() const
555cdf0e10cSrcweir {
556cdf0e10cSrcweir 	if ( !mpImp->pHCGraphic )
557cdf0e10cSrcweir 	{
558cdf0e10cSrcweir 		uno::Reference< io::XInputStream > xInStream;
559cdf0e10cSrcweir 		try
560cdf0e10cSrcweir 		{
561cdf0e10cSrcweir 			// if the object needs size on load, that means that it is not our object
562cdf0e10cSrcweir 			// currently the HC mode is supported only for OOo own objects so the following
563cdf0e10cSrcweir 			// check is used as an optimization
564cdf0e10cSrcweir 			// TODO/LATER: shouldn't there be a special status flag to detect alien implementation?
565cdf0e10cSrcweir 			if ( mpImp->nViewAspect == embed::Aspects::MSOLE_CONTENT
566cdf0e10cSrcweir 			  && mxObj.is() && !( mxObj->getStatus( mpImp->nViewAspect ) & embed::EmbedMisc::EMBED_NEEDSSIZEONLOAD ) )
567cdf0e10cSrcweir 			{
568cdf0e10cSrcweir 				// TODO/LATER: optimization, it makes no sence to do it for OLE objects
569cdf0e10cSrcweir 				if ( mxObj->getCurrentState() == embed::EmbedStates::LOADED )
570cdf0e10cSrcweir 					mxObj->changeState( embed::EmbedStates::RUNNING );
571cdf0e10cSrcweir 
572cdf0e10cSrcweir 				// TODO: return for the aspect of the document
573cdf0e10cSrcweir 				embed::VisualRepresentation aVisualRepresentation;
574cdf0e10cSrcweir     			uno::Reference< datatransfer::XTransferable > xTransferable( mxObj->getComponent(), uno::UNO_QUERY );
575cdf0e10cSrcweir 				if ( !xTransferable.is() )
576cdf0e10cSrcweir 					throw uno::RuntimeException();
577cdf0e10cSrcweir 
578cdf0e10cSrcweir 				datatransfer::DataFlavor aDataFlavor(
579cdf0e10cSrcweir             			::rtl::OUString::createFromAscii(
580cdf0e10cSrcweir 								"application/x-openoffice-highcontrast-gdimetafile;windows_formatname=\"GDIMetaFile\"" ),
581cdf0e10cSrcweir 						::rtl::OUString::createFromAscii( "GDIMetaFile" ),
582cdf0e10cSrcweir 						::getCppuType( (const uno::Sequence< sal_Int8 >*) NULL ) );
583cdf0e10cSrcweir 
584cdf0e10cSrcweir 				uno::Sequence < sal_Int8 > aSeq;
585cdf0e10cSrcweir 				if ( ( xTransferable->getTransferData( aDataFlavor ) >>= aSeq ) && aSeq.getLength() )
586cdf0e10cSrcweir 					xInStream = new ::comphelper::SequenceInputStream( aSeq );
587cdf0e10cSrcweir 			}
588cdf0e10cSrcweir 		}
589cdf0e10cSrcweir 		catch ( uno::Exception& )
590cdf0e10cSrcweir 		{
591cdf0e10cSrcweir 		}
592cdf0e10cSrcweir 
593cdf0e10cSrcweir 		if ( xInStream.is() )
594cdf0e10cSrcweir 		{
595cdf0e10cSrcweir 			SvStream* pStream = NULL;
596cdf0e10cSrcweir 			pStream = ::utl::UcbStreamHelper::CreateStream( xInStream );
597cdf0e10cSrcweir 			if ( pStream )
598cdf0e10cSrcweir 			{
599cdf0e10cSrcweir 				if ( !pStream->GetError() )
600cdf0e10cSrcweir 				{
601cdf0e10cSrcweir         			GraphicFilter* pGF = GraphicFilter::GetGraphicFilter();
602cdf0e10cSrcweir 					Graphic* pGraphic = new Graphic();
603cdf0e10cSrcweir         			if ( pGF->ImportGraphic( *pGraphic, String(), *pStream, GRFILTER_FORMAT_DONTKNOW ) == 0 )
604cdf0e10cSrcweir 						mpImp->pHCGraphic = pGraphic;
605cdf0e10cSrcweir 					else
606cdf0e10cSrcweir 						delete pGraphic;
607cdf0e10cSrcweir                     mpImp->mnGraphicVersion++;
608cdf0e10cSrcweir 				}
609cdf0e10cSrcweir 
610cdf0e10cSrcweir         		delete pStream;
611cdf0e10cSrcweir 			}
612cdf0e10cSrcweir 		}
613cdf0e10cSrcweir 	}
614cdf0e10cSrcweir 
615cdf0e10cSrcweir 	return mpImp->pHCGraphic;
616cdf0e10cSrcweir }
617cdf0e10cSrcweir 
618cdf0e10cSrcweir void EmbeddedObjectRef::SetGraphicStream( const uno::Reference< io::XInputStream >& xInGrStream,
619cdf0e10cSrcweir 											const ::rtl::OUString& rMediaType )
620cdf0e10cSrcweir {
621cdf0e10cSrcweir     if ( mpImp->pGraphic )
622cdf0e10cSrcweir         delete mpImp->pGraphic;
623cdf0e10cSrcweir     mpImp->pGraphic = new Graphic();
624cdf0e10cSrcweir     mpImp->aMediaType = rMediaType;
625cdf0e10cSrcweir 	if ( mpImp->pHCGraphic )
626cdf0e10cSrcweir         DELETEZ( mpImp->pHCGraphic );
627cdf0e10cSrcweir     mpImp->mnGraphicVersion++;
628cdf0e10cSrcweir 
629cdf0e10cSrcweir     SvStream* pGraphicStream = ::utl::UcbStreamHelper::CreateStream( xInGrStream );
630cdf0e10cSrcweir 
631cdf0e10cSrcweir     if ( pGraphicStream )
632cdf0e10cSrcweir     {
633cdf0e10cSrcweir         GraphicFilter* pGF = GraphicFilter::GetGraphicFilter();
634cdf0e10cSrcweir         pGF->ImportGraphic( *mpImp->pGraphic, String(), *pGraphicStream, GRFILTER_FORMAT_DONTKNOW );
635cdf0e10cSrcweir         mpImp->mnGraphicVersion++;
636cdf0e10cSrcweir 
637cdf0e10cSrcweir 		if ( mpImp->pContainer )
638cdf0e10cSrcweir 		{
639cdf0e10cSrcweir 			pGraphicStream->Seek( 0 );
640cdf0e10cSrcweir 			uno::Reference< io::XInputStream > xInSeekGrStream = new ::utl::OSeekableInputStreamWrapper( pGraphicStream );
641cdf0e10cSrcweir 
642cdf0e10cSrcweir     		mpImp->pContainer->InsertGraphicStream( xInSeekGrStream, mpImp->aPersistName, rMediaType );
643cdf0e10cSrcweir 		}
644cdf0e10cSrcweir 
645cdf0e10cSrcweir         delete pGraphicStream;
646cdf0e10cSrcweir 	}
647cdf0e10cSrcweir 
648cdf0e10cSrcweir     mpImp->bNeedUpdate = sal_False;
649cdf0e10cSrcweir 
650cdf0e10cSrcweir }
651cdf0e10cSrcweir 
652cdf0e10cSrcweir void EmbeddedObjectRef::SetGraphic( const Graphic& rGraphic, const ::rtl::OUString& rMediaType )
653cdf0e10cSrcweir {
654cdf0e10cSrcweir     if ( mpImp->pGraphic )
655cdf0e10cSrcweir         delete mpImp->pGraphic;
656cdf0e10cSrcweir     mpImp->pGraphic = new Graphic( rGraphic );
657cdf0e10cSrcweir     mpImp->aMediaType = rMediaType;
658cdf0e10cSrcweir 	if ( mpImp->pHCGraphic )
659cdf0e10cSrcweir         DELETEZ( mpImp->pHCGraphic );
660cdf0e10cSrcweir     mpImp->mnGraphicVersion++;
661cdf0e10cSrcweir 
662cdf0e10cSrcweir     if ( mpImp->pContainer )
663cdf0e10cSrcweir 		SetGraphicToContainer( rGraphic, *mpImp->pContainer, mpImp->aPersistName, rMediaType );
664cdf0e10cSrcweir 
665cdf0e10cSrcweir     mpImp->bNeedUpdate = sal_False;
666cdf0e10cSrcweir }
667cdf0e10cSrcweir 
668cdf0e10cSrcweir SvStream* EmbeddedObjectRef::GetGraphicStream( sal_Bool bUpdate ) const
669cdf0e10cSrcweir {
670cdf0e10cSrcweir 	RTL_LOGFILE_CONTEXT( aLog, "svtools (mv76033) svt::EmbeddedObjectRef::GetGraphicStream" );
671cdf0e10cSrcweir     DBG_ASSERT( bUpdate || mpImp->pContainer, "Can't retrieve current graphic!" );
672cdf0e10cSrcweir     uno::Reference < io::XInputStream > xStream;
673cdf0e10cSrcweir     if ( mpImp->pContainer && !bUpdate )
674cdf0e10cSrcweir     {
675cdf0e10cSrcweir 		RTL_LOGFILE_CONTEXT_TRACE( aLog, "getting stream from container" );
676cdf0e10cSrcweir         // try to get graphic stream from container storage
677cdf0e10cSrcweir         xStream = mpImp->pContainer->GetGraphicStream( mxObj, &mpImp->aMediaType );
678cdf0e10cSrcweir         if ( xStream.is() )
679cdf0e10cSrcweir         {
680cdf0e10cSrcweir             const sal_Int32 nConstBufferSize = 32000;
681cdf0e10cSrcweir             SvStream *pStream = new SvMemoryStream( 32000, 32000 );
682cdf0e10cSrcweir             sal_Int32 nRead=0;
683cdf0e10cSrcweir             uno::Sequence < sal_Int8 > aSequence ( nConstBufferSize );
684cdf0e10cSrcweir             do
685cdf0e10cSrcweir             {
686cdf0e10cSrcweir                 nRead = xStream->readBytes ( aSequence, nConstBufferSize );
687cdf0e10cSrcweir                 pStream->Write( aSequence.getConstArray(), nRead );
688cdf0e10cSrcweir             }
689cdf0e10cSrcweir             while ( nRead == nConstBufferSize );
690cdf0e10cSrcweir             pStream->Seek(0);
691cdf0e10cSrcweir             return pStream;
692cdf0e10cSrcweir         }
693cdf0e10cSrcweir     }
694cdf0e10cSrcweir 
695cdf0e10cSrcweir     if ( !xStream.is() )
696cdf0e10cSrcweir     {
697cdf0e10cSrcweir 		RTL_LOGFILE_CONTEXT_TRACE( aLog, "getting stream from object" );
698cdf0e10cSrcweir         // update wanted or no stream in container storage available
699cdf0e10cSrcweir 		xStream = GetGraphicReplacementStream( mpImp->nViewAspect, mxObj, &mpImp->aMediaType );
700cdf0e10cSrcweir 
701cdf0e10cSrcweir 		if ( xStream.is() )
702cdf0e10cSrcweir 		{
703cdf0e10cSrcweir 			if ( mpImp->pContainer )
704cdf0e10cSrcweir             	mpImp->pContainer->InsertGraphicStream( xStream, mpImp->aPersistName, mpImp->aMediaType );
705cdf0e10cSrcweir 
706cdf0e10cSrcweir             SvStream* pResult = ::utl::UcbStreamHelper::CreateStream( xStream );
707cdf0e10cSrcweir             if ( pResult && bUpdate )
708cdf0e10cSrcweir                 mpImp->bNeedUpdate = sal_False;
709cdf0e10cSrcweir 
710cdf0e10cSrcweir             return pResult;
711cdf0e10cSrcweir         }
712cdf0e10cSrcweir     }
713cdf0e10cSrcweir 
714cdf0e10cSrcweir     return NULL;
715cdf0e10cSrcweir }
716cdf0e10cSrcweir 
717cdf0e10cSrcweir void EmbeddedObjectRef::DrawPaintReplacement( const Rectangle &rRect, const String &rText, OutputDevice *pOut )
718cdf0e10cSrcweir {
719cdf0e10cSrcweir 	MapMode aMM( MAP_APPFONT );
720cdf0e10cSrcweir 	Size aAppFontSz = pOut->LogicToLogic( Size( 0, 8 ), &aMM, NULL );
721cdf0e10cSrcweir 	Font aFnt( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "Helvetica" ) ), aAppFontSz );
722cdf0e10cSrcweir 	aFnt.SetTransparent( sal_True );
723cdf0e10cSrcweir 	aFnt.SetColor( Color( COL_LIGHTRED ) );
724cdf0e10cSrcweir 	aFnt.SetWeight( WEIGHT_BOLD );
725cdf0e10cSrcweir 	aFnt.SetFamily( FAMILY_SWISS );
726cdf0e10cSrcweir 
727cdf0e10cSrcweir 	pOut->Push();
728cdf0e10cSrcweir 	pOut->SetBackground();
729cdf0e10cSrcweir 	pOut->SetFont( aFnt );
730cdf0e10cSrcweir 
731cdf0e10cSrcweir 	Point aPt;
732cdf0e10cSrcweir 	// Nun den Text so skalieren, dass er in das Rect passt.
733cdf0e10cSrcweir 	// Wir fangen mit der Defaultsize an und gehen 1-AppFont runter
734cdf0e10cSrcweir 	for( sal_uInt16 i = 8; i > 2; i-- )
735cdf0e10cSrcweir 	{
736cdf0e10cSrcweir 		aPt.X() = (rRect.GetWidth()  - pOut->GetTextWidth( rText )) / 2;
737cdf0e10cSrcweir 		aPt.Y() = (rRect.GetHeight() - pOut->GetTextHeight()) / 2;
738cdf0e10cSrcweir 
739cdf0e10cSrcweir 		sal_Bool bTiny = sal_False;
740cdf0e10cSrcweir 		if( aPt.X() < 0 ) bTiny = sal_True, aPt.X() = 0;
741cdf0e10cSrcweir 		if( aPt.Y() < 0 ) bTiny = sal_True, aPt.Y() = 0;
742cdf0e10cSrcweir 		if( bTiny )
743cdf0e10cSrcweir 		{
744cdf0e10cSrcweir 			// heruntergehen bei kleinen Bildern
745cdf0e10cSrcweir 			aFnt.SetSize( Size( 0, aAppFontSz.Height() * i / 8 ) );
746cdf0e10cSrcweir 			pOut->SetFont( aFnt );
747cdf0e10cSrcweir 		}
748cdf0e10cSrcweir 		else
749cdf0e10cSrcweir 			break;
750cdf0e10cSrcweir 	}
751cdf0e10cSrcweir 
752cdf0e10cSrcweir     Bitmap aBmp( SvtResId( BMP_PLUGIN ) );
753cdf0e10cSrcweir 	long nHeight = rRect.GetHeight() - pOut->GetTextHeight();
754cdf0e10cSrcweir 	long nWidth = rRect.GetWidth();
755cdf0e10cSrcweir 	if( nHeight > 0 )
756cdf0e10cSrcweir 	{
757cdf0e10cSrcweir 		aPt.Y() = nHeight;
758cdf0e10cSrcweir 		Point	aP = rRect.TopLeft();
759cdf0e10cSrcweir 		Size	aBmpSize = aBmp.GetSizePixel();
760cdf0e10cSrcweir 		// Bitmap einpassen
761cdf0e10cSrcweir 		if( nHeight * 10 / nWidth
762cdf0e10cSrcweir 		  > aBmpSize.Height() * 10 / aBmpSize.Width() )
763cdf0e10cSrcweir 		{
764cdf0e10cSrcweir 			// nach der Breite ausrichten
765cdf0e10cSrcweir 			// Proportion beibehalten
766cdf0e10cSrcweir 			long nH = nWidth * aBmpSize.Height() / aBmpSize.Width();
767cdf0e10cSrcweir 			// zentrieren
768cdf0e10cSrcweir 			aP.Y() += (nHeight - nH) / 2;
769cdf0e10cSrcweir 			nHeight = nH;
770cdf0e10cSrcweir 		}
771cdf0e10cSrcweir 		else
772cdf0e10cSrcweir 		{
773cdf0e10cSrcweir 			// nach der H"ohe ausrichten
774cdf0e10cSrcweir 			// Proportion beibehalten
775cdf0e10cSrcweir 			long nW = nHeight * aBmpSize.Width() / aBmpSize.Height();
776cdf0e10cSrcweir 			// zentrieren
777cdf0e10cSrcweir 			aP.X() += (nWidth - nW) / 2;
778cdf0e10cSrcweir 			nWidth = nW;
779cdf0e10cSrcweir 		}
780cdf0e10cSrcweir 
781cdf0e10cSrcweir 		pOut->DrawBitmap( aP, Size( nWidth, nHeight ), aBmp );
782cdf0e10cSrcweir 	}
783cdf0e10cSrcweir 
784cdf0e10cSrcweir 	pOut->IntersectClipRegion( rRect );
785cdf0e10cSrcweir 	aPt += rRect.TopLeft();
786cdf0e10cSrcweir 	pOut->DrawText( aPt, rText );
787cdf0e10cSrcweir 	pOut->Pop();
788cdf0e10cSrcweir }
789cdf0e10cSrcweir 
790cdf0e10cSrcweir void EmbeddedObjectRef::DrawShading( const Rectangle &rRect, OutputDevice *pOut )
791cdf0e10cSrcweir {
792cdf0e10cSrcweir 	GDIMetaFile * pMtf = pOut->GetConnectMetaFile();
793cdf0e10cSrcweir 	if( pMtf && pMtf->IsRecord() )
794cdf0e10cSrcweir 		return;
795cdf0e10cSrcweir 
796cdf0e10cSrcweir 	pOut->Push();
797cdf0e10cSrcweir 	pOut->SetLineColor( Color( COL_BLACK ) );
798cdf0e10cSrcweir 
799cdf0e10cSrcweir 	Size aPixSize = pOut->LogicToPixel( rRect.GetSize() );
800cdf0e10cSrcweir 	aPixSize.Width() -= 1;
801cdf0e10cSrcweir 	aPixSize.Height() -= 1;
802cdf0e10cSrcweir 	Point aPixViewPos = pOut->LogicToPixel( rRect.TopLeft() );
803cdf0e10cSrcweir 	sal_Int32 nMax = aPixSize.Width() + aPixSize.Height();
804cdf0e10cSrcweir 	for( sal_Int32 i = 5; i < nMax; i += 5 )
805cdf0e10cSrcweir 	{
806cdf0e10cSrcweir 		Point a1( aPixViewPos ), a2( aPixViewPos );
807cdf0e10cSrcweir 		if( i > aPixSize.Width() )
808cdf0e10cSrcweir 			a1 += Point( aPixSize.Width(), i - aPixSize.Width() );
809cdf0e10cSrcweir 		else
810cdf0e10cSrcweir 			a1 += Point( i, 0 );
811cdf0e10cSrcweir 		if( i > aPixSize.Height() )
812cdf0e10cSrcweir 			a2 += Point( i - aPixSize.Height(), aPixSize.Height() );
813cdf0e10cSrcweir 		else
814cdf0e10cSrcweir 			a2 += Point( 0, i );
815cdf0e10cSrcweir 
816cdf0e10cSrcweir 		pOut->DrawLine( pOut->PixelToLogic( a1 ), pOut->PixelToLogic( a2 ) );
817cdf0e10cSrcweir 	}
818cdf0e10cSrcweir 
819cdf0e10cSrcweir 	pOut->Pop();
820cdf0e10cSrcweir 
821cdf0e10cSrcweir }
822cdf0e10cSrcweir 
823cdf0e10cSrcweir sal_Bool EmbeddedObjectRef::TryRunningState()
824cdf0e10cSrcweir {
825cdf0e10cSrcweir     return TryRunningState( mxObj );
826cdf0e10cSrcweir }
827cdf0e10cSrcweir 
828cdf0e10cSrcweir sal_Bool EmbeddedObjectRef::TryRunningState( const uno::Reference < embed::XEmbeddedObject >& xEmbObj )
829cdf0e10cSrcweir {
830cdf0e10cSrcweir 	if ( !xEmbObj.is() )
831cdf0e10cSrcweir 		return sal_False;
832cdf0e10cSrcweir 
833cdf0e10cSrcweir     try
834cdf0e10cSrcweir     {
835cdf0e10cSrcweir         if ( xEmbObj->getCurrentState() == embed::EmbedStates::LOADED )
836cdf0e10cSrcweir             xEmbObj->changeState( embed::EmbedStates::RUNNING );
837cdf0e10cSrcweir     }
838cdf0e10cSrcweir     catch ( uno::Exception& )
839cdf0e10cSrcweir     {
840cdf0e10cSrcweir         return sal_False;
841cdf0e10cSrcweir     }
842cdf0e10cSrcweir 
843cdf0e10cSrcweir     return sal_True;
844cdf0e10cSrcweir }
845cdf0e10cSrcweir 
846cdf0e10cSrcweir void EmbeddedObjectRef::SetGraphicToContainer( const Graphic& rGraphic,
847cdf0e10cSrcweir                                                 comphelper::EmbeddedObjectContainer& aContainer,
848cdf0e10cSrcweir                                                 const ::rtl::OUString& aName,
849cdf0e10cSrcweir 												const ::rtl::OUString& aMediaType )
850cdf0e10cSrcweir {
851cdf0e10cSrcweir     SvMemoryStream aStream;
852cdf0e10cSrcweir     aStream.SetVersion( SOFFICE_FILEFORMAT_CURRENT );
853cdf0e10cSrcweir     if ( rGraphic.ExportNative( aStream ) )
854cdf0e10cSrcweir 	{
855cdf0e10cSrcweir 		aStream.Seek( 0 );
856cdf0e10cSrcweir 
857cdf0e10cSrcweir        	uno::Reference < io::XInputStream > xStream = new ::utl::OSeekableInputStreamWrapper( aStream );
858cdf0e10cSrcweir        	aContainer.InsertGraphicStream( xStream, aName, aMediaType );
859cdf0e10cSrcweir 	}
860cdf0e10cSrcweir     else
861cdf0e10cSrcweir         OSL_ENSURE( sal_False, "Export of graphic is failed!\n" );
862cdf0e10cSrcweir }
863cdf0e10cSrcweir 
864cdf0e10cSrcweir sal_Bool EmbeddedObjectRef::ObjectIsModified( const uno::Reference< embed::XEmbeddedObject >& xObj )
865cdf0e10cSrcweir 	throw( uno::Exception )
866cdf0e10cSrcweir {
867cdf0e10cSrcweir 	sal_Bool bResult = sal_False;
868cdf0e10cSrcweir 
869cdf0e10cSrcweir 	sal_Int32 nState = xObj->getCurrentState();
870cdf0e10cSrcweir 	if ( nState != embed::EmbedStates::LOADED && nState != embed::EmbedStates::RUNNING )
871cdf0e10cSrcweir 	{
872cdf0e10cSrcweir 		// the object is active so if the model is modified the replacement
873cdf0e10cSrcweir 		// should be retrieved from the object
874cdf0e10cSrcweir 		uno::Reference< util::XModifiable > xModifiable( xObj->getComponent(), uno::UNO_QUERY );
875cdf0e10cSrcweir 		if ( xModifiable.is() )
876cdf0e10cSrcweir 			bResult = xModifiable->isModified();
877cdf0e10cSrcweir 	}
878cdf0e10cSrcweir 
879cdf0e10cSrcweir 	return bResult;
880cdf0e10cSrcweir }
881cdf0e10cSrcweir 
882cdf0e10cSrcweir uno::Reference< io::XInputStream > EmbeddedObjectRef::GetGraphicReplacementStream(
883cdf0e10cSrcweir 																sal_Int64 nViewAspect,
884cdf0e10cSrcweir 																const uno::Reference< embed::XEmbeddedObject >& xObj,
885cdf0e10cSrcweir 																::rtl::OUString* pMediaType )
886cdf0e10cSrcweir 	throw()
887cdf0e10cSrcweir {
888cdf0e10cSrcweir     return ::comphelper::EmbeddedObjectContainer::GetGraphicReplacementStream(nViewAspect,xObj,pMediaType);
889cdf0e10cSrcweir }
890cdf0e10cSrcweir 
891cdf0e10cSrcweir void EmbeddedObjectRef::UpdateReplacementOnDemand()
892cdf0e10cSrcweir {
893cdf0e10cSrcweir     DELETEZ( mpImp->pGraphic );
894cdf0e10cSrcweir     mpImp->bNeedUpdate = sal_True;
895cdf0e10cSrcweir 	if ( mpImp->pHCGraphic )
896cdf0e10cSrcweir         DELETEZ( mpImp->pHCGraphic );
897cdf0e10cSrcweir     mpImp->mnGraphicVersion++;
898cdf0e10cSrcweir 
899cdf0e10cSrcweir     if( mpImp->pContainer )
900cdf0e10cSrcweir     {
901cdf0e10cSrcweir         //remove graphic from container thus a new up to date one is requested on save
902cdf0e10cSrcweir         mpImp->pContainer->RemoveGraphicStream( mpImp->aPersistName );
903cdf0e10cSrcweir     }
904cdf0e10cSrcweir }
905cdf0e10cSrcweir 
906cdf0e10cSrcweir sal_Bool EmbeddedObjectRef::IsChart() const
907cdf0e10cSrcweir {
908cdf0e10cSrcweir     //todo maybe for 3.0:
909cdf0e10cSrcweir     //if the changes work good for chart
910cdf0e10cSrcweir     //we should apply them for all own ole objects
911cdf0e10cSrcweir 
912cdf0e10cSrcweir     //#i83708# #i81857# #i79578# request an ole replacement image only if really necessary
913cdf0e10cSrcweir     //as this call can be very expensive and does block the user interface as long at it takes
914cdf0e10cSrcweir 
915cdf0e10cSrcweir     if ( !mxObj.is() )
916cdf0e10cSrcweir         return false;
917cdf0e10cSrcweir 
918cdf0e10cSrcweir     SvGlobalName aObjClsId( mxObj->getClassID() );
919cdf0e10cSrcweir     if(
920cdf0e10cSrcweir         SvGlobalName(SO3_SCH_CLASSID_30) == aObjClsId
921cdf0e10cSrcweir         || SvGlobalName(SO3_SCH_CLASSID_40) == aObjClsId
922cdf0e10cSrcweir         || SvGlobalName(SO3_SCH_CLASSID_50) == aObjClsId
923cdf0e10cSrcweir         || SvGlobalName(SO3_SCH_CLASSID_60) == aObjClsId)
924cdf0e10cSrcweir     {
925cdf0e10cSrcweir         return sal_True;
926cdf0e10cSrcweir     }
927cdf0e10cSrcweir 
928cdf0e10cSrcweir     return sal_False;
929cdf0e10cSrcweir }
930cdf0e10cSrcweir 
931cdf0e10cSrcweir // #i104867#
932cdf0e10cSrcweir sal_uInt32 EmbeddedObjectRef::getGraphicVersion() const
933cdf0e10cSrcweir {
934cdf0e10cSrcweir     return mpImp->mnGraphicVersion;
935cdf0e10cSrcweir }
936cdf0e10cSrcweir 
937cdf0e10cSrcweir void EmbeddedObjectRef::SetDefaultSizeForChart( const Size& rSizeIn_100TH_MM )
938cdf0e10cSrcweir {
939cdf0e10cSrcweir     //#i103460# charts do not necessaryly have an own size within ODF files,
940cdf0e10cSrcweir     //for this case they need to use the size settings from the surrounding frame,
941cdf0e10cSrcweir     //which is made available with this method
942cdf0e10cSrcweir 
943cdf0e10cSrcweir     mpImp->aDefaultSizeForChart_In_100TH_MM = awt::Size( rSizeIn_100TH_MM.getWidth(), rSizeIn_100TH_MM.getHeight() );
944cdf0e10cSrcweir 
945cdf0e10cSrcweir     ::com::sun::star::uno::Reference < ::com::sun::star::chart2::XDefaultSizeTransmitter > xSizeTransmitter( mxObj, uno::UNO_QUERY );
946cdf0e10cSrcweir     DBG_ASSERT( xSizeTransmitter.is(), "Object does not support XDefaultSizeTransmitter -> will cause #i103460#!" );
947cdf0e10cSrcweir     if( xSizeTransmitter.is() )
948cdf0e10cSrcweir         xSizeTransmitter->setDefaultSize( mpImp->aDefaultSizeForChart_In_100TH_MM );
949cdf0e10cSrcweir }
950cdf0e10cSrcweir 
951cdf0e10cSrcweir } // namespace svt
952cdf0e10cSrcweir 
953