1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include "propertyhandler.hxx"
22 #include "formmetadata.hxx"
23 #include "formstrings.hxx"
24 #include "handlerhelper.hxx"
25 #include "cellbindinghelper.hxx"
27 #include <com/sun/star/inspection/XObjectInspectorUI.hpp>
28 #include <com/sun/star/awt/XControlModel.hpp>
29 #include <com/sun/star/drawing/XControlShape.hpp>
30 #include <com/sun/star/container/XMap.hpp>
31 #include <com/sun/star/inspection/XNumericControl.hpp>
32 #include <com/sun/star/util/MeasureUnit.hpp>
33 #include <com/sun/star/text/TextContentAnchorType.hpp>
34 #include <com/sun/star/lang/XServiceInfo.hpp>
35 #include <com/sun/star/sheet/XSpreadsheet.hpp>
36 #include <com/sun/star/table/XColumnRowRange.hpp>
37 #include <com/sun/star/table/XCellRange.hpp>
38 #include <com/sun/star/container/XChild.hpp>
39 #include <com/sun/star/form/XGridColumnFactory.hpp>
41 #include <cppuhelper/interfacecontainer.hxx>
42 #include <comphelper/componentbase.hxx>
43 #include <tools/debug.hxx>
44 #include <tools/diagnose_ex.h>
46 //........................................................................
49 //........................................................................
51 using ::com::sun::star::uno::Reference
;
52 using ::com::sun::star::uno::XInterface
;
53 using ::com::sun::star::uno::UNO_QUERY
;
54 using ::com::sun::star::uno::UNO_QUERY_THROW
;
55 using ::com::sun::star::uno::UNO_SET_THROW
;
56 using ::com::sun::star::uno::Exception
;
57 using ::com::sun::star::uno::RuntimeException
;
58 using ::com::sun::star::uno::Any
;
59 using ::com::sun::star::uno::makeAny
;
60 using ::com::sun::star::uno::Sequence
;
61 using ::com::sun::star::uno::Type
;
62 using ::com::sun::star::uno::XComponentContext
;
63 using ::com::sun::star::beans::UnknownPropertyException
;
64 using ::com::sun::star::beans::Property
;
65 using ::com::sun::star::awt::XControlModel
;
66 using ::com::sun::star::drawing::XControlShape
;
67 using ::com::sun::star::container::XMap
;
68 using ::com::sun::star::inspection::LineDescriptor
;
69 using ::com::sun::star::inspection::XPropertyControlFactory
;
70 using ::com::sun::star::lang::NullPointerException
;
71 using ::com::sun::star::beans::Optional
;
72 using ::com::sun::star::inspection::XNumericControl
;
73 using ::com::sun::star::drawing::XShape
;
74 using ::com::sun::star::beans::PropertyChangeEvent
;
75 using ::com::sun::star::lang::EventObject
;
76 using ::com::sun::star::beans::XPropertySet
;
77 using ::com::sun::star::beans::XPropertyChangeListener
;
78 using ::com::sun::star::text::TextContentAnchorType
;
79 using ::com::sun::star::text::TextContentAnchorType_AT_PARAGRAPH
;
80 using ::com::sun::star::text::TextContentAnchorType_AS_CHARACTER
;
81 using ::com::sun::star::beans::XPropertySetInfo
;
82 using ::com::sun::star::inspection::XObjectInspectorUI
;
83 using ::com::sun::star::lang::XServiceInfo
;
84 using ::com::sun::star::sheet::XSpreadsheet
;
85 using ::com::sun::star::table::XColumnRowRange
;
86 using ::com::sun::star::table::XTableColumns
;
87 using ::com::sun::star::table::XTableRows
;
88 using ::com::sun::star::table::XCellRange
;
89 using ::com::sun::star::container::XIndexAccess
;
90 using ::com::sun::star::container::XChild
;
91 using ::com::sun::star::form::XGridColumnFactory
;
93 namespace MeasureUnit
= ::com::sun::star::util::MeasureUnit
;
95 typedef ::com::sun::star::awt::Point AwtPoint
;
96 typedef ::com::sun::star::awt::Size AwtSize
;
98 #define ANCHOR_TO_SHEET 0
99 #define ANCHOR_TO_CELL 1
101 //====================================================================
102 //= BroadcastHelperBase
103 //====================================================================
104 class BroadcastHelperBase
107 BroadcastHelperBase( ::osl::Mutex
& _rMutex
)
108 :maBHelper( _rMutex
)
113 ::cppu::OBroadcastHelper
& getBroadcastHelper() { return maBHelper
; }
116 ::cppu::OBroadcastHelper maBHelper
;
119 //====================================================================
120 //= ShapeGeometryChangeNotifier - declaration
121 //====================================================================
122 /** helper class to work around the ...unfortunate implementation of property change broadcasts
123 in the XShape implementation, which broadcasts way too generous and unspecified
125 typedef ::comphelper::ComponentBase ShapeGeometryChangeNotifier_CBase
;
126 typedef ::cppu::WeakImplHelper1
< ::com::sun::star::beans::XPropertyChangeListener
127 > ShapeGeometryChangeNotifier_IBase
;
129 class ShapeGeometryChangeNotifier
:public BroadcastHelperBase
130 ,public ShapeGeometryChangeNotifier_CBase
131 ,public ShapeGeometryChangeNotifier_IBase
134 ShapeGeometryChangeNotifier( ::cppu::OWeakObject
& _rParent
, ::osl::Mutex
& _rParentMutex
, const Reference
< XShape
>& _shape
)
135 :BroadcastHelperBase( _rParentMutex
)
136 ,ShapeGeometryChangeNotifier_CBase( BroadcastHelperBase::getBroadcastHelper(), ::comphelper::ComponentBase::NoInitializationNeeded() )
137 ,ShapeGeometryChangeNotifier_IBase()
138 ,m_rParent( _rParent
)
139 ,m_aPropertyChangeListeners( _rParentMutex
)
142 ENSURE_OR_THROW( m_xShape
.is(), "illegal shape!" );
146 // property change broadcasting
147 void addPropertyChangeListener( const Reference
< XPropertyChangeListener
>& _listener
)
149 m_aPropertyChangeListeners
.addInterface( _listener
);
151 void removePropertyChangeListener( const Reference
< XPropertyChangeListener
>& _listener
)
153 m_aPropertyChangeListeners
.removeInterface( _listener
);
156 // XComponent equivalent
159 ::osl::MutexGuard
aGuard( getMutex() );
160 impl_dispose_nothrow();
164 virtual void SAL_CALL
acquire( ) throw ()
169 virtual void SAL_CALL
release( ) throw ()
174 // XPropertyChangeListener
175 virtual void SAL_CALL
propertyChange( const PropertyChangeEvent
& _event
) throw (RuntimeException
);
178 virtual void SAL_CALL
disposing( const EventObject
& _event
) throw (RuntimeException
);
181 virtual ~ShapeGeometryChangeNotifier()
183 if ( !getBroadcastHelper().bDisposed
)
191 ::cppu::OBroadcastHelper
& getBroadcastHelper() { return BroadcastHelperBase::getBroadcastHelper(); }
194 void impl_init_nothrow();
195 void impl_dispose_nothrow();
198 ::cppu::OWeakObject
& m_rParent
;
199 ::cppu::OInterfaceContainerHelper m_aPropertyChangeListeners
;
200 Reference
< XShape
> m_xShape
;
203 //====================================================================
204 //= FormGeometryHandler - declaration
205 //====================================================================
206 class FormGeometryHandler
;
207 typedef HandlerComponentBase
< FormGeometryHandler
> FormGeometryHandler_Base
;
208 /** a property handler for any virtual string properties
210 class FormGeometryHandler
: public FormGeometryHandler_Base
214 const Reference
< XComponentContext
>& _rxContext
217 static OUString SAL_CALL
getImplementationName_static( ) throw (RuntimeException
);
218 static Sequence
< OUString
> SAL_CALL
getSupportedServiceNames_static( ) throw (RuntimeException
);
221 ~FormGeometryHandler();
224 // XPropertyHandler overriables
225 virtual Any SAL_CALL
getPropertyValue( const OUString
& _rPropertyName
) throw (UnknownPropertyException
, RuntimeException
);
226 virtual void SAL_CALL
setPropertyValue( const OUString
& _rPropertyName
, const Any
& _rValue
) throw (UnknownPropertyException
, RuntimeException
);
227 virtual LineDescriptor SAL_CALL
describePropertyLine( const 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
);
228 virtual void SAL_CALL
addPropertyChangeListener( const ::com::sun::star::uno::Reference
< ::com::sun::star::beans::XPropertyChangeListener
>& _rxListener
) throw (::com::sun::star::uno::RuntimeException
);
229 virtual void SAL_CALL
removePropertyChangeListener( const ::com::sun::star::uno::Reference
< ::com::sun::star::beans::XPropertyChangeListener
>& _rxListener
) throw (::com::sun::star::uno::RuntimeException
);
230 virtual Sequence
< OUString
> SAL_CALL
getActuatingProperties( ) throw (RuntimeException
);
231 virtual void SAL_CALL
actuatingPropertyChanged( const OUString
& _rActuatingPropertyName
, const Any
& _rNewValue
, const Any
& _rOldValue
, const Reference
< XObjectInspectorUI
>& _rxInspectorUI
, sal_Bool _bFirstTimeInit
) throw (NullPointerException
, RuntimeException
);
233 // OComponentHandler overridables
234 virtual void SAL_CALL
disposing();
236 // PropertyHandler overridables
237 virtual Sequence
< Property
> SAL_CALL
doDescribeSupportedProperties() const;
240 virtual void onNewComponent();
243 bool impl_haveTextAnchorType_nothrow() const;
244 bool impl_haveSheetAnchorType_nothrow() const;
245 void impl_setSheetAnchorType_nothrow( const sal_Int32 _nAnchorType
) const;
248 Reference
< XControlShape
> m_xAssociatedShape
;
249 Reference
< XPropertySet
> m_xShapeProperties
;
250 ::rtl::Reference
< ShapeGeometryChangeNotifier
> m_xChangeNotifier
;
253 //====================================================================
254 //= FormGeometryHandler - implementation
255 //====================================================================
256 DBG_NAME( FormGeometryHandler
)
257 //--------------------------------------------------------------------
258 FormGeometryHandler::FormGeometryHandler( const Reference
< XComponentContext
>& _rxContext
)
259 :FormGeometryHandler_Base( _rxContext
)
261 DBG_CTOR( FormGeometryHandler
, NULL
);
264 //--------------------------------------------------------------------
265 FormGeometryHandler::~FormGeometryHandler( )
267 if ( !rBHelper
.bDisposed
)
273 DBG_DTOR( FormGeometryHandler
, NULL
);
276 //--------------------------------------------------------------------
277 void FormGeometryHandler::onNewComponent()
279 if ( m_xChangeNotifier
.is() )
281 m_xChangeNotifier
->dispose();
282 m_xChangeNotifier
.clear();
284 m_xAssociatedShape
.clear();
285 m_xShapeProperties
.clear();
287 FormGeometryHandler_Base::onNewComponent();
291 Reference
< XControlModel
> xControlModel( m_xComponent
, UNO_QUERY
);
292 if ( xControlModel
.is() )
294 // do not ask the map for shapes for grid control columns ....
295 Reference
< XChild
> xCompChild( m_xComponent
, UNO_QUERY_THROW
);
296 Reference
< XGridColumnFactory
> xCheckGrid( xCompChild
->getParent(), UNO_QUERY
);
297 if ( !xCheckGrid
.is() )
299 Reference
< XMap
> xControlMap( m_aContext
.getContextValueByAsciiName( "ControlShapeAccess" ), UNO_QUERY_THROW
);
300 m_xAssociatedShape
.set( xControlMap
->get( makeAny( xControlModel
) ), UNO_QUERY_THROW
);
301 m_xShapeProperties
.set( m_xAssociatedShape
, UNO_QUERY_THROW
);
305 catch( const Exception
& )
307 DBG_UNHANDLED_EXCEPTION();
310 if ( m_xAssociatedShape
.is() )
311 m_xChangeNotifier
= new ShapeGeometryChangeNotifier( *this, m_aMutex
, m_xAssociatedShape
.get() );
314 //--------------------------------------------------------------------
315 OUString SAL_CALL
FormGeometryHandler::getImplementationName_static( ) throw (RuntimeException
)
317 return OUString( "com.sun.star.comp.extensions.FormGeometryHandler" );
320 //--------------------------------------------------------------------
321 Sequence
< OUString
> SAL_CALL
FormGeometryHandler::getSupportedServiceNames_static( ) throw (RuntimeException
)
323 Sequence
< OUString
> aSupported( 1 );
324 aSupported
[0] = OUString( "com.sun.star.form.inspection.FormGeometryHandler" );
328 //--------------------------------------------------------------------
329 Any SAL_CALL
FormGeometryHandler::getPropertyValue( const OUString
& _rPropertyName
) throw (UnknownPropertyException
, RuntimeException
)
331 ::osl::MutexGuard
aGuard( m_aMutex
);
332 PropertyId
nPropId( impl_getPropertyId_throw( _rPropertyName
) );
334 ENSURE_OR_THROW2( m_xAssociatedShape
.is(), "internal error: properties, but no shape!", *this );
335 ENSURE_OR_THROW2( m_xShapeProperties
.is(), "internal error: no shape properties!", *this );
342 case PROPERTY_ID_POSITIONX
:
343 aReturn
<<= m_xAssociatedShape
->getPosition().X
;
345 case PROPERTY_ID_POSITIONY
:
346 aReturn
<<= m_xAssociatedShape
->getPosition().Y
;
348 case PROPERTY_ID_WIDTH
:
349 aReturn
<<= m_xAssociatedShape
->getSize().Width
;
351 case PROPERTY_ID_HEIGHT
:
352 aReturn
<<= m_xAssociatedShape
->getSize().Height
;
354 case PROPERTY_ID_TEXT_ANCHOR_TYPE
:
355 aReturn
= m_xShapeProperties
->getPropertyValue( PROPERTY_ANCHOR_TYPE
);
356 OSL_ENSURE( aReturn
.hasValue(), "FormGeometryHandler::getPropertyValue: illegal anchor type!" );
358 case PROPERTY_ID_SHEET_ANCHOR_TYPE
:
360 Reference
< XSpreadsheet
> xAnchorSheet( m_xShapeProperties
->getPropertyValue( PROPERTY_ANCHOR
), UNO_QUERY
);
361 aReturn
<<= sal_Int32( xAnchorSheet
.is() ? ANCHOR_TO_SHEET
: ANCHOR_TO_CELL
);
366 OSL_FAIL( "FormGeometryHandler::getPropertyValue: huh?" );
370 catch( const Exception
& )
372 DBG_UNHANDLED_EXCEPTION();
377 //--------------------------------------------------------------------
378 void SAL_CALL
FormGeometryHandler::setPropertyValue( const OUString
& _rPropertyName
, const Any
& _rValue
) throw (UnknownPropertyException
, RuntimeException
)
380 ::osl::MutexGuard
aGuard( m_aMutex
);
381 PropertyId
nPropId( impl_getPropertyId_throw( _rPropertyName
) );
383 ENSURE_OR_THROW2( m_xAssociatedShape
.is(), "internal error: properties, but no shape!", *this );
384 ENSURE_OR_THROW2( m_xShapeProperties
.is(), "internal error: properties, but no shape!", *this );
390 case PROPERTY_ID_POSITIONX
:
391 case PROPERTY_ID_POSITIONY
:
393 sal_Int32
nPosition(0);
394 OSL_VERIFY( _rValue
>>= nPosition
);
396 AwtPoint
aPos( m_xAssociatedShape
->getPosition() );
397 if ( nPropId
== PROPERTY_ID_POSITIONX
)
401 m_xAssociatedShape
->setPosition( aPos
);
405 case PROPERTY_ID_WIDTH
:
406 case PROPERTY_ID_HEIGHT
:
409 OSL_VERIFY( _rValue
>>= nSize
);
411 AwtSize
aSize( m_xAssociatedShape
->getSize() );
412 if ( nPropId
== PROPERTY_ID_WIDTH
)
415 aSize
.Height
= nSize
;
416 m_xAssociatedShape
->setSize( aSize
);
420 case PROPERTY_ID_TEXT_ANCHOR_TYPE
:
421 m_xShapeProperties
->setPropertyValue( PROPERTY_ANCHOR_TYPE
, _rValue
);
424 case PROPERTY_ID_SHEET_ANCHOR_TYPE
:
426 sal_Int32 nSheetAnchorType
= 0;
427 OSL_VERIFY( _rValue
>>= nSheetAnchorType
);
428 impl_setSheetAnchorType_nothrow( nSheetAnchorType
);
433 OSL_FAIL( "FormGeometryHandler::getPropertyValue: huh?" );
437 catch( const Exception
& )
439 DBG_UNHANDLED_EXCEPTION();
443 //--------------------------------------------------------------------
444 LineDescriptor SAL_CALL
FormGeometryHandler::describePropertyLine( const OUString
& _rPropertyName
,
445 const Reference
< XPropertyControlFactory
>& _rxControlFactory
)
446 throw (UnknownPropertyException
, NullPointerException
, RuntimeException
)
448 ::osl::MutexGuard
aGuard( m_aMutex
);
449 PropertyId
nPropId( impl_getPropertyId_throw( _rPropertyName
) );
451 LineDescriptor
aLineDesc( PropertyHandler::describePropertyLine( _rPropertyName
, _rxControlFactory
) );
454 bool bIsSize
= false;
457 case PROPERTY_ID_WIDTH
:
458 case PROPERTY_ID_HEIGHT
:
461 case PROPERTY_ID_POSITIONX
:
462 case PROPERTY_ID_POSITIONY
:
464 Optional
< double > aZero( sal_True
, 0 );
465 Optional
< double > aValueNotPresent( sal_False
, 0 );
466 aLineDesc
.Control
= PropertyHandlerHelper::createNumericControl(
467 _rxControlFactory
, 2, bIsSize
? aZero
: aValueNotPresent
, aValueNotPresent
, sal_False
);
469 Reference
< XNumericControl
> xNumericControl( aLineDesc
.Control
, UNO_QUERY_THROW
);
470 xNumericControl
->setValueUnit( MeasureUnit::MM_100TH
);
471 xNumericControl
->setDisplayUnit( impl_getDocumentMeasurementUnit_throw() );
475 case PROPERTY_ID_TEXT_ANCHOR_TYPE
:
476 case PROPERTY_ID_SHEET_ANCHOR_TYPE
:
477 // default handling from PropertyHandler is sufficient
481 OSL_FAIL( "FormGeometryHandler::describePropertyLine: huh?" );
485 catch( const Exception
& )
487 DBG_UNHANDLED_EXCEPTION();
492 //--------------------------------------------------------------------
493 void SAL_CALL
FormGeometryHandler::addPropertyChangeListener( const Reference
< XPropertyChangeListener
>& _listener
) throw (RuntimeException
)
495 ::osl::MutexGuard
aGuard( m_aMutex
);
496 OSL_PRECOND( m_xChangeNotifier
.is(), "FormGeometryHandler::addPropertyChangeListener: no notified, implies no shape!?" );
497 if ( m_xChangeNotifier
.is() )
498 m_xChangeNotifier
->addPropertyChangeListener( _listener
);
501 //--------------------------------------------------------------------
502 void SAL_CALL
FormGeometryHandler::removePropertyChangeListener( const Reference
< XPropertyChangeListener
>& _listener
) throw (RuntimeException
)
504 ::osl::MutexGuard
aGuard( m_aMutex
);
505 OSL_PRECOND( m_xChangeNotifier
.is(), "FormGeometryHandler::removePropertyChangeListener: no notified, implies no shape!?" );
506 if ( m_xChangeNotifier
.is() )
507 m_xChangeNotifier
->removePropertyChangeListener( _listener
);
510 //--------------------------------------------------------------------
511 Sequence
< OUString
> SAL_CALL
FormGeometryHandler::getActuatingProperties( ) throw (RuntimeException
)
513 Sequence
< OUString
> aInterestedIn(1);
514 aInterestedIn
[0] = PROPERTY_TEXT_ANCHOR_TYPE
;
515 return aInterestedIn
;
518 //--------------------------------------------------------------------
519 void SAL_CALL
FormGeometryHandler::actuatingPropertyChanged( const OUString
& _rActuatingPropertyName
, const Any
& _rNewValue
, const Any
& /*_rOldValue*/, const Reference
< XObjectInspectorUI
>& _rxInspectorUI
, sal_Bool
/*_bFirstTimeInit*/ ) throw (NullPointerException
, RuntimeException
)
521 if ( !_rxInspectorUI
.is() )
522 throw NullPointerException();
524 ::osl::MutexGuard
aGuard( m_aMutex
);
525 PropertyId
nActuatingPropId( impl_getPropertyId_throw( _rActuatingPropertyName
) );
527 switch ( nActuatingPropId
)
529 case PROPERTY_ID_TEXT_ANCHOR_TYPE
:
531 TextContentAnchorType
eAnchorType( TextContentAnchorType_AT_PARAGRAPH
);
532 OSL_VERIFY( _rNewValue
>>= eAnchorType
);
533 _rxInspectorUI
->enablePropertyUI( PROPERTY_POSITIONX
, eAnchorType
!= TextContentAnchorType_AS_CHARACTER
);
537 OSL_FAIL( "FormGeometryHandler::actuatingPropertyChanged: not registered for this property!" );
542 //--------------------------------------------------------------------
543 Sequence
< Property
> SAL_CALL
FormGeometryHandler::doDescribeSupportedProperties() const
545 if ( !m_xAssociatedShape
.is() )
546 return Sequence
< Property
>();
548 ::std::vector
< Property
> aProperties
;
550 addInt32PropertyDescription( aProperties
, PROPERTY_POSITIONX
);
551 addInt32PropertyDescription( aProperties
, PROPERTY_POSITIONY
);
552 addInt32PropertyDescription( aProperties
, PROPERTY_WIDTH
);
553 addInt32PropertyDescription( aProperties
, PROPERTY_HEIGHT
);
555 if ( impl_haveTextAnchorType_nothrow() )
556 implAddPropertyDescription( aProperties
, PROPERTY_TEXT_ANCHOR_TYPE
, ::cppu::UnoType
< TextContentAnchorType
>::get() );
558 if ( impl_haveSheetAnchorType_nothrow() )
559 addInt32PropertyDescription( aProperties
, PROPERTY_SHEET_ANCHOR_TYPE
);
561 return Sequence
< Property
>( &(*aProperties
.begin()), aProperties
.size() );
564 //--------------------------------------------------------------------
565 void SAL_CALL
FormGeometryHandler::disposing()
567 FormGeometryHandler_Base::disposing();
569 if ( m_xChangeNotifier
.is() )
571 m_xChangeNotifier
->dispose();
572 m_xChangeNotifier
.clear();
576 //--------------------------------------------------------------------
577 bool FormGeometryHandler::impl_haveTextAnchorType_nothrow() const
579 ENSURE_OR_THROW( m_xShapeProperties
.is(), "not to be called without shape properties" );
582 Reference
< XPropertySetInfo
> xPSI( m_xShapeProperties
->getPropertySetInfo(), UNO_SET_THROW
);
583 if ( xPSI
->hasPropertyByName( PROPERTY_ANCHOR_TYPE
) )
586 catch( const Exception
& )
588 DBG_UNHANDLED_EXCEPTION();
593 //--------------------------------------------------------------------
594 bool FormGeometryHandler::impl_haveSheetAnchorType_nothrow() const
596 ENSURE_OR_THROW( m_xShapeProperties
.is(), "not to be called without shape properties" );
599 Reference
< XPropertySetInfo
> xPSI( m_xShapeProperties
->getPropertySetInfo(), UNO_SET_THROW
);
600 if ( !xPSI
->hasPropertyByName( PROPERTY_ANCHOR
) )
602 Reference
< XServiceInfo
> xSI( m_xAssociatedShape
, UNO_QUERY_THROW
);
603 if ( xSI
->supportsService( OUString( "com.sun.star.sheet.Shape" ) ) )
606 catch( const Exception
& )
608 DBG_UNHANDLED_EXCEPTION();
613 //--------------------------------------------------------------------
616 static sal_Int32
lcl_getLowerBoundRowOrColumn( const Reference
< XIndexAccess
>& _rxRowsOrColumns
, const bool _bRows
,
617 const AwtPoint
& _rRelativePosition
)
619 sal_Int32 nAccumulated
= 0;
621 const sal_Int32
& rRelativePos
= _bRows
? _rRelativePosition
.Y
: _rRelativePosition
.X
;
623 sal_Int32 nElements
= _rxRowsOrColumns
->getCount();
624 sal_Int32 currentPos
= 0;
625 for ( currentPos
=0; currentPos
<nElements
; ++currentPos
)
627 Reference
< XPropertySet
> xRowOrColumn( _rxRowsOrColumns
->getByIndex( currentPos
), UNO_QUERY_THROW
);
629 sal_Bool bIsVisible
= sal_True
;
630 OSL_VERIFY( xRowOrColumn
->getPropertyValue( PROPERTY_IS_VISIBLE
) >>= bIsVisible
);
634 sal_Int32
nHeightOrWidth( 0 );
635 OSL_VERIFY( xRowOrColumn
->getPropertyValue( _bRows
? OUString(PROPERTY_HEIGHT
) : OUString(PROPERTY_WIDTH
) ) >>= nHeightOrWidth
);
637 if ( nAccumulated
+ nHeightOrWidth
> rRelativePos
)
640 nAccumulated
+= nHeightOrWidth
;
647 //--------------------------------------------------------------------
648 void FormGeometryHandler::impl_setSheetAnchorType_nothrow( const sal_Int32 _nAnchorType
) const
650 ENSURE_OR_THROW( m_xShapeProperties
.is(), "illegal to be called without shape properties." );
653 CellBindingHelper
aHelper( m_xComponent
, impl_getContextDocument_nothrow() );
654 // find the sheet which the control belongs to
655 Reference
< XSpreadsheet
> xSheet
;
656 aHelper
.getControlSheetIndex( xSheet
);
658 switch ( _nAnchorType
)
660 case ANCHOR_TO_SHEET
:
661 OSL_ENSURE( xSheet
.is(),
662 "FormGeometryHandler::impl_setSheetAnchorType_nothrow: sheet not found!" );
665 AwtPoint
aPreservePosition( m_xAssociatedShape
->getPosition() );
666 m_xShapeProperties
->setPropertyValue( PROPERTY_ANCHOR
, makeAny( xSheet
) );
667 m_xAssociatedShape
->setPosition( aPreservePosition
);
673 Reference
< XColumnRowRange
> xColsRows( xSheet
, UNO_QUERY_THROW
);
675 // get the current anchor
676 Reference
< XSpreadsheet
> xCurrentAnchor
;
677 OSL_VERIFY( m_xShapeProperties
->getPropertyValue( PROPERTY_ANCHOR
) >>= xCurrentAnchor
);
678 OSL_ENSURE( xCurrentAnchor
.is(), "FormGeometryHandler::impl_setSheetAnchorType_nothrow: only to be called when currently anchored to a sheet!" );
680 // get the current position
681 AwtPoint
aRelativePosition( m_xAssociatedShape
->getPosition() );
683 Reference
< XTableColumns
> xCols( xColsRows
->getColumns(), UNO_SET_THROW
);
684 sal_Int32 nNewAnchorCol
= lcl_getLowerBoundRowOrColumn( xCols
.get(), false, aRelativePosition
);
686 Reference
< XTableRows
> xRows( xColsRows
->getRows(), UNO_SET_THROW
);
687 sal_Int32 nNewAnchorRow
= lcl_getLowerBoundRowOrColumn( xRows
.get(), true, aRelativePosition
);
689 Reference
< XCellRange
> xSheetCellRange( xSheet
, UNO_QUERY_THROW
);
690 Any
aNewAnchorCell( xSheetCellRange
->getCellByPosition( nNewAnchorCol
, nNewAnchorRow
) );
691 m_xShapeProperties
->setPropertyValue( PROPERTY_ANCHOR
, aNewAnchorCell
);
696 OSL_FAIL( "FormGeometryHandler::impl_setSheetAnchorType_nothrow: illegal anchor type!" );
700 catch( const Exception
& )
702 DBG_UNHANDLED_EXCEPTION();
706 //====================================================================
707 //= ShapeGeometryChangeNotifier - implementation
708 //====================================================================
711 struct EventTranslation
713 OUString sPropertyName
;
714 Any aNewPropertyValue
;
716 EventTranslation( const OUString
& _propertyName
, const Any
& _newPropertyValue
)
717 :sPropertyName( _propertyName
)
718 ,aNewPropertyValue( _newPropertyValue
)
724 //--------------------------------------------------------------------
725 void SAL_CALL
ShapeGeometryChangeNotifier::propertyChange( const PropertyChangeEvent
& _event
) throw (RuntimeException
)
727 ::comphelper::ComponentMethodGuard
aGuard( *this );
729 ::std::vector
< EventTranslation
> aEventTranslations
;
730 aEventTranslations
.reserve(2);
732 if ( _event
.PropertyName
== "Position" )
734 AwtPoint aPos
= m_xShape
->getPosition();
735 aEventTranslations
.push_back( EventTranslation( PROPERTY_POSITIONX
, makeAny( aPos
.X
) ) );
736 aEventTranslations
.push_back( EventTranslation( PROPERTY_POSITIONY
, makeAny( aPos
.Y
) ) );
738 else if ( _event
.PropertyName
== "Size" )
740 AwtSize aSize
= m_xShape
->getSize();
741 aEventTranslations
.push_back( EventTranslation( PROPERTY_WIDTH
, makeAny( aSize
.Width
) ) );
742 aEventTranslations
.push_back( EventTranslation( PROPERTY_HEIGHT
, makeAny( aSize
.Height
) ) );
744 else if ( _event
.PropertyName
== PROPERTY_ANCHOR_TYPE
)
746 aEventTranslations
.push_back( EventTranslation( PROPERTY_TEXT_ANCHOR_TYPE
, makeAny( _event
.NewValue
) ) );
748 else if ( _event
.PropertyName
== PROPERTY_ANCHOR
)
750 aEventTranslations
.push_back( EventTranslation( PROPERTY_SHEET_ANCHOR_TYPE
, makeAny( _event
.NewValue
) ) );
753 PropertyChangeEvent
aTranslatedEvent( _event
);
754 aTranslatedEvent
.Source
= m_rParent
;
757 for ( ::std::vector
< EventTranslation
>::const_iterator t
= aEventTranslations
.begin();
758 t
!= aEventTranslations
.end();
762 aTranslatedEvent
.PropertyName
= t
->sPropertyName
;
763 aTranslatedEvent
.NewValue
= t
->aNewPropertyValue
;
764 m_aPropertyChangeListeners
.notifyEach( &XPropertyChangeListener::propertyChange
, aTranslatedEvent
);
768 //--------------------------------------------------------------------
769 void SAL_CALL
ShapeGeometryChangeNotifier::disposing( const EventObject
& /*_event*/ ) throw (RuntimeException
)
771 ::comphelper::ComponentMethodGuard
aGuard( *this );
772 impl_dispose_nothrow();
775 //--------------------------------------------------------------------
776 void ShapeGeometryChangeNotifier::impl_init_nothrow()
778 osl_atomic_increment( &m_refCount
);
781 Reference
< XPropertySet
> xShapeProperties( m_xShape
, UNO_QUERY_THROW
);
782 xShapeProperties
->addPropertyChangeListener( OUString(), this );
784 catch( const Exception
& )
786 DBG_UNHANDLED_EXCEPTION();
788 osl_atomic_decrement( &m_refCount
);
791 //--------------------------------------------------------------------
792 void ShapeGeometryChangeNotifier::impl_dispose_nothrow()
796 Reference
< XPropertySet
> xShapeProperties( m_xShape
, UNO_QUERY_THROW
);
797 xShapeProperties
->removePropertyChangeListener( OUString(), this );
799 catch( const Exception
& )
801 DBG_UNHANDLED_EXCEPTION();
804 getBroadcastHelper().bDisposed
= true;
807 //........................................................................
809 //........................................................................
811 extern "C" void SAL_CALL
createRegistryInfo_FormGeometryHandler()
813 ::pcr::FormGeometryHandler::registerImplementation();
816 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */