1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: embedhlp.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svtools.hxx"
34 #include <svtools/embedhlp.hxx>
35 #include <svtools/filter.hxx>
36 #include <svtools/svtools.hrc>
37 #include <svtools/svtdata.hxx>
39 #include <comphelper/embeddedobjectcontainer.hxx>
40 #include <comphelper/seqstream.hxx>
41 #include <toolkit/helper/vclunohelper.hxx>
42 #include <unotools/ucbstreamhelper.hxx>
43 #include <unotools/streamwrap.hxx>
45 #include <tools/globname.hxx>
46 #include <sot/clsids.hxx>
47 #include <com/sun/star/util/XModifyListener.hpp>
48 #ifndef _COM_SUN_STAR_UTIL_XMODIFYiBLE_HPP_
49 #include <com/sun/star/util/XModifiable.hpp>
51 #include <com/sun/star/embed/EmbedStates.hpp>
52 #include <com/sun/star/embed/EmbedMisc.hpp>
53 #include <com/sun/star/embed/XStateChangeListener.hpp>
54 #include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
55 #include <com/sun/star/util/XModifiable.hpp>
56 #include <com/sun/star/datatransfer/XTransferable.hpp>
57 #include <cppuhelper/implbase4.hxx>
58 #include "vcl/svapp.hxx"
59 #include <rtl/logfile.hxx>
61 using namespace com::sun::star
;
66 class EmbedEventListener_Impl
: public ::cppu::WeakImplHelper4
< embed::XStateChangeListener
,
67 document::XEventListener
,
68 util::XModifyListener
,
69 util::XCloseListener
>
72 EmbeddedObjectRef
* pObject
;
75 EmbedEventListener_Impl( EmbeddedObjectRef
* p
) :
80 static EmbedEventListener_Impl
* Create( EmbeddedObjectRef
* );
82 virtual void SAL_CALL
changingState( const lang::EventObject
& aEvent
, ::sal_Int32 nOldState
, ::sal_Int32 nNewState
)
83 throw (embed::WrongStateException
, uno::RuntimeException
);
84 virtual void SAL_CALL
stateChanged( const lang::EventObject
& aEvent
, ::sal_Int32 nOldState
, ::sal_Int32 nNewState
)
85 throw (uno::RuntimeException
);
86 virtual void SAL_CALL
queryClosing( const lang::EventObject
& Source
, ::sal_Bool GetsOwnership
)
87 throw (util::CloseVetoException
, uno::RuntimeException
);
88 virtual void SAL_CALL
notifyClosing( const lang::EventObject
& Source
) throw (uno::RuntimeException
);
89 virtual void SAL_CALL
notifyEvent( const document::EventObject
& aEvent
) throw( uno::RuntimeException
);
90 virtual void SAL_CALL
disposing( const lang::EventObject
& aEvent
) throw( uno::RuntimeException
);
91 virtual void SAL_CALL
modified( const ::com::sun::star::lang::EventObject
& aEvent
) throw (::com::sun::star::uno::RuntimeException
);
94 EmbedEventListener_Impl
* EmbedEventListener_Impl::Create( EmbeddedObjectRef
* p
)
96 EmbedEventListener_Impl
* xRet
= new EmbedEventListener_Impl( p
);
99 if ( p
->GetObject().is() )
101 p
->GetObject()->addStateChangeListener( xRet
);
103 uno::Reference
< util::XCloseable
> xClose( p
->GetObject(), uno::UNO_QUERY
);
104 DBG_ASSERT( xClose
.is(), "Object does not support XCloseable!" );
106 xClose
->addCloseListener( xRet
);
108 uno::Reference
< document::XEventBroadcaster
> xBrd( p
->GetObject(), uno::UNO_QUERY
);
110 xBrd
->addEventListener( xRet
);
112 xRet
->nState
= p
->GetObject()->getCurrentState();
113 if ( xRet
->nState
== embed::EmbedStates::RUNNING
)
115 uno::Reference
< util::XModifiable
> xMod( p
->GetObject()->getComponent(), uno::UNO_QUERY
);
117 // listen for changes in running state (update replacements in case of changes)
118 xMod
->addModifyListener( xRet
);
125 void SAL_CALL
EmbedEventListener_Impl::changingState( const lang::EventObject
&,
128 throw ( embed::WrongStateException
,
129 uno::RuntimeException
)
133 void SAL_CALL
EmbedEventListener_Impl::stateChanged( const lang::EventObject
&,
134 ::sal_Int32 nOldState
,
135 ::sal_Int32 nNewState
)
136 throw ( uno::RuntimeException
)
138 ::vos::OGuard
aGuard( Application::GetSolarMutex() );
143 uno::Reference
< util::XModifiable
> xMod( pObject
->GetObject()->getComponent(), uno::UNO_QUERY
);
144 if ( nNewState
== embed::EmbedStates::RUNNING
)
146 // TODO/LATER: container must be set before!
147 // When is this event created? Who sets the new container when it changed?
148 if( ( pObject
->GetViewAspect() != embed::Aspects::MSOLE_ICON
) && nOldState
!= embed::EmbedStates::LOADED
&& !pObject
->IsChart() )
149 // get new replacement after deactivation
150 pObject
->UpdateReplacement();
152 if( pObject
->IsChart() && nOldState
== embed::EmbedStates::UI_ACTIVE
)
154 //create a new metafile replacement when leaving the edit mode
155 //for buggy documents where the old image looks different from the correct one
156 if( xMod
.is() && !xMod
->isModified() )//in case of modification a new replacement will be requested anyhow
157 pObject
->UpdateReplacementOnDemand();
160 if ( xMod
.is() && nOldState
== embed::EmbedStates::LOADED
)
161 // listen for changes (update replacements in case of changes)
162 xMod
->addModifyListener( this );
164 else if ( nNewState
== embed::EmbedStates::LOADED
)
166 // in loaded state we can't listen
168 xMod
->removeModifyListener( this );
172 void SAL_CALL
EmbedEventListener_Impl::modified( const lang::EventObject
& ) throw (uno::RuntimeException
)
174 ::vos::OGuard
aGuard( Application::GetSolarMutex() );
175 if ( pObject
&& pObject
->GetViewAspect() != embed::Aspects::MSOLE_ICON
)
177 if ( nState
== embed::EmbedStates::RUNNING
)
179 // updates only necessary in non-active states
180 if( pObject
->IsChart() )
181 pObject
->UpdateReplacementOnDemand();
183 pObject
->UpdateReplacement();
185 else if ( nState
== embed::EmbedStates::ACTIVE
||
186 nState
== embed::EmbedStates::UI_ACTIVE
||
187 nState
== embed::EmbedStates::INPLACE_ACTIVE
)
189 // in case the object is inplace or UI active the replacement image should be updated on demand
190 pObject
->UpdateReplacementOnDemand();
196 void SAL_CALL
EmbedEventListener_Impl::notifyEvent( const document::EventObject
& aEvent
) throw( uno::RuntimeException
)
198 ::vos::OGuard
aGuard( Application::GetSolarMutex() );
201 if ( pObject
&& aEvent
.EventName
.equalsAscii("OnSaveDone") || aEvent
.EventName
.equalsAscii("OnSaveAsDone") )
203 // TODO/LATER: container must be set before!
204 // When is this event created? Who sets the new container when it changed?
205 pObject
->UpdateReplacement();
209 if ( pObject
&& aEvent
.EventName
.equalsAscii("OnVisAreaChanged") && pObject
->GetViewAspect() != embed::Aspects::MSOLE_ICON
&& !pObject
->IsChart() )
211 pObject
->UpdateReplacement();
215 void SAL_CALL
EmbedEventListener_Impl::queryClosing( const lang::EventObject
& Source
, ::sal_Bool
)
216 throw ( util::CloseVetoException
, uno::RuntimeException
)
218 // An embedded object can be shared between several objects (f.e. for undo purposes)
219 // the object will not be closed before the last "customer" is destroyed
220 // Now the EmbeddedObjectRef helper class works like a "lock" on the object
221 if ( pObject
&& pObject
->IsLocked() && Source
.Source
== pObject
->GetObject() )
222 throw util::CloseVetoException();
225 void SAL_CALL
EmbedEventListener_Impl::notifyClosing( const lang::EventObject
& Source
) throw (::com::sun::star::uno::RuntimeException
)
227 if ( pObject
&& Source
.Source
== pObject
->GetObject() )
234 void SAL_CALL
EmbedEventListener_Impl::disposing( const lang::EventObject
& aEvent
) throw( uno::RuntimeException
)
236 if ( pObject
&& aEvent
.Source
== pObject
->GetObject() )
243 struct EmbeddedObjectRef_Impl
245 EmbedEventListener_Impl
* xListener
;
246 ::rtl::OUString aPersistName
;
247 ::rtl::OUString aMediaType
;
248 comphelper::EmbeddedObjectContainer
* pContainer
;
251 sal_Int64 nViewAspect
;
253 sal_Bool bNeedUpdate
;
256 void EmbeddedObjectRef::Construct_Impl()
258 mpImp
= new EmbeddedObjectRef_Impl
;
259 mpImp
->pContainer
= 0;
261 mpImp
->pHCGraphic
= 0;
262 mpImp
->nViewAspect
= embed::Aspects::MSOLE_CONTENT
;
263 mpImp
->bIsLocked
= FALSE
;
264 mpImp
->bNeedUpdate
= sal_False
;
267 EmbeddedObjectRef::EmbeddedObjectRef()
272 EmbeddedObjectRef::EmbeddedObjectRef( const NS_UNO::Reference
< NS_EMBED::XEmbeddedObject
>& xObj
, sal_Int64 nAspect
)
275 mpImp
->nViewAspect
= nAspect
;
277 mpImp
->xListener
= EmbedEventListener_Impl::Create( this );
280 EmbeddedObjectRef::EmbeddedObjectRef( const EmbeddedObjectRef
& rObj
)
282 mpImp
= new EmbeddedObjectRef_Impl
;
283 mpImp
->pContainer
= rObj
.mpImp
->pContainer
;
284 mpImp
->nViewAspect
= rObj
.mpImp
->nViewAspect
;
285 mpImp
->bIsLocked
= rObj
.mpImp
->bIsLocked
;
287 mpImp
->xListener
= EmbedEventListener_Impl::Create( this );
288 mpImp
->aPersistName
= rObj
.mpImp
->aPersistName
;
289 mpImp
->aMediaType
= rObj
.mpImp
->aMediaType
;
290 mpImp
->bNeedUpdate
= rObj
.mpImp
->bNeedUpdate
;
292 if ( rObj
.mpImp
->pGraphic
&& !rObj
.mpImp
->bNeedUpdate
)
293 mpImp
->pGraphic
= new Graphic( *rObj
.mpImp
->pGraphic
);
297 mpImp
->pHCGraphic
= 0;
300 EmbeddedObjectRef::~EmbeddedObjectRef()
302 delete mpImp
->pGraphic
;
303 if ( mpImp
->pHCGraphic
) DELETEZ( mpImp
->pHCGraphic
);
307 EmbeddedObjectRef& EmbeddedObjectRef::operator = ( const EmbeddedObjectRef& rObj )
309 DBG_ASSERT( !mxObj.is(), "Never assign an already assigned object!" );
311 delete mpImp->pGraphic;
312 if ( mpImp->pHCGraphic ) DELETEZ( mpImp->pHCGraphic );
315 mpImp->nViewAspect = rObj.mpImp->nViewAspect;
316 mpImp->bIsLocked = rObj.mpImp->bIsLocked;
318 mpImp->xListener = EmbedEventListener_Impl::Create( this );
319 mpImp->pContainer = rObj.mpImp->pContainer;
320 mpImp->aPersistName = rObj.mpImp->aPersistName;
321 mpImp->aMediaType = rObj.mpImp->aMediaType;
322 mpImp->bNeedUpdate = rObj.mpImp->bNeedUpdate;
324 if ( rObj.mpImp->pGraphic && !rObj.mpImp->bNeedUpdate )
325 mpImp->pGraphic = new Graphic( *rObj.mpImp->pGraphic );
331 void EmbeddedObjectRef::Assign( const NS_UNO::Reference
< NS_EMBED::XEmbeddedObject
>& xObj
, sal_Int64 nAspect
)
333 DBG_ASSERT( !mxObj
.is(), "Never assign an already assigned object!" );
336 mpImp
->nViewAspect
= nAspect
;
338 mpImp
->xListener
= EmbedEventListener_Impl::Create( this );
341 void EmbeddedObjectRef::Clear()
343 if ( mxObj
.is() && mpImp
->xListener
)
345 mxObj
->removeStateChangeListener( mpImp
->xListener
);
347 uno::Reference
< util::XCloseable
> xClose( mxObj
, uno::UNO_QUERY
);
349 xClose
->removeCloseListener( mpImp
->xListener
);
351 uno::Reference
< document::XEventBroadcaster
> xBrd( mxObj
, uno::UNO_QUERY
);
353 xBrd
->removeEventListener( mpImp
->xListener
);
355 if ( mpImp
->bIsLocked
)
361 mxObj
->changeState( embed::EmbedStates::LOADED
);
362 xClose
->close( sal_True
);
364 catch ( util::CloseVetoException
& )
366 // there's still someone who needs the object!
368 catch ( uno::Exception
& )
370 OSL_ENSURE( sal_False
, "Error on switching of the object to loaded state and closing!\n" );
375 if ( mpImp
->xListener
)
377 mpImp
->xListener
->pObject
= 0;
378 mpImp
->xListener
->release();
379 mpImp
->xListener
= 0;
383 mpImp
->bNeedUpdate
= sal_False
;
386 mpImp
->pContainer
= 0;
387 mpImp
->bIsLocked
= FALSE
;
388 mpImp
->bNeedUpdate
= sal_False
;
391 void EmbeddedObjectRef::AssignToContainer( comphelper::EmbeddedObjectContainer
* pContainer
, const ::rtl::OUString
& rPersistName
)
393 mpImp
->pContainer
= pContainer
;
394 mpImp
->aPersistName
= rPersistName
;
396 if ( mpImp
->pGraphic
&& !mpImp
->bNeedUpdate
&& pContainer
)
397 SetGraphicToContainer( *mpImp
->pGraphic
, *pContainer
, mpImp
->aPersistName
, ::rtl::OUString() );
400 comphelper::EmbeddedObjectContainer
* EmbeddedObjectRef::GetContainer() const
402 return mpImp
->pContainer
;
405 ::rtl::OUString
EmbeddedObjectRef::GetPersistName() const
407 return mpImp
->aPersistName
;
410 MapUnit
EmbeddedObjectRef::GetMapUnit() const
412 if ( mpImp
->nViewAspect
== embed::Aspects::MSOLE_CONTENT
)
413 return VCLUnoHelper::UnoEmbed2VCLMapUnit( mxObj
->getMapUnit( mpImp
->nViewAspect
) );
415 // TODO/LATER: currently only CONTENT aspect requires communication with the object
419 sal_Int64
EmbeddedObjectRef::GetViewAspect() const
421 return mpImp
->nViewAspect
;
424 void EmbeddedObjectRef::SetViewAspect( sal_Int64 nAspect
)
426 mpImp
->nViewAspect
= nAspect
;
429 void EmbeddedObjectRef::Lock( BOOL bLock
)
431 mpImp
->bIsLocked
= bLock
;
434 BOOL
EmbeddedObjectRef::IsLocked() const
436 return mpImp
->bIsLocked
;
439 void EmbeddedObjectRef::GetReplacement( BOOL bUpdate
)
443 DELETEZ( mpImp
->pGraphic
);
444 mpImp
->aMediaType
= ::rtl::OUString();
445 mpImp
->pGraphic
= new Graphic
;
446 if ( mpImp
->pHCGraphic
) DELETEZ( mpImp
->pHCGraphic
);
448 else if ( !mpImp
->pGraphic
)
449 mpImp
->pGraphic
= new Graphic
;
452 DBG_ERROR("No update, but replacement exists already!");
456 SvStream
* pGraphicStream
= GetGraphicStream( bUpdate
);
457 if ( pGraphicStream
)
459 GraphicFilter
* pGF
= GraphicFilter::GetGraphicFilter();
460 if( mpImp
->pGraphic
)
461 pGF
->ImportGraphic( *mpImp
->pGraphic
, String(), *pGraphicStream
, GRFILTER_FORMAT_DONTKNOW
);
462 delete pGraphicStream
;
466 Graphic
* EmbeddedObjectRef::GetGraphic( ::rtl::OUString
* pMediaType
) const
468 if ( mpImp
->bNeedUpdate
)
469 // bNeedUpdate will be set to false while retrieving new replacement
470 const_cast < EmbeddedObjectRef
* >(this)->GetReplacement( sal_True
);
471 else if ( !mpImp
->pGraphic
)
472 const_cast < EmbeddedObjectRef
* >(this)->GetReplacement( FALSE
);
474 if ( mpImp
->pGraphic
&& pMediaType
)
475 *pMediaType
= mpImp
->aMediaType
;
476 return mpImp
->pGraphic
;
479 Size
EmbeddedObjectRef::GetSize( MapMode
* pTargetMapMode
) const
481 MapMode
aSourceMapMode( MAP_100TH_MM
);
484 if ( mpImp
->nViewAspect
== embed::Aspects::MSOLE_ICON
)
486 Graphic
* pGraphic
= GetGraphic();
489 aSourceMapMode
= pGraphic
->GetPrefMapMode();
490 aResult
= pGraphic
->GetPrefSize();
493 aResult
= Size( 2500, 2500 );
503 aSize
= mxObj
->getVisualAreaSize( mpImp
->nViewAspect
);
505 catch( embed::NoVisualAreaSizeException
& )
508 catch( uno::Exception
& )
510 OSL_ENSURE( sal_False
, "Something went wrong on getting of the size of the object!" );
515 aSourceMapMode
= VCLUnoHelper::UnoEmbed2VCLMapUnit( mxObj
->getMapUnit( mpImp
->nViewAspect
) );
517 catch( uno::Exception
)
519 OSL_ENSURE( sal_False
, "Can not get the map mode!" );
523 if ( !aSize
.Height
&& !aSize
.Width
)
529 aResult
= Size( aSize
.Width
, aSize
.Height
);
532 if ( pTargetMapMode
)
533 aResult
= OutputDevice::LogicToLogic( aResult
, aSourceMapMode
, *pTargetMapMode
);
538 Graphic
* EmbeddedObjectRef::GetHCGraphic() const
540 if ( !mpImp
->pHCGraphic
)
542 uno::Reference
< io::XInputStream
> xInStream
;
545 // if the object needs size on load, that means that it is not our object
546 // currently the HC mode is supported only for OOo own objects so the following
547 // check is used as an optimization
548 // TODO/LATER: shouldn't there be a special status flag to detect alien implementation?
549 if ( mpImp
->nViewAspect
== embed::Aspects::MSOLE_CONTENT
550 && mxObj
.is() && !( mxObj
->getStatus( mpImp
->nViewAspect
) & embed::EmbedMisc::EMBED_NEEDSSIZEONLOAD
) )
552 // TODO/LATER: optimization, it makes no sence to do it for OLE objects
553 if ( mxObj
->getCurrentState() == embed::EmbedStates::LOADED
)
554 mxObj
->changeState( embed::EmbedStates::RUNNING
);
556 // TODO: return for the aspect of the document
557 embed::VisualRepresentation aVisualRepresentation
;
558 uno::Reference
< datatransfer::XTransferable
> xTransferable( mxObj
->getComponent(), uno::UNO_QUERY
);
559 if ( !xTransferable
.is() )
560 throw uno::RuntimeException();
562 datatransfer::DataFlavor
aDataFlavor(
563 ::rtl::OUString::createFromAscii(
564 "application/x-openoffice-highcontrast-gdimetafile;windows_formatname=\"GDIMetaFile\"" ),
565 ::rtl::OUString::createFromAscii( "GDIMetaFile" ),
566 ::getCppuType( (const uno::Sequence
< sal_Int8
>*) NULL
) );
568 uno::Sequence
< sal_Int8
> aSeq
;
569 if ( ( xTransferable
->getTransferData( aDataFlavor
) >>= aSeq
) && aSeq
.getLength() )
570 xInStream
= new ::comphelper::SequenceInputStream( aSeq
);
573 catch ( uno::Exception
& )
577 if ( xInStream
.is() )
579 SvStream
* pStream
= NULL
;
580 pStream
= ::utl::UcbStreamHelper::CreateStream( xInStream
);
583 if ( !pStream
->GetError() )
585 GraphicFilter
* pGF
= GraphicFilter::GetGraphicFilter();
586 Graphic
* pGraphic
= new Graphic();
587 if ( pGF
->ImportGraphic( *pGraphic
, String(), *pStream
, GRFILTER_FORMAT_DONTKNOW
) == 0 )
588 mpImp
->pHCGraphic
= pGraphic
;
598 return mpImp
->pHCGraphic
;
601 void EmbeddedObjectRef::SetGraphicStream( const uno::Reference
< io::XInputStream
>& xInGrStream
,
602 const ::rtl::OUString
& rMediaType
)
604 if ( mpImp
->pGraphic
)
605 delete mpImp
->pGraphic
;
606 mpImp
->pGraphic
= new Graphic();
607 mpImp
->aMediaType
= rMediaType
;
608 if ( mpImp
->pHCGraphic
) DELETEZ( mpImp
->pHCGraphic
);
610 SvStream
* pGraphicStream
= ::utl::UcbStreamHelper::CreateStream( xInGrStream
);
612 if ( pGraphicStream
)
614 GraphicFilter
* pGF
= GraphicFilter::GetGraphicFilter();
615 pGF
->ImportGraphic( *mpImp
->pGraphic
, String(), *pGraphicStream
, GRFILTER_FORMAT_DONTKNOW
);
617 if ( mpImp
->pContainer
)
619 pGraphicStream
->Seek( 0 );
620 uno::Reference
< io::XInputStream
> xInSeekGrStream
= new ::utl::OSeekableInputStreamWrapper( pGraphicStream
);
622 mpImp
->pContainer
->InsertGraphicStream( xInSeekGrStream
, mpImp
->aPersistName
, rMediaType
);
625 delete pGraphicStream
;
628 mpImp
->bNeedUpdate
= sal_False
;
632 void EmbeddedObjectRef::SetGraphic( const Graphic
& rGraphic
, const ::rtl::OUString
& rMediaType
)
634 if ( mpImp
->pGraphic
)
635 delete mpImp
->pGraphic
;
636 mpImp
->pGraphic
= new Graphic( rGraphic
);
637 mpImp
->aMediaType
= rMediaType
;
638 if ( mpImp
->pHCGraphic
) DELETEZ( mpImp
->pHCGraphic
);
640 if ( mpImp
->pContainer
)
641 SetGraphicToContainer( rGraphic
, *mpImp
->pContainer
, mpImp
->aPersistName
, rMediaType
);
643 mpImp
->bNeedUpdate
= sal_False
;
646 SvStream
* EmbeddedObjectRef::GetGraphicStream( BOOL bUpdate
) const
648 RTL_LOGFILE_CONTEXT( aLog
, "svtools (mv76033) svt::EmbeddedObjectRef::GetGraphicStream" );
649 DBG_ASSERT( bUpdate
|| mpImp
->pContainer
, "Can't retrieve current graphic!" );
650 uno::Reference
< io::XInputStream
> xStream
;
651 if ( mpImp
->pContainer
&& !bUpdate
)
653 RTL_LOGFILE_CONTEXT_TRACE( aLog
, "getting stream from container" );
654 // try to get graphic stream from container storage
655 xStream
= mpImp
->pContainer
->GetGraphicStream( mxObj
, &mpImp
->aMediaType
);
658 const sal_Int32 nConstBufferSize
= 32000;
659 SvStream
*pStream
= new SvMemoryStream( 32000, 32000 );
661 uno::Sequence
< sal_Int8
> aSequence ( nConstBufferSize
);
664 nRead
= xStream
->readBytes ( aSequence
, nConstBufferSize
);
665 pStream
->Write( aSequence
.getConstArray(), nRead
);
667 while ( nRead
== nConstBufferSize
);
675 RTL_LOGFILE_CONTEXT_TRACE( aLog
, "getting stream from object" );
676 // update wanted or no stream in container storage available
677 xStream
= GetGraphicReplacementStream( mpImp
->nViewAspect
, mxObj
, &mpImp
->aMediaType
);
681 if ( mpImp
->pContainer
)
682 mpImp
->pContainer
->InsertGraphicStream( xStream
, mpImp
->aPersistName
, mpImp
->aMediaType
);
684 SvStream
* pResult
= ::utl::UcbStreamHelper::CreateStream( xStream
);
685 if ( pResult
&& bUpdate
)
686 mpImp
->bNeedUpdate
= sal_False
;
695 void EmbeddedObjectRef::DrawPaintReplacement( const Rectangle
&rRect
, const String
&rText
, OutputDevice
*pOut
)
697 MapMode
aMM( MAP_APPFONT
);
698 Size aAppFontSz
= pOut
->LogicToLogic( Size( 0, 8 ), &aMM
, NULL
);
699 Font
aFnt( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "Helvetica" ) ), aAppFontSz
);
700 aFnt
.SetTransparent( TRUE
);
701 aFnt
.SetColor( Color( COL_LIGHTRED
) );
702 aFnt
.SetWeight( WEIGHT_BOLD
);
703 aFnt
.SetFamily( FAMILY_SWISS
);
706 pOut
->SetBackground();
707 pOut
->SetFont( aFnt
);
710 // Nun den Text so skalieren, dass er in das Rect passt.
711 // Wir fangen mit der Defaultsize an und gehen 1-AppFont runter
712 for( USHORT i
= 8; i
> 2; i
-- )
714 aPt
.X() = (rRect
.GetWidth() - pOut
->GetTextWidth( rText
)) / 2;
715 aPt
.Y() = (rRect
.GetHeight() - pOut
->GetTextHeight()) / 2;
718 if( aPt
.X() < 0 ) bTiny
= TRUE
, aPt
.X() = 0;
719 if( aPt
.Y() < 0 ) bTiny
= TRUE
, aPt
.Y() = 0;
722 // heruntergehen bei kleinen Bildern
723 aFnt
.SetSize( Size( 0, aAppFontSz
.Height() * i
/ 8 ) );
724 pOut
->SetFont( aFnt
);
730 Bitmap
aBmp( SvtResId( BMP_PLUGIN
) );
731 long nHeight
= rRect
.GetHeight() - pOut
->GetTextHeight();
732 long nWidth
= rRect
.GetWidth();
736 Point aP
= rRect
.TopLeft();
737 Size aBmpSize
= aBmp
.GetSizePixel();
739 if( nHeight
* 10 / nWidth
740 > aBmpSize
.Height() * 10 / aBmpSize
.Width() )
742 // nach der Breite ausrichten
743 // Proportion beibehalten
744 long nH
= nWidth
* aBmpSize
.Height() / aBmpSize
.Width();
746 aP
.Y() += (nHeight
- nH
) / 2;
751 // nach der H"ohe ausrichten
752 // Proportion beibehalten
753 long nW
= nHeight
* aBmpSize
.Width() / aBmpSize
.Height();
755 aP
.X() += (nWidth
- nW
) / 2;
759 pOut
->DrawBitmap( aP
, Size( nWidth
, nHeight
), aBmp
);
762 pOut
->IntersectClipRegion( rRect
);
763 aPt
+= rRect
.TopLeft();
764 pOut
->DrawText( aPt
, rText
);
768 void EmbeddedObjectRef::DrawShading( const Rectangle
&rRect
, OutputDevice
*pOut
)
770 GDIMetaFile
* pMtf
= pOut
->GetConnectMetaFile();
771 if( pMtf
&& pMtf
->IsRecord() )
775 pOut
->SetLineColor( Color( COL_BLACK
) );
777 Size aPixSize
= pOut
->LogicToPixel( rRect
.GetSize() );
778 aPixSize
.Width() -= 1;
779 aPixSize
.Height() -= 1;
780 Point aPixViewPos
= pOut
->LogicToPixel( rRect
.TopLeft() );
781 INT32 nMax
= aPixSize
.Width() + aPixSize
.Height();
782 for( INT32 i
= 5; i
< nMax
; i
+= 5 )
784 Point
a1( aPixViewPos
), a2( aPixViewPos
);
785 if( i
> aPixSize
.Width() )
786 a1
+= Point( aPixSize
.Width(), i
- aPixSize
.Width() );
789 if( i
> aPixSize
.Height() )
790 a2
+= Point( i
- aPixSize
.Height(), aPixSize
.Height() );
794 pOut
->DrawLine( pOut
->PixelToLogic( a1
), pOut
->PixelToLogic( a2
) );
801 BOOL
EmbeddedObjectRef::TryRunningState()
803 return TryRunningState( mxObj
);
806 BOOL
EmbeddedObjectRef::TryRunningState( const uno::Reference
< embed::XEmbeddedObject
>& xEmbObj
)
813 if ( xEmbObj
->getCurrentState() == embed::EmbedStates::LOADED
)
814 xEmbObj
->changeState( embed::EmbedStates::RUNNING
);
816 catch ( uno::Exception
& )
824 void EmbeddedObjectRef::SetGraphicToContainer( const Graphic
& rGraphic
,
825 comphelper::EmbeddedObjectContainer
& aContainer
,
826 const ::rtl::OUString
& aName
,
827 const ::rtl::OUString
& aMediaType
)
829 SvMemoryStream aStream
;
830 aStream
.SetVersion( SOFFICE_FILEFORMAT_CURRENT
);
831 if ( rGraphic
.ExportNative( aStream
) )
835 uno::Reference
< io::XInputStream
> xStream
= new ::utl::OSeekableInputStreamWrapper( aStream
);
836 aContainer
.InsertGraphicStream( xStream
, aName
, aMediaType
);
839 OSL_ENSURE( sal_False
, "Export of graphic is failed!\n" );
842 sal_Bool
EmbeddedObjectRef::ObjectIsModified( const uno::Reference
< embed::XEmbeddedObject
>& xObj
)
843 throw( uno::Exception
)
845 sal_Bool bResult
= sal_False
;
847 sal_Int32 nState
= xObj
->getCurrentState();
848 if ( nState
!= embed::EmbedStates::LOADED
&& nState
!= embed::EmbedStates::RUNNING
)
850 // the object is active so if the model is modified the replacement
851 // should be retrieved from the object
852 uno::Reference
< util::XModifiable
> xModifiable( xObj
->getComponent(), uno::UNO_QUERY
);
853 if ( xModifiable
.is() )
854 bResult
= xModifiable
->isModified();
860 uno::Reference
< io::XInputStream
> EmbeddedObjectRef::GetGraphicReplacementStream(
861 sal_Int64 nViewAspect
,
862 const uno::Reference
< embed::XEmbeddedObject
>& xObj
,
863 ::rtl::OUString
* pMediaType
)
866 return ::comphelper::EmbeddedObjectContainer::GetGraphicReplacementStream(nViewAspect
,xObj
,pMediaType
);
869 void EmbeddedObjectRef::UpdateReplacementOnDemand()
871 DELETEZ( mpImp
->pGraphic
);
872 mpImp
->bNeedUpdate
= sal_True
;
873 if ( mpImp
->pHCGraphic
) DELETEZ( mpImp
->pHCGraphic
);
875 if( mpImp
->pContainer
)
877 //remove graphic from container thus a new up to date one is requested on save
878 mpImp
->pContainer
->RemoveGraphicStream( mpImp
->aPersistName
);
882 BOOL
EmbeddedObjectRef::IsChart() const
884 //todo maybe for 3.0:
885 //if the changes work good for chart
886 //we should apply them for all own ole objects
888 //#i83708# #i81857# #i79578# request an ole replacement image only if really necessary
889 //as this call can be very expensive and does block the user interface as long at it takes
894 SvGlobalName
aObjClsId( mxObj
->getClassID() );
896 SvGlobalName(SO3_SCH_CLASSID_30
) == aObjClsId
897 || SvGlobalName(SO3_SCH_CLASSID_40
) == aObjClsId
898 || SvGlobalName(SO3_SCH_CLASSID_50
) == aObjClsId
899 || SvGlobalName(SO3_SCH_CLASSID_60
) == aObjClsId
)