merged tag ooo/OOO330_m14
[LibreOffice.git] / extensions / source / propctrlr / formgeometryhandler.cxx
blob31a2b93152380a09ee17f67f1a65aa2ea0d1f46a
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 //........................................................................
58 namespace pcr
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
118 protected:
119 BroadcastHelperBase( ::osl::Mutex& _rMutex )
120 :maBHelper( _rMutex )
124 protected:
125 ::cppu::OBroadcastHelper& getBroadcastHelper() { return maBHelper; }
127 private:
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
145 public:
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 )
152 ,m_xShape( _shape )
154 ENSURE_OR_THROW( m_xShape.is(), "illegal shape!" );
155 impl_init_nothrow();
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
169 void dispose()
171 ::osl::MutexGuard aGuard( getMutex() );
172 impl_dispose_nothrow();
175 // XInterface
176 virtual void SAL_CALL acquire( ) throw ()
178 m_rParent.acquire();
181 virtual void SAL_CALL release( ) throw ()
183 m_rParent.release();
186 // XPropertyChangeListener
187 virtual void SAL_CALL propertyChange( const PropertyChangeEvent& _event ) throw (RuntimeException);
189 // XEventListener
190 virtual void SAL_CALL disposing( const EventObject& _event ) throw (RuntimeException);
192 protected:
193 virtual ~ShapeGeometryChangeNotifier()
195 if ( !getBroadcastHelper().bDisposed )
197 acquire();
198 dispose();
202 protected:
203 ::cppu::OBroadcastHelper& getBroadcastHelper() { return BroadcastHelperBase::getBroadcastHelper(); }
205 private:
206 void impl_init_nothrow();
207 void impl_dispose_nothrow();
209 private:
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
224 public:
225 FormGeometryHandler(
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);
232 protected:
233 ~FormGeometryHandler();
235 protected:
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;
251 protected:
252 virtual void onNewComponent();
254 private:
255 bool impl_haveTextAnchorType_nothrow() const;
256 bool impl_haveSheetAnchorType_nothrow() const;
257 void impl_setSheetAnchorType_nothrow( const sal_Int32 _nAnchorType ) const;
259 private:
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 )
281 acquire();
282 dispose();
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" ) );
337 return aSupported;
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 );
349 Any aReturn;
352 switch ( nPropId )
354 case PROPERTY_ID_POSITIONX:
355 aReturn <<= m_xAssociatedShape->getPosition().X;
356 break;
357 case PROPERTY_ID_POSITIONY:
358 aReturn <<= m_xAssociatedShape->getPosition().Y;
359 break;
360 case PROPERTY_ID_WIDTH:
361 aReturn <<= m_xAssociatedShape->getSize().Width;
362 break;
363 case PROPERTY_ID_HEIGHT:
364 aReturn <<= m_xAssociatedShape->getSize().Height;
365 break;
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!" );
369 break;
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 );
375 break;
377 default:
378 OSL_ENSURE( false, "FormGeometryHandler::getPropertyValue: huh?" );
379 break;
382 catch( const Exception& )
384 DBG_UNHANDLED_EXCEPTION();
386 return aReturn;
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 );
400 switch ( nPropId )
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 )
410 aPos.X = nPosition;
411 else
412 aPos.Y = nPosition;
413 m_xAssociatedShape->setPosition( aPos );
415 break;
417 case PROPERTY_ID_WIDTH:
418 case PROPERTY_ID_HEIGHT:
420 sal_Int32 nSize(0);
421 OSL_VERIFY( _rValue >>= nSize );
423 AwtSize aSize( m_xAssociatedShape->getSize() );
424 if ( nPropId == PROPERTY_ID_WIDTH )
425 aSize.Width = nSize;
426 else
427 aSize.Height = nSize;
428 m_xAssociatedShape->setSize( aSize );
430 break;
432 case PROPERTY_ID_TEXT_ANCHOR_TYPE:
433 m_xShapeProperties->setPropertyValue( PROPERTY_ANCHOR_TYPE, _rValue );
434 break;
436 case PROPERTY_ID_SHEET_ANCHOR_TYPE:
438 sal_Int32 nSheetAnchorType = 0;
439 OSL_VERIFY( _rValue >>= nSheetAnchorType );
440 impl_setSheetAnchorType_nothrow( nSheetAnchorType );
442 break;
444 default:
445 OSL_ENSURE( false, "FormGeometryHandler::getPropertyValue: huh?" );
446 break;
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;
467 switch ( nPropId )
469 case PROPERTY_ID_WIDTH:
470 case PROPERTY_ID_HEIGHT:
471 bIsSize = true;
472 // NO break!
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() );
485 break;
487 case PROPERTY_ID_TEXT_ANCHOR_TYPE:
488 case PROPERTY_ID_SHEET_ANCHOR_TYPE:
489 // default handling from PropertyHandler is sufficient
490 break;
492 default:
493 OSL_ENSURE( false, "FormGeometryHandler::describePropertyLine: huh?" );
494 break;
497 catch( const Exception& )
499 DBG_UNHANDLED_EXCEPTION();
501 return aLineDesc;
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 );
547 break;
548 default:
549 OSL_ENSURE( false, "FormGeometryHandler::actuatingPropertyChanged: not registered for this property!" );
550 break;
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 ) )
596 return true;
598 catch( const Exception& )
600 DBG_UNHANDLED_EXCEPTION();
602 return false;
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 ) )
613 return false;
614 Reference< XServiceInfo > xSI( m_xAssociatedShape, UNO_QUERY_THROW );
615 if ( xSI->supportsService( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.Shape" ) ) ) )
616 return true;
618 catch( const Exception& )
620 DBG_UNHANDLED_EXCEPTION();
622 return false;
625 //--------------------------------------------------------------------
626 namespace
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 );
643 if ( !bIsVisible )
644 continue;
646 sal_Int32 nHeightOrWidth( 0 );
647 OSL_VERIFY( xRowOrColumn->getPropertyValue( _bRows ? PROPERTY_HEIGHT : PROPERTY_WIDTH ) >>= nHeightOrWidth );
649 if ( nAccumulated + nHeightOrWidth > rRelativePos )
650 break;
652 nAccumulated += nHeightOrWidth;
655 return currentPos;
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!" );
675 if ( xSheet.is() )
677 AwtPoint aPreservePosition( m_xAssociatedShape->getPosition() );
678 m_xShapeProperties->setPropertyValue( PROPERTY_ANCHOR, makeAny( xSheet ) );
679 m_xAssociatedShape->setPosition( aPreservePosition );
681 break;
683 case ANCHOR_TO_CELL:
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 );
705 break;
707 default:
708 OSL_ENSURE( false, "FormGeometryHandler::impl_setSheetAnchorType_nothrow: illegal anchor type!" );
709 break;
712 catch( const Exception& )
714 DBG_UNHANDLED_EXCEPTION();
718 //====================================================================
719 //= ShapeGeometryChangeNotifier - implementation
720 //====================================================================
721 namespace
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;
768 aGuard.clear();
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 //........................................................................
820 } // namespace pcr
821 //........................................................................
823 extern "C" void SAL_CALL createRegistryInfo_FormGeometryHandler()
825 ::pcr::FormGeometryHandler::registerImplementation();