bump product version to 5.0.4.1
[LibreOffice.git] / svx / source / svdraw / svdoole2.cxx
blob403646b6f10e0b505d9d221159ce2fd92616fcf3
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 .
20 #include <svx/svdoole2.hxx>
22 #include <com/sun/star/util/XModifyBroadcaster.hpp>
23 #include <com/sun/star/util/XModifiable.hpp>
24 #include <com/sun/star/chart2/XChartDocument.hpp>
25 #include <com/sun/star/embed/EmbedStates.hpp>
26 #include <com/sun/star/embed/ElementModes.hpp>
27 #include <com/sun/star/embed/EmbedMisc.hpp>
28 #include <com/sun/star/embed/Aspects.hpp>
29 #include <com/sun/star/embed/XEmbedPersist2.hpp>
30 #include <com/sun/star/embed/XInplaceClient.hpp>
31 #include <com/sun/star/embed/XInplaceObject.hpp>
32 #include <com/sun/star/embed/XLinkageSupport.hpp>
33 #include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
34 #include <com/sun/star/embed/XWindowSupplier.hpp>
35 #include <com/sun/star/document/XEventListener.hpp>
36 #include <com/sun/star/container/XChild.hpp>
37 #include <com/sun/star/document/XStorageBasedDocument.hpp>
39 #include <comphelper/processfactory.hxx>
40 #include <cppuhelper/exc_hlp.hxx>
41 #include <unotools/ucbstreamhelper.hxx>
43 #include <toolkit/helper/vclunohelper.hxx>
44 #include <toolkit/awt/vclxwindow.hxx>
45 #include <toolkit/helper/convert.hxx>
47 #include <vcl/graphicfilter.hxx>
48 #include <svtools/embedhlp.hxx>
50 #include <sfx2/objsh.hxx>
51 #include <sfx2/ipclient.hxx>
52 #include <sfx2/lnkbase.hxx>
53 #include <tools/stream.hxx>
54 #include <comphelper/anytostring.hxx>
55 #include <svx/svdpagv.hxx>
56 #include <tools/globname.hxx>
57 #include <vcl/jobset.hxx>
58 #include <comphelper/classids.hxx>
60 #include <sot/formats.hxx>
61 #include <sfx2/linkmgr.hxx>
62 #include <svtools/transfer.hxx>
63 #include <cppuhelper/implbase5.hxx>
65 #include <svl/solar.hrc>
66 #include <svl/urihelper.hxx>
67 #include <osl/mutex.hxx>
68 #include <vcl/svapp.hxx>
70 #include <svx/charthelper.hxx>
71 #include <svx/svdmodel.hxx>
72 #include "svdglob.hxx"
73 #include "svx/svdstr.hrc"
74 #include <svx/svdetc.hxx>
75 #include <svx/svdview.hxx>
76 #include "unomlstr.hxx"
77 #include <sdr/contact/viewcontactofsdrole2obj.hxx>
78 #include <svx/svdograf.hxx>
79 #include <sdr/properties/oleproperties.hxx>
80 #include <svx/xlnclit.hxx>
81 #include <svx/xbtmpit.hxx>
82 #include <svx/xflbmtit.hxx>
83 #include <svx/xflbstit.hxx>
84 #include <basegfx/matrix/b2dhommatrix.hxx>
85 #include <basegfx/polygon/b2dpolypolygon.hxx>
86 #include <editeng/outlobj.hxx>
87 #include <svx/svdpage.hxx>
89 using namespace ::com::sun::star;
91 static uno::Reference < beans::XPropertySet > lcl_getFrame_throw(const SdrOle2Obj* _pObject)
93 uno::Reference < beans::XPropertySet > xFrame;
94 if ( _pObject )
96 uno::Reference< frame::XController> xController = _pObject->GetParentXModel()->getCurrentController();
97 if ( xController.is() )
99 xFrame.set( xController->getFrame(),uno::UNO_QUERY_THROW);
101 } // if ( _pObject )
102 return xFrame;
105 class SdrLightEmbeddedClient_Impl : public ::cppu::WeakImplHelper5
106 < embed::XStateChangeListener
107 , document::XEventListener
108 , embed::XInplaceClient
109 , embed::XEmbeddedClient
110 , embed::XWindowSupplier
113 uno::Reference< awt::XWindow > m_xWindow;
114 SdrOle2Obj* mpObj;
116 Fraction m_aScaleWidth;
117 Fraction m_aScaleHeight;
120 public:
121 SdrLightEmbeddedClient_Impl( SdrOle2Obj* pObj );
122 void Release();
124 void SetSizeScale( const Fraction& aScaleWidth, const Fraction& aScaleHeight )
126 m_aScaleWidth = aScaleWidth;
127 m_aScaleHeight = aScaleHeight;
130 Fraction GetScaleWidth() const { return m_aScaleWidth; }
131 Fraction GetScaleHeight() const { return m_aScaleHeight; }
133 void setWindow(const uno::Reference< awt::XWindow >& _xWindow);
135 private:
136 Rectangle impl_getScaledRect_nothrow() const;
137 // XStateChangeListener
138 virtual void SAL_CALL changingState( const ::com::sun::star::lang::EventObject& aEvent, ::sal_Int32 nOldState, ::sal_Int32 nNewState ) throw (::com::sun::star::embed::WrongStateException, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
139 virtual void SAL_CALL stateChanged( const ::com::sun::star::lang::EventObject& aEvent, ::sal_Int32 nOldState, ::sal_Int32 nNewState ) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
140 virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& aEvent ) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
142 // document::XEventListener
143 virtual void SAL_CALL notifyEvent( const document::EventObject& aEvent ) throw( uno::RuntimeException, std::exception ) SAL_OVERRIDE;
145 // XEmbeddedClient
146 virtual void SAL_CALL saveObject() throw ( embed::ObjectSaveVetoException, uno::Exception, uno::RuntimeException, std::exception ) SAL_OVERRIDE;
147 virtual void SAL_CALL visibilityChanged( sal_Bool bVisible ) throw ( embed::WrongStateException, uno::RuntimeException, std::exception ) SAL_OVERRIDE;
149 // XComponentSupplier
150 virtual uno::Reference< util::XCloseable > SAL_CALL getComponent() throw ( uno::RuntimeException, std::exception ) SAL_OVERRIDE;
152 // XInplaceClient
153 virtual sal_Bool SAL_CALL canInplaceActivate() throw ( uno::RuntimeException, std::exception ) SAL_OVERRIDE;
154 virtual void SAL_CALL activatingInplace() throw ( embed::WrongStateException, uno::RuntimeException, std::exception ) SAL_OVERRIDE;
155 virtual void SAL_CALL activatingUI() throw ( embed::WrongStateException, uno::RuntimeException, std::exception ) SAL_OVERRIDE;
156 virtual void SAL_CALL deactivatedInplace() throw ( embed::WrongStateException, uno::RuntimeException, std::exception ) SAL_OVERRIDE;
157 virtual void SAL_CALL deactivatedUI() throw ( embed::WrongStateException, uno::RuntimeException, std::exception ) SAL_OVERRIDE;
158 virtual uno::Reference< ::com::sun::star::frame::XLayoutManager > SAL_CALL getLayoutManager() throw ( embed::WrongStateException, uno::RuntimeException, std::exception ) SAL_OVERRIDE;
159 virtual uno::Reference< frame::XDispatchProvider > SAL_CALL getInplaceDispatchProvider() throw ( embed::WrongStateException, uno::RuntimeException, std::exception ) SAL_OVERRIDE;
160 virtual awt::Rectangle SAL_CALL getPlacement() throw ( embed::WrongStateException, uno::RuntimeException, std::exception ) SAL_OVERRIDE;
161 virtual awt::Rectangle SAL_CALL getClipRectangle() throw ( embed::WrongStateException, uno::RuntimeException, std::exception ) SAL_OVERRIDE;
162 virtual void SAL_CALL translateAccelerators( const uno::Sequence< awt::KeyEvent >& aKeys ) throw ( embed::WrongStateException, uno::RuntimeException, std::exception ) SAL_OVERRIDE;
163 virtual void SAL_CALL scrollObject( const awt::Size& aOffset ) throw ( embed::WrongStateException, uno::RuntimeException, std::exception ) SAL_OVERRIDE;
164 virtual void SAL_CALL changedPlacement( const awt::Rectangle& aPosRect ) throw ( embed::WrongStateException, uno::Exception, uno::RuntimeException, std::exception ) SAL_OVERRIDE;
166 // XWindowSupplier
167 virtual uno::Reference< awt::XWindow > SAL_CALL getWindow() throw ( uno::RuntimeException, std::exception ) SAL_OVERRIDE;
171 SdrLightEmbeddedClient_Impl::SdrLightEmbeddedClient_Impl( SdrOle2Obj* pObj )
172 : mpObj( pObj )
175 Rectangle SdrLightEmbeddedClient_Impl::impl_getScaledRect_nothrow() const
177 Rectangle aLogicRect( mpObj->GetLogicRect() );
178 // apply scaling to object area and convert to pixels
179 aLogicRect.SetSize( Size( Fraction( aLogicRect.GetWidth() ) * m_aScaleWidth,
180 Fraction( aLogicRect.GetHeight() ) * m_aScaleHeight ) );
181 return aLogicRect;
184 void SAL_CALL SdrLightEmbeddedClient_Impl::changingState( const ::com::sun::star::lang::EventObject& /*aEvent*/, ::sal_Int32 /*nOldState*/, ::sal_Int32 /*nNewState*/ ) throw (::com::sun::star::embed::WrongStateException, ::com::sun::star::uno::RuntimeException, std::exception)
189 void SdrLightEmbeddedClient_Impl::Release()
192 SolarMutexGuard aGuard;
193 mpObj = NULL;
196 release();
200 void SAL_CALL SdrLightEmbeddedClient_Impl::stateChanged( const ::com::sun::star::lang::EventObject& /*aEvent*/, ::sal_Int32 nOldState, ::sal_Int32 nNewState ) throw (::com::sun::star::uno::RuntimeException, std::exception)
202 SolarMutexGuard aGuard;
204 if ( mpObj && nOldState == embed::EmbedStates::LOADED && nNewState == embed::EmbedStates::RUNNING )
206 mpObj->ObjectLoaded();
207 GetSdrGlobalData().GetOLEObjCache().InsertObj(mpObj);
209 else if ( mpObj && nNewState == embed::EmbedStates::LOADED && nOldState == embed::EmbedStates::RUNNING )
211 GetSdrGlobalData().GetOLEObjCache().RemoveObj(mpObj);
216 void SAL_CALL SdrLightEmbeddedClient_Impl::disposing( const ::com::sun::star::lang::EventObject& /*aEvent*/ ) throw (::com::sun::star::uno::RuntimeException, std::exception)
218 SolarMutexGuard aGuard;
220 GetSdrGlobalData().GetOLEObjCache().RemoveObj(mpObj);
224 void SAL_CALL SdrLightEmbeddedClient_Impl::notifyEvent( const document::EventObject& aEvent ) throw( uno::RuntimeException, std::exception )
226 // TODO/LATER: when writer uses this implementation the code could be shared with SfxInPlaceClient_Impl
228 SolarMutexGuard aGuard;
230 // the code currently makes sense only in case there is no other client
231 if ( mpObj && mpObj->GetAspect() != embed::Aspects::MSOLE_ICON && aEvent.EventName == "OnVisAreaChanged"
232 && mpObj->GetObjRef().is() && mpObj->GetObjRef()->getClientSite() == uno::Reference< embed::XEmbeddedClient >( this ) )
236 MapUnit aContainerMapUnit( MAP_100TH_MM );
237 uno::Reference< embed::XVisualObject > xParentVis( mpObj->GetParentXModel(), uno::UNO_QUERY );
238 if ( xParentVis.is() )
239 aContainerMapUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xParentVis->getMapUnit( mpObj->GetAspect() ) );
241 MapUnit aObjMapUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( mpObj->GetObjRef()->getMapUnit( mpObj->GetAspect() ) );
243 Rectangle aVisArea;
244 awt::Size aSz;
247 aSz = mpObj->GetObjRef()->getVisualAreaSize( mpObj->GetAspect() );
249 catch( embed::NoVisualAreaSizeException& )
251 OSL_FAIL( "No visual area size!\n" );
252 aSz.Width = 5000;
253 aSz.Height = 5000;
255 catch( uno::Exception& )
257 OSL_FAIL( "Unexpected exception!\n" );
258 aSz.Width = 5000;
259 aSz.Height = 5000;
262 aVisArea.SetSize( Size( aSz.Width, aSz.Height ) );
263 aVisArea = OutputDevice::LogicToLogic( aVisArea, aObjMapUnit, aContainerMapUnit );
264 Size aScaledSize( static_cast< long >( m_aScaleWidth * Fraction( aVisArea.GetWidth() ) ),
265 static_cast< long >( m_aScaleHeight * Fraction( aVisArea.GetHeight() ) ) );
266 Rectangle aLogicRect( mpObj->GetLogicRect() );
268 // react to the change if the difference is bigger than one pixel
269 Size aPixelDiff =
270 Application::GetDefaultDevice()->LogicToPixel(
271 Size( aLogicRect.GetWidth() - aScaledSize.Width(),
272 aLogicRect.GetHeight() - aScaledSize.Height() ),
273 aContainerMapUnit );
274 if( aPixelDiff.Width() || aPixelDiff.Height() )
276 mpObj->SetLogicRect( Rectangle( aLogicRect.TopLeft(), aScaledSize ) );
277 mpObj->BroadcastObjectChange();
279 else
280 mpObj->ActionChanged();
282 catch( uno::Exception& )
284 OSL_FAIL( "Unexpected exception!\n" );
290 void SAL_CALL SdrLightEmbeddedClient_Impl::saveObject()
291 throw ( embed::ObjectSaveVetoException,
292 uno::Exception,
293 uno::RuntimeException, std::exception )
295 // TODO/LATER: when writer uses this implementation the code could be shared with SfxInPlaceClient_Impl
296 uno::Reference< embed::XCommonEmbedPersist > xPersist;
297 uno::Reference< util::XModifiable > xModifiable;
300 SolarMutexGuard aGuard;
302 if ( !mpObj )
303 throw embed::ObjectSaveVetoException();
305 // the common persistence is supported by objects and links
306 xPersist = uno::Reference< embed::XCommonEmbedPersist >( mpObj->GetObjRef(), uno::UNO_QUERY_THROW );
307 xModifiable = uno::Reference< util::XModifiable >( mpObj->GetParentXModel(), uno::UNO_QUERY );
310 xPersist->storeOwn();
312 if ( xModifiable.is() )
313 xModifiable->setModified( true );
317 void SAL_CALL SdrLightEmbeddedClient_Impl::visibilityChanged( sal_Bool /*bVisible*/ )
318 throw ( embed::WrongStateException,
319 uno::RuntimeException, std::exception )
321 // nothing to do currently
322 // TODO/LATER: when writer uses this implementation the code could be shared with SfxInPlaceClient_Impl
323 if ( mpObj )
325 Rectangle aLogicRect( mpObj->GetLogicRect() );
326 Size aLogicSize( aLogicRect.GetWidth(), aLogicRect.GetHeight() );
328 if( mpObj->IsChart() )
330 //charts never should be stretched see #i84323# for example
331 mpObj->SetLogicRect( Rectangle( aLogicRect.TopLeft(), aLogicSize ) );
332 mpObj->BroadcastObjectChange();
333 } // if( mpObj->IsChart() )
338 uno::Reference< util::XCloseable > SAL_CALL SdrLightEmbeddedClient_Impl::getComponent()
339 throw ( uno::RuntimeException, std::exception )
341 uno::Reference< util::XCloseable > xResult;
343 SolarMutexGuard aGuard;
344 if ( mpObj )
345 xResult = uno::Reference< util::XCloseable >( mpObj->GetParentXModel(), uno::UNO_QUERY );
347 return xResult;
349 // XInplaceClient
351 sal_Bool SAL_CALL SdrLightEmbeddedClient_Impl::canInplaceActivate()
352 throw ( uno::RuntimeException, std::exception )
354 bool bRet = false;
355 SolarMutexGuard aGuard;
356 if ( mpObj )
358 uno::Reference< embed::XEmbeddedObject > xObject = mpObj->GetObjRef();
359 if ( !xObject.is() )
360 throw uno::RuntimeException();
361 // we don't want to switch directly from outplace to inplace mode
362 bRet = !( xObject->getCurrentState() == embed::EmbedStates::ACTIVE || mpObj->GetAspect() == embed::Aspects::MSOLE_ICON );
363 } // if ( mpObj )
364 return bRet;
368 void SAL_CALL SdrLightEmbeddedClient_Impl::activatingInplace()
369 throw ( embed::WrongStateException,
370 uno::RuntimeException, std::exception )
375 void SAL_CALL SdrLightEmbeddedClient_Impl::activatingUI()
376 throw ( embed::WrongStateException,
377 uno::RuntimeException, std::exception )
379 SolarMutexGuard aGuard;
381 uno::Reference < beans::XPropertySet > xFrame( lcl_getFrame_throw(mpObj));
382 uno::Reference < frame::XFrame > xOwnFrame( xFrame,uno::UNO_QUERY);
383 uno::Reference < frame::XFramesSupplier > xParentFrame( xOwnFrame->getCreator(), uno::UNO_QUERY );
384 if ( xParentFrame.is() )
385 xParentFrame->setActiveFrame( xOwnFrame );
387 OLEObjCache& rObjCache = GetSdrGlobalData().GetOLEObjCache();
388 const sal_uIntPtr nCount = rObjCache.size();
389 for(sal_Int32 i = nCount-1 ; i >= 0;--i)
391 SdrOle2Obj* pObj = rObjCache[i];
392 if ( pObj != mpObj )
394 // only deactivate ole objects which belongs to the same frame
395 if ( xFrame == lcl_getFrame_throw(pObj) )
397 uno::Reference< embed::XEmbeddedObject > xObject = pObj->GetObjRef();
400 if ( (xObject->getStatus( pObj->GetAspect() ) & embed::EmbedMisc::MS_EMBED_ACTIVATEWHENVISIBLE) ||
401 svt::EmbeddedObjectRef::IsGLChart(xObject) )
402 xObject->changeState( embed::EmbedStates::INPLACE_ACTIVE );
403 else
405 // the links should not stay in running state for long time because of locking
406 uno::Reference< embed::XLinkageSupport > xLink( xObject, uno::UNO_QUERY );
407 if ( xLink.is() && xLink->isLink() )
408 xObject->changeState( embed::EmbedStates::LOADED );
409 else
410 xObject->changeState( embed::EmbedStates::RUNNING );
413 catch (com::sun::star::uno::Exception& )
417 } // for(sal_Int32 i = nCount-1 ; i >= 0;--i)
421 void SAL_CALL SdrLightEmbeddedClient_Impl::deactivatedInplace()
422 throw ( embed::WrongStateException,
423 uno::RuntimeException, std::exception )
428 void SAL_CALL SdrLightEmbeddedClient_Impl::deactivatedUI()
429 throw ( embed::WrongStateException,
430 uno::RuntimeException, std::exception )
432 SolarMutexGuard aGuard;
433 com::sun::star::uno::Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager(getLayoutManager());
434 if ( xLayoutManager.is() )
436 static const char aMenuBarURL[] = "private:resource/menubar/menubar";
437 if ( !xLayoutManager->isElementVisible( aMenuBarURL ) )
438 xLayoutManager->createElement( aMenuBarURL );
443 uno::Reference< ::com::sun::star::frame::XLayoutManager > SAL_CALL SdrLightEmbeddedClient_Impl::getLayoutManager()
444 throw ( embed::WrongStateException,
445 uno::RuntimeException, std::exception )
447 uno::Reference< ::com::sun::star::frame::XLayoutManager > xMan;
448 SolarMutexGuard aGuard;
449 uno::Reference < beans::XPropertySet > xFrame( lcl_getFrame_throw(mpObj));
452 xMan.set(xFrame->getPropertyValue("LayoutManager"),uno::UNO_QUERY);
454 catch ( uno::Exception& )
456 throw uno::RuntimeException();
459 return xMan;
463 uno::Reference< frame::XDispatchProvider > SAL_CALL SdrLightEmbeddedClient_Impl::getInplaceDispatchProvider()
464 throw ( embed::WrongStateException,
465 uno::RuntimeException, std::exception )
467 SolarMutexGuard aGuard;
468 return uno::Reference < frame::XDispatchProvider >( lcl_getFrame_throw(mpObj), uno::UNO_QUERY_THROW );
472 awt::Rectangle SAL_CALL SdrLightEmbeddedClient_Impl::getPlacement()
473 throw ( embed::WrongStateException,
474 uno::RuntimeException, std::exception )
476 SolarMutexGuard aGuard;
477 if ( !mpObj )
478 throw uno::RuntimeException();
480 Rectangle aLogicRect = impl_getScaledRect_nothrow();
481 MapUnit aContainerMapUnit( MAP_100TH_MM );
482 uno::Reference< embed::XVisualObject > xParentVis( mpObj->GetParentXModel(), uno::UNO_QUERY );
483 if ( xParentVis.is() )
484 aContainerMapUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xParentVis->getMapUnit( mpObj->GetAspect() ) );
486 aLogicRect = Application::GetDefaultDevice()->LogicToPixel(aLogicRect,aContainerMapUnit);
487 return AWTRectangle( aLogicRect );
491 awt::Rectangle SAL_CALL SdrLightEmbeddedClient_Impl::getClipRectangle()
492 throw ( embed::WrongStateException,
493 uno::RuntimeException, std::exception )
495 return getPlacement();
499 void SAL_CALL SdrLightEmbeddedClient_Impl::translateAccelerators( const uno::Sequence< awt::KeyEvent >& /*aKeys*/ )
500 throw ( embed::WrongStateException,
501 uno::RuntimeException, std::exception )
506 void SAL_CALL SdrLightEmbeddedClient_Impl::scrollObject( const awt::Size& /*aOffset*/ )
507 throw ( embed::WrongStateException,
508 uno::RuntimeException, std::exception )
513 void SAL_CALL SdrLightEmbeddedClient_Impl::changedPlacement( const awt::Rectangle& aPosRect )
514 throw ( embed::WrongStateException,
515 uno::Exception,
516 uno::RuntimeException, std::exception )
518 SolarMutexGuard aGuard;
519 if ( !mpObj )
520 throw uno::RuntimeException();
522 uno::Reference< embed::XInplaceObject > xInplace( mpObj->GetObjRef(), uno::UNO_QUERY );
523 if ( !xInplace.is() )
524 throw uno::RuntimeException();
526 // check if the change is at least one pixel in size
527 awt::Rectangle aOldRect = getPlacement();
528 Rectangle aNewPixelRect = VCLRectangle( aPosRect );
529 Rectangle aOldPixelRect = VCLRectangle( aOldRect );
530 if ( aOldPixelRect == aNewPixelRect )
531 // nothing has changed
532 return;
534 // new scaled object area
535 MapUnit aContainerMapUnit( MAP_100TH_MM );
536 uno::Reference< embed::XVisualObject > xParentVis( mpObj->GetParentXModel(), uno::UNO_QUERY );
537 if ( xParentVis.is() )
538 aContainerMapUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xParentVis->getMapUnit( mpObj->GetAspect() ) );
540 Rectangle aNewLogicRect = Application::GetDefaultDevice()->PixelToLogic(aNewPixelRect,aContainerMapUnit);
541 Rectangle aLogicRect = impl_getScaledRect_nothrow();
543 if ( aNewLogicRect != aLogicRect )
545 // the calculation of the object area has not changed the object size
546 // it should be done here then
547 //SfxBooleanFlagGuard aGuard( m_bResizeNoScale, true );
549 // new size of the object area without scaling
550 Size aNewObjSize( Fraction( aNewLogicRect.GetWidth() ) / m_aScaleWidth,
551 Fraction( aNewLogicRect.GetHeight() ) / m_aScaleHeight );
553 // now remove scaling from new placement and keep this a the new object area
554 aNewLogicRect.SetSize( aNewObjSize );
555 // react to the change if the difference is bigger than one pixel
556 Size aPixelDiff =
557 Application::GetDefaultDevice()->LogicToPixel(
558 Size( aLogicRect.GetWidth() - aNewObjSize.Width(),
559 aLogicRect.GetHeight() - aNewObjSize.Height() ),
560 aContainerMapUnit );
561 if( aPixelDiff.Width() || aPixelDiff.Height() )
563 mpObj->SetLogicRect( Rectangle( aLogicRect.TopLeft(), aNewObjSize ) );
564 mpObj->BroadcastObjectChange();
566 else
567 mpObj->ActionChanged();
570 // XWindowSupplier
572 uno::Reference< awt::XWindow > SAL_CALL SdrLightEmbeddedClient_Impl::getWindow()
573 throw ( uno::RuntimeException, std::exception )
575 SolarMutexGuard aGuard;
576 uno::Reference< awt::XWindow > xCurrent = m_xWindow;
577 if ( !xCurrent.is() )
579 if ( !mpObj )
580 throw uno::RuntimeException();
581 uno::Reference< frame::XFrame> xFrame(lcl_getFrame_throw(mpObj),uno::UNO_QUERY_THROW);
582 xCurrent = xFrame->getComponentWindow();
583 } // if ( !xCurrent.is() )
584 return xCurrent;
586 void SdrLightEmbeddedClient_Impl::setWindow(const uno::Reference< awt::XWindow >& _xWindow)
588 m_xWindow = _xWindow;
593 class SdrEmbedObjectLink : public sfx2::SvBaseLink
595 SdrOle2Obj* pObj;
597 public:
598 SdrEmbedObjectLink(SdrOle2Obj* pObj);
599 virtual ~SdrEmbedObjectLink();
601 virtual void Closed() SAL_OVERRIDE;
602 virtual ::sfx2::SvBaseLink::UpdateResult DataChanged(
603 const OUString& rMimeType, const ::com::sun::star::uno::Any & rValue ) SAL_OVERRIDE;
605 bool Connect() { return GetRealObject() != NULL; }
610 SdrEmbedObjectLink::SdrEmbedObjectLink(SdrOle2Obj* pObject):
611 ::sfx2::SvBaseLink( ::SfxLinkUpdateMode::ONCALL, SotClipboardFormatId::SVXB ),
612 pObj(pObject)
614 SetSynchron( false );
619 SdrEmbedObjectLink::~SdrEmbedObjectLink()
625 ::sfx2::SvBaseLink::UpdateResult SdrEmbedObjectLink::DataChanged(
626 const OUString& /*rMimeType*/, const ::com::sun::star::uno::Any & /*rValue*/ )
628 if ( !pObj->UpdateLinkURL_Impl() )
630 // the link URL was not changed
631 uno::Reference< embed::XEmbeddedObject > xObject = pObj->GetObjRef();
632 OSL_ENSURE( xObject.is(), "The object must exist always!\n" );
633 if ( xObject.is() )
635 // let the object reload the link
636 // TODO/LATER: reload call could be used for this case
640 sal_Int32 nState = xObject->getCurrentState();
641 if ( nState != embed::EmbedStates::LOADED )
643 // in some cases the linked file probably is not locked so it could be changed
644 xObject->changeState( embed::EmbedStates::LOADED );
645 xObject->changeState( nState );
648 catch ( uno::Exception& )
654 pObj->GetNewReplacement();
655 pObj->SetChanged();
657 return SUCCESS;
662 void SdrEmbedObjectLink::Closed()
664 pObj->BreakFileLink_Impl();
665 SvBaseLink::Closed();
670 class SdrOle2ObjImpl
672 public:
673 svt::EmbeddedObjectRef mxObjRef;
675 Graphic* mpGraphic;
676 // TODO/LATER: do we really need this pointer?
677 GraphicObject* mpGraphicObject;
678 OUString maProgName;
679 OUString aPersistName; // name of object in persist
680 SdrLightEmbeddedClient_Impl* pLightClient; // must be registered as client only using AddOwnLightClient() call
682 bool mbFrame:1; // Due to compatibility at SdrTextObj for now
683 bool mbInDestruction:1;
684 bool mbSuppressSetVisAreaSize:1; // #i118524#
685 mutable bool mbTypeAsked:1;
686 mutable bool mbIsChart:1;
687 bool mbLoadingOLEObjectFailed:1; // New local var to avoid repeated loading if load of OLE2 fails
688 bool mbConnected:1;
690 SdrEmbedObjectLink* mpObjectLink;
691 OUString maLinkURL;
693 SvxUnoShapeModifyListener* mpModifyListener;
695 SdrOle2ObjImpl( bool bFrame ) :
696 mpGraphic(NULL),
697 mpGraphicObject(NULL),
698 pLightClient (NULL),
699 mbFrame(bFrame),
700 mbInDestruction(false),
701 mbSuppressSetVisAreaSize(false),
702 mbTypeAsked(false),
703 mbIsChart(false),
704 mbLoadingOLEObjectFailed(false),
705 mbConnected(false),
706 mpObjectLink(NULL),
707 mpModifyListener(NULL)
709 mxObjRef.Lock(true);
712 SdrOle2ObjImpl( bool bFrame, const svt::EmbeddedObjectRef& rObjRef ) :
713 mxObjRef(rObjRef),
714 mpGraphic(NULL),
715 mpGraphicObject(NULL),
716 pLightClient (NULL),
717 mbFrame(bFrame),
718 mbInDestruction(false),
719 mbSuppressSetVisAreaSize(false),
720 mbTypeAsked(false),
721 mbIsChart(false),
722 mbLoadingOLEObjectFailed(false),
723 mbConnected(false),
724 mpObjectLink(NULL),
725 mpModifyListener(NULL)
727 mxObjRef.Lock(true);
730 ~SdrOle2ObjImpl()
732 delete mpGraphic;
733 delete mpGraphicObject;
735 if (mpModifyListener)
737 mpModifyListener->invalidate();
738 mpModifyListener->release();
745 // Predicate determining whether the given OLE is an internal math
746 // object
747 static bool ImplIsMathObj( const uno::Reference < embed::XEmbeddedObject >& rObjRef )
749 if ( !rObjRef.is() )
750 return false;
752 SvGlobalName aClassName( rObjRef->getClassID() );
753 if( aClassName == SvGlobalName(SO3_SM_CLASSID_30) ||
754 aClassName == SvGlobalName(SO3_SM_CLASSID_40) ||
755 aClassName == SvGlobalName(SO3_SM_CLASSID_50) ||
756 aClassName == SvGlobalName(SO3_SM_CLASSID_60) ||
757 aClassName == SvGlobalName(SO3_SM_CLASSID) )
759 return true;
761 else
763 return false;
768 // BaseProperties section
770 sdr::properties::BaseProperties* SdrOle2Obj::CreateObjectSpecificProperties()
772 return new sdr::properties::OleProperties(*this);
776 // DrawContact section
778 sdr::contact::ViewContact* SdrOle2Obj::CreateObjectSpecificViewContact()
780 return new sdr::contact::ViewContactOfSdrOle2Obj(*this);
785 TYPEINIT1(SdrOle2Obj,SdrRectObj);
787 SdrOle2Obj::SdrOle2Obj( bool bFrame_ ) :
788 mpImpl(new SdrOle2ObjImpl(bFrame_))
792 SdrOle2Obj::SdrOle2Obj( const svt::EmbeddedObjectRef& rNewObjRef, const OUString& rNewObjName, const Rectangle& rNewRect, bool bFrame_ ) :
793 SdrRectObj(rNewRect),
794 mpImpl(new SdrOle2ObjImpl(bFrame_, rNewObjRef))
796 mpImpl->aPersistName = rNewObjName;
798 if (mpImpl->mxObjRef.is() && (mpImpl->mxObjRef->getStatus( GetAspect() ) & embed::EmbedMisc::EMBED_NEVERRESIZE ) )
799 SetResizeProtect(true);
801 // For math objects, set closed state to transparent
802 SetClosedObj(!ImplIsMathObj( mpImpl->mxObjRef.GetObject() ));
805 OUString SdrOle2Obj::GetStyleString()
807 OUString strStyle;
808 if (mpImpl->mxObjRef.is() && mpImpl->mxObjRef.IsChart())
810 strStyle = mpImpl->mxObjRef.GetChartType();
812 return strStyle;
817 SdrOle2Obj::~SdrOle2Obj()
819 mpImpl->mbInDestruction = true;
821 if ( mpImpl->mbConnected )
822 Disconnect();
824 DisconnectFileLink_Impl();
826 if ( mpImpl->pLightClient )
828 mpImpl->pLightClient->Release();
829 mpImpl->pLightClient = NULL;
832 delete mpImpl;
836 void SdrOle2Obj::SetAspect( sal_Int64 nAspect )
838 mpImpl->mxObjRef.SetViewAspect( nAspect );
841 const svt::EmbeddedObjectRef& SdrOle2Obj::getEmbeddedObjectRef() const
843 return mpImpl->mxObjRef;
846 sal_Int64 SdrOle2Obj::GetAspect() const
848 return mpImpl->mxObjRef.GetViewAspect();
851 bool SdrOle2Obj::isInplaceActive() const
853 return mpImpl->mxObjRef.is() && embed::EmbedStates::INPLACE_ACTIVE == mpImpl->mxObjRef->getCurrentState();
856 bool SdrOle2Obj::isUiActive() const
858 return mpImpl->mxObjRef.is() && embed::EmbedStates::UI_ACTIVE == mpImpl->mxObjRef->getCurrentState();
861 void SdrOle2Obj::SetGraphic_Impl(const Graphic* pGrf)
863 if (mpImpl->mpGraphic)
865 delete mpImpl->mpGraphic;
866 mpImpl->mpGraphic = NULL;
867 delete mpImpl->mpGraphicObject;
868 mpImpl->mpGraphicObject = NULL;
871 if (pGrf)
873 mpImpl->mpGraphic = new Graphic(*pGrf);
874 mpImpl->mpGraphicObject = new GraphicObject(*mpImpl->mpGraphic);
877 SetChanged();
878 BroadcastObjectChange();
881 void SdrOle2Obj::SetGraphic(const Graphic* pGrf)
883 // only for setting a preview graphic
884 SetGraphic_Impl( pGrf );
887 void SdrOle2Obj::SetProgName( const OUString& rName )
889 mpImpl->maProgName = rName;
892 const OUString& SdrOle2Obj::GetProgName() const
894 return mpImpl->maProgName;
897 bool SdrOle2Obj::IsEmpty() const
899 return !mpImpl->mxObjRef.is();
904 void SdrOle2Obj::Connect()
906 if( IsEmptyPresObj() )
907 return;
909 if( mpImpl->mbConnected )
911 // currently there are situations where it seems to be unavoidable to have multiple connects
912 // changing this would need a larger code rewrite, so for now I remove the assertion
913 // OSL_FAIL("Connect() called on connected object!");
914 return;
917 Connect_Impl();
918 AddListeners_Impl();
923 bool SdrOle2Obj::UpdateLinkURL_Impl()
925 bool bResult = false;
927 if ( mpImpl->mpObjectLink )
929 sfx2::LinkManager* pLinkManager = pModel ? pModel->GetLinkManager() : NULL;
930 if ( pLinkManager )
932 OUString aNewLinkURL;
933 sfx2::LinkManager::GetDisplayNames( mpImpl->mpObjectLink, 0, &aNewLinkURL, 0, 0 );
934 if ( !aNewLinkURL.equalsIgnoreAsciiCase( mpImpl->maLinkURL ) )
936 const_cast<SdrOle2Obj*>(this)->GetObjRef_Impl();
937 uno::Reference<embed::XCommonEmbedPersist> xPersObj( mpImpl->mxObjRef.GetObject(), uno::UNO_QUERY );
938 OSL_ENSURE( xPersObj.is(), "The object must exist!\n" );
939 if ( xPersObj.is() )
943 sal_Int32 nCurState = mpImpl->mxObjRef->getCurrentState();
944 if ( nCurState != embed::EmbedStates::LOADED )
945 mpImpl->mxObjRef->changeState(embed::EmbedStates::LOADED);
947 // TODO/LATER: there should be possible to get current mediadescriptor settings from the object
948 uno::Sequence< beans::PropertyValue > aArgs( 1 );
949 aArgs[0].Name = "URL";
950 aArgs[0].Value <<= OUString( aNewLinkURL );
951 xPersObj->reload( aArgs, uno::Sequence< beans::PropertyValue >() );
953 mpImpl->maLinkURL = aNewLinkURL;
954 bResult = true;
956 if ( nCurState != embed::EmbedStates::LOADED )
957 mpImpl->mxObjRef->changeState(nCurState);
959 catch( ::com::sun::star::uno::Exception& )
961 OSL_FAIL(
962 OString(OString("SdrOle2Obj::UpdateLinkURL_Impl(), "
963 "exception caught: ") +
964 OUStringToOString(
965 comphelper::anyToString( cppu::getCaughtException() ),
966 RTL_TEXTENCODING_UTF8 )).getStr() );
970 if ( !bResult )
972 // TODO/LATER: return the old name to the link manager, is it possible?
978 return bResult;
983 void SdrOle2Obj::BreakFileLink_Impl()
985 uno::Reference<document::XStorageBasedDocument> xDoc;
986 if ( pModel )
987 xDoc.set( pModel->getUnoModel(),uno::UNO_QUERY);
989 if ( xDoc.is() )
991 uno::Reference< embed::XStorage > xStorage = xDoc->getDocumentStorage();
992 if ( xStorage.is() )
996 uno::Reference< embed::XLinkageSupport > xLinkSupport( mpImpl->mxObjRef.GetObject(), uno::UNO_QUERY_THROW );
997 xLinkSupport->breakLink( xStorage, mpImpl->aPersistName );
998 DisconnectFileLink_Impl();
999 mpImpl->maLinkURL.clear();
1001 catch( ::com::sun::star::uno::Exception& )
1003 OSL_FAIL(
1004 OString(OString("SdrOle2Obj::BreakFileLink_Impl(), "
1005 "exception caught: ") +
1006 OUStringToOString(
1007 comphelper::anyToString( cppu::getCaughtException() ),
1008 RTL_TEXTENCODING_UTF8 )).getStr() );
1016 void SdrOle2Obj::DisconnectFileLink_Impl()
1018 sfx2::LinkManager* pLinkManager = pModel ? pModel->GetLinkManager() : NULL;
1019 if ( pLinkManager && mpImpl->mpObjectLink )
1021 pLinkManager->Remove( mpImpl->mpObjectLink );
1022 mpImpl->mpObjectLink = NULL;
1028 void SdrOle2Obj::CheckFileLink_Impl()
1030 if (pModel && mpImpl->mxObjRef.GetObject().is() && !mpImpl->mpObjectLink)
1034 uno::Reference< embed::XLinkageSupport > xLinkSupport( mpImpl->mxObjRef.GetObject(), uno::UNO_QUERY );
1035 if ( xLinkSupport.is() && xLinkSupport->isLink() )
1037 OUString aLinkURL = xLinkSupport->getLinkURL();
1038 if ( !aLinkURL.isEmpty() )
1040 // this is a file link so the model link manager should handle it
1041 sfx2::LinkManager* pLinkManager = pModel->GetLinkManager();
1042 if ( pLinkManager )
1044 mpImpl->mpObjectLink = new SdrEmbedObjectLink( this );
1045 mpImpl->maLinkURL = aLinkURL;
1046 pLinkManager->InsertFileLink( *mpImpl->mpObjectLink, OBJECT_CLIENT_OLE, aLinkURL, NULL, NULL );
1047 mpImpl->mpObjectLink->Connect();
1052 catch( ::com::sun::star::uno::Exception& )
1054 OSL_FAIL(
1055 OString(OString("SdrOle2Obj::CheckFileLink_Impl(), "
1056 "exception caught: ") +
1057 OUStringToOString(
1058 comphelper::anyToString( cppu::getCaughtException() ),
1059 RTL_TEXTENCODING_UTF8 )).getStr() );
1066 void SdrOle2Obj::Reconnect_Impl()
1068 DBG_ASSERT( mpImpl->mbConnected, "Assigned unconnected object?!" );
1069 Connect_Impl();
1072 void SdrOle2Obj::Connect_Impl()
1074 if( pModel && !mpImpl->aPersistName.isEmpty() )
1078 ::comphelper::IEmbeddedHelper* pPers = pModel->GetPersist();
1079 if ( pPers )
1081 comphelper::EmbeddedObjectContainer& rContainer = pPers->getEmbeddedObjectContainer();
1082 if ( !rContainer.HasEmbeddedObject( mpImpl->aPersistName )
1083 || ( mpImpl->mxObjRef.is() && !rContainer.HasEmbeddedObject( mpImpl->mxObjRef.GetObject() ) ) )
1085 // object not known to container document
1086 // No object -> disaster!
1087 DBG_ASSERT( mpImpl->mxObjRef.is(), "No object in connect!");
1088 if ( mpImpl->mxObjRef.is() )
1090 // object came from the outside, now add it to the container
1091 OUString aTmp;
1092 rContainer.InsertEmbeddedObject( mpImpl->mxObjRef.GetObject(), aTmp );
1093 mpImpl->aPersistName = aTmp;
1096 else if ( !mpImpl->mxObjRef.is() )
1098 mpImpl->mxObjRef.Assign( rContainer.GetEmbeddedObject( mpImpl->aPersistName ), mpImpl->mxObjRef.GetViewAspect() );
1099 mpImpl->mbTypeAsked = false;
1102 if ( mpImpl->mxObjRef.GetObject().is() )
1104 mpImpl->mxObjRef.AssignToContainer( &rContainer, mpImpl->aPersistName );
1105 mpImpl->mbConnected = true;
1106 mpImpl->mxObjRef.Lock( true );
1110 if ( mpImpl->mxObjRef.is() )
1112 if ( !mpImpl->pLightClient )
1114 mpImpl->pLightClient = new SdrLightEmbeddedClient_Impl( this );
1115 mpImpl->pLightClient->acquire();
1118 mpImpl->mxObjRef->addStateChangeListener( mpImpl->pLightClient );
1119 mpImpl->mxObjRef->addEventListener( uno::Reference< document::XEventListener >( mpImpl->pLightClient ) );
1121 if ( mpImpl->mxObjRef->getCurrentState() != embed::EmbedStates::LOADED )
1122 GetSdrGlobalData().GetOLEObjCache().InsertObj(this);
1124 CheckFileLink_Impl();
1126 uno::Reference< container::XChild > xChild( mpImpl->mxObjRef.GetObject(), uno::UNO_QUERY );
1127 if( xChild.is() )
1129 uno::Reference< uno::XInterface > xParent( pModel->getUnoModel());
1130 if( xParent.is())
1131 xChild->setParent( pModel->getUnoModel() );
1136 catch( ::com::sun::star::uno::Exception& )
1138 OSL_FAIL(
1139 OString(OString("SdrOle2Obj::Connect_Impl(), "
1140 "exception caught: ") +
1141 OUStringToOString(
1142 comphelper::anyToString( cppu::getCaughtException() ),
1143 RTL_TEXTENCODING_UTF8 )).getStr() );
1147 //TODO/LATER: wait for definition of MiscStatus RESIZEONPRINTERCHANGE
1148 //if ( xObjRef.is() && (*ppObjRef)->GetMiscStatus() & SVOBJ_MISCSTATUS_RESIZEONPRINTERCHANGE )
1150 //TODO/LATER: needs a new handling for OnPrinterChanged
1152 if (pModel && pModel->GetRefDevice() &&
1153 pModel->GetRefDevice()->GetOutDevType() == OUTDEV_PRINTER)
1155 // Kein RefDevice oder RefDevice kein Printer
1156 bool bModified = (*ppObjRef)->IsModified();
1157 Printer* pPrinter = (Printer*) pModel->GetRefDevice();
1158 (*ppObjRef)->OnDocumentPrinterChanged( pPrinter );
1159 (*ppObjRef)->SetModified( bModified );
1164 void SdrOle2Obj::ObjectLoaded()
1166 AddListeners_Impl();
1169 void SdrOle2Obj::AddListeners_Impl()
1171 if( mpImpl->mxObjRef.is() && mpImpl->mxObjRef->getCurrentState() != embed::EmbedStates::LOADED )
1173 // register modify listener
1174 if (!mpImpl->mpModifyListener)
1176 mpImpl->mpModifyListener = new SvxUnoShapeModifyListener(this);
1177 mpImpl->mpModifyListener->acquire();
1180 uno::Reference< util::XModifyBroadcaster > xBC( getXModel(), uno::UNO_QUERY );
1181 if (xBC.is() && mpImpl->mpModifyListener)
1183 uno::Reference<util::XModifyListener> xListener(mpImpl->mpModifyListener);
1184 xBC->addModifyListener( xListener );
1191 void SdrOle2Obj::Disconnect()
1193 if( IsEmptyPresObj() )
1194 return;
1196 if( !mpImpl->mbConnected )
1198 OSL_FAIL("Disconnect() called on disconnected object!");
1199 return;
1202 RemoveListeners_Impl();
1203 Disconnect_Impl();
1206 void SdrOle2Obj::RemoveListeners_Impl()
1208 if ( mpImpl->mxObjRef.is() && !mpImpl->aPersistName.isEmpty() )
1212 sal_Int32 nState = mpImpl->mxObjRef->getCurrentState();
1213 if ( nState != embed::EmbedStates::LOADED )
1215 uno::Reference< util::XModifyBroadcaster > xBC( getXModel(), uno::UNO_QUERY );
1216 if (xBC.is() && mpImpl->mpModifyListener)
1218 uno::Reference<util::XModifyListener> xListener(mpImpl->mpModifyListener);
1219 xBC->removeModifyListener( xListener );
1223 catch( ::com::sun::star::uno::Exception& )
1225 OSL_FAIL(
1226 OString(OString("SdrOle2Obj::RemoveListeners_Impl(), "
1227 "exception caught: ") +
1228 OUStringToOString(
1229 comphelper::anyToString( cppu::getCaughtException() ),
1230 RTL_TEXTENCODING_UTF8 )).getStr() );
1235 void SdrOle2Obj::Disconnect_Impl()
1239 if ( pModel && !mpImpl->aPersistName.isEmpty() )
1241 if( pModel->IsInDestruction() )
1243 // TODO/LATER: here we must assume that the destruction of the model is enough to make clear that we will not
1244 // remove the object from the container, even if the DrawingObject itself is not destroyed (unfortunately this
1245 // There is no real need to do the following removing of the object from the container
1246 // in case the model has correct persistence, but in case of problems such a removing
1247 // would make the behavior of the office more stable
1249 comphelper::EmbeddedObjectContainer* pContainer = mpImpl->mxObjRef.GetContainer();
1250 if ( pContainer )
1252 pContainer->CloseEmbeddedObject( mpImpl->mxObjRef.GetObject() );
1253 mpImpl->mxObjRef.AssignToContainer( NULL, mpImpl->aPersistName );
1256 // happens later than the destruction of the model, so we can't assert that).
1257 //DBG_ASSERT( bInDestruction, "Model is destroyed, but not me?!" );
1258 //TODO/LATER: should be make sure that the ObjectShell also forgets the object, because we will close it soon?
1260 uno::Reference < util::XCloseable > xClose( xObjRef, uno::UNO_QUERY );
1261 if ( xClose.is() )
1265 xClose->close( true );
1267 catch ( util::CloseVetoException& )
1269 // there's still someone who needs the object!
1273 xObjRef = NULL;*/
1275 else if ( mpImpl->mxObjRef.is() )
1277 if ( pModel->getUnoModel().is() )
1279 // remove object, but don't close it (that's up to someone else)
1280 comphelper::EmbeddedObjectContainer* pContainer = mpImpl->mxObjRef.GetContainer();
1281 if ( pContainer )
1283 pContainer->RemoveEmbeddedObject( mpImpl->mxObjRef.GetObject(), false);
1285 // TODO/LATER: mpImpl->aPersistName contains outdated information, to keep it updated
1286 // it should be returned from RemoveEmbeddedObject call. Currently it is no problem,
1287 // since no container is adjusted, actually the empty string could be provided as a name here
1288 mpImpl->mxObjRef.AssignToContainer( NULL, mpImpl->aPersistName );
1291 DisconnectFileLink_Impl();
1296 if ( mpImpl->mxObjRef.is() && mpImpl->pLightClient )
1298 mpImpl->mxObjRef->removeStateChangeListener ( mpImpl->pLightClient );
1299 mpImpl->mxObjRef->removeEventListener( uno::Reference< document::XEventListener >( mpImpl->pLightClient ) );
1300 mpImpl->mxObjRef->setClientSite( NULL );
1302 GetSdrGlobalData().GetOLEObjCache().RemoveObj(this);
1305 catch( ::com::sun::star::uno::Exception& )
1307 OSL_FAIL(
1308 OString(OString("SdrOle2Obj::Disconnect_Impl(), "
1309 "exception caught: ") +
1310 OUStringToOString(
1311 comphelper::anyToString( cppu::getCaughtException() ),
1312 RTL_TEXTENCODING_UTF8 )).getStr() );
1315 mpImpl->mbConnected = false;
1320 SdrObject* SdrOle2Obj::createSdrGrafObjReplacement(bool bAddText, bool /* bUseHCGraphic */) const
1322 const Graphic* pOLEGraphic = GetGraphic();
1324 if(pOLEGraphic)
1326 // #i118485# allow creating a SdrGrafObj representation
1327 SdrGrafObj* pClone = new SdrGrafObj(*pOLEGraphic);
1328 pClone->SetModel(GetModel());
1330 // copy transformation
1331 basegfx::B2DHomMatrix aMatrix;
1332 basegfx::B2DPolyPolygon aPolyPolygon;
1334 TRGetBaseGeometry(aMatrix, aPolyPolygon);
1335 pClone->TRSetBaseGeometry(aMatrix, aPolyPolygon);
1337 // copy all attributes to support graphic styles for OLEs
1338 pClone->SetStyleSheet(GetStyleSheet(), false);
1339 pClone->SetMergedItemSet(GetMergedItemSet());
1341 if(bAddText)
1343 // #i118485# copy text (Caution! Model needed, as guaranteed in aw080)
1344 OutlinerParaObject* pOPO = GetOutlinerParaObject();
1346 if(pOPO && GetModel())
1348 pClone->NbcSetOutlinerParaObject(new OutlinerParaObject(*pOPO));
1352 return pClone;
1354 else
1356 // #i100710# pOLEGraphic may be zero (no visualisation available),
1357 // so we need to use the OLE replacement graphic
1358 SdrRectObj* pClone = new SdrRectObj(GetSnapRect());
1359 pClone->SetModel(GetModel());
1361 // gray outline
1362 pClone->SetMergedItem(XLineStyleItem(com::sun::star::drawing::LineStyle_SOLID));
1363 const svtools::ColorConfig aColorConfig;
1364 const svtools::ColorConfigValue aColor(aColorConfig.GetColorValue(svtools::OBJECTBOUNDARIES));
1365 pClone->SetMergedItem(XLineColorItem(OUString(), aColor.nColor));
1367 // bitmap fill
1368 pClone->SetMergedItem(XFillStyleItem(drawing::FillStyle_BITMAP));
1369 pClone->SetMergedItem(XFillBitmapItem(OUString(), GetEmptyOLEReplacementGraphic()));
1370 pClone->SetMergedItem(XFillBmpTileItem(false));
1371 pClone->SetMergedItem(XFillBmpStretchItem(false));
1373 return pClone;
1377 SdrObject* SdrOle2Obj::DoConvertToPolyObj(bool bBezier, bool bAddText) const
1379 // #i118485# missing converter added
1380 if(GetModel())
1382 SdrObject* pRetval = createSdrGrafObjReplacement(true, false);
1384 if(pRetval)
1386 SdrObject* pRetval2 = pRetval->DoConvertToPolyObj(bBezier, bAddText);
1387 SdrObject::Free(pRetval);
1389 return pRetval2;
1393 return 0;
1398 void SdrOle2Obj::SetModel(SdrModel* pNewModel)
1400 ::comphelper::IEmbeddedHelper* pDestPers = pNewModel ? pNewModel->GetPersist() : 0;
1401 ::comphelper::IEmbeddedHelper* pSrcPers = pModel ? pModel->GetPersist() : 0;
1403 if ( pNewModel == pModel )
1405 // don't know if this is necessary or if it will ever happen, but who knows?!
1406 SdrRectObj::SetModel( pNewModel );
1407 return;
1410 // assignment to model has changed
1411 DBG_ASSERT( pSrcPers || !mpImpl->mbConnected, "Connected object without a model?!" );
1413 DBG_ASSERT( pDestPers, "The destination model must have a persistence! Please submit an issue!" );
1414 DBG_ASSERT( pDestPers != pSrcPers, "The source and the destination models should have different persistences! Problems are possible!" );
1416 // this is a bug if the target model has no persistence
1417 // no error handling is possible so just do nothing in this method
1418 if ( !pDestPers )
1419 return;
1421 RemoveListeners_Impl();
1423 if( pDestPers && pSrcPers && !IsEmptyPresObj() )
1427 // move the object's storage; ObjectRef remains the same, but PersistName may change
1428 OUString aTmp;
1429 comphelper::EmbeddedObjectContainer& rContainer = pSrcPers->getEmbeddedObjectContainer();
1430 uno::Reference < embed::XEmbeddedObject > xObj = rContainer.GetEmbeddedObject( mpImpl->aPersistName );
1431 DBG_ASSERT( !mpImpl->mxObjRef.is() || mpImpl->mxObjRef.GetObject() == xObj, "Wrong object identity!" );
1432 if ( xObj.is() )
1434 pDestPers->getEmbeddedObjectContainer().MoveEmbeddedObject( rContainer, xObj, aTmp );
1435 mpImpl->aPersistName = aTmp;
1436 mpImpl->mxObjRef.AssignToContainer( &pDestPers->getEmbeddedObjectContainer(), aTmp );
1438 DBG_ASSERT( !aTmp.isEmpty(), "Copying embedded object failed!" );
1440 catch( ::com::sun::star::uno::Exception& )
1442 OSL_FAIL(
1443 OString(OString("SdrOle2Obj::SetModel(), "
1444 "exception caught: ") +
1445 OUStringToOString(
1446 comphelper::anyToString( cppu::getCaughtException() ),
1447 RTL_TEXTENCODING_UTF8 )).getStr() );
1451 SdrRectObj::SetModel( pNewModel );
1453 // #i43086#
1454 // #i85304 redo the change for charts for the above bugfix, as #i43086# does not occur anymore
1455 //so maybe the ImpSetVisAreaSize call can be removed here completely
1456 //Nevertheless I leave it in for other objects as I am not sure about the side effects when removing now
1457 if( pModel && !pModel->isLocked() && !IsChart() )
1458 ImpSetVisAreaSize();
1460 if( pDestPers && !IsEmptyPresObj() )
1462 if ( !pSrcPers || IsEmptyPresObj() )
1463 // object wasn't connected, now it should be
1464 Connect_Impl();
1465 else
1466 Reconnect_Impl();
1469 AddListeners_Impl();
1474 void SdrOle2Obj::SetPage(SdrPage* pNewPage)
1476 bool bRemove=pNewPage==NULL && pPage!=NULL;
1477 bool bInsert=pNewPage!=NULL && pPage==NULL;
1479 if (bRemove && mpImpl->mbConnected )
1480 Disconnect();
1482 if(!pModel && !GetStyleSheet() && pNewPage && pNewPage->GetModel())
1484 // #i119287# Set default StyleSheet for SdrGrafObj here, it is different from 'Default'. This
1485 // needs to be done before the style 'Default' is set from the :SetModel() call which is triggered
1486 // from the following :SetPage().
1487 // TTTT: Needs to be moved in branch aw080 due to having a SdrModel from the beginning, is at this
1488 // place for convenience currently (works in both versions, is not in the way)
1489 SfxStyleSheet* pSheet = pNewPage->GetModel()->GetDefaultStyleSheetForSdrGrafObjAndSdrOle2Obj();
1491 if(pSheet)
1493 SetStyleSheet(pSheet, false);
1495 else
1497 SetMergedItem(XFillStyleItem(drawing::FillStyle_NONE));
1498 SetMergedItem(XLineStyleItem(drawing::LineStyle_NONE));
1502 SdrRectObj::SetPage(pNewPage);
1504 if (bInsert && !mpImpl->mbConnected )
1505 Connect();
1510 void SdrOle2Obj::SetObjRef( const com::sun::star::uno::Reference < com::sun::star::embed::XEmbeddedObject >& rNewObjRef )
1512 DBG_ASSERT( !rNewObjRef.is() || !mpImpl->mxObjRef.GetObject().is(), "SetObjRef called on already initialized object!");
1513 if( rNewObjRef == mpImpl->mxObjRef.GetObject() )
1514 return;
1516 // the caller of the method is responsible to control the old object, it will not be closed here
1517 // Otherwise WW8 import crashes because it transfers control to OLENode by this method
1518 if ( mpImpl->mxObjRef.GetObject().is() )
1519 mpImpl->mxObjRef.Lock( false );
1521 // avoid removal of object in Disconnect! It is definitely a HACK to call SetObjRef(0)!
1522 // This call will try to close the objects; so if anybody else wants to keep it, it must be locked by a CloseListener
1523 mpImpl->mxObjRef.Clear();
1525 if ( mpImpl->mbConnected )
1526 Disconnect();
1528 mpImpl->mxObjRef.Assign( rNewObjRef, GetAspect() );
1529 mpImpl->mbTypeAsked = false;
1531 if ( mpImpl->mxObjRef.is() )
1533 DELETEZ(mpImpl->mpGraphic);
1535 if ( (mpImpl->mxObjRef->getStatus( GetAspect() ) & embed::EmbedMisc::EMBED_NEVERRESIZE ) )
1536 SetResizeProtect(true);
1538 // For math objects, set closed state to transparent
1539 SetClosedObj(!ImplIsMathObj( rNewObjRef ));
1541 Connect();
1544 SetChanged();
1545 BroadcastObjectChange();
1550 void SdrOle2Obj::SetClosedObj( bool bIsClosed )
1552 // TODO/LATER: do we still need this hack?
1553 // Allow changes to the closed state of OLE objects
1554 bClosedObj = bIsClosed;
1559 SdrObject* SdrOle2Obj::getFullDragClone() const
1561 // #i118485# use central replacement generator
1562 return createSdrGrafObjReplacement(false, true);
1567 void SdrOle2Obj::SetPersistName( const OUString& rPersistName )
1569 DBG_ASSERT( mpImpl->aPersistName.isEmpty(), "Persist name changed!");
1571 mpImpl->aPersistName = rPersistName;
1572 mpImpl->mbLoadingOLEObjectFailed = false;
1574 Connect();
1575 SetChanged();
1578 void SdrOle2Obj::AbandonObject()
1580 mpImpl->aPersistName.clear();
1581 mpImpl->mbLoadingOLEObjectFailed = false;
1582 SetObjRef(0);
1587 OUString SdrOle2Obj::GetPersistName() const
1589 return mpImpl->aPersistName;
1594 void SdrOle2Obj::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
1596 // #i118485# Allowing much more attributes for OLEs
1597 rInfo.bRotateFreeAllowed = true;
1598 rInfo.bRotate90Allowed = true;
1599 rInfo.bMirrorFreeAllowed = true;
1600 rInfo.bMirror45Allowed = true;
1601 rInfo.bMirror90Allowed = true;
1602 rInfo.bTransparenceAllowed = true;
1603 rInfo.bGradientAllowed = true;
1604 rInfo.bShearAllowed = true;
1605 rInfo.bEdgeRadiusAllowed = false;
1606 rInfo.bNoOrthoDesired = false;
1607 rInfo.bCanConvToPath = true;
1608 rInfo.bCanConvToPoly = true;
1609 rInfo.bCanConvToPathLineToArea = false;
1610 rInfo.bCanConvToPolyLineToArea = false;
1611 rInfo.bCanConvToContour = true;
1616 sal_uInt16 SdrOle2Obj::GetObjIdentifier() const
1618 return mpImpl->mbFrame ? sal_uInt16(OBJ_FRAME) : sal_uInt16(OBJ_OLE2);
1623 OUString SdrOle2Obj::TakeObjNameSingul() const
1625 OUStringBuffer sName(ImpGetResStr(mpImpl->mbFrame ? STR_ObjNameSingulFrame : STR_ObjNameSingulOLE2));
1627 const OUString aName(GetName());
1629 if (!aName.isEmpty())
1631 sName.append(" '");
1632 sName.append(aName);
1633 sName.append('\'');
1636 return sName.makeStringAndClear();
1641 OUString SdrOle2Obj::TakeObjNamePlural() const
1643 return ImpGetResStr(mpImpl->mbFrame ? STR_ObjNamePluralFrame : STR_ObjNamePluralOLE2);
1648 SdrOle2Obj* SdrOle2Obj::Clone() const
1650 return CloneHelper< SdrOle2Obj >();
1653 SdrOle2Obj* SdrOle2Obj::CloneWithShellIDs( const OUString& rSrcShellID, const OUString& rDestShellID ) const
1655 SdrOle2Obj* pObj =
1656 dynamic_cast<SdrOle2Obj*>(
1657 SdrObjFactory::MakeNewObject(GetObjInventor(), GetObjIdentifier(), NULL));
1659 if (pObj)
1660 pObj->assignFrom(*this, rSrcShellID, rDestShellID);
1662 return pObj;
1665 SdrOle2Obj& SdrOle2Obj::assignFrom(
1666 const SdrOle2Obj& rObj, const OUString& rSrcShellID, const OUString& rDestShellID )
1668 //TODO/LATER: who takes over control of my old object?!
1669 if( &rObj != this )
1671 // #116235#
1672 // ImpAssign( rObj );
1673 const SdrOle2Obj& rOle2Obj = static_cast< const SdrOle2Obj& >( rObj );
1675 uno::Reference<util::XCloseable> xClose(mpImpl->mxObjRef.GetObject(), uno::UNO_QUERY);
1677 if( pModel && mpImpl->mbConnected )
1678 Disconnect();
1680 SdrRectObj::operator=( rObj );
1682 // Manually copying bClosedObj attribute
1683 SetClosedObj( rObj.IsClosedObj() );
1685 mpImpl->aPersistName = rOle2Obj.mpImpl->aPersistName;
1686 mpImpl->maProgName = rOle2Obj.mpImpl->maProgName;
1687 mpImpl->mbFrame = rOle2Obj.mpImpl->mbFrame;
1689 if (rOle2Obj.mpImpl->mpGraphic)
1691 if (mpImpl->mpGraphic)
1693 delete mpImpl->mpGraphic;
1694 delete mpImpl->mpGraphicObject;
1697 mpImpl->mpGraphic = new Graphic(*rOle2Obj.mpImpl->mpGraphic);
1698 mpImpl->mpGraphicObject = new GraphicObject(*mpImpl->mpGraphic);
1701 if( pModel && rObj.GetModel() && !IsEmptyPresObj() )
1703 ::comphelper::IEmbeddedHelper* pDestPers = pModel->GetPersist();
1704 ::comphelper::IEmbeddedHelper* pSrcPers = rObj.GetModel()->GetPersist();
1705 if( pDestPers && pSrcPers )
1707 DBG_ASSERT( !mpImpl->mxObjRef.is(), "Object already existing!" );
1708 comphelper::EmbeddedObjectContainer& rContainer = pSrcPers->getEmbeddedObjectContainer();
1709 uno::Reference < embed::XEmbeddedObject > xObj = rContainer.GetEmbeddedObject( mpImpl->aPersistName );
1710 if ( xObj.is() )
1712 OUString aTmp;
1713 mpImpl->mxObjRef.Assign( pDestPers->getEmbeddedObjectContainer().CopyAndGetEmbeddedObject(
1714 rContainer, xObj, aTmp, rSrcShellID, rDestShellID), rOle2Obj.GetAspect());
1715 mpImpl->mbTypeAsked = false;
1716 mpImpl->aPersistName = aTmp;
1717 CheckFileLink_Impl();
1720 Connect();
1724 return *this;
1727 SdrOle2Obj& SdrOle2Obj::operator=(const SdrOle2Obj& rObj)
1729 return assignFrom(rObj, OUString(), OUString());
1732 void SdrOle2Obj::ImpSetVisAreaSize()
1734 // #i118524# do not again set VisAreaSize when the call comes from OLE client (e.g. ObjectAreaChanged)
1735 if (mpImpl->mbSuppressSetVisAreaSize)
1736 return;
1738 // currently there is no need to recalculate scaling for iconified objects
1739 // TODO/LATER: it might be needed in future when it is possible to change the icon
1740 if ( GetAspect() == embed::Aspects::MSOLE_ICON )
1741 return;
1743 // the object area of an embedded object was changed, e.g. by user interaction an a selected object
1744 GetObjRef();
1745 if (mpImpl->mxObjRef.is())
1747 OSL_ASSERT( pModel );
1748 sal_Int64 nMiscStatus = mpImpl->mxObjRef->getStatus( GetAspect() );
1750 // the client is required to get access to scaling
1751 SfxInPlaceClient* pClient = SfxInPlaceClient::GetClient( dynamic_cast<SfxObjectShell*>(pModel->GetPersist()), mpImpl->mxObjRef.GetObject() );
1752 bool bHasOwnClient =
1753 ( mpImpl->pLightClient
1754 && mpImpl->mxObjRef->getClientSite() == uno::Reference< embed::XEmbeddedClient >( mpImpl->pLightClient ) );
1756 if ( pClient || bHasOwnClient )
1758 // TODO: IMHO we need to do similar things when object is UIActive or OutplaceActive?!
1759 if ( ((nMiscStatus & embed::EmbedMisc::MS_EMBED_RECOMPOSEONRESIZE) &&
1760 svt::EmbeddedObjectRef::TryRunningState( mpImpl->mxObjRef.GetObject() ))
1761 || mpImpl->mxObjRef->getCurrentState() == embed::EmbedStates::INPLACE_ACTIVE
1764 Fraction aScaleWidth;
1765 Fraction aScaleHeight;
1766 if ( pClient )
1768 aScaleWidth = pClient->GetScaleWidth();
1769 aScaleHeight = pClient->GetScaleHeight();
1771 else
1773 aScaleWidth = mpImpl->pLightClient->GetScaleWidth();
1774 aScaleHeight = mpImpl->pLightClient->GetScaleHeight();
1777 // The object wants to resize itself (f.e. Chart wants to recalculate the layout)
1778 // or object is inplace active and so has a window that must be resized also
1779 // In these cases the change in the object area size will be reflected in a change of the
1780 // objects' visual area. The scaling will not change, but it might exist already and must
1781 // be used in calculations
1782 MapUnit aMapUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( mpImpl->mxObjRef->getMapUnit( GetAspect() ) );
1783 Size aVisSize( (long)( Fraction( maRect.GetWidth() ) / aScaleWidth ),
1784 (long)( Fraction( maRect.GetHeight() ) / aScaleHeight ) );
1786 aVisSize = OutputDevice::LogicToLogic( aVisSize, pModel->GetScaleUnit(), aMapUnit);
1787 awt::Size aSz;
1788 aSz.Width = aVisSize.Width();
1789 aSz.Height = aVisSize.Height();
1790 mpImpl->mxObjRef->setVisualAreaSize( GetAspect(), aSz );
1794 aSz = mpImpl->mxObjRef->getVisualAreaSize( GetAspect() );
1796 catch( embed::NoVisualAreaSizeException& )
1799 Rectangle aAcceptedVisArea;
1800 aAcceptedVisArea.SetSize( Size( (long)( Fraction( long( aSz.Width ) ) * aScaleWidth ),
1801 (long)( Fraction( long( aSz.Height ) ) * aScaleHeight ) ) );
1802 if (aVisSize != aAcceptedVisArea.GetSize())
1804 // server changed VisArea to its liking and the VisArea is different than the suggested one
1805 // store the new value as given by the object
1806 MapUnit aNewMapUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( mpImpl->mxObjRef->getMapUnit( GetAspect() ) );
1807 maRect.SetSize(OutputDevice::LogicToLogic( aAcceptedVisArea.GetSize(), aNewMapUnit, pModel->GetScaleUnit()));
1810 // make the new object area known to the client
1811 // compared to the "else" branch aRect might have been changed by the object and no additional scaling was applied
1812 // WHY this -> OSL_ASSERT( pClient );
1813 if( pClient )
1814 pClient->SetObjArea(maRect);
1816 // we need a new replacement image as the object has resized itself
1818 //#i79578# don't request a new replacement image for charts to often
1819 //a chart sends a modified call to the framework if it was changed
1820 //thus the replacement update is already handled there
1821 if( !IsChart() )
1822 mpImpl->mxObjRef.UpdateReplacement();
1824 else
1826 // The object isn't active and does not want to resize itself so the changed object area size
1827 // will be reflected in a changed object scaling
1828 Fraction aScaleWidth;
1829 Fraction aScaleHeight;
1830 Size aObjAreaSize;
1831 if ( CalculateNewScaling( aScaleWidth, aScaleHeight, aObjAreaSize ) )
1833 if ( pClient )
1835 Rectangle aScaleRect(maRect.TopLeft(), aObjAreaSize);
1836 pClient->SetObjAreaAndScale( aScaleRect, aScaleWidth, aScaleHeight);
1838 else
1840 mpImpl->pLightClient->SetSizeScale( aScaleWidth, aScaleHeight );
1845 else if( (nMiscStatus & embed::EmbedMisc::MS_EMBED_RECOMPOSEONRESIZE) &&
1846 svt::EmbeddedObjectRef::TryRunningState( mpImpl->mxObjRef.GetObject() ) )
1848 //also handle not sfx based ole objects e.g. charts
1849 //#i83860# resizing charts in impress distorts fonts
1850 uno::Reference< embed::XVisualObject > xVisualObject( this->getXModel(), uno::UNO_QUERY );
1851 if( xVisualObject.is() )
1853 MapUnit aMapUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( mpImpl->mxObjRef->getMapUnit( GetAspect() ) );
1854 Point aTL( maRect.TopLeft() );
1855 Point aBR( maRect.BottomRight() );
1856 Point aTL2( OutputDevice::LogicToLogic( aTL, pModel->GetScaleUnit(), aMapUnit) );
1857 Point aBR2( OutputDevice::LogicToLogic( aBR, pModel->GetScaleUnit(), aMapUnit) );
1858 Rectangle aNewRect( aTL2, aBR2 );
1859 xVisualObject->setVisualAreaSize( GetAspect(), awt::Size( aNewRect.GetWidth(), aNewRect.GetHeight() ) );
1867 void SdrOle2Obj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
1869 if( pModel && !pModel->isLocked() )
1871 GetObjRef();
1872 if ( mpImpl->mxObjRef.is() && ( mpImpl->mxObjRef->getStatus( GetAspect() ) & embed::EmbedMisc::MS_EMBED_RECOMPOSEONRESIZE ) )
1874 // if the object needs recompose on resize
1875 // the client site should be created before the resize will take place
1876 // check whether there is no client site and create it if necessary
1877 AddOwnLightClient();
1881 SdrRectObj::NbcResize(rRef,xFact,yFact);
1882 if( pModel && !pModel->isLocked() )
1883 ImpSetVisAreaSize();
1888 void SdrOle2Obj::SetGeoData(const SdrObjGeoData& rGeo)
1890 SdrRectObj::SetGeoData(rGeo);
1892 if( pModel && !pModel->isLocked() )
1893 ImpSetVisAreaSize();
1898 void SdrOle2Obj::NbcSetSnapRect(const Rectangle& rRect)
1900 SdrRectObj::NbcSetSnapRect(rRect);
1902 if( pModel && !pModel->isLocked() )
1903 ImpSetVisAreaSize();
1905 if ( mpImpl->mxObjRef.is() && IsChart() )
1907 //#i103460# charts do not necessarily have an own size within ODF files,
1908 //for this case they need to use the size settings from the surrounding frame,
1909 //which is made available with this method as there is no other way
1910 mpImpl->mxObjRef.SetDefaultSizeForChart( Size( rRect.GetWidth(), rRect.GetHeight() ) );
1916 void SdrOle2Obj::NbcSetLogicRect(const Rectangle& rRect)
1918 SdrRectObj::NbcSetLogicRect(rRect);
1920 if( pModel && !pModel->isLocked() )
1921 ImpSetVisAreaSize();
1924 const Graphic* SdrOle2Obj::GetGraphic() const
1926 if ( mpImpl->mxObjRef.is() )
1927 return mpImpl->mxObjRef.GetGraphic();
1928 return mpImpl->mpGraphic;
1931 void SdrOle2Obj::GetNewReplacement()
1933 if ( mpImpl->mxObjRef.is() )
1934 mpImpl->mxObjRef.UpdateReplacement();
1939 Size SdrOle2Obj::GetOrigObjSize( MapMode* pTargetMapMode ) const
1941 return mpImpl->mxObjRef.GetSize( pTargetMapMode );
1944 void SdrOle2Obj::setSuppressSetVisAreaSize( bool bNew )
1946 mpImpl->mbSuppressSetVisAreaSize = bNew;
1949 void SdrOle2Obj::NbcMove(const Size& rSize)
1951 SdrRectObj::NbcMove(rSize);
1953 if( pModel && !pModel->isLocked() )
1954 ImpSetVisAreaSize();
1959 bool SdrOle2Obj::CanUnloadRunningObj( const uno::Reference< embed::XEmbeddedObject >& xObj, sal_Int64 nAspect )
1961 uno::Reference<embed::XEmbedPersist2> xPersist(xObj, uno::UNO_QUERY);
1962 if (xPersist.is())
1964 if (!xPersist->isStored())
1965 // It doesn't have persistent storage. We can't unload this.
1966 return false;
1969 bool bResult = false;
1971 sal_Int32 nState = xObj->getCurrentState();
1972 if ( nState == embed::EmbedStates::LOADED )
1974 // the object is already unloaded
1975 bResult = true;
1977 else
1979 uno::Reference < util::XModifiable > xModifiable( xObj->getComponent(), uno::UNO_QUERY );
1980 if ( !xModifiable.is() )
1981 bResult = true;
1982 else
1984 sal_Int64 nMiscStatus = xObj->getStatus( nAspect );
1986 if ( embed::EmbedMisc::MS_EMBED_ALWAYSRUN != ( nMiscStatus & embed::EmbedMisc::MS_EMBED_ALWAYSRUN ) &&
1987 embed::EmbedMisc::EMBED_ACTIVATEIMMEDIATELY != ( nMiscStatus & embed::EmbedMisc::EMBED_ACTIVATEIMMEDIATELY ) &&
1988 !( xModifiable.is() && xModifiable->isModified() ) &&
1989 !( nState == embed::EmbedStates::INPLACE_ACTIVE || nState == embed::EmbedStates::UI_ACTIVE || nState == embed::EmbedStates::ACTIVE ) )
1991 bResult = true;
1996 return bResult;
2001 bool SdrOle2Obj::Unload( const uno::Reference< embed::XEmbeddedObject >& xObj, sal_Int64 nAspect )
2003 bool bResult = false;
2005 if ( CanUnloadRunningObj( xObj, nAspect ) )
2009 xObj->changeState( embed::EmbedStates::LOADED );
2010 bResult = true;
2012 catch( ::com::sun::star::uno::Exception& )
2014 OSL_FAIL(
2015 OString(OString("SdrOle2Obj::Unload=(), "
2016 "exception caught: ") +
2017 OUStringToOString(
2018 comphelper::anyToString( cppu::getCaughtException() ),
2019 RTL_TEXTENCODING_UTF8 )).getStr() );
2023 return bResult;
2028 bool SdrOle2Obj::Unload()
2030 if (!mpImpl->mxObjRef.is())
2031 // Already unloaded.
2032 return true;
2034 bool bUnloaded = false;
2035 if ( pModel && mpImpl->mxObjRef.is() )
2037 bUnloaded = Unload( mpImpl->mxObjRef.GetObject(), GetAspect() );
2040 return bUnloaded;
2045 void SdrOle2Obj::GetObjRef_Impl()
2047 if ( !mpImpl->mxObjRef.is() && !mpImpl->aPersistName.isEmpty() && pModel && pModel->GetPersist() )
2049 // Only try loading if it did not went wrong up to now
2050 if(!mpImpl->mbLoadingOLEObjectFailed)
2052 mpImpl->mxObjRef.Assign( pModel->GetPersist()->getEmbeddedObjectContainer().GetEmbeddedObject( mpImpl->aPersistName ), GetAspect() );
2053 mpImpl->mbTypeAsked = false;
2054 CheckFileLink_Impl();
2056 // If loading of OLE object failed, remember that to not invoke a endless
2057 // loop trying to load it again and again.
2058 if( mpImpl->mxObjRef.is() )
2060 mpImpl->mbLoadingOLEObjectFailed = true;
2063 // For math objects, set closed state to transparent
2064 SetClosedObj(!ImplIsMathObj( mpImpl->mxObjRef.GetObject() ));
2067 if ( mpImpl->mxObjRef.is() )
2069 if( !IsEmptyPresObj() )
2071 // remember modified status of model
2072 const bool bWasChanged = pModel && pModel->IsChanged();
2074 // perhaps preview not valid anymore
2075 // This line changes the modified state of the model
2076 SetGraphic_Impl( NULL );
2078 // if status was not set before, force it back
2079 // to not set, so that SetGraphic(0L) above does not
2080 // set the modified state of the model.
2081 if(!bWasChanged && pModel && pModel->IsChanged())
2083 pModel->SetChanged( false );
2087 sal_Int64 nMiscStatus = mpImpl->mxObjRef->getStatus( GetAspect() );
2088 (void)nMiscStatus;
2089 //TODO/LATER: wait until ResizeOnPrinterChange is defined
2090 //if ( nMiscStatus & SVOBJ_MISCSTATUS_RESIZEONPRINTERCHANGE )
2092 if (pModel && pModel->GetRefDevice() &&
2093 pModel->GetRefDevice()->GetOutDevType() == OUTDEV_PRINTER)
2095 if (!mpImpl->mbInDestruction)
2097 //TODO/LATER: printerchange notification
2099 // prevent SetModified (don't want no update here)
2100 bool bWasEnabled = (*ppObjRef)->IsEnableSetModified();
2101 if ( bWasEnabled )
2102 (*ppObjRef)->EnableSetModified( false );
2104 // Kein RefDevice oder RefDevice kein Printer
2105 Printer* pPrinter = (Printer*) pModel->GetRefDevice();
2106 (*ppObjRef)->OnDocumentPrinterChanged( pPrinter );
2108 // reset state
2109 (*ppObjRef)->EnableSetModified( bWasEnabled );*/
2115 if ( mpImpl->mxObjRef.is() )
2116 Connect();
2119 if ( mpImpl->mbConnected )
2120 // move object to first position in cache
2121 GetSdrGlobalData().GetOLEObjCache().InsertObj(this);
2124 uno::Reference < embed::XEmbeddedObject > SdrOle2Obj::GetObjRef() const
2126 const_cast<SdrOle2Obj*>(this)->GetObjRef_Impl();
2127 return mpImpl->mxObjRef.GetObject();
2130 uno::Reference < embed::XEmbeddedObject > SdrOle2Obj::GetObjRef_NoInit() const
2132 return mpImpl->mxObjRef.GetObject();
2137 uno::Reference< frame::XModel > SdrOle2Obj::getXModel() const
2139 GetObjRef();
2140 if ( svt::EmbeddedObjectRef::TryRunningState(mpImpl->mxObjRef.GetObject()) )
2141 return uno::Reference< frame::XModel >( mpImpl->mxObjRef->getComponent(), uno::UNO_QUERY );
2142 else
2143 return uno::Reference< frame::XModel >();
2148 bool SdrOle2Obj::IsChart() const
2150 if (!mpImpl->mbTypeAsked)
2152 mpImpl->mbIsChart = mpImpl->mxObjRef.IsChart();
2153 mpImpl->mbTypeAsked = true;
2155 return mpImpl->mbIsChart;
2158 bool SdrOle2Obj::IsReal3DChart() const
2160 if (!IsChart())
2161 return false;
2163 uno::Reference<chart2::XChartDocument> xChart2Document(getXModel(), uno::UNO_QUERY);
2164 uno::Reference<chart2::XDiagram> xChart2Diagram(xChart2Document->getFirstDiagram(), uno::UNO_QUERY);
2166 if (!xChart2Diagram.is())
2167 return false;
2169 return ChartHelper::isGL3DDiagram(xChart2Diagram);
2172 void SdrOle2Obj::SetGraphicToObj( const Graphic& aGraphic, const OUString& aMediaType )
2174 mpImpl->mxObjRef.SetGraphic( aGraphic, aMediaType );
2178 void SdrOle2Obj::SetGraphicToObj( const uno::Reference< io::XInputStream >& xGrStream, const OUString& aMediaType )
2180 mpImpl->mxObjRef.SetGraphicStream( xGrStream, aMediaType );
2184 bool SdrOle2Obj::IsCalc() const
2186 if ( !mpImpl->mxObjRef.is() )
2187 return false;
2189 SvGlobalName aObjClsId( mpImpl->mxObjRef->getClassID() );
2190 if( SvGlobalName(SO3_SC_CLASSID_30) == aObjClsId
2191 || SvGlobalName(SO3_SC_CLASSID_40) == aObjClsId
2192 || SvGlobalName(SO3_SC_CLASSID_50) == aObjClsId
2193 || SvGlobalName(SO3_SC_CLASSID_60) == aObjClsId
2194 || SvGlobalName(SO3_SC_OLE_EMBED_CLASSID_60) == aObjClsId
2195 || SvGlobalName(SO3_SC_OLE_EMBED_CLASSID_8) == aObjClsId
2196 || SvGlobalName(SO3_SC_CLASSID) == aObjClsId )
2198 return true;
2201 return false;
2204 uno::Reference< frame::XModel > SdrOle2Obj::GetParentXModel() const
2206 uno::Reference< frame::XModel > xDoc;
2207 if ( pModel )
2208 xDoc.set( pModel->getUnoModel(),uno::UNO_QUERY);
2209 return xDoc;
2213 bool SdrOle2Obj::CalculateNewScaling( Fraction& aScaleWidth, Fraction& aScaleHeight, Size& aObjAreaSize )
2215 // TODO/LEAN: to avoid rounding errors scaling always uses the VisArea.
2216 // If we don't cache it for own objects also we must load the object here
2217 if ( !mpImpl->mxObjRef.is() || !pModel )
2218 return false;
2220 MapMode aMapMode( pModel->GetScaleUnit() );
2221 aObjAreaSize = mpImpl->mxObjRef.GetSize( &aMapMode );
2223 Size aSize = maRect.GetSize();
2224 aScaleWidth = Fraction(aSize.Width(), aObjAreaSize.Width() );
2225 aScaleHeight = Fraction(aSize.Height(), aObjAreaSize.Height() );
2227 // reduce to 10 binary digits
2228 Kuerzen(aScaleHeight, 10);
2229 Kuerzen(aScaleWidth, 10);
2231 return true;
2235 bool SdrOle2Obj::AddOwnLightClient()
2237 // The Own Light Client must be registered in object only using this method!
2238 if ( !SfxInPlaceClient::GetClient( dynamic_cast<SfxObjectShell*>(pModel->GetPersist()), mpImpl->mxObjRef.GetObject() )
2239 && !( mpImpl->pLightClient && mpImpl->mxObjRef->getClientSite() == uno::Reference< embed::XEmbeddedClient >( mpImpl->pLightClient ) ) )
2241 Connect();
2243 if ( mpImpl->mxObjRef.is() && mpImpl->pLightClient )
2245 Fraction aScaleWidth;
2246 Fraction aScaleHeight;
2247 Size aObjAreaSize;
2248 if ( CalculateNewScaling( aScaleWidth, aScaleHeight, aObjAreaSize ) )
2250 mpImpl->pLightClient->SetSizeScale( aScaleWidth, aScaleHeight );
2251 try {
2252 mpImpl->mxObjRef->setClientSite( mpImpl->pLightClient );
2253 return true;
2254 } catch( uno::Exception& )
2260 return false;
2263 return true;
2268 Graphic SdrOle2Obj::GetEmptyOLEReplacementGraphic()
2270 return Graphic(BitmapEx(ResId(BMP_SVXOLEOBJ, *ImpGetResMgr())));
2275 void SdrOle2Obj::SetWindow(const com::sun::star::uno::Reference < com::sun::star::awt::XWindow >& _xWindow)
2277 if ( mpImpl->mxObjRef.is() && mpImpl->pLightClient )
2279 mpImpl->pLightClient->setWindow(_xWindow);
2283 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */