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