1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <svx/svdoole2.hxx>
22 #include <com/sun/star/beans/XPropertySet.hpp>
23 #include <com/sun/star/util/XModifyBroadcaster.hpp>
24 #include <com/sun/star/util/XModifiable.hpp>
25 #include <com/sun/star/embed/EmbedStates.hpp>
26 #include <com/sun/star/embed/EmbedMisc.hpp>
27 #include <com/sun/star/embed/Aspects.hpp>
28 #include <com/sun/star/embed/ObjectSaveVetoException.hpp>
29 #include <com/sun/star/embed/XEmbeddedObject.hpp>
30 #include <com/sun/star/embed/XEmbedPersist2.hpp>
31 #include <com/sun/star/embed/XInplaceClient.hpp>
32 #include <com/sun/star/embed/XInplaceObject.hpp>
33 #include <com/sun/star/embed/XLinkageSupport.hpp>
34 #include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
35 #include <com/sun/star/embed/XWindowSupplier.hpp>
36 #include <com/sun/star/document/XEventListener.hpp>
37 #include <com/sun/star/container/XChild.hpp>
38 #include <com/sun/star/document/XStorageBasedDocument.hpp>
39 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
41 #include <cppuhelper/exc_hlp.hxx>
43 #include <toolkit/helper/vclunohelper.hxx>
44 #include <toolkit/helper/convert.hxx>
46 #include <svtools/colorcfg.hxx>
47 #include <svtools/embedhlp.hxx>
49 #include <sfx2/objsh.hxx>
50 #include <sfx2/ipclient.hxx>
51 #include <sfx2/lnkbase.hxx>
52 #include <tools/debug.hxx>
53 #include <tools/globname.hxx>
54 #include <tools/diagnose_ex.h>
55 #include <comphelper/classids.hxx>
57 #include <sot/formats.hxx>
58 #include <cppuhelper/implbase.hxx>
60 #include <vcl/svapp.hxx>
62 #include <svx/svdmodel.hxx>
63 #include <svx/dialmgr.hxx>
64 #include <svx/strings.hrc>
65 #include <svx/svdetc.hxx>
66 #include <unomlstr.hxx>
67 #include <sdr/contact/viewcontactofsdrole2obj.hxx>
68 #include <svx/svdograf.hxx>
69 #include <sdr/properties/oleproperties.hxx>
70 #include <svx/xlineit0.hxx>
71 #include <svx/xlnclit.hxx>
72 #include <svx/xbtmpit.hxx>
73 #include <svx/xfillit0.hxx>
74 #include <svx/xflbmtit.hxx>
75 #include <svx/xflbstit.hxx>
76 #include <basegfx/matrix/b2dhommatrix.hxx>
77 #include <basegfx/polygon/b2dpolypolygon.hxx>
78 #include <editeng/outlobj.hxx>
79 #include <svx/svdpage.hxx>
80 #include <rtl/ustrbuf.hxx>
81 #include <rtl/ref.hxx>
82 #include <bitmaps.hlst>
84 using namespace ::com::sun::star
;
86 static uno::Reference
< beans::XPropertySet
> lcl_getFrame_throw(const SdrOle2Obj
* _pObject
)
88 uno::Reference
< beans::XPropertySet
> xFrame
;
91 uno::Reference
< frame::XController
> xController
= _pObject
->GetParentXModel()->getCurrentController();
92 if ( xController
.is() )
94 xFrame
.set( xController
->getFrame(),uno::UNO_QUERY_THROW
);
102 class SdrLightEmbeddedClient_Impl
: public ::cppu::WeakImplHelper
103 < embed::XStateChangeListener
104 , document::XEventListener
105 , embed::XInplaceClient
106 , embed::XEmbeddedClient
107 , embed::XWindowSupplier
110 uno::Reference
< awt::XWindow
> m_xWindow
;
113 Fraction m_aScaleWidth
;
114 Fraction m_aScaleHeight
;
118 explicit SdrLightEmbeddedClient_Impl( SdrOle2Obj
* pObj
);
119 virtual ~SdrLightEmbeddedClient_Impl() override
;
121 void SetSizeScale( const Fraction
& aScaleWidth
, const Fraction
& aScaleHeight
)
123 m_aScaleWidth
= aScaleWidth
;
124 m_aScaleHeight
= aScaleHeight
;
127 const Fraction
& GetScaleWidth() const { return m_aScaleWidth
; }
128 const Fraction
& GetScaleHeight() const { return m_aScaleHeight
; }
130 void setWindow(const uno::Reference
< awt::XWindow
>& _xWindow
);
135 tools::Rectangle
impl_getScaledRect_nothrow() const;
136 // XStateChangeListener
137 virtual void SAL_CALL
changingState( const css::lang::EventObject
& aEvent
, ::sal_Int32 nOldState
, ::sal_Int32 nNewState
) override
;
138 virtual void SAL_CALL
stateChanged( const css::lang::EventObject
& aEvent
, ::sal_Int32 nOldState
, ::sal_Int32 nNewState
) override
;
139 virtual void SAL_CALL
disposing( const css::lang::EventObject
& aEvent
) override
;
141 // document::XEventListener
142 virtual void SAL_CALL
notifyEvent( const document::EventObject
& aEvent
) override
;
145 virtual void SAL_CALL
saveObject() override
;
146 virtual void SAL_CALL
visibilityChanged( sal_Bool bVisible
) override
;
148 // XComponentSupplier
149 virtual uno::Reference
< util::XCloseable
> SAL_CALL
getComponent() override
;
152 virtual sal_Bool SAL_CALL
canInplaceActivate() override
;
153 virtual void SAL_CALL
activatingInplace() override
;
154 virtual void SAL_CALL
activatingUI() override
;
155 virtual void SAL_CALL
deactivatedInplace() override
;
156 virtual void SAL_CALL
deactivatedUI() override
;
157 virtual uno::Reference
< css::frame::XLayoutManager
> SAL_CALL
getLayoutManager() override
;
158 virtual uno::Reference
< frame::XDispatchProvider
> SAL_CALL
getInplaceDispatchProvider() override
;
159 virtual awt::Rectangle SAL_CALL
getPlacement() override
;
160 virtual awt::Rectangle SAL_CALL
getClipRectangle() override
;
161 virtual void SAL_CALL
translateAccelerators( const uno::Sequence
< awt::KeyEvent
>& aKeys
) override
;
162 virtual void SAL_CALL
scrollObject( const awt::Size
& aOffset
) override
;
163 virtual void SAL_CALL
changedPlacement( const awt::Rectangle
& aPosRect
) override
;
166 virtual uno::Reference
< awt::XWindow
> SAL_CALL
getWindow() override
;
171 SdrLightEmbeddedClient_Impl::SdrLightEmbeddedClient_Impl( SdrOle2Obj
* pObj
)
175 SdrLightEmbeddedClient_Impl::~SdrLightEmbeddedClient_Impl()
179 tools::Rectangle
SdrLightEmbeddedClient_Impl::impl_getScaledRect_nothrow() const
181 tools::Rectangle
aLogicRect( mpObj
->GetLogicRect() );
182 // apply scaling to object area and convert to pixels
183 aLogicRect
.SetSize( Size( tools::Long( aLogicRect
.GetWidth() * m_aScaleWidth
),
184 tools::Long( aLogicRect
.GetHeight() * m_aScaleHeight
) ) );
188 void SAL_CALL
SdrLightEmbeddedClient_Impl::changingState( const css::lang::EventObject
& /*aEvent*/, ::sal_Int32
/*nOldState*/, ::sal_Int32
/*nNewState*/ )
192 void SAL_CALL
SdrLightEmbeddedClient_Impl::stateChanged( const css::lang::EventObject
& /*aEvent*/, ::sal_Int32 nOldState
, ::sal_Int32 nNewState
)
194 SolarMutexGuard aGuard
;
196 if ( mpObj
&& nOldState
== embed::EmbedStates::LOADED
&& nNewState
== embed::EmbedStates::RUNNING
)
198 mpObj
->ObjectLoaded();
199 GetSdrGlobalData().GetOLEObjCache().InsertObj(mpObj
);
201 else if ( mpObj
&& nNewState
== embed::EmbedStates::LOADED
&& nOldState
== embed::EmbedStates::RUNNING
)
203 GetSdrGlobalData().GetOLEObjCache().RemoveObj(mpObj
);
207 void SdrLightEmbeddedClient_Impl::disconnect()
209 SolarMutexGuard aGuard
;
212 GetSdrGlobalData().GetOLEObjCache().RemoveObj(mpObj
);
216 void SAL_CALL
SdrLightEmbeddedClient_Impl::disposing( const css::lang::EventObject
& /*aEvent*/ )
221 void SAL_CALL
SdrLightEmbeddedClient_Impl::notifyEvent( const document::EventObject
& aEvent
)
223 // TODO/LATER: when writer uses this implementation the code could be shared with SfxInPlaceClient_Impl
225 SolarMutexGuard aGuard
;
227 // the code currently makes sense only in case there is no other client
228 if ( !(mpObj
&& mpObj
->GetAspect() != embed::Aspects::MSOLE_ICON
&& aEvent
.EventName
== "OnVisAreaChanged"
229 && mpObj
->GetObjRef().is() && mpObj
->GetObjRef()->getClientSite() == uno::Reference
< embed::XEmbeddedClient
>( this )) )
234 MapUnit
aContainerMapUnit( MapUnit::Map100thMM
);
235 uno::Reference
< embed::XVisualObject
> xParentVis( mpObj
->GetParentXModel(), uno::UNO_QUERY
);
236 if ( xParentVis
.is() )
237 aContainerMapUnit
= VCLUnoHelper::UnoEmbed2VCLMapUnit( xParentVis
->getMapUnit( mpObj
->GetAspect() ) );
239 MapUnit aObjMapUnit
= VCLUnoHelper::UnoEmbed2VCLMapUnit( mpObj
->GetObjRef()->getMapUnit( mpObj
->GetAspect() ) );
241 tools::Rectangle aVisArea
;
245 aSz
= mpObj
->GetObjRef()->getVisualAreaSize( mpObj
->GetAspect() );
247 catch( embed::NoVisualAreaSizeException
& )
249 TOOLS_WARN_EXCEPTION("svx.svdraw", "No visual area size!");
253 catch( uno::Exception
& )
255 TOOLS_WARN_EXCEPTION("svx.svdraw", "");
260 aVisArea
.SetSize( Size( aSz
.Width
, aSz
.Height
) );
261 aVisArea
= OutputDevice::LogicToLogic(aVisArea
, MapMode(aObjMapUnit
), MapMode(aContainerMapUnit
));
262 Size
aScaledSize( static_cast< tools::Long
>( m_aScaleWidth
* Fraction( aVisArea
.GetWidth() ) ),
263 static_cast< tools::Long
>( m_aScaleHeight
* Fraction( aVisArea
.GetHeight() ) ) );
264 tools::Rectangle
aLogicRect( mpObj
->GetLogicRect() );
266 // react to the change if the difference is bigger than one pixel
268 Application::GetDefaultDevice()->LogicToPixel(
269 Size( aLogicRect
.GetWidth() - aScaledSize
.Width(),
270 aLogicRect
.GetHeight() - aScaledSize
.Height() ),
271 MapMode(aContainerMapUnit
));
272 if( aPixelDiff
.Width() || aPixelDiff
.Height() )
274 mpObj
->SetLogicRect( tools::Rectangle( aLogicRect
.TopLeft(), aScaledSize
) );
275 mpObj
->BroadcastObjectChange();
278 mpObj
->ActionChanged();
280 catch( uno::Exception
& )
282 TOOLS_WARN_EXCEPTION("svx.svdraw", "");
286 void SAL_CALL
SdrLightEmbeddedClient_Impl::saveObject()
288 // TODO/LATER: when writer uses this implementation the code could be shared with SfxInPlaceClient_Impl
289 uno::Reference
< embed::XCommonEmbedPersist
> xPersist
;
290 uno::Reference
< util::XModifiable
> xModifiable
;
293 SolarMutexGuard aGuard
;
296 throw embed::ObjectSaveVetoException();
298 // the common persistence is supported by objects and links
299 xPersist
.set( mpObj
->GetObjRef(), uno::UNO_QUERY_THROW
);
300 xModifiable
.set( mpObj
->GetParentXModel(), uno::UNO_QUERY
);
303 xPersist
->storeOwn();
305 if ( xModifiable
.is() )
306 xModifiable
->setModified( true );
309 void SAL_CALL
SdrLightEmbeddedClient_Impl::visibilityChanged( sal_Bool
/*bVisible*/ )
311 // nothing to do currently
312 // TODO/LATER: when writer uses this implementation the code could be shared with SfxInPlaceClient_Impl
315 tools::Rectangle
aLogicRect( mpObj
->GetLogicRect() );
316 Size
aLogicSize( aLogicRect
.GetWidth(), aLogicRect
.GetHeight() );
318 if( mpObj
->IsChart() )
320 //charts never should be stretched see #i84323# for example
321 mpObj
->SetLogicRect( tools::Rectangle( aLogicRect
.TopLeft(), aLogicSize
) );
322 mpObj
->BroadcastObjectChange();
323 } // if( mpObj->IsChart() )
327 uno::Reference
< util::XCloseable
> SAL_CALL
SdrLightEmbeddedClient_Impl::getComponent()
329 uno::Reference
< util::XCloseable
> xResult
;
331 SolarMutexGuard aGuard
;
333 xResult
.set( mpObj
->GetParentXModel(), uno::UNO_QUERY
);
339 sal_Bool SAL_CALL
SdrLightEmbeddedClient_Impl::canInplaceActivate()
342 SolarMutexGuard aGuard
;
345 uno::Reference
< embed::XEmbeddedObject
> xObject
= mpObj
->GetObjRef();
347 throw uno::RuntimeException();
348 // we don't want to switch directly from outplace to inplace mode
349 bRet
= ( xObject
->getCurrentState() != embed::EmbedStates::ACTIVE
&& mpObj
->GetAspect() != embed::Aspects::MSOLE_ICON
);
354 void SAL_CALL
SdrLightEmbeddedClient_Impl::activatingInplace()
358 void SAL_CALL
SdrLightEmbeddedClient_Impl::activatingUI()
360 SolarMutexGuard aGuard
;
362 uno::Reference
< beans::XPropertySet
> xFrame( lcl_getFrame_throw(mpObj
));
363 uno::Reference
< frame::XFrame
> xOwnFrame( xFrame
,uno::UNO_QUERY
);
364 uno::Reference
< frame::XFramesSupplier
> xParentFrame
= xOwnFrame
->getCreator();
365 if ( xParentFrame
.is() )
366 xParentFrame
->setActiveFrame( xOwnFrame
);
368 OLEObjCache
& rObjCache
= GetSdrGlobalData().GetOLEObjCache();
369 const size_t nCount
= rObjCache
.size();
370 for(sal_Int32 i
= nCount
-1 ; i
>= 0;--i
)
372 SdrOle2Obj
* pObj
= rObjCache
[i
];
375 // only deactivate ole objects which belongs to the same frame
376 if ( xFrame
== lcl_getFrame_throw(pObj
) )
378 const uno::Reference
< embed::XEmbeddedObject
>& xObject
= pObj
->GetObjRef();
381 if ( xObject
->getStatus( pObj
->GetAspect() ) & embed::EmbedMisc::MS_EMBED_ACTIVATEWHENVISIBLE
)
382 xObject
->changeState( embed::EmbedStates::INPLACE_ACTIVE
);
385 // the links should not stay in running state for long time because of locking
386 uno::Reference
< embed::XLinkageSupport
> xLink( xObject
, uno::UNO_QUERY
);
387 if ( xLink
.is() && xLink
->isLink() )
388 xObject
->changeState( embed::EmbedStates::LOADED
);
390 xObject
->changeState( embed::EmbedStates::RUNNING
);
393 catch (css::uno::Exception
& )
397 } // for(sal_Int32 i = nCount-1 ; i >= 0;--i)
400 void SAL_CALL
SdrLightEmbeddedClient_Impl::deactivatedInplace()
404 void SAL_CALL
SdrLightEmbeddedClient_Impl::deactivatedUI()
406 SolarMutexGuard aGuard
;
407 css::uno::Reference
< css::frame::XLayoutManager
> xLayoutManager(getLayoutManager());
408 if ( xLayoutManager
.is() )
410 static const char aMenuBarURL
[] = "private:resource/menubar/menubar";
411 if ( !xLayoutManager
->isElementVisible( aMenuBarURL
) )
412 xLayoutManager
->createElement( aMenuBarURL
);
416 uno::Reference
< css::frame::XLayoutManager
> SAL_CALL
SdrLightEmbeddedClient_Impl::getLayoutManager()
418 uno::Reference
< css::frame::XLayoutManager
> xMan
;
419 SolarMutexGuard aGuard
;
420 uno::Reference
< beans::XPropertySet
> xFrame( lcl_getFrame_throw(mpObj
));
423 xMan
.set(xFrame
->getPropertyValue("LayoutManager"),uno::UNO_QUERY
);
425 catch ( uno::Exception
& ex
)
427 css::uno::Any anyEx
= cppu::getCaughtException();
428 throw css::lang::WrappedTargetRuntimeException( ex
.Message
,
435 uno::Reference
< frame::XDispatchProvider
> SAL_CALL
SdrLightEmbeddedClient_Impl::getInplaceDispatchProvider()
437 SolarMutexGuard aGuard
;
438 return uno::Reference
< frame::XDispatchProvider
>( lcl_getFrame_throw(mpObj
), uno::UNO_QUERY_THROW
);
441 awt::Rectangle SAL_CALL
SdrLightEmbeddedClient_Impl::getPlacement()
443 SolarMutexGuard aGuard
;
445 throw uno::RuntimeException();
447 tools::Rectangle aLogicRect
= impl_getScaledRect_nothrow();
448 MapUnit
aContainerMapUnit( MapUnit::Map100thMM
);
449 uno::Reference
< embed::XVisualObject
> xParentVis( mpObj
->GetParentXModel(), uno::UNO_QUERY
);
450 if ( xParentVis
.is() )
451 aContainerMapUnit
= VCLUnoHelper::UnoEmbed2VCLMapUnit( xParentVis
->getMapUnit( mpObj
->GetAspect() ) );
453 aLogicRect
= Application::GetDefaultDevice()->LogicToPixel(aLogicRect
, MapMode(aContainerMapUnit
));
454 return AWTRectangle( aLogicRect
);
457 awt::Rectangle SAL_CALL
SdrLightEmbeddedClient_Impl::getClipRectangle()
459 return getPlacement();
462 void SAL_CALL
SdrLightEmbeddedClient_Impl::translateAccelerators( const uno::Sequence
< awt::KeyEvent
>& /*aKeys*/ )
466 void SAL_CALL
SdrLightEmbeddedClient_Impl::scrollObject( const awt::Size
& /*aOffset*/ )
470 void SAL_CALL
SdrLightEmbeddedClient_Impl::changedPlacement( const awt::Rectangle
& aPosRect
)
472 SolarMutexGuard aGuard
;
474 throw uno::RuntimeException();
476 uno::Reference
< embed::XInplaceObject
> xInplace( mpObj
->GetObjRef(), uno::UNO_QUERY_THROW
);
478 // check if the change is at least one pixel in size
479 awt::Rectangle aOldRect
= getPlacement();
480 tools::Rectangle aNewPixelRect
= VCLRectangle( aPosRect
);
481 tools::Rectangle aOldPixelRect
= VCLRectangle( aOldRect
);
482 if ( aOldPixelRect
== aNewPixelRect
)
483 // nothing has changed
486 // new scaled object area
487 MapUnit
aContainerMapUnit( MapUnit::Map100thMM
);
488 uno::Reference
< embed::XVisualObject
> xParentVis( mpObj
->GetParentXModel(), uno::UNO_QUERY
);
489 if ( xParentVis
.is() )
490 aContainerMapUnit
= VCLUnoHelper::UnoEmbed2VCLMapUnit( xParentVis
->getMapUnit( mpObj
->GetAspect() ) );
492 tools::Rectangle aNewLogicRect
= Application::GetDefaultDevice()->PixelToLogic(aNewPixelRect
, MapMode(aContainerMapUnit
));
493 tools::Rectangle aLogicRect
= impl_getScaledRect_nothrow();
495 if ( aNewLogicRect
== aLogicRect
)
498 // the calculation of the object area has not changed the object size
499 // it should be done here then
500 //SfxBooleanFlagGuard aGuard( m_bResizeNoScale, true );
502 // new size of the object area without scaling
503 Size
aNewObjSize( tools::Long( aNewLogicRect
.GetWidth() / m_aScaleWidth
),
504 tools::Long( aNewLogicRect
.GetHeight() / m_aScaleHeight
) );
506 // now remove scaling from new placement and keep this at the new object area
507 aNewLogicRect
.SetSize( aNewObjSize
);
508 // react to the change if the difference is bigger than one pixel
510 Application::GetDefaultDevice()->LogicToPixel(
511 Size( aLogicRect
.GetWidth() - aNewObjSize
.Width(),
512 aLogicRect
.GetHeight() - aNewObjSize
.Height() ),
513 MapMode(aContainerMapUnit
));
514 if( aPixelDiff
.Width() || aPixelDiff
.Height() )
516 mpObj
->SetLogicRect( tools::Rectangle( aLogicRect
.TopLeft(), aNewObjSize
) );
517 mpObj
->BroadcastObjectChange();
520 mpObj
->ActionChanged();
524 uno::Reference
< awt::XWindow
> SAL_CALL
SdrLightEmbeddedClient_Impl::getWindow()
526 SolarMutexGuard aGuard
;
527 uno::Reference
< awt::XWindow
> xCurrent
= m_xWindow
;
528 if ( !xCurrent
.is() )
531 throw uno::RuntimeException();
532 uno::Reference
< frame::XFrame
> xFrame(lcl_getFrame_throw(mpObj
),uno::UNO_QUERY_THROW
);
533 xCurrent
= xFrame
->getComponentWindow();
534 } // if ( !xCurrent.is() )
537 void SdrLightEmbeddedClient_Impl::setWindow(const uno::Reference
< awt::XWindow
>& _xWindow
)
539 m_xWindow
= _xWindow
;
542 SdrEmbedObjectLink::SdrEmbedObjectLink(SdrOle2Obj
* pObject
):
543 ::sfx2::SvBaseLink( ::SfxLinkUpdateMode::ONCALL
, SotClipboardFormatId::SVXB
),
546 SetSynchron( false );
549 SdrEmbedObjectLink::~SdrEmbedObjectLink()
553 ::sfx2::SvBaseLink::UpdateResult
SdrEmbedObjectLink::DataChanged(
554 const OUString
& /*rMimeType*/, const css::uno::Any
& /*rValue*/ )
556 if ( !pObj
->UpdateLinkURL_Impl() )
558 // the link URL was not changed
559 uno::Reference
< embed::XEmbeddedObject
> xObject
= pObj
->GetObjRef();
560 OSL_ENSURE( xObject
.is(), "The object must exist always!" );
563 // let the object reload the link
564 // TODO/LATER: reload call could be used for this case
568 sal_Int32 nState
= xObject
->getCurrentState();
569 if ( nState
!= embed::EmbedStates::LOADED
)
571 // in some cases the linked file probably is not locked so it could be changed
572 xObject
->changeState( embed::EmbedStates::LOADED
);
573 xObject
->changeState( nState
);
576 catch ( uno::Exception
& )
582 pObj
->GetNewReplacement();
588 void SdrEmbedObjectLink::Closed()
590 pObj
->BreakFileLink_Impl();
591 SvBaseLink::Closed();
597 svt::EmbeddedObjectRef mxObjRef
;
599 std::unique_ptr
<Graphic
> mxGraphic
;
601 OUString aPersistName
; // name of object in persist
602 rtl::Reference
<SdrLightEmbeddedClient_Impl
> mxLightClient
; // must be registered as client only using AddOwnLightClient() call
604 bool mbFrame
:1; // Due to compatibility at SdrTextObj for now
605 bool mbSuppressSetVisAreaSize
:1; // #i118524#
606 mutable bool mbTypeAsked
:1;
607 mutable bool mbIsChart
:1;
608 bool mbLoadingOLEObjectFailed
:1; // New local var to avoid repeated loading if load of OLE2 fails
611 SdrEmbedObjectLink
* mpObjectLink
;
614 rtl::Reference
<SvxUnoShapeModifyListener
> mxModifyListener
;
616 explicit SdrOle2ObjImpl( bool bFrame
) :
618 mbSuppressSetVisAreaSize(false),
621 mbLoadingOLEObjectFailed(false),
623 mpObjectLink(nullptr)
628 SdrOle2ObjImpl( bool bFrame
, const svt::EmbeddedObjectRef
& rObjRef
) :
631 mbSuppressSetVisAreaSize(false),
634 mbLoadingOLEObjectFailed(false),
636 mpObjectLink(nullptr)
645 if (mxModifyListener
.is())
647 mxModifyListener
->invalidate();
652 // Predicate determining whether the given OLE is an internal math
654 static bool ImplIsMathObj( const uno::Reference
< embed::XEmbeddedObject
>& rObjRef
)
659 SvGlobalName
aClassName( rObjRef
->getClassID() );
660 return aClassName
== SvGlobalName(SO3_SM_CLASSID_30
) ||
661 aClassName
== SvGlobalName(SO3_SM_CLASSID_40
) ||
662 aClassName
== SvGlobalName(SO3_SM_CLASSID_50
) ||
663 aClassName
== SvGlobalName(SO3_SM_CLASSID_60
) ||
664 aClassName
== SvGlobalName(SO3_SM_CLASSID
);
667 // BaseProperties section
669 std::unique_ptr
<sdr::properties::BaseProperties
> SdrOle2Obj::CreateObjectSpecificProperties()
671 return std::make_unique
<sdr::properties::OleProperties
>(*this);
674 // DrawContact section
676 std::unique_ptr
<sdr::contact::ViewContact
> SdrOle2Obj::CreateObjectSpecificViewContact()
678 return std::make_unique
<sdr::contact::ViewContactOfSdrOle2Obj
>(*this);
681 void SdrOle2Obj::Init()
683 // Stuff that was done from old SetModel:
684 // #i43086# #i85304 redo the change for charts for the above bugfix, as #i43086# does not occur anymore
685 // so maybe the ImpSetVisAreaSize call can be removed here completely
686 // Nevertheless I leave it in for other objects as I am not sure about the side effects when removing now
687 if(!getSdrModelFromSdrObject().isLocked() && !IsChart())
692 ::comphelper::IEmbeddedHelper
* pDestPers(getSdrModelFromSdrObject().GetPersist());
693 if(pDestPers
&& !IsEmptyPresObj())
695 // object wasn't connected, now it should be
702 SdrOle2Obj::SdrOle2Obj(
705 : SdrRectObj(rSdrModel
),
706 mpImpl(new SdrOle2ObjImpl(bFrame_
))
711 SdrOle2Obj::SdrOle2Obj(
713 const svt::EmbeddedObjectRef
& rNewObjRef
,
714 const OUString
& rNewObjName
,
715 const tools::Rectangle
& rNewRect
)
716 : SdrRectObj(rSdrModel
, rNewRect
),
717 mpImpl(new SdrOle2ObjImpl(false/*bFrame_*/, rNewObjRef
))
719 mpImpl
->aPersistName
= rNewObjName
;
721 if (mpImpl
->mxObjRef
.is() && (mpImpl
->mxObjRef
->getStatus( GetAspect() ) & embed::EmbedMisc::EMBED_NEVERRESIZE
) )
722 SetResizeProtect(true);
724 // For math objects, set closed state to transparent
725 SetClosedObj(!ImplIsMathObj( mpImpl
->mxObjRef
.GetObject() ));
730 OUString
SdrOle2Obj::GetStyleString()
733 if (mpImpl
->mxObjRef
.is() && mpImpl
->mxObjRef
.IsChart())
735 strStyle
= mpImpl
->mxObjRef
.GetChartType();
740 SdrOle2Obj::~SdrOle2Obj()
742 if ( mpImpl
->mbConnected
)
745 DisconnectFileLink_Impl();
747 if (mpImpl
->mxLightClient
)
749 mpImpl
->mxLightClient
->disconnect();
750 mpImpl
->mxLightClient
.clear();
754 void SdrOle2Obj::SetAspect( sal_Int64 nAspect
)
756 mpImpl
->mxObjRef
.SetViewAspect( nAspect
);
759 const svt::EmbeddedObjectRef
& SdrOle2Obj::getEmbeddedObjectRef() const
761 return mpImpl
->mxObjRef
;
764 sal_Int64
SdrOle2Obj::GetAspect() const
766 return mpImpl
->mxObjRef
.GetViewAspect();
769 bool SdrOle2Obj::isInplaceActive() const
771 return mpImpl
->mxObjRef
.is() && embed::EmbedStates::INPLACE_ACTIVE
== mpImpl
->mxObjRef
->getCurrentState();
774 bool SdrOle2Obj::isUiActive() const
776 return mpImpl
->mxObjRef
.is() && embed::EmbedStates::UI_ACTIVE
== mpImpl
->mxObjRef
->getCurrentState();
779 void SdrOle2Obj::SetGraphic(const Graphic
& rGrf
)
781 // only for setting a preview graphic
782 mpImpl
->mxGraphic
.reset(new Graphic(rGrf
));
785 BroadcastObjectChange();
788 void SdrOle2Obj::ClearGraphic()
790 mpImpl
->mxGraphic
.reset();
793 BroadcastObjectChange();
796 void SdrOle2Obj::SetProgName( const OUString
& rName
)
798 mpImpl
->maProgName
= rName
;
801 const OUString
& SdrOle2Obj::GetProgName() const
803 return mpImpl
->maProgName
;
806 bool SdrOle2Obj::IsEmpty() const
808 return !mpImpl
->mxObjRef
.is();
811 void SdrOle2Obj::Connect()
813 if( IsEmptyPresObj() )
816 if( mpImpl
->mbConnected
)
818 // currently there are situations where it seems to be unavoidable to have multiple connects
819 // changing this would need a larger code rewrite, so for now I remove the assertion
820 // OSL_FAIL("Connect() called on connected object!");
828 bool SdrOle2Obj::UpdateLinkURL_Impl()
830 bool bResult
= false;
832 if ( mpImpl
->mpObjectLink
)
834 sfx2::LinkManager
* pLinkManager(getSdrModelFromSdrObject().GetLinkManager());
838 OUString aNewLinkURL
;
839 sfx2::LinkManager::GetDisplayNames( mpImpl
->mpObjectLink
, nullptr, &aNewLinkURL
);
840 if ( !aNewLinkURL
.equalsIgnoreAsciiCase( mpImpl
->maLinkURL
) )
843 uno::Reference
<embed::XCommonEmbedPersist
> xPersObj( mpImpl
->mxObjRef
.GetObject(), uno::UNO_QUERY
);
844 OSL_ENSURE( xPersObj
.is(), "The object must exist!" );
849 sal_Int32 nCurState
= mpImpl
->mxObjRef
->getCurrentState();
850 if ( nCurState
!= embed::EmbedStates::LOADED
)
851 mpImpl
->mxObjRef
->changeState(embed::EmbedStates::LOADED
);
853 // TODO/LATER: there should be possible to get current mediadescriptor settings from the object
854 uno::Sequence
< beans::PropertyValue
> aArgs( 1 );
855 aArgs
[0].Name
= "URL";
856 aArgs
[0].Value
<<= aNewLinkURL
;
857 xPersObj
->reload( aArgs
, uno::Sequence
< beans::PropertyValue
>() );
859 mpImpl
->maLinkURL
= aNewLinkURL
;
862 if ( nCurState
!= embed::EmbedStates::LOADED
)
863 mpImpl
->mxObjRef
->changeState(nCurState
);
865 catch( css::uno::Exception
const & )
867 TOOLS_WARN_EXCEPTION( "svx", "SdrOle2Obj::UpdateLinkURL_Impl()" );
873 // TODO/LATER: return the old name to the link manager, is it possible?
882 void SdrOle2Obj::BreakFileLink_Impl()
884 uno::Reference
<document::XStorageBasedDocument
> xDoc(getSdrModelFromSdrObject().getUnoModel(), uno::UNO_QUERY
);
889 uno::Reference
< embed::XStorage
> xStorage
= xDoc
->getDocumentStorage();
890 if ( !xStorage
.is() )
895 uno::Reference
< embed::XLinkageSupport
> xLinkSupport( mpImpl
->mxObjRef
.GetObject(), uno::UNO_QUERY_THROW
);
896 xLinkSupport
->breakLink( xStorage
, mpImpl
->aPersistName
);
897 DisconnectFileLink_Impl();
898 mpImpl
->maLinkURL
.clear();
900 catch( css::uno::Exception
& )
902 TOOLS_WARN_EXCEPTION( "svx", "SdrOle2Obj::BreakFileLink_Impl()" );
906 void SdrOle2Obj::DisconnectFileLink_Impl()
908 sfx2::LinkManager
* pLinkManager(getSdrModelFromSdrObject().GetLinkManager());
910 if ( pLinkManager
&& mpImpl
->mpObjectLink
)
912 pLinkManager
->Remove( mpImpl
->mpObjectLink
);
913 mpImpl
->mpObjectLink
= nullptr;
917 void SdrOle2Obj::CheckFileLink_Impl()
919 if (!mpImpl
->mxObjRef
.GetObject().is() || mpImpl
->mpObjectLink
)
924 uno::Reference
< embed::XLinkageSupport
> xLinkSupport( mpImpl
->mxObjRef
.GetObject(), uno::UNO_QUERY
);
926 if ( xLinkSupport
.is() && xLinkSupport
->isLink() )
928 OUString aLinkURL
= xLinkSupport
->getLinkURL();
930 if ( !aLinkURL
.isEmpty() )
932 // this is a file link so the model link manager should handle it
933 sfx2::LinkManager
* pLinkManager(getSdrModelFromSdrObject().GetLinkManager());
937 mpImpl
->mpObjectLink
= new SdrEmbedObjectLink( this );
938 mpImpl
->maLinkURL
= aLinkURL
;
939 pLinkManager
->InsertFileLink( *mpImpl
->mpObjectLink
, sfx2::SvBaseLinkObjectType::ClientOle
, aLinkURL
);
940 mpImpl
->mpObjectLink
->Connect();
945 catch (const css::uno::Exception
&)
947 TOOLS_WARN_EXCEPTION("svx", "SdrOle2Obj::CheckFileLink_Impl()");
951 void SdrOle2Obj::Connect_Impl()
953 if(mpImpl
->aPersistName
.isEmpty() )
958 ::comphelper::IEmbeddedHelper
* pPers(getSdrModelFromSdrObject().GetPersist());
962 comphelper::EmbeddedObjectContainer
& rContainer
= pPers
->getEmbeddedObjectContainer();
964 if ( !rContainer
.HasEmbeddedObject( mpImpl
->aPersistName
)
965 || ( mpImpl
->mxObjRef
.is() && !rContainer
.HasEmbeddedObject( mpImpl
->mxObjRef
.GetObject() ) ) )
967 // object not known to container document
968 // No object -> disaster!
969 DBG_ASSERT( mpImpl
->mxObjRef
.is(), "No object in connect!");
970 if ( mpImpl
->mxObjRef
.is() )
972 // object came from the outside, now add it to the container
974 rContainer
.InsertEmbeddedObject( mpImpl
->mxObjRef
.GetObject(), aTmp
);
975 mpImpl
->aPersistName
= aTmp
;
978 else if ( !mpImpl
->mxObjRef
.is() )
980 mpImpl
->mxObjRef
.Assign( rContainer
.GetEmbeddedObject( mpImpl
->aPersistName
), mpImpl
->mxObjRef
.GetViewAspect() );
981 mpImpl
->mbTypeAsked
= false;
984 if ( mpImpl
->mxObjRef
.GetObject().is() )
986 mpImpl
->mxObjRef
.AssignToContainer( &rContainer
, mpImpl
->aPersistName
);
987 mpImpl
->mbConnected
= true;
988 mpImpl
->mxObjRef
.Lock();
992 if ( mpImpl
->mxObjRef
.is() )
994 if ( !mpImpl
->mxLightClient
.is() )
995 mpImpl
->mxLightClient
= new SdrLightEmbeddedClient_Impl( this );
997 mpImpl
->mxObjRef
->addStateChangeListener( mpImpl
->mxLightClient
.get() );
998 mpImpl
->mxObjRef
->addEventListener( uno::Reference
< document::XEventListener
>( mpImpl
->mxLightClient
.get() ) );
1000 if ( mpImpl
->mxObjRef
->getCurrentState() != embed::EmbedStates::LOADED
)
1001 GetSdrGlobalData().GetOLEObjCache().InsertObj(this);
1003 CheckFileLink_Impl();
1005 uno::Reference
< container::XChild
> xChild( mpImpl
->mxObjRef
.GetObject(), uno::UNO_QUERY
);
1008 uno::Reference
< uno::XInterface
> xParent( getSdrModelFromSdrObject().getUnoModel());
1010 xChild
->setParent( getSdrModelFromSdrObject().getUnoModel() );
1015 catch( css::uno::Exception
& )
1017 TOOLS_WARN_EXCEPTION( "svx", "SdrOle2Obj::Connect_Impl()" );
1021 void SdrOle2Obj::ObjectLoaded()
1023 AddListeners_Impl();
1026 void SdrOle2Obj::AddListeners_Impl()
1028 if( !(mpImpl
->mxObjRef
.is() && mpImpl
->mxObjRef
->getCurrentState() != embed::EmbedStates::LOADED
) )
1031 // register modify listener
1032 if (!mpImpl
->mxModifyListener
.is())
1034 mpImpl
->mxModifyListener
= new SvxUnoShapeModifyListener(this);
1037 uno::Reference
< util::XModifyBroadcaster
> xBC( getXModel(), uno::UNO_QUERY
);
1040 uno::Reference
<util::XModifyListener
> xListener(mpImpl
->mxModifyListener
.get());
1041 xBC
->addModifyListener( xListener
);
1045 void SdrOle2Obj::Disconnect()
1047 if( IsEmptyPresObj() )
1050 if( !mpImpl
->mbConnected
)
1052 OSL_FAIL("Disconnect() called on disconnected object!");
1056 RemoveListeners_Impl();
1060 void SdrOle2Obj::RemoveListeners_Impl()
1062 if ( !mpImpl
->mxObjRef
.is() || mpImpl
->aPersistName
.isEmpty() )
1067 sal_Int32 nState
= mpImpl
->mxObjRef
->getCurrentState();
1068 if ( nState
!= embed::EmbedStates::LOADED
)
1070 uno::Reference
< util::XModifyBroadcaster
> xBC( getXModel(), uno::UNO_QUERY
);
1071 if (xBC
.is() && mpImpl
->mxModifyListener
.is())
1073 uno::Reference
<util::XModifyListener
> xListener(mpImpl
->mxModifyListener
.get());
1074 xBC
->removeModifyListener( xListener
);
1078 catch( css::uno::Exception
& )
1080 TOOLS_WARN_EXCEPTION( "svx", "SdrOle2Obj::RemoveListeners_Impl()" );
1084 void SdrOle2Obj::Disconnect_Impl()
1088 if ( !mpImpl
->aPersistName
.isEmpty() )
1090 if( getSdrModelFromSdrObject().IsInDestruction() )
1092 // TODO/LATER: here we must assume that the destruction of the model is enough to make clear that we will not
1093 // remove the object from the container, even if the DrawingObject itself is not destroyed (unfortunately this
1094 // There is no real need to do the following removing of the object from the container
1095 // in case the model has correct persistence, but in case of problems such a removing
1096 // would make the behavior of the office more stable
1098 comphelper::EmbeddedObjectContainer
* pContainer
= mpImpl
->mxObjRef
.GetContainer();
1101 pContainer
->CloseEmbeddedObject( mpImpl
->mxObjRef
.GetObject() );
1102 mpImpl
->mxObjRef
.AssignToContainer( nullptr, mpImpl
->aPersistName
);
1105 // happens later than the destruction of the model, so we can't assert that).
1106 //DBG_ASSERT( bInDestruction, "Model is destroyed, but not me?!" );
1107 //TODO/LATER: should be make sure that the ObjectShell also forgets the object, because we will close it soon?
1109 uno::Reference < util::XCloseable > xClose( xObjRef, uno::UNO_QUERY );
1114 xClose->close( true );
1116 catch ( util::CloseVetoException& )
1118 // there's still someone who needs the object!
1124 else if ( mpImpl
->mxObjRef
.is() )
1126 if ( getSdrModelFromSdrObject().getUnoModel().is() )
1128 // remove object, but don't close it (that's up to someone else)
1129 comphelper::EmbeddedObjectContainer
* pContainer
= mpImpl
->mxObjRef
.GetContainer();
1132 pContainer
->RemoveEmbeddedObject( mpImpl
->mxObjRef
.GetObject() );
1134 // TODO/LATER: mpImpl->aPersistName contains outdated information, to keep it updated
1135 // it should be returned from RemoveEmbeddedObject call. Currently it is no problem,
1136 // since no container is adjusted, actually the empty string could be provided as a name here
1137 mpImpl
->mxObjRef
.AssignToContainer( nullptr, mpImpl
->aPersistName
);
1140 DisconnectFileLink_Impl();
1145 if ( mpImpl
->mxObjRef
.is() && mpImpl
->mxLightClient
.is() )
1147 mpImpl
->mxObjRef
->removeStateChangeListener ( mpImpl
->mxLightClient
.get() );
1148 mpImpl
->mxObjRef
->removeEventListener( uno::Reference
< document::XEventListener
>( mpImpl
->mxLightClient
.get() ) );
1149 mpImpl
->mxObjRef
->setClientSite( nullptr );
1151 GetSdrGlobalData().GetOLEObjCache().RemoveObj(this);
1154 catch( css::uno::Exception
& )
1156 TOOLS_WARN_EXCEPTION( "svx", "SdrOle2Obj::Disconnect_Impl()" );
1159 mpImpl
->mbConnected
= false;
1162 SdrObjectUniquePtr
SdrOle2Obj::createSdrGrafObjReplacement(bool bAddText
) const
1164 const Graphic
* pOLEGraphic
= GetGraphic();
1168 // #i118485# allow creating a SdrGrafObj representation
1169 SdrGrafObj
* pClone
= new SdrGrafObj(
1170 getSdrModelFromSdrObject(),
1173 // copy transformation
1174 basegfx::B2DHomMatrix aMatrix
;
1175 basegfx::B2DPolyPolygon aPolyPolygon
;
1177 TRGetBaseGeometry(aMatrix
, aPolyPolygon
);
1178 pClone
->TRSetBaseGeometry(aMatrix
, aPolyPolygon
);
1180 // copy all attributes to support graphic styles for OLEs
1181 pClone
->SetStyleSheet(GetStyleSheet(), false);
1182 pClone
->SetMergedItemSet(GetMergedItemSet());
1186 // #i118485# copy text (Caution! Model needed, as guaranteed in aw080)
1187 OutlinerParaObject
* pOPO
= GetOutlinerParaObject();
1191 pClone
->NbcSetOutlinerParaObject(std::make_unique
<OutlinerParaObject
>(*pOPO
));
1195 return SdrObjectUniquePtr(pClone
);
1199 // #i100710# pOLEGraphic may be zero (no visualisation available),
1200 // so we need to use the OLE replacement graphic
1201 SdrRectObj
* pClone
= new SdrRectObj(
1202 getSdrModelFromSdrObject(),
1206 pClone
->SetMergedItem(XLineStyleItem(css::drawing::LineStyle_SOLID
));
1207 const svtools::ColorConfig aColorConfig
;
1208 const svtools::ColorConfigValue
aColor(aColorConfig
.GetColorValue(svtools::OBJECTBOUNDARIES
));
1209 pClone
->SetMergedItem(XLineColorItem(OUString(), aColor
.nColor
));
1212 pClone
->SetMergedItem(XFillStyleItem(drawing::FillStyle_BITMAP
));
1213 pClone
->SetMergedItem(XFillBitmapItem(OUString(), GetEmptyOLEReplacementGraphic()));
1214 pClone
->SetMergedItem(XFillBmpTileItem(false));
1215 pClone
->SetMergedItem(XFillBmpStretchItem(false));
1217 return SdrObjectUniquePtr(pClone
);
1221 SdrObjectUniquePtr
SdrOle2Obj::DoConvertToPolyObj(bool bBezier
, bool bAddText
) const
1223 // #i118485# missing converter added
1224 SdrObjectUniquePtr pRetval
= createSdrGrafObjReplacement(true);
1228 return pRetval
->DoConvertToPolyObj(bBezier
, bAddText
);
1234 void SdrOle2Obj::handlePageChange(SdrPage
* pOldPage
, SdrPage
* pNewPage
)
1236 const bool bRemove(pNewPage
== nullptr && pOldPage
!= nullptr);
1237 const bool bInsert(pNewPage
!= nullptr && pOldPage
== nullptr);
1239 if (bRemove
&& mpImpl
->mbConnected
)
1245 SdrRectObj::handlePageChange(pOldPage
, pNewPage
);
1247 if (bInsert
&& !mpImpl
->mbConnected
)
1253 void SdrOle2Obj::SetObjRef( const css::uno::Reference
< css::embed::XEmbeddedObject
>& rNewObjRef
)
1255 DBG_ASSERT( !rNewObjRef
.is() || !mpImpl
->mxObjRef
.GetObject().is(), "SetObjRef called on already initialized object!");
1256 if( rNewObjRef
== mpImpl
->mxObjRef
.GetObject() )
1259 // the caller of the method is responsible to control the old object, it will not be closed here
1260 // Otherwise WW8 import crashes because it transfers control to OLENode by this method
1261 if ( mpImpl
->mxObjRef
.GetObject().is() )
1262 mpImpl
->mxObjRef
.Lock( false );
1264 // avoid removal of object in Disconnect! It is definitely a HACK to call SetObjRef(0)!
1265 // This call will try to close the objects; so if anybody else wants to keep it, it must be locked by a CloseListener
1266 mpImpl
->mxObjRef
.Clear();
1268 if ( mpImpl
->mbConnected
)
1271 mpImpl
->mxObjRef
.Assign( rNewObjRef
, GetAspect() );
1272 mpImpl
->mbTypeAsked
= false;
1274 if ( mpImpl
->mxObjRef
.is() )
1276 mpImpl
->mxGraphic
.reset();
1278 if ( mpImpl
->mxObjRef
->getStatus( GetAspect() ) & embed::EmbedMisc::EMBED_NEVERRESIZE
)
1279 SetResizeProtect(true);
1281 // For math objects, set closed state to transparent
1282 SetClosedObj(!ImplIsMathObj( rNewObjRef
));
1288 BroadcastObjectChange();
1291 void SdrOle2Obj::SetClosedObj( bool bIsClosed
)
1293 // TODO/LATER: do we still need this hack?
1294 // Allow changes to the closed state of OLE objects
1295 bClosedObj
= bIsClosed
;
1298 SdrObjectUniquePtr
SdrOle2Obj::getFullDragClone() const
1300 // #i118485# use central replacement generator
1301 return createSdrGrafObjReplacement(false);
1304 void SdrOle2Obj::SetPersistName( const OUString
& rPersistName
)
1306 DBG_ASSERT( mpImpl
->aPersistName
.isEmpty(), "Persist name changed!");
1308 mpImpl
->aPersistName
= rPersistName
;
1309 mpImpl
->mbLoadingOLEObjectFailed
= false;
1315 void SdrOle2Obj::AbandonObject()
1317 mpImpl
->aPersistName
.clear();
1318 mpImpl
->mbLoadingOLEObjectFailed
= false;
1322 const OUString
& SdrOle2Obj::GetPersistName() const
1324 return mpImpl
->aPersistName
;
1327 void SdrOle2Obj::TakeObjInfo(SdrObjTransformInfoRec
& rInfo
) const
1329 // #i118485# Allowing much more attributes for OLEs
1330 rInfo
.bRotateFreeAllowed
= true;
1331 rInfo
.bRotate90Allowed
= true;
1332 rInfo
.bMirrorFreeAllowed
= true;
1333 rInfo
.bMirror45Allowed
= true;
1334 rInfo
.bMirror90Allowed
= true;
1335 rInfo
.bTransparenceAllowed
= true;
1336 rInfo
.bShearAllowed
= true;
1337 rInfo
.bEdgeRadiusAllowed
= false;
1338 rInfo
.bNoOrthoDesired
= false;
1339 rInfo
.bCanConvToPath
= true;
1340 rInfo
.bCanConvToPoly
= true;
1341 rInfo
.bCanConvToPathLineToArea
= false;
1342 rInfo
.bCanConvToPolyLineToArea
= false;
1343 rInfo
.bCanConvToContour
= true;
1346 SdrObjKind
SdrOle2Obj::GetObjIdentifier() const
1348 return mpImpl
->mbFrame
? OBJ_FRAME
: OBJ_OLE2
;
1351 OUString
SdrOle2Obj::TakeObjNameSingul() const
1353 OUStringBuffer
sName(SvxResId(mpImpl
->mbFrame
? STR_ObjNameSingulFrame
: STR_ObjNameSingulOLE2
));
1355 const OUString
aName(GetName());
1357 if (!aName
.isEmpty())
1360 sName
.append(aName
);
1364 return sName
.makeStringAndClear();
1367 OUString
SdrOle2Obj::TakeObjNamePlural() const
1369 return SvxResId(mpImpl
->mbFrame
? STR_ObjNamePluralFrame
: STR_ObjNamePluralOLE2
);
1372 SdrOle2Obj
* SdrOle2Obj::CloneSdrObject(SdrModel
& rTargetModel
) const
1374 return CloneHelper
< SdrOle2Obj
>(rTargetModel
);
1377 SdrOle2Obj
& SdrOle2Obj::operator=(const SdrOle2Obj
& rObj
)
1379 return assignFrom(rObj
);
1382 SdrOle2Obj
& SdrOle2Obj::assignFrom(const SdrOle2Obj
& rObj
)
1384 //TODO/LATER: who takes over control of my old object?!
1390 // ImpAssign( rObj );
1391 const SdrOle2Obj
& rOle2Obj
= rObj
;
1393 if( mpImpl
->mbConnected
)
1396 SdrRectObj::operator=( rObj
);
1398 // Manually copying bClosedObj attribute
1399 SetClosedObj( rObj
.IsClosedObj() );
1401 mpImpl
->aPersistName
= rOle2Obj
.mpImpl
->aPersistName
;
1402 mpImpl
->maProgName
= rOle2Obj
.mpImpl
->maProgName
;
1403 mpImpl
->mbFrame
= rOle2Obj
.mpImpl
->mbFrame
;
1405 if (rOle2Obj
.mpImpl
->mxGraphic
)
1407 mpImpl
->mxGraphic
.reset(new Graphic(*rOle2Obj
.mpImpl
->mxGraphic
));
1410 if( !IsEmptyPresObj() )
1412 ::comphelper::IEmbeddedHelper
* pDestPers(getSdrModelFromSdrObject().GetPersist());
1413 ::comphelper::IEmbeddedHelper
* pSrcPers(rObj
.getSdrModelFromSdrObject().GetPersist());
1414 if( pDestPers
&& pSrcPers
)
1416 DBG_ASSERT( !mpImpl
->mxObjRef
.is(), "Object already existing!" );
1417 comphelper::EmbeddedObjectContainer
& rContainer
= pSrcPers
->getEmbeddedObjectContainer();
1418 uno::Reference
< embed::XEmbeddedObject
> xObj
= rContainer
.GetEmbeddedObject( mpImpl
->aPersistName
);
1422 mpImpl
->mxObjRef
.Assign( pDestPers
->getEmbeddedObjectContainer().CopyAndGetEmbeddedObject(
1423 rContainer
, xObj
, aTmp
, pSrcPers
->getDocumentBaseURL(), pDestPers
->getDocumentBaseURL()), rOle2Obj
.GetAspect());
1424 mpImpl
->mbTypeAsked
= false;
1425 mpImpl
->aPersistName
= aTmp
;
1426 CheckFileLink_Impl();
1436 void SdrOle2Obj::ImpSetVisAreaSize()
1438 // #i118524# do not again set VisAreaSize when the call comes from OLE client (e.g. ObjectAreaChanged)
1439 if (mpImpl
->mbSuppressSetVisAreaSize
)
1442 // currently there is no need to recalculate scaling for iconified objects
1443 // TODO/LATER: it might be needed in future when it is possible to change the icon
1444 if ( GetAspect() == embed::Aspects::MSOLE_ICON
)
1447 // the object area of an embedded object was changed, e.g. by user interaction an a selected object
1449 if (!mpImpl
->mxObjRef
.is())
1452 sal_Int64 nMiscStatus
= mpImpl
->mxObjRef
->getStatus( GetAspect() );
1454 // the client is required to get access to scaling
1455 SfxInPlaceClient
* pClient(
1456 SfxInPlaceClient::GetClient(
1457 dynamic_cast<SfxObjectShell
*>(
1458 getSdrModelFromSdrObject().GetPersist()),
1459 mpImpl
->mxObjRef
.GetObject()));
1460 const bool bHasOwnClient(
1461 mpImpl
->mxLightClient
.is() &&
1462 mpImpl
->mxObjRef
->getClientSite() == uno::Reference
< embed::XEmbeddedClient
>( mpImpl
->mxLightClient
.get() ) );
1464 if ( pClient
|| bHasOwnClient
)
1466 // TODO: IMHO we need to do similar things when object is UIActive or OutplaceActive?!
1467 if ( ((nMiscStatus
& embed::EmbedMisc::MS_EMBED_RECOMPOSEONRESIZE
) &&
1468 svt::EmbeddedObjectRef::TryRunningState( mpImpl
->mxObjRef
.GetObject() ))
1469 || mpImpl
->mxObjRef
->getCurrentState() == embed::EmbedStates::INPLACE_ACTIVE
1472 Fraction aScaleWidth
;
1473 Fraction aScaleHeight
;
1476 aScaleWidth
= pClient
->GetScaleWidth();
1477 aScaleHeight
= pClient
->GetScaleHeight();
1481 aScaleWidth
= mpImpl
->mxLightClient
->GetScaleWidth();
1482 aScaleHeight
= mpImpl
->mxLightClient
->GetScaleHeight();
1485 // The object wants to resize itself (f.e. Chart wants to recalculate the layout)
1486 // or object is inplace active and so has a window that must be resized also
1487 // In these cases the change in the object area size will be reflected in a change of the
1488 // objects' visual area. The scaling will not change, but it might exist already and must
1489 // be used in calculations
1490 MapUnit aMapUnit
= VCLUnoHelper::UnoEmbed2VCLMapUnit( mpImpl
->mxObjRef
->getMapUnit( GetAspect() ) );
1491 Size
aVisSize( static_cast<tools::Long
>( Fraction( maRect
.GetWidth() ) / aScaleWidth
),
1492 static_cast<tools::Long
>( Fraction( maRect
.GetHeight() ) / aScaleHeight
) );
1494 aVisSize
= OutputDevice::LogicToLogic(
1496 MapMode(getSdrModelFromSdrObject().GetScaleUnit()),
1499 aSz
.Width
= aVisSize
.Width();
1500 aSz
.Height
= aVisSize
.Height();
1501 mpImpl
->mxObjRef
->setVisualAreaSize( GetAspect(), aSz
);
1505 aSz
= mpImpl
->mxObjRef
->getVisualAreaSize( GetAspect() );
1507 catch( embed::NoVisualAreaSizeException
& )
1510 tools::Rectangle aAcceptedVisArea
;
1511 aAcceptedVisArea
.SetSize( Size( static_cast<tools::Long
>( Fraction( tools::Long( aSz
.Width
) ) * aScaleWidth
),
1512 static_cast<tools::Long
>( Fraction( tools::Long( aSz
.Height
) ) * aScaleHeight
) ) );
1513 if (aVisSize
!= aAcceptedVisArea
.GetSize())
1515 // server changed VisArea to its liking and the VisArea is different than the suggested one
1516 // store the new value as given by the object
1517 MapUnit aNewMapUnit
= VCLUnoHelper::UnoEmbed2VCLMapUnit( mpImpl
->mxObjRef
->getMapUnit( GetAspect() ) );
1519 OutputDevice::LogicToLogic(
1520 aAcceptedVisArea
.GetSize(),
1521 MapMode(aNewMapUnit
),
1522 MapMode(getSdrModelFromSdrObject().GetScaleUnit())));
1525 // make the new object area known to the client
1526 // compared to the "else" branch aRect might have been changed by the object and no additional scaling was applied
1527 // WHY this -> OSL_ASSERT( pClient );
1529 pClient
->SetObjArea(maRect
);
1531 // we need a new replacement image as the object has resized itself
1533 //#i79578# don't request a new replacement image for charts to often
1534 //a chart sends a modified call to the framework if it was changed
1535 //thus the replacement update is already handled there
1537 mpImpl
->mxObjRef
.UpdateReplacement();
1541 // The object isn't active and does not want to resize itself so the changed object area size
1542 // will be reflected in a changed object scaling
1543 Fraction aScaleWidth
;
1544 Fraction aScaleHeight
;
1546 if ( CalculateNewScaling( aScaleWidth
, aScaleHeight
, aObjAreaSize
) )
1550 tools::Rectangle
aScaleRect(maRect
.TopLeft(), aObjAreaSize
);
1551 pClient
->SetObjAreaAndScale( aScaleRect
, aScaleWidth
, aScaleHeight
);
1555 mpImpl
->mxLightClient
->SetSizeScale( aScaleWidth
, aScaleHeight
);
1560 else if( (nMiscStatus
& embed::EmbedMisc::MS_EMBED_RECOMPOSEONRESIZE
) &&
1561 svt::EmbeddedObjectRef::TryRunningState( mpImpl
->mxObjRef
.GetObject() ) )
1563 //also handle not sfx based ole objects e.g. charts
1564 //#i83860# resizing charts in impress distorts fonts
1565 uno::Reference
< embed::XVisualObject
> xVisualObject( getXModel(), uno::UNO_QUERY
);
1566 if( xVisualObject
.is() )
1568 const MapUnit
aMapUnit(
1569 VCLUnoHelper::UnoEmbed2VCLMapUnit(
1570 mpImpl
->mxObjRef
->getMapUnit(GetAspect())));
1571 const Point
aTL( maRect
.TopLeft() );
1572 const Point
aBR( maRect
.BottomRight() );
1574 OutputDevice::LogicToLogic(
1576 MapMode(getSdrModelFromSdrObject().GetScaleUnit()),
1577 MapMode(aMapUnit
)));
1579 OutputDevice::LogicToLogic(
1581 MapMode(getSdrModelFromSdrObject().GetScaleUnit()),
1582 MapMode(aMapUnit
)));
1583 const tools::Rectangle
aNewRect(
1587 xVisualObject
->setVisualAreaSize(
1590 aNewRect
.GetWidth(),
1591 aNewRect
.GetHeight()));
1596 void SdrOle2Obj::NbcResize(const Point
& rRef
, const Fraction
& xFact
, const Fraction
& yFact
)
1598 if(!getSdrModelFromSdrObject().isLocked())
1602 if ( mpImpl
->mxObjRef
.is() && ( mpImpl
->mxObjRef
->getStatus( GetAspect() ) & embed::EmbedMisc::MS_EMBED_RECOMPOSEONRESIZE
) )
1604 // if the object needs recompose on resize
1605 // the client site should be created before the resize will take place
1606 // check whether there is no client site and create it if necessary
1607 AddOwnLightClient();
1611 SdrRectObj::NbcResize(rRef
,xFact
,yFact
);
1613 if( !getSdrModelFromSdrObject().isLocked() )
1614 ImpSetVisAreaSize();
1617 void SdrOle2Obj::SetGeoData(const SdrObjGeoData
& rGeo
)
1619 SdrRectObj::SetGeoData(rGeo
);
1621 if( !getSdrModelFromSdrObject().isLocked() )
1622 ImpSetVisAreaSize();
1625 void SdrOle2Obj::NbcSetSnapRect(const tools::Rectangle
& rRect
)
1627 SdrRectObj::NbcSetSnapRect(rRect
);
1629 if( !getSdrModelFromSdrObject().isLocked() )
1630 ImpSetVisAreaSize();
1632 if ( mpImpl
->mxObjRef
.is() && IsChart() )
1634 //#i103460# charts do not necessarily have an own size within ODF files,
1635 //for this case they need to use the size settings from the surrounding frame,
1636 //which is made available with this method as there is no other way
1637 mpImpl
->mxObjRef
.SetDefaultSizeForChart( Size( rRect
.GetWidth(), rRect
.GetHeight() ) );
1641 void SdrOle2Obj::NbcSetLogicRect(const tools::Rectangle
& rRect
)
1643 SdrRectObj::NbcSetLogicRect(rRect
);
1645 if( !getSdrModelFromSdrObject().isLocked() )
1646 ImpSetVisAreaSize();
1649 const Graphic
* SdrOle2Obj::GetGraphic() const
1651 if ( mpImpl
->mxObjRef
.is() )
1652 return mpImpl
->mxObjRef
.GetGraphic();
1653 return mpImpl
->mxGraphic
.get();
1656 void SdrOle2Obj::GetNewReplacement()
1658 if ( mpImpl
->mxObjRef
.is() )
1659 mpImpl
->mxObjRef
.UpdateReplacement();
1662 Size
SdrOle2Obj::GetOrigObjSize( MapMode
const * pTargetMapMode
) const
1664 return mpImpl
->mxObjRef
.GetSize( pTargetMapMode
);
1667 void SdrOle2Obj::setSuppressSetVisAreaSize( bool bNew
)
1669 mpImpl
->mbSuppressSetVisAreaSize
= bNew
;
1672 void SdrOle2Obj::NbcMove(const Size
& rSize
)
1674 SdrRectObj::NbcMove(rSize
);
1676 if( !getSdrModelFromSdrObject().isLocked() )
1677 ImpSetVisAreaSize();
1680 bool SdrOle2Obj::CanUnloadRunningObj( const uno::Reference
< embed::XEmbeddedObject
>& xObj
, sal_Int64 nAspect
)
1682 uno::Reference
<embed::XEmbedPersist2
> xPersist(xObj
, uno::UNO_QUERY
);
1685 if (!xPersist
->isStored())
1686 // It doesn't have persistent storage. We can't unload this.
1690 bool bResult
= false;
1692 sal_Int32 nState
= xObj
->getCurrentState();
1693 if ( nState
== embed::EmbedStates::LOADED
)
1695 // the object is already unloaded
1700 uno::Reference
< util::XModifiable
> xModifiable( xObj
->getComponent(), uno::UNO_QUERY
);
1701 if ( !xModifiable
.is() )
1705 sal_Int64 nMiscStatus
= xObj
->getStatus( nAspect
);
1707 if ( embed::EmbedMisc::MS_EMBED_ALWAYSRUN
!= ( nMiscStatus
& embed::EmbedMisc::MS_EMBED_ALWAYSRUN
) &&
1708 embed::EmbedMisc::EMBED_ACTIVATEIMMEDIATELY
!= ( nMiscStatus
& embed::EmbedMisc::EMBED_ACTIVATEIMMEDIATELY
) &&
1709 !( xModifiable
.is() && xModifiable
->isModified() ) &&
1710 !( nState
== embed::EmbedStates::INPLACE_ACTIVE
|| nState
== embed::EmbedStates::UI_ACTIVE
|| nState
== embed::EmbedStates::ACTIVE
) )
1720 bool SdrOle2Obj::Unload( const uno::Reference
< embed::XEmbeddedObject
>& xObj
, sal_Int64 nAspect
)
1722 bool bResult
= false;
1724 if ( CanUnloadRunningObj( xObj
, nAspect
) )
1728 xObj
->changeState( embed::EmbedStates::LOADED
);
1731 catch( css::uno::Exception
& )
1733 TOOLS_WARN_EXCEPTION( "svx", "SdrOle2Obj::Unload()" );
1740 bool SdrOle2Obj::Unload()
1742 if (!mpImpl
->mxObjRef
.is())
1743 // Already unloaded.
1746 bool bUnloaded
= false;
1748 if ( mpImpl
->mxObjRef
.is() )
1750 bUnloaded
= Unload( mpImpl
->mxObjRef
.GetObject(), GetAspect() );
1756 void SdrOle2Obj::GetObjRef_Impl()
1758 if ( !mpImpl
->mxObjRef
.is() && !mpImpl
->aPersistName
.isEmpty() && getSdrModelFromSdrObject().GetPersist() )
1760 // Only try loading if it did not went wrong up to now
1761 if(!mpImpl
->mbLoadingOLEObjectFailed
)
1763 mpImpl
->mxObjRef
.Assign(
1764 getSdrModelFromSdrObject().GetPersist()->getEmbeddedObjectContainer().GetEmbeddedObject(mpImpl
->aPersistName
),
1766 mpImpl
->mbTypeAsked
= false;
1767 CheckFileLink_Impl();
1769 // If loading of OLE object failed, remember that to not invoke an endless
1770 // loop trying to load it again and again.
1771 if( mpImpl
->mxObjRef
.is() )
1773 mpImpl
->mbLoadingOLEObjectFailed
= true;
1776 // For math objects, set closed state to transparent
1777 SetClosedObj(!ImplIsMathObj( mpImpl
->mxObjRef
.GetObject() ));
1780 if ( mpImpl
->mxObjRef
.is() )
1782 if( !IsEmptyPresObj() )
1784 // remember modified status of model
1785 const bool bWasChanged(getSdrModelFromSdrObject().IsChanged());
1787 // perhaps preview not valid anymore
1788 // This line changes the modified state of the model
1791 // if status was not set before, force it back
1792 // to not set, so that SetGraphic(0) above does not
1793 // set the modified state of the model.
1794 if(!bWasChanged
&& getSdrModelFromSdrObject().IsChanged())
1796 getSdrModelFromSdrObject().SetChanged( false );
1801 if ( mpImpl
->mxObjRef
.is() )
1805 if ( mpImpl
->mbConnected
)
1807 // move object to first position in cache
1808 GetSdrGlobalData().GetOLEObjCache().InsertObj(this);
1812 uno::Reference
< embed::XEmbeddedObject
> const & SdrOle2Obj::GetObjRef() const
1814 const_cast<SdrOle2Obj
*>(this)->GetObjRef_Impl();
1815 return mpImpl
->mxObjRef
.GetObject();
1818 uno::Reference
< embed::XEmbeddedObject
> const & SdrOle2Obj::GetObjRef_NoInit() const
1820 return mpImpl
->mxObjRef
.GetObject();
1823 uno::Reference
< frame::XModel
> SdrOle2Obj::getXModel() const
1826 if ( svt::EmbeddedObjectRef::TryRunningState(mpImpl
->mxObjRef
.GetObject()) )
1827 return uno::Reference
< frame::XModel
>( mpImpl
->mxObjRef
->getComponent(), uno::UNO_QUERY
);
1829 return uno::Reference
< frame::XModel
>();
1832 bool SdrOle2Obj::IsChart() const
1834 if (!mpImpl
->mbTypeAsked
)
1836 mpImpl
->mbIsChart
= mpImpl
->mxObjRef
.IsChart();
1837 mpImpl
->mbTypeAsked
= true;
1839 return mpImpl
->mbIsChart
;
1842 void SdrOle2Obj::SetGraphicToObj( const Graphic
& aGraphic
)
1844 mpImpl
->mxObjRef
.SetGraphic( aGraphic
, OUString() );
1845 // if the object isn't valid, e.g. link to something that doesn't exist, set the fallback
1846 // graphic as mxGraphic so SdrOle2Obj::GetGraphic will show the fallback
1847 if (const Graphic
* pObjGraphic
= mpImpl
->mxObjRef
.is() ? nullptr : mpImpl
->mxObjRef
.GetGraphic())
1848 mpImpl
->mxGraphic
.reset(new Graphic(*pObjGraphic
));
1851 void SdrOle2Obj::SetGraphicToObj( const uno::Reference
< io::XInputStream
>& xGrStream
, const OUString
& aMediaType
)
1853 mpImpl
->mxObjRef
.SetGraphicStream( xGrStream
, aMediaType
);
1854 // if the object isn't valid, e.g. link to something that doesn't exist, set the fallback
1855 // graphic as mxGraphic so SdrOle2Obj::GetGraphic will show the fallback
1856 if (const Graphic
* pObjGraphic
= mpImpl
->mxObjRef
.is() ? nullptr : mpImpl
->mxObjRef
.GetGraphic())
1857 mpImpl
->mxGraphic
.reset(new Graphic(*pObjGraphic
));
1860 bool SdrOle2Obj::IsCalc() const
1862 if ( !mpImpl
->mxObjRef
.is() )
1865 SvGlobalName
aObjClsId( mpImpl
->mxObjRef
->getClassID() );
1866 return SvGlobalName(SO3_SC_CLASSID_30
) == aObjClsId
1867 || SvGlobalName(SO3_SC_CLASSID_40
) == aObjClsId
1868 || SvGlobalName(SO3_SC_CLASSID_50
) == aObjClsId
1869 || SvGlobalName(SO3_SC_CLASSID_60
) == aObjClsId
1870 || SvGlobalName(SO3_SC_OLE_EMBED_CLASSID_60
) == aObjClsId
1871 || SvGlobalName(SO3_SC_OLE_EMBED_CLASSID_8
) == aObjClsId
1872 || SvGlobalName(SO3_SC_CLASSID
) == aObjClsId
;
1875 uno::Reference
< frame::XModel
> SdrOle2Obj::GetParentXModel() const
1877 uno::Reference
< frame::XModel
> xDoc(getSdrModelFromSdrObject().getUnoModel(), uno::UNO_QUERY
);
1881 bool SdrOle2Obj::CalculateNewScaling( Fraction
& aScaleWidth
, Fraction
& aScaleHeight
, Size
& aObjAreaSize
)
1883 // TODO/LEAN: to avoid rounding errors scaling always uses the VisArea.
1884 // If we don't cache it for own objects also we must load the object here
1885 if (!mpImpl
->mxObjRef
.is())
1888 MapMode
aMapMode(getSdrModelFromSdrObject().GetScaleUnit());
1889 aObjAreaSize
= mpImpl
->mxObjRef
.GetSize( &aMapMode
);
1891 Size aSize
= maRect
.GetSize();
1892 aScaleWidth
= Fraction(aSize
.Width(), aObjAreaSize
.Width() );
1893 aScaleHeight
= Fraction(aSize
.Height(), aObjAreaSize
.Height() );
1895 // reduce to 10 binary digits
1896 aScaleHeight
.ReduceInaccurate(10);
1897 aScaleWidth
.ReduceInaccurate(10);
1902 bool SdrOle2Obj::AddOwnLightClient()
1904 // The Own Light Client must be registered in object only using this method!
1905 if ( !SfxInPlaceClient::GetClient( dynamic_cast<SfxObjectShell
*>(getSdrModelFromSdrObject().GetPersist()), mpImpl
->mxObjRef
.GetObject() )
1906 && !( mpImpl
->mxLightClient
.is() && mpImpl
->mxObjRef
->getClientSite() == uno::Reference
< embed::XEmbeddedClient
>( mpImpl
->mxLightClient
.get() ) ) )
1910 if ( mpImpl
->mxObjRef
.is() && mpImpl
->mxLightClient
.is() )
1912 Fraction aScaleWidth
;
1913 Fraction aScaleHeight
;
1915 if ( CalculateNewScaling( aScaleWidth
, aScaleHeight
, aObjAreaSize
) )
1917 mpImpl
->mxLightClient
->SetSizeScale( aScaleWidth
, aScaleHeight
);
1919 mpImpl
->mxObjRef
->setClientSite( mpImpl
->mxLightClient
.get() );
1921 } catch( uno::Exception
& )
1933 Graphic
SdrOle2Obj::GetEmptyOLEReplacementGraphic()
1935 return Graphic(BitmapEx(BMP_SVXOLEOBJ
));
1938 void SdrOle2Obj::SetWindow(const css::uno::Reference
< css::awt::XWindow
>& _xWindow
)
1940 if ( mpImpl
->mxObjRef
.is() && mpImpl
->mxLightClient
.is() )
1942 mpImpl
->mxLightClient
->setWindow(_xWindow
);
1946 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */