1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <svx/sdr/contact/viewobjectcontactofunocontrol.hxx>
22 #include <svx/sdr/contact/viewcontactofunocontrol.hxx>
23 #include <svx/sdr/contact/displayinfo.hxx>
24 #include <svx/sdr/properties/properties.hxx>
25 #include <svx/sdr/contact/objectcontactofpageview.hxx>
26 #include <svx/sdr/primitive2d/svx_primitivetypes2d.hxx>
27 #include <svx/svdouno.hxx>
28 #include <svx/svdpagv.hxx>
29 #include <svx/svdview.hxx>
30 #include <svx/sdrpagewindow.hxx>
31 #include "svx/sdrpaintwindow.hxx"
33 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
34 #include <com/sun/star/awt/XControl.hpp>
35 #include <com/sun/star/awt/XControlModel.hpp>
36 #include <com/sun/star/awt/XControlContainer.hpp>
37 #include <com/sun/star/awt/XWindow2.hpp>
38 #include <com/sun/star/awt/PosSize.hpp>
39 #include <com/sun/star/awt/XView.hpp>
40 #include <com/sun/star/beans/XPropertySet.hpp>
41 #include <com/sun/star/lang/XComponent.hpp>
42 #include <com/sun/star/awt/InvalidateStyle.hpp>
43 #include <com/sun/star/util/XModeChangeListener.hpp>
44 #include <com/sun/star/util/XModeChangeBroadcaster.hpp>
45 #include <com/sun/star/container/XContainerListener.hpp>
46 #include <com/sun/star/container/XContainer.hpp>
48 #include <vcl/svapp.hxx>
49 #include <osl/mutex.hxx>
50 #include <comphelper/processfactory.hxx>
51 #include <comphelper/scopeguard.hxx>
52 #include <cppuhelper/implbase4.hxx>
53 #include <toolkit/helper/vclunohelper.hxx>
54 #include <tools/diagnose_ex.h>
55 #include <basegfx/matrix/b2dhommatrix.hxx>
56 #include <drawinglayer/primitive2d/controlprimitive2d.hxx>
58 #include <boost/bind.hpp>
62 Form controls (more precise: UNO Controls) in the drawing layer are ... prone to breakage, since they have some
63 specialities which the drawing layer currently doesn't capture too well. In particular, having a living VCL
64 window as child of the document window, and coupling this Window to a drawing layer object, makes things
67 Below is a list of issues which existed in the past. Whenever you change code here, you're encouraged to
68 verify those issues are still fixed. (Whenever you have some additional time, you're encouraged to write
69 an automatic test for one or more of those issues for which this is possible :)
71 http://www.openoffice.org/issues/show_bug.cgi?id=105992
72 zooming documents containg (alive) form controls improperly positions the controls
74 http://www.openoffice.org/issues/show_bug.cgi?id=104362
75 crash when copy a control
77 http://www.openoffice.org/issues/show_bug.cgi?id=104544
78 Gridcontrol duplicated after design view on/off
80 http://www.openoffice.org/issues/show_bug.cgi?id=102089
81 print preview shows control elements with property printable=false
83 http://www.openoffice.org/issues/show_bug.cgi?id=102090
84 problem with setVisible on TextControl
86 http://www.openoffice.org/issues/show_bug.cgi?id=103138
87 loop when insert a control in draw
89 http://www.openoffice.org/issues/show_bug.cgi?id=101398
90 initially-displaying a document with many controls is very slow
92 http://www.openoffice.org/issues/show_bug.cgi?id=72429
93 repaint error in form wizard in bugdoc database
95 http://www.openoffice.org/issues/show_bug.cgi?id=72694
96 form control artifacts when scrolling a text fast
99 issues in the old (Sun-internal) bug tracking system:
102 form controls being in redlining or in hidden section are visible in alive-mode
106 //........................................................................
107 namespace sdr
{ namespace contact
{
108 //........................................................................
110 using namespace ::com::sun::star::awt::InvalidateStyle
;
111 using ::com::sun::star::uno::Reference
;
112 using ::com::sun::star::uno::XInterface
;
113 using ::com::sun::star::uno::UNO_QUERY
;
114 using ::com::sun::star::uno::UNO_QUERY_THROW
;
115 using ::com::sun::star::uno::UNO_SET_THROW
;
116 using ::com::sun::star::uno::Exception
;
117 using ::com::sun::star::uno::RuntimeException
;
118 using ::com::sun::star::awt::XControl
;
119 using ::com::sun::star::lang::XMultiServiceFactory
;
120 using ::com::sun::star::awt::XControlModel
;
121 using ::com::sun::star::awt::XControlContainer
;
122 using ::com::sun::star::awt::XWindow
;
123 using ::com::sun::star::awt::XWindow2
;
124 using ::com::sun::star::awt::XWindowListener
;
125 using ::com::sun::star::awt::PosSize::POSSIZE
;
126 using ::com::sun::star::awt::XView
;
127 using ::com::sun::star::awt::XGraphics
;
128 using ::com::sun::star::awt::WindowEvent
;
129 using ::com::sun::star::beans::XPropertySet
;
130 using ::com::sun::star::beans::XPropertySetInfo
;
131 using ::com::sun::star::lang::XComponent
;
132 using ::com::sun::star::awt::XWindowPeer
;
133 using ::com::sun::star::beans::XPropertyChangeListener
;
134 using ::com::sun::star::util::XModeChangeListener
;
135 using ::com::sun::star::util::XModeChangeBroadcaster
;
136 using ::com::sun::star::util::ModeChangeEvent
;
137 using ::com::sun::star::lang::EventObject
;
138 using ::com::sun::star::beans::PropertyChangeEvent
;
139 using ::com::sun::star::container::XContainerListener
;
140 using ::com::sun::star::container::XContainer
;
141 using ::com::sun::star::container::ContainerEvent
;
142 using ::com::sun::star::uno::Any
;
144 //====================================================================
146 //====================================================================
150 Reference
< XControl
> m_xControl
;
151 Reference
< XWindow2
> m_xControlWindow
;
152 Reference
< XView
> m_xControlView
;
162 explicit ControlHolder( const Reference
< XControl
>& _rxControl
)
170 ControlHolder
& operator=( const Reference
< XControl
>& _rxControl
)
174 m_xControl
= _rxControl
;
175 if ( m_xControl
.is() )
177 m_xControlWindow
.set( m_xControl
, UNO_QUERY
);
178 m_xControlView
.set( m_xControl
, UNO_QUERY
);
179 if ( !m_xControlWindow
.is() || !m_xControlView
.is() )
181 OSL_FAIL( "ControlHolder::operator=: invalid XControl, missing required interfaces!" );
190 inline bool is() const { return m_xControl
.is() && m_xControlWindow
.is() && m_xControlView
.is(); }
191 inline void clear() { m_xControl
.clear(); m_xControlWindow
.clear(); m_xControlView
.clear(); }
193 // delegators for the methods of the UNO interfaces
194 // Note all those will crash if called for a NULL object.
195 inline bool isDesignMode() const { return m_xControl
->isDesignMode(); }
196 inline void setDesignMode( const bool _bDesign
) const { m_xControl
->setDesignMode( _bDesign
); }
197 inline bool isVisible() const { return m_xControlWindow
->isVisible(); }
198 inline void setVisible( const bool _bVisible
) const { m_xControlWindow
->setVisible( _bVisible
); }
199 inline Reference
< XControlModel
>
200 getModel() const { return m_xControl
->getModel(); }
201 inline void setModel( const Reference
< XControlModel
>& _m
) const { m_xControl
->setModel( _m
); }
202 inline bool isTransparent() const { return m_xControl
->isTransparent(); }
203 inline Reference
< XWindowPeer
>
204 getPeer() const { return m_xControl
->getPeer(); }
206 inline void addWindowListener( const Reference
< XWindowListener
>& _l
) const { m_xControlWindow
->addWindowListener( _l
); }
207 inline void removeWindowListener( const Reference
< XWindowListener
>& _l
) const { m_xControlWindow
->removeWindowListener( _l
); }
208 void setPosSize( const Rectangle
& _rPosSize
) const;
211 void setZoom( const ::basegfx::B2DVector
& _rScale
) const;
215 inline void setGraphics( const Reference
< XGraphics
>& _g
) const { m_xControlView
->setGraphics( _g
); }
216 inline Reference
< XGraphics
>
217 getGraphics() const { return m_xControlView
->getGraphics(); }
218 inline void draw( const Point
& _rTopLeft
) const { m_xControlView
->draw( _rTopLeft
.X(), _rTopLeft
.Y() ); }
220 void invalidate() const;
223 inline const Reference
< XControl
>& getControl() const { return m_xControl
; }
226 //--------------------------------------------------------------------
227 bool operator==( const ControlHolder
& _rControl
, const Reference
< XInterface
>& _rxCompare
)
229 return _rControl
.getControl() == _rxCompare
;
232 //--------------------------------------------------------------------
233 bool operator==( const Reference
< XInterface
>& _rxCompare
, const ControlHolder
& _rControl
)
235 return _rxCompare
== _rControl
.getControl();
238 //--------------------------------------------------------------------
239 bool operator==( const ControlHolder
& _rControl
, const Any
& _rxCompare
)
241 return _rControl
== Reference
< XInterface
>( _rxCompare
, UNO_QUERY
);
244 //--------------------------------------------------------------------
245 bool operator==( const Any
& _rxCompare
, const ControlHolder
& _rControl
)
247 return Reference
< XInterface
>( _rxCompare
, UNO_QUERY
) == _rControl
;
250 //--------------------------------------------------------------------
251 void ControlHolder::setPosSize( const Rectangle
& _rPosSize
) const
253 // no check whether we're valid, this is the responsibility of the caller
255 // don't call setPosSize when pos/size did not change
256 // #i104181# / 2009-08-18 / frank.schoenheit@sun.com
257 ::Rectangle
aCurrentRect( getPosSize() );
258 if ( aCurrentRect
!= _rPosSize
)
260 m_xControlWindow
->setPosSize(
261 _rPosSize
.Left(), _rPosSize
.Top(), _rPosSize
.GetWidth(), _rPosSize
.GetHeight(),
267 //--------------------------------------------------------------------
268 ::Rectangle
ControlHolder::getPosSize() const
270 // no check whether we're valid, this is the responsibility of the caller
271 return VCLUnoHelper::ConvertToVCLRect( m_xControlWindow
->getPosSize() );
274 //--------------------------------------------------------------------
275 void ControlHolder::setZoom( const ::basegfx::B2DVector
& _rScale
) const
277 // no check whether we're valid, this is the responsibility of the caller
278 m_xControlView
->setZoom( (float)_rScale
.getX(), (float)_rScale
.getY() );
281 //--------------------------------------------------------------------
282 void ControlHolder::invalidate() const
284 Reference
< XWindowPeer
> xPeer( m_xControl
->getPeer() );
287 Window
* pWindow
= VCLUnoHelper::GetWindow( xPeer
);
288 OSL_ENSURE( pWindow
, "ControlHolder::invalidate: no implementation access!" );
290 pWindow
->Invalidate();
294 //--------------------------------------------------------------------
295 ::basegfx::B2DVector
ControlHolder::getZoom() const
297 // no check whether we're valid, this is the responsibility of the caller
299 // Argh. Why does XView have a setZoom only, but not a getZoom?
300 Window
* pWindow
= VCLUnoHelper::GetWindow( m_xControl
->getPeer() );
301 OSL_ENSURE( pWindow
, "ControlHolder::getZoom: no implementation access!" );
303 ::basegfx::B2DVector
aZoom( 1, 1 );
306 const Fraction
& rZoom( pWindow
->GetZoom() );
307 aZoom
.setX( (double)rZoom
);
308 aZoom
.setY( (double)rZoom
);
313 //====================================================================
314 //= UnoControlContactHelper
315 //====================================================================
316 class UnoControlContactHelper
319 /** positions a control, and sets its zoom mode, using a given transformation and output device
321 static void adjustControlGeometry_throw(
322 const ControlHolder
& _rControl
,
323 const Rectangle
& _rLogicBoundingRect
,
324 const ::basegfx::B2DHomMatrix
& _rViewTransformation
,
325 const ::basegfx::B2DHomMatrix
& _rZoomLevelNormalization
328 /** disposes the given control
330 static void disposeAndClearControl_nothrow(
331 ControlHolder
& _rControl
335 UnoControlContactHelper(); // never implemented
336 UnoControlContactHelper( const UnoControlContactHelper
& ); // never implemented
337 UnoControlContactHelper
& operator=( const UnoControlContactHelper
& ); // never implemented
340 //--------------------------------------------------------------------
341 void UnoControlContactHelper::adjustControlGeometry_throw( const ControlHolder
& _rControl
, const Rectangle
& _rLogicBoundingRect
,
342 const basegfx::B2DHomMatrix
& _rViewTransformation
, const ::basegfx::B2DHomMatrix
& _rZoomLevelNormalization
)
344 OSL_PRECOND( _rControl
.is(), "UnoControlContactHelper::adjustControlGeometry_throw: illegal control!" );
345 if ( !_rControl
.is() )
348 #if OSL_DEBUG_LEVEL > 0
349 ::basegfx::B2DTuple aViewScale
, aViewTranslate
;
350 double nViewRotate(0), nViewShearX(0);
351 _rViewTransformation
.decompose( aViewScale
, aViewTranslate
, nViewRotate
, nViewShearX
);
353 ::basegfx::B2DTuple aZoomScale
, aZoomTranslate
;
354 double nZoomRotate(0), nZoomShearX(0);
355 _rZoomLevelNormalization
.decompose( aZoomScale
, aZoomTranslate
, nZoomRotate
, nZoomShearX
);
358 // transform the logic bound rect, using the view transformation, to pixel coordinates
359 ::basegfx::B2DPoint
aTopLeft( _rLogicBoundingRect
.Left(), _rLogicBoundingRect
.Top() );
360 aTopLeft
*= _rViewTransformation
;
361 ::basegfx::B2DPoint
aBottomRight( _rLogicBoundingRect
.Right(), _rLogicBoundingRect
.Bottom() );
362 aBottomRight
*= _rViewTransformation
;
364 const Rectangle
aPaintRectPixel( (long)aTopLeft
.getX(), (long)aTopLeft
.getY(), (long)aBottomRight
.getX(), (long)aBottomRight
.getY() );
365 _rControl
.setPosSize( aPaintRectPixel
);
367 // determine the scale from the current view transformation, and the normalization matrix
368 ::basegfx::B2DHomMatrix
aObtainResolutionDependentScale( _rViewTransformation
* _rZoomLevelNormalization
);
369 ::basegfx::B2DVector aScale
, aTranslate
;
370 double fRotate
, fShearX
;
371 aObtainResolutionDependentScale
.decompose( aScale
, aTranslate
, fRotate
, fShearX
);
372 _rControl
.setZoom( aScale
);
375 //--------------------------------------------------------------------
376 void UnoControlContactHelper::disposeAndClearControl_nothrow( ControlHolder
& _rControl
)
380 Reference
< XComponent
> xControlComp( _rControl
.getControl(), UNO_QUERY
);
381 if ( xControlComp
.is() )
382 xControlComp
->dispose();
384 catch( const Exception
& )
386 DBG_UNHANDLED_EXCEPTION();
391 //====================================================================
393 //====================================================================
394 /** interface encapsulating access to an SdrPageView, stripped down to the methods we really need
396 class IPageViewAccess
399 /** determines whether the view is currently in design mode
401 virtual bool isDesignMode() const = 0;
403 /** retrieves the control container for a given output device
405 virtual Reference
< XControlContainer
>
406 getControlContainer( const OutputDevice
& _rDevice
) const = 0;
408 /** determines whether a given layer is visible
410 virtual bool isLayerVisible( SdrLayerID _nLayerID
) const = 0;
413 ~IPageViewAccess() {}
416 //====================================================================
417 //= SdrPageViewAccess
418 //====================================================================
419 /** is a ->IPageViewAccess implementation based on a real ->SdrPageView instance
421 class SdrPageViewAccess
: public IPageViewAccess
423 const SdrPageView
& m_rPageView
;
425 explicit SdrPageViewAccess( const SdrPageView
& _rPageView
) : m_rPageView( _rPageView
) { }
427 virtual ~SdrPageViewAccess() {}
429 virtual bool isDesignMode() const;
430 virtual Reference
< XControlContainer
>
431 getControlContainer( const OutputDevice
& _rDevice
) const;
432 virtual bool isLayerVisible( SdrLayerID _nLayerID
) const;
435 //--------------------------------------------------------------------
436 bool SdrPageViewAccess::isDesignMode() const
438 return m_rPageView
.GetView().IsDesignMode();
441 //--------------------------------------------------------------------
442 Reference
< XControlContainer
> SdrPageViewAccess::getControlContainer( const OutputDevice
& _rDevice
) const
444 Reference
< XControlContainer
> xControlContainer
= m_rPageView
.GetControlContainer( _rDevice
);
445 DBG_ASSERT( xControlContainer
.is() || NULL
== m_rPageView
.FindPageWindow( ( const_cast< OutputDevice
& >( _rDevice
) ) ),
446 "SdrPageViewAccess::getControlContainer: the output device is known, but there is no control container for it?" );
447 return xControlContainer
;
450 //--------------------------------------------------------------------
451 bool SdrPageViewAccess::isLayerVisible( SdrLayerID _nLayerID
) const
453 return m_rPageView
.GetVisibleLayers().IsSet( _nLayerID
);
456 //====================================================================
457 //= InvisibleControlViewAccess
458 //====================================================================
459 /** is a ->IPageViewAccess implementation which can be used to create an invisble control for
462 class InvisibleControlViewAccess
: public IPageViewAccess
465 Reference
< XControlContainer
>& m_rControlContainer
;
467 explicit InvisibleControlViewAccess( Reference
< XControlContainer
>& _inout_ControlContainer
)
468 :m_rControlContainer( _inout_ControlContainer
)
472 virtual ~InvisibleControlViewAccess() {}
474 virtual bool isDesignMode() const;
475 virtual Reference
< XControlContainer
>
476 getControlContainer( const OutputDevice
& _rDevice
) const;
477 virtual bool isLayerVisible( SdrLayerID _nLayerID
) const;
480 //--------------------------------------------------------------------
481 bool InvisibleControlViewAccess::isDesignMode() const
486 //--------------------------------------------------------------------
487 Reference
< XControlContainer
> InvisibleControlViewAccess::getControlContainer( const OutputDevice
& _rDevice
) const
489 if ( !m_rControlContainer
.is() )
491 const Window
* pWindow
= dynamic_cast< const Window
* >( &_rDevice
);
492 OSL_ENSURE( pWindow
, "InvisibleControlViewAccess::getControlContainer: expected to be called for a window only!" );
494 m_rControlContainer
= VCLUnoHelper::CreateControlContainer( const_cast< Window
* >( pWindow
) );
496 return m_rControlContainer
;
499 //--------------------------------------------------------------------
500 bool InvisibleControlViewAccess::isLayerVisible( SdrLayerID
/*_nLayerID*/ ) const
505 //====================================================================
506 //= DummyPageViewAccess
507 //====================================================================
508 /** is a ->IPageViewAccess implementation which can be used to create a control for an arbitrary
511 The implementation will report the "PageView" as being in design mode, all layers to be visible,
512 and will not return any ControlContainer, so all control container related features (notifications etc)
515 class DummyPageViewAccess
: public IPageViewAccess
518 DummyPageViewAccess()
522 virtual ~DummyPageViewAccess() {}
524 virtual bool isDesignMode() const;
525 virtual Reference
< XControlContainer
>
526 getControlContainer( const OutputDevice
& _rDevice
) const;
527 virtual bool isLayerVisible( SdrLayerID _nLayerID
) const;
530 //--------------------------------------------------------------------
531 bool DummyPageViewAccess::isDesignMode() const
536 //--------------------------------------------------------------------
537 Reference
< XControlContainer
> DummyPageViewAccess::getControlContainer( const OutputDevice
& /*_rDevice*/ ) const
542 //--------------------------------------------------------------------
543 bool DummyPageViewAccess::isLayerVisible( SdrLayerID
/*_nLayerID*/ ) const
548 //====================================================================
549 //= ViewObjectContactOfUnoControl_Impl
550 //====================================================================
551 typedef ::cppu::WeakImplHelper4
< XWindowListener
552 , XPropertyChangeListener
554 , XModeChangeListener
555 > ViewObjectContactOfUnoControl_Impl_Base
;
557 class SVX_DLLPRIVATE ViewObjectContactOfUnoControl_Impl
: public ViewObjectContactOfUnoControl_Impl_Base
560 // fdo#41935 note that access to members is protected with SolarMutex;
561 // the class previously had its own mutex but that is prone to deadlock
563 /// the instance whose IMPL we are
564 ViewObjectContactOfUnoControl
* m_pAntiImpl
;
566 /// are we currently inside impl_ensureControl_nothrow?
567 bool m_bCreatingControl
;
569 /// the control we're responsible for
570 ControlHolder m_aControl
;
572 /// the ControlContainer where we inserted our control
573 Reference
< XContainer
> m_xContainer
;
575 /// the output device for which the control was created
576 const OutputDevice
* m_pOutputDeviceForWindow
;
578 /// flag indicating whether the control is currently visible
579 bool m_bControlIsVisible
;
581 /// are we currently listening at a design mode control?
582 bool m_bIsDesignModeListening
;
590 /// is the control currently in design mode?
591 mutable ViewControlMode m_eControlDesignMode
;
593 ::basegfx::B2DHomMatrix m_aZoomLevelNormalization
;
596 explicit ViewObjectContactOfUnoControl_Impl( ViewObjectContactOfUnoControl
* _pAntiImpl
);
598 /** disposes the instance, which is nonfunctional afterwards
602 /** determines whether the instance is disposed
604 bool isDisposed() const { return impl_isDisposed_nofail(); }
606 /** determines whether the instance is alive
608 bool isAlive() const { return !isDisposed(); }
610 /** returns the SdrUnoObject associated with the ViewContact
615 bool getUnoObject( SdrUnoObj
*& _out_rpObject
) const;
617 /** ensures that we have an ->XControl
619 Must only be called if a control is needed when no DisplayInfo is present, yet.
621 For creating a control, an ->OutputDevice is needed, and an ->SdrPageView. Both will be obtained
622 from a ->ObjectContactOfPageView. So, if our (anti-impl's) object contact is not a ->ObjectContactOfPageView,
623 this method fill fail.
625 Failure of this method will be reported via an assertion in a non-product version.
627 bool ensureControl( const basegfx::B2DHomMatrix
* _pInitialViewTransformationOrNULL
);
629 /** returns our XControl, if it already has been created
631 If you want to ensure that the control exists before accessing it, use ->ensureControl
633 inline const ControlHolder
&
634 getExistentControl() const { return m_aControl
; }
637 hasControl() const { return m_aControl
.is(); }
639 /** positions our XControl according to the geometry settings in the SdrUnoObj, modified by the given
640 transformation, and sets proper zoom settings according to our device
643 ->m_pOutputDeviceForWindow and ->m_aControl are not <NULL/>
645 void positionAndZoomControl( const basegfx::B2DHomMatrix
& _rViewTransformation
) const;
647 /** determines whether or not our control is printable
649 Effectively, this method returns the value of the "Printable" property
650 of the control's model. If we have no control, <FALSE/> is returned.
652 bool isPrintableControl() const;
654 /** sets the design mode on the control, or at least remembers the flag for the
655 time the control is created
657 void setControlDesignMode( bool _bDesignMode
) const;
659 /** determines whether our control is currently visible
662 bool isControlVisible() const { return impl_isControlVisible_nofail(); }
664 /// creates an XControl for the given device and SdrUnoObj
666 createControlForDevice(
667 IPageViewAccess
& _rPageView
,
668 const OutputDevice
& _rDevice
,
669 const SdrUnoObj
& _rUnoObject
,
670 const basegfx::B2DHomMatrix
& _rInitialViewTransformation
,
671 const basegfx::B2DHomMatrix
& _rInitialZoomNormalization
,
672 ControlHolder
& _out_rControl
675 const ViewContactOfUnoControl
&
676 getViewContact() const
678 ENSURE_OR_THROW( !impl_isDisposed_nofail(), "already disposed" );
679 return static_cast< const ViewContactOfUnoControl
& >( m_pAntiImpl
->GetViewContact() );
683 ~ViewObjectContactOfUnoControl_Impl();
686 virtual void SAL_CALL
disposing( const EventObject
& Source
) throw(RuntimeException
);
689 virtual void SAL_CALL
windowResized( const WindowEvent
& e
) throw(RuntimeException
);
690 virtual void SAL_CALL
windowMoved( const WindowEvent
& e
) throw(RuntimeException
);
691 virtual void SAL_CALL
windowShown( const EventObject
& e
) throw(RuntimeException
);
692 virtual void SAL_CALL
windowHidden( const EventObject
& e
) throw(RuntimeException
);
694 // XPropertyChangeListener
695 virtual void SAL_CALL
propertyChange( const PropertyChangeEvent
& evt
) throw(RuntimeException
);
697 // XModeChangeListener
698 virtual void SAL_CALL
modeChanged( const ModeChangeEvent
& _rSource
) throw (RuntimeException
);
700 // XContainerListener
701 virtual void SAL_CALL
elementInserted( const ::com::sun::star::container::ContainerEvent
& Event
) throw (::com::sun::star::uno::RuntimeException
);
702 virtual void SAL_CALL
elementRemoved( const ::com::sun::star::container::ContainerEvent
& Event
) throw (::com::sun::star::uno::RuntimeException
);
703 virtual void SAL_CALL
elementReplaced( const ::com::sun::star::container::ContainerEvent
& Event
) throw (::com::sun::star::uno::RuntimeException
);
706 /** retrieves the SdrPageView which our associated SdrPageViewWindow belongs to
708 @param out_rpPageView
709 a reference to a pointer holding, upon return, the desired SdrPageView
712 <TRUE/> if and only if a ->SdrPageView could be obtained
715 We really belong to an SdrPageViewWindow. Perhaps (I'm not sure ATM :)
716 there are instance for which this might not be true, but those instances
717 should never have a need to call this method.
723 The method expects success, if it returns with <FALSE/>, this will have been
728 bool impl_getPageView_nothrow( SdrPageView
*& _out_rpPageView
);
730 /** adjusts the control visibility so it respects its layer's visibility
733 set to <TRUE/> if you want to force a ->XWindow::setVisible call,
734 no matter if the control visibility is already correct
737 ->m_aControl is not <NULL/>
743 We really belong to an SdrPageViewWindow. There are instance for which this
744 might not be true, but those instances should never have a need to call
747 void impl_adjustControlVisibilityToLayerVisibility_throw( bool _bForce
);
749 /** adjusts the control visibility so it respects its layer's visibility
751 The control must never be visibile if it's in design mode.
752 In alive mode, it must be visibility if and only it's on a visible layer.
755 the control whose visibility is to be adjusted
758 provides access to the attributes of the SdrPageView which the control finally belongs to
763 @param _bIsCurrentlyVisible
764 determines whether the control is currently visible. Note that this is only a shortcut for
765 querying _rxControl for the XWindow2 interface, and calling isVisible at this interface.
766 This shortcut has been chosen since the caller usually already has this information.
767 If _bForce is <TRUE/>, _bIsCurrentlyVisible is ignored.
770 set to <TRUE/> if you want to force a ->XWindow::setVisible call,
771 no matter if the control visibility is already correct
776 static void impl_adjustControlVisibilityToLayerVisibility_throw( const ControlHolder
& _rxControl
, const SdrUnoObj
& _rUnoObject
,
777 IPageViewAccess
& _rPageView
, bool _bIsCurrentlyVisible
, bool _bForce
);
779 /** starts or stops listening at various aspects of our control
782 ->m_aControl is not <NULL/>
784 void impl_switchControlListening_nothrow( bool _bStart
);
786 /** starts or stops listening at our control container
789 ->m_xContainer is not <NULL/>
791 void impl_switchContainerListening_nothrow( bool _bStart
);
793 /** starts or stops listening at the control for design-mode relevant facets
795 void impl_switchDesignModeListening_nothrow( bool _bStart
);
797 /** starts or stops listening for all properties at our control
800 determines whether to start or to stop listening
803 ->m_aControl is not <NULL/>
805 void impl_switchPropertyListening_nothrow( bool _bStart
);
807 /** disposes the instance
808 @param _bAlsoDisposeControl
809 determines whether the XControl should be disposed, too
811 void impl_dispose_nothrow( bool _bAlsoDisposeControl
);
813 /** determines whether the instance is disposed
816 bool impl_isDisposed_nofail() const { return m_pAntiImpl
== NULL
; }
818 /** determines whether our control is currently visible
821 bool impl_isControlVisible_nofail() const { return m_bControlIsVisible
; }
823 /** determines whether we are currently a listener at the control for desgin-mode relevant facets
826 bool impl_isDesignModeListening_nofail() const { return m_bIsDesignModeListening
; }
828 /** determines whether the control currently is in design mode
831 The design mode must already be known. It is known when we first had access to
832 an SdrPageView (which carries this flag), or somebody explicitly set it from
835 inline bool impl_isControlDesignMode_nothrow() const
837 DBG_ASSERT( m_eControlDesignMode
!= eUnknown
, "ViewObjectContactOfUnoControl_Impl::impl_isControlDesignMode_nothrow: mode is still unknown!" );
838 return m_eControlDesignMode
== eDesign
;
841 /** ensures that we have a control for the given PageView/OutputDevice
843 bool impl_ensureControl_nothrow(
844 IPageViewAccess
& _rPageView
,
845 const OutputDevice
& _rDevice
,
846 const basegfx::B2DHomMatrix
& _rInitialViewTransformation
849 /** retrieves the device which a PageView belongs to, starting from its ObjectContactOfPageView
851 Since #i72752#, the PaintWindow (and thus the OutputDevice) associated with a PageView is not
852 constant over its lifetime. Instead, during some paint operations, the PaintWindow/OutputDevice
853 might be temporarily patched.
855 This method cares for this, by retrieving the very original OutputDevice.
857 static const OutputDevice
& impl_getPageViewOutputDevice_nothrow( const ObjectContactOfPageView
& _rObjectContact
);
859 const OutputDevice
& impl_getOutputDevice_throw() const;
862 ViewObjectContactOfUnoControl_Impl(); // never implemented
863 ViewObjectContactOfUnoControl_Impl( const ViewObjectContactOfUnoControl_Impl
& ); // never implemented
864 ViewObjectContactOfUnoControl_Impl
& operator=( const ViewObjectContactOfUnoControl_Impl
& ); // never implemented
867 //====================================================================
868 //= LazyControlCreationPrimitive2D
869 //====================================================================
870 class LazyControlCreationPrimitive2D
: public ::drawinglayer::primitive2d::BufferedDecompositionPrimitive2D
873 typedef ::drawinglayer::primitive2d::BufferedDecompositionPrimitive2D BufferedDecompositionPrimitive2D
;
876 virtual ::drawinglayer::primitive2d::Primitive2DSequence
878 const ::drawinglayer::geometry::ViewInformation2D
& rViewInformation
881 virtual ::drawinglayer::primitive2d::Primitive2DSequence
882 create2DDecomposition(
883 const ::drawinglayer::geometry::ViewInformation2D
& rViewInformation
886 virtual ::basegfx::B2DRange
888 const ::drawinglayer::geometry::ViewInformation2D
& rViewInformation
892 explicit LazyControlCreationPrimitive2D( const ::rtl::Reference
< ViewObjectContactOfUnoControl_Impl
>& _pVOCImpl
)
893 :m_pVOCImpl( _pVOCImpl
)
895 ENSURE_OR_THROW( m_pVOCImpl
.is(), "Illegal argument." );
896 getTransformation( m_pVOCImpl
->getViewContact(), m_aTransformation
);
899 virtual bool operator==(const BasePrimitive2D
& rPrimitive
) const;
901 // declare unique ID for this primitive class
902 DeclPrimitive2DIDBlock()
904 static void getTransformation( const ViewContactOfUnoControl
& _rVOC
, ::basegfx::B2DHomMatrix
& _out_Transformation
);
907 void impl_positionAndZoomControl( const ::drawinglayer::geometry::ViewInformation2D
& _rViewInformation
) const
909 if ( !_rViewInformation
.getViewport().isEmpty() )
910 m_pVOCImpl
->positionAndZoomControl( _rViewInformation
.getObjectToViewTransformation() );
914 ::rtl::Reference
< ViewObjectContactOfUnoControl_Impl
> m_pVOCImpl
;
915 /** The geometry is part of the identity of an primitive, so we cannot calculate it on demand
916 (since the data the calculation is based on might have changed then), but need to calc
917 it at construction time, and remember it.
919 ::basegfx::B2DHomMatrix m_aTransformation
;
922 //====================================================================
923 //= ViewObjectContactOfUnoControl_Impl
924 //====================================================================
925 DBG_NAME( ViewObjectContactOfUnoControl_Impl
)
926 //--------------------------------------------------------------------
927 ViewObjectContactOfUnoControl_Impl::ViewObjectContactOfUnoControl_Impl( ViewObjectContactOfUnoControl
* _pAntiImpl
)
928 :m_pAntiImpl( _pAntiImpl
)
929 ,m_bCreatingControl( false )
930 ,m_pOutputDeviceForWindow( NULL
)
931 ,m_bControlIsVisible( false )
932 ,m_bIsDesignModeListening( false )
933 ,m_eControlDesignMode( eUnknown
)
934 ,m_aZoomLevelNormalization()
936 DBG_CTOR( ViewObjectContactOfUnoControl_Impl
, NULL
);
937 DBG_ASSERT( m_pAntiImpl
, "ViewObjectContactOfUnoControl_Impl::ViewObjectContactOfUnoControl_Impl: invalid AntiImpl!" );
939 const OutputDevice
& rPageViewDevice( impl_getOutputDevice_throw() );
940 m_aZoomLevelNormalization
= rPageViewDevice
.GetInverseViewTransformation();
942 #if OSL_DEBUG_LEVEL > 1
943 ::basegfx::B2DVector aScale
, aTranslate
;
944 double fRotate
, fShearX
;
945 m_aZoomLevelNormalization
.decompose( aScale
, aTranslate
, fRotate
, fShearX
);
948 ::basegfx::B2DHomMatrix aScaleNormalization
;
949 MapMode
aCurrentDeviceMapMode( rPageViewDevice
.GetMapMode() );
950 aScaleNormalization
.set( 0, 0, (double)aCurrentDeviceMapMode
.GetScaleX() );
951 aScaleNormalization
.set( 1, 1, (double)aCurrentDeviceMapMode
.GetScaleY() );
952 m_aZoomLevelNormalization
*= aScaleNormalization
;
954 #if OSL_DEBUG_LEVEL > 1
955 m_aZoomLevelNormalization
.decompose( aScale
, aTranslate
, fRotate
, fShearX
);
959 //--------------------------------------------------------------------
960 ViewObjectContactOfUnoControl_Impl::~ViewObjectContactOfUnoControl_Impl()
962 if ( !impl_isDisposed_nofail() )
968 DBG_DTOR( ViewObjectContactOfUnoControl_Impl
, NULL
);
971 //--------------------------------------------------------------------
972 void ViewObjectContactOfUnoControl_Impl::impl_dispose_nothrow( bool _bAlsoDisposeControl
)
974 if ( impl_isDisposed_nofail() )
977 if ( m_aControl
.is() )
978 impl_switchControlListening_nothrow( false );
980 if ( m_xContainer
.is() )
981 impl_switchContainerListening_nothrow( false );
983 // dispose the control
984 if ( _bAlsoDisposeControl
)
985 UnoControlContactHelper::disposeAndClearControl_nothrow( m_aControl
);
988 m_xContainer
.clear();
989 m_pOutputDeviceForWindow
= NULL
;
990 m_bControlIsVisible
= false;
995 //--------------------------------------------------------------------
996 void ViewObjectContactOfUnoControl_Impl::dispose()
998 SolarMutexGuard aSolarGuard
;
999 impl_dispose_nothrow( true );
1002 //--------------------------------------------------------------------
1003 bool ViewObjectContactOfUnoControl_Impl::getUnoObject( SdrUnoObj
*& _out_rpObject
) const
1005 OSL_PRECOND( !impl_isDisposed_nofail(), "ViewObjectContactOfUnoControl_Impl::getUnoObject: already disposed()" );
1006 if ( impl_isDisposed_nofail() )
1007 _out_rpObject
= NULL
;
1010 _out_rpObject
= dynamic_cast< SdrUnoObj
* >( m_pAntiImpl
->GetViewContact().TryToGetSdrObject() );
1011 DBG_ASSERT( _out_rpObject
|| !m_pAntiImpl
->GetViewContact().TryToGetSdrObject(),
1012 "ViewObjectContactOfUnoControl_Impl::getUnoObject: invalid SdrObject!" );
1014 return ( _out_rpObject
!= NULL
);
1017 //--------------------------------------------------------------------
1018 void ViewObjectContactOfUnoControl_Impl::positionAndZoomControl( const basegfx::B2DHomMatrix
& _rViewTransformation
) const
1020 OSL_PRECOND( m_aControl
.is(), "ViewObjectContactOfUnoControl_Impl::positionAndZoomControl: no output device or no control!" );
1021 if ( !m_aControl
.is() )
1026 SdrUnoObj
* pUnoObject( NULL
);
1027 if ( getUnoObject( pUnoObject
) )
1029 Point aGridOffset
= pUnoObject
->GetGridOffset();
1030 Rectangle
aRect( pUnoObject
->GetLogicRect() );
1031 // Hack for calc, transform position of object according
1032 // to current zoom so as objects relative position to grid
1034 aRect
+= aGridOffset
;
1035 UnoControlContactHelper::adjustControlGeometry_throw( m_aControl
, aRect
, _rViewTransformation
, m_aZoomLevelNormalization
);
1038 OSL_FAIL( "ViewObjectContactOfUnoControl_Impl::positionAndZoomControl: no SdrUnoObj!" );
1040 catch( const Exception
& )
1042 DBG_UNHANDLED_EXCEPTION();
1046 //--------------------------------------------------------------------
1047 bool ViewObjectContactOfUnoControl_Impl::ensureControl( const basegfx::B2DHomMatrix
* _pInitialViewTransformationOrNULL
)
1049 OSL_PRECOND( !impl_isDisposed_nofail(), "ViewObjectContactOfUnoControl_Impl::ensureControl: already disposed()" );
1050 if ( impl_isDisposed_nofail() )
1053 ObjectContactOfPageView
* pPageViewContact
= dynamic_cast< ObjectContactOfPageView
* >( &m_pAntiImpl
->GetObjectContact() );
1054 if ( pPageViewContact
)
1056 SdrPageViewAccess
aPVAccess( pPageViewContact
->GetPageWindow().GetPageView() );
1057 const OutputDevice
& rDevice( impl_getPageViewOutputDevice_nothrow( *pPageViewContact
) );
1058 return impl_ensureControl_nothrow(
1061 _pInitialViewTransformationOrNULL
? *_pInitialViewTransformationOrNULL
: rDevice
.GetViewTransformation()
1065 DummyPageViewAccess aNoPageView
;
1066 const OutputDevice
& rDevice( impl_getOutputDevice_throw() );
1067 return impl_ensureControl_nothrow(
1070 _pInitialViewTransformationOrNULL
? *_pInitialViewTransformationOrNULL
: rDevice
.GetViewTransformation()
1074 //--------------------------------------------------------------------
1075 const OutputDevice
& ViewObjectContactOfUnoControl_Impl::impl_getOutputDevice_throw() const
1077 ObjectContactOfPageView
* pPageViewContact
= dynamic_cast< ObjectContactOfPageView
* >( &m_pAntiImpl
->GetObjectContact() );
1078 if ( pPageViewContact
)
1080 // do not use ObjectContact::TryToGetOutputDevice here, it would not care for the PageWindow's
1081 // OriginalPaintWindow
1082 return impl_getPageViewOutputDevice_nothrow( *pPageViewContact
);
1085 const OutputDevice
* pDevice
= m_pAntiImpl
->GetObjectContact().TryToGetOutputDevice();
1086 ENSURE_OR_THROW( pDevice
, "no output device -> no control" );
1090 //--------------------------------------------------------------------
1091 const OutputDevice
& ViewObjectContactOfUnoControl_Impl::impl_getPageViewOutputDevice_nothrow( const ObjectContactOfPageView
& _rObjectContact
)
1093 // if the PageWindow has a patched PaintWindow, use the original PaintWindow
1094 // this ensures that our control is _not_ re-created just because somebody
1095 // (temporarily) changed the window to paint onto.
1096 // #i72429# / 2007-02-20 / frank.schoenheit@sun.com
1097 SdrPageWindow
& rPageWindow( _rObjectContact
.GetPageWindow() );
1098 if ( rPageWindow
.GetOriginalPaintWindow() )
1099 return rPageWindow
.GetOriginalPaintWindow()->GetOutputDevice();
1101 return rPageWindow
.GetPaintWindow().GetOutputDevice();
1106 static void lcl_resetFlag( bool& rbFlag
)
1112 //--------------------------------------------------------------------
1113 bool ViewObjectContactOfUnoControl_Impl::impl_ensureControl_nothrow( IPageViewAccess
& _rPageView
, const OutputDevice
& _rDevice
,
1114 const basegfx::B2DHomMatrix
& _rInitialViewTransformation
)
1116 if ( m_bCreatingControl
)
1118 OSL_FAIL( "ViewObjectContactOfUnoControl_Impl::impl_ensureControl_nothrow: reentrance is not really good here!" );
1119 // We once had a situation where this was called reentrantly, which lead to all kind of strange effects. All
1120 // those affected the grid control, which is the only control so far which is visible in design mode (and
1121 // not only in alive mode).
1122 // Creating the control triggered an Window::Update on some of its child windows, which triggered a
1123 // Paint on parent of the grid control (e.g. the SwEditWin), which triggered a reentrant call to this method,
1124 // which it is not really prepared for.
1126 // /me thinks that re-entrance should be caught on a higher level, i.e. the Drawing Layer should not allow
1127 // reentrant paint requests. For the moment, until /me can discuss this with AW, catch it here.
1128 // 2009-08-27 / #i104544# frank.schoenheit@sun.com
1132 m_bCreatingControl
= true;
1133 ::comphelper::ScopeGuard
aGuard( ::boost::bind( lcl_resetFlag
, ::boost::ref( m_bCreatingControl
) ) );
1135 if ( m_aControl
.is() )
1137 if ( m_pOutputDeviceForWindow
== &_rDevice
)
1140 // Somebody requested a control for a new device, which means either of
1141 // - our PageView's paint window changed since we were last here
1142 // - we don't belong to a page view, and are simply painted onto different devices
1143 // The first sounds strange (doens't it?), the second means we could perhaps
1144 // optimize this in the future - there is no need to re-create the control every time,
1146 // #i74523# / 2007-02-15 / frank.schoenheit@sun.com
1147 if ( m_xContainer
.is() )
1148 impl_switchContainerListening_nothrow( false );
1149 impl_switchControlListening_nothrow( false );
1150 UnoControlContactHelper::disposeAndClearControl_nothrow( m_aControl
);
1153 SdrUnoObj
* pUnoObject( NULL
);
1154 if ( !getUnoObject( pUnoObject
) )
1157 ControlHolder aControl
;
1158 if ( !createControlForDevice( _rPageView
, _rDevice
, *pUnoObject
, _rInitialViewTransformation
, m_aZoomLevelNormalization
, aControl
) )
1161 m_pOutputDeviceForWindow
= &_rDevice
;
1162 m_aControl
= aControl
;
1163 m_xContainer
= m_xContainer
.query( _rPageView
.getControlContainer( _rDevice
) );
1164 DBG_ASSERT( ( m_xContainer
.is() // either have a XControlContainer
1165 || ( ( !_rPageView
.getControlContainer( _rDevice
).is() ) // or don't have any container,
1166 && ( dynamic_cast< const Window
* >( &_rDevice
) == NULL
) // which is allowed for non-Window instances only
1169 "ViewObjectContactOfUnoControl_Impl::impl_ensureControl_nothrow: no XContainer at the ControlContainer!" );
1173 m_eControlDesignMode
= m_aControl
.isDesignMode() ? eDesign
: eAlive
;
1174 m_bControlIsVisible
= m_aControl
.isVisible();
1176 catch( const Exception
& )
1178 DBG_UNHANDLED_EXCEPTION();
1181 // start listening at all aspects of the control which are interesting to us ...
1182 impl_switchControlListening_nothrow( true );
1184 // start listening at the control container, in case somebody tampers with our control
1185 if ( m_xContainer
.is() )
1186 impl_switchContainerListening_nothrow( true );
1188 return m_aControl
.is();
1191 //--------------------------------------------------------------------
1192 bool ViewObjectContactOfUnoControl_Impl::createControlForDevice( IPageViewAccess
& _rPageView
,
1193 const OutputDevice
& _rDevice
, const SdrUnoObj
& _rUnoObject
, const basegfx::B2DHomMatrix
& _rInitialViewTransformation
,
1194 const basegfx::B2DHomMatrix
& _rInitialZoomNormalization
, ControlHolder
& _out_rControl
)
1196 _out_rControl
.clear();
1198 Reference
< XControlModel
> xControlModel( _rUnoObject
.GetUnoControlModel() );
1199 DBG_ASSERT( xControlModel
.is(), "ViewObjectContactOfUnoControl_Impl::createControlForDevice: no control model at the SdrUnoObject!?" );
1200 if ( !xControlModel
.is() )
1203 bool bSuccess
= false;
1206 const OUString
sControlServiceName( _rUnoObject
.GetUnoControlTypeName() );
1208 Reference
< css::uno::XComponentContext
> xContext
= ::comphelper::getProcessComponentContext();
1209 _out_rControl
= Reference
<XControl
>( xContext
->getServiceManager()->createInstanceWithContext(sControlServiceName
, xContext
), UNO_QUERY_THROW
);
1211 // knit the model and the control
1212 _out_rControl
.setModel( xControlModel
);
1213 Point aGridOffset
= _rUnoObject
.GetGridOffset();
1214 Rectangle
aRect( _rUnoObject
.GetLogicRect() );
1215 // Hack for calc, transform position of object according
1216 // to current zoom so as objects relative position to grid
1218 aRect
+= aGridOffset
;
1221 UnoControlContactHelper::adjustControlGeometry_throw(
1224 _rInitialViewTransformation
,
1225 _rInitialZoomNormalization
1228 // set design mode before peer is created,
1229 // this is also needed for accessibility
1230 _out_rControl
.setDesignMode( _rPageView
.isDesignMode() );
1232 // adjust the initial visibility according to the visibility of the layer
1233 impl_adjustControlVisibilityToLayerVisibility_throw( _out_rControl
, _rUnoObject
, _rPageView
, false, true );
1235 // add the control to the respective control container
1237 Reference
< XControlContainer
> xControlContainer( _rPageView
.getControlContainer( _rDevice
) );
1238 if ( xControlContainer
.is() )
1239 xControlContainer
->addControl( sControlServiceName
, _out_rControl
.getControl() );
1243 catch( const Exception
& )
1245 DBG_UNHANDLED_EXCEPTION();
1250 // delete the control which might have been created already
1251 UnoControlContactHelper::disposeAndClearControl_nothrow( _out_rControl
);
1254 return _out_rControl
.is();
1257 //--------------------------------------------------------------------
1258 bool ViewObjectContactOfUnoControl_Impl::impl_getPageView_nothrow( SdrPageView
*& _out_rpPageView
)
1260 OSL_PRECOND( !impl_isDisposed_nofail(), "ViewObjectContactOfUnoControl_Impl::impl_getPageView_nothrow: already disposed!" );
1262 _out_rpPageView
= NULL
;
1263 if ( impl_isDisposed_nofail() )
1266 ObjectContactOfPageView
* pPageViewContact
= dynamic_cast< ObjectContactOfPageView
* >( &m_pAntiImpl
->GetObjectContact() );
1267 if ( pPageViewContact
)
1268 _out_rpPageView
= &pPageViewContact
->GetPageWindow().GetPageView();
1270 DBG_ASSERT( _out_rpPageView
!= NULL
, "ViewObjectContactOfUnoControl_Impl::impl_getPageView_nothrow: this method is expected to always have success!" );
1271 return ( _out_rpPageView
!= NULL
);
1274 //--------------------------------------------------------------------
1275 void ViewObjectContactOfUnoControl_Impl::impl_adjustControlVisibilityToLayerVisibility_throw( bool _bForce
)
1277 OSL_PRECOND( m_aControl
.is(),
1278 "ViewObjectContactOfUnoControl_Impl::impl_adjustControlVisibilityToLayerVisibility_throw: only valid if we have a control!" );
1280 SdrPageView
* pPageView( NULL
);
1281 if ( !impl_getPageView_nothrow( pPageView
) )
1284 SdrUnoObj
* pUnoObject( NULL
);
1285 if ( !getUnoObject( pUnoObject
) )
1288 SdrPageViewAccess
aPVAccess( *pPageView
);
1289 impl_adjustControlVisibilityToLayerVisibility_throw( m_aControl
, *pUnoObject
, aPVAccess
, impl_isControlVisible_nofail(), _bForce
);
1292 //--------------------------------------------------------------------
1293 void ViewObjectContactOfUnoControl_Impl::impl_adjustControlVisibilityToLayerVisibility_throw( const ControlHolder
& _rControl
,
1294 const SdrUnoObj
& _rUnoObject
, IPageViewAccess
& _rPageView
, bool _bIsCurrentlyVisible
, bool _bForce
)
1296 // in design mode, there is no problem with the visibility: The XControl is hidden by
1297 // default, and the Drawing Layer will simply not call our paint routine, if we're in
1298 // a hidden layer. So, only alive mode matters.
1299 if ( !_rControl
.isDesignMode() )
1301 // the layer of our object
1302 SdrLayerID nObjectLayer
= _rUnoObject
.GetLayer();
1303 // is the object we're residing in visible in this view?
1304 bool bIsObjectVisible
= _rUnoObject
.IsVisible() && _rPageView
.isLayerVisible( nObjectLayer
);
1306 if ( _bForce
|| ( bIsObjectVisible
!= _bIsCurrentlyVisible
) )
1308 _rControl
.setVisible( bIsObjectVisible
);
1313 //--------------------------------------------------------------------
1314 void ViewObjectContactOfUnoControl_Impl::impl_switchContainerListening_nothrow( bool _bStart
)
1316 OSL_PRECOND( m_xContainer
.is(), "ViewObjectContactOfUnoControl_Impl::impl_switchContainerListening_nothrow: no control container!" );
1317 if ( !m_xContainer
.is() )
1323 m_xContainer
->addContainerListener( this );
1325 m_xContainer
->removeContainerListener( this );
1327 catch( const Exception
& )
1329 DBG_UNHANDLED_EXCEPTION();
1333 //--------------------------------------------------------------------
1334 void ViewObjectContactOfUnoControl_Impl::impl_switchControlListening_nothrow( bool _bStart
)
1336 OSL_PRECOND( m_aControl
.is(), "ViewObjectContactOfUnoControl_Impl::impl_switchControlListening_nothrow: invalid control!" );
1337 if ( !m_aControl
.is() )
1342 // listen for visibility changes
1344 m_aControl
.addWindowListener( this );
1346 m_aControl
.removeWindowListener( this );
1348 // in design mode, listen for some more aspects
1349 impl_switchDesignModeListening_nothrow( impl_isControlDesignMode_nothrow() && _bStart
);
1351 // listen for design mode changes
1352 Reference
< XModeChangeBroadcaster
> xDesignModeChanges( m_aControl
.getControl(), UNO_QUERY_THROW
);
1354 xDesignModeChanges
->addModeChangeListener( this );
1356 xDesignModeChanges
->removeModeChangeListener( this );
1358 catch( const Exception
& )
1360 DBG_UNHANDLED_EXCEPTION();
1364 //--------------------------------------------------------------------
1365 void ViewObjectContactOfUnoControl_Impl::impl_switchDesignModeListening_nothrow( bool _bStart
)
1367 if ( impl_isDesignModeListening_nofail() != _bStart
)
1369 m_bIsDesignModeListening
= _bStart
;
1370 impl_switchPropertyListening_nothrow( _bStart
);
1374 //------------------------------------------------------------------------------
1375 void ViewObjectContactOfUnoControl_Impl::impl_switchPropertyListening_nothrow( bool _bStart
)
1377 OSL_PRECOND( m_aControl
.is(), "ViewObjectContactOfUnoControl_Impl::impl_switchPropertyListening_nothrow: no control!" );
1378 if ( !m_aControl
.is() )
1383 Reference
< XPropertySet
> xModelProperties( m_aControl
.getModel(), UNO_QUERY_THROW
);
1385 xModelProperties
->addPropertyChangeListener( OUString(), this );
1387 xModelProperties
->removePropertyChangeListener( OUString(), this );
1389 catch( const Exception
& )
1391 DBG_UNHANDLED_EXCEPTION();
1395 //--------------------------------------------------------------------
1396 bool ViewObjectContactOfUnoControl_Impl::isPrintableControl() const
1398 SdrUnoObj
* pUnoObject( NULL
);
1399 if ( !getUnoObject( pUnoObject
) )
1402 bool bIsPrintable
= false;
1405 Reference
< XPropertySet
> xModelProperties( pUnoObject
->GetUnoControlModel(), UNO_QUERY_THROW
);
1406 static const OUString
s_sPrintablePropertyName( "Printable" );
1407 OSL_VERIFY( xModelProperties
->getPropertyValue( s_sPrintablePropertyName
) >>= bIsPrintable
);
1409 catch( const Exception
& )
1411 DBG_UNHANDLED_EXCEPTION();
1413 return bIsPrintable
;
1416 //--------------------------------------------------------------------
1417 void SAL_CALL
ViewObjectContactOfUnoControl_Impl::disposing( const EventObject
& Source
) throw(RuntimeException
)
1419 SolarMutexGuard aSolarGuard
;
1420 // some code below - in particular our disposal - might trigger actions which require the
1421 // SolarMutex. In particular, in our disposal, we remove ourself as listener from the control,
1422 // which alone needs the SolarMutex. Of course this - a removeFooListener needed the SolarMutex -
1423 // is the real bug. Toolkit really is infested with solar mutex usage ... :(
1424 // #i82169# / 2007-11-14 / frank.schoenheit@sun.com
1426 if ( !m_aControl
.is() )
1429 if ( ( m_aControl
== Source
.Source
)
1430 || ( m_aControl
.getModel() == Source
.Source
)
1433 // the model or the control is dying ... hmm, not much sense in that we ourself continue
1435 impl_dispose_nothrow( false );
1439 DBG_ASSERT( Source
.Source
== m_xContainer
, "ViewObjectContactOfUnoControl_Impl::disposing: Who's this?" );
1442 //--------------------------------------------------------------------
1443 void SAL_CALL
ViewObjectContactOfUnoControl_Impl::windowResized( const WindowEvent
& /*e*/ ) throw(RuntimeException
)
1445 // not interested in
1448 //--------------------------------------------------------------------
1449 void SAL_CALL
ViewObjectContactOfUnoControl_Impl::windowMoved( const WindowEvent
& /*e*/ ) throw(RuntimeException
)
1451 // not interested in
1454 //--------------------------------------------------------------------
1455 void SAL_CALL
ViewObjectContactOfUnoControl_Impl::windowShown( const EventObject
& /*e*/ ) throw(RuntimeException
)
1457 SolarMutexGuard aSolarGuard
;
1458 m_bControlIsVisible
= true;
1461 //--------------------------------------------------------------------
1462 void SAL_CALL
ViewObjectContactOfUnoControl_Impl::windowHidden( const EventObject
& /*e*/ ) throw(RuntimeException
)
1464 SolarMutexGuard aSolarGuard
;
1465 m_bControlIsVisible
= false;
1468 //--------------------------------------------------------------------
1469 void SAL_CALL
ViewObjectContactOfUnoControl_Impl::propertyChange( const PropertyChangeEvent
& /*_rEvent*/ ) throw(RuntimeException
)
1471 SolarMutexGuard aSolarGuard
;
1472 // (re)painting might require VCL operations, which need the SolarMutex
1474 OSL_PRECOND( !impl_isDisposed_nofail(), "ViewObjectContactOfUnoControl_Impl::propertyChange: already disposed()" );
1475 if ( impl_isDisposed_nofail() )
1478 DBG_ASSERT( m_aControl
.is(), "ViewObjectContactOfUnoControl_Impl::propertyChange: " );
1479 if ( !m_aControl
.is() )
1482 // a generic property changed. If we're in design mode, we need to repaint the control
1483 if ( impl_isControlDesignMode_nothrow() )
1485 m_pAntiImpl
->propertyChange();
1489 //--------------------------------------------------------------------
1490 void SAL_CALL
ViewObjectContactOfUnoControl_Impl::modeChanged( const ModeChangeEvent
& _rSource
) throw (RuntimeException
)
1492 SolarMutexGuard aSolarGuard
;
1494 DBG_ASSERT( _rSource
.NewMode
== "design" || _rSource
.NewMode
== "alive", "ViewObjectContactOfUnoControl_Impl::modeChanged: unexpected mode!" );
1496 m_eControlDesignMode
= _rSource
.NewMode
== "design" ? eDesign
: eAlive
;
1498 impl_switchDesignModeListening_nothrow( impl_isControlDesignMode_nothrow() );
1502 // if the control is part of a invisible layer, we need to explicitly hide it in alive mode
1503 impl_adjustControlVisibilityToLayerVisibility_throw( false );
1505 catch( const Exception
& )
1507 DBG_UNHANDLED_EXCEPTION();
1511 //--------------------------------------------------------------------
1512 void SAL_CALL
ViewObjectContactOfUnoControl_Impl::elementInserted( const ContainerEvent
& /*_Event*/ ) throw (RuntimeException
)
1514 // not interested in
1517 //--------------------------------------------------------------------
1518 void SAL_CALL
ViewObjectContactOfUnoControl_Impl::elementRemoved( const ContainerEvent
& Event
) throw (RuntimeException
)
1520 SolarMutexGuard aSolarGuard
;
1521 // some code below - in particular our disposal - might trigger actions which require the
1522 // SolarMutex. In particular, in our disposal, we remove ourself as listener from the control,
1523 // which alone needs the SolarMutex. Of course this - a removeFooListener needed the SolarMutex -
1524 // is the real bug. Toolkit really is infested with solar mutex usage ... :(
1525 // #i82169# / 2007-11-14 / frank.schoenheit@sun.com
1526 DBG_ASSERT( Event
.Source
== m_xContainer
, "ViewObjectContactOfUnoControl_Impl::elementRemoved: where did this come from?" );
1528 if ( m_aControl
== Event
.Element
)
1529 impl_dispose_nothrow( false );
1532 //--------------------------------------------------------------------
1533 void SAL_CALL
ViewObjectContactOfUnoControl_Impl::elementReplaced( const ContainerEvent
& Event
) throw (RuntimeException
)
1535 SolarMutexGuard aSolarGuard
;
1536 DBG_ASSERT( Event
.Source
== m_xContainer
, "ViewObjectContactOfUnoControl_Impl::elementReplaced: where did this come from?" );
1538 if ( ! ( m_aControl
== Event
.ReplacedElement
) )
1541 Reference
< XControl
> xNewControl( Event
.Element
, UNO_QUERY
);
1542 DBG_ASSERT( xNewControl
.is(), "ViewObjectContactOfUnoControl_Impl::elementReplaced: invalid new control!" );
1543 if ( !xNewControl
.is() )
1546 ENSURE_OR_THROW( m_pOutputDeviceForWindow
, "calling this without /me having an output device should be impossible." );
1548 DBG_ASSERT( xNewControl
->getModel() == m_aControl
.getModel(), "ViewObjectContactOfUnoControl_Impl::elementReplaced: another model at the new control?" );
1549 // another model should - in the drawing layer - also imply another SdrUnoObj, which
1550 // should also result in new ViewContact, and thus in new ViewObjectContacts
1552 impl_switchControlListening_nothrow( false );
1554 ControlHolder
aNewControl( xNewControl
);
1555 aNewControl
.setZoom( m_aControl
.getZoom() );
1556 aNewControl
.setPosSize( m_aControl
.getPosSize() );
1557 aNewControl
.setDesignMode( impl_isControlDesignMode_nothrow() );
1559 m_aControl
= xNewControl
;
1560 m_bControlIsVisible
= m_aControl
.isVisible();
1562 impl_switchControlListening_nothrow( true );
1564 m_pAntiImpl
->onControlChangedOrModified( ViewObjectContactOfUnoControl::ImplAccess() );
1567 //--------------------------------------------------------------------
1568 void ViewObjectContactOfUnoControl_Impl::setControlDesignMode( bool _bDesignMode
) const
1570 if ( ( m_eControlDesignMode
!= eUnknown
) && ( _bDesignMode
== impl_isControlDesignMode_nothrow() ) )
1573 m_eControlDesignMode
= _bDesignMode
? eDesign
: eAlive
;
1575 if ( !m_aControl
.is() )
1576 // nothing to do, the setting will be respected as soon as the control
1582 m_aControl
.setDesignMode( _bDesignMode
);
1584 catch( const Exception
& )
1586 DBG_UNHANDLED_EXCEPTION();
1590 //====================================================================
1591 //= LazyControlCreationPrimitive2D
1592 //====================================================================
1593 //--------------------------------------------------------------------
1594 bool LazyControlCreationPrimitive2D::operator==(const BasePrimitive2D
& rPrimitive
) const
1596 if ( !BufferedDecompositionPrimitive2D::operator==( rPrimitive
) )
1599 const LazyControlCreationPrimitive2D
* pRHS
= dynamic_cast< const LazyControlCreationPrimitive2D
* >( &rPrimitive
);
1603 if ( m_pVOCImpl
!= pRHS
->m_pVOCImpl
)
1606 if ( m_aTransformation
!= pRHS
->m_aTransformation
)
1612 //--------------------------------------------------------------------
1613 void LazyControlCreationPrimitive2D::getTransformation( const ViewContactOfUnoControl
& _rVOC
, ::basegfx::B2DHomMatrix
& _out_Transformation
)
1615 // Do use model data directly to create the correct geometry. Do NOT
1616 // use getBoundRect()/getSnapRect() here; tese will use the sequence of
1617 // primitives themselves in the long run.
1618 Rectangle
aSdrGeoData( _rVOC
.GetSdrUnoObj().GetGeoRect() );
1619 Point aGridOffset
= _rVOC
.GetSdrUnoObj().GetGridOffset();
1620 // Hack for calc, transform position of object according
1621 // to current zoom so as objects relative position to grid
1623 aSdrGeoData
+= aGridOffset
;
1624 const basegfx::B2DRange
aRange(
1627 aSdrGeoData
.Right(),
1628 aSdrGeoData
.Bottom()
1631 _out_Transformation
.identity();
1632 _out_Transformation
.set( 0, 0, aRange
.getWidth() );
1633 _out_Transformation
.set( 1, 1, aRange
.getHeight() );
1634 _out_Transformation
.set( 0, 2, aRange
.getMinX() );
1635 _out_Transformation
.set( 1, 2, aRange
.getMinY() );
1638 //--------------------------------------------------------------------
1639 ::basegfx::B2DRange
LazyControlCreationPrimitive2D::getB2DRange( const ::drawinglayer::geometry::ViewInformation2D
& /*rViewInformation*/ ) const
1641 ::basegfx::B2DRange
aRange( 0.0, 0.0, 1.0, 1.0 );
1642 aRange
.transform( m_aTransformation
);
1646 //--------------------------------------------------------------------
1647 ::drawinglayer::primitive2d::Primitive2DSequence
LazyControlCreationPrimitive2D::get2DDecomposition( const ::drawinglayer::geometry::ViewInformation2D
& _rViewInformation
) const
1649 #if OSL_DEBUG_LEVEL > 1
1650 ::basegfx::B2DVector aScale
, aTranslate
;
1651 double fRotate
, fShearX
;
1652 _rViewInformation
.getObjectToViewTransformation().decompose( aScale
, aTranslate
, fRotate
, fShearX
);
1654 if ( m_pVOCImpl
->hasControl() )
1655 impl_positionAndZoomControl( _rViewInformation
);
1656 return BufferedDecompositionPrimitive2D::get2DDecomposition( _rViewInformation
);
1659 //--------------------------------------------------------------------
1660 ::drawinglayer::primitive2d::Primitive2DSequence
LazyControlCreationPrimitive2D::create2DDecomposition( const ::drawinglayer::geometry::ViewInformation2D
& _rViewInformation
) const
1662 #if OSL_DEBUG_LEVEL > 1
1663 ::basegfx::B2DVector aScale
, aTranslate
;
1664 double fRotate
, fShearX
;
1665 _rViewInformation
.getObjectToViewTransformation().decompose( aScale
, aTranslate
, fRotate
, fShearX
);
1667 const bool bHadControl
= m_pVOCImpl
->getExistentControl().is();
1669 // force control here to make it a VCL ChildWindow. Will be fetched
1670 // and used below by getExistentControl()
1671 m_pVOCImpl
->ensureControl( &_rViewInformation
.getObjectToViewTransformation() );
1672 impl_positionAndZoomControl( _rViewInformation
);
1675 const ViewContactOfUnoControl
& rViewContactOfUnoControl( m_pVOCImpl
->getViewContact() );
1676 Reference
< XControlModel
> xControlModel( rViewContactOfUnoControl
.GetSdrUnoObj().GetUnoControlModel() );
1677 const ControlHolder
& rControl( m_pVOCImpl
->getExistentControl() );
1679 if ( !bHadControl
&& rControl
.is() && rControl
.isVisible() )
1680 rControl
.invalidate();
1682 if ( !bHadControl
&& rControl
.is() && rControl
.isVisible() )
1683 rControl
.invalidate();
1685 // check if we already have an XControl.
1686 if ( !xControlModel
.is() || !rControl
.is() )
1687 // use the default mechanism. This will create a ControlPrimitive2D without
1688 // handing over a XControl. If not even a XControlModel exists, it will
1689 // create the SdrObject fallback visualisation
1690 return rViewContactOfUnoControl
.getViewIndependentPrimitive2DSequence();
1692 // create a primitive and hand over the existing xControl. This will
1693 // allow the primitive to not need to create another one on demand.
1694 const drawinglayer::primitive2d::Primitive2DReference
xRetval( new ::drawinglayer::primitive2d::ControlPrimitive2D(
1695 m_aTransformation
, xControlModel
, rControl
.getControl() ) );
1697 return drawinglayer::primitive2d::Primitive2DSequence(&xRetval
, 1);
1700 //--------------------------------------------------------------------
1701 ImplPrimitive2DIDBlock( LazyControlCreationPrimitive2D
, PRIMITIVE2D_ID_SDRCONTROLPRIMITIVE2D
)
1703 //====================================================================
1704 //= ViewObjectContactOfUnoControl
1705 //====================================================================
1706 DBG_NAME( ViewObjectContactOfUnoControl
)
1707 //--------------------------------------------------------------------
1708 ViewObjectContactOfUnoControl::ViewObjectContactOfUnoControl( ObjectContact
& _rObjectContact
, ViewContactOfUnoControl
& _rViewContact
)
1709 :ViewObjectContactOfSdrObj( _rObjectContact
, _rViewContact
)
1710 ,m_pImpl( new ViewObjectContactOfUnoControl_Impl( this ) )
1712 DBG_CTOR( ViewObjectContactOfUnoControl
, NULL
);
1715 //--------------------------------------------------------------------
1716 ViewObjectContactOfUnoControl::~ViewObjectContactOfUnoControl()
1721 DBG_DTOR( ViewObjectContactOfUnoControl
, NULL
);
1724 //--------------------------------------------------------------------
1725 Reference
< XControl
> ViewObjectContactOfUnoControl::getControl()
1727 SolarMutexGuard aSolarGuard
;
1728 m_pImpl
->ensureControl( NULL
);
1729 return m_pImpl
->getExistentControl().getControl();
1732 //--------------------------------------------------------------------
1733 Reference
< XControl
> ViewObjectContactOfUnoControl::getTemporaryControlForWindow(
1734 const Window
& _rWindow
, Reference
< XControlContainer
>& _inout_ControlContainer
, const SdrUnoObj
& _rUnoObject
)
1736 ControlHolder aControl
;
1738 InvisibleControlViewAccess
aSimulatePageView( _inout_ControlContainer
);
1739 OSL_VERIFY( ViewObjectContactOfUnoControl_Impl::createControlForDevice( aSimulatePageView
, _rWindow
, _rUnoObject
,
1740 _rWindow
.GetViewTransformation(), _rWindow
.GetInverseViewTransformation(), aControl
) );
1741 return aControl
.getControl();
1744 //--------------------------------------------------------------------
1745 void ViewObjectContactOfUnoControl::ensureControlVisibility( bool _bVisible
) const
1747 SolarMutexGuard aSolarGuard
;
1751 const ControlHolder
& rControl( m_pImpl
->getExistentControl() );
1752 if ( !rControl
.is() )
1755 // only need to care for alive mode
1756 if ( rControl
.isDesignMode() )
1759 // is the visibility correct?
1760 if ( m_pImpl
->isControlVisible() == _bVisible
)
1764 rControl
.setVisible( _bVisible
);
1765 DBG_ASSERT( m_pImpl
->isControlVisible() == _bVisible
, "ViewObjectContactOfUnoControl::ensureControlVisibility: this didn't work!" );
1766 // now this would mean that either isControlVisible is not reliable,
1767 // or that showing/hiding the window did not work as intended.
1769 catch( const Exception
& )
1771 DBG_UNHANDLED_EXCEPTION();
1775 //--------------------------------------------------------------------
1776 void ViewObjectContactOfUnoControl::setControlDesignMode( bool _bDesignMode
) const
1778 SolarMutexGuard aSolarGuard
;
1779 m_pImpl
->setControlDesignMode( _bDesignMode
);
1783 // when live mode is switched on, a refresh is needed. The edit mode visualisation
1784 // needs to be repainted and the now used VCL-Window needs to be positioned and
1785 // sized. Both is done from the repant refresh.
1786 const_cast< ViewObjectContactOfUnoControl
* >(this)->ActionChanged();
1790 //--------------------------------------------------------------------
1791 drawinglayer::primitive2d::Primitive2DSequence
ViewObjectContactOfUnoControl::createPrimitive2DSequence(const DisplayInfo
& /*rDisplayInfo*/) const
1793 if ( m_pImpl
->isDisposed() )
1794 // our control already died.
1795 // TODO: Is it worth re-creating the control? Finally, this is a pathological situation, it means some instance
1796 // disposed the control though it doesn't own it. So, /me thinks we should not bother here.
1797 return drawinglayer::primitive2d::Primitive2DSequence();
1799 if ( GetObjectContact().getViewInformation2D().getViewTransformation().isIdentity() )
1800 // remove this when #i115754# is fixed
1801 return drawinglayer::primitive2d::Primitive2DSequence();
1803 // ignore existing controls which are in alive mode and manually switched to "invisible"
1804 // #102090# / 2009-06-05 / frank.schoenheit@sun.com
1805 const ControlHolder
& rControl( m_pImpl
->getExistentControl() );
1806 if ( rControl
.is() && !rControl
.isDesignMode() && !rControl
.isVisible() )
1807 return drawinglayer::primitive2d::Primitive2DSequence();
1809 ::drawinglayer::primitive2d::Primitive2DReference
xPrimitive( new LazyControlCreationPrimitive2D( m_pImpl
) );
1810 return ::drawinglayer::primitive2d::Primitive2DSequence( &xPrimitive
, 1 );
1813 //--------------------------------------------------------------------
1814 bool ViewObjectContactOfUnoControl::isPrimitiveVisible( const DisplayInfo
& _rDisplayInfo
) const
1816 SolarMutexGuard aSolarGuard
;
1818 if ( m_pImpl
->hasControl() )
1820 const ::drawinglayer::geometry::ViewInformation2D
& rViewInformation( GetObjectContact().getViewInformation2D() );
1821 #if OSL_DEBUG_LEVEL > 1
1822 ::basegfx::B2DVector aScale
, aTranslate
;
1823 double fRotate
, fShearX
;
1824 rViewInformation
.getObjectToViewTransformation().decompose( aScale
, aTranslate
, fRotate
, fShearX
);
1827 if ( !rViewInformation
.getViewport().isEmpty() )
1828 m_pImpl
->positionAndZoomControl( rViewInformation
.getObjectToViewTransformation() );
1831 return ViewObjectContactOfSdrObj::isPrimitiveVisible( _rDisplayInfo
);
1834 //--------------------------------------------------------------------
1835 void ViewObjectContactOfUnoControl::propertyChange()
1837 impl_onControlChangedOrModified();
1840 //--------------------------------------------------------------------
1841 void ViewObjectContactOfUnoControl::ActionChanged()
1844 ViewObjectContactOfSdrObj::ActionChanged();
1845 const ControlHolder
& rControl(m_pImpl
->getExistentControl());
1847 if(rControl
.is() && !rControl
.isDesignMode())
1849 // #i93180# if layer visibility has changed and control is in live mode, it is necessary
1850 // to correct visibility to make those control vanish on SdrObject LayerID changes
1851 const SdrPageView
* pSdrPageView
= GetObjectContact().TryToGetSdrPageView();
1855 const SdrObject
& rObject
= getSdrObject();
1856 const bool bIsLayerVisible( rObject
.IsVisible() && pSdrPageView
->GetVisibleLayers().IsSet(rObject
.GetLayer()));
1858 if(rControl
.isVisible() != bIsLayerVisible
)
1860 rControl
.setVisible(bIsLayerVisible
);
1866 //--------------------------------------------------------------------
1867 void ViewObjectContactOfUnoControl::impl_onControlChangedOrModified()
1869 // graphical invalidate at all views
1872 // #i93318# flush Primitive2DSequence to force recreation with updated XControlModel
1873 // since e.g. background color has changed and existing decompositions are possibly no
1874 // longer valid. Unfortunately this is not detected from ControlPrimitive2D::operator==
1875 // since it only has a uno reference to the XControlModel
1876 flushPrimitive2DSequence();
1879 //====================================================================
1880 //= UnoControlPrintOrPreviewContact
1881 //====================================================================
1882 DBG_NAME( UnoControlPrintOrPreviewContact
)
1883 //--------------------------------------------------------------------
1884 UnoControlPrintOrPreviewContact::UnoControlPrintOrPreviewContact( ObjectContactOfPageView
& _rObjectContact
, ViewContactOfUnoControl
& _rViewContact
)
1885 :ViewObjectContactOfUnoControl( _rObjectContact
, _rViewContact
)
1887 DBG_CTOR( UnoControlPrintOrPreviewContact
, NULL
);
1890 //--------------------------------------------------------------------
1891 UnoControlPrintOrPreviewContact::~UnoControlPrintOrPreviewContact()
1893 DBG_DTOR( UnoControlPrintOrPreviewContact
, NULL
);
1896 //--------------------------------------------------------------------
1897 drawinglayer::primitive2d::Primitive2DSequence
UnoControlPrintOrPreviewContact::createPrimitive2DSequence(const DisplayInfo
& rDisplayInfo
) const
1899 if ( !m_pImpl
->isPrintableControl() )
1900 return drawinglayer::primitive2d::Primitive2DSequence();
1901 return ViewObjectContactOfUnoControl::createPrimitive2DSequence( rDisplayInfo
);
1904 //........................................................................
1905 } } // namespace sdr::contact
1906 //........................................................................
1908 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */