Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include <svx/sdr/contact/viewobjectcontactofunocontrol.hxx>
31 : : #include <svx/sdr/contact/viewcontactofunocontrol.hxx>
32 : : #include <svx/sdr/contact/displayinfo.hxx>
33 : : #include <svx/sdr/properties/properties.hxx>
34 : : #include <svx/sdr/contact/objectcontactofpageview.hxx>
35 : : #include <svx/sdr/primitive2d/svx_primitivetypes2d.hxx>
36 : : #include <svx/svdouno.hxx>
37 : : #include <svx/svdpagv.hxx>
38 : : #include <svx/svdview.hxx>
39 : : #include <svx/sdrpagewindow.hxx>
40 : : #include "svx/sdrpaintwindow.hxx"
41 : :
42 : : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
43 : : #include <com/sun/star/awt/XControl.hpp>
44 : : #include <com/sun/star/awt/XControlModel.hpp>
45 : : #include <com/sun/star/awt/XControlContainer.hpp>
46 : : #include <com/sun/star/awt/XWindow2.hpp>
47 : : #include <com/sun/star/awt/PosSize.hpp>
48 : : #include <com/sun/star/awt/XView.hpp>
49 : : #include <com/sun/star/beans/XPropertySet.hpp>
50 : : #include <com/sun/star/lang/XComponent.hpp>
51 : : #include <com/sun/star/awt/InvalidateStyle.hpp>
52 : : #include <com/sun/star/util/XModeChangeListener.hpp>
53 : : #include <com/sun/star/util/XModeChangeBroadcaster.hpp>
54 : : #include <com/sun/star/container/XContainerListener.hpp>
55 : : #include <com/sun/star/container/XContainer.hpp>
56 : :
57 : : #include <vcl/svapp.hxx>
58 : : #include <osl/mutex.hxx>
59 : : #include <comphelper/processfactory.hxx>
60 : : #include <comphelper/scopeguard.hxx>
61 : : #include <cppuhelper/implbase4.hxx>
62 : : #include <toolkit/helper/vclunohelper.hxx>
63 : : #include <tools/diagnose_ex.h>
64 : : #include <basegfx/matrix/b2dhommatrix.hxx>
65 : : #include <drawinglayer/primitive2d/controlprimitive2d.hxx>
66 : :
67 : : #include <boost/bind.hpp>
68 : :
69 : : /*
70 : :
71 : : Form controls (more precise: UNO Controls) in the drawing layer are ... prone to breakage, since they have some
72 : : specialities which the drawing layer currently doesn't capture too well. In particular, having a living VCL
73 : : window as child of the document window, and coupling this Window to a drawing layer object, makes things
74 : : difficult sometimes.
75 : :
76 : : Below is a list of issues which existed in the past. Whenever you change code here, you're encouraged to
77 : : verify those issues are still fixed. (Whenever you have some additional time, you're encouraged to write
78 : : an automatic test for one or more of those issues for which this is possible :)
79 : :
80 : : http://www.openoffice.org/issues/show_bug.cgi?id=105992
81 : : zooming documents containg (alive) form controls improperly positions the controls
82 : :
83 : : http://www.openoffice.org/issues/show_bug.cgi?id=104362
84 : : crash when copy a control
85 : :
86 : : http://www.openoffice.org/issues/show_bug.cgi?id=104544
87 : : Gridcontrol duplicated after design view on/off
88 : :
89 : : http://www.openoffice.org/issues/show_bug.cgi?id=102089
90 : : print preview shows control elements with property printable=false
91 : :
92 : : http://www.openoffice.org/issues/show_bug.cgi?id=102090
93 : : problem with setVisible on TextControl
94 : :
95 : : http://www.openoffice.org/issues/show_bug.cgi?id=103138
96 : : loop when insert a control in draw
97 : :
98 : : http://www.openoffice.org/issues/show_bug.cgi?id=101398
99 : : initially-displaying a document with many controls is very slow
100 : :
101 : : http://www.openoffice.org/issues/show_bug.cgi?id=72429
102 : : repaint error in form wizard in bugdoc database
103 : :
104 : : http://www.openoffice.org/issues/show_bug.cgi?id=72694
105 : : form control artifacts when scrolling a text fast
106 : :
107 : :
108 : : issues in the old (Sun-internal) bug tracking system:
109 : :
110 : : #110592#
111 : : form controls being in redlining or in hidden section are visible in alive-mode
112 : :
113 : : */
114 : :
115 : : //........................................................................
116 : : namespace sdr { namespace contact {
117 : : //........................................................................
118 : :
119 : : /** === begin UNO using === **/
120 : : using namespace ::com::sun::star::awt::InvalidateStyle;
121 : : using ::com::sun::star::uno::Reference;
122 : : using ::com::sun::star::uno::XInterface;
123 : : using ::com::sun::star::uno::UNO_QUERY;
124 : : using ::com::sun::star::uno::UNO_QUERY_THROW;
125 : : using ::com::sun::star::uno::UNO_SET_THROW;
126 : : using ::com::sun::star::uno::Exception;
127 : : using ::com::sun::star::uno::RuntimeException;
128 : : using ::com::sun::star::awt::XControl;
129 : : using ::com::sun::star::lang::XMultiServiceFactory;
130 : : using ::com::sun::star::awt::XControlModel;
131 : : using ::com::sun::star::awt::XControlContainer;
132 : : using ::com::sun::star::awt::XWindow;
133 : : using ::com::sun::star::awt::XWindow2;
134 : : using ::com::sun::star::awt::XWindowListener;
135 : : using ::com::sun::star::awt::PosSize::POSSIZE;
136 : : using ::com::sun::star::awt::XView;
137 : : using ::com::sun::star::awt::XGraphics;
138 : : using ::com::sun::star::awt::WindowEvent;
139 : : using ::com::sun::star::beans::XPropertySet;
140 : : using ::com::sun::star::beans::XPropertySetInfo;
141 : : using ::com::sun::star::lang::XComponent;
142 : : using ::com::sun::star::awt::XWindowPeer;
143 : : using ::com::sun::star::beans::XPropertyChangeListener;
144 : : using ::com::sun::star::util::XModeChangeListener;
145 : : using ::com::sun::star::util::XModeChangeBroadcaster;
146 : : using ::com::sun::star::util::ModeChangeEvent;
147 : : using ::com::sun::star::lang::EventObject;
148 : : using ::com::sun::star::beans::PropertyChangeEvent;
149 : : using ::com::sun::star::lang::XComponent;
150 : : using ::com::sun::star::container::XContainerListener;
151 : : using ::com::sun::star::container::XContainer;
152 : : using ::com::sun::star::container::ContainerEvent;
153 : : using ::com::sun::star::uno::Any;
154 : : /** === end UNO using === **/
155 : :
156 : : //====================================================================
157 : : //= ControlHolder
158 : : //====================================================================
159 : 1343 : class ControlHolder
160 : : {
161 : : private:
162 : : Reference< XControl > m_xControl;
163 : : Reference< XWindow2 > m_xControlWindow;
164 : : Reference< XView > m_xControlView;
165 : :
166 : : public:
167 : 996 : ControlHolder()
168 : : :m_xControl()
169 : : ,m_xControlWindow()
170 : 996 : ,m_xControlView()
171 : : {
172 : 996 : }
173 : :
174 : 0 : explicit ControlHolder( const Reference< XControl >& _rxControl )
175 : : :m_xControl()
176 : : ,m_xControlWindow()
177 : 0 : ,m_xControlView()
178 : : {
179 [ # # ]: 0 : *this = _rxControl;
180 : 0 : }
181 : :
182 : 350 : ControlHolder& operator=( const Reference< XControl >& _rxControl )
183 : : {
184 : 350 : clear();
185 : :
186 : 350 : m_xControl = _rxControl;
187 [ + - ]: 350 : if ( m_xControl.is() )
188 : : {
189 : 350 : m_xControlWindow.set( m_xControl, UNO_QUERY );
190 : 350 : m_xControlView.set( m_xControl, UNO_QUERY );
191 [ - + ][ - + ]: 350 : if ( !m_xControlWindow.is() || !m_xControlView.is() )
[ + - ]
192 : : {
193 : : OSL_FAIL( "ControlHolder::operator=: invalid XControl, missing required interfaces!" );
194 : 0 : clear();
195 : : }
196 : : }
197 : :
198 : 350 : return *this;
199 : : }
200 : :
201 : : public:
202 [ + + ][ + - ]: 121761 : inline bool is() const { return m_xControl.is() && m_xControlWindow.is() && m_xControlView.is(); }
[ + - ]
203 : 1932 : inline void clear() { m_xControl.clear(); m_xControlWindow.clear(); m_xControlView.clear(); }
204 : :
205 : : // delegators for the methods of the UNO interfaces
206 : : // Note all those will crash if called for a NULL object.
207 : 21138 : inline bool isDesignMode() const { return m_xControl->isDesignMode(); }
208 : 356 : inline void setDesignMode( const bool _bDesign ) const { m_xControl->setDesignMode( _bDesign ); }
209 : 1173 : inline bool isVisible() const { return m_xControlWindow->isVisible(); }
210 : 19 : inline void setVisible( const bool _bVisible ) const { m_xControlWindow->setVisible( _bVisible ); }
211 : : inline Reference< XControlModel >
212 : 808 : getModel() const { return m_xControl->getModel(); }
213 : 350 : inline void setModel( const Reference< XControlModel >& _m ) const { m_xControl->setModel( _m ); }
214 : : inline bool isTransparent() const { return m_xControl->isTransparent(); }
215 : : inline Reference< XWindowPeer >
216 : : getPeer() const { return m_xControl->getPeer(); }
217 : :
218 : 350 : inline void addWindowListener( const Reference< XWindowListener >& _l ) const { m_xControlWindow->addWindowListener( _l ); }
219 : 347 : inline void removeWindowListener( const Reference< XWindowListener >& _l ) const { m_xControlWindow->removeWindowListener( _l ); }
220 : : void setPosSize( const Rectangle& _rPosSize ) const;
221 : : Rectangle
222 : : getPosSize() const;
223 : : void setZoom( const ::basegfx::B2DVector& _rScale ) const;
224 : : ::basegfx::B2DVector
225 : : getZoom() const;
226 : :
227 : : inline void setGraphics( const Reference< XGraphics >& _g ) const { m_xControlView->setGraphics( _g ); }
228 : : inline Reference< XGraphics >
229 : : getGraphics() const { return m_xControlView->getGraphics(); }
230 : : inline void draw( const Point& _rTopLeft ) const { m_xControlView->draw( _rTopLeft.X(), _rTopLeft.Y() ); }
231 : :
232 : : void invalidate() const;
233 : :
234 : : public:
235 : 5279 : inline const Reference< XControl >& getControl() const { return m_xControl; }
236 : : };
237 : :
238 : : //--------------------------------------------------------------------
239 : 164 : bool operator==( const ControlHolder& _rControl, const Reference< XInterface >& _rxCompare )
240 : : {
241 : 164 : return _rControl.getControl() == _rxCompare;
242 : : }
243 : :
244 : : //--------------------------------------------------------------------
245 : 0 : bool operator==( const Reference< XInterface >& _rxCompare, const ControlHolder& _rControl )
246 : : {
247 : 0 : return _rxCompare == _rControl.getControl();
248 : : }
249 : :
250 : : //--------------------------------------------------------------------
251 : 136 : bool operator==( const ControlHolder& _rControl, const Any& _rxCompare )
252 : : {
253 [ + - ]: 136 : return _rControl == Reference< XInterface >( _rxCompare, UNO_QUERY );
254 : : }
255 : :
256 : : //--------------------------------------------------------------------
257 : 0 : bool operator==( const Any& _rxCompare, const ControlHolder& _rControl )
258 : : {
259 [ # # ]: 0 : return Reference< XInterface >( _rxCompare, UNO_QUERY ) == _rControl;
260 : : }
261 : :
262 : : //--------------------------------------------------------------------
263 : 19938 : void ControlHolder::setPosSize( const Rectangle& _rPosSize ) const
264 : : {
265 : : // no check whether we're valid, this is the responsibility of the caller
266 : :
267 : : // don't call setPosSize when pos/size did not change
268 : : // #i104181# / 2009-08-18 / frank.schoenheit@sun.com
269 [ + - ]: 19938 : ::Rectangle aCurrentRect( getPosSize() );
270 [ + - ][ + + ]: 19938 : if ( aCurrentRect != _rPosSize )
271 : : {
272 [ + - ]: 413 : m_xControlWindow->setPosSize(
273 : : _rPosSize.Left(), _rPosSize.Top(), _rPosSize.GetWidth(), _rPosSize.GetHeight(),
274 : : POSSIZE
275 [ + - ][ + - ]: 413 : );
[ + - ]
276 : : }
277 : 19938 : }
278 : :
279 : : //--------------------------------------------------------------------
280 : 19938 : ::Rectangle ControlHolder::getPosSize() const
281 : : {
282 : : // no check whether we're valid, this is the responsibility of the caller
283 [ + - ]: 19938 : return VCLUnoHelper::ConvertToVCLRect( m_xControlWindow->getPosSize() );
284 : : }
285 : :
286 : : //--------------------------------------------------------------------
287 : 19938 : void ControlHolder::setZoom( const ::basegfx::B2DVector& _rScale ) const
288 : : {
289 : : // no check whether we're valid, this is the responsibility of the caller
290 : 19938 : m_xControlView->setZoom( (float)_rScale.getX(), (float)_rScale.getY() );
291 : 19938 : }
292 : :
293 : : //--------------------------------------------------------------------
294 : 102 : void ControlHolder::invalidate() const
295 : : {
296 [ + - ][ + - ]: 102 : Reference< XWindowPeer > xPeer( m_xControl->getPeer() );
297 [ + + ]: 102 : if ( xPeer.is() )
298 : : {
299 [ + - ]: 78 : Window* pWindow = VCLUnoHelper::GetWindow( xPeer );
300 : : OSL_ENSURE( pWindow, "ControlHolder::invalidate: no implementation access!" );
301 [ + - ]: 78 : if ( pWindow )
302 [ + - ]: 78 : pWindow->Invalidate();
303 : 102 : }
304 : 102 : }
305 : :
306 : : //--------------------------------------------------------------------
307 : 0 : ::basegfx::B2DVector ControlHolder::getZoom() const
308 : : {
309 : : // no check whether we're valid, this is the responsibility of the caller
310 : :
311 : : // Argh. Why does XView have a setZoom only, but not a getZoom?
312 [ # # ]: 0 : Window* pWindow = VCLUnoHelper::GetWindow( m_xControl->getPeer() );
313 : : OSL_ENSURE( pWindow, "ControlHolder::getZoom: no implementation access!" );
314 : :
315 : 0 : ::basegfx::B2DVector aZoom( 1, 1 );
316 [ # # ]: 0 : if ( pWindow )
317 : : {
318 [ # # ]: 0 : const Fraction& rZoom( pWindow->GetZoom() );
319 [ # # ]: 0 : aZoom.setX( (double)rZoom );
320 [ # # ]: 0 : aZoom.setY( (double)rZoom );
321 : : }
322 : 0 : return aZoom;
323 : : }
324 : :
325 : : //====================================================================
326 : : //= UnoControlContactHelper
327 : : //====================================================================
328 : : class UnoControlContactHelper
329 : : {
330 : : public:
331 : : /** positions a control, and sets its zoom mode, using a given transformation and output device
332 : : */
333 : : static void adjustControlGeometry_throw(
334 : : const ControlHolder& _rControl,
335 : : const Rectangle& _rLogicBoundingRect,
336 : : const ::basegfx::B2DHomMatrix& _rViewTransformation,
337 : : const ::basegfx::B2DHomMatrix& _rZoomLevelNormalization
338 : : );
339 : :
340 : : /** disposes the given control
341 : : */
342 : : static void disposeAndClearControl_nothrow(
343 : : ControlHolder& _rControl
344 : : );
345 : :
346 : : private:
347 : : UnoControlContactHelper(); // never implemented
348 : : UnoControlContactHelper( const UnoControlContactHelper& ); // never implemented
349 : : UnoControlContactHelper& operator=( const UnoControlContactHelper& ); // never implemented
350 : : };
351 : :
352 : : //--------------------------------------------------------------------
353 : 19938 : void UnoControlContactHelper::adjustControlGeometry_throw( const ControlHolder& _rControl, const Rectangle& _rLogicBoundingRect,
354 : : const basegfx::B2DHomMatrix& _rViewTransformation, const ::basegfx::B2DHomMatrix& _rZoomLevelNormalization )
355 : : {
356 : : OSL_PRECOND( _rControl.is(), "UnoControlContactHelper::adjustControlGeometry_throw: illegal control!" );
357 [ + - ]: 19938 : if ( !_rControl.is() )
358 : 19938 : return;
359 : :
360 : : #if OSL_DEBUG_LEVEL > 0
361 : : ::basegfx::B2DTuple aViewScale, aViewTranslate;
362 : : double nViewRotate(0), nViewShearX(0);
363 : : _rViewTransformation.decompose( aViewScale, aViewTranslate, nViewRotate, nViewShearX );
364 : :
365 : : ::basegfx::B2DTuple aZoomScale, aZoomTranslate;
366 : : double nZoomRotate(0), nZoomShearX(0);
367 : : _rZoomLevelNormalization.decompose( aZoomScale, aZoomTranslate, nZoomRotate, nZoomShearX );
368 : : #endif
369 : :
370 : : // transform the logic bound rect, using the view transformation, to pixel coordinates
371 : 19938 : ::basegfx::B2DPoint aTopLeft( _rLogicBoundingRect.Left(), _rLogicBoundingRect.Top() );
372 [ + - ]: 19938 : aTopLeft *= _rViewTransformation;
373 : 19938 : ::basegfx::B2DPoint aBottomRight( _rLogicBoundingRect.Right(), _rLogicBoundingRect.Bottom() );
374 [ + - ]: 19938 : aBottomRight *= _rViewTransformation;
375 : :
376 [ + - ]: 19938 : const Rectangle aPaintRectPixel( (long)aTopLeft.getX(), (long)aTopLeft.getY(), (long)aBottomRight.getX(), (long)aBottomRight.getY() );
377 [ + - ]: 19938 : _rControl.setPosSize( aPaintRectPixel );
378 : :
379 : : // determine the scale from the current view transformation, and the normalization matrix
380 [ + - ]: 19938 : ::basegfx::B2DHomMatrix aObtainResolutionDependentScale( _rViewTransformation * _rZoomLevelNormalization );
381 : 19938 : ::basegfx::B2DVector aScale, aTranslate;
382 : : double fRotate, fShearX;
383 [ + - ]: 19938 : aObtainResolutionDependentScale.decompose( aScale, aTranslate, fRotate, fShearX );
384 [ + - ][ + - ]: 19938 : _rControl.setZoom( aScale );
385 : : }
386 : :
387 : : //--------------------------------------------------------------------
388 : 589 : void UnoControlContactHelper::disposeAndClearControl_nothrow( ControlHolder& _rControl )
389 : : {
390 : : try
391 : : {
392 [ + - ]: 589 : Reference< XComponent > xControlComp( _rControl.getControl(), UNO_QUERY );
393 [ + + ]: 589 : if ( xControlComp.is() )
394 [ + - ][ + - ]: 589 : xControlComp->dispose();
[ # # ]
395 : : }
396 : 0 : catch( const Exception& )
397 : : {
398 : : DBG_UNHANDLED_EXCEPTION();
399 : : }
400 : 589 : _rControl.clear();
401 : 589 : }
402 : :
403 : : //====================================================================
404 : : //= IPageViewAccess
405 : : //====================================================================
406 : : /** interface encapsulating access to an SdrPageView, stripped down to the methods we really need
407 : : */
408 : 3772 : class IPageViewAccess
409 : : {
410 : : public:
411 : : /** determines whether the view is currently in design mode
412 : : */
413 : : virtual bool isDesignMode() const = 0;
414 : :
415 : : /** retrieves the control container for a given output device
416 : : */
417 : : virtual Reference< XControlContainer >
418 : : getControlContainer( const OutputDevice& _rDevice ) const = 0;
419 : :
420 : : /** determines whether a given layer is visible
421 : : */
422 : : virtual bool isLayerVisible( SdrLayerID _nLayerID ) const = 0;
423 : :
424 : : protected:
425 : 3772 : ~IPageViewAccess() {}
426 : : };
427 : :
428 : : //====================================================================
429 : : //= SdrPageViewAccess
430 : : //====================================================================
431 : : /** is a ->IPageViewAccess implementation based on a real ->SdrPageView instance
432 : : */
433 : : class SdrPageViewAccess : public IPageViewAccess
434 : : {
435 : : const SdrPageView& m_rPageView;
436 : : public:
437 : 3769 : explicit SdrPageViewAccess( const SdrPageView& _rPageView ) : m_rPageView( _rPageView ) { }
438 : :
439 [ - + ]: 3769 : virtual ~SdrPageViewAccess() {}
440 : :
441 : : virtual bool isDesignMode() const;
442 : : virtual Reference< XControlContainer >
443 : : getControlContainer( const OutputDevice& _rDevice ) const;
444 : : virtual bool isLayerVisible( SdrLayerID _nLayerID ) const;
445 : : };
446 : :
447 : : //--------------------------------------------------------------------
448 : 347 : bool SdrPageViewAccess::isDesignMode() const
449 : : {
450 : 347 : return m_rPageView.GetView().IsDesignMode();
451 : : }
452 : :
453 : : //--------------------------------------------------------------------
454 : 694 : Reference< XControlContainer > SdrPageViewAccess::getControlContainer( const OutputDevice& _rDevice ) const
455 : : {
456 : 694 : Reference< XControlContainer > xControlContainer = m_rPageView.GetControlContainer( _rDevice );
457 : : DBG_ASSERT( xControlContainer.is() || NULL == m_rPageView.FindPageWindow( ( const_cast< OutputDevice& >( _rDevice ) ) ),
458 : : "SdrPageViewAccess::getControlContainer: the output device is known, but there is no control container for it?" );
459 : 694 : return xControlContainer;
460 : : }
461 : :
462 : : //--------------------------------------------------------------------
463 : 85 : bool SdrPageViewAccess::isLayerVisible( SdrLayerID _nLayerID ) const
464 : : {
465 : 85 : return m_rPageView.GetVisibleLayers().IsSet( _nLayerID );
466 : : }
467 : :
468 : : //====================================================================
469 : : //= InvisibleControlViewAccess
470 : : //====================================================================
471 : : /** is a ->IPageViewAccess implementation which can be used to create an invisble control for
472 : : an arbitrary window
473 : : */
474 : : class InvisibleControlViewAccess : public IPageViewAccess
475 : : {
476 : : private:
477 : : Reference< XControlContainer >& m_rControlContainer;
478 : : public:
479 : 0 : explicit InvisibleControlViewAccess( Reference< XControlContainer >& _inout_ControlContainer )
480 : 0 : :m_rControlContainer( _inout_ControlContainer )
481 : : {
482 : 0 : }
483 : :
484 [ # # ]: 0 : virtual ~InvisibleControlViewAccess() {}
485 : :
486 : : virtual bool isDesignMode() const;
487 : : virtual Reference< XControlContainer >
488 : : getControlContainer( const OutputDevice& _rDevice ) const;
489 : : virtual bool isLayerVisible( SdrLayerID _nLayerID ) const;
490 : : };
491 : :
492 : : //--------------------------------------------------------------------
493 : 0 : bool InvisibleControlViewAccess::isDesignMode() const
494 : : {
495 : 0 : return true;
496 : : }
497 : :
498 : : //--------------------------------------------------------------------
499 : 0 : Reference< XControlContainer > InvisibleControlViewAccess::getControlContainer( const OutputDevice& _rDevice ) const
500 : : {
501 [ # # ]: 0 : if ( !m_rControlContainer.is() )
502 : : {
503 [ # # ]: 0 : const Window* pWindow = dynamic_cast< const Window* >( &_rDevice );
504 : : OSL_ENSURE( pWindow, "InvisibleControlViewAccess::getControlContainer: expected to be called for a window only!" );
505 [ # # ]: 0 : if ( pWindow )
506 [ # # ]: 0 : m_rControlContainer = VCLUnoHelper::CreateControlContainer( const_cast< Window* >( pWindow ) );
507 : : }
508 : 0 : return m_rControlContainer;
509 : : }
510 : :
511 : : //--------------------------------------------------------------------
512 : 0 : bool InvisibleControlViewAccess::isLayerVisible( SdrLayerID /*_nLayerID*/ ) const
513 : : {
514 : 0 : return false;
515 : : }
516 : :
517 : : //====================================================================
518 : : //= DummyPageViewAccess
519 : : //====================================================================
520 : : /** is a ->IPageViewAccess implementation which can be used to create a control for an arbitrary
521 : : non-Window device
522 : :
523 : : The implementation will report the "PageView" as being in design mode, all layers to be visible,
524 : : and will not return any ControlContainer, so all control container related features (notifications etc)
525 : : are not available.
526 : : */
527 : : class DummyPageViewAccess : public IPageViewAccess
528 : : {
529 : : public:
530 : 3 : DummyPageViewAccess()
531 : 3 : {
532 : 3 : }
533 : :
534 [ - + ]: 3 : virtual ~DummyPageViewAccess() {}
535 : :
536 : : virtual bool isDesignMode() const;
537 : : virtual Reference< XControlContainer >
538 : : getControlContainer( const OutputDevice& _rDevice ) const;
539 : : virtual bool isLayerVisible( SdrLayerID _nLayerID ) const;
540 : : };
541 : :
542 : : //--------------------------------------------------------------------
543 : 3 : bool DummyPageViewAccess::isDesignMode() const
544 : : {
545 : 3 : return true;
546 : : }
547 : :
548 : : //--------------------------------------------------------------------
549 : 6 : Reference< XControlContainer > DummyPageViewAccess::getControlContainer( const OutputDevice& /*_rDevice*/ ) const
550 : : {
551 : 6 : return NULL;
552 : : }
553 : :
554 : : //--------------------------------------------------------------------
555 : 0 : bool DummyPageViewAccess::isLayerVisible( SdrLayerID /*_nLayerID*/ ) const
556 : : {
557 : 0 : return true;
558 : : }
559 : :
560 : : //====================================================================
561 : : //= ViewObjectContactOfUnoControl_Impl
562 : : //====================================================================
563 : : typedef ::cppu::WeakImplHelper4 < XWindowListener
564 : : , XPropertyChangeListener
565 : : , XContainerListener
566 : : , XModeChangeListener
567 : : > ViewObjectContactOfUnoControl_Impl_Base;
568 : :
569 : : class SVX_DLLPRIVATE ViewObjectContactOfUnoControl_Impl : public ViewObjectContactOfUnoControl_Impl_Base
570 : : {
571 : : private:
572 : : // fdo#41935 note that access to members is protected with SolarMutex;
573 : : // the class previously had its own mutex but that is prone to deadlock
574 : :
575 : : /// the instance whose IMPL we are
576 : : ViewObjectContactOfUnoControl* m_pAntiImpl;
577 : :
578 : : /// are we currently inside impl_ensureControl_nothrow?
579 : : bool m_bCreatingControl;
580 : :
581 : : /// the control we're responsible for
582 : : ControlHolder m_aControl;
583 : :
584 : : /// the ControlContainer where we inserted our control
585 : : Reference< XContainer > m_xContainer;
586 : :
587 : : /// the output device for which the control was created
588 : : const OutputDevice* m_pOutputDeviceForWindow;
589 : :
590 : : /// flag indicating whether the control is currently visible
591 : : bool m_bControlIsVisible;
592 : :
593 : : /// are we currently listening at a design mode control?
594 : : bool m_bIsDesignModeListening;
595 : :
596 : : enum ViewControlMode
597 : : {
598 : : eDesign,
599 : : eAlive,
600 : : eUnknown
601 : : };
602 : : /// is the control currently in design mode?
603 : : mutable ViewControlMode m_eControlDesignMode;
604 : :
605 : : ::basegfx::B2DHomMatrix m_aZoomLevelNormalization;
606 : :
607 : : public:
608 : : explicit ViewObjectContactOfUnoControl_Impl( ViewObjectContactOfUnoControl* _pAntiImpl );
609 : :
610 : : /** disposes the instance, which is nonfunctional afterwards
611 : : */
612 : : void dispose();
613 : :
614 : : /** determines whether the instance is disposed
615 : : */
616 : 13777 : bool isDisposed() const { return impl_isDisposed_nofail(); }
617 : :
618 : : /** determines whether the instance is alive
619 : : */
620 : : bool isAlive() const { return !isDisposed(); }
621 : :
622 : : /** returns the SdrUnoObject associated with the ViewContact
623 : :
624 : : @precond
625 : : We're not disposed.
626 : : */
627 : : bool getUnoObject( SdrUnoObj*& _out_rpObject ) const;
628 : :
629 : : /** ensures that we have an ->XControl
630 : :
631 : : Must only be called if a control is needed when no DisplayInfo is present, yet.
632 : :
633 : : For creating a control, an ->OutputDevice is needed, and an ->SdrPageView. Both will be obtained
634 : : from a ->ObjectContactOfPageView. So, if our (anti-impl's) object contact is not a ->ObjectContactOfPageView,
635 : : this method fill fail.
636 : :
637 : : Failure of this method will be reported via an assertion in a non-product version.
638 : : */
639 : : bool ensureControl( const basegfx::B2DHomMatrix* _pInitialViewTransformationOrNULL );
640 : :
641 : : /** returns our XControl, if it already has been created
642 : :
643 : : If you want to ensure that the control exists before accessing it, use ->ensureControl
644 : : */
645 : : inline const ControlHolder&
646 : 36216 : getExistentControl() const { return m_aControl; }
647 : :
648 : : inline bool
649 : 28301 : hasControl() const { return m_aControl.is(); }
650 : :
651 : : /** positions our XControl according to the geometry settings in the SdrUnoObj, modified by the given
652 : : transformation, and sets proper zoom settings according to our device
653 : :
654 : : @precond
655 : : ->m_pOutputDeviceForWindow and ->m_aControl are not <NULL/>
656 : : */
657 : : void positionAndZoomControl( const basegfx::B2DHomMatrix& _rViewTransformation ) const;
658 : :
659 : : /** determines whether or not our control is printable
660 : :
661 : : Effectively, this method returns the value of the "Printable" property
662 : : of the control's model. If we have no control, <FALSE/> is returned.
663 : : */
664 : : bool isPrintableControl() const;
665 : :
666 : : /** sets the design mode on the control, or at least remembers the flag for the
667 : : time the control is created
668 : : */
669 : : void setControlDesignMode( bool _bDesignMode ) const;
670 : :
671 : : /** determines whether our control is currently visible
672 : : @nofail
673 : : */
674 : 0 : bool isControlVisible() const { return impl_isControlVisible_nofail(); }
675 : :
676 : : /// creates an XControl for the given device and SdrUnoObj
677 : : static bool
678 : : createControlForDevice(
679 : : IPageViewAccess& _rPageView,
680 : : const OutputDevice& _rDevice,
681 : : const SdrUnoObj& _rUnoObject,
682 : : const basegfx::B2DHomMatrix& _rInitialViewTransformation,
683 : : const basegfx::B2DHomMatrix& _rInitialZoomNormalization,
684 : : ControlHolder& _out_rControl
685 : : );
686 : :
687 : : const ViewContactOfUnoControl&
688 : 17204 : getViewContact() const
689 : : {
690 [ - + ][ # # ]: 17204 : ENSURE_OR_THROW( !impl_isDisposed_nofail(), "already disposed" );
[ # # ][ # # ]
691 : 17204 : return static_cast< const ViewContactOfUnoControl& >( m_pAntiImpl->GetViewContact() );
692 : : }
693 : :
694 : : protected:
695 : : ~ViewObjectContactOfUnoControl_Impl();
696 : :
697 : : // XEventListener
698 : : virtual void SAL_CALL disposing( const EventObject& Source ) throw(RuntimeException);
699 : :
700 : : // XWindowListener
701 : : virtual void SAL_CALL windowResized( const WindowEvent& e ) throw(RuntimeException);
702 : : virtual void SAL_CALL windowMoved( const WindowEvent& e ) throw(RuntimeException);
703 : : virtual void SAL_CALL windowShown( const EventObject& e ) throw(RuntimeException);
704 : : virtual void SAL_CALL windowHidden( const EventObject& e ) throw(RuntimeException);
705 : :
706 : : // XPropertyChangeListener
707 : : virtual void SAL_CALL propertyChange( const PropertyChangeEvent& evt ) throw(RuntimeException);
708 : :
709 : : // XModeChangeListener
710 : : virtual void SAL_CALL modeChanged( const ModeChangeEvent& _rSource ) throw (RuntimeException);
711 : :
712 : : // XContainerListener
713 : : virtual void SAL_CALL elementInserted( const ::com::sun::star::container::ContainerEvent& Event ) throw (::com::sun::star::uno::RuntimeException);
714 : : virtual void SAL_CALL elementRemoved( const ::com::sun::star::container::ContainerEvent& Event ) throw (::com::sun::star::uno::RuntimeException);
715 : : virtual void SAL_CALL elementReplaced( const ::com::sun::star::container::ContainerEvent& Event ) throw (::com::sun::star::uno::RuntimeException);
716 : :
717 : : private:
718 : : /** retrieves the SdrPageView which our associated SdrPageViewWindow belongs to
719 : :
720 : : @param out_rpPageView
721 : : a reference to a pointer holding, upon return, the desired SdrPageView
722 : :
723 : : @return
724 : : <TRUE/> if and only if a ->SdrPageView could be obtained
725 : :
726 : : @precond
727 : : We really belong to an SdrPageViewWindow. Perhaps (I'm not sure ATM :)
728 : : there are instance for which this might not be true, but those instances
729 : : should never have a need to call this method.
730 : :
731 : : @precond
732 : : We're not disposed.
733 : :
734 : : @postcond
735 : : The method expects success, if it returns with <FALSE/>, this will have been
736 : : asserted.
737 : :
738 : : @nothrow
739 : : */
740 : : bool impl_getPageView_nothrow( SdrPageView*& _out_rpPageView );
741 : :
742 : : /** adjusts the control visibility so it respects its layer's visibility
743 : :
744 : : @param _bForce
745 : : set to <TRUE/> if you want to force a ->XWindow::setVisible call,
746 : : no matter if the control visibility is already correct
747 : :
748 : : @precond
749 : : ->m_aControl is not <NULL/>
750 : :
751 : : @precond
752 : : We're not disposed.
753 : :
754 : : @precond
755 : : We really belong to an SdrPageViewWindow. There are instance for which this
756 : : might not be true, but those instances should never have a need to call
757 : : this method.
758 : : */
759 : : void impl_adjustControlVisibilityToLayerVisibility_throw( bool _bForce );
760 : :
761 : : /** adjusts the control visibility so it respects its layer's visibility
762 : :
763 : : The control must never be visibile if it's in design mode.
764 : : In alive mode, it must be visibility if and only it's on a visible layer.
765 : :
766 : : @param _rxControl
767 : : the control whose visibility is to be adjusted
768 : :
769 : : @param _rPageView
770 : : provides access to the attributes of the SdrPageView which the control finally belongs to
771 : :
772 : : @param _rUnoObject
773 : : our SdrUnoObj
774 : :
775 : : @param _bIsCurrentlyVisible
776 : : determines whether the control is currently visible. Note that this is only a shortcut for
777 : : querying _rxControl for the XWindow2 interface, and calling isVisible at this interface.
778 : : This shortcut has been chosen since the caller usually already has this information.
779 : : If _bForce is <TRUE/>, _bIsCurrentlyVisible is ignored.
780 : :
781 : : @param _bForce
782 : : set to <TRUE/> if you want to force a ->XWindow::setVisible call,
783 : : no matter if the control visibility is already correct
784 : :
785 : : @precond
786 : : We're not disposed.
787 : : */
788 : : static void impl_adjustControlVisibilityToLayerVisibility_throw( const ControlHolder& _rxControl, const SdrUnoObj& _rUnoObject,
789 : : IPageViewAccess& _rPageView, bool _bIsCurrentlyVisible, bool _bForce );
790 : :
791 : : /** starts or stops listening at various aspects of our control
792 : :
793 : : @precond
794 : : ->m_aControl is not <NULL/>
795 : : */
796 : : void impl_switchControlListening_nothrow( bool _bStart );
797 : :
798 : : /** starts or stops listening at our control container
799 : :
800 : : @precond
801 : : ->m_xContainer is not <NULL/>
802 : : */
803 : : void impl_switchContainerListening_nothrow( bool _bStart );
804 : :
805 : : /** starts or stops listening at the control for design-mode relevant facets
806 : : */
807 : : void impl_switchDesignModeListening_nothrow( bool _bStart );
808 : :
809 : : /** starts or stops listening for all properties at our control
810 : :
811 : : @param _bStart
812 : : determines whether to start or to stop listening
813 : :
814 : : @precond
815 : : ->m_aControl is not <NULL/>
816 : : */
817 : : void impl_switchPropertyListening_nothrow( bool _bStart );
818 : :
819 : : /** disposes the instance
820 : : @param _bAlsoDisposeControl
821 : : determines whether the XControl should be disposed, too
822 : : */
823 : : void impl_dispose_nothrow( bool _bAlsoDisposeControl );
824 : :
825 : : /** determines whether the instance is disposed
826 : : @nofail
827 : : */
828 : 66311 : bool impl_isDisposed_nofail() const { return m_pAntiImpl == NULL; }
829 : :
830 : : /** determines whether our control is currently visible
831 : : @nofail
832 : : */
833 : 126 : bool impl_isControlVisible_nofail() const { return m_bControlIsVisible; }
834 : :
835 : : /** determines whether we are currently a listener at the control for desgin-mode relevant facets
836 : : @nofail
837 : : */
838 : 823 : bool impl_isDesignModeListening_nofail() const { return m_bIsDesignModeListening; }
839 : :
840 : : /** determines whether the control currently is in design mode
841 : :
842 : : @precond
843 : : The design mode must already be known. It is known when we first had access to
844 : : an SdrPageView (which carries this flag), or somebody explicitly set it from
845 : : outside.
846 : : */
847 : 11131 : inline bool impl_isControlDesignMode_nothrow() const
848 : : {
849 : : DBG_ASSERT( m_eControlDesignMode != eUnknown, "ViewObjectContactOfUnoControl_Impl::impl_isControlDesignMode_nothrow: mode is still unknown!" );
850 : 11131 : return m_eControlDesignMode == eDesign;
851 : : }
852 : :
853 : : /** ensures that we have a control for the given PageView/OutputDevice
854 : : */
855 : : bool impl_ensureControl_nothrow(
856 : : IPageViewAccess& _rPageView,
857 : : const OutputDevice& _rDevice,
858 : : const basegfx::B2DHomMatrix& _rInitialViewTransformation
859 : : );
860 : :
861 : : /** retrieves the device which a PageView belongs to, starting from its ObjectContactOfPageView
862 : :
863 : : Since #i72752#, the PaintWindow (and thus the OutputDevice) associated with a PageView is not
864 : : constant over its lifetime. Instead, during some paint operations, the PaintWindow/OutputDevice
865 : : might be temporarily patched.
866 : :
867 : : This method cares for this, by retrieving the very original OutputDevice.
868 : : */
869 : : static const OutputDevice& impl_getPageViewOutputDevice_nothrow( const ObjectContactOfPageView& _rObjectContact );
870 : :
871 : : const OutputDevice& impl_getOutputDevice_throw() const;
872 : :
873 : : private:
874 : : ViewObjectContactOfUnoControl_Impl(); // never implemented
875 : : ViewObjectContactOfUnoControl_Impl( const ViewObjectContactOfUnoControl_Impl& ); // never implemented
876 : : ViewObjectContactOfUnoControl_Impl& operator=( const ViewObjectContactOfUnoControl_Impl& ); // never implemented
877 : : };
878 : :
879 : : //====================================================================
880 : : //= LazyControlCreationPrimitive2D
881 : : //====================================================================
882 [ + - ][ - + ]: 27498 : class LazyControlCreationPrimitive2D : public ::drawinglayer::primitive2d::BufferedDecompositionPrimitive2D
883 : : {
884 : : private:
885 : : typedef ::drawinglayer::primitive2d::BufferedDecompositionPrimitive2D BufferedDecompositionPrimitive2D;
886 : :
887 : : protected:
888 : : virtual ::drawinglayer::primitive2d::Primitive2DSequence
889 : : get2DDecomposition(
890 : : const ::drawinglayer::geometry::ViewInformation2D& rViewInformation
891 : : ) const;
892 : :
893 : : virtual ::drawinglayer::primitive2d::Primitive2DSequence
894 : : create2DDecomposition(
895 : : const ::drawinglayer::geometry::ViewInformation2D& rViewInformation
896 : : ) const;
897 : :
898 : : virtual ::basegfx::B2DRange
899 : : getB2DRange(
900 : : const ::drawinglayer::geometry::ViewInformation2D& rViewInformation
901 : : ) const;
902 : :
903 : : public:
904 : 13752 : explicit LazyControlCreationPrimitive2D( const ::rtl::Reference< ViewObjectContactOfUnoControl_Impl >& _pVOCImpl )
905 [ + - ]: 13752 : :m_pVOCImpl( _pVOCImpl )
906 : : {
907 [ - + ][ # # ]: 13752 : ENSURE_OR_THROW( m_pVOCImpl.is(), "Illegal argument." );
[ # # ][ # # ]
908 [ + - ][ + - ]: 13752 : getTransformation( m_pVOCImpl->getViewContact(), m_aTransformation );
909 : 13752 : }
910 : :
911 : : virtual bool operator==(const BasePrimitive2D& rPrimitive) const;
912 : :
913 : : // declare unique ID for this primitive class
914 : : DeclPrimitrive2DIDBlock()
915 : :
916 : : static void getTransformation( const ViewContactOfUnoControl& _rVOC, ::basegfx::B2DHomMatrix& _out_Transformation );
917 : :
918 : : private:
919 : 7404 : void impl_positionAndZoomControl( const ::drawinglayer::geometry::ViewInformation2D& _rViewInformation ) const
920 : : {
921 [ + + ]: 7404 : if ( !_rViewInformation.getViewport().isEmpty() )
922 : 7401 : m_pVOCImpl->positionAndZoomControl( _rViewInformation.getObjectToViewTransformation() );
923 : 7404 : }
924 : :
925 : : private:
926 : : ::rtl::Reference< ViewObjectContactOfUnoControl_Impl > m_pVOCImpl;
927 : : /** The geometry is part of the identity of an primitive, so we cannot calculate it on demand
928 : : (since the data the calculation is based on might have changed then), but need to calc
929 : : it at construction time, and remember it.
930 : : */
931 : : ::basegfx::B2DHomMatrix m_aTransformation;
932 : : };
933 : :
934 : : //====================================================================
935 : : //= ViewObjectContactOfUnoControl_Impl
936 : : //====================================================================
937 : : DBG_NAME( ViewObjectContactOfUnoControl_Impl )
938 : : //--------------------------------------------------------------------
939 : 498 : ViewObjectContactOfUnoControl_Impl::ViewObjectContactOfUnoControl_Impl( ViewObjectContactOfUnoControl* _pAntiImpl )
940 : : :m_pAntiImpl( _pAntiImpl )
941 : : ,m_bCreatingControl( false )
942 : : ,m_pOutputDeviceForWindow( NULL )
943 : : ,m_bControlIsVisible( false )
944 : : ,m_bIsDesignModeListening( false )
945 : : ,m_eControlDesignMode( eUnknown )
946 [ + - ][ + - ]: 498 : ,m_aZoomLevelNormalization()
947 : : {
948 : : DBG_CTOR( ViewObjectContactOfUnoControl_Impl, NULL );
949 : : DBG_ASSERT( m_pAntiImpl, "ViewObjectContactOfUnoControl_Impl::ViewObjectContactOfUnoControl_Impl: invalid AntiImpl!" );
950 : :
951 [ + - ]: 498 : const OutputDevice& rPageViewDevice( impl_getOutputDevice_throw() );
952 [ + - ][ + - ]: 498 : m_aZoomLevelNormalization = rPageViewDevice.GetInverseViewTransformation();
[ + - ]
953 : :
954 : : #if OSL_DEBUG_LEVEL > 1
955 : : ::basegfx::B2DVector aScale, aTranslate;
956 : : double fRotate, fShearX;
957 : : m_aZoomLevelNormalization.decompose( aScale, aTranslate, fRotate, fShearX );
958 : : #endif
959 : :
960 [ + - ]: 498 : ::basegfx::B2DHomMatrix aScaleNormalization;
961 [ + - ]: 498 : MapMode aCurrentDeviceMapMode( rPageViewDevice.GetMapMode() );
962 [ + - ][ + - ]: 498 : aScaleNormalization.set( 0, 0, (double)aCurrentDeviceMapMode.GetScaleX() );
963 [ + - ][ + - ]: 498 : aScaleNormalization.set( 1, 1, (double)aCurrentDeviceMapMode.GetScaleY() );
964 [ + - ][ + - ]: 498 : m_aZoomLevelNormalization *= aScaleNormalization;
[ + - ]
965 : :
966 : : #if OSL_DEBUG_LEVEL > 1
967 : : m_aZoomLevelNormalization.decompose( aScale, aTranslate, fRotate, fShearX );
968 : : #endif
969 : 498 : }
970 : :
971 : : //--------------------------------------------------------------------
972 [ + - ][ + - ]: 495 : ViewObjectContactOfUnoControl_Impl::~ViewObjectContactOfUnoControl_Impl()
973 : : {
974 [ - + ]: 495 : if ( !impl_isDisposed_nofail() )
975 : : {
976 : 0 : acquire();
977 [ # # ]: 0 : dispose();
978 : : }
979 : :
980 : : DBG_DTOR( ViewObjectContactOfUnoControl_Impl, NULL );
981 [ - + ]: 990 : }
982 : :
983 : : //--------------------------------------------------------------------
984 : 549 : void ViewObjectContactOfUnoControl_Impl::impl_dispose_nothrow( bool _bAlsoDisposeControl )
985 : : {
986 [ + + ]: 549 : if ( impl_isDisposed_nofail() )
987 : 549 : return;
988 : :
989 [ + + ]: 495 : if ( m_aControl.is() )
990 : 347 : impl_switchControlListening_nothrow( false );
991 : :
992 [ + + ]: 495 : if ( m_xContainer.is() )
993 : 344 : impl_switchContainerListening_nothrow( false );
994 : :
995 : : // dispose the control
996 [ + + ]: 495 : if ( _bAlsoDisposeControl )
997 : 441 : UnoControlContactHelper::disposeAndClearControl_nothrow( m_aControl );
998 : :
999 : 495 : m_aControl.clear();
1000 : 495 : m_xContainer.clear();
1001 : 495 : m_pOutputDeviceForWindow = NULL;
1002 : 495 : m_bControlIsVisible = false;
1003 : :
1004 : 495 : m_pAntiImpl = NULL;
1005 : : }
1006 : :
1007 : : //--------------------------------------------------------------------
1008 : 495 : void ViewObjectContactOfUnoControl_Impl::dispose()
1009 : : {
1010 [ + - ]: 495 : SolarMutexGuard aSolarGuard;
1011 [ + - ][ + - ]: 495 : impl_dispose_nothrow( true );
1012 : 495 : }
1013 : :
1014 : : //--------------------------------------------------------------------
1015 : 20212 : bool ViewObjectContactOfUnoControl_Impl::getUnoObject( SdrUnoObj*& _out_rpObject ) const
1016 : : {
1017 : : OSL_PRECOND( !impl_isDisposed_nofail(), "ViewObjectContactOfUnoControl_Impl::getUnoObject: already disposed()" );
1018 [ - + ]: 20212 : if ( impl_isDisposed_nofail() )
1019 : 0 : _out_rpObject = NULL;
1020 : : else
1021 : : {
1022 [ - + ]: 20212 : _out_rpObject = dynamic_cast< SdrUnoObj* >( m_pAntiImpl->GetViewContact().TryToGetSdrObject() );
1023 : : DBG_ASSERT( _out_rpObject || !m_pAntiImpl->GetViewContact().TryToGetSdrObject(),
1024 : : "ViewObjectContactOfUnoControl_Impl::getUnoObject: invalid SdrObject!" );
1025 : : }
1026 : 20212 : return ( _out_rpObject != NULL );
1027 : : }
1028 : :
1029 : : //--------------------------------------------------------------------
1030 : 19736 : void ViewObjectContactOfUnoControl_Impl::positionAndZoomControl( const basegfx::B2DHomMatrix& _rViewTransformation ) const
1031 : : {
1032 : : OSL_PRECOND( m_aControl.is(), "ViewObjectContactOfUnoControl_Impl::positionAndZoomControl: no output device or no control!" );
1033 [ + + ]: 19736 : if ( !m_aControl.is() )
1034 [ # # ]: 19736 : return;
1035 : :
1036 : : try
1037 : : {
1038 : 19588 : SdrUnoObj* pUnoObject( NULL );
1039 [ + - ][ + - ]: 19588 : if ( getUnoObject( pUnoObject ) )
1040 : : {
1041 [ + - ][ + - ]: 19588 : UnoControlContactHelper::adjustControlGeometry_throw( m_aControl, pUnoObject->GetLogicRect(), _rViewTransformation, m_aZoomLevelNormalization );
1042 : : }
1043 : : else
1044 : : OSL_FAIL( "ViewObjectContactOfUnoControl_Impl::positionAndZoomControl: no SdrUnoObj!" );
1045 : : }
1046 : 0 : catch( const Exception& )
1047 : : {
1048 : : DBG_UNHANDLED_EXCEPTION();
1049 : : }
1050 : : }
1051 : :
1052 : : //--------------------------------------------------------------------
1053 : 3646 : bool ViewObjectContactOfUnoControl_Impl::ensureControl( const basegfx::B2DHomMatrix* _pInitialViewTransformationOrNULL )
1054 : : {
1055 : : OSL_PRECOND( !impl_isDisposed_nofail(), "ViewObjectContactOfUnoControl_Impl::ensureControl: already disposed()" );
1056 [ - + ]: 3646 : if ( impl_isDisposed_nofail() )
1057 : 0 : return false;
1058 : :
1059 [ - + ]: 3646 : ObjectContactOfPageView* pPageViewContact = dynamic_cast< ObjectContactOfPageView* >( &m_pAntiImpl->GetObjectContact() );
1060 [ + + ]: 3646 : if ( pPageViewContact )
1061 : : {
1062 : 3643 : SdrPageViewAccess aPVAccess( pPageViewContact->GetPageWindow().GetPageView() );
1063 : 3643 : const OutputDevice& rDevice( impl_getPageViewOutputDevice_nothrow( *pPageViewContact ) );
1064 : : return impl_ensureControl_nothrow(
1065 : : aPVAccess,
1066 : : rDevice,
1067 : : _pInitialViewTransformationOrNULL ? *_pInitialViewTransformationOrNULL : rDevice.GetViewTransformation()
1068 [ + - ][ + - ]: 3643 : );
[ + - ][ + - ]
[ + + ]
1069 : : }
1070 : :
1071 : 3 : DummyPageViewAccess aNoPageView;
1072 [ + - ]: 3 : const OutputDevice& rDevice( impl_getOutputDevice_throw() );
1073 : : return impl_ensureControl_nothrow(
1074 : : aNoPageView,
1075 : : rDevice,
1076 : : _pInitialViewTransformationOrNULL ? *_pInitialViewTransformationOrNULL : rDevice.GetViewTransformation()
1077 [ + - ][ + - ]: 3646 : );
[ # # ][ + - ]
[ + - ]
1078 : : }
1079 : :
1080 : : //--------------------------------------------------------------------
1081 : 501 : const OutputDevice& ViewObjectContactOfUnoControl_Impl::impl_getOutputDevice_throw() const
1082 : : {
1083 [ - + ]: 501 : ObjectContactOfPageView* pPageViewContact = dynamic_cast< ObjectContactOfPageView* >( &m_pAntiImpl->GetObjectContact() );
1084 [ + + ]: 501 : if ( pPageViewContact )
1085 : : {
1086 : : // do not use ObjectContact::TryToGetOutputDevice here, it would not care for the PageWindow's
1087 : : // OriginalPaintWindow
1088 : 495 : return impl_getPageViewOutputDevice_nothrow( *pPageViewContact );
1089 : : }
1090 : :
1091 : 6 : const OutputDevice* pDevice = m_pAntiImpl->GetObjectContact().TryToGetOutputDevice();
1092 [ # # ][ # # ]: 6 : ENSURE_OR_THROW( pDevice, "no output device -> no control" );
[ # # ][ - + ]
1093 : 501 : return *pDevice;
1094 : : }
1095 : :
1096 : : //--------------------------------------------------------------------
1097 : 4138 : const OutputDevice& ViewObjectContactOfUnoControl_Impl::impl_getPageViewOutputDevice_nothrow( const ObjectContactOfPageView& _rObjectContact )
1098 : : {
1099 : : // if the PageWindow has a patched PaintWindow, use the original PaintWindow
1100 : : // this ensures that our control is _not_ re-created just because somebody
1101 : : // (temporarily) changed the window to paint onto.
1102 : : // #i72429# / 2007-02-20 / frank.schoenheit@sun.com
1103 : 4138 : SdrPageWindow& rPageWindow( _rObjectContact.GetPageWindow() );
1104 [ + + ]: 4138 : if ( rPageWindow.GetOriginalPaintWindow() )
1105 : 3463 : return rPageWindow.GetOriginalPaintWindow()->GetOutputDevice();
1106 : :
1107 : 4138 : return rPageWindow.GetPaintWindow().GetOutputDevice();
1108 : : }
1109 : :
1110 : : namespace
1111 : : {
1112 : 3646 : static void lcl_resetFlag( bool& rbFlag )
1113 : : {
1114 : 3646 : rbFlag = false;
1115 : 3646 : }
1116 : : }
1117 : :
1118 : : //--------------------------------------------------------------------
1119 : 3646 : bool ViewObjectContactOfUnoControl_Impl::impl_ensureControl_nothrow( IPageViewAccess& _rPageView, const OutputDevice& _rDevice,
1120 : : const basegfx::B2DHomMatrix& _rInitialViewTransformation )
1121 : : {
1122 [ - + ]: 3646 : if ( m_bCreatingControl )
1123 : : {
1124 : : OSL_FAIL( "ViewObjectContactOfUnoControl_Impl::impl_ensureControl_nothrow: reentrance is not really good here!" );
1125 : : // We once had a situation where this was called reentrantly, which lead to all kind of strange effects. All
1126 : : // those affected the grid control, which is the only control so far which is visible in design mode (and
1127 : : // not only in alive mode).
1128 : : // Creating the control triggered an Window::Update on some of its child windows, which triggered a
1129 : : // Paint on parent of the grid control (e.g. the SwEditWin), which triggered a reentrant call to this method,
1130 : : // which it is not really prepared for.
1131 : : //
1132 : : // /me thinks that re-entrance should be caught on a higher level, i.e. the Drawing Layer should not allow
1133 : : // reentrant paint requests. For the moment, until /me can discuss this with AW, catch it here.
1134 : : // 2009-08-27 / #i104544# frank.schoenheit@sun.com
1135 : 0 : return false;
1136 : : }
1137 : :
1138 : 3646 : m_bCreatingControl = true;
1139 [ + - ][ + - ]: 3646 : ::comphelper::ScopeGuard aGuard( ::boost::bind( lcl_resetFlag, ::boost::ref( m_bCreatingControl ) ) );
[ + - ]
1140 : :
1141 [ + + ]: 3646 : if ( m_aControl.is() )
1142 : : {
1143 [ + - ]: 3148 : if ( m_pOutputDeviceForWindow == &_rDevice )
1144 : 3148 : return true;
1145 : :
1146 : : // Somebody requested a control for a new device, which means either of
1147 : : // - our PageView's paint window changed since we were last here
1148 : : // - we don't belong to a page view, and are simply painted onto different devices
1149 : : // The first sounds strange (doens't it?), the second means we could perhaps
1150 : : // optimize this in the future - there is no need to re-create the control every time,
1151 : : // is it?
1152 : : // #i74523# / 2007-02-15 / frank.schoenheit@sun.com
1153 [ # # ]: 0 : if ( m_xContainer.is() )
1154 [ # # ]: 0 : impl_switchContainerListening_nothrow( false );
1155 [ # # ]: 0 : impl_switchControlListening_nothrow( false );
1156 [ # # ]: 0 : UnoControlContactHelper::disposeAndClearControl_nothrow( m_aControl );
1157 : : }
1158 : :
1159 : 498 : SdrUnoObj* pUnoObject( NULL );
1160 [ + - ][ - + ]: 498 : if ( !getUnoObject( pUnoObject ) )
1161 : 0 : return false;
1162 : :
1163 [ + - ]: 498 : ControlHolder aControl;
1164 [ + - ][ + + ]: 498 : if ( !createControlForDevice( _rPageView, _rDevice, *pUnoObject, _rInitialViewTransformation, m_aZoomLevelNormalization, aControl ) )
1165 : 148 : return false;
1166 : :
1167 : 350 : m_pOutputDeviceForWindow = &_rDevice;
1168 [ + - ]: 350 : m_aControl = aControl;
1169 [ + - ][ + - ]: 350 : m_xContainer = m_xContainer.query( _rPageView.getControlContainer( _rDevice ) );
[ + - ][ # # ]
1170 : : DBG_ASSERT( ( m_xContainer.is() // either have a XControlContainer
1171 : : || ( ( !_rPageView.getControlContainer( _rDevice ).is() ) // or don't have any container,
1172 : : && ( dynamic_cast< const Window* >( &_rDevice ) == NULL ) // which is allowed for non-Window instances only
1173 : : )
1174 : : ),
1175 : : "ViewObjectContactOfUnoControl_Impl::impl_ensureControl_nothrow: no XContainer at the ControlContainer!" );
1176 : :
1177 : : try
1178 : : {
1179 [ + + ][ + - ]: 350 : m_eControlDesignMode = m_aControl.isDesignMode() ? eDesign : eAlive;
1180 [ + - ]: 350 : m_bControlIsVisible = m_aControl.isVisible();
1181 : : }
1182 [ # # ]: 0 : catch( const Exception& )
1183 : : {
1184 : : DBG_UNHANDLED_EXCEPTION();
1185 : : }
1186 : :
1187 : : // start listening at all aspects of the control which are interesting to us ...
1188 [ + - ]: 350 : impl_switchControlListening_nothrow( true );
1189 : :
1190 : : // start listening at the control container, in case somebody tampers with our control
1191 [ + + ]: 350 : if ( m_xContainer.is() )
1192 [ + - ]: 347 : impl_switchContainerListening_nothrow( true );
1193 : :
1194 [ + - ][ + - ]: 3646 : return m_aControl.is();
1195 : : }
1196 : :
1197 : : //--------------------------------------------------------------------
1198 : 498 : bool ViewObjectContactOfUnoControl_Impl::createControlForDevice( IPageViewAccess& _rPageView,
1199 : : const OutputDevice& _rDevice, const SdrUnoObj& _rUnoObject, const basegfx::B2DHomMatrix& _rInitialViewTransformation,
1200 : : const basegfx::B2DHomMatrix& _rInitialZoomNormalization, ControlHolder& _out_rControl )
1201 : : {
1202 [ + - ]: 498 : _out_rControl.clear();
1203 : :
1204 [ + - ]: 498 : Reference< XControlModel > xControlModel( _rUnoObject.GetUnoControlModel() );
1205 : : DBG_ASSERT( xControlModel.is(), "ViewObjectContactOfUnoControl_Impl::createControlForDevice: no control model at the SdrUnoObject!?" );
1206 [ - + ]: 498 : if ( !xControlModel.is() )
1207 : 0 : return false;
1208 : :
1209 : 498 : bool bSuccess = false;
1210 : : try
1211 : : {
1212 [ + - ]: 498 : const ::rtl::OUString sControlServiceName( _rUnoObject.GetUnoControlTypeName() );
1213 : :
1214 [ + - ][ + - ]: 498 : Reference< XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory(), UNO_SET_THROW );
1215 [ + - ][ + + ]: 498 : _out_rControl = Reference< XControl >( xFactory->createInstance( sControlServiceName ), UNO_QUERY_THROW );
[ + - ][ + - ]
1216 : :
1217 : : // knit the model and the control
1218 [ + - ]: 350 : _out_rControl.setModel( xControlModel );
1219 : :
1220 : : // proper geometry
1221 : : UnoControlContactHelper::adjustControlGeometry_throw(
1222 : : _out_rControl,
1223 [ + - ]: 350 : _rUnoObject.GetLogicRect(),
1224 : : _rInitialViewTransformation,
1225 : : _rInitialZoomNormalization
1226 [ + - ]: 350 : );
1227 : :
1228 : : // set design mode before peer is created,
1229 : : // this is also needed for accessibility
1230 [ + - ][ + - ]: 350 : _out_rControl.setDesignMode( _rPageView.isDesignMode() );
1231 : :
1232 : : // adjust the initial visibility according to the visibility of the layer
1233 [ + - ]: 350 : impl_adjustControlVisibilityToLayerVisibility_throw( _out_rControl, _rUnoObject, _rPageView, false, true );
1234 : :
1235 : : // add the control to the respective control container
1236 : : // do this last
1237 [ + - ]: 350 : Reference< XControlContainer > xControlContainer( _rPageView.getControlContainer( _rDevice ) );
1238 [ + + ]: 350 : if ( xControlContainer.is() )
1239 [ + - ][ + - ]: 347 : xControlContainer->addControl( sControlServiceName, _out_rControl.getControl() );
1240 : :
1241 [ - + ]: 498 : bSuccess = true;
1242 : : }
1243 [ + - ]: 148 : catch( const Exception& )
1244 : : {
1245 : : DBG_UNHANDLED_EXCEPTION();
1246 : : }
1247 : :
1248 [ + + ]: 498 : if ( !bSuccess )
1249 : : {
1250 : : // delete the control which might have been created already
1251 [ + - ]: 148 : UnoControlContactHelper::disposeAndClearControl_nothrow( _out_rControl );
1252 : : }
1253 : :
1254 : 498 : return _out_rControl.is();
1255 : : }
1256 : :
1257 : : //--------------------------------------------------------------------
1258 : 126 : bool ViewObjectContactOfUnoControl_Impl::impl_getPageView_nothrow( SdrPageView*& _out_rpPageView )
1259 : : {
1260 : : OSL_PRECOND( !impl_isDisposed_nofail(), "ViewObjectContactOfUnoControl_Impl::impl_getPageView_nothrow: already disposed!" );
1261 : :
1262 : 126 : _out_rpPageView = NULL;
1263 [ - + ]: 126 : if ( impl_isDisposed_nofail() )
1264 : 0 : return false;
1265 : :
1266 [ - + ]: 126 : ObjectContactOfPageView* pPageViewContact = dynamic_cast< ObjectContactOfPageView* >( &m_pAntiImpl->GetObjectContact() );
1267 [ + - ]: 126 : if ( pPageViewContact )
1268 : 126 : _out_rpPageView = &pPageViewContact->GetPageWindow().GetPageView();
1269 : :
1270 : : DBG_ASSERT( _out_rpPageView != NULL, "ViewObjectContactOfUnoControl_Impl::impl_getPageView_nothrow: this method is expected to always have success!" );
1271 : 126 : return ( _out_rpPageView != NULL );
1272 : : }
1273 : :
1274 : : //--------------------------------------------------------------------
1275 : 126 : void ViewObjectContactOfUnoControl_Impl::impl_adjustControlVisibilityToLayerVisibility_throw( bool _bForce )
1276 : : {
1277 : : OSL_PRECOND( m_aControl.is(),
1278 : : "ViewObjectContactOfUnoControl_Impl::impl_adjustControlVisibilityToLayerVisibility_throw: only valid if we have a control!" );
1279 : :
1280 : 126 : SdrPageView* pPageView( NULL );
1281 [ + - ]: 126 : if ( !impl_getPageView_nothrow( pPageView ) )
1282 : : return;
1283 : :
1284 : 126 : SdrUnoObj* pUnoObject( NULL );
1285 [ + - ][ + - ]: 126 : if ( !getUnoObject( pUnoObject ) )
1286 : : return;
1287 : :
1288 : 126 : SdrPageViewAccess aPVAccess( *pPageView );
1289 [ + - ]: 126 : impl_adjustControlVisibilityToLayerVisibility_throw( m_aControl, *pUnoObject, aPVAccess, impl_isControlVisible_nofail(), _bForce );
1290 : : }
1291 : :
1292 : : //--------------------------------------------------------------------
1293 : 476 : void ViewObjectContactOfUnoControl_Impl::impl_adjustControlVisibilityToLayerVisibility_throw( const ControlHolder& _rControl,
1294 : : const SdrUnoObj& _rUnoObject, IPageViewAccess& _rPageView, bool _bIsCurrentlyVisible, bool _bForce )
1295 : : {
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 [ + + ]: 476 : if ( !_rControl.isDesignMode() )
1300 : : {
1301 : : // the layer of our object
1302 : 85 : SdrLayerID nObjectLayer = _rUnoObject.GetLayer();
1303 : : // is the object we're residing in visible in this view?
1304 [ + - ][ + - ]: 85 : bool bIsObjectVisible = _rUnoObject.IsVisible() && _rPageView.isLayerVisible( nObjectLayer );
1305 : :
1306 [ + + ][ - + ]: 85 : if ( _bForce || ( bIsObjectVisible != _bIsCurrentlyVisible ) )
1307 : : {
1308 : 19 : _rControl.setVisible( bIsObjectVisible );
1309 : : }
1310 : : }
1311 : 476 : }
1312 : :
1313 : : //--------------------------------------------------------------------
1314 : 691 : void ViewObjectContactOfUnoControl_Impl::impl_switchContainerListening_nothrow( bool _bStart )
1315 : : {
1316 : : OSL_PRECOND( m_xContainer.is(), "ViewObjectContactOfUnoControl_Impl::impl_switchContainerListening_nothrow: no control container!" );
1317 [ - + ]: 691 : if ( !m_xContainer.is() )
1318 : 691 : return;
1319 : :
1320 : : try
1321 : : {
1322 [ + + ]: 691 : if ( _bStart )
1323 [ + - ][ + - ]: 347 : m_xContainer->addContainerListener( this );
[ + - ]
1324 : : else
1325 [ + - ][ + - ]: 344 : m_xContainer->removeContainerListener( this );
[ + - ][ # # ]
1326 : : }
1327 : 0 : catch( const Exception& )
1328 : : {
1329 : : DBG_UNHANDLED_EXCEPTION();
1330 : : }
1331 : : }
1332 : :
1333 : : //--------------------------------------------------------------------
1334 : 697 : void ViewObjectContactOfUnoControl_Impl::impl_switchControlListening_nothrow( bool _bStart )
1335 : : {
1336 : : OSL_PRECOND( m_aControl.is(), "ViewObjectContactOfUnoControl_Impl::impl_switchControlListening_nothrow: invalid control!" );
1337 [ - + ]: 697 : if ( !m_aControl.is() )
1338 : 697 : return;
1339 : :
1340 : : try
1341 : : {
1342 : : // listen for visibility changes
1343 [ + + ]: 697 : if ( _bStart )
1344 [ + - ][ + - ]: 350 : m_aControl.addWindowListener( this );
1345 : : else
1346 [ + - ][ + - ]: 347 : m_aControl.removeWindowListener( this );
1347 : :
1348 : : // in design mode, listen for some more aspects
1349 [ + + ][ + + ]: 697 : impl_switchDesignModeListening_nothrow( impl_isControlDesignMode_nothrow() && _bStart );
[ + - ]
1350 : :
1351 : : // listen for design mode changes
1352 [ + - ]: 697 : Reference< XModeChangeBroadcaster > xDesignModeChanges( m_aControl.getControl(), UNO_QUERY_THROW );
1353 [ + + ]: 697 : if ( _bStart )
1354 [ + - ][ + - ]: 350 : xDesignModeChanges->addModeChangeListener( this );
[ + - ]
1355 : : else
1356 [ + - ][ + - ]: 697 : xDesignModeChanges->removeModeChangeListener( this );
[ + - ][ # # ]
1357 : : }
1358 : 0 : catch( const Exception& )
1359 : : {
1360 : : DBG_UNHANDLED_EXCEPTION();
1361 : : }
1362 : : }
1363 : :
1364 : : //--------------------------------------------------------------------
1365 : 823 : void ViewObjectContactOfUnoControl_Impl::impl_switchDesignModeListening_nothrow( bool _bStart )
1366 : : {
1367 [ + + ]: 823 : if ( impl_isDesignModeListening_nofail() != _bStart )
1368 : : {
1369 : 782 : m_bIsDesignModeListening = _bStart;
1370 : 782 : impl_switchPropertyListening_nothrow( _bStart );
1371 : : }
1372 : 823 : }
1373 : :
1374 : : //------------------------------------------------------------------------------
1375 : 782 : void ViewObjectContactOfUnoControl_Impl::impl_switchPropertyListening_nothrow( bool _bStart )
1376 : : {
1377 : : OSL_PRECOND( m_aControl.is(), "ViewObjectContactOfUnoControl_Impl::impl_switchPropertyListening_nothrow: no control!" );
1378 [ - + ]: 782 : if ( !m_aControl.is() )
1379 : 782 : return;
1380 : :
1381 : : try
1382 : : {
1383 [ + - ][ + - ]: 782 : Reference< XPropertySet > xModelProperties( m_aControl.getModel(), UNO_QUERY_THROW );
1384 [ + + ]: 782 : if ( _bStart )
1385 [ + - ][ + - ]: 391 : xModelProperties->addPropertyChangeListener( ::rtl::OUString(), this );
[ + - ]
1386 : : else
1387 [ + - ][ + - ]: 782 : xModelProperties->removePropertyChangeListener( ::rtl::OUString(), this );
[ + - ][ # # ]
1388 : : }
1389 : 0 : catch( const Exception& )
1390 : : {
1391 : : DBG_UNHANDLED_EXCEPTION();
1392 : : }
1393 : : }
1394 : :
1395 : : //--------------------------------------------------------------------
1396 : 0 : bool ViewObjectContactOfUnoControl_Impl::isPrintableControl() const
1397 : : {
1398 : 0 : SdrUnoObj* pUnoObject( NULL );
1399 [ # # ][ # # ]: 0 : if ( !getUnoObject( pUnoObject ) )
1400 : 0 : return false;
1401 : :
1402 : 0 : bool bIsPrintable = false;
1403 : : try
1404 : : {
1405 [ # # ][ # # ]: 0 : Reference< XPropertySet > xModelProperties( pUnoObject->GetUnoControlModel(), UNO_QUERY_THROW );
1406 [ # # ][ # # ]: 0 : static const ::rtl::OUString s_sPrintablePropertyName( RTL_CONSTASCII_USTRINGPARAM( "Printable" ) );
[ # # ][ # # ]
1407 [ # # ][ # # ]: 0 : OSL_VERIFY( xModelProperties->getPropertyValue( s_sPrintablePropertyName ) >>= bIsPrintable );
[ # # ]
1408 : : }
1409 [ # # ]: 0 : catch( const Exception& )
1410 : : {
1411 : : DBG_UNHANDLED_EXCEPTION();
1412 : : }
1413 : 0 : return bIsPrintable;
1414 : : }
1415 : :
1416 : : //--------------------------------------------------------------------
1417 : 28 : void SAL_CALL ViewObjectContactOfUnoControl_Impl::disposing( const EventObject& Source ) throw(RuntimeException)
1418 : : {
1419 [ + - ]: 28 : 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
1425 : :
1426 [ - + ]: 28 : if ( !m_aControl.is() )
1427 : : return;
1428 : :
1429 [ + - ][ + + ]: 82 : if ( ( m_aControl == Source.Source )
[ + - ][ + - ]
1430 [ + - ][ + - ]: 54 : || ( m_aControl.getModel() == Source.Source )
[ + + ][ # # ]
1431 : : )
1432 : : {
1433 : : // the model or the control is dying ... hmm, not much sense in that we ourself continue
1434 : : // living
1435 [ + - ]: 28 : impl_dispose_nothrow( false );
1436 : : return;
1437 : : }
1438 : :
1439 [ + - ][ - + ]: 28 : DBG_ASSERT( Source.Source == m_xContainer, "ViewObjectContactOfUnoControl_Impl::disposing: Who's this?" );
1440 : : }
1441 : :
1442 : : //--------------------------------------------------------------------
1443 : 624 : void SAL_CALL ViewObjectContactOfUnoControl_Impl::windowResized( const WindowEvent& /*e*/ ) throw(RuntimeException)
1444 : : {
1445 : : // not interested in
1446 : 624 : }
1447 : :
1448 : : //--------------------------------------------------------------------
1449 : 1054 : void SAL_CALL ViewObjectContactOfUnoControl_Impl::windowMoved( const WindowEvent& /*e*/ ) throw(RuntimeException)
1450 : : {
1451 : : // not interested in
1452 : 1054 : }
1453 : :
1454 : : //--------------------------------------------------------------------
1455 : 4089 : void SAL_CALL ViewObjectContactOfUnoControl_Impl::windowShown( const EventObject& /*e*/ ) throw(RuntimeException)
1456 : : {
1457 [ + - ]: 4089 : SolarMutexGuard aSolarGuard;
1458 [ + - ]: 4089 : m_bControlIsVisible = true;
1459 : 4089 : }
1460 : :
1461 : : //--------------------------------------------------------------------
1462 : 4113 : void SAL_CALL ViewObjectContactOfUnoControl_Impl::windowHidden( const EventObject& /*e*/ ) throw(RuntimeException)
1463 : : {
1464 [ + - ]: 4113 : SolarMutexGuard aSolarGuard;
1465 [ + - ]: 4113 : m_bControlIsVisible = false;
1466 : 4113 : }
1467 : :
1468 : : //--------------------------------------------------------------------
1469 : 10302 : void SAL_CALL ViewObjectContactOfUnoControl_Impl::propertyChange( const PropertyChangeEvent& /*_rEvent*/ ) throw(RuntimeException)
1470 : : {
1471 [ + - ]: 10302 : SolarMutexGuard aSolarGuard;
1472 : : // (re)painting might require VCL operations, which need the SolarMutex
1473 : :
1474 : : OSL_PRECOND( !impl_isDisposed_nofail(), "ViewObjectContactOfUnoControl_Impl::propertyChange: already disposed()" );
1475 [ - + ]: 10302 : if ( impl_isDisposed_nofail() )
1476 : : return;
1477 : :
1478 : : DBG_ASSERT( m_aControl.is(), "ViewObjectContactOfUnoControl_Impl::propertyChange: " );
1479 [ - + ]: 10302 : if ( !m_aControl.is() )
1480 : : return;
1481 : :
1482 : : // a generic property changed. If we're in design mode, we need to repaint the control
1483 [ + - ]: 10302 : if ( impl_isControlDesignMode_nothrow() )
1484 : : {
1485 [ + - ]: 10302 : m_pAntiImpl->propertyChange();
1486 [ + - ][ + - ]: 10302 : }
1487 : : }
1488 : :
1489 : : //--------------------------------------------------------------------
1490 : 126 : void SAL_CALL ViewObjectContactOfUnoControl_Impl::modeChanged( const ModeChangeEvent& _rSource ) throw (RuntimeException)
1491 : : {
1492 [ + - ]: 126 : SolarMutexGuard aSolarGuard;
1493 : :
1494 : : DBG_ASSERT( _rSource.NewMode == "design" || _rSource.NewMode == "alive", "ViewObjectContactOfUnoControl_Impl::modeChanged: unexpected mode!" );
1495 : :
1496 [ + + ]: 126 : m_eControlDesignMode = _rSource.NewMode == "design" ? eDesign : eAlive;
1497 : :
1498 [ + - ]: 126 : impl_switchDesignModeListening_nothrow( impl_isControlDesignMode_nothrow() );
1499 : :
1500 : : try
1501 : : {
1502 : : // if the control is part of a invisible layer, we need to explicitly hide it in alive mode
1503 [ + - ]: 126 : impl_adjustControlVisibilityToLayerVisibility_throw( false );
1504 : : }
1505 [ # # ]: 0 : catch( const Exception& )
1506 : : {
1507 : : DBG_UNHANDLED_EXCEPTION();
1508 [ + - ]: 126 : }
1509 [ # # ]: 126 : }
1510 : :
1511 : : //--------------------------------------------------------------------
1512 : 116 : void SAL_CALL ViewObjectContactOfUnoControl_Impl::elementInserted( const ContainerEvent& /*_Event*/ ) throw (RuntimeException)
1513 : : {
1514 : : // not interested in
1515 : 116 : }
1516 : :
1517 : : //--------------------------------------------------------------------
1518 : 136 : void SAL_CALL ViewObjectContactOfUnoControl_Impl::elementRemoved( const ContainerEvent& Event ) throw (RuntimeException)
1519 : : {
1520 [ + - ]: 136 : 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?" );
1527 : :
1528 [ + - ][ + + ]: 136 : if ( m_aControl == Event.Element )
1529 [ + - ][ + - ]: 136 : impl_dispose_nothrow( false );
1530 : 136 : }
1531 : :
1532 : : //--------------------------------------------------------------------
1533 : 0 : void SAL_CALL ViewObjectContactOfUnoControl_Impl::elementReplaced( const ContainerEvent& Event ) throw (RuntimeException)
1534 : : {
1535 [ # # ]: 0 : SolarMutexGuard aSolarGuard;
1536 : : DBG_ASSERT( Event.Source == m_xContainer, "ViewObjectContactOfUnoControl_Impl::elementReplaced: where did this come from?" );
1537 : :
1538 [ # # ][ # # ]: 0 : if ( ! ( m_aControl == Event.ReplacedElement ) )
1539 : : return;
1540 : :
1541 [ # # ]: 0 : Reference< XControl > xNewControl( Event.Element, UNO_QUERY );
1542 : : DBG_ASSERT( xNewControl.is(), "ViewObjectContactOfUnoControl_Impl::elementReplaced: invalid new control!" );
1543 [ # # ]: 0 : if ( !xNewControl.is() )
1544 : : return;
1545 : :
1546 [ # # ][ # # ]: 0 : ENSURE_OR_THROW( m_pOutputDeviceForWindow, "calling this without /me having an output device should be impossible." );
[ # # ][ # # ]
1547 : :
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
1551 : :
1552 [ # # ]: 0 : impl_switchControlListening_nothrow( false );
1553 : :
1554 [ # # ]: 0 : ControlHolder aNewControl( xNewControl );
1555 [ # # ][ # # ]: 0 : aNewControl.setZoom( m_aControl.getZoom() );
1556 [ # # ][ # # ]: 0 : aNewControl.setPosSize( m_aControl.getPosSize() );
1557 [ # # ]: 0 : aNewControl.setDesignMode( impl_isControlDesignMode_nothrow() );
1558 : :
1559 [ # # ]: 0 : m_aControl = xNewControl;
1560 [ # # ]: 0 : m_bControlIsVisible = m_aControl.isVisible();
1561 : :
1562 [ # # ]: 0 : impl_switchControlListening_nothrow( true );
1563 : :
1564 [ # # ][ # # ]: 0 : m_pAntiImpl->onControlChangedOrModified( ViewObjectContactOfUnoControl::ImplAccess() );
[ # # ][ # # ]
[ # # ]
1565 : : }
1566 : :
1567 : : //--------------------------------------------------------------------
1568 : 6 : void ViewObjectContactOfUnoControl_Impl::setControlDesignMode( bool _bDesignMode ) const
1569 : : {
1570 [ + - ][ - + ]: 6 : if ( ( m_eControlDesignMode != eUnknown ) && ( _bDesignMode == impl_isControlDesignMode_nothrow() ) )
[ - + ]
1571 : : // nothing to do
1572 : 0 : return;
1573 [ - + ]: 6 : m_eControlDesignMode = _bDesignMode ? eDesign : eAlive;
1574 : :
1575 [ - + ]: 6 : if ( !m_aControl.is() )
1576 : : // nothing to do, the setting will be respected as soon as the control
1577 : : // is created
1578 : 0 : return;
1579 : :
1580 : : try
1581 : : {
1582 [ + - ][ # # ]: 6 : m_aControl.setDesignMode( _bDesignMode );
1583 : : }
1584 : 0 : catch( const Exception& )
1585 : : {
1586 : : DBG_UNHANDLED_EXCEPTION();
1587 : : }
1588 : : }
1589 : :
1590 : : //====================================================================
1591 : : //= LazyControlCreationPrimitive2D
1592 : : //====================================================================
1593 : : //--------------------------------------------------------------------
1594 : 7892 : bool LazyControlCreationPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
1595 : : {
1596 [ - + ]: 7892 : if ( !BufferedDecompositionPrimitive2D::operator==( rPrimitive ) )
1597 : 0 : return false;
1598 : :
1599 [ - + ]: 7892 : const LazyControlCreationPrimitive2D* pRHS = dynamic_cast< const LazyControlCreationPrimitive2D* >( &rPrimitive );
1600 [ - + ]: 7892 : if ( !pRHS )
1601 : 0 : return false;
1602 : :
1603 [ - + ]: 7892 : if ( m_pVOCImpl != pRHS->m_pVOCImpl )
1604 : 0 : return false;
1605 : :
1606 [ + + ]: 7892 : if ( m_aTransformation != pRHS->m_aTransformation )
1607 : 503 : return false;
1608 : :
1609 : 7892 : return true;
1610 : : }
1611 : :
1612 : : //--------------------------------------------------------------------
1613 : 13752 : void LazyControlCreationPrimitive2D::getTransformation( const ViewContactOfUnoControl& _rVOC, ::basegfx::B2DHomMatrix& _out_Transformation )
1614 : : {
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 : 13752 : const Rectangle aSdrGeoData( _rVOC.GetSdrUnoObj().GetGeoRect() );
1619 : : const basegfx::B2DRange aRange(
1620 : 13752 : aSdrGeoData.Left(),
1621 : 13752 : aSdrGeoData.Top(),
1622 : 13752 : aSdrGeoData.Right(),
1623 : 13752 : aSdrGeoData.Bottom()
1624 [ + - ]: 13752 : );
1625 : :
1626 [ + - ]: 13752 : _out_Transformation.identity();
1627 [ + - ][ + - ]: 13752 : _out_Transformation.set( 0, 0, aRange.getWidth() );
1628 [ + - ][ + - ]: 13752 : _out_Transformation.set( 1, 1, aRange.getHeight() );
1629 [ + - ][ + - ]: 13752 : _out_Transformation.set( 0, 2, aRange.getMinX() );
1630 [ + - ][ + - ]: 13752 : _out_Transformation.set( 1, 2, aRange.getMinY() );
1631 : 13752 : }
1632 : :
1633 : : //--------------------------------------------------------------------
1634 : 33595 : ::basegfx::B2DRange LazyControlCreationPrimitive2D::getB2DRange( const ::drawinglayer::geometry::ViewInformation2D& /*rViewInformation*/ ) const
1635 : : {
1636 : 33595 : ::basegfx::B2DRange aRange( 0.0, 0.0, 1.0, 1.0 );
1637 : 33595 : aRange.transform( m_aTransformation );
1638 : 33595 : return aRange;
1639 : : }
1640 : :
1641 : : //--------------------------------------------------------------------
1642 : 6742 : ::drawinglayer::primitive2d::Primitive2DSequence LazyControlCreationPrimitive2D::get2DDecomposition( const ::drawinglayer::geometry::ViewInformation2D& _rViewInformation ) const
1643 : : {
1644 : : #if OSL_DEBUG_LEVEL > 1
1645 : : ::basegfx::B2DVector aScale, aTranslate;
1646 : : double fRotate, fShearX;
1647 : : _rViewInformation.getObjectToViewTransformation().decompose( aScale, aTranslate, fRotate, fShearX );
1648 : : #endif
1649 [ + + ]: 6742 : if ( m_pVOCImpl->hasControl() )
1650 : 3952 : impl_positionAndZoomControl( _rViewInformation );
1651 : 6742 : return BufferedDecompositionPrimitive2D::get2DDecomposition( _rViewInformation );
1652 : : }
1653 : :
1654 : : //--------------------------------------------------------------------
1655 : 3452 : ::drawinglayer::primitive2d::Primitive2DSequence LazyControlCreationPrimitive2D::create2DDecomposition( const ::drawinglayer::geometry::ViewInformation2D& _rViewInformation ) const
1656 : : {
1657 : : #if OSL_DEBUG_LEVEL > 1
1658 : : ::basegfx::B2DVector aScale, aTranslate;
1659 : : double fRotate, fShearX;
1660 : : _rViewInformation.getObjectToViewTransformation().decompose( aScale, aTranslate, fRotate, fShearX );
1661 : : #endif
1662 : 3452 : const bool bHadControl = m_pVOCImpl->getExistentControl().is();
1663 : :
1664 : : // force control here to make it a VCL ChildWindow. Will be fetched
1665 : : // and used below by getExistentControl()
1666 [ + - ][ + - ]: 3452 : m_pVOCImpl->ensureControl( &_rViewInformation.getObjectToViewTransformation() );
1667 [ + - ]: 3452 : impl_positionAndZoomControl( _rViewInformation );
1668 : :
1669 : : // get needed data
1670 [ + - ]: 3452 : const ViewContactOfUnoControl& rViewContactOfUnoControl( m_pVOCImpl->getViewContact() );
1671 [ + - ]: 3452 : Reference< XControlModel > xControlModel( rViewContactOfUnoControl.GetSdrUnoObj().GetUnoControlModel() );
1672 : 3452 : const ControlHolder& rControl( m_pVOCImpl->getExistentControl() );
1673 : :
1674 [ + + ][ + - ]: 3452 : if ( !bHadControl && rControl.is() && rControl.isVisible() )
[ + + ][ + + ]
[ + + ]
1675 [ + - ]: 51 : rControl.invalidate();
1676 : :
1677 [ + + ][ + + ]: 3452 : if ( !bHadControl && rControl.is() && rControl.isVisible() )
[ + - ][ + + ]
[ + + ]
1678 [ + - ]: 51 : rControl.invalidate();
1679 : :
1680 : : // check if we already have an XControl.
1681 [ + + ][ + + ]: 3452 : if ( !xControlModel.is() || !rControl.is() )
[ + + ]
1682 : : // use the default mechanism. This will create a ControlPrimitive2D without
1683 : : // handing over a XControl. If not even a XControlModel exists, it will
1684 : : // create the SdrObject fallback visualisation
1685 [ + - ]: 164 : return rViewContactOfUnoControl.getViewIndependentPrimitive2DSequence();
1686 : :
1687 : : // create a primitive and hand over the existing xControl. This will
1688 : : // allow the primitive to not need to create another one on demand.
1689 : : const drawinglayer::primitive2d::Primitive2DReference xRetval( new ::drawinglayer::primitive2d::ControlPrimitive2D(
1690 [ + - ][ + - ]: 3288 : m_aTransformation, xControlModel, rControl.getControl() ) );
[ + - ]
1691 : :
1692 [ + - ]: 3452 : return drawinglayer::primitive2d::Primitive2DSequence(&xRetval, 1);
1693 : : }
1694 : :
1695 : : //--------------------------------------------------------------------
1696 : 28889 : ImplPrimitrive2DIDBlock( LazyControlCreationPrimitive2D, PRIMITIVE2D_ID_SDRCONTROLPRIMITIVE2D )
1697 : :
1698 : : //====================================================================
1699 : : //= ViewObjectContactOfUnoControl
1700 : : //====================================================================
1701 : : DBG_NAME( ViewObjectContactOfUnoControl )
1702 : : //--------------------------------------------------------------------
1703 : 498 : ViewObjectContactOfUnoControl::ViewObjectContactOfUnoControl( ObjectContact& _rObjectContact, ViewContactOfUnoControl& _rViewContact )
1704 : : :ViewObjectContactOfSdrObj( _rObjectContact, _rViewContact )
1705 [ + - ]: 498 : ,m_pImpl( new ViewObjectContactOfUnoControl_Impl( this ) )
1706 : : {
1707 : : DBG_CTOR( ViewObjectContactOfUnoControl, NULL );
1708 : 498 : }
1709 : :
1710 : : //--------------------------------------------------------------------
1711 : 495 : ViewObjectContactOfUnoControl::~ViewObjectContactOfUnoControl()
1712 : : {
1713 [ + - ]: 495 : m_pImpl->dispose();
1714 [ + - ]: 495 : m_pImpl = NULL;
1715 : :
1716 : : DBG_DTOR( ViewObjectContactOfUnoControl, NULL );
1717 [ - + ]: 990 : }
1718 : :
1719 : : //--------------------------------------------------------------------
1720 : 194 : Reference< XControl > ViewObjectContactOfUnoControl::getControl()
1721 : : {
1722 [ + - ]: 194 : SolarMutexGuard aSolarGuard;
1723 [ + - ]: 194 : m_pImpl->ensureControl( NULL );
1724 [ + - ]: 194 : return m_pImpl->getExistentControl().getControl();
1725 : : }
1726 : :
1727 : : //--------------------------------------------------------------------
1728 : 0 : Reference< XControl > ViewObjectContactOfUnoControl::getTemporaryControlForWindow(
1729 : : const Window& _rWindow, Reference< XControlContainer >& _inout_ControlContainer, const SdrUnoObj& _rUnoObject )
1730 : : {
1731 [ # # ]: 0 : ControlHolder aControl;
1732 : :
1733 : 0 : InvisibleControlViewAccess aSimulatePageView( _inout_ControlContainer );
1734 [ # # ][ # # ]: 0 : OSL_VERIFY( ViewObjectContactOfUnoControl_Impl::createControlForDevice( aSimulatePageView, _rWindow, _rUnoObject,
[ # # ][ # # ]
[ # # ]
1735 : : _rWindow.GetViewTransformation(), _rWindow.GetInverseViewTransformation(), aControl ) );
1736 [ # # ]: 0 : return aControl.getControl();
1737 : : }
1738 : :
1739 : : //--------------------------------------------------------------------
1740 : 874 : void ViewObjectContactOfUnoControl::ensureControlVisibility( bool _bVisible ) const
1741 : : {
1742 [ + - ]: 874 : SolarMutexGuard aSolarGuard;
1743 : :
1744 : : try
1745 : : {
1746 : 874 : const ControlHolder& rControl( m_pImpl->getExistentControl() );
1747 [ + - ]: 874 : if ( !rControl.is() )
1748 : : return;
1749 : :
1750 : : // only need to care for alive mode
1751 [ # # ][ # # ]: 0 : if ( rControl.isDesignMode() )
1752 : : return;
1753 : :
1754 : : // is the visibility correct?
1755 [ # # ][ # # ]: 0 : if ( m_pImpl->isControlVisible() == _bVisible )
1756 : : return;
1757 : :
1758 : : // no -> adjust it
1759 [ # # ]: 0 : rControl.setVisible( _bVisible );
1760 : : DBG_ASSERT( m_pImpl->isControlVisible() == _bVisible, "ViewObjectContactOfUnoControl::ensureControlVisibility: this didn't work!" );
1761 : : // now this would mean that either isControlVisible is not reliable,
1762 : : // or that showing/hiding the window did not work as intended.
1763 : : }
1764 [ # # ]: 0 : catch( const Exception& )
1765 : : {
1766 : : DBG_UNHANDLED_EXCEPTION();
1767 [ + - ][ - + ]: 874 : }
[ # # ]
1768 : : }
1769 : :
1770 : : //--------------------------------------------------------------------
1771 : 6 : void ViewObjectContactOfUnoControl::setControlDesignMode( bool _bDesignMode ) const
1772 : : {
1773 [ + - ]: 6 : SolarMutexGuard aSolarGuard;
1774 [ + - ]: 6 : m_pImpl->setControlDesignMode( _bDesignMode );
1775 : :
1776 [ + - ]: 6 : if(!_bDesignMode)
1777 : : {
1778 : : // when live mode is switched on, a refresh is needed. The edit mode visualisation
1779 : : // needs to be repainted and the now used VCL-Window needs to be positioned and
1780 : : // sized. Both is done from the repant refresh.
1781 [ + - ]: 6 : const_cast< ViewObjectContactOfUnoControl* >(this)->ActionChanged();
1782 [ + - ]: 6 : }
1783 : 6 : }
1784 : :
1785 : : //--------------------------------------------------------------------
1786 : 13777 : drawinglayer::primitive2d::Primitive2DSequence ViewObjectContactOfUnoControl::createPrimitive2DSequence(const DisplayInfo& /*rDisplayInfo*/) const
1787 : : {
1788 [ + - ][ + + ]: 13777 : if ( m_pImpl->isDisposed() )
1789 : : // our control already died.
1790 : : // TODO: Is it worth re-creating the control? Finally, this is a pathological situation, it means some instance
1791 : : // disposed the control though it doesn't own it. So, /me thinks we should not bother here.
1792 [ + - ]: 20 : return drawinglayer::primitive2d::Primitive2DSequence();
1793 : :
1794 [ + - ][ + - ]: 13757 : if ( GetObjectContact().getViewInformation2D().getViewTransformation().isIdentity() )
[ - + ]
1795 : : // remove this when #i115754# is fixed
1796 [ # # ]: 0 : return drawinglayer::primitive2d::Primitive2DSequence();
1797 : :
1798 : : // ignore existing controls which are in alive mode and manually switched to "invisible"
1799 : : // #102090# / 2009-06-05 / frank.schoenheit@sun.com
1800 : 13757 : const ControlHolder& rControl( m_pImpl->getExistentControl() );
1801 [ + - ][ + + ]: 13757 : if ( rControl.is() && !rControl.isDesignMode() && !rControl.isVisible() )
[ + - ][ + + ]
[ + + ][ + + ]
1802 [ + - ]: 5 : return drawinglayer::primitive2d::Primitive2DSequence();
1803 : :
1804 [ + - ][ + - ]: 13752 : ::drawinglayer::primitive2d::Primitive2DReference xPrimitive( new LazyControlCreationPrimitive2D( m_pImpl ) );
[ + - ]
1805 [ + - ]: 13777 : return ::drawinglayer::primitive2d::Primitive2DSequence( &xPrimitive, 1 );
1806 : : }
1807 : :
1808 : : //--------------------------------------------------------------------
1809 : 21559 : bool ViewObjectContactOfUnoControl::isPrimitiveVisible( const DisplayInfo& _rDisplayInfo ) const
1810 : : {
1811 [ + - ]: 21559 : SolarMutexGuard aSolarGuard;
1812 : :
1813 [ + + ]: 21559 : if ( m_pImpl->hasControl() )
1814 : : {
1815 : 12335 : const ::drawinglayer::geometry::ViewInformation2D& rViewInformation( GetObjectContact().getViewInformation2D() );
1816 : : #if OSL_DEBUG_LEVEL > 1
1817 : : ::basegfx::B2DVector aScale, aTranslate;
1818 : : double fRotate, fShearX;
1819 : : rViewInformation.getObjectToViewTransformation().decompose( aScale, aTranslate, fRotate, fShearX );
1820 : : #endif
1821 : :
1822 [ + - ][ + - ]: 12335 : if ( !rViewInformation.getViewport().isEmpty() )
[ + - ]
1823 [ + - ][ + - ]: 12335 : m_pImpl->positionAndZoomControl( rViewInformation.getObjectToViewTransformation() );
1824 : : }
1825 : :
1826 [ + - ][ + - ]: 21559 : return ViewObjectContactOfSdrObj::isPrimitiveVisible( _rDisplayInfo );
1827 : : }
1828 : :
1829 : : //--------------------------------------------------------------------
1830 : 10302 : void ViewObjectContactOfUnoControl::propertyChange()
1831 : : {
1832 : 10302 : impl_onControlChangedOrModified();
1833 : 10302 : }
1834 : :
1835 : : //--------------------------------------------------------------------
1836 : 14487 : void ViewObjectContactOfUnoControl::ActionChanged()
1837 : : {
1838 : : // call parent
1839 : 14487 : ViewObjectContactOfSdrObj::ActionChanged();
1840 : 14487 : const ControlHolder& rControl(m_pImpl->getExistentControl());
1841 : :
1842 [ + + ][ + + ]: 14487 : if(rControl.is() && !rControl.isDesignMode())
[ + + ]
1843 : : {
1844 : : // #i93180# if layer visibility has changed and control is in live mode, it is necessary
1845 : : // to correct visibility to make those control vanish on SdrObject LayerID changes
1846 : 6 : const SdrPageView* pSdrPageView = GetObjectContact().TryToGetSdrPageView();
1847 : :
1848 [ + - ]: 6 : if(pSdrPageView)
1849 : : {
1850 : 6 : const SdrObject& rObject = getSdrObject();
1851 [ + - ][ + - ]: 6 : const bool bIsLayerVisible( rObject.IsVisible() && pSdrPageView->GetVisibleLayers().IsSet(rObject.GetLayer()));
1852 : :
1853 [ - + ]: 6 : if(rControl.isVisible() != bIsLayerVisible)
1854 : : {
1855 : 0 : rControl.setVisible(bIsLayerVisible);
1856 : : }
1857 : : }
1858 : : }
1859 : 14487 : }
1860 : :
1861 : : //--------------------------------------------------------------------
1862 : 10302 : void ViewObjectContactOfUnoControl::impl_onControlChangedOrModified()
1863 : : {
1864 : : // graphical invalidate at all views
1865 : 10302 : ActionChanged();
1866 : :
1867 : : // #i93318# flush Primitive2DSequence to force recreation with updated XControlModel
1868 : : // since e.g. background color has changed and existing decompositions are possibly no
1869 : : // longer valid. Unfortunately this is not detected from ControlPrimitive2D::operator==
1870 : : // since it only has a uno reference to the XControlModel
1871 : 10302 : flushPrimitive2DSequence();
1872 : 10302 : }
1873 : :
1874 : : //====================================================================
1875 : : //= UnoControlPrintOrPreviewContact
1876 : : //====================================================================
1877 : : DBG_NAME( UnoControlPrintOrPreviewContact )
1878 : : //--------------------------------------------------------------------
1879 : 0 : UnoControlPrintOrPreviewContact::UnoControlPrintOrPreviewContact( ObjectContactOfPageView& _rObjectContact, ViewContactOfUnoControl& _rViewContact )
1880 : 0 : :ViewObjectContactOfUnoControl( _rObjectContact, _rViewContact )
1881 : : {
1882 : : DBG_CTOR( UnoControlPrintOrPreviewContact, NULL );
1883 : 0 : }
1884 : :
1885 : : //--------------------------------------------------------------------
1886 : 0 : UnoControlPrintOrPreviewContact::~UnoControlPrintOrPreviewContact()
1887 : : {
1888 : : DBG_DTOR( UnoControlPrintOrPreviewContact, NULL );
1889 [ # # ]: 0 : }
1890 : :
1891 : : //--------------------------------------------------------------------
1892 : 0 : drawinglayer::primitive2d::Primitive2DSequence UnoControlPrintOrPreviewContact::createPrimitive2DSequence(const DisplayInfo& rDisplayInfo ) const
1893 : : {
1894 [ # # ]: 0 : if ( !m_pImpl->isPrintableControl() )
1895 : 0 : return drawinglayer::primitive2d::Primitive2DSequence();
1896 : 0 : return ViewObjectContactOfUnoControl::createPrimitive2DSequence( rDisplayInfo );
1897 : : }
1898 : :
1899 : : //........................................................................
1900 [ + - ][ + - ]: 450 : } } // namespace sdr::contact
1901 : : //........................................................................
1902 : :
1903 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|