LCOV - code coverage report
Current view: top level - svx/source/sdr/contact - viewobjectcontactofunocontrol.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 415 523 79.3 %
Date: 2014-04-11 Functions: 94 113 83.2 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10