fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / svtools / source / misc / embedhlp.cxx
blob7a3ce2447412930178a8b8b09af5557a35730eb5
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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;
51 namespace svt {
53 class EmbedEventListener_Impl : public ::cppu::WeakImplHelper4 < embed::XStateChangeListener,
54 document::XEventListener,
55 util::XModifyListener,
56 util::XCloseListener >
58 public:
59 EmbeddedObjectRef* pObject;
60 sal_Int32 nState;
62 EmbedEventListener_Impl( EmbeddedObjectRef* p ) :
63 pObject(p)
64 , nState(-1)
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 );
84 xRet->acquire();
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!" );
92 if ( xClose.is() )
93 xClose->addCloseListener( xRet );
95 uno::Reference < document::XEventBroadcaster > xBrd( p->GetObject(), uno::UNO_QUERY );
96 if ( xBrd.is() )
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 );
103 if ( xMod.is() )
104 // listen for changes in running state (update replacements in case of changes)
105 xMod->addModifyListener( xRet );
109 return xRet;
112 void SAL_CALL EmbedEventListener_Impl::changingState( const lang::EventObject&,
113 ::sal_Int32,
114 ::sal_Int32 )
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;
126 nState = nNewState;
127 if ( !pObject )
128 return;
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
154 if ( xMod.is() )
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();
169 else
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() )
206 pObject->Clear();
207 pObject = 0;
211 void SAL_CALL EmbedEventListener_Impl::disposing( const lang::EventObject& aEvent ) throw( uno::RuntimeException )
213 if ( pObject && aEvent.Source == pObject->GetObject() )
215 pObject->Clear();
216 pObject = 0;
220 struct EmbeddedObjectRef_Impl
222 uno::Reference <embed::XEmbeddedObject> mxObj;
224 EmbedEventListener_Impl* xListener;
225 OUString aPersistName;
226 OUString aMediaType;
227 comphelper::EmbeddedObjectContainer* pContainer;
228 Graphic* pGraphic;
229 sal_Int64 nViewAspect;
230 bool bIsLocked:1;
231 bool bNeedUpdate:1;
233 // #i104867#
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() :
238 pContainer(NULL),
239 pGraphic(NULL),
240 nViewAspect(embed::Aspects::MSOLE_CONTENT),
241 bIsLocked(false),
242 bNeedUpdate(false),
243 mnGraphicVersion(0),
244 aDefaultSizeForChart_In_100TH_MM(awt::Size(8000,7000))
247 EmbeddedObjectRef_Impl( const EmbeddedObjectRef_Impl& r ) :
248 mxObj(r.mxObj),
249 aPersistName(r.aPersistName),
250 aMediaType(r.aMediaType),
251 pContainer(r.pContainer),
252 pGraphic(NULL),
253 nViewAspect(r.nViewAspect),
254 bIsLocked(r.bIsLocked),
255 bNeedUpdate(r.bNeedUpdate),
256 mnGraphicVersion(0),
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()
265 delete pGraphic;
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()
297 Clear();
298 delete mpImpl;
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!");
305 Clear();
306 mpImpl->nViewAspect = nAspect;
307 mpImpl->mxObj = xObj;
308 mpImpl->xListener = EmbedEventListener_Impl::Create( this );
310 //#i103460#
311 if ( IsChart() )
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);
327 if ( xClose.is() )
328 xClose->removeCloseListener( mpImpl->xListener );
330 uno::Reference<document::XEventBroadcaster> xBrd(mpImpl->mxObj, uno::UNO_QUERY);
331 if ( xBrd.is() )
332 xBrd->removeEventListener( mpImpl->xListener );
334 if ( mpImpl->bIsLocked )
336 if ( xClose.is() )
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 )
411 if ( 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++;
423 else
425 OSL_FAIL("No update, but replacement exists already!");
426 return;
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 );
463 Size aResult;
465 if ( mpImpl->nViewAspect == embed::Aspects::MSOLE_ICON )
467 const Graphic* pGraphic = GetGraphic();
468 if ( pGraphic )
470 aSourceMapMode = pGraphic->GetPrefMapMode();
471 aResult = pGraphic->GetPrefSize();
473 else
474 aResult = Size( 2500, 2500 );
476 else
478 awt::Size aSize;
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 )
506 aSize.Width = 5000;
507 aSize.Height = 5000;
510 aResult = Size( aSize.Width, aSize.Height );
513 if ( pTargetMapMode )
514 aResult = OutputDevice::LogicToLogic( aResult, aSourceMapMode, *pTargetMapMode );
516 return aResult;
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);
575 if ( xStream.is() )
577 const sal_Int32 nConstBufferSize = 32000;
578 SvStream *pStream = new SvMemoryStream( 32000, 32000 );
581 sal_Int32 nRead=0;
582 uno::Sequence < sal_Int8 > aSequence ( nConstBufferSize );
585 nRead = xStream->readBytes ( aSequence, nConstBufferSize );
586 pStream->Write( aSequence.getConstArray(), nRead );
588 while ( nRead == nConstBufferSize );
589 pStream->Seek(0);
590 return pStream;
592 catch (const uno::Exception& ex)
594 SAL_WARN("svtools.misc", "discarding broken embedded object preview: " << ex.Message);
595 delete pStream;
596 xStream.clear();
601 if ( !xStream.is() )
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);
607 if ( xStream.is() )
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;
616 return pResult;
620 return NULL;
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 );
633 pOut->Push();
634 pOut->SetBackground();
635 pOut->SetFont( aFnt );
637 Point aPt;
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;
645 bool bTiny = false;
646 if( aPt.X() < 0 ) bTiny = true, aPt.X() = 0;
647 if( aPt.Y() < 0 ) bTiny = true, aPt.Y() = 0;
648 if( bTiny )
650 // heruntergehen bei kleinen Bildern
651 aFnt.SetSize( Size( 0, aAppFontSz.Height() * i / 8 ) );
652 pOut->SetFont( aFnt );
654 else
655 break;
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 )
663 aPt.Y() = nHeight;
664 Point aP = rRect.TopLeft();
665 Size aBmpSize = aBmp.GetSizePixel();
666 // Bitmap einpassen
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();
673 // zentrieren
674 aP.Y() += (nHeight - nH) / 2;
675 nHeight = nH;
677 else
679 // nach der H"ohe ausrichten
680 // Proportion beibehalten
681 long nW = nHeight * aBmpSize.Width() / aBmpSize.Height();
682 // zentrieren
683 aP.X() += (nWidth - nW) / 2;
684 nWidth = nW;
687 pOut->DrawBitmap( aP, Size( nWidth, nHeight ), aBmp );
690 pOut->IntersectClipRegion( rRect );
691 aPt += rRect.TopLeft();
692 pOut->DrawText( aPt, rText );
693 pOut->Pop();
696 void EmbeddedObjectRef::DrawShading( const Rectangle &rRect, OutputDevice *pOut )
698 GDIMetaFile * pMtf = pOut->GetConnectMetaFile();
699 if( pMtf && pMtf->IsRecord() )
700 return;
702 pOut->Push();
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() );
715 else
716 a1 += Point( i, 0 );
717 if( i > aPixSize.Height() )
718 a2 += Point( i - aPixSize.Height(), aPixSize.Height() );
719 else
720 a2 += Point( 0, i );
722 pOut->DrawLine( pOut->PixelToLogic( a1 ), pOut->PixelToLogic( a2 ) );
725 pOut->Pop();
729 bool EmbeddedObjectRef::TryRunningState( const uno::Reference < embed::XEmbeddedObject >& xEmbObj )
731 if ( !xEmbObj.is() )
732 return false;
736 if ( xEmbObj->getCurrentState() == embed::EmbedStates::LOADED )
737 xEmbObj->changeState( embed::EmbedStates::RUNNING );
739 catch (const uno::Exception&)
741 return false;
744 return true;
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 ) )
756 aStream.Seek( 0 );
758 uno::Reference < io::XInputStream > xStream = new ::utl::OSeekableInputStreamWrapper( aStream );
759 aContainer.InsertGraphicStream( xStream, aName, aMediaType );
761 else
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 )
769 throw()
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())
802 return false;
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)
811 return true;
814 return false;
817 // #i104867#
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 );
837 } // namespace svt
839 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */