1 /*************************************************************************
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * Copyright 2000, 2010 Oracle and/or its affiliates.
6 * OpenOffice.org - a multi-platform office productivity suite
8 * This file is part of OpenOffice.org.
10 * OpenOffice.org is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU Lesser General Public License version 3
12 * only, as published by the Free Software Foundation.
14 * OpenOffice.org is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Lesser General Public License version 3 for more details
18 * (a copy is included in the LICENSE file that accompanied this code).
20 * You should have received a copy of the GNU Lesser General Public License
21 * version 3 along with OpenOffice.org. If not, see
22 * <http://www.openoffice.org/license.html>
23 * for a copy of the LGPLv3 License.
25 ************************************************************************/
27 // MARKER(update_precomp.py): autogen include statement, do not remove
28 #include "precompiled_extensions.hxx"
30 #include "propertyhandler.hxx"
31 #include "formmetadata.hxx"
32 #include "formstrings.hxx"
33 #include "handlerhelper.hxx"
34 #include "cellbindinghelper.hxx"
36 /** === begin UNO includes === **/
37 #include <com/sun/star/inspection/XObjectInspectorUI.hpp>
38 #include <com/sun/star/awt/XControlModel.hpp>
39 #include <com/sun/star/drawing/XControlShape.hpp>
40 #include <com/sun/star/container/XMap.hpp>
41 #include <com/sun/star/inspection/XNumericControl.hpp>
42 #include <com/sun/star/util/MeasureUnit.hpp>
43 #include <com/sun/star/text/TextContentAnchorType.hpp>
44 #include <com/sun/star/lang/XServiceInfo.hpp>
45 #include <com/sun/star/sheet/XSpreadsheet.hpp>
46 #include <com/sun/star/table/XColumnRowRange.hpp>
47 #include <com/sun/star/table/XCellRange.hpp>
48 #include <com/sun/star/container/XChild.hpp>
49 #include <com/sun/star/form/XGridColumnFactory.hpp>
50 /** === end UNO includes === **/
52 #include <cppuhelper/interfacecontainer.hxx>
53 #include <comphelper/componentbase.hxx>
54 #include <tools/debug.hxx>
55 #include <tools/diagnose_ex.h>
57 //........................................................................
60 //........................................................................
62 /** === begin UNO using === **/
63 using ::com::sun::star::uno::Reference
;
64 using ::com::sun::star::uno::XInterface
;
65 using ::com::sun::star::uno::UNO_QUERY
;
66 using ::com::sun::star::uno::UNO_QUERY_THROW
;
67 using ::com::sun::star::uno::UNO_SET_THROW
;
68 using ::com::sun::star::uno::Exception
;
69 using ::com::sun::star::uno::RuntimeException
;
70 using ::com::sun::star::uno::Any
;
71 using ::com::sun::star::uno::makeAny
;
72 using ::com::sun::star::uno::Sequence
;
73 using ::com::sun::star::uno::Type
;
74 using ::com::sun::star::uno::XComponentContext
;
75 using ::com::sun::star::beans::UnknownPropertyException
;
76 using ::com::sun::star::beans::Property
;
77 using ::com::sun::star::awt::XControlModel
;
78 using ::com::sun::star::drawing::XControlShape
;
79 using ::com::sun::star::container::XMap
;
80 using ::com::sun::star::inspection::LineDescriptor
;
81 using ::com::sun::star::inspection::XPropertyControlFactory
;
82 using ::com::sun::star::lang::NullPointerException
;
83 using ::com::sun::star::beans::Optional
;
84 using ::com::sun::star::inspection::XNumericControl
;
85 using ::com::sun::star::drawing::XShape
;
86 using ::com::sun::star::beans::PropertyChangeEvent
;
87 using ::com::sun::star::lang::EventObject
;
88 using ::com::sun::star::beans::XPropertySet
;
89 using ::com::sun::star::beans::XPropertyChangeListener
;
90 using ::com::sun::star::text::TextContentAnchorType
;
91 using ::com::sun::star::text::TextContentAnchorType_AT_PARAGRAPH
;
92 using ::com::sun::star::text::TextContentAnchorType_AS_CHARACTER
;
93 using ::com::sun::star::beans::XPropertySetInfo
;
94 using ::com::sun::star::inspection::XObjectInspectorUI
;
95 using ::com::sun::star::lang::XServiceInfo
;
96 using ::com::sun::star::sheet::XSpreadsheet
;
97 using ::com::sun::star::table::XColumnRowRange
;
98 using ::com::sun::star::table::XTableColumns
;
99 using ::com::sun::star::table::XTableRows
;
100 using ::com::sun::star::table::XCellRange
;
101 using ::com::sun::star::container::XIndexAccess
;
102 using ::com::sun::star::container::XChild
;
103 using ::com::sun::star::form::XGridColumnFactory
;
104 /** === end UNO using === **/
105 namespace MeasureUnit
= ::com::sun::star::util::MeasureUnit
;
107 typedef ::com::sun::star::awt::Point AwtPoint
;
108 typedef ::com::sun::star::awt::Size AwtSize
;
110 #define ANCHOR_TO_SHEET 0
111 #define ANCHOR_TO_CELL 1
113 //====================================================================
114 //= BroadcastHelperBase
115 //====================================================================
116 class BroadcastHelperBase
119 BroadcastHelperBase( ::osl::Mutex
& _rMutex
)
120 :maBHelper( _rMutex
)
125 ::cppu::OBroadcastHelper
& getBroadcastHelper() { return maBHelper
; }
128 ::cppu::OBroadcastHelper maBHelper
;
131 //====================================================================
132 //= ShapeGeometryChangeNotifier - declaration
133 //====================================================================
134 /** helper class to work around the ...unfortunate implementation of property change broadcasts
135 in the XShape implementation, which broadcasts way too generous and unspecified
137 typedef ::comphelper::ComponentBase ShapeGeometryChangeNotifier_CBase
;
138 typedef ::cppu::WeakImplHelper1
< ::com::sun::star::beans::XPropertyChangeListener
139 > ShapeGeometryChangeNotifier_IBase
;
141 class ShapeGeometryChangeNotifier
:public BroadcastHelperBase
142 ,public ShapeGeometryChangeNotifier_CBase
143 ,public ShapeGeometryChangeNotifier_IBase
146 ShapeGeometryChangeNotifier( ::cppu::OWeakObject
& _rParent
, ::osl::Mutex
& _rParentMutex
, const Reference
< XShape
>& _shape
)
147 :BroadcastHelperBase( _rParentMutex
)
148 ,ShapeGeometryChangeNotifier_CBase( BroadcastHelperBase::getBroadcastHelper(), ::comphelper::ComponentBase::NoInitializationNeeded() )
149 ,ShapeGeometryChangeNotifier_IBase()
150 ,m_rParent( _rParent
)
151 ,m_aPropertyChangeListeners( _rParentMutex
)
154 ENSURE_OR_THROW( m_xShape
.is(), "illegal shape!" );
158 // property change broadcasting
159 void addPropertyChangeListener( const Reference
< XPropertyChangeListener
>& _listener
)
161 m_aPropertyChangeListeners
.addInterface( _listener
);
163 void removePropertyChangeListener( const Reference
< XPropertyChangeListener
>& _listener
)
165 m_aPropertyChangeListeners
.removeInterface( _listener
);
168 // XComponent equivalent
171 ::osl::MutexGuard
aGuard( getMutex() );
172 impl_dispose_nothrow();
176 virtual void SAL_CALL
acquire( ) throw ()
181 virtual void SAL_CALL
release( ) throw ()
186 // XPropertyChangeListener
187 virtual void SAL_CALL
propertyChange( const PropertyChangeEvent
& _event
) throw (RuntimeException
);
190 virtual void SAL_CALL
disposing( const EventObject
& _event
) throw (RuntimeException
);
193 virtual ~ShapeGeometryChangeNotifier()
195 if ( !getBroadcastHelper().bDisposed
)
203 ::cppu::OBroadcastHelper
& getBroadcastHelper() { return BroadcastHelperBase::getBroadcastHelper(); }
206 void impl_init_nothrow();
207 void impl_dispose_nothrow();
210 ::cppu::OWeakObject
& m_rParent
;
211 ::cppu::OInterfaceContainerHelper m_aPropertyChangeListeners
;
212 Reference
< XShape
> m_xShape
;
215 //====================================================================
216 //= FormGeometryHandler - declaration
217 //====================================================================
218 class FormGeometryHandler
;
219 typedef HandlerComponentBase
< FormGeometryHandler
> FormGeometryHandler_Base
;
220 /** a property handler for any virtual string properties
222 class FormGeometryHandler
: public FormGeometryHandler_Base
226 const Reference
< XComponentContext
>& _rxContext
229 static ::rtl::OUString SAL_CALL
getImplementationName_static( ) throw (RuntimeException
);
230 static Sequence
< ::rtl::OUString
> SAL_CALL
getSupportedServiceNames_static( ) throw (RuntimeException
);
233 ~FormGeometryHandler();
236 // XPropertyHandler overriables
237 virtual Any SAL_CALL
getPropertyValue( const ::rtl::OUString
& _rPropertyName
) throw (UnknownPropertyException
, RuntimeException
);
238 virtual void SAL_CALL
setPropertyValue( const ::rtl::OUString
& _rPropertyName
, const Any
& _rValue
) throw (UnknownPropertyException
, RuntimeException
);
239 virtual LineDescriptor SAL_CALL
describePropertyLine( const ::rtl::OUString
& _rPropertyName
, const ::com::sun::star::uno::Reference
< ::com::sun::star::inspection::XPropertyControlFactory
>& _rxControlFactory
) throw (::com::sun::star::beans::UnknownPropertyException
, ::com::sun::star::lang::NullPointerException
, ::com::sun::star::uno::RuntimeException
);
240 virtual void SAL_CALL
addPropertyChangeListener( const ::com::sun::star::uno::Reference
< ::com::sun::star::beans::XPropertyChangeListener
>& _rxListener
) throw (::com::sun::star::uno::RuntimeException
);
241 virtual void SAL_CALL
removePropertyChangeListener( const ::com::sun::star::uno::Reference
< ::com::sun::star::beans::XPropertyChangeListener
>& _rxListener
) throw (::com::sun::star::uno::RuntimeException
);
242 virtual Sequence
< ::rtl::OUString
> SAL_CALL
getActuatingProperties( ) throw (RuntimeException
);
243 virtual void SAL_CALL
actuatingPropertyChanged( const ::rtl::OUString
& _rActuatingPropertyName
, const Any
& _rNewValue
, const Any
& _rOldValue
, const Reference
< XObjectInspectorUI
>& _rxInspectorUI
, sal_Bool _bFirstTimeInit
) throw (NullPointerException
, RuntimeException
);
245 // OComponentHandler overridables
246 virtual void SAL_CALL
disposing();
248 // PropertyHandler overridables
249 virtual Sequence
< Property
> SAL_CALL
doDescribeSupportedProperties() const;
252 virtual void onNewComponent();
255 bool impl_haveTextAnchorType_nothrow() const;
256 bool impl_haveSheetAnchorType_nothrow() const;
257 void impl_setSheetAnchorType_nothrow( const sal_Int32 _nAnchorType
) const;
260 Reference
< XControlShape
> m_xAssociatedShape
;
261 Reference
< XPropertySet
> m_xShapeProperties
;
262 ::rtl::Reference
< ShapeGeometryChangeNotifier
> m_xChangeNotifier
;
265 //====================================================================
266 //= FormGeometryHandler - implementation
267 //====================================================================
268 DBG_NAME( FormGeometryHandler
)
269 //--------------------------------------------------------------------
270 FormGeometryHandler::FormGeometryHandler( const Reference
< XComponentContext
>& _rxContext
)
271 :FormGeometryHandler_Base( _rxContext
)
273 DBG_CTOR( FormGeometryHandler
, NULL
);
276 //--------------------------------------------------------------------
277 FormGeometryHandler::~FormGeometryHandler( )
279 if ( !rBHelper
.bDisposed
)
285 DBG_DTOR( FormGeometryHandler
, NULL
);
288 //--------------------------------------------------------------------
289 void FormGeometryHandler::onNewComponent()
291 if ( m_xChangeNotifier
.is() )
293 m_xChangeNotifier
->dispose();
294 m_xChangeNotifier
.clear();
296 m_xAssociatedShape
.clear();
297 m_xShapeProperties
.clear();
299 FormGeometryHandler_Base::onNewComponent();
303 Reference
< XControlModel
> xControlModel( m_xComponent
, UNO_QUERY
);
304 if ( xControlModel
.is() )
306 // do not ask the map for shapes for grid control columns ....
307 Reference
< XChild
> xCompChild( m_xComponent
, UNO_QUERY_THROW
);
308 Reference
< XGridColumnFactory
> xCheckGrid( xCompChild
->getParent(), UNO_QUERY
);
309 if ( !xCheckGrid
.is() )
311 Reference
< XMap
> xControlMap( m_aContext
.getContextValueByAsciiName( "ControlShapeAccess" ), UNO_QUERY_THROW
);
312 m_xAssociatedShape
.set( xControlMap
->get( makeAny( xControlModel
) ), UNO_QUERY_THROW
);
313 m_xShapeProperties
.set( m_xAssociatedShape
, UNO_QUERY_THROW
);
317 catch( const Exception
& )
319 DBG_UNHANDLED_EXCEPTION();
322 if ( m_xAssociatedShape
.is() )
323 m_xChangeNotifier
= new ShapeGeometryChangeNotifier( *this, m_aMutex
, m_xAssociatedShape
.get() );
326 //--------------------------------------------------------------------
327 ::rtl::OUString SAL_CALL
FormGeometryHandler::getImplementationName_static( ) throw (RuntimeException
)
329 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.extensions.FormGeometryHandler" ) );
332 //--------------------------------------------------------------------
333 Sequence
< ::rtl::OUString
> SAL_CALL
FormGeometryHandler::getSupportedServiceNames_static( ) throw (RuntimeException
)
335 Sequence
< ::rtl::OUString
> aSupported( 1 );
336 aSupported
[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.form.inspection.FormGeometryHandler" ) );
340 //--------------------------------------------------------------------
341 Any SAL_CALL
FormGeometryHandler::getPropertyValue( const ::rtl::OUString
& _rPropertyName
) throw (UnknownPropertyException
, RuntimeException
)
343 ::osl::MutexGuard
aGuard( m_aMutex
);
344 PropertyId
nPropId( impl_getPropertyId_throw( _rPropertyName
) );
346 ENSURE_OR_THROW2( m_xAssociatedShape
.is(), "internal error: properties, but no shape!", *this );
347 ENSURE_OR_THROW2( m_xShapeProperties
.is(), "internal error: no shape properties!", *this );
354 case PROPERTY_ID_POSITIONX
:
355 aReturn
<<= m_xAssociatedShape
->getPosition().X
;
357 case PROPERTY_ID_POSITIONY
:
358 aReturn
<<= m_xAssociatedShape
->getPosition().Y
;
360 case PROPERTY_ID_WIDTH
:
361 aReturn
<<= m_xAssociatedShape
->getSize().Width
;
363 case PROPERTY_ID_HEIGHT
:
364 aReturn
<<= m_xAssociatedShape
->getSize().Height
;
366 case PROPERTY_ID_TEXT_ANCHOR_TYPE
:
367 aReturn
= m_xShapeProperties
->getPropertyValue( PROPERTY_ANCHOR_TYPE
);
368 OSL_ENSURE( aReturn
.hasValue(), "FormGeometryHandler::getPropertyValue: illegal anchor type!" );
370 case PROPERTY_ID_SHEET_ANCHOR_TYPE
:
372 Reference
< XSpreadsheet
> xAnchorSheet( m_xShapeProperties
->getPropertyValue( PROPERTY_ANCHOR
), UNO_QUERY
);
373 aReturn
<<= sal_Int32( xAnchorSheet
.is() ? ANCHOR_TO_SHEET
: ANCHOR_TO_CELL
);
378 OSL_ENSURE( false, "FormGeometryHandler::getPropertyValue: huh?" );
382 catch( const Exception
& )
384 DBG_UNHANDLED_EXCEPTION();
389 //--------------------------------------------------------------------
390 void SAL_CALL
FormGeometryHandler::setPropertyValue( const ::rtl::OUString
& _rPropertyName
, const Any
& _rValue
) throw (UnknownPropertyException
, RuntimeException
)
392 ::osl::MutexGuard
aGuard( m_aMutex
);
393 PropertyId
nPropId( impl_getPropertyId_throw( _rPropertyName
) );
395 ENSURE_OR_THROW2( m_xAssociatedShape
.is(), "internal error: properties, but no shape!", *this );
396 ENSURE_OR_THROW2( m_xShapeProperties
.is(), "internal error: properties, but no shape!", *this );
402 case PROPERTY_ID_POSITIONX
:
403 case PROPERTY_ID_POSITIONY
:
405 sal_Int32
nPosition(0);
406 OSL_VERIFY( _rValue
>>= nPosition
);
408 AwtPoint
aPos( m_xAssociatedShape
->getPosition() );
409 if ( nPropId
== PROPERTY_ID_POSITIONX
)
413 m_xAssociatedShape
->setPosition( aPos
);
417 case PROPERTY_ID_WIDTH
:
418 case PROPERTY_ID_HEIGHT
:
421 OSL_VERIFY( _rValue
>>= nSize
);
423 AwtSize
aSize( m_xAssociatedShape
->getSize() );
424 if ( nPropId
== PROPERTY_ID_WIDTH
)
427 aSize
.Height
= nSize
;
428 m_xAssociatedShape
->setSize( aSize
);
432 case PROPERTY_ID_TEXT_ANCHOR_TYPE
:
433 m_xShapeProperties
->setPropertyValue( PROPERTY_ANCHOR_TYPE
, _rValue
);
436 case PROPERTY_ID_SHEET_ANCHOR_TYPE
:
438 sal_Int32 nSheetAnchorType
= 0;
439 OSL_VERIFY( _rValue
>>= nSheetAnchorType
);
440 impl_setSheetAnchorType_nothrow( nSheetAnchorType
);
445 OSL_ENSURE( false, "FormGeometryHandler::getPropertyValue: huh?" );
449 catch( const Exception
& )
451 DBG_UNHANDLED_EXCEPTION();
455 //--------------------------------------------------------------------
456 LineDescriptor SAL_CALL
FormGeometryHandler::describePropertyLine( const ::rtl::OUString
& _rPropertyName
,
457 const Reference
< XPropertyControlFactory
>& _rxControlFactory
)
458 throw (UnknownPropertyException
, NullPointerException
, RuntimeException
)
460 ::osl::MutexGuard
aGuard( m_aMutex
);
461 PropertyId
nPropId( impl_getPropertyId_throw( _rPropertyName
) );
463 LineDescriptor
aLineDesc( PropertyHandler::describePropertyLine( _rPropertyName
, _rxControlFactory
) );
466 bool bIsSize
= false;
469 case PROPERTY_ID_WIDTH
:
470 case PROPERTY_ID_HEIGHT
:
473 case PROPERTY_ID_POSITIONX
:
474 case PROPERTY_ID_POSITIONY
:
476 Optional
< double > aZero( sal_True
, 0 );
477 Optional
< double > aValueNotPresent( sal_False
, 0 );
478 aLineDesc
.Control
= PropertyHandlerHelper::createNumericControl(
479 _rxControlFactory
, 2, bIsSize
? aZero
: aValueNotPresent
, aValueNotPresent
, sal_False
);
481 Reference
< XNumericControl
> xNumericControl( aLineDesc
.Control
, UNO_QUERY_THROW
);
482 xNumericControl
->setValueUnit( MeasureUnit::MM_100TH
);
483 xNumericControl
->setDisplayUnit( impl_getDocumentMeasurementUnit_throw() );
487 case PROPERTY_ID_TEXT_ANCHOR_TYPE
:
488 case PROPERTY_ID_SHEET_ANCHOR_TYPE
:
489 // default handling from PropertyHandler is sufficient
493 OSL_ENSURE( false, "FormGeometryHandler::describePropertyLine: huh?" );
497 catch( const Exception
& )
499 DBG_UNHANDLED_EXCEPTION();
504 //--------------------------------------------------------------------
505 void SAL_CALL
FormGeometryHandler::addPropertyChangeListener( const Reference
< XPropertyChangeListener
>& _listener
) throw (RuntimeException
)
507 ::osl::MutexGuard
aGuard( m_aMutex
);
508 OSL_PRECOND( m_xChangeNotifier
.is(), "FormGeometryHandler::addPropertyChangeListener: no notified, implies no shape!?" );
509 if ( m_xChangeNotifier
.is() )
510 m_xChangeNotifier
->addPropertyChangeListener( _listener
);
513 //--------------------------------------------------------------------
514 void SAL_CALL
FormGeometryHandler::removePropertyChangeListener( const Reference
< XPropertyChangeListener
>& _listener
) throw (RuntimeException
)
516 ::osl::MutexGuard
aGuard( m_aMutex
);
517 OSL_PRECOND( m_xChangeNotifier
.is(), "FormGeometryHandler::removePropertyChangeListener: no notified, implies no shape!?" );
518 if ( m_xChangeNotifier
.is() )
519 m_xChangeNotifier
->removePropertyChangeListener( _listener
);
522 //--------------------------------------------------------------------
523 Sequence
< ::rtl::OUString
> SAL_CALL
FormGeometryHandler::getActuatingProperties( ) throw (RuntimeException
)
525 Sequence
< ::rtl::OUString
> aInterestedIn(1);
526 aInterestedIn
[0] = PROPERTY_TEXT_ANCHOR_TYPE
;
527 return aInterestedIn
;
530 //--------------------------------------------------------------------
531 void SAL_CALL
FormGeometryHandler::actuatingPropertyChanged( const ::rtl::OUString
& _rActuatingPropertyName
, const Any
& _rNewValue
, const Any
& /*_rOldValue*/, const Reference
< XObjectInspectorUI
>& _rxInspectorUI
, sal_Bool
/*_bFirstTimeInit*/ ) throw (NullPointerException
, RuntimeException
)
533 if ( !_rxInspectorUI
.is() )
534 throw NullPointerException();
536 ::osl::MutexGuard
aGuard( m_aMutex
);
537 PropertyId
nActuatingPropId( impl_getPropertyId_throw( _rActuatingPropertyName
) );
539 switch ( nActuatingPropId
)
541 case PROPERTY_ID_TEXT_ANCHOR_TYPE
:
543 TextContentAnchorType
eAnchorType( TextContentAnchorType_AT_PARAGRAPH
);
544 OSL_VERIFY( _rNewValue
>>= eAnchorType
);
545 _rxInspectorUI
->enablePropertyUI( PROPERTY_POSITIONX
, eAnchorType
!= TextContentAnchorType_AS_CHARACTER
);
549 OSL_ENSURE( false, "FormGeometryHandler::actuatingPropertyChanged: not registered for this property!" );
554 //--------------------------------------------------------------------
555 Sequence
< Property
> SAL_CALL
FormGeometryHandler::doDescribeSupportedProperties() const
557 if ( !m_xAssociatedShape
.is() )
558 return Sequence
< Property
>();
560 ::std::vector
< Property
> aProperties
;
562 addInt32PropertyDescription( aProperties
, PROPERTY_POSITIONX
);
563 addInt32PropertyDescription( aProperties
, PROPERTY_POSITIONY
);
564 addInt32PropertyDescription( aProperties
, PROPERTY_WIDTH
);
565 addInt32PropertyDescription( aProperties
, PROPERTY_HEIGHT
);
567 if ( impl_haveTextAnchorType_nothrow() )
568 implAddPropertyDescription( aProperties
, PROPERTY_TEXT_ANCHOR_TYPE
, ::cppu::UnoType
< TextContentAnchorType
>::get() );
570 if ( impl_haveSheetAnchorType_nothrow() )
571 addInt32PropertyDescription( aProperties
, PROPERTY_SHEET_ANCHOR_TYPE
);
573 return Sequence
< Property
>( &(*aProperties
.begin()), aProperties
.size() );
576 //--------------------------------------------------------------------
577 void SAL_CALL
FormGeometryHandler::disposing()
579 FormGeometryHandler_Base::disposing();
581 if ( m_xChangeNotifier
.is() )
583 m_xChangeNotifier
->dispose();
584 m_xChangeNotifier
.clear();
588 //--------------------------------------------------------------------
589 bool FormGeometryHandler::impl_haveTextAnchorType_nothrow() const
591 ENSURE_OR_THROW( m_xShapeProperties
.is(), "not to be called without shape properties" );
594 Reference
< XPropertySetInfo
> xPSI( m_xShapeProperties
->getPropertySetInfo(), UNO_SET_THROW
);
595 if ( xPSI
->hasPropertyByName( PROPERTY_ANCHOR_TYPE
) )
598 catch( const Exception
& )
600 DBG_UNHANDLED_EXCEPTION();
605 //--------------------------------------------------------------------
606 bool FormGeometryHandler::impl_haveSheetAnchorType_nothrow() const
608 ENSURE_OR_THROW( m_xShapeProperties
.is(), "not to be called without shape properties" );
611 Reference
< XPropertySetInfo
> xPSI( m_xShapeProperties
->getPropertySetInfo(), UNO_SET_THROW
);
612 if ( !xPSI
->hasPropertyByName( PROPERTY_ANCHOR
) )
614 Reference
< XServiceInfo
> xSI( m_xAssociatedShape
, UNO_QUERY_THROW
);
615 if ( xSI
->supportsService( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.Shape" ) ) ) )
618 catch( const Exception
& )
620 DBG_UNHANDLED_EXCEPTION();
625 //--------------------------------------------------------------------
628 static sal_Int32
lcl_getLowerBoundRowOrColumn( const Reference
< XIndexAccess
>& _rxRowsOrColumns
, const bool _bRows
,
629 const AwtPoint
& _rRelativePosition
)
631 sal_Int32 nAccumulated
= 0;
633 const sal_Int32
& rRelativePos
= _bRows
? _rRelativePosition
.Y
: _rRelativePosition
.X
;
635 sal_Int32 nElements
= _rxRowsOrColumns
->getCount();
636 sal_Int32 currentPos
= 0;
637 for ( currentPos
=0; currentPos
<nElements
; ++currentPos
)
639 Reference
< XPropertySet
> xRowOrColumn( _rxRowsOrColumns
->getByIndex( currentPos
), UNO_QUERY_THROW
);
641 sal_Bool bIsVisible
= sal_True
;
642 OSL_VERIFY( xRowOrColumn
->getPropertyValue( PROPERTY_IS_VISIBLE
) >>= bIsVisible
);
646 sal_Int32
nHeightOrWidth( 0 );
647 OSL_VERIFY( xRowOrColumn
->getPropertyValue( _bRows
? PROPERTY_HEIGHT
: PROPERTY_WIDTH
) >>= nHeightOrWidth
);
649 if ( nAccumulated
+ nHeightOrWidth
> rRelativePos
)
652 nAccumulated
+= nHeightOrWidth
;
659 //--------------------------------------------------------------------
660 void FormGeometryHandler::impl_setSheetAnchorType_nothrow( const sal_Int32 _nAnchorType
) const
662 ENSURE_OR_THROW( m_xShapeProperties
.is(), "illegal to be called without shape properties." );
665 CellBindingHelper
aHelper( m_xComponent
, impl_getContextDocument_nothrow() );
666 // find the sheet which the control belongs to
667 Reference
< XSpreadsheet
> xSheet
;
668 aHelper
.getControlSheetIndex( xSheet
);
670 switch ( _nAnchorType
)
672 case ANCHOR_TO_SHEET
:
673 OSL_ENSURE( xSheet
.is(),
674 "FormGeometryHandler::impl_setSheetAnchorType_nothrow: sheet not found!" );
677 AwtPoint
aPreservePosition( m_xAssociatedShape
->getPosition() );
678 m_xShapeProperties
->setPropertyValue( PROPERTY_ANCHOR
, makeAny( xSheet
) );
679 m_xAssociatedShape
->setPosition( aPreservePosition
);
685 Reference
< XColumnRowRange
> xColsRows( xSheet
, UNO_QUERY_THROW
);
687 // get the current anchor
688 Reference
< XSpreadsheet
> xCurrentAnchor
;
689 OSL_VERIFY( m_xShapeProperties
->getPropertyValue( PROPERTY_ANCHOR
) >>= xCurrentAnchor
);
690 OSL_ENSURE( xCurrentAnchor
.is(), "FormGeometryHandler::impl_setSheetAnchorType_nothrow: only to be called when currently anchored to a sheet!" );
692 // get the current position
693 AwtPoint
aRelativePosition( m_xAssociatedShape
->getPosition() );
695 Reference
< XTableColumns
> xCols( xColsRows
->getColumns(), UNO_SET_THROW
);
696 sal_Int32 nNewAnchorCol
= lcl_getLowerBoundRowOrColumn( xCols
.get(), false, aRelativePosition
);
698 Reference
< XTableRows
> xRows( xColsRows
->getRows(), UNO_SET_THROW
);
699 sal_Int32 nNewAnchorRow
= lcl_getLowerBoundRowOrColumn( xRows
.get(), true, aRelativePosition
);
701 Reference
< XCellRange
> xSheetCellRange( xSheet
, UNO_QUERY_THROW
);
702 Any
aNewAnchorCell( xSheetCellRange
->getCellByPosition( nNewAnchorCol
, nNewAnchorRow
) );
703 m_xShapeProperties
->setPropertyValue( PROPERTY_ANCHOR
, aNewAnchorCell
);
708 OSL_ENSURE( false, "FormGeometryHandler::impl_setSheetAnchorType_nothrow: illegal anchor type!" );
712 catch( const Exception
& )
714 DBG_UNHANDLED_EXCEPTION();
718 //====================================================================
719 //= ShapeGeometryChangeNotifier - implementation
720 //====================================================================
723 struct EventTranslation
725 ::rtl::OUString sPropertyName
;
726 Any aNewPropertyValue
;
728 EventTranslation( const ::rtl::OUString
& _propertyName
, const Any
& _newPropertyValue
)
729 :sPropertyName( _propertyName
)
730 ,aNewPropertyValue( _newPropertyValue
)
736 //--------------------------------------------------------------------
737 void SAL_CALL
ShapeGeometryChangeNotifier::propertyChange( const PropertyChangeEvent
& _event
) throw (RuntimeException
)
739 ::comphelper::ComponentMethodGuard
aGuard( *this );
741 ::std::vector
< EventTranslation
> aEventTranslations
;
742 aEventTranslations
.reserve(2);
744 if ( _event
.PropertyName
.equalsAscii( "Position" ) )
746 AwtPoint aPos
= m_xShape
->getPosition();
747 aEventTranslations
.push_back( EventTranslation( PROPERTY_POSITIONX
, makeAny( aPos
.X
) ) );
748 aEventTranslations
.push_back( EventTranslation( PROPERTY_POSITIONY
, makeAny( aPos
.Y
) ) );
750 else if ( _event
.PropertyName
.equalsAscii( "Size" ) )
752 AwtSize aSize
= m_xShape
->getSize();
753 aEventTranslations
.push_back( EventTranslation( PROPERTY_WIDTH
, makeAny( aSize
.Width
) ) );
754 aEventTranslations
.push_back( EventTranslation( PROPERTY_HEIGHT
, makeAny( aSize
.Height
) ) );
756 else if ( _event
.PropertyName
== PROPERTY_ANCHOR_TYPE
)
758 aEventTranslations
.push_back( EventTranslation( PROPERTY_TEXT_ANCHOR_TYPE
, makeAny( _event
.NewValue
) ) );
760 else if ( _event
.PropertyName
== PROPERTY_ANCHOR
)
762 aEventTranslations
.push_back( EventTranslation( PROPERTY_SHEET_ANCHOR_TYPE
, makeAny( _event
.NewValue
) ) );
765 PropertyChangeEvent
aTranslatedEvent( _event
);
766 aTranslatedEvent
.Source
= m_rParent
;
769 for ( ::std::vector
< EventTranslation
>::const_iterator t
= aEventTranslations
.begin();
770 t
!= aEventTranslations
.end();
774 aTranslatedEvent
.PropertyName
= t
->sPropertyName
;
775 aTranslatedEvent
.NewValue
= t
->aNewPropertyValue
;
776 m_aPropertyChangeListeners
.notifyEach( &XPropertyChangeListener::propertyChange
, aTranslatedEvent
);
780 //--------------------------------------------------------------------
781 void SAL_CALL
ShapeGeometryChangeNotifier::disposing( const EventObject
& /*_event*/ ) throw (RuntimeException
)
783 ::comphelper::ComponentMethodGuard
aGuard( *this );
784 impl_dispose_nothrow();
787 //--------------------------------------------------------------------
788 void ShapeGeometryChangeNotifier::impl_init_nothrow()
790 osl_incrementInterlockedCount( &m_refCount
);
793 Reference
< XPropertySet
> xShapeProperties( m_xShape
, UNO_QUERY_THROW
);
794 xShapeProperties
->addPropertyChangeListener( ::rtl::OUString(), this );
796 catch( const Exception
& )
798 DBG_UNHANDLED_EXCEPTION();
800 osl_decrementInterlockedCount( &m_refCount
);
803 //--------------------------------------------------------------------
804 void ShapeGeometryChangeNotifier::impl_dispose_nothrow()
808 Reference
< XPropertySet
> xShapeProperties( m_xShape
, UNO_QUERY_THROW
);
809 xShapeProperties
->removePropertyChangeListener( ::rtl::OUString(), this );
811 catch( const Exception
& )
813 DBG_UNHANDLED_EXCEPTION();
816 getBroadcastHelper().bDisposed
= true;
819 //........................................................................
821 //........................................................................
823 extern "C" void SAL_CALL
createRegistryInfo_FormGeometryHandler()
825 ::pcr::FormGeometryHandler::registerImplementation();