1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <svtools/embedhlp.hxx>
22 #include <vcl/graphicfilter.hxx>
23 #include <svtools/svtools.hrc>
24 #include <svtools/svtresid.hxx>
26 #include <comphelper/embeddedobjectcontainer.hxx>
27 #include <comphelper/seqstream.hxx>
28 #include <toolkit/helper/vclunohelper.hxx>
29 #include <unotools/ucbstreamhelper.hxx>
30 #include <unotools/streamwrap.hxx>
32 #include <tools/globname.hxx>
33 #include <comphelper/classids.hxx>
34 #include <com/sun/star/util/XModifyListener.hpp>
35 #include <com/sun/star/util/XModifiable.hpp>
36 #include <com/sun/star/embed/Aspects.hpp>
37 #include <com/sun/star/embed/EmbedMisc.hpp>
38 #include <com/sun/star/embed/EmbedStates.hpp>
39 #include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
40 #include <com/sun/star/embed/XEmbeddedObject.hpp>
41 #include <com/sun/star/embed/XStateChangeListener.hpp>
42 #include <com/sun/star/datatransfer/XTransferable.hpp>
43 #include <com/sun/star/chart2/XDefaultSizeTransmitter.hpp>
44 #include <cppuhelper/implbase4.hxx>
45 #include "vcl/svapp.hxx"
46 #include <rtl/logfile.hxx>
47 #include <osl/mutex.hxx>
49 using namespace com::sun::star
;
53 class EmbedEventListener_Impl
: public ::cppu::WeakImplHelper4
< embed::XStateChangeListener
,
54 document::XEventListener
,
55 util::XModifyListener
,
56 util::XCloseListener
>
59 EmbeddedObjectRef
* pObject
;
62 EmbedEventListener_Impl( EmbeddedObjectRef
* p
) :
67 static EmbedEventListener_Impl
* Create( EmbeddedObjectRef
* );
69 virtual void SAL_CALL
changingState( const lang::EventObject
& aEvent
, ::sal_Int32 nOldState
, ::sal_Int32 nNewState
)
70 throw (embed::WrongStateException
, uno::RuntimeException
);
71 virtual void SAL_CALL
stateChanged( const lang::EventObject
& aEvent
, ::sal_Int32 nOldState
, ::sal_Int32 nNewState
)
72 throw (uno::RuntimeException
);
73 virtual void SAL_CALL
queryClosing( const lang::EventObject
& Source
, ::sal_Bool GetsOwnership
)
74 throw (util::CloseVetoException
, uno::RuntimeException
);
75 virtual void SAL_CALL
notifyClosing( const lang::EventObject
& Source
) throw (uno::RuntimeException
);
76 virtual void SAL_CALL
notifyEvent( const document::EventObject
& aEvent
) throw( uno::RuntimeException
);
77 virtual void SAL_CALL
disposing( const lang::EventObject
& aEvent
) throw( uno::RuntimeException
);
78 virtual void SAL_CALL
modified( const ::com::sun::star::lang::EventObject
& aEvent
) throw (::com::sun::star::uno::RuntimeException
);
81 EmbedEventListener_Impl
* EmbedEventListener_Impl::Create( EmbeddedObjectRef
* p
)
83 EmbedEventListener_Impl
* xRet
= new EmbedEventListener_Impl( p
);
86 if ( p
->GetObject().is() )
88 p
->GetObject()->addStateChangeListener( xRet
);
90 uno::Reference
< util::XCloseable
> xClose( p
->GetObject(), uno::UNO_QUERY
);
91 DBG_ASSERT( xClose
.is(), "Object does not support XCloseable!" );
93 xClose
->addCloseListener( xRet
);
95 uno::Reference
< document::XEventBroadcaster
> xBrd( p
->GetObject(), uno::UNO_QUERY
);
97 xBrd
->addEventListener( xRet
);
99 xRet
->nState
= p
->GetObject()->getCurrentState();
100 if ( xRet
->nState
== embed::EmbedStates::RUNNING
)
102 uno::Reference
< util::XModifiable
> xMod( p
->GetObject()->getComponent(), uno::UNO_QUERY
);
104 // listen for changes in running state (update replacements in case of changes)
105 xMod
->addModifyListener( xRet
);
112 void SAL_CALL
EmbedEventListener_Impl::changingState( const lang::EventObject
&,
115 throw ( embed::WrongStateException
,
116 uno::RuntimeException
)
120 void SAL_CALL
EmbedEventListener_Impl::stateChanged( const lang::EventObject
&,
121 ::sal_Int32 nOldState
,
122 ::sal_Int32 nNewState
)
123 throw ( uno::RuntimeException
)
125 SolarMutexGuard aGuard
;
130 uno::Reference
< util::XModifiable
> xMod( pObject
->GetObject()->getComponent(), uno::UNO_QUERY
);
131 if ( nNewState
== embed::EmbedStates::RUNNING
)
133 // TODO/LATER: container must be set before!
134 // When is this event created? Who sets the new container when it changed?
135 if( ( pObject
->GetViewAspect() != embed::Aspects::MSOLE_ICON
) && nOldState
!= embed::EmbedStates::LOADED
&& !pObject
->IsChart() )
136 // get new replacement after deactivation
137 pObject
->UpdateReplacement();
139 if( pObject
->IsChart() && nOldState
== embed::EmbedStates::UI_ACTIVE
)
141 //create a new metafile replacement when leaving the edit mode
142 //for buggy documents where the old image looks different from the correct one
143 if( xMod
.is() && !xMod
->isModified() )//in case of modification a new replacement will be requested anyhow
144 pObject
->UpdateReplacementOnDemand();
147 if ( xMod
.is() && nOldState
== embed::EmbedStates::LOADED
)
148 // listen for changes (update replacements in case of changes)
149 xMod
->addModifyListener( this );
151 else if ( nNewState
== embed::EmbedStates::LOADED
)
153 // in loaded state we can't listen
155 xMod
->removeModifyListener( this );
159 void SAL_CALL
EmbedEventListener_Impl::modified( const lang::EventObject
& ) throw (uno::RuntimeException
)
161 SolarMutexGuard aGuard
;
162 if ( pObject
&& pObject
->GetViewAspect() != embed::Aspects::MSOLE_ICON
)
164 if ( nState
== embed::EmbedStates::RUNNING
)
166 // updates only necessary in non-active states
167 if( pObject
->IsChart() )
168 pObject
->UpdateReplacementOnDemand();
170 pObject
->UpdateReplacement();
172 else if ( nState
== embed::EmbedStates::ACTIVE
||
173 nState
== embed::EmbedStates::UI_ACTIVE
||
174 nState
== embed::EmbedStates::INPLACE_ACTIVE
)
176 // in case the object is inplace or UI active the replacement image should be updated on demand
177 pObject
->UpdateReplacementOnDemand();
182 void SAL_CALL
EmbedEventListener_Impl::notifyEvent( const document::EventObject
& aEvent
) throw( uno::RuntimeException
)
184 SolarMutexGuard aGuard
;
186 if ( pObject
&& aEvent
.EventName
== "OnVisAreaChanged" && pObject
->GetViewAspect() != embed::Aspects::MSOLE_ICON
&& !pObject
->IsChart() )
188 pObject
->UpdateReplacement();
192 void SAL_CALL
EmbedEventListener_Impl::queryClosing( const lang::EventObject
& Source
, ::sal_Bool
)
193 throw ( util::CloseVetoException
, uno::RuntimeException
)
195 // An embedded object can be shared between several objects (f.e. for undo purposes)
196 // the object will not be closed before the last "customer" is destroyed
197 // Now the EmbeddedObjectRef helper class works like a "lock" on the object
198 if ( pObject
&& pObject
->IsLocked() && Source
.Source
== pObject
->GetObject() )
199 throw util::CloseVetoException();
202 void SAL_CALL
EmbedEventListener_Impl::notifyClosing( const lang::EventObject
& Source
) throw (::com::sun::star::uno::RuntimeException
)
204 if ( pObject
&& Source
.Source
== pObject
->GetObject() )
211 void SAL_CALL
EmbedEventListener_Impl::disposing( const lang::EventObject
& aEvent
) throw( uno::RuntimeException
)
213 if ( pObject
&& aEvent
.Source
== pObject
->GetObject() )
220 struct EmbeddedObjectRef_Impl
222 uno::Reference
<embed::XEmbeddedObject
> mxObj
;
224 EmbedEventListener_Impl
* xListener
;
225 OUString aPersistName
;
227 comphelper::EmbeddedObjectContainer
* pContainer
;
229 sal_Int64 nViewAspect
;
234 sal_uInt32 mnGraphicVersion
;
235 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
237 EmbeddedObjectRef_Impl() :
240 nViewAspect(embed::Aspects::MSOLE_CONTENT
),
244 aDefaultSizeForChart_In_100TH_MM(awt::Size(8000,7000))
247 EmbeddedObjectRef_Impl( const EmbeddedObjectRef_Impl
& r
) :
249 aPersistName(r
.aPersistName
),
250 aMediaType(r
.aMediaType
),
251 pContainer(r
.pContainer
),
253 nViewAspect(r
.nViewAspect
),
254 bIsLocked(r
.bIsLocked
),
255 bNeedUpdate(r
.bNeedUpdate
),
257 aDefaultSizeForChart_In_100TH_MM(r
.aDefaultSizeForChart_In_100TH_MM
)
259 if (r
.pGraphic
&& !r
.bNeedUpdate
)
260 pGraphic
= new Graphic(*r
.pGraphic
);
263 ~EmbeddedObjectRef_Impl()
269 const uno::Reference
<embed::XEmbeddedObject
>& EmbeddedObjectRef::operator->() const
271 return mpImpl
->mxObj
;
274 const uno::Reference
<embed::XEmbeddedObject
>& EmbeddedObjectRef::GetObject() const
276 return mpImpl
->mxObj
;
279 EmbeddedObjectRef::EmbeddedObjectRef() : mpImpl(new EmbeddedObjectRef_Impl
) {}
281 EmbeddedObjectRef::EmbeddedObjectRef( const uno::Reference
< embed::XEmbeddedObject
>& xObj
, sal_Int64 nAspect
) :
282 mpImpl(new EmbeddedObjectRef_Impl
)
284 mpImpl
->nViewAspect
= nAspect
;
285 mpImpl
->mxObj
= xObj
;
286 mpImpl
->xListener
= EmbedEventListener_Impl::Create( this );
289 EmbeddedObjectRef::EmbeddedObjectRef( const EmbeddedObjectRef
& rObj
) :
290 mpImpl(new EmbeddedObjectRef_Impl(*rObj
.mpImpl
))
292 mpImpl
->xListener
= EmbedEventListener_Impl::Create( this );
295 EmbeddedObjectRef::~EmbeddedObjectRef()
301 void EmbeddedObjectRef::Assign( const uno::Reference
< embed::XEmbeddedObject
>& xObj
, sal_Int64 nAspect
)
303 DBG_ASSERT(!mpImpl
->mxObj
.is(), "Never assign an already assigned object!");
306 mpImpl
->nViewAspect
= nAspect
;
307 mpImpl
->mxObj
= xObj
;
308 mpImpl
->xListener
= EmbedEventListener_Impl::Create( this );
313 uno::Reference
< chart2::XDefaultSizeTransmitter
> xSizeTransmitter( xObj
, uno::UNO_QUERY
);
314 DBG_ASSERT( xSizeTransmitter
.is(), "Object does not support XDefaultSizeTransmitter -> will cause #i103460#!" );
315 if( xSizeTransmitter
.is() )
316 xSizeTransmitter
->setDefaultSize( mpImpl
->aDefaultSizeForChart_In_100TH_MM
);
320 void EmbeddedObjectRef::Clear()
322 if (mpImpl
->mxObj
.is() && mpImpl
->xListener
)
324 mpImpl
->mxObj
->removeStateChangeListener(mpImpl
->xListener
);
326 uno::Reference
<util::XCloseable
> xClose(mpImpl
->mxObj
, uno::UNO_QUERY
);
328 xClose
->removeCloseListener( mpImpl
->xListener
);
330 uno::Reference
<document::XEventBroadcaster
> xBrd(mpImpl
->mxObj
, uno::UNO_QUERY
);
332 xBrd
->removeEventListener( mpImpl
->xListener
);
334 if ( mpImpl
->bIsLocked
)
340 mpImpl
->mxObj
->changeState(embed::EmbedStates::LOADED
);
341 xClose
->close( true );
343 catch (const util::CloseVetoException
&)
345 // there's still someone who needs the object!
347 catch (const uno::Exception
&)
349 OSL_FAIL( "Error on switching of the object to loaded state and closing!\n" );
354 if ( mpImpl
->xListener
)
356 mpImpl
->xListener
->pObject
= 0;
357 mpImpl
->xListener
->release();
358 mpImpl
->xListener
= 0;
361 mpImpl
->mxObj
= NULL
;
362 mpImpl
->bNeedUpdate
= false;
365 mpImpl
->pContainer
= 0;
366 mpImpl
->bIsLocked
= false;
367 mpImpl
->bNeedUpdate
= false;
370 bool EmbeddedObjectRef::is() const
372 return mpImpl
->mxObj
.is();
375 void EmbeddedObjectRef::AssignToContainer( comphelper::EmbeddedObjectContainer
* pContainer
, const OUString
& rPersistName
)
377 mpImpl
->pContainer
= pContainer
;
378 mpImpl
->aPersistName
= rPersistName
;
380 if ( mpImpl
->pGraphic
&& !mpImpl
->bNeedUpdate
&& pContainer
)
381 SetGraphicToContainer( *mpImpl
->pGraphic
, *pContainer
, mpImpl
->aPersistName
, OUString() );
384 comphelper::EmbeddedObjectContainer
* EmbeddedObjectRef::GetContainer() const
386 return mpImpl
->pContainer
;
389 sal_Int64
EmbeddedObjectRef::GetViewAspect() const
391 return mpImpl
->nViewAspect
;
394 void EmbeddedObjectRef::SetViewAspect( sal_Int64 nAspect
)
396 mpImpl
->nViewAspect
= nAspect
;
399 void EmbeddedObjectRef::Lock( bool bLock
)
401 mpImpl
->bIsLocked
= bLock
;
404 bool EmbeddedObjectRef::IsLocked() const
406 return mpImpl
->bIsLocked
;
409 void EmbeddedObjectRef::GetReplacement( bool bUpdate
)
413 DELETEZ( mpImpl
->pGraphic
);
414 mpImpl
->aMediaType
= OUString();
415 mpImpl
->pGraphic
= new Graphic
;
416 mpImpl
->mnGraphicVersion
++;
418 else if ( !mpImpl
->pGraphic
)
420 mpImpl
->pGraphic
= new Graphic
;
421 mpImpl
->mnGraphicVersion
++;
425 OSL_FAIL("No update, but replacement exists already!");
429 SvStream
* pGraphicStream
= GetGraphicStream( bUpdate
);
430 if ( pGraphicStream
)
432 GraphicFilter
& rGF
= GraphicFilter::GetGraphicFilter();
433 if( mpImpl
->pGraphic
)
434 rGF
.ImportGraphic( *mpImpl
->pGraphic
, OUString(), *pGraphicStream
, GRFILTER_FORMAT_DONTKNOW
);
435 mpImpl
->mnGraphicVersion
++;
436 delete pGraphicStream
;
440 const Graphic
* EmbeddedObjectRef::GetGraphic( OUString
* pMediaType
) const
444 if ( mpImpl
->bNeedUpdate
)
445 // bNeedUpdate will be set to false while retrieving new replacement
446 const_cast < EmbeddedObjectRef
* >(this)->GetReplacement(true);
447 else if ( !mpImpl
->pGraphic
)
448 const_cast < EmbeddedObjectRef
* >(this)->GetReplacement(false);
450 catch( const uno::Exception
& ex
)
452 SAL_WARN("svtools.misc", "Something went wrong on getting the graphic: " << ex
.Message
);
455 if ( mpImpl
->pGraphic
&& pMediaType
)
456 *pMediaType
= mpImpl
->aMediaType
;
457 return mpImpl
->pGraphic
;
460 Size
EmbeddedObjectRef::GetSize( MapMode
* pTargetMapMode
) const
462 MapMode
aSourceMapMode( MAP_100TH_MM
);
465 if ( mpImpl
->nViewAspect
== embed::Aspects::MSOLE_ICON
)
467 const Graphic
* pGraphic
= GetGraphic();
470 aSourceMapMode
= pGraphic
->GetPrefMapMode();
471 aResult
= pGraphic
->GetPrefSize();
474 aResult
= Size( 2500, 2500 );
480 if (mpImpl
->mxObj
.is())
484 aSize
= mpImpl
->mxObj
->getVisualAreaSize(mpImpl
->nViewAspect
);
486 catch(const embed::NoVisualAreaSizeException
&)
489 catch(const uno::Exception
&)
491 OSL_FAIL( "Something went wrong on getting of the size of the object!" );
496 aSourceMapMode
= VCLUnoHelper::UnoEmbed2VCLMapUnit(mpImpl
->mxObj
->getMapUnit(mpImpl
->nViewAspect
));
498 catch(const uno::Exception
&)
500 OSL_FAIL( "Can not get the map mode!" );
504 if ( !aSize
.Height
&& !aSize
.Width
)
510 aResult
= Size( aSize
.Width
, aSize
.Height
);
513 if ( pTargetMapMode
)
514 aResult
= OutputDevice::LogicToLogic( aResult
, aSourceMapMode
, *pTargetMapMode
);
519 void EmbeddedObjectRef::SetGraphicStream( const uno::Reference
< io::XInputStream
>& xInGrStream
,
520 const OUString
& rMediaType
)
522 if ( mpImpl
->pGraphic
)
523 delete mpImpl
->pGraphic
;
524 mpImpl
->pGraphic
= new Graphic();
525 mpImpl
->aMediaType
= rMediaType
;
526 mpImpl
->mnGraphicVersion
++;
528 SvStream
* pGraphicStream
= ::utl::UcbStreamHelper::CreateStream( xInGrStream
);
530 if ( pGraphicStream
)
532 GraphicFilter
& rGF
= GraphicFilter::GetGraphicFilter();
533 rGF
.ImportGraphic( *mpImpl
->pGraphic
, String(), *pGraphicStream
, GRFILTER_FORMAT_DONTKNOW
);
534 mpImpl
->mnGraphicVersion
++;
536 if ( mpImpl
->pContainer
)
538 pGraphicStream
->Seek( 0 );
539 uno::Reference
< io::XInputStream
> xInSeekGrStream
= new ::utl::OSeekableInputStreamWrapper( pGraphicStream
);
541 mpImpl
->pContainer
->InsertGraphicStream( xInSeekGrStream
, mpImpl
->aPersistName
, rMediaType
);
544 delete pGraphicStream
;
547 mpImpl
->bNeedUpdate
= false;
551 void EmbeddedObjectRef::SetGraphic( const Graphic
& rGraphic
, const OUString
& rMediaType
)
553 if ( mpImpl
->pGraphic
)
554 delete mpImpl
->pGraphic
;
555 mpImpl
->pGraphic
= new Graphic( rGraphic
);
556 mpImpl
->aMediaType
= rMediaType
;
557 mpImpl
->mnGraphicVersion
++;
559 if ( mpImpl
->pContainer
)
560 SetGraphicToContainer( rGraphic
, *mpImpl
->pContainer
, mpImpl
->aPersistName
, rMediaType
);
562 mpImpl
->bNeedUpdate
= false;
565 SvStream
* EmbeddedObjectRef::GetGraphicStream( bool bUpdate
) const
567 RTL_LOGFILE_CONTEXT( aLog
, "svtools (mv76033) svt::EmbeddedObjectRef::GetGraphicStream" );
568 DBG_ASSERT( bUpdate
|| mpImpl
->pContainer
, "Can't retrieve current graphic!" );
569 uno::Reference
< io::XInputStream
> xStream
;
570 if ( mpImpl
->pContainer
&& !bUpdate
)
572 RTL_LOGFILE_CONTEXT_TRACE( aLog
, "getting stream from container" );
573 // try to get graphic stream from container storage
574 xStream
= mpImpl
->pContainer
->GetGraphicStream(mpImpl
->mxObj
, &mpImpl
->aMediaType
);
577 const sal_Int32 nConstBufferSize
= 32000;
578 SvStream
*pStream
= new SvMemoryStream( 32000, 32000 );
582 uno::Sequence
< sal_Int8
> aSequence ( nConstBufferSize
);
585 nRead
= xStream
->readBytes ( aSequence
, nConstBufferSize
);
586 pStream
->Write( aSequence
.getConstArray(), nRead
);
588 while ( nRead
== nConstBufferSize
);
592 catch (const uno::Exception
& ex
)
594 SAL_WARN("svtools.misc", "discarding broken embedded object preview: " << ex
.Message
);
603 RTL_LOGFILE_CONTEXT_TRACE( aLog
, "getting stream from object" );
604 // update wanted or no stream in container storage available
605 xStream
= GetGraphicReplacementStream(mpImpl
->nViewAspect
, mpImpl
->mxObj
, &mpImpl
->aMediaType
);
609 if ( mpImpl
->pContainer
)
610 mpImpl
->pContainer
->InsertGraphicStream( xStream
, mpImpl
->aPersistName
, mpImpl
->aMediaType
);
612 SvStream
* pResult
= ::utl::UcbStreamHelper::CreateStream( xStream
);
613 if ( pResult
&& bUpdate
)
614 mpImpl
->bNeedUpdate
= false;
623 void EmbeddedObjectRef::DrawPaintReplacement( const Rectangle
&rRect
, const OUString
&rText
, OutputDevice
*pOut
)
625 MapMode
aMM( MAP_APPFONT
);
626 Size aAppFontSz
= pOut
->LogicToLogic( Size( 0, 8 ), &aMM
, NULL
);
627 Font
aFnt( OUString("Helvetica"), aAppFontSz
);
628 aFnt
.SetTransparent( true );
629 aFnt
.SetColor( Color( COL_LIGHTRED
) );
630 aFnt
.SetWeight( WEIGHT_BOLD
);
631 aFnt
.SetFamily( FAMILY_SWISS
);
634 pOut
->SetBackground();
635 pOut
->SetFont( aFnt
);
638 // Nun den Text so skalieren, dass er in das Rect passt.
639 // Wir fangen mit der Defaultsize an und gehen 1-AppFont runter
640 for( sal_uInt16 i
= 8; i
> 2; i
-- )
642 aPt
.X() = (rRect
.GetWidth() - pOut
->GetTextWidth( rText
)) / 2;
643 aPt
.Y() = (rRect
.GetHeight() - pOut
->GetTextHeight()) / 2;
646 if( aPt
.X() < 0 ) bTiny
= true, aPt
.X() = 0;
647 if( aPt
.Y() < 0 ) bTiny
= true, aPt
.Y() = 0;
650 // heruntergehen bei kleinen Bildern
651 aFnt
.SetSize( Size( 0, aAppFontSz
.Height() * i
/ 8 ) );
652 pOut
->SetFont( aFnt
);
658 Bitmap
aBmp( SvtResId( BMP_PLUGIN
) );
659 long nHeight
= rRect
.GetHeight() - pOut
->GetTextHeight();
660 long nWidth
= rRect
.GetWidth();
661 if( nHeight
> 0 && aBmp
.GetSizePixel().Width() > 0 )
664 Point aP
= rRect
.TopLeft();
665 Size aBmpSize
= aBmp
.GetSizePixel();
667 if( nHeight
* 10 / nWidth
668 > aBmpSize
.Height() * 10 / aBmpSize
.Width() )
670 // nach der Breite ausrichten
671 // Proportion beibehalten
672 long nH
= nWidth
* aBmpSize
.Height() / aBmpSize
.Width();
674 aP
.Y() += (nHeight
- nH
) / 2;
679 // nach der H"ohe ausrichten
680 // Proportion beibehalten
681 long nW
= nHeight
* aBmpSize
.Width() / aBmpSize
.Height();
683 aP
.X() += (nWidth
- nW
) / 2;
687 pOut
->DrawBitmap( aP
, Size( nWidth
, nHeight
), aBmp
);
690 pOut
->IntersectClipRegion( rRect
);
691 aPt
+= rRect
.TopLeft();
692 pOut
->DrawText( aPt
, rText
);
696 void EmbeddedObjectRef::DrawShading( const Rectangle
&rRect
, OutputDevice
*pOut
)
698 GDIMetaFile
* pMtf
= pOut
->GetConnectMetaFile();
699 if( pMtf
&& pMtf
->IsRecord() )
703 pOut
->SetLineColor( Color( COL_BLACK
) );
705 Size aPixSize
= pOut
->LogicToPixel( rRect
.GetSize() );
706 aPixSize
.Width() -= 1;
707 aPixSize
.Height() -= 1;
708 Point aPixViewPos
= pOut
->LogicToPixel( rRect
.TopLeft() );
709 sal_Int32 nMax
= aPixSize
.Width() + aPixSize
.Height();
710 for( sal_Int32 i
= 5; i
< nMax
; i
+= 5 )
712 Point
a1( aPixViewPos
), a2( aPixViewPos
);
713 if( i
> aPixSize
.Width() )
714 a1
+= Point( aPixSize
.Width(), i
- aPixSize
.Width() );
717 if( i
> aPixSize
.Height() )
718 a2
+= Point( i
- aPixSize
.Height(), aPixSize
.Height() );
722 pOut
->DrawLine( pOut
->PixelToLogic( a1
), pOut
->PixelToLogic( a2
) );
729 bool EmbeddedObjectRef::TryRunningState( const uno::Reference
< embed::XEmbeddedObject
>& xEmbObj
)
736 if ( xEmbObj
->getCurrentState() == embed::EmbedStates::LOADED
)
737 xEmbObj
->changeState( embed::EmbedStates::RUNNING
);
739 catch (const uno::Exception
&)
747 void EmbeddedObjectRef::SetGraphicToContainer( const Graphic
& rGraphic
,
748 comphelper::EmbeddedObjectContainer
& aContainer
,
749 const OUString
& aName
,
750 const OUString
& aMediaType
)
752 SvMemoryStream aStream
;
753 aStream
.SetVersion( SOFFICE_FILEFORMAT_CURRENT
);
754 if ( rGraphic
.ExportNative( aStream
) )
758 uno::Reference
< io::XInputStream
> xStream
= new ::utl::OSeekableInputStreamWrapper( aStream
);
759 aContainer
.InsertGraphicStream( xStream
, aName
, aMediaType
);
762 OSL_FAIL( "Export of graphic is failed!\n" );
765 uno::Reference
< io::XInputStream
> EmbeddedObjectRef::GetGraphicReplacementStream(
766 sal_Int64 nViewAspect
,
767 const uno::Reference
< embed::XEmbeddedObject
>& xObj
,
768 OUString
* pMediaType
)
771 return ::comphelper::EmbeddedObjectContainer::GetGraphicReplacementStream(nViewAspect
,xObj
,pMediaType
);
774 void EmbeddedObjectRef::UpdateReplacement()
776 GetReplacement( true );
779 void EmbeddedObjectRef::UpdateReplacementOnDemand()
781 DELETEZ( mpImpl
->pGraphic
);
782 mpImpl
->bNeedUpdate
= true;
783 mpImpl
->mnGraphicVersion
++;
785 if( mpImpl
->pContainer
)
787 //remove graphic from container thus a new up to date one is requested on save
788 mpImpl
->pContainer
->RemoveGraphicStream( mpImpl
->aPersistName
);
792 bool EmbeddedObjectRef::IsChart() const
794 //todo maybe for 3.0:
795 //if the changes work good for chart
796 //we should apply them for all own ole objects
798 //#i83708# #i81857# #i79578# request an ole replacement image only if really necessary
799 //as this call can be very expensive and does block the user interface as long at it takes
801 if (!mpImpl
->mxObj
.is())
804 SvGlobalName
aObjClsId(mpImpl
->mxObj
->getClassID());
806 SvGlobalName(SO3_SCH_CLASSID_30
) == aObjClsId
807 || SvGlobalName(SO3_SCH_CLASSID_40
) == aObjClsId
808 || SvGlobalName(SO3_SCH_CLASSID_50
) == aObjClsId
809 || SvGlobalName(SO3_SCH_CLASSID_60
) == aObjClsId
)
818 sal_uInt32
EmbeddedObjectRef::getGraphicVersion() const
820 return mpImpl
->mnGraphicVersion
;
823 void EmbeddedObjectRef::SetDefaultSizeForChart( const Size
& rSizeIn_100TH_MM
)
825 //#i103460# charts do not necessaryly have an own size within ODF files,
826 //for this case they need to use the size settings from the surrounding frame,
827 //which is made available with this method
829 mpImpl
->aDefaultSizeForChart_In_100TH_MM
= awt::Size( rSizeIn_100TH_MM
.getWidth(), rSizeIn_100TH_MM
.getHeight() );
831 uno::Reference
<chart2::XDefaultSizeTransmitter
> xSizeTransmitter(mpImpl
->mxObj
, uno::UNO_QUERY
);
832 DBG_ASSERT( xSizeTransmitter
.is(), "Object does not support XDefaultSizeTransmitter -> will cause #i103460#!" );
833 if( xSizeTransmitter
.is() )
834 xSizeTransmitter
->setDefaultSize( mpImpl
->aDefaultSizeForChart_In_100TH_MM
);
839 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */