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