merge the formfield patch from ooo-build
[ooovba.git] / extensions / source / propctrlr / formgeometryhandler.cxx
blob09a2f663d30361ace7e24fa67de85ec1646412ff
1 /*************************************************************************
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3 *
4 * Copyright 2009 by Sun Microsystems, Inc.
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.
24 ************************************************************************/
26 // MARKER(update_precomp.py): autogen include statement, do not remove
27 #include "precompiled_extensions.hxx"
29 #include "propertyhandler.hxx"
30 #include "formmetadata.hxx"
31 #include "formstrings.hxx"
32 #include "handlerhelper.hxx"
33 #include "cellbindinghelper.hxx"
35 /** === begin UNO includes === **/
36 #include <com/sun/star/inspection/XObjectInspectorUI.hpp>
37 #include <com/sun/star/awt/XControlModel.hpp>
38 #include <com/sun/star/drawing/XControlShape.hpp>
39 #include <com/sun/star/container/XMap.hpp>
40 #include <com/sun/star/inspection/XNumericControl.hpp>
41 #include <com/sun/star/util/MeasureUnit.hpp>
42 #include <com/sun/star/text/TextContentAnchorType.hpp>
43 #include <com/sun/star/lang/XServiceInfo.hpp>
44 #include <com/sun/star/sheet/XSpreadsheet.hpp>
45 #include <com/sun/star/table/XColumnRowRange.hpp>
46 #include <com/sun/star/table/XCellRange.hpp>
47 #include <com/sun/star/container/XChild.hpp>
48 #include <com/sun/star/form/XGridColumnFactory.hpp>
49 /** === end UNO includes === **/
51 #include <cppuhelper/interfacecontainer.hxx>
52 #include <comphelper/componentbase.hxx>
53 #include <tools/debug.hxx>
54 #include <tools/diagnose_ex.h>
56 //........................................................................
57 namespace pcr
59 //........................................................................
61 /** === begin UNO using === **/
62 using ::com::sun::star::uno::Reference;
63 using ::com::sun::star::uno::XInterface;
64 using ::com::sun::star::uno::UNO_QUERY;
65 using ::com::sun::star::uno::UNO_QUERY_THROW;
66 using ::com::sun::star::uno::UNO_SET_THROW;
67 using ::com::sun::star::uno::Exception;
68 using ::com::sun::star::uno::RuntimeException;
69 using ::com::sun::star::uno::Any;
70 using ::com::sun::star::uno::makeAny;
71 using ::com::sun::star::uno::Sequence;
72 using ::com::sun::star::uno::Type;
73 using ::com::sun::star::uno::XComponentContext;
74 using ::com::sun::star::beans::UnknownPropertyException;
75 using ::com::sun::star::beans::Property;
76 using ::com::sun::star::awt::XControlModel;
77 using ::com::sun::star::drawing::XControlShape;
78 using ::com::sun::star::container::XMap;
79 using ::com::sun::star::inspection::LineDescriptor;
80 using ::com::sun::star::inspection::XPropertyControlFactory;
81 using ::com::sun::star::lang::NullPointerException;
82 using ::com::sun::star::beans::Optional;
83 using ::com::sun::star::inspection::XNumericControl;
84 using ::com::sun::star::drawing::XShape;
85 using ::com::sun::star::beans::PropertyChangeEvent;
86 using ::com::sun::star::lang::EventObject;
87 using ::com::sun::star::beans::XPropertySet;
88 using ::com::sun::star::beans::XPropertyChangeListener;
89 using ::com::sun::star::text::TextContentAnchorType;
90 using ::com::sun::star::text::TextContentAnchorType_AT_PARAGRAPH;
91 using ::com::sun::star::text::TextContentAnchorType_AS_CHARACTER;
92 using ::com::sun::star::beans::XPropertySetInfo;
93 using ::com::sun::star::inspection::XObjectInspectorUI;
94 using ::com::sun::star::lang::XServiceInfo;
95 using ::com::sun::star::sheet::XSpreadsheet;
96 using ::com::sun::star::table::XColumnRowRange;
97 using ::com::sun::star::table::XTableColumns;
98 using ::com::sun::star::table::XTableRows;
99 using ::com::sun::star::table::XCellRange;
100 using ::com::sun::star::container::XIndexAccess;
101 using ::com::sun::star::container::XChild;
102 using ::com::sun::star::form::XGridColumnFactory;
103 /** === end UNO using === **/
104 namespace MeasureUnit = ::com::sun::star::util::MeasureUnit;
106 typedef ::com::sun::star::awt::Point AwtPoint;
107 typedef ::com::sun::star::awt::Size AwtSize;
109 #define ANCHOR_TO_SHEET 0
110 #define ANCHOR_TO_CELL 1
112 //====================================================================
113 //= BroadcastHelperBase
114 //====================================================================
115 class BroadcastHelperBase
117 protected:
118 BroadcastHelperBase( ::osl::Mutex& _rMutex )
119 :maBHelper( _rMutex )
123 protected:
124 ::cppu::OBroadcastHelper& getBroadcastHelper() { return maBHelper; }
126 private:
127 ::cppu::OBroadcastHelper maBHelper;
130 //====================================================================
131 //= ShapeGeometryChangeNotifier - declaration
132 //====================================================================
133 /** helper class to work around the ...unfortunate implementation of property change broadcasts
134 in the XShape implementation, which broadcasts way too generous and unspecified
136 typedef ::comphelper::ComponentBase ShapeGeometryChangeNotifier_CBase;
137 typedef ::cppu::WeakImplHelper1 < ::com::sun::star::beans::XPropertyChangeListener
138 > ShapeGeometryChangeNotifier_IBase;
140 class ShapeGeometryChangeNotifier :public BroadcastHelperBase
141 ,public ShapeGeometryChangeNotifier_CBase
142 ,public ShapeGeometryChangeNotifier_IBase
144 public:
145 ShapeGeometryChangeNotifier( ::cppu::OWeakObject& _rParent, ::osl::Mutex& _rParentMutex, const Reference< XShape >& _shape )
146 :BroadcastHelperBase( _rParentMutex )
147 ,ShapeGeometryChangeNotifier_CBase( BroadcastHelperBase::getBroadcastHelper(), ::comphelper::ComponentBase::NoInitializationNeeded() )
148 ,ShapeGeometryChangeNotifier_IBase()
149 ,m_rParent( _rParent )
150 ,m_aPropertyChangeListeners( _rParentMutex )
151 ,m_xShape( _shape )
153 ENSURE_OR_THROW( m_xShape.is(), "illegal shape!" );
154 impl_init_nothrow();
157 // property change broadcasting
158 void addPropertyChangeListener( const Reference< XPropertyChangeListener >& _listener )
160 m_aPropertyChangeListeners.addInterface( _listener );
162 void removePropertyChangeListener( const Reference< XPropertyChangeListener >& _listener )
164 m_aPropertyChangeListeners.removeInterface( _listener );
167 // XComponent equivalent
168 void dispose()
170 ::osl::MutexGuard aGuard( getMutex() );
171 impl_dispose_nothrow();
174 // XInterface
175 virtual void SAL_CALL acquire( ) throw ()
177 m_rParent.acquire();
180 virtual void SAL_CALL release( ) throw ()
182 m_rParent.release();
185 // XPropertyChangeListener
186 virtual void SAL_CALL propertyChange( const PropertyChangeEvent& _event ) throw (RuntimeException);
188 // XEventListener
189 virtual void SAL_CALL disposing( const EventObject& _event ) throw (RuntimeException);
191 protected:
192 virtual ~ShapeGeometryChangeNotifier()
194 if ( !getBroadcastHelper().bDisposed )
196 acquire();
197 dispose();
201 protected:
202 ::cppu::OBroadcastHelper& getBroadcastHelper() { return BroadcastHelperBase::getBroadcastHelper(); }
204 private:
205 void impl_init_nothrow();
206 void impl_dispose_nothrow();
208 private:
209 ::cppu::OWeakObject& m_rParent;
210 ::cppu::OInterfaceContainerHelper m_aPropertyChangeListeners;
211 Reference< XShape > m_xShape;
214 //====================================================================
215 //= FormGeometryHandler - declaration
216 //====================================================================
217 class FormGeometryHandler;
218 typedef HandlerComponentBase< FormGeometryHandler > FormGeometryHandler_Base;
219 /** a property handler for any virtual string properties
221 class FormGeometryHandler : public FormGeometryHandler_Base
223 public:
224 FormGeometryHandler(
225 const Reference< XComponentContext >& _rxContext
228 static ::rtl::OUString SAL_CALL getImplementationName_static( ) throw (RuntimeException);
229 static Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames_static( ) throw (RuntimeException);
231 protected:
232 ~FormGeometryHandler();
234 protected:
235 // XPropertyHandler overriables
236 virtual Any SAL_CALL getPropertyValue( const ::rtl::OUString& _rPropertyName ) throw (UnknownPropertyException, RuntimeException);
237 virtual void SAL_CALL setPropertyValue( const ::rtl::OUString& _rPropertyName, const Any& _rValue ) throw (UnknownPropertyException, RuntimeException);
238 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);
239 virtual void SAL_CALL addPropertyChangeListener( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& _rxListener ) throw (::com::sun::star::uno::RuntimeException);
240 virtual void SAL_CALL removePropertyChangeListener( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& _rxListener ) throw (::com::sun::star::uno::RuntimeException);
241 virtual Sequence< ::rtl::OUString > SAL_CALL getActuatingProperties( ) throw (RuntimeException);
242 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);
244 // OComponentHandler overridables
245 virtual void SAL_CALL disposing();
247 // PropertyHandler overridables
248 virtual Sequence< Property > SAL_CALL doDescribeSupportedProperties() const;
250 protected:
251 virtual void onNewComponent();
253 private:
254 bool impl_haveTextAnchorType_nothrow() const;
255 bool impl_haveSheetAnchorType_nothrow() const;
256 void impl_setSheetAnchorType_nothrow( const sal_Int32 _nAnchorType ) const;
258 private:
259 Reference< XControlShape > m_xAssociatedShape;
260 Reference< XPropertySet > m_xShapeProperties;
261 ::rtl::Reference< ShapeGeometryChangeNotifier > m_xChangeNotifier;
264 //====================================================================
265 //= FormGeometryHandler - implementation
266 //====================================================================
267 DBG_NAME( FormGeometryHandler )
268 //--------------------------------------------------------------------
269 FormGeometryHandler::FormGeometryHandler( const Reference< XComponentContext >& _rxContext )
270 :FormGeometryHandler_Base( _rxContext )
272 DBG_CTOR( FormGeometryHandler, NULL );
275 //--------------------------------------------------------------------
276 FormGeometryHandler::~FormGeometryHandler( )
278 if ( !rBHelper.bDisposed )
280 acquire();
281 dispose();
284 DBG_DTOR( FormGeometryHandler, NULL );
287 //--------------------------------------------------------------------
288 void FormGeometryHandler::onNewComponent()
290 if ( m_xChangeNotifier.is() )
292 m_xChangeNotifier->dispose();
293 m_xChangeNotifier.clear();
295 m_xAssociatedShape.clear();
296 m_xShapeProperties.clear();
298 FormGeometryHandler_Base::onNewComponent();
302 Reference< XControlModel > xControlModel( m_xComponent, UNO_QUERY );
303 if ( xControlModel.is() )
305 // do not ask the map for shapes for grid control columns ....
306 Reference< XChild > xCompChild( m_xComponent, UNO_QUERY_THROW );
307 Reference< XGridColumnFactory > xCheckGrid( xCompChild->getParent(), UNO_QUERY );
308 if ( !xCheckGrid.is() )
310 Reference< XMap > xControlMap( m_aContext.getContextValueByAsciiName( "ControlShapeAccess" ), UNO_QUERY_THROW );
311 m_xAssociatedShape.set( xControlMap->get( makeAny( xControlModel ) ), UNO_QUERY_THROW );
312 m_xShapeProperties.set( m_xAssociatedShape, UNO_QUERY_THROW );
316 catch( const Exception& )
318 DBG_UNHANDLED_EXCEPTION();
321 if ( m_xAssociatedShape.is() )
322 m_xChangeNotifier = new ShapeGeometryChangeNotifier( *this, m_aMutex, m_xAssociatedShape.get() );
325 //--------------------------------------------------------------------
326 ::rtl::OUString SAL_CALL FormGeometryHandler::getImplementationName_static( ) throw (RuntimeException)
328 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.extensions.FormGeometryHandler" ) );
331 //--------------------------------------------------------------------
332 Sequence< ::rtl::OUString > SAL_CALL FormGeometryHandler::getSupportedServiceNames_static( ) throw (RuntimeException)
334 Sequence< ::rtl::OUString > aSupported( 1 );
335 aSupported[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.form.inspection.FormGeometryHandler" ) );
336 return aSupported;
339 //--------------------------------------------------------------------
340 Any SAL_CALL FormGeometryHandler::getPropertyValue( const ::rtl::OUString& _rPropertyName ) throw (UnknownPropertyException, RuntimeException)
342 ::osl::MutexGuard aGuard( m_aMutex );
343 PropertyId nPropId( impl_getPropertyId_throw( _rPropertyName ) );
345 ENSURE_OR_THROW2( m_xAssociatedShape.is(), "internal error: properties, but no shape!", *this );
346 ENSURE_OR_THROW2( m_xShapeProperties.is(), "internal error: no shape properties!", *this );
348 Any aReturn;
351 switch ( nPropId )
353 case PROPERTY_ID_POSITIONX:
354 aReturn <<= m_xAssociatedShape->getPosition().X;
355 break;
356 case PROPERTY_ID_POSITIONY:
357 aReturn <<= m_xAssociatedShape->getPosition().Y;
358 break;
359 case PROPERTY_ID_WIDTH:
360 aReturn <<= m_xAssociatedShape->getSize().Width;
361 break;
362 case PROPERTY_ID_HEIGHT:
363 aReturn <<= m_xAssociatedShape->getSize().Height;
364 break;
365 case PROPERTY_ID_TEXT_ANCHOR_TYPE:
366 aReturn = m_xShapeProperties->getPropertyValue( PROPERTY_ANCHOR_TYPE );
367 OSL_ENSURE( aReturn.hasValue(), "FormGeometryHandler::getPropertyValue: illegal anchor type!" );
368 break;
369 case PROPERTY_ID_SHEET_ANCHOR_TYPE:
371 Reference< XSpreadsheet > xAnchorSheet( m_xShapeProperties->getPropertyValue( PROPERTY_ANCHOR ), UNO_QUERY );
372 aReturn <<= sal_Int32( xAnchorSheet.is() ? ANCHOR_TO_SHEET : ANCHOR_TO_CELL );
374 break;
376 default:
377 OSL_ENSURE( false, "FormGeometryHandler::getPropertyValue: huh?" );
378 break;
381 catch( const Exception& )
383 DBG_UNHANDLED_EXCEPTION();
385 return aReturn;
388 //--------------------------------------------------------------------
389 void SAL_CALL FormGeometryHandler::setPropertyValue( const ::rtl::OUString& _rPropertyName, const Any& _rValue ) throw (UnknownPropertyException, RuntimeException)
391 ::osl::MutexGuard aGuard( m_aMutex );
392 PropertyId nPropId( impl_getPropertyId_throw( _rPropertyName ) );
394 ENSURE_OR_THROW2( m_xAssociatedShape.is(), "internal error: properties, but no shape!", *this );
395 ENSURE_OR_THROW2( m_xShapeProperties.is(), "internal error: properties, but no shape!", *this );
399 switch ( nPropId )
401 case PROPERTY_ID_POSITIONX:
402 case PROPERTY_ID_POSITIONY:
404 sal_Int32 nPosition(0);
405 OSL_VERIFY( _rValue >>= nPosition );
407 AwtPoint aPos( m_xAssociatedShape->getPosition() );
408 if ( nPropId == PROPERTY_ID_POSITIONX )
409 aPos.X = nPosition;
410 else
411 aPos.Y = nPosition;
412 m_xAssociatedShape->setPosition( aPos );
414 break;
416 case PROPERTY_ID_WIDTH:
417 case PROPERTY_ID_HEIGHT:
419 sal_Int32 nSize(0);
420 OSL_VERIFY( _rValue >>= nSize );
422 AwtSize aSize( m_xAssociatedShape->getSize() );
423 if ( nPropId == PROPERTY_ID_WIDTH )
424 aSize.Width = nSize;
425 else
426 aSize.Height = nSize;
427 m_xAssociatedShape->setSize( aSize );
429 break;
431 case PROPERTY_ID_TEXT_ANCHOR_TYPE:
432 m_xShapeProperties->setPropertyValue( PROPERTY_ANCHOR_TYPE, _rValue );
433 break;
435 case PROPERTY_ID_SHEET_ANCHOR_TYPE:
437 sal_Int32 nSheetAnchorType = 0;
438 OSL_VERIFY( _rValue >>= nSheetAnchorType );
439 impl_setSheetAnchorType_nothrow( nSheetAnchorType );
441 break;
443 default:
444 OSL_ENSURE( false, "FormGeometryHandler::getPropertyValue: huh?" );
445 break;
448 catch( const Exception& )
450 DBG_UNHANDLED_EXCEPTION();
454 //--------------------------------------------------------------------
455 LineDescriptor SAL_CALL FormGeometryHandler::describePropertyLine( const ::rtl::OUString& _rPropertyName,
456 const Reference< XPropertyControlFactory >& _rxControlFactory )
457 throw (UnknownPropertyException, NullPointerException, RuntimeException)
459 ::osl::MutexGuard aGuard( m_aMutex );
460 PropertyId nPropId( impl_getPropertyId_throw( _rPropertyName ) );
462 LineDescriptor aLineDesc( PropertyHandler::describePropertyLine( _rPropertyName, _rxControlFactory ) );
465 bool bIsSize = false;
466 switch ( nPropId )
468 case PROPERTY_ID_WIDTH:
469 case PROPERTY_ID_HEIGHT:
470 bIsSize = true;
471 // NO break!
472 case PROPERTY_ID_POSITIONX:
473 case PROPERTY_ID_POSITIONY:
475 Optional< double > aZero( sal_True, 0 );
476 Optional< double > aValueNotPresent( sal_False, 0 );
477 aLineDesc.Control = PropertyHandlerHelper::createNumericControl(
478 _rxControlFactory, 2, bIsSize ? aZero : aValueNotPresent, aValueNotPresent, sal_False );
480 Reference< XNumericControl > xNumericControl( aLineDesc.Control, UNO_QUERY_THROW );
481 xNumericControl->setValueUnit( MeasureUnit::MM_100TH );
482 xNumericControl->setDisplayUnit( impl_getDocumentMeasurementUnit_throw() );
484 break;
486 case PROPERTY_ID_TEXT_ANCHOR_TYPE:
487 case PROPERTY_ID_SHEET_ANCHOR_TYPE:
488 // default handling from PropertyHandler is sufficient
489 break;
491 default:
492 OSL_ENSURE( false, "FormGeometryHandler::describePropertyLine: huh?" );
493 break;
496 catch( const Exception& )
498 DBG_UNHANDLED_EXCEPTION();
500 return aLineDesc;
503 //--------------------------------------------------------------------
504 void SAL_CALL FormGeometryHandler::addPropertyChangeListener( const Reference< XPropertyChangeListener >& _listener ) throw (RuntimeException)
506 ::osl::MutexGuard aGuard( m_aMutex );
507 OSL_PRECOND( m_xChangeNotifier.is(), "FormGeometryHandler::addPropertyChangeListener: no notified, implies no shape!?" );
508 if ( m_xChangeNotifier.is() )
509 m_xChangeNotifier->addPropertyChangeListener( _listener );
512 //--------------------------------------------------------------------
513 void SAL_CALL FormGeometryHandler::removePropertyChangeListener( const Reference< XPropertyChangeListener >& _listener ) throw (RuntimeException)
515 ::osl::MutexGuard aGuard( m_aMutex );
516 OSL_PRECOND( m_xChangeNotifier.is(), "FormGeometryHandler::removePropertyChangeListener: no notified, implies no shape!?" );
517 if ( m_xChangeNotifier.is() )
518 m_xChangeNotifier->removePropertyChangeListener( _listener );
521 //--------------------------------------------------------------------
522 Sequence< ::rtl::OUString > SAL_CALL FormGeometryHandler::getActuatingProperties( ) throw (RuntimeException)
524 Sequence< ::rtl::OUString > aInterestedIn(1);
525 aInterestedIn[0] = PROPERTY_TEXT_ANCHOR_TYPE;
526 return aInterestedIn;
529 //--------------------------------------------------------------------
530 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)
532 if ( !_rxInspectorUI.is() )
533 throw NullPointerException();
535 ::osl::MutexGuard aGuard( m_aMutex );
536 PropertyId nActuatingPropId( impl_getPropertyId_throw( _rActuatingPropertyName ) );
538 switch ( nActuatingPropId )
540 case PROPERTY_ID_TEXT_ANCHOR_TYPE:
542 TextContentAnchorType eAnchorType( TextContentAnchorType_AT_PARAGRAPH );
543 OSL_VERIFY( _rNewValue >>= eAnchorType );
544 _rxInspectorUI->enablePropertyUI( PROPERTY_POSITIONX, eAnchorType != TextContentAnchorType_AS_CHARACTER );
546 break;
547 default:
548 OSL_ENSURE( false, "FormGeometryHandler::actuatingPropertyChanged: not registered for this property!" );
549 break;
553 //--------------------------------------------------------------------
554 Sequence< Property > SAL_CALL FormGeometryHandler::doDescribeSupportedProperties() const
556 if ( !m_xAssociatedShape.is() )
557 return Sequence< Property >();
559 ::std::vector< Property > aProperties;
561 addInt32PropertyDescription( aProperties, PROPERTY_POSITIONX );
562 addInt32PropertyDescription( aProperties, PROPERTY_POSITIONY );
563 addInt32PropertyDescription( aProperties, PROPERTY_WIDTH );
564 addInt32PropertyDescription( aProperties, PROPERTY_HEIGHT );
566 if ( impl_haveTextAnchorType_nothrow() )
567 implAddPropertyDescription( aProperties, PROPERTY_TEXT_ANCHOR_TYPE, ::cppu::UnoType< TextContentAnchorType >::get() );
569 if ( impl_haveSheetAnchorType_nothrow() )
570 addInt32PropertyDescription( aProperties, PROPERTY_SHEET_ANCHOR_TYPE );
572 return Sequence< Property >( &(*aProperties.begin()), aProperties.size() );
575 //--------------------------------------------------------------------
576 void SAL_CALL FormGeometryHandler::disposing()
578 FormGeometryHandler_Base::disposing();
580 if ( m_xChangeNotifier.is() )
582 m_xChangeNotifier->dispose();
583 m_xChangeNotifier.clear();
587 //--------------------------------------------------------------------
588 bool FormGeometryHandler::impl_haveTextAnchorType_nothrow() const
590 ENSURE_OR_THROW( m_xShapeProperties.is(), "not to be called without shape properties" );
593 Reference< XPropertySetInfo > xPSI( m_xShapeProperties->getPropertySetInfo(), UNO_SET_THROW );
594 if ( xPSI->hasPropertyByName( PROPERTY_ANCHOR_TYPE ) )
595 return true;
597 catch( const Exception& )
599 DBG_UNHANDLED_EXCEPTION();
601 return false;
604 //--------------------------------------------------------------------
605 bool FormGeometryHandler::impl_haveSheetAnchorType_nothrow() const
607 ENSURE_OR_THROW( m_xShapeProperties.is(), "not to be called without shape properties" );
610 Reference< XPropertySetInfo > xPSI( m_xShapeProperties->getPropertySetInfo(), UNO_SET_THROW );
611 if ( !xPSI->hasPropertyByName( PROPERTY_ANCHOR ) )
612 return false;
613 Reference< XServiceInfo > xSI( m_xAssociatedShape, UNO_QUERY_THROW );
614 if ( xSI->supportsService( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.Shape" ) ) ) )
615 return true;
617 catch( const Exception& )
619 DBG_UNHANDLED_EXCEPTION();
621 return false;
624 //--------------------------------------------------------------------
625 namespace
627 static sal_Int32 lcl_getLowerBoundRowOrColumn( const Reference< XIndexAccess >& _rxRowsOrColumns, const bool _bRows,
628 const AwtPoint& _rRelativePosition )
630 sal_Int32 nAccumulated = 0;
632 const sal_Int32& rRelativePos = _bRows ? _rRelativePosition.Y : _rRelativePosition.X;
634 sal_Int32 nElements = _rxRowsOrColumns->getCount();
635 sal_Int32 currentPos = 0;
636 for ( currentPos=0; currentPos<nElements; ++currentPos )
638 Reference< XPropertySet > xRowOrColumn( _rxRowsOrColumns->getByIndex( currentPos ), UNO_QUERY_THROW );
640 sal_Bool bIsVisible = sal_True;
641 OSL_VERIFY( xRowOrColumn->getPropertyValue( PROPERTY_IS_VISIBLE ) >>= bIsVisible );
642 if ( !bIsVisible )
643 continue;
645 sal_Int32 nHeightOrWidth( 0 );
646 OSL_VERIFY( xRowOrColumn->getPropertyValue( _bRows ? PROPERTY_HEIGHT : PROPERTY_WIDTH ) >>= nHeightOrWidth );
648 if ( nAccumulated + nHeightOrWidth > rRelativePos )
649 break;
651 nAccumulated += nHeightOrWidth;
654 return currentPos;
658 //--------------------------------------------------------------------
659 void FormGeometryHandler::impl_setSheetAnchorType_nothrow( const sal_Int32 _nAnchorType ) const
661 ENSURE_OR_THROW( m_xShapeProperties.is(), "illegal to be called without shape properties." );
664 CellBindingHelper aHelper( m_xComponent, impl_getContextDocument_nothrow() );
665 // find the sheet which the control belongs to
666 Reference< XSpreadsheet > xSheet;
667 aHelper.getControlSheetIndex( xSheet );
669 switch ( _nAnchorType )
671 case ANCHOR_TO_SHEET:
672 OSL_ENSURE( xSheet.is(),
673 "FormGeometryHandler::impl_setSheetAnchorType_nothrow: sheet not found!" );
674 if ( xSheet.is() )
676 AwtPoint aPreservePosition( m_xAssociatedShape->getPosition() );
677 m_xShapeProperties->setPropertyValue( PROPERTY_ANCHOR, makeAny( xSheet ) );
678 m_xAssociatedShape->setPosition( aPreservePosition );
680 break;
682 case ANCHOR_TO_CELL:
684 Reference< XColumnRowRange > xColsRows( xSheet, UNO_QUERY_THROW );
686 // get the current anchor
687 Reference< XSpreadsheet > xCurrentAnchor;
688 OSL_VERIFY( m_xShapeProperties->getPropertyValue( PROPERTY_ANCHOR ) >>= xCurrentAnchor );
689 OSL_ENSURE( xCurrentAnchor.is(), "FormGeometryHandler::impl_setSheetAnchorType_nothrow: only to be called when currently anchored to a sheet!" );
691 // get the current position
692 AwtPoint aRelativePosition( m_xAssociatedShape->getPosition() );
694 Reference< XTableColumns > xCols( xColsRows->getColumns(), UNO_SET_THROW );
695 sal_Int32 nNewAnchorCol = lcl_getLowerBoundRowOrColumn( xCols.get(), false, aRelativePosition );
697 Reference< XTableRows > xRows( xColsRows->getRows(), UNO_SET_THROW );
698 sal_Int32 nNewAnchorRow = lcl_getLowerBoundRowOrColumn( xRows.get(), true, aRelativePosition );
700 Reference< XCellRange > xSheetCellRange( xSheet, UNO_QUERY_THROW );
701 Any aNewAnchorCell( xSheetCellRange->getCellByPosition( nNewAnchorCol, nNewAnchorRow ) );
702 m_xShapeProperties->setPropertyValue( PROPERTY_ANCHOR, aNewAnchorCell );
704 break;
706 default:
707 OSL_ENSURE( false, "FormGeometryHandler::impl_setSheetAnchorType_nothrow: illegal anchor type!" );
708 break;
711 catch( const Exception& )
713 DBG_UNHANDLED_EXCEPTION();
717 //====================================================================
718 //= ShapeGeometryChangeNotifier - implementation
719 //====================================================================
720 namespace
722 struct EventTranslation
724 ::rtl::OUString sPropertyName;
725 Any aNewPropertyValue;
727 EventTranslation( const ::rtl::OUString& _propertyName, const Any& _newPropertyValue )
728 :sPropertyName( _propertyName )
729 ,aNewPropertyValue( _newPropertyValue )
735 //--------------------------------------------------------------------
736 void SAL_CALL ShapeGeometryChangeNotifier::propertyChange( const PropertyChangeEvent& _event ) throw (RuntimeException)
738 ::comphelper::ComponentMethodGuard aGuard( *this );
740 ::std::vector< EventTranslation > aEventTranslations;
741 aEventTranslations.reserve(2);
743 if ( _event.PropertyName.equalsAscii( "Position" ) )
745 AwtPoint aPos = m_xShape->getPosition();
746 aEventTranslations.push_back( EventTranslation( PROPERTY_POSITIONX, makeAny( aPos.X ) ) );
747 aEventTranslations.push_back( EventTranslation( PROPERTY_POSITIONY, makeAny( aPos.Y ) ) );
749 else if ( _event.PropertyName.equalsAscii( "Size" ) )
751 AwtSize aSize = m_xShape->getSize();
752 aEventTranslations.push_back( EventTranslation( PROPERTY_WIDTH, makeAny( aSize.Width ) ) );
753 aEventTranslations.push_back( EventTranslation( PROPERTY_HEIGHT, makeAny( aSize.Height ) ) );
755 else if ( _event.PropertyName == PROPERTY_ANCHOR_TYPE )
757 aEventTranslations.push_back( EventTranslation( PROPERTY_TEXT_ANCHOR_TYPE, makeAny( _event.NewValue ) ) );
759 else if ( _event.PropertyName == PROPERTY_ANCHOR )
761 aEventTranslations.push_back( EventTranslation( PROPERTY_SHEET_ANCHOR_TYPE, makeAny( _event.NewValue ) ) );
764 PropertyChangeEvent aTranslatedEvent( _event );
765 aTranslatedEvent.Source = m_rParent;
767 aGuard.clear();
768 for ( ::std::vector< EventTranslation >::const_iterator t = aEventTranslations.begin();
769 t != aEventTranslations.end();
773 aTranslatedEvent.PropertyName = t->sPropertyName;
774 aTranslatedEvent.NewValue = t->aNewPropertyValue;
775 m_aPropertyChangeListeners.notifyEach( &XPropertyChangeListener::propertyChange, aTranslatedEvent );
779 //--------------------------------------------------------------------
780 void SAL_CALL ShapeGeometryChangeNotifier::disposing( const EventObject& /*_event*/ ) throw (RuntimeException)
782 ::comphelper::ComponentMethodGuard aGuard( *this );
783 impl_dispose_nothrow();
786 //--------------------------------------------------------------------
787 void ShapeGeometryChangeNotifier::impl_init_nothrow()
789 osl_incrementInterlockedCount( &m_refCount );
792 Reference< XPropertySet > xShapeProperties( m_xShape, UNO_QUERY_THROW );
793 xShapeProperties->addPropertyChangeListener( ::rtl::OUString(), this );
795 catch( const Exception& )
797 DBG_UNHANDLED_EXCEPTION();
799 osl_decrementInterlockedCount( &m_refCount );
802 //--------------------------------------------------------------------
803 void ShapeGeometryChangeNotifier::impl_dispose_nothrow()
807 Reference< XPropertySet > xShapeProperties( m_xShape, UNO_QUERY_THROW );
808 xShapeProperties->removePropertyChangeListener( ::rtl::OUString(), this );
810 catch( const Exception& )
812 DBG_UNHANDLED_EXCEPTION();
815 getBroadcastHelper().bDisposed = true;
818 //........................................................................
819 } // namespace pcr
820 //........................................................................
822 extern "C" void SAL_CALL createRegistryInfo_FormGeometryHandler()
824 ::pcr::FormGeometryHandler::registerImplementation();