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