summaryrefslogtreecommitdiff
path: root/svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx')
-rw-r--r--svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx593
1 files changed, 296 insertions, 297 deletions
diff --git a/svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx b/svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx
index 43114516c7..2ba50855ae 100644
--- a/svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx
+++ b/svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx
@@ -35,6 +35,7 @@
#include <svx/sdr/contact/displayinfo.hxx>
#include <svx/sdr/properties/properties.hxx>
#include <svx/sdr/contact/objectcontactofpageview.hxx>
+#include <svx/sdr/primitive2d/svx_primitivetypes2d.hxx>
/** === begin UNO includes === **/
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
@@ -80,6 +81,7 @@ namespace sdr { namespace contact {
using ::com::sun::star::uno::XInterface;
using ::com::sun::star::uno::UNO_QUERY;
using ::com::sun::star::uno::UNO_QUERY_THROW;
+ using ::com::sun::star::uno::UNO_SET_THROW;
using ::com::sun::star::uno::Exception;
using ::com::sun::star::uno::RuntimeException;
using ::com::sun::star::awt::XControl;
@@ -175,7 +177,11 @@ namespace sdr { namespace contact {
inline void addWindowListener( const Reference< XWindowListener >& _l ) const { m_xControlWindow->addWindowListener( _l ); }
inline void removeWindowListener( const Reference< XWindowListener >& _l ) const { m_xControlWindow->removeWindowListener( _l ); }
void setPosSize( const Rectangle& _rPosSize ) const;
- void setZoom( const MapMode& _rMapMode ) const;
+ Rectangle
+ getPosSize() const;
+ void setZoom( const ::basegfx::B2DVector& _rScale ) const;
+ ::basegfx::B2DVector
+ getZoom() const;
inline void setGraphics( const Reference< XGraphics >& _g ) const { m_xControlView->setGraphics( _g ); }
inline Reference< XGraphics >
@@ -221,10 +227,36 @@ namespace sdr { namespace contact {
}
//--------------------------------------------------------------------
- void ControlHolder::setZoom( const MapMode& _rMapMode ) const
+ ::Rectangle ControlHolder::getPosSize() const
{
// no check whether we're valid, this is the responsibility of the caller
- m_xControlView->setZoom( (float)double( _rMapMode.GetScaleX() ), (float)double( _rMapMode.GetScaleY() ) );
+ return VCLUnoHelper::ConvertToVCLRect( m_xControlWindow->getPosSize() );
+ }
+
+ //--------------------------------------------------------------------
+ void ControlHolder::setZoom( const ::basegfx::B2DVector& _rScale ) const
+ {
+ // no check whether we're valid, this is the responsibility of the caller
+ m_xControlView->setZoom( (float)_rScale.getX(), (float)_rScale.getY() );
+ }
+
+ //--------------------------------------------------------------------
+ ::basegfx::B2DVector ControlHolder::getZoom() const
+ {
+ // no check whether we're valid, this is the responsibility of the caller
+
+ // Argh. Why does XView have a setZoom only, but not a getZoom?
+ Window* pWindow = VCLUnoHelper::GetWindow( m_xControlWindow );
+ OSL_ENSURE( pWindow, "ControlHolder::setZoom: no implementation access!" );
+
+ ::basegfx::B2DVector aZoom( 1, 1 );
+ if ( pWindow )
+ {
+ const Fraction& rZoom( pWindow->GetZoom() );
+ aZoom.setX( (double)rZoom );
+ aZoom.setY( (double)rZoom );
+ }
+ return aZoom;
}
//====================================================================
@@ -233,37 +265,13 @@ namespace sdr { namespace contact {
class UnoControlContactHelper
{
public:
- /** positions a control relative to a device
-
- @precond <arg>_pDevice</arg> is not <NULL/>
+ /** positions a control, and sets its zoom mode, using a given transformation and output device
*/
- static void positionControl_throw(
+ static void adjustControlGeometry_throw(
const ControlHolder& _rControl,
const Rectangle& _rLogicBoundingRect,
- const OutputDevice* _pDevice
- );
-
- /** sets the zoom at a UNO control, according to a Device's MapMode
-
- @precond <arg>_pDevice</arg> is not <NULL/>
- */
- static void setControlZoom(
- const ControlHolder& _rControl,
- const OutputDevice* _pDevice
- );
-
- /** draws a given control onto it's current XGraphics, at given coordinates
-
- Note that the control is not drawn onto the given device, instead you must
- use ->XView::setGraphics yourself, before calling this method. The given ->OutputDevice
- is only used to calculate pixel coordinates from logic coordinates
-
- @precond <arg>_pDevice</arg> is not <NULL/>
- */
- static void drawControl(
- const ControlHolder& _rControl,
- const Point& _rLogicTopLeft,
- const OutputDevice* _pDevice
+ const ::basegfx::B2DHomMatrix& _rViewTransformation,
+ const ::basegfx::B2DHomMatrix& _rZoomLevelNormalization
);
/** disposes the given control
@@ -279,50 +287,28 @@ namespace sdr { namespace contact {
};
//--------------------------------------------------------------------
- void UnoControlContactHelper::positionControl_throw( const ControlHolder& _rControl, const Rectangle& _rLogicBoundingRect,
- const OutputDevice* _pDevice )
+ void UnoControlContactHelper::adjustControlGeometry_throw( const ControlHolder& _rControl, const Rectangle& _rLogicBoundingRect,
+ const basegfx::B2DHomMatrix& _rViewTransformation, const ::basegfx::B2DHomMatrix& _rZoomLevelNormalization )
{
- OSL_PRECOND( _pDevice, "UnoControlContactHelper::positionControl_throw: no device -> no survival!" );
-
- if ( _rControl.is() )
- {
- const Rectangle aPaintRectPixel(
- _pDevice->LogicToPixel( _rLogicBoundingRect.TopLeft() ),
- _pDevice->LogicToPixel( _rLogicBoundingRect.GetSize() )
- );
-
- _rControl.setPosSize( aPaintRectPixel );
- }
- }
-
- //--------------------------------------------------------------------
- void UnoControlContactHelper::setControlZoom( const ControlHolder& _rControl, const OutputDevice* _pDevice )
- {
- OSL_PRECOND( _pDevice, "UnoControlContactHelper::setControlZoom: no device -> no survival!" );
- OSL_PRECOND( _rControl.is(), "UnoControlContactHelper::setControlZoom: illegal control!" );
-
- if ( _rControl.is() )
- _rControl.setZoom( _pDevice->GetMapMode() );
- }
-
- //--------------------------------------------------------------------
- void UnoControlContactHelper::drawControl( const ControlHolder& _rControl, const Point& _rLogicTopLeft,
- const OutputDevice* _pDevice )
- {
- OSL_PRECOND( _rControl.is(), "UnoControlContactHelper::drawControl: invalid control!" );
+ OSL_PRECOND( _rControl.is(), "UnoControlContactHelper::adjustControlGeometry_throw: illegal control!" );
if ( !_rControl.is() )
return;
- try
- {
- _rControl.draw(
- _pDevice->LogicToPixel( _rLogicTopLeft )
- );
- }
- catch( const Exception& )
- {
- DBG_UNHANDLED_EXCEPTION();
- }
+ // transform the logic bound rect, using the view transformation, to pixel coordinates
+ ::basegfx::B2DPoint aTopLeft( _rLogicBoundingRect.Left(), _rLogicBoundingRect.Top() );
+ aTopLeft *= _rViewTransformation;
+ ::basegfx::B2DPoint aBottomRight( _rLogicBoundingRect.Right(), _rLogicBoundingRect.Bottom() );
+ aBottomRight *= _rViewTransformation;
+
+ const Rectangle aPaintRectPixel( (long)aTopLeft.getX(), (long)aTopLeft.getY(), (long)aBottomRight.getX(), (long)aBottomRight.getY() );
+ _rControl.setPosSize( aPaintRectPixel );
+
+ // determine the scale from the current view transformation, and the normalization matrix
+ ::basegfx::B2DHomMatrix aObtainResolutionDependentScale( _rViewTransformation * _rZoomLevelNormalization );
+ ::basegfx::B2DVector aScale, aTranslate;
+ double fRotate, fShearX;
+ aObtainResolutionDependentScale.decompose( aScale, aTranslate, fRotate, fShearX );
+ _rControl.setZoom( aScale );
}
//--------------------------------------------------------------------
@@ -402,40 +388,7 @@ namespace sdr { namespace contact {
}
//====================================================================
- //= DummyPageViewAccess
- //====================================================================
- /** is a ->IPageViewAccess implementation which defaults all attribute access, and thus can be
- operated without an actual ->SdrPageView
- */
- class DummyPageViewAccess : public IPageViewAccess
- {
- public:
- virtual bool isDesignMode() const;
- virtual Reference< XControlContainer >
- getControlContainer( const OutputDevice& _rDevice ) const;
- virtual bool isLayerVisible( SdrLayerID _nLayerID ) const;
- };
-
- //--------------------------------------------------------------------
- bool DummyPageViewAccess::isDesignMode() const
- {
- return true;
- }
-
- //--------------------------------------------------------------------
- Reference< XControlContainer > DummyPageViewAccess::getControlContainer( const OutputDevice& /*_rDevice*/ ) const
- {
- return Reference< XControlContainer >();
- }
-
- //--------------------------------------------------------------------
- bool DummyPageViewAccess::isLayerVisible( SdrLayerID /*_nLayerID*/ ) const
- {
- return true;
- }
-
- //====================================================================
- //= DummyPageViewAccess
+ //= InvisibleControlViewAccess
//====================================================================
/** is a ->IPageViewAccess implementation which can be used to create an invisble control for
an arbitrary device
@@ -510,7 +463,7 @@ namespace sdr { namespace contact {
Reference< XContainer > m_xContainer;
/// the output device for which the control was created
- OutputDevice const* m_pOutputDeviceForWindow;
+ const OutputDevice* m_pOutputDeviceForWindow;
/// flag indicating whether the control is currently visible
bool m_bControlIsVisible;
@@ -527,6 +480,8 @@ namespace sdr { namespace contact {
/// is the control currently in design mode?
mutable ViewControlMode m_eControlDesignMode;
+ ::basegfx::B2DHomMatrix m_aZoomLevelNormalization;
+
public:
ViewObjectContactOfUnoControl_Impl( ViewObjectContactOfUnoControl* _pAntiImpl );
@@ -549,17 +504,13 @@ namespace sdr { namespace contact {
*/
bool getUnoObject( SdrUnoObj*& _out_rpObject ) const;
- /** ensures that we have an XControl which can be painted onto the given display
- */
- bool ensureControl( const DisplayInfo& _rDisplayInfo );
-
/** ensures that we have an ->XControl
Must only be called if a control is needed when no DisplayInfo is present, yet.
- For creating a control, an ->OutputDevice is needed, and an ->SdrPageView. Both can only be
- obtained from a ->DisplayInfo struct, or alternatively a ->ObjectContactOfPageView. So, if
- our (anti-impl's) object contact is not a ->ObjectContactOfPageView, this method fill fail.
+ For creating a control, an ->OutputDevice is needed, and an ->SdrPageView. Both will be obtained
+ from a ->ObjectContactOfPageView. So, if our (anti-impl's) object contact is not a ->ObjectContactOfPageView,
+ this method fill fail.
Failure of this method will be reported via an assertion in a non-product version.
*/
@@ -572,22 +523,16 @@ namespace sdr { namespace contact {
inline const ControlHolder&
getExistentControl() const { return m_aControl; }
- /** positions our XControl according to the geometry settings in the SdrUnoObj,
- and sets proper zoom settings according to our device
+ inline bool
+ hasControl() const { return m_aControl.is(); }
+
+ /** positions our XControl according to the geometry settings in the SdrUnoObj, modified by the given
+ transformation, and sets proper zoom settings according to our device
@precond
->m_pOutputDeviceForWindow and ->m_aControl are not <NULL/>
- @tolerant
- If the preconditions are not met, nothing is done at all
*/
- void positionAndZoomControl() const;
-
- /** positions the control for a paint onto a given device
-
- If we do not (yet) have a control, or the control does not belong to the
- device for which a paint is requested, no positioning happens.
- */
- void positionControlForPaint( const DisplayInfo& _rDisplayInfo ) const;
+ void positionAndZoomControl( const basegfx::B2DHomMatrix& _rViewTransformation ) const;
/** determines whether or not our control is printable
@@ -626,6 +571,13 @@ namespace sdr { namespace contact {
struct GuardAccess { friend class VOCGuard; private: GuardAccess() { } };
::osl::Mutex& getMutex( GuardAccess ) const { return m_aMutex; }
+ const ViewContactOfUnoControl&
+ getViewContact() const
+ {
+ ENSURE_OR_THROW( !impl_isDisposed_nofail(), "already disposed" );
+ return static_cast< const ViewContactOfUnoControl& >( m_pAntiImpl->GetViewContact() );
+ }
+
protected:
~ViewObjectContactOfUnoControl_Impl();
@@ -797,10 +749,11 @@ namespace sdr { namespace contact {
This method cares for this, by retrieving the very original OutputDevice.
*/
- const OutputDevice& imp_getPageViewDevice_nothrow( const ObjectContactOfPageView& _rObjectContact ) const;
+ static const OutputDevice& imp_getPageViewDevice_nothrow( const ObjectContactOfPageView& _rObjectContact );
+ const OutputDevice& imp_getPageViewDevice_nothrow() const;
private:
- ViewObjectContactOfUnoControl_Impl(); // never implemented
+ ViewObjectContactOfUnoControl_Impl(); // never implemented
ViewObjectContactOfUnoControl_Impl( const ViewObjectContactOfUnoControl_Impl& ); // never implemented
ViewObjectContactOfUnoControl_Impl& operator=( const ViewObjectContactOfUnoControl_Impl& ); // never implemented
};
@@ -812,18 +765,65 @@ namespace sdr { namespace contact {
*/
class VOCGuard
{
- const ViewObjectContactOfUnoControl_Impl& m_rImpl;
- ::osl::MutexGuard m_aMutexGuard;
+ private:
+ ::osl::MutexGuard m_aMutexGuard;
public:
VOCGuard( const ViewObjectContactOfUnoControl_Impl& _rImpl )
- :m_rImpl( _rImpl )
- ,m_aMutexGuard( _rImpl.getMutex( ViewObjectContactOfUnoControl_Impl::GuardAccess() ) )
+ :m_aMutexGuard( _rImpl.getMutex( ViewObjectContactOfUnoControl_Impl::GuardAccess() ) )
{
}
};
//====================================================================
+ //= LazyControlCreationPrimitive2D
+ //====================================================================
+ class LazyControlCreationPrimitive2D : public ::drawinglayer::primitive2d::BasePrimitive2D
+ {
+ private:
+ typedef ::drawinglayer::primitive2d::BasePrimitive2D BasePrimitive2D;
+
+ protected:
+ virtual ::drawinglayer::primitive2d::Primitive2DSequence
+ get2DDecomposition(
+ const ::drawinglayer::geometry::ViewInformation2D& rViewInformation
+ ) const;
+
+ virtual ::drawinglayer::primitive2d::Primitive2DSequence
+ createLocalDecomposition(
+ const ::drawinglayer::geometry::ViewInformation2D& rViewInformation
+ ) const;
+
+ virtual ::basegfx::B2DRange
+ getB2DRange(
+ const ::drawinglayer::geometry::ViewInformation2D& rViewInformation
+ ) const;
+
+ public:
+ LazyControlCreationPrimitive2D( const ::rtl::Reference< ViewObjectContactOfUnoControl_Impl >& _pVOCImpl )
+ :m_pVOCImpl( _pVOCImpl )
+ {
+ ENSURE_OR_THROW( m_pVOCImpl.is(), "Illegal argument." );
+ getTransformation( m_pVOCImpl->getViewContact(), m_aTransformation );
+ }
+
+ virtual bool operator==(const BasePrimitive2D& rPrimitive) const;
+
+ // declare unique ID for this primitive class
+ DeclPrimitrive2DIDBlock()
+
+ static void getTransformation( const ViewContactOfUnoControl& _rVOC, ::basegfx::B2DHomMatrix& _out_Transformation );
+
+ private:
+ ::rtl::Reference< ViewObjectContactOfUnoControl_Impl > m_pVOCImpl;
+ /** The geometry is part of the identity of an primitive, so we cannot calculate it on demand
+ (since the data the calculation is based on might have changed then), but need to calc
+ it at construction time, and remember it.
+ */
+ ::basegfx::B2DHomMatrix m_aTransformation;
+ };
+
+ //====================================================================
//= ViewObjectContactOfUnoControl_Impl
//====================================================================
DBG_NAME( ViewObjectContactOfUnoControl_Impl )
@@ -834,10 +834,20 @@ namespace sdr { namespace contact {
,m_bControlIsVisible( false )
,m_bIsDesignModeListening( false )
,m_eControlDesignMode( eUnknown )
+ ,m_aZoomLevelNormalization()
{
DBG_CTOR( ViewObjectContactOfUnoControl_Impl, NULL );
DBG_ASSERT( m_pAntiImpl, "ViewObjectContactOfUnoControl_Impl::ViewObjectContactOfUnoControl_Impl: invalid AntiImpl!" );
- }
+
+ const OutputDevice& rPageViewDevice( imp_getPageViewDevice_nothrow() );
+ m_aZoomLevelNormalization = rPageViewDevice.GetInverseViewTransformation();
+
+ ::basegfx::B2DHomMatrix aScaleNormalization;
+ MapMode aCurrentDeviceMapMode( rPageViewDevice.GetMapMode() );
+ aScaleNormalization.set( 0, 0, (double)aCurrentDeviceMapMode.GetScaleX() );
+ aScaleNormalization.set( 1, 1, (double)aCurrentDeviceMapMode.GetScaleY() );
+ m_aZoomLevelNormalization *= aScaleNormalization;
+ }
//--------------------------------------------------------------------
ViewObjectContactOfUnoControl_Impl::~ViewObjectContactOfUnoControl_Impl()
@@ -898,27 +908,21 @@ namespace sdr { namespace contact {
}
//--------------------------------------------------------------------
- void ViewObjectContactOfUnoControl_Impl::positionControlForPaint( const DisplayInfo& /* #i74769# _rDisplayInfo*/ ) const
- {
- if ( !m_aControl.is() )
- return;
-
- positionAndZoomControl();
- }
-
- //--------------------------------------------------------------------
- void ViewObjectContactOfUnoControl_Impl::positionAndZoomControl() const
+ void ViewObjectContactOfUnoControl_Impl::positionAndZoomControl( const basegfx::B2DHomMatrix& _rViewTransformation ) const
{
- OSL_PRECOND( m_pOutputDeviceForWindow && m_aControl.is(), "ViewObjectContactOfUnoControl_Impl::positionAndZoomControl: no output device or no control!" );
- if ( !m_pOutputDeviceForWindow || !m_aControl.is() )
+ OSL_PRECOND( ( m_pOutputDeviceForWindow != NULL ) && m_aControl.is(), "ViewObjectContactOfUnoControl_Impl::positionAndZoomControl: no output device or no control!" );
+ if ( ( m_pOutputDeviceForWindow == NULL ) || !m_aControl.is() )
return;
try
{
SdrUnoObj* pUnoObject( NULL );
if ( getUnoObject( pUnoObject ) )
- UnoControlContactHelper::positionControl_throw( m_aControl, pUnoObject->GetLogicRect(), m_pOutputDeviceForWindow );
- UnoControlContactHelper::setControlZoom( m_aControl, m_pOutputDeviceForWindow );
+ {
+ UnoControlContactHelper::adjustControlGeometry_throw( m_aControl, pUnoObject->GetLogicRect(), _rViewTransformation, m_aZoomLevelNormalization );
+ }
+ else
+ OSL_ENSURE( false, "ViewObjectContactOfUnoControl_Impl::positionAndZoomControl: no SdrUnoObj!" );
}
catch( const Exception& )
{
@@ -927,37 +931,6 @@ namespace sdr { namespace contact {
}
//--------------------------------------------------------------------
- bool ViewObjectContactOfUnoControl_Impl::ensureControl( const DisplayInfo& /*_rDisplayInfo*/ )
- {
- OSL_PRECOND( !impl_isDisposed_nofail(), "ViewObjectContactOfUnoControl_Impl::ensureControl: already disposed()" );
- if ( impl_isDisposed_nofail() )
- return false;
-
- const OutputDevice* pDeviceForControl( NULL );
-
- // if we're working for a page view, use the respective OutputDevice at the proper
- // PaintWindow. The DisplayInfo might only contain a temporary (virtual) device, which
- // is dangerous to remember
- // 2006-10-24 / #i70604# / frank.schoenheit@sun.com
- ObjectContactOfPageView* pPageViewContact = dynamic_cast< ObjectContactOfPageView* >( &m_pAntiImpl->GetObjectContact() );
- if ( pPageViewContact )
- pDeviceForControl = &imp_getPageViewDevice_nothrow( *pPageViewContact );
-
- if ( !pDeviceForControl && pPageViewContact)
- pDeviceForControl = pPageViewContact->TryToGetOutputDevice();
-
- DBG_ASSERT( pDeviceForControl, "ViewObjectContactOfUnoControl_Impl::ensureControl: no output device!" );
- if ( !pDeviceForControl )
- return false;
-
- SdrPageView* pPageView = m_pAntiImpl->GetObjectContact().TryToGetSdrPageView();
-
- ::std::auto_ptr< IPageViewAccess > pPVAccess;
- pPVAccess.reset( pPageView ? (IPageViewAccess*)new SdrPageViewAccess( *pPageView ) : (IPageViewAccess*)new DummyPageViewAccess() );
- return impl_ensureControl_nothrow( *pPVAccess, *pDeviceForControl );
- }
-
- //--------------------------------------------------------------------
bool ViewObjectContactOfUnoControl_Impl::ensureControl()
{
OSL_PRECOND( !impl_isDisposed_nofail(), "ViewObjectContactOfUnoControl_Impl::ensureControl: already disposed()" );
@@ -977,13 +950,21 @@ namespace sdr { namespace contact {
}
//--------------------------------------------------------------------
- const OutputDevice& ViewObjectContactOfUnoControl_Impl::imp_getPageViewDevice_nothrow( const ObjectContactOfPageView& _rObjectContact ) const
+ const OutputDevice& ViewObjectContactOfUnoControl_Impl::imp_getPageViewDevice_nothrow() const
+ {
+ ObjectContactOfPageView* pPageViewContact = dynamic_cast< ObjectContactOfPageView* >( &m_pAntiImpl->GetObjectContact() );
+ ENSURE_OR_THROW( pPageViewContact, "need a ObjectContactOfPageView." );
+ return imp_getPageViewDevice_nothrow( *pPageViewContact );
+ }
+
+ //--------------------------------------------------------------------
+ const OutputDevice& ViewObjectContactOfUnoControl_Impl::imp_getPageViewDevice_nothrow( const ObjectContactOfPageView& _rObjectContact )
{
// if the PageWindow has a patched PaintWindow, use the original PaintWindow
// this ensures that our control is _not_ re-created just because somebody
// (temporarily) changed the window to paint onto.
// #i72429# / 2007-02-20 / frank.schoenheit@sun.com
- const SdrPageWindow& rPageWindow( _rObjectContact.GetPageWindow() );
+ SdrPageWindow& rPageWindow( _rObjectContact.GetPageWindow() );
if ( rPageWindow.GetOriginalPaintWindow() )
return rPageWindow.GetOriginalPaintWindow()->GetOutputDevice();
@@ -1001,7 +982,7 @@ namespace sdr { namespace contact {
// Somebody requested a control for a new device, which means either of
// - our PageView's paint window changed since we were last here
// - we don't belong to a page view, and are simply painted onto different devices
- // The first sounds strange (doens't it?), the second means we could perhaps
+ // The first sounds strange (doens't it?), the second means we could perhaps
// optimize this in the future - there is no need to re-create the control every time,
// is it?
// #i74523# / 2007-02-15 / frank.schoenheit@sun.com
@@ -1063,44 +1044,37 @@ namespace sdr { namespace contact {
bool bSuccess = false;
try
{
- do
- {
- const ::rtl::OUString sControlServiceName( _rUnoObject.GetUnoControlTypeName() );
+ const ::rtl::OUString sControlServiceName( _rUnoObject.GetUnoControlTypeName() );
- Reference< XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() );
- if ( xFactory.is() )
- {
- _out_rControl = Reference< XControl >( xFactory->createInstance( sControlServiceName ), UNO_QUERY );
- }
- DBG_ASSERT( _out_rControl.is(), "ViewObjectContactOfUnoControl_Impl::createControlForDevice: no control could be created!" );
- if ( !_out_rControl.is() )
- break;
+ Reference< XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory(), UNO_SET_THROW );
+ _out_rControl = Reference< XControl >( xFactory->createInstance( sControlServiceName ), UNO_QUERY_THROW );
- // knit the model and the control
- _out_rControl.setModel( xControlModel );
+ // knit the model and the control
+ _out_rControl.setModel( xControlModel );
- UnoControlContactHelper::positionControl_throw( _out_rControl, _rUnoObject.GetLogicRect(), &_rDevice );
-
- // proper zoom
- UnoControlContactHelper::setControlZoom( _out_rControl, &_rDevice );
+ // proper geometry
+ UnoControlContactHelper::adjustControlGeometry_throw(
+ _out_rControl,
+ _rUnoObject.GetLogicRect(),
+ _rDevice.GetViewTransformation(),
+ _rDevice.GetInverseViewTransformation()
+ );
- // #107049# set design mode before peer is created,
- // this is also needed for accessibility
- _out_rControl.setDesignMode( _rPageView.isDesignMode() );
+ // #107049# set design mode before peer is created,
+ // this is also needed for accessibility
+ _out_rControl.setDesignMode( _rPageView.isDesignMode() );
- // adjust the initial visibility according to the visibility of the layer
- // 2003-06-03 - #110592# - fs@openoffice.org
- impl_adjustControlVisibilityToLayerVisibility_throw( _out_rControl, _rUnoObject, _rPageView, false, true );
+ // adjust the initial visibility according to the visibility of the layer
+ // 2003-06-03 - #110592# - fs@openoffice.org
+ impl_adjustControlVisibilityToLayerVisibility_throw( _out_rControl, _rUnoObject, _rPageView, false, true );
- // add the control to the respective control container
- // #108327# do this last
- Reference< XControlContainer > xControlContainer( _rPageView.getControlContainer( _rDevice ) );
- if ( xControlContainer.is() )
- xControlContainer->addControl( sControlServiceName, _out_rControl.getControl() );
+ // add the control to the respective control container
+ // #108327# do this last
+ Reference< XControlContainer > xControlContainer( _rPageView.getControlContainer( _rDevice ) );
+ if ( xControlContainer.is() )
+ xControlContainer->addControl( sControlServiceName, _out_rControl.getControl() );
- bSuccess = true;
- }
- while ( false );
+ bSuccess = true;
}
catch( const Exception& )
{
@@ -1257,18 +1231,16 @@ namespace sdr { namespace contact {
//--------------------------------------------------------------------
bool ViewObjectContactOfUnoControl_Impl::isPrintableControl() const
{
- if ( !m_aControl.is() )
+ SdrUnoObj* pUnoObject( NULL );
+ if ( !getUnoObject( pUnoObject ) )
return false;
bool bIsPrintable = false;
try
{
- Reference< XPropertySet > xModelProperties( m_aControl.getModel(), UNO_QUERY );
- Reference< XPropertySetInfo > xPropertyInfo( xModelProperties.is() ? xModelProperties->getPropertySetInfo() : Reference< XPropertySetInfo >() );
- const ::rtl::OUString sPrintablePropertyName( RTL_CONSTASCII_USTRINGPARAM( "Printable" ) );
-
- if ( xPropertyInfo.is() && xPropertyInfo->hasPropertyByName( sPrintablePropertyName ) )
- OSL_VERIFY( xModelProperties->getPropertyValue( sPrintablePropertyName ) >>= bIsPrintable );
+ Reference< XPropertySet > xModelProperties( pUnoObject->GetUnoControlModel(), UNO_QUERY_THROW );
+ static const ::rtl::OUString s_sPrintablePropertyName( RTL_CONSTASCII_USTRINGPARAM( "Printable" ) );
+ OSL_VERIFY( xModelProperties->getPropertyValue( s_sPrintablePropertyName ) >>= bIsPrintable );
}
catch( const Exception& )
{
@@ -1411,15 +1383,20 @@ namespace sdr { namespace contact {
if ( !xNewControl.is() )
return;
+ ENSURE_OR_THROW( m_pOutputDeviceForWindow, "calling this without /me having an output device should be impossible." );
+
DBG_ASSERT( xNewControl->getModel() == m_aControl.getModel(), "ViewObjectContactOfUnoControl_Impl::elementReplaced: another model at the new control?" );
// another model should - in the drawing layer - also imply another SdrUnoObj, which
// should also result in new ViewContact, and thus in new ViewObjectContacts
impl_switchControlListening_nothrow( false );
+ ControlHolder aNewControl( xNewControl );
+ aNewControl.setZoom( m_aControl.getZoom() );
+ aNewControl.setPosSize( m_aControl.getPosSize() );
+ aNewControl.setDesignMode( impl_isControlDesignMode_nothrow() );
+
m_aControl = xNewControl;
- positionAndZoomControl();
- m_aControl.setDesignMode( impl_isControlDesignMode_nothrow() );
m_bControlIsVisible = m_aControl.isVisible();
impl_switchControlListening_nothrow( true );
@@ -1449,30 +1426,96 @@ namespace sdr { namespace contact {
}
}
+ //====================================================================
+ //= LazyControlCreationPrimitive2D
+ //====================================================================
//--------------------------------------------------------------------
- bool ViewObjectContactOfUnoControl_Impl::belongsToDevice( const OutputDevice* _pDevice ) const
+ bool LazyControlCreationPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
{
- DBG_ASSERT( _pDevice, "ViewObjectContactOfUnoControl_Impl::belongsToDevice: invalid device!" );
+ if ( !BasePrimitive2D::operator==( rPrimitive ) )
+ return false;
- OSL_PRECOND( !impl_isDisposed_nofail(), "ViewObjectContactOfUnoControl_Impl::belongsToDevice: already disposed!" );
- if ( impl_isDisposed_nofail() )
+ const LazyControlCreationPrimitive2D* pRHS = dynamic_cast< const LazyControlCreationPrimitive2D* >( &rPrimitive );
+ if ( !pRHS )
return false;
- if ( m_pOutputDeviceForWindow )
- {
- if ( _pDevice == m_pOutputDeviceForWindow )
- return true;
+ if ( m_pVOCImpl != pRHS->m_pVOCImpl )
return false;
- }
- ObjectContactOfPageView* pPageViewContact = dynamic_cast< ObjectContactOfPageView* >( &m_pAntiImpl->GetObjectContact() );
- if ( pPageViewContact )
- return ( _pDevice == &imp_getPageViewDevice_nothrow( *pPageViewContact ) );
+ if ( m_aTransformation != pRHS->m_aTransformation )
+ return false;
- DBG_ERROR( "ViewObjectContactOfUnoControl_Impl::belongsToDevice: could not determine the device I belong to!" );
- return false;
+ return true;
+ }
+
+ //--------------------------------------------------------------------
+ void LazyControlCreationPrimitive2D::getTransformation( const ViewContactOfUnoControl& _rVOC, ::basegfx::B2DHomMatrix& _out_Transformation )
+ {
+ // Do use model data directly to create the correct geometry. Do NOT
+ // use getBoundRect()/getSnapRect() here; tese will use the sequence of
+ // primitives themselves in the long run.
+ const Rectangle aSdrGeoData( _rVOC.GetSdrUnoObj().GetGeoRect() );
+ const basegfx::B2DRange aRange(
+ aSdrGeoData.Left(),
+ aSdrGeoData.Top(),
+ aSdrGeoData.Right(),
+ aSdrGeoData.Bottom()
+ );
+
+ _out_Transformation.identity();
+ _out_Transformation.set( 0, 0, aRange.getWidth() );
+ _out_Transformation.set( 1, 1, aRange.getHeight() );
+ _out_Transformation.set( 0, 2, aRange.getMinX() );
+ _out_Transformation.set( 1, 2, aRange.getMinY() );
}
+ //--------------------------------------------------------------------
+ ::basegfx::B2DRange LazyControlCreationPrimitive2D::getB2DRange( const ::drawinglayer::geometry::ViewInformation2D& /*rViewInformation*/ ) const
+ {
+ ::basegfx::B2DRange aRange( 0.0, 0.0, 1.0, 1.0 );
+ aRange.transform( m_aTransformation );
+ return aRange;
+ }
+
+ //--------------------------------------------------------------------
+ ::drawinglayer::primitive2d::Primitive2DSequence LazyControlCreationPrimitive2D::get2DDecomposition( const ::drawinglayer::geometry::ViewInformation2D& _rViewInformation ) const
+ {
+ if ( m_pVOCImpl->hasControl() )
+ m_pVOCImpl->positionAndZoomControl( _rViewInformation.getObjectToViewTransformation() );
+ return BasePrimitive2D::get2DDecomposition( _rViewInformation );
+ }
+
+ //--------------------------------------------------------------------
+ ::drawinglayer::primitive2d::Primitive2DSequence LazyControlCreationPrimitive2D::createLocalDecomposition( const ::drawinglayer::geometry::ViewInformation2D& _rViewInformation ) const
+ {
+ // force control here to make it a VCL ChildWindow. Will be fetched
+ // and used below by getExistentControl()
+ m_pVOCImpl->ensureControl();
+ m_pVOCImpl->positionAndZoomControl( _rViewInformation.getObjectToViewTransformation() );
+
+ // get needed data
+ const ViewContactOfUnoControl& rViewContactOfUnoControl( m_pVOCImpl->getViewContact() );
+ Reference< XControlModel > xControlModel( rViewContactOfUnoControl.GetSdrUnoObj().GetUnoControlModel() );
+ const ControlHolder& rControl( m_pVOCImpl->getExistentControl() );
+
+ // check if we already have an XControl.
+ if ( !xControlModel.is() || !rControl.is() )
+ // use the default mechanism. This will create a ControlPrimitive2D without
+ // handing over a XControl. If not even a XControlModel exists, it will
+ // create the SdrObject fallback visualisation
+ return rViewContactOfUnoControl.getViewIndependentPrimitive2DSequence();
+
+ // create a primitive and hand over the existing xControl. This will
+ // allow the primitive to not need to create another one on demand.
+ const drawinglayer::primitive2d::Primitive2DReference xRetval( new ::drawinglayer::primitive2d::ControlPrimitive2D(
+ m_aTransformation, xControlModel, rControl.getControl() ) );
+
+ return drawinglayer::primitive2d::Primitive2DSequence(&xRetval, 1);
+ }
+
+ //--------------------------------------------------------------------
+ ImplPrimitrive2DIDBlock( LazyControlCreationPrimitive2D, PRIMITIVE2D_ID_SDRCONTROLPRIMITIVE2D )
+
//====================================================================
//= ViewObjectContactOfUnoControl
//====================================================================
@@ -1522,20 +1565,6 @@ namespace sdr { namespace contact {
}
//--------------------------------------------------------------------
- void ViewObjectContactOfUnoControl::positionControlForPaint( const DisplayInfo& _rDisplayInfo ) const
- {
- VOCGuard aGuard( *m_pImpl );
-
- // ensure we have a control. If we don't, then the Drawing Layer might be tempted to
- // never draw the complete form layer.
- // #i75095# / 2007-03-05 / frank.schoenheit@sun.com
- m_pImpl->ensureControl( _rDisplayInfo );
-
- // position the control
- m_pImpl->positionControlForPaint( _rDisplayInfo );
- }
-
- //--------------------------------------------------------------------
void ViewObjectContactOfUnoControl::ensureControlVisibility( bool _bVisible ) const
{
VOCGuard aGuard( *m_pImpl );
@@ -1582,70 +1611,32 @@ namespace sdr { namespace contact {
}
//--------------------------------------------------------------------
- bool ViewObjectContactOfUnoControl::belongsToDevice( const OutputDevice* _pDevice ) const
+ drawinglayer::primitive2d::Primitive2DSequence ViewObjectContactOfUnoControl::createPrimitive2DSequence(const DisplayInfo& /*rDisplayInfo*/) const
{
- VOCGuard aGuard( *m_pImpl );
- return m_pImpl->belongsToDevice( _pDevice );
+ if ( m_pImpl->isDisposed() )
+ // our control already died.
+ // TODO: Is it worth re-creating the control? Finally, this is a pathological situation, it means some instance
+ // disposed the control though it doesn't own it. So, /me thinks we should not bother here.
+ return drawinglayer::primitive2d::Primitive2DSequence();
+
+ ::drawinglayer::primitive2d::Primitive2DReference xPrimitive( new LazyControlCreationPrimitive2D( m_pImpl ) );
+ return ::drawinglayer::primitive2d::Primitive2DSequence( &xPrimitive, 1 );
}
//--------------------------------------------------------------------
- drawinglayer::primitive2d::Primitive2DSequence ViewObjectContactOfUnoControl::createPrimitive2DSequence(const DisplayInfo& rDisplayInfo) const
- {
- // force control here to make it a VCL ChildWindow. Will be fetched
- // and used below by getExistentControl()
- m_pImpl->ensureControl();
- m_pImpl->positionControlForPaint(rDisplayInfo);
-
- // get needed data
- const ViewContactOfUnoControl& rViewContactOfUnoControl(static_cast< const ViewContactOfUnoControl& >(GetViewContact()));
- Reference< XControlModel > xControlModel(rViewContactOfUnoControl.GetSdrUnoObj().GetUnoControlModel());
- const ControlHolder& rControl(m_pImpl->getExistentControl());
-
- // check if we already have a XControl.
- if(xControlModel.is() && rControl.is())
- {
- // create a primitive and hand over the existing xControl. This will
- // allow the primitive to not need to create another one on demand.
- // Do use model data directly to create the correct geometry. Do NOT
- // use getBoundRect()/getSnapRect() here; tese will use the sequence of
- // primitives themselves in the long run.
- const Rectangle aUnoControlModelData(rViewContactOfUnoControl.GetSdrUnoObj().GetGeoRect());
- const basegfx::B2DRange aRange(aUnoControlModelData.Left(), aUnoControlModelData.Top(), aUnoControlModelData.Right(), aUnoControlModelData.Bottom());
-
- // create object transform
- basegfx::B2DHomMatrix aTransform;
- aTransform.set(0, 0, aRange.getWidth());
- aTransform.set(1, 1, aRange.getHeight());
- aTransform.set(0, 2, aRange.getMinX());
- aTransform.set(1, 2, aRange.getMinY());
-
- // create control primitive with existing XControl
- const drawinglayer::primitive2d::Primitive2DReference xRetval(new drawinglayer::primitive2d::ControlPrimitive2D(
- aTransform, xControlModel, rControl.getControl()));
-
- return drawinglayer::primitive2d::Primitive2DSequence(&xRetval, 1);
- }
- else
- {
- // use the default mechanism. This will create a ControlPrimitive2D without
- // handing over a XControl. If not even a XControlModel exists, it will
- // create the SdrObject fallback visualisation
- return rViewContactOfUnoControl.getViewIndependentPrimitive2DSequence();
- }
- }
-
void ViewObjectContactOfUnoControl::propertyChange()
{
// graphical invalidate at all views
ActionChanged();
// #i93318# flush Primitive2DSequence to force recreation with updated XControlModel
- // since e.g. background color has changed and existing decompositions are evtl. no
+ // since e.g. background color has changed and existing decompositions are possibly no
// longer valid. Unfortunately this is not detected from ControlPrimitive2D::operator==
// since it only has a uno reference to the XControlModel
flushPrimitive2DSequence();
}
+ //--------------------------------------------------------------------
void ViewObjectContactOfUnoControl::ActionChanged()
{
// call parent
@@ -1721,6 +1712,14 @@ namespace sdr { namespace contact {
DBG_DTOR( UnoControlPrintOrPreviewContact, NULL );
}
+ //--------------------------------------------------------------------
+ drawinglayer::primitive2d::Primitive2DSequence UnoControlPrintOrPreviewContact::createPrimitive2DSequence(const DisplayInfo& rDisplayInfo ) const
+ {
+ if ( !m_pImpl->isPrintableControl() )
+ return drawinglayer::primitive2d::Primitive2DSequence();
+ return ViewObjectContactOfUnoControl::createPrimitive2DSequence( rDisplayInfo );
+ }
+
//====================================================================
//= UnoControlPDFExportContact
//====================================================================