bump product version to 4.1.6.2
[LibreOffice.git] / extensions / source / propctrlr / formgeometryhandler.cxx
blob6738b66ae02ccca95479230876b5ac089461d6ba
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 //........................................................................
47 namespace pcr
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
106 protected:
107 BroadcastHelperBase( ::osl::Mutex& _rMutex )
108 :maBHelper( _rMutex )
112 protected:
113 ::cppu::OBroadcastHelper& getBroadcastHelper() { return maBHelper; }
115 private:
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
133 public:
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 )
140 ,m_xShape( _shape )
142 ENSURE_OR_THROW( m_xShape.is(), "illegal shape!" );
143 impl_init_nothrow();
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
157 void dispose()
159 ::osl::MutexGuard aGuard( getMutex() );
160 impl_dispose_nothrow();
163 // XInterface
164 virtual void SAL_CALL acquire( ) throw ()
166 m_rParent.acquire();
169 virtual void SAL_CALL release( ) throw ()
171 m_rParent.release();
174 // XPropertyChangeListener
175 virtual void SAL_CALL propertyChange( const PropertyChangeEvent& _event ) throw (RuntimeException);
177 // XEventListener
178 virtual void SAL_CALL disposing( const EventObject& _event ) throw (RuntimeException);
180 protected:
181 virtual ~ShapeGeometryChangeNotifier()
183 if ( !getBroadcastHelper().bDisposed )
185 acquire();
186 dispose();
190 protected:
191 ::cppu::OBroadcastHelper& getBroadcastHelper() { return BroadcastHelperBase::getBroadcastHelper(); }
193 private:
194 void impl_init_nothrow();
195 void impl_dispose_nothrow();
197 private:
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
212 public:
213 FormGeometryHandler(
214 const Reference< XComponentContext >& _rxContext
217 static OUString SAL_CALL getImplementationName_static( ) throw (RuntimeException);
218 static Sequence< OUString > SAL_CALL getSupportedServiceNames_static( ) throw (RuntimeException);
220 protected:
221 ~FormGeometryHandler();
223 protected:
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;
239 protected:
240 virtual void onNewComponent();
242 private:
243 bool impl_haveTextAnchorType_nothrow() const;
244 bool impl_haveSheetAnchorType_nothrow() const;
245 void impl_setSheetAnchorType_nothrow( const sal_Int32 _nAnchorType ) const;
247 private:
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 )
269 acquire();
270 dispose();
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" );
325 return aSupported;
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 );
337 Any aReturn;
340 switch ( nPropId )
342 case PROPERTY_ID_POSITIONX:
343 aReturn <<= m_xAssociatedShape->getPosition().X;
344 break;
345 case PROPERTY_ID_POSITIONY:
346 aReturn <<= m_xAssociatedShape->getPosition().Y;
347 break;
348 case PROPERTY_ID_WIDTH:
349 aReturn <<= m_xAssociatedShape->getSize().Width;
350 break;
351 case PROPERTY_ID_HEIGHT:
352 aReturn <<= m_xAssociatedShape->getSize().Height;
353 break;
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!" );
357 break;
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 );
363 break;
365 default:
366 OSL_FAIL( "FormGeometryHandler::getPropertyValue: huh?" );
367 break;
370 catch( const Exception& )
372 DBG_UNHANDLED_EXCEPTION();
374 return aReturn;
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 );
388 switch ( nPropId )
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 )
398 aPos.X = nPosition;
399 else
400 aPos.Y = nPosition;
401 m_xAssociatedShape->setPosition( aPos );
403 break;
405 case PROPERTY_ID_WIDTH:
406 case PROPERTY_ID_HEIGHT:
408 sal_Int32 nSize(0);
409 OSL_VERIFY( _rValue >>= nSize );
411 AwtSize aSize( m_xAssociatedShape->getSize() );
412 if ( nPropId == PROPERTY_ID_WIDTH )
413 aSize.Width = nSize;
414 else
415 aSize.Height = nSize;
416 m_xAssociatedShape->setSize( aSize );
418 break;
420 case PROPERTY_ID_TEXT_ANCHOR_TYPE:
421 m_xShapeProperties->setPropertyValue( PROPERTY_ANCHOR_TYPE, _rValue );
422 break;
424 case PROPERTY_ID_SHEET_ANCHOR_TYPE:
426 sal_Int32 nSheetAnchorType = 0;
427 OSL_VERIFY( _rValue >>= nSheetAnchorType );
428 impl_setSheetAnchorType_nothrow( nSheetAnchorType );
430 break;
432 default:
433 OSL_FAIL( "FormGeometryHandler::getPropertyValue: huh?" );
434 break;
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;
455 switch ( nPropId )
457 case PROPERTY_ID_WIDTH:
458 case PROPERTY_ID_HEIGHT:
459 bIsSize = true;
460 // NO break!
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() );
473 break;
475 case PROPERTY_ID_TEXT_ANCHOR_TYPE:
476 case PROPERTY_ID_SHEET_ANCHOR_TYPE:
477 // default handling from PropertyHandler is sufficient
478 break;
480 default:
481 OSL_FAIL( "FormGeometryHandler::describePropertyLine: huh?" );
482 break;
485 catch( const Exception& )
487 DBG_UNHANDLED_EXCEPTION();
489 return aLineDesc;
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 );
535 break;
536 default:
537 OSL_FAIL( "FormGeometryHandler::actuatingPropertyChanged: not registered for this property!" );
538 break;
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 ) )
584 return true;
586 catch( const Exception& )
588 DBG_UNHANDLED_EXCEPTION();
590 return false;
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 ) )
601 return false;
602 Reference< XServiceInfo > xSI( m_xAssociatedShape, UNO_QUERY_THROW );
603 if ( xSI->supportsService( OUString( "com.sun.star.sheet.Shape" ) ) )
604 return true;
606 catch( const Exception& )
608 DBG_UNHANDLED_EXCEPTION();
610 return false;
613 //--------------------------------------------------------------------
614 namespace
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 );
631 if ( !bIsVisible )
632 continue;
634 sal_Int32 nHeightOrWidth( 0 );
635 OSL_VERIFY( xRowOrColumn->getPropertyValue( _bRows ? OUString(PROPERTY_HEIGHT) : OUString(PROPERTY_WIDTH) ) >>= nHeightOrWidth );
637 if ( nAccumulated + nHeightOrWidth > rRelativePos )
638 break;
640 nAccumulated += nHeightOrWidth;
643 return currentPos;
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!" );
663 if ( xSheet.is() )
665 AwtPoint aPreservePosition( m_xAssociatedShape->getPosition() );
666 m_xShapeProperties->setPropertyValue( PROPERTY_ANCHOR, makeAny( xSheet ) );
667 m_xAssociatedShape->setPosition( aPreservePosition );
669 break;
671 case ANCHOR_TO_CELL:
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 );
693 break;
695 default:
696 OSL_FAIL( "FormGeometryHandler::impl_setSheetAnchorType_nothrow: illegal anchor type!" );
697 break;
700 catch( const Exception& )
702 DBG_UNHANDLED_EXCEPTION();
706 //====================================================================
707 //= ShapeGeometryChangeNotifier - implementation
708 //====================================================================
709 namespace
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;
756 aGuard.clear();
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 //........................................................................
808 } // namespace pcr
809 //........................................................................
811 extern "C" void SAL_CALL createRegistryInfo_FormGeometryHandler()
813 ::pcr::FormGeometryHandler::registerImplementation();
816 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */