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