bump product version to 6.3.0.0.beta1
[LibreOffice.git] / extensions / source / propctrlr / formgeometryhandler.cxx
blobd97301c743ab4434487df69a9ee3facf6ed4f2bb
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 .
20 #include <sal/config.h>
22 #include "pcrservices.hxx"
23 #include "propertyhandler.hxx"
24 #include "formmetadata.hxx"
25 #include "formstrings.hxx"
26 #include "handlerhelper.hxx"
27 #include "cellbindinghelper.hxx"
29 #include <com/sun/star/inspection/XObjectInspectorUI.hpp>
30 #include <com/sun/star/awt/XControlModel.hpp>
31 #include <com/sun/star/drawing/XControlShape.hpp>
32 #include <com/sun/star/container/XMap.hpp>
33 #include <com/sun/star/inspection/XNumericControl.hpp>
34 #include <com/sun/star/util/MeasureUnit.hpp>
35 #include <com/sun/star/text/TextContentAnchorType.hpp>
36 #include <com/sun/star/lang/NullPointerException.hpp>
37 #include <com/sun/star/lang/XServiceInfo.hpp>
38 #include <com/sun/star/sheet/XSpreadsheet.hpp>
39 #include <com/sun/star/table/XColumnRowRange.hpp>
40 #include <com/sun/star/container/XChild.hpp>
41 #include <com/sun/star/form/XGridColumnFactory.hpp>
43 #include <cppuhelper/implbase.hxx>
44 #include <cppuhelper/interfacecontainer.hxx>
45 #include <comphelper/componentbase.hxx>
46 #include <tools/diagnose_ex.h>
48 namespace pcr
52 using ::com::sun::star::uno::Reference;
53 using ::com::sun::star::uno::XInterface;
54 using ::com::sun::star::uno::UNO_QUERY;
55 using ::com::sun::star::uno::UNO_QUERY_THROW;
56 using ::com::sun::star::uno::UNO_SET_THROW;
57 using ::com::sun::star::uno::Exception;
58 using ::com::sun::star::uno::RuntimeException;
59 using ::com::sun::star::uno::Any;
60 using ::com::sun::star::uno::makeAny;
61 using ::com::sun::star::uno::Sequence;
62 using ::com::sun::star::uno::XComponentContext;
63 using ::com::sun::star::beans::Property;
64 using ::com::sun::star::awt::XControlModel;
65 using ::com::sun::star::drawing::XControlShape;
66 using ::com::sun::star::container::XMap;
67 using ::com::sun::star::inspection::LineDescriptor;
68 using ::com::sun::star::inspection::XPropertyControlFactory;
69 using ::com::sun::star::lang::NullPointerException;
70 using ::com::sun::star::beans::Optional;
71 using ::com::sun::star::inspection::XNumericControl;
72 using ::com::sun::star::drawing::XShape;
73 using ::com::sun::star::beans::PropertyChangeEvent;
74 using ::com::sun::star::lang::EventObject;
75 using ::com::sun::star::beans::XPropertySet;
76 using ::com::sun::star::beans::XPropertyChangeListener;
77 using ::com::sun::star::text::TextContentAnchorType;
78 using ::com::sun::star::text::TextContentAnchorType_AT_PARAGRAPH;
79 using ::com::sun::star::text::TextContentAnchorType_AS_CHARACTER;
80 using ::com::sun::star::beans::XPropertySetInfo;
81 using ::com::sun::star::inspection::XObjectInspectorUI;
82 using ::com::sun::star::lang::XServiceInfo;
83 using ::com::sun::star::sheet::XSpreadsheet;
84 using ::com::sun::star::table::XColumnRowRange;
85 using ::com::sun::star::table::XTableColumns;
86 using ::com::sun::star::table::XTableRows;
87 using ::com::sun::star::container::XIndexAccess;
88 using ::com::sun::star::container::XChild;
89 using ::com::sun::star::form::XGridColumnFactory;
91 namespace MeasureUnit = css::util::MeasureUnit;
93 #define ANCHOR_TO_SHEET 0
94 #define ANCHOR_TO_CELL 1
97 //= BroadcastHelperBase
99 class BroadcastHelperBase
101 protected:
102 explicit BroadcastHelperBase( ::osl::Mutex& _rMutex )
103 :maBHelper( _rMutex )
107 protected:
108 ::cppu::OBroadcastHelper& getBroadcastHelper() { return maBHelper; }
110 private:
111 ::cppu::OBroadcastHelper maBHelper;
115 //= ShapeGeometryChangeNotifier - declaration
117 /** helper class to work around the ...unfortunate implementation of property change broadcasts
118 in the XShape implementation, which broadcasts way too generous and unspecified
120 typedef ::comphelper::ComponentBase ShapeGeometryChangeNotifier_CBase;
121 typedef ::cppu::WeakImplHelper < css::beans::XPropertyChangeListener
122 > ShapeGeometryChangeNotifier_IBase;
124 class ShapeGeometryChangeNotifier :public BroadcastHelperBase
125 ,public ShapeGeometryChangeNotifier_CBase
126 ,public ShapeGeometryChangeNotifier_IBase
128 public:
129 ShapeGeometryChangeNotifier( ::cppu::OWeakObject& _rParent, ::osl::Mutex& _rParentMutex, const Reference< XShape >& _shape )
130 :BroadcastHelperBase( _rParentMutex )
131 ,ShapeGeometryChangeNotifier_CBase( BroadcastHelperBase::getBroadcastHelper(), ::comphelper::ComponentBase::NoInitializationNeeded() )
132 ,ShapeGeometryChangeNotifier_IBase()
133 ,m_rParent( _rParent )
134 ,m_aPropertyChangeListeners( _rParentMutex )
135 ,m_xShape( _shape )
137 ENSURE_OR_THROW( m_xShape.is(), "illegal shape!" );
138 impl_init_nothrow();
141 // property change broadcasting
142 void addPropertyChangeListener( const Reference< XPropertyChangeListener >& _listener )
144 m_aPropertyChangeListeners.addInterface( _listener );
146 void removePropertyChangeListener( const Reference< XPropertyChangeListener >& _listener )
148 m_aPropertyChangeListeners.removeInterface( _listener );
151 // XComponent equivalent
152 void dispose()
154 ::osl::MutexGuard aGuard( getMutex() );
155 impl_dispose_nothrow();
158 // XInterface
159 virtual void SAL_CALL acquire( ) throw () override
161 m_rParent.acquire();
164 virtual void SAL_CALL release( ) throw () override
166 m_rParent.release();
169 // XPropertyChangeListener
170 virtual void SAL_CALL propertyChange( const PropertyChangeEvent& _event ) override;
172 // XEventListener
173 virtual void SAL_CALL disposing( const EventObject& _event ) override;
175 protected:
176 virtual ~ShapeGeometryChangeNotifier() override
178 if ( !getBroadcastHelper().bDisposed )
180 acquire();
181 dispose();
185 protected:
186 ::cppu::OBroadcastHelper& getBroadcastHelper() { return BroadcastHelperBase::getBroadcastHelper(); }
188 private:
189 void impl_init_nothrow();
190 void impl_dispose_nothrow();
192 private:
193 ::cppu::OWeakObject& m_rParent;
194 ::comphelper::OInterfaceContainerHelper2 m_aPropertyChangeListeners;
195 Reference< XShape > m_xShape;
199 //= FormGeometryHandler - declaration
201 class FormGeometryHandler;
202 typedef HandlerComponentBase< FormGeometryHandler > FormGeometryHandler_Base;
203 /** a property handler for any virtual string properties
205 class FormGeometryHandler : public FormGeometryHandler_Base
207 public:
208 explicit FormGeometryHandler(
209 const Reference< XComponentContext >& _rxContext
212 /// @throws RuntimeException
213 static OUString getImplementationName_static( );
214 /// @throws RuntimeException
215 static Sequence< OUString > getSupportedServiceNames_static( );
217 protected:
218 virtual ~FormGeometryHandler() override;
220 protected:
221 // XPropertyHandler overriables
222 virtual Any SAL_CALL getPropertyValue( const OUString& _rPropertyName ) override;
223 virtual void SAL_CALL setPropertyValue( const OUString& _rPropertyName, const Any& _rValue ) override;
224 virtual LineDescriptor SAL_CALL describePropertyLine( const OUString& _rPropertyName, const css::uno::Reference< css::inspection::XPropertyControlFactory >& _rxControlFactory ) override;
225 virtual void SAL_CALL addPropertyChangeListener( const css::uno::Reference< css::beans::XPropertyChangeListener >& _rxListener ) override;
226 virtual void SAL_CALL removePropertyChangeListener( const css::uno::Reference< css::beans::XPropertyChangeListener >& _rxListener ) override;
227 virtual Sequence< OUString > SAL_CALL getActuatingProperties( ) override;
228 virtual void SAL_CALL actuatingPropertyChanged( const OUString& _rActuatingPropertyName, const Any& _rNewValue, const Any& _rOldValue, const Reference< XObjectInspectorUI >& _rxInspectorUI, sal_Bool _bFirstTimeInit ) override;
230 // OComponentHandler overridables
231 virtual void SAL_CALL disposing() override;
233 // PropertyHandler overridables
234 virtual Sequence< Property > doDescribeSupportedProperties() const override;
236 protected:
237 virtual void onNewComponent() override;
239 private:
240 bool impl_haveTextAnchorType_nothrow() const;
241 bool impl_haveSheetAnchorType_nothrow() const;
242 void impl_setSheetAnchorType_nothrow( const sal_Int32 _nAnchorType ) const;
244 private:
245 Reference< XControlShape > m_xAssociatedShape;
246 Reference< XPropertySet > m_xShapeProperties;
247 ::rtl::Reference< ShapeGeometryChangeNotifier > m_xChangeNotifier;
251 //= FormGeometryHandler - implementation
254 FormGeometryHandler::FormGeometryHandler( const Reference< XComponentContext >& _rxContext )
255 :FormGeometryHandler_Base( _rxContext )
260 FormGeometryHandler::~FormGeometryHandler( )
262 if ( !rBHelper.bDisposed )
264 acquire();
265 dispose();
271 void FormGeometryHandler::onNewComponent()
273 if ( m_xChangeNotifier.is() )
275 m_xChangeNotifier->dispose();
276 m_xChangeNotifier.clear();
278 m_xAssociatedShape.clear();
279 m_xShapeProperties.clear();
281 FormGeometryHandler_Base::onNewComponent();
285 Reference< XControlModel > xControlModel( m_xComponent, UNO_QUERY );
286 if ( xControlModel.is() )
288 // do not ask the map for shapes for grid control columns ....
289 Reference< XChild > xCompChild( m_xComponent, UNO_QUERY_THROW );
290 Reference< XGridColumnFactory > xCheckGrid( xCompChild->getParent(), UNO_QUERY );
291 if ( !xCheckGrid.is() )
293 Reference< XMap > xControlMap;
294 Any any = m_xContext->getValueByName( "ControlShapeAccess" );
295 any >>= xControlMap;
296 m_xAssociatedShape.set( xControlMap->get( makeAny( xControlModel ) ), UNO_QUERY_THROW );
297 m_xShapeProperties.set( m_xAssociatedShape, UNO_QUERY_THROW );
301 catch( const Exception& )
303 DBG_UNHANDLED_EXCEPTION("extensions.propctrlr");
306 if ( m_xAssociatedShape.is() )
307 m_xChangeNotifier = new ShapeGeometryChangeNotifier( *this, m_aMutex, m_xAssociatedShape.get() );
311 OUString FormGeometryHandler::getImplementationName_static( )
313 return OUString( "com.sun.star.comp.extensions.FormGeometryHandler" );
317 Sequence< OUString > FormGeometryHandler::getSupportedServiceNames_static( )
319 Sequence<OUString> aSupported { "com.sun.star.form.inspection.FormGeometryHandler" };
320 return aSupported;
324 Any SAL_CALL FormGeometryHandler::getPropertyValue( const OUString& _rPropertyName )
326 ::osl::MutexGuard aGuard( m_aMutex );
327 PropertyId nPropId( impl_getPropertyId_throwUnknownProperty( _rPropertyName ) );
329 ENSURE_OR_THROW2( m_xAssociatedShape.is(), "internal error: properties, but no shape!", *this );
330 ENSURE_OR_THROW2( m_xShapeProperties.is(), "internal error: no shape properties!", *this );
332 Any aReturn;
335 switch ( nPropId )
337 case PROPERTY_ID_POSITIONX:
338 aReturn <<= m_xAssociatedShape->getPosition().X;
339 break;
340 case PROPERTY_ID_POSITIONY:
341 aReturn <<= m_xAssociatedShape->getPosition().Y;
342 break;
343 case PROPERTY_ID_WIDTH:
344 aReturn <<= m_xAssociatedShape->getSize().Width;
345 break;
346 case PROPERTY_ID_HEIGHT:
347 aReturn <<= m_xAssociatedShape->getSize().Height;
348 break;
349 case PROPERTY_ID_TEXT_ANCHOR_TYPE:
350 aReturn = m_xShapeProperties->getPropertyValue( PROPERTY_ANCHOR_TYPE );
351 OSL_ENSURE( aReturn.hasValue(), "FormGeometryHandler::getPropertyValue: illegal anchor type!" );
352 break;
353 case PROPERTY_ID_SHEET_ANCHOR_TYPE:
355 Reference< XSpreadsheet > xAnchorSheet( m_xShapeProperties->getPropertyValue( PROPERTY_ANCHOR ), UNO_QUERY );
356 aReturn <<= sal_Int32( xAnchorSheet.is() ? ANCHOR_TO_SHEET : ANCHOR_TO_CELL );
358 break;
360 default:
361 OSL_FAIL( "FormGeometryHandler::getPropertyValue: huh?" );
362 break;
365 catch( const Exception& )
367 DBG_UNHANDLED_EXCEPTION("extensions.propctrlr");
369 return aReturn;
373 void SAL_CALL FormGeometryHandler::setPropertyValue( const OUString& _rPropertyName, const Any& _rValue )
375 ::osl::MutexGuard aGuard( m_aMutex );
376 PropertyId nPropId( impl_getPropertyId_throwUnknownProperty( _rPropertyName ) );
378 ENSURE_OR_THROW2( m_xAssociatedShape.is(), "internal error: properties, but no shape!", *this );
379 ENSURE_OR_THROW2( m_xShapeProperties.is(), "internal error: properties, but no shape!", *this );
383 switch ( nPropId )
385 case PROPERTY_ID_POSITIONX:
386 case PROPERTY_ID_POSITIONY:
388 sal_Int32 nPosition(0);
389 OSL_VERIFY( _rValue >>= nPosition );
391 css::awt::Point aPos( m_xAssociatedShape->getPosition() );
392 if ( nPropId == PROPERTY_ID_POSITIONX )
393 aPos.X = nPosition;
394 else
395 aPos.Y = nPosition;
396 m_xAssociatedShape->setPosition( aPos );
398 break;
400 case PROPERTY_ID_WIDTH:
401 case PROPERTY_ID_HEIGHT:
403 sal_Int32 nSize(0);
404 OSL_VERIFY( _rValue >>= nSize );
406 css::awt::Size aSize( m_xAssociatedShape->getSize() );
407 if ( nPropId == PROPERTY_ID_WIDTH )
408 aSize.Width = nSize;
409 else
410 aSize.Height = nSize;
411 m_xAssociatedShape->setSize( aSize );
413 break;
415 case PROPERTY_ID_TEXT_ANCHOR_TYPE:
416 m_xShapeProperties->setPropertyValue( PROPERTY_ANCHOR_TYPE, _rValue );
417 break;
419 case PROPERTY_ID_SHEET_ANCHOR_TYPE:
421 sal_Int32 nSheetAnchorType = 0;
422 OSL_VERIFY( _rValue >>= nSheetAnchorType );
423 impl_setSheetAnchorType_nothrow( nSheetAnchorType );
425 break;
427 default:
428 OSL_FAIL( "FormGeometryHandler::getPropertyValue: huh?" );
429 break;
432 catch( const Exception& )
434 DBG_UNHANDLED_EXCEPTION("extensions.propctrlr");
439 LineDescriptor SAL_CALL FormGeometryHandler::describePropertyLine( const OUString& _rPropertyName,
440 const Reference< XPropertyControlFactory >& _rxControlFactory )
442 ::osl::MutexGuard aGuard( m_aMutex );
443 PropertyId nPropId( impl_getPropertyId_throwUnknownProperty( _rPropertyName ) );
445 LineDescriptor aLineDesc( PropertyHandler::describePropertyLine( _rPropertyName, _rxControlFactory ) );
448 bool bIsSize = false;
449 switch ( nPropId )
451 case PROPERTY_ID_WIDTH:
452 case PROPERTY_ID_HEIGHT:
453 bIsSize = true;
454 [[fallthrough]];
455 case PROPERTY_ID_POSITIONX:
456 case PROPERTY_ID_POSITIONY:
458 Optional< double > aZero( true, 0 );
459 Optional< double > aValueNotPresent( false, 0 );
460 aLineDesc.Control = PropertyHandlerHelper::createNumericControl(
461 _rxControlFactory, 2, bIsSize ? aZero : aValueNotPresent, aValueNotPresent );
463 Reference< XNumericControl > xNumericControl( aLineDesc.Control, UNO_QUERY_THROW );
464 xNumericControl->setValueUnit( MeasureUnit::MM_100TH );
465 xNumericControl->setDisplayUnit( impl_getDocumentMeasurementUnit_throw() );
467 break;
469 case PROPERTY_ID_TEXT_ANCHOR_TYPE:
470 case PROPERTY_ID_SHEET_ANCHOR_TYPE:
471 // default handling from PropertyHandler is sufficient
472 break;
474 default:
475 OSL_FAIL( "FormGeometryHandler::describePropertyLine: huh?" );
476 break;
479 catch( const Exception& )
481 DBG_UNHANDLED_EXCEPTION("extensions.propctrlr");
483 return aLineDesc;
487 void SAL_CALL FormGeometryHandler::addPropertyChangeListener( const Reference< XPropertyChangeListener >& _listener )
489 ::osl::MutexGuard aGuard( m_aMutex );
490 OSL_PRECOND( m_xChangeNotifier.is(), "FormGeometryHandler::addPropertyChangeListener: no notified, implies no shape!?" );
491 if ( m_xChangeNotifier.is() )
492 m_xChangeNotifier->addPropertyChangeListener( _listener );
496 void SAL_CALL FormGeometryHandler::removePropertyChangeListener( const Reference< XPropertyChangeListener >& _listener )
498 ::osl::MutexGuard aGuard( m_aMutex );
499 OSL_PRECOND( m_xChangeNotifier.is(), "FormGeometryHandler::removePropertyChangeListener: no notified, implies no shape!?" );
500 if ( m_xChangeNotifier.is() )
501 m_xChangeNotifier->removePropertyChangeListener( _listener );
505 Sequence< OUString > SAL_CALL FormGeometryHandler::getActuatingProperties( )
507 Sequence< OUString > aInterestedIn { PROPERTY_TEXT_ANCHOR_TYPE };
508 return aInterestedIn;
512 void SAL_CALL FormGeometryHandler::actuatingPropertyChanged( const OUString& _rActuatingPropertyName, const Any& _rNewValue, const Any& /*_rOldValue*/, const Reference< XObjectInspectorUI >& _rxInspectorUI, sal_Bool /*_bFirstTimeInit*/ )
514 if ( !_rxInspectorUI.is() )
515 throw NullPointerException();
517 ::osl::MutexGuard aGuard( m_aMutex );
518 PropertyId nActuatingPropId( impl_getPropertyId_nothrow( _rActuatingPropertyName ) );
520 switch ( nActuatingPropId )
522 case PROPERTY_ID_TEXT_ANCHOR_TYPE:
524 TextContentAnchorType eAnchorType( TextContentAnchorType_AT_PARAGRAPH );
525 OSL_VERIFY( _rNewValue >>= eAnchorType );
526 _rxInspectorUI->enablePropertyUI( PROPERTY_POSITIONX, eAnchorType != TextContentAnchorType_AS_CHARACTER );
528 break;
529 case -1:
530 throw RuntimeException();
531 break;
532 default:
533 OSL_FAIL( "FormGeometryHandler::actuatingPropertyChanged: not registered for this property!" );
534 break;
539 Sequence< Property > FormGeometryHandler::doDescribeSupportedProperties() const
541 if ( !m_xAssociatedShape.is() )
542 return Sequence< Property >();
544 std::vector< Property > aProperties;
546 addInt32PropertyDescription( aProperties, PROPERTY_POSITIONX );
547 addInt32PropertyDescription( aProperties, PROPERTY_POSITIONY );
548 addInt32PropertyDescription( aProperties, PROPERTY_WIDTH );
549 addInt32PropertyDescription( aProperties, PROPERTY_HEIGHT );
551 if ( impl_haveTextAnchorType_nothrow() )
552 implAddPropertyDescription( aProperties, PROPERTY_TEXT_ANCHOR_TYPE, ::cppu::UnoType< TextContentAnchorType >::get() );
554 if ( impl_haveSheetAnchorType_nothrow() )
555 addInt32PropertyDescription( aProperties, PROPERTY_SHEET_ANCHOR_TYPE );
557 return comphelper::containerToSequence(aProperties);
561 void SAL_CALL FormGeometryHandler::disposing()
563 FormGeometryHandler_Base::disposing();
565 if ( m_xChangeNotifier.is() )
567 m_xChangeNotifier->dispose();
568 m_xChangeNotifier.clear();
573 bool FormGeometryHandler::impl_haveTextAnchorType_nothrow() const
575 ENSURE_OR_THROW( m_xShapeProperties.is(), "not to be called without shape properties" );
578 Reference< XPropertySetInfo > xPSI( m_xShapeProperties->getPropertySetInfo(), UNO_SET_THROW );
579 if ( xPSI->hasPropertyByName( PROPERTY_ANCHOR_TYPE ) )
580 return true;
582 catch( const Exception& )
584 DBG_UNHANDLED_EXCEPTION("extensions.propctrlr");
586 return false;
590 bool FormGeometryHandler::impl_haveSheetAnchorType_nothrow() const
592 ENSURE_OR_THROW( m_xShapeProperties.is(), "not to be called without shape properties" );
595 Reference< XPropertySetInfo > xPSI( m_xShapeProperties->getPropertySetInfo(), UNO_SET_THROW );
596 if ( !xPSI->hasPropertyByName( PROPERTY_ANCHOR ) )
597 return false;
598 Reference< XServiceInfo > xSI( m_xAssociatedShape, UNO_QUERY_THROW );
599 if ( xSI->supportsService("com.sun.star.sheet.Shape") )
600 return true;
602 catch( const Exception& )
604 DBG_UNHANDLED_EXCEPTION("extensions.propctrlr");
606 return false;
610 namespace
612 sal_Int32 lcl_getLowerBoundRowOrColumn( const Reference< XIndexAccess >& _rxRowsOrColumns, const bool _bRows,
613 const css::awt::Point& _rRelativePosition )
615 sal_Int32 nAccumulated = 0;
617 const sal_Int32& rRelativePos = _bRows ? _rRelativePosition.Y : _rRelativePosition.X;
619 sal_Int32 nElements = _rxRowsOrColumns->getCount();
620 sal_Int32 currentPos = 0;
621 for ( currentPos=0; currentPos<nElements; ++currentPos )
623 Reference< XPropertySet > xRowOrColumn( _rxRowsOrColumns->getByIndex( currentPos ), UNO_QUERY_THROW );
625 bool bIsVisible = true;
626 OSL_VERIFY( xRowOrColumn->getPropertyValue( PROPERTY_IS_VISIBLE ) >>= bIsVisible );
627 if ( !bIsVisible )
628 continue;
630 sal_Int32 nHeightOrWidth( 0 );
631 OSL_VERIFY( xRowOrColumn->getPropertyValue( _bRows ? OUString(PROPERTY_HEIGHT) : OUString(PROPERTY_WIDTH) ) >>= nHeightOrWidth );
633 if ( nAccumulated + nHeightOrWidth > rRelativePos )
634 break;
636 nAccumulated += nHeightOrWidth;
639 return currentPos;
644 void FormGeometryHandler::impl_setSheetAnchorType_nothrow( const sal_Int32 _nAnchorType ) const
646 ENSURE_OR_THROW( m_xShapeProperties.is(), "illegal to be called without shape properties." );
649 CellBindingHelper aHelper( m_xComponent, impl_getContextDocument_nothrow() );
650 // find the sheet which the control belongs to
651 Reference< XSpreadsheet > xSheet;
652 aHelper.getControlSheetIndex( xSheet );
654 switch ( _nAnchorType )
656 case ANCHOR_TO_SHEET:
657 OSL_ENSURE( xSheet.is(),
658 "FormGeometryHandler::impl_setSheetAnchorType_nothrow: sheet not found!" );
659 if ( xSheet.is() )
661 css::awt::Point aPreservePosition( m_xAssociatedShape->getPosition() );
662 m_xShapeProperties->setPropertyValue( PROPERTY_ANCHOR, makeAny( xSheet ) );
663 m_xAssociatedShape->setPosition( aPreservePosition );
665 break;
667 case ANCHOR_TO_CELL:
669 Reference< XColumnRowRange > xColsRows( xSheet, UNO_QUERY_THROW );
671 // get the current anchor
672 Reference< XSpreadsheet > xCurrentAnchor;
673 OSL_VERIFY( m_xShapeProperties->getPropertyValue( PROPERTY_ANCHOR ) >>= xCurrentAnchor );
674 OSL_ENSURE( xCurrentAnchor.is(), "FormGeometryHandler::impl_setSheetAnchorType_nothrow: only to be called when currently anchored to a sheet!" );
676 // get the current position
677 css::awt::Point aRelativePosition( m_xAssociatedShape->getPosition() );
679 Reference< XTableColumns > xCols( xColsRows->getColumns(), UNO_SET_THROW );
680 sal_Int32 nNewAnchorCol = lcl_getLowerBoundRowOrColumn( xCols.get(), false, aRelativePosition );
682 Reference< XTableRows > xRows( xColsRows->getRows(), UNO_SET_THROW );
683 sal_Int32 nNewAnchorRow = lcl_getLowerBoundRowOrColumn( xRows.get(), true, aRelativePosition );
685 Any aNewAnchorCell( xSheet->getCellByPosition( nNewAnchorCol, nNewAnchorRow ) );
686 m_xShapeProperties->setPropertyValue( PROPERTY_ANCHOR, aNewAnchorCell );
688 break;
690 default:
691 OSL_FAIL( "FormGeometryHandler::impl_setSheetAnchorType_nothrow: illegal anchor type!" );
692 break;
695 catch( const Exception& )
697 DBG_UNHANDLED_EXCEPTION("extensions.propctrlr");
702 //= ShapeGeometryChangeNotifier - implementation
704 namespace
706 struct EventTranslation
708 OUString sPropertyName;
709 Any aNewPropertyValue;
711 EventTranslation( const OUString& _propertyName, const Any& _newPropertyValue )
712 :sPropertyName( _propertyName )
713 ,aNewPropertyValue( _newPropertyValue )
720 void SAL_CALL ShapeGeometryChangeNotifier::propertyChange( const PropertyChangeEvent& _event )
722 ::comphelper::ComponentMethodGuard aGuard( *this );
724 std::vector< EventTranslation > aEventTranslations;
725 aEventTranslations.reserve(2);
727 if ( _event.PropertyName == "Position" )
729 css::awt::Point aPos = m_xShape->getPosition();
730 aEventTranslations.push_back( EventTranslation( PROPERTY_POSITIONX, makeAny( aPos.X ) ) );
731 aEventTranslations.push_back( EventTranslation( PROPERTY_POSITIONY, makeAny( aPos.Y ) ) );
733 else if ( _event.PropertyName == "Size" )
735 css::awt::Size aSize = m_xShape->getSize();
736 aEventTranslations.push_back( EventTranslation( PROPERTY_WIDTH, makeAny( aSize.Width ) ) );
737 aEventTranslations.push_back( EventTranslation( PROPERTY_HEIGHT, makeAny( aSize.Height ) ) );
739 else if ( _event.PropertyName == PROPERTY_ANCHOR_TYPE )
741 aEventTranslations.push_back( EventTranslation( PROPERTY_TEXT_ANCHOR_TYPE, _event.NewValue ) );
743 else if ( _event.PropertyName == PROPERTY_ANCHOR )
745 aEventTranslations.push_back( EventTranslation( PROPERTY_SHEET_ANCHOR_TYPE, _event.NewValue ) );
748 PropertyChangeEvent aTranslatedEvent( _event );
749 aTranslatedEvent.Source = m_rParent;
751 aGuard.clear();
752 for (auto const& eventTranslation : aEventTranslations)
754 aTranslatedEvent.PropertyName = eventTranslation.sPropertyName;
755 aTranslatedEvent.NewValue = eventTranslation.aNewPropertyValue;
756 m_aPropertyChangeListeners.notifyEach( &XPropertyChangeListener::propertyChange, aTranslatedEvent );
761 void SAL_CALL ShapeGeometryChangeNotifier::disposing( const EventObject& /*_event*/ )
763 ::comphelper::ComponentMethodGuard aGuard( *this );
764 impl_dispose_nothrow();
768 void ShapeGeometryChangeNotifier::impl_init_nothrow()
770 osl_atomic_increment( &m_refCount );
773 Reference< XPropertySet > xShapeProperties( m_xShape, UNO_QUERY_THROW );
774 xShapeProperties->addPropertyChangeListener( OUString(), this );
776 catch( const Exception& )
778 DBG_UNHANDLED_EXCEPTION("extensions.propctrlr");
780 osl_atomic_decrement( &m_refCount );
784 void ShapeGeometryChangeNotifier::impl_dispose_nothrow()
788 Reference< XPropertySet > xShapeProperties( m_xShape, UNO_QUERY_THROW );
789 xShapeProperties->removePropertyChangeListener( OUString(), this );
791 catch( const Exception& )
793 DBG_UNHANDLED_EXCEPTION("extensions.propctrlr");
796 getBroadcastHelper().bDisposed = true;
800 } // namespace pcr
803 extern "C" void createRegistryInfo_FormGeometryHandler()
805 ::pcr::FormGeometryHandler::registerImplementation();
808 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */