LibreOffice Module extensions (master) 1
formgeometryhandler.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <sal/config.h>
21
22#include "propertyhandler.hxx"
23#include "formmetadata.hxx"
24#include "formstrings.hxx"
25#include "handlerhelper.hxx"
26#include "cellbindinghelper.hxx"
27
28#include <com/sun/star/inspection/XObjectInspectorUI.hpp>
29#include <com/sun/star/awt/XControlModel.hpp>
30#include <com/sun/star/drawing/XControlShape.hpp>
31#include <com/sun/star/container/XMap.hpp>
32#include <com/sun/star/inspection/XNumericControl.hpp>
33#include <com/sun/star/util/MeasureUnit.hpp>
34#include <com/sun/star/text/TextContentAnchorType.hpp>
35#include <com/sun/star/lang/NullPointerException.hpp>
36#include <com/sun/star/lang/XServiceInfo.hpp>
37#include <com/sun/star/sheet/XSpreadsheet.hpp>
38#include <com/sun/star/table/XColumnRowRange.hpp>
39#include <com/sun/star/container/XChild.hpp>
40#include <com/sun/star/form/XGridColumnFactory.hpp>
41
46#include <rtl/ref.hxx>
47#include <utility>
49
50namespace pcr
51{
52
53
54 using ::com::sun::star::uno::Reference;
55 using ::com::sun::star::uno::XInterface;
56 using ::com::sun::star::uno::UNO_QUERY;
57 using ::com::sun::star::uno::UNO_QUERY_THROW;
58 using ::com::sun::star::uno::UNO_SET_THROW;
59 using ::com::sun::star::uno::Exception;
60 using ::com::sun::star::uno::RuntimeException;
61 using ::com::sun::star::uno::Any;
62 using ::com::sun::star::uno::Sequence;
63 using ::com::sun::star::uno::XComponentContext;
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::container::XIndexAccess;
89 using ::com::sun::star::container::XChild;
90 using ::com::sun::star::form::XGridColumnFactory;
91
92 namespace MeasureUnit = css::util::MeasureUnit;
93
94 #define ANCHOR_TO_SHEET 0
95 #define ANCHOR_TO_CELL 1
96
97
98 //= BroadcastHelperBase
99
100 namespace {
101
102 class BroadcastHelperBase
103 {
104 protected:
105 explicit BroadcastHelperBase( ::osl::Mutex& _rMutex )
106 :maBHelper( _rMutex )
107 {
108 }
109
110 protected:
111 ::cppu::OBroadcastHelper& getBroadcastHelper() { return maBHelper; }
112
113 private:
114 ::cppu::OBroadcastHelper maBHelper;
115 };
116
117 }
118
119 //= ShapeGeometryChangeNotifier - declaration
120
125 typedef ::cppu::WeakImplHelper < css::beans::XPropertyChangeListener
127
128 namespace {
129
130 class ShapeGeometryChangeNotifier :public BroadcastHelperBase
133 {
134 public:
135 ShapeGeometryChangeNotifier( ::cppu::OWeakObject& _rParent, ::osl::Mutex& _rParentMutex, const Reference< XShape >& _shape )
136 :BroadcastHelperBase( _rParentMutex )
138 ,m_rParent( _rParent )
139 ,m_aPropertyChangeListeners( _rParentMutex )
140 ,m_xShape( _shape )
141 {
142 ENSURE_OR_THROW( m_xShape.is(), "illegal shape!" );
143 impl_init_nothrow();
144 }
145
146 // property change broadcasting
147 void addPropertyChangeListener( const Reference< XPropertyChangeListener >& _listener )
148 {
149 m_aPropertyChangeListeners.addInterface( _listener );
150 }
151 void removePropertyChangeListener( const Reference< XPropertyChangeListener >& _listener )
152 {
153 m_aPropertyChangeListeners.removeInterface( _listener );
154 }
155
156 // XComponent equivalent
157 void dispose()
158 {
159 ::osl::MutexGuard aGuard( getMutex() );
160 impl_dispose_nothrow();
161 }
162
163 // XInterface
164 virtual void SAL_CALL acquire( ) noexcept override
165 {
166 m_rParent.acquire();
167 }
168
169 virtual void SAL_CALL release( ) noexcept override
170 {
171 m_rParent.release();
172 }
173
174 // XPropertyChangeListener
175 virtual void SAL_CALL propertyChange( const PropertyChangeEvent& _event ) override;
176
177 // XEventListener
178 virtual void SAL_CALL disposing( const EventObject& _event ) override;
179
180 protected:
181 virtual ~ShapeGeometryChangeNotifier() override
182 {
183 if ( !getBroadcastHelper().bDisposed )
184 {
185 acquire();
186 dispose();
187 }
188 }
189
190 protected:
191 ::cppu::OBroadcastHelper& getBroadcastHelper() { return BroadcastHelperBase::getBroadcastHelper(); }
192
193 private:
194 void impl_init_nothrow();
195 void impl_dispose_nothrow();
196
197 private:
199 ::comphelper::OInterfaceContainerHelper2 m_aPropertyChangeListeners;
200 Reference< XShape > m_xShape;
201 };
202
203 }
204
205 //= FormGeometryHandler - declaration
206
207 namespace {
208
209 class FormGeometryHandler;
210
211 }
212
216 namespace {
217
218 class FormGeometryHandler : public PropertyHandlerComponent
219 {
220 public:
221 explicit FormGeometryHandler(
222 const Reference< XComponentContext >& _rxContext
223 );
224
225 protected:
226 virtual ~FormGeometryHandler() override;
227
228 protected:
229 // XServiceInfo
230 virtual OUString SAL_CALL getImplementationName() override;
231 virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames () override;
232
233 // XPropertyHandler overriables
234 virtual Any SAL_CALL getPropertyValue( const OUString& _rPropertyName ) override;
235 virtual void SAL_CALL setPropertyValue( const OUString& _rPropertyName, const Any& _rValue ) override;
236 virtual LineDescriptor SAL_CALL describePropertyLine( const OUString& _rPropertyName, const css::uno::Reference< css::inspection::XPropertyControlFactory >& _rxControlFactory ) override;
237 virtual void SAL_CALL addPropertyChangeListener( const css::uno::Reference< css::beans::XPropertyChangeListener >& _rxListener ) override;
238 virtual void SAL_CALL removePropertyChangeListener( const css::uno::Reference< css::beans::XPropertyChangeListener >& _rxListener ) override;
239 virtual Sequence< OUString > SAL_CALL getActuatingProperties( ) override;
240 virtual void SAL_CALL actuatingPropertyChanged( const OUString& _rActuatingPropertyName, const Any& _rNewValue, const Any& _rOldValue, const Reference< XObjectInspectorUI >& _rxInspectorUI, sal_Bool _bFirstTimeInit ) override;
241
242 // OComponentHandler overridables
243 virtual void SAL_CALL disposing() override;
244
245 // PropertyHandler overridables
246 virtual Sequence< Property > doDescribeSupportedProperties() const override;
247
248 protected:
249 virtual void onNewComponent() override;
250
251 private:
252 bool impl_haveTextAnchorType_nothrow() const;
253 bool impl_haveSheetAnchorType_nothrow() const;
254 void impl_setSheetAnchorType_nothrow( const sal_Int32 _nAnchorType ) const;
255
256 private:
257 Reference< XControlShape > m_xAssociatedShape;
258 Reference< XPropertySet > m_xShapeProperties;
260 };
261
262 }
263
264 //= FormGeometryHandler - implementation
265
266
267 FormGeometryHandler::FormGeometryHandler( const Reference< XComponentContext >& _rxContext )
268 :PropertyHandlerComponent( _rxContext )
269 {
270 }
271
272
273 FormGeometryHandler::~FormGeometryHandler( )
274 {
275 if ( !rBHelper.bDisposed )
276 {
277 acquire();
278 dispose();
279 }
280
281 }
282
283
284 void FormGeometryHandler::onNewComponent()
285 {
286 if ( m_xChangeNotifier.is() )
287 {
288 m_xChangeNotifier->dispose();
289 m_xChangeNotifier.clear();
290 }
291 m_xAssociatedShape.clear();
292 m_xShapeProperties.clear();
293
294 PropertyHandlerComponent::onNewComponent();
295
296 try
297 {
298 Reference< XControlModel > xControlModel( m_xComponent, UNO_QUERY );
299 if ( xControlModel.is() )
300 {
301 // do not ask the map for shapes for grid control columns...
302 Reference< XChild > xCompChild( m_xComponent, UNO_QUERY_THROW );
303 Reference< XGridColumnFactory > xCheckGrid( xCompChild->getParent(), UNO_QUERY );
304 if ( !xCheckGrid.is() )
305 {
306 Reference< XMap > xControlMap;
307 Any any = m_xContext->getValueByName( "ControlShapeAccess" );
308 any >>= xControlMap;
309 m_xAssociatedShape.set( xControlMap->get( Any( xControlModel ) ), UNO_QUERY_THROW );
310 m_xShapeProperties.set( m_xAssociatedShape, UNO_QUERY_THROW );
311 }
312 }
313 }
314 catch( const Exception& )
315 {
316 DBG_UNHANDLED_EXCEPTION("extensions.propctrlr");
317 }
318
319 if ( m_xAssociatedShape.is() )
320 m_xChangeNotifier = new ShapeGeometryChangeNotifier( *this, m_aMutex, m_xAssociatedShape );
321 }
322
323
324 OUString FormGeometryHandler::getImplementationName( )
325 {
326 return "com.sun.star.comp.extensions.FormGeometryHandler";
327 }
328
329
330 Sequence< OUString > FormGeometryHandler::getSupportedServiceNames( )
331 {
332 return { "com.sun.star.form.inspection.FormGeometryHandler" };
333 }
334
335
336 Any SAL_CALL FormGeometryHandler::getPropertyValue( const OUString& _rPropertyName )
337 {
338 ::osl::MutexGuard aGuard( m_aMutex );
339 PropertyId nPropId( impl_getPropertyId_throwUnknownProperty( _rPropertyName ) );
340
341 ENSURE_OR_THROW2( m_xAssociatedShape.is(), "internal error: properties, but no shape!", *this );
342 ENSURE_OR_THROW2( m_xShapeProperties.is(), "internal error: no shape properties!", *this );
343
344 Any aReturn;
345 try
346 {
347 switch ( nPropId )
348 {
350 aReturn <<= m_xAssociatedShape->getPosition().X;
351 break;
353 aReturn <<= m_xAssociatedShape->getPosition().Y;
354 break;
356 aReturn <<= m_xAssociatedShape->getSize().Width;
357 break;
359 aReturn <<= m_xAssociatedShape->getSize().Height;
360 break;
362 aReturn = m_xShapeProperties->getPropertyValue( PROPERTY_ANCHOR_TYPE );
363 OSL_ENSURE( aReturn.hasValue(), "FormGeometryHandler::getPropertyValue: illegal anchor type!" );
364 break;
366 {
367 Reference< XSpreadsheet > xAnchorSheet( m_xShapeProperties->getPropertyValue( PROPERTY_ANCHOR ), UNO_QUERY );
368 aReturn <<= sal_Int32( xAnchorSheet.is() ? ANCHOR_TO_SHEET : ANCHOR_TO_CELL );
369 }
370 break;
371
372 default:
373 OSL_FAIL( "FormGeometryHandler::getPropertyValue: huh?" );
374 break;
375 }
376 }
377 catch( const Exception& )
378 {
379 DBG_UNHANDLED_EXCEPTION("extensions.propctrlr");
380 }
381 return aReturn;
382 }
383
384
385 void SAL_CALL FormGeometryHandler::setPropertyValue( const OUString& _rPropertyName, const Any& _rValue )
386 {
387 ::osl::MutexGuard aGuard( m_aMutex );
388 PropertyId nPropId( impl_getPropertyId_throwUnknownProperty( _rPropertyName ) );
389
390 ENSURE_OR_THROW2( m_xAssociatedShape.is(), "internal error: properties, but no shape!", *this );
391 ENSURE_OR_THROW2( m_xShapeProperties.is(), "internal error: properties, but no shape!", *this );
392
393 try
394 {
395 switch ( nPropId )
396 {
399 {
400 sal_Int32 nPosition(0);
401 OSL_VERIFY( _rValue >>= nPosition );
402
403 css::awt::Point aPos( m_xAssociatedShape->getPosition() );
404 if ( nPropId == PROPERTY_ID_POSITIONX )
405 aPos.X = nPosition;
406 else
407 aPos.Y = nPosition;
408 m_xAssociatedShape->setPosition( aPos );
409 }
410 break;
411
414 {
415 sal_Int32 nSize(0);
416 OSL_VERIFY( _rValue >>= nSize );
417
418 css::awt::Size aSize( m_xAssociatedShape->getSize() );
419 if ( nPropId == PROPERTY_ID_WIDTH )
420 aSize.Width = nSize;
421 else
422 aSize.Height = nSize;
423 m_xAssociatedShape->setSize( aSize );
424 }
425 break;
426
428 m_xShapeProperties->setPropertyValue( PROPERTY_ANCHOR_TYPE, _rValue );
429 break;
430
432 {
433 sal_Int32 nSheetAnchorType = 0;
434 OSL_VERIFY( _rValue >>= nSheetAnchorType );
435 impl_setSheetAnchorType_nothrow( nSheetAnchorType );
436 }
437 break;
438
439 default:
440 OSL_FAIL( "FormGeometryHandler::getPropertyValue: huh?" );
441 break;
442 }
443 }
444 catch( const Exception& )
445 {
446 DBG_UNHANDLED_EXCEPTION("extensions.propctrlr");
447 }
448 }
449
450
451 LineDescriptor SAL_CALL FormGeometryHandler::describePropertyLine( const OUString& _rPropertyName,
452 const Reference< XPropertyControlFactory >& _rxControlFactory )
453 {
454 ::osl::MutexGuard aGuard( m_aMutex );
455 PropertyId nPropId( impl_getPropertyId_throwUnknownProperty( _rPropertyName ) );
456
457 LineDescriptor aLineDesc( PropertyHandler::describePropertyLine( _rPropertyName, _rxControlFactory ) );
458 try
459 {
460 bool bIsSize = false;
461 switch ( nPropId )
462 {
465 bIsSize = true;
466 [[fallthrough]];
469 {
470 Optional< double > aZero( true, 0 );
471 Optional< double > aValueNotPresent( false, 0 );
472 aLineDesc.Control = PropertyHandlerHelper::createNumericControl(
473 _rxControlFactory, 2, bIsSize ? aZero : aValueNotPresent, aValueNotPresent );
474
475 Reference< XNumericControl > xNumericControl( aLineDesc.Control, UNO_QUERY_THROW );
476 xNumericControl->setValueUnit( MeasureUnit::MM_100TH );
477 xNumericControl->setDisplayUnit( impl_getDocumentMeasurementUnit_throw() );
478 }
479 break;
480
483 // default handling from PropertyHandler is sufficient
484 break;
485
486 default:
487 OSL_FAIL( "FormGeometryHandler::describePropertyLine: huh?" );
488 break;
489 }
490 }
491 catch( const Exception& )
492 {
493 DBG_UNHANDLED_EXCEPTION("extensions.propctrlr");
494 }
495 return aLineDesc;
496 }
497
498
499 void SAL_CALL FormGeometryHandler::addPropertyChangeListener( const Reference< XPropertyChangeListener >& _listener )
500 {
501 ::osl::MutexGuard aGuard( m_aMutex );
502 OSL_PRECOND( m_xChangeNotifier.is(), "FormGeometryHandler::addPropertyChangeListener: no notified, implies no shape!?" );
503 if ( m_xChangeNotifier.is() )
504 m_xChangeNotifier->addPropertyChangeListener( _listener );
505 }
506
507
508 void SAL_CALL FormGeometryHandler::removePropertyChangeListener( const Reference< XPropertyChangeListener >& _listener )
509 {
510 ::osl::MutexGuard aGuard( m_aMutex );
511 OSL_PRECOND( m_xChangeNotifier.is(), "FormGeometryHandler::removePropertyChangeListener: no notified, implies no shape!?" );
512 if ( m_xChangeNotifier.is() )
513 m_xChangeNotifier->removePropertyChangeListener( _listener );
514 }
515
516
517 Sequence< OUString > SAL_CALL FormGeometryHandler::getActuatingProperties( )
518 {
519 Sequence< OUString > aInterestedIn { PROPERTY_TEXT_ANCHOR_TYPE };
520 return aInterestedIn;
521 }
522
523
524 void SAL_CALL FormGeometryHandler::actuatingPropertyChanged( const OUString& _rActuatingPropertyName, const Any& _rNewValue, const Any& /*_rOldValue*/, const Reference< XObjectInspectorUI >& _rxInspectorUI, sal_Bool /*_bFirstTimeInit*/ )
525 {
526 if ( !_rxInspectorUI.is() )
527 throw NullPointerException();
528
529 ::osl::MutexGuard aGuard( m_aMutex );
530 PropertyId nActuatingPropId( impl_getPropertyId_nothrow( _rActuatingPropertyName ) );
531
532 switch ( nActuatingPropId )
533 {
535 {
536 TextContentAnchorType eAnchorType( TextContentAnchorType_AT_PARAGRAPH );
537 OSL_VERIFY( _rNewValue >>= eAnchorType );
538 _rxInspectorUI->enablePropertyUI( PROPERTY_POSITIONX, eAnchorType != TextContentAnchorType_AS_CHARACTER );
539 }
540 break;
541 case -1:
542 throw RuntimeException();
543 break;
544 default:
545 OSL_FAIL( "FormGeometryHandler::actuatingPropertyChanged: not registered for this property!" );
546 break;
547 }
548 }
549
550
551 Sequence< Property > FormGeometryHandler::doDescribeSupportedProperties() const
552 {
553 if ( !m_xAssociatedShape.is() )
554 return Sequence< Property >();
555
556 std::vector< Property > aProperties;
557
558 addInt32PropertyDescription( aProperties, PROPERTY_POSITIONX );
559 addInt32PropertyDescription( aProperties, PROPERTY_POSITIONY );
560 addInt32PropertyDescription( aProperties, PROPERTY_WIDTH );
561 addInt32PropertyDescription( aProperties, PROPERTY_HEIGHT );
562
563 if ( impl_haveTextAnchorType_nothrow() )
564 implAddPropertyDescription( aProperties, PROPERTY_TEXT_ANCHOR_TYPE, ::cppu::UnoType< TextContentAnchorType >::get() );
565
566 if ( impl_haveSheetAnchorType_nothrow() )
567 addInt32PropertyDescription( aProperties, PROPERTY_SHEET_ANCHOR_TYPE );
568
569 return comphelper::containerToSequence(aProperties);
570 }
571
572
573 void SAL_CALL FormGeometryHandler::disposing()
574 {
575 PropertyHandlerComponent::disposing();
576
577 if ( m_xChangeNotifier.is() )
578 {
579 m_xChangeNotifier->dispose();
580 m_xChangeNotifier.clear();
581 }
582 }
583
584
585 bool FormGeometryHandler::impl_haveTextAnchorType_nothrow() const
586 {
587 ENSURE_OR_THROW( m_xShapeProperties.is(), "not to be called without shape properties" );
588 try
589 {
590 Reference< XPropertySetInfo > xPSI( m_xShapeProperties->getPropertySetInfo(), UNO_SET_THROW );
591 if ( xPSI->hasPropertyByName( PROPERTY_ANCHOR_TYPE ) )
592 return true;
593 }
594 catch( const Exception& )
595 {
596 DBG_UNHANDLED_EXCEPTION("extensions.propctrlr");
597 }
598 return false;
599 }
600
601
602 bool FormGeometryHandler::impl_haveSheetAnchorType_nothrow() const
603 {
604 ENSURE_OR_THROW( m_xShapeProperties.is(), "not to be called without shape properties" );
605 try
606 {
607 Reference< XPropertySetInfo > xPSI( m_xShapeProperties->getPropertySetInfo(), UNO_SET_THROW );
608 if ( !xPSI->hasPropertyByName( PROPERTY_ANCHOR ) )
609 return false;
610 Reference< XServiceInfo > xSI( m_xAssociatedShape, UNO_QUERY_THROW );
611 if ( xSI->supportsService("com.sun.star.sheet.Shape") )
612 return true;
613 }
614 catch( const Exception& )
615 {
616 DBG_UNHANDLED_EXCEPTION("extensions.propctrlr");
617 }
618 return false;
619 }
620
621
622 namespace
623 {
624 sal_Int32 lcl_getLowerBoundRowOrColumn( const Reference< XIndexAccess >& _rxRowsOrColumns, const bool _bRows,
625 const css::awt::Point& _rRelativePosition )
626 {
627 sal_Int32 nAccumulated = 0;
628
629 const sal_Int32& rRelativePos = _bRows ? _rRelativePosition.Y : _rRelativePosition.X;
630
631 sal_Int32 nElements = _rxRowsOrColumns->getCount();
632 sal_Int32 currentPos = 0;
633 for ( currentPos=0; currentPos<nElements; ++currentPos )
634 {
635 Reference< XPropertySet > xRowOrColumn( _rxRowsOrColumns->getByIndex( currentPos ), UNO_QUERY_THROW );
636
637 bool bIsVisible = true;
638 OSL_VERIFY( xRowOrColumn->getPropertyValue( PROPERTY_IS_VISIBLE ) >>= bIsVisible );
639 if ( !bIsVisible )
640 continue;
641
642 sal_Int32 nHeightOrWidth( 0 );
643 OSL_VERIFY( xRowOrColumn->getPropertyValue( _bRows ? OUString(PROPERTY_HEIGHT) : OUString(PROPERTY_WIDTH) ) >>= nHeightOrWidth );
644
645 if ( nAccumulated + nHeightOrWidth > rRelativePos )
646 break;
647
648 nAccumulated += nHeightOrWidth;
649 }
650
651 return currentPos;
652 }
653 }
654
655
656 void FormGeometryHandler::impl_setSheetAnchorType_nothrow( const sal_Int32 _nAnchorType ) const
657 {
658 ENSURE_OR_THROW( m_xShapeProperties.is(), "illegal to be called without shape properties." );
659 try
660 {
661 CellBindingHelper aHelper( m_xComponent, impl_getContextDocument_nothrow() );
662 // find the sheet which the control belongs to
663 Reference< XSpreadsheet > xSheet;
664 aHelper.getControlSheetIndex( xSheet );
665
666 switch ( _nAnchorType )
667 {
668 case ANCHOR_TO_SHEET:
669 OSL_ENSURE( xSheet.is(),
670 "FormGeometryHandler::impl_setSheetAnchorType_nothrow: sheet not found!" );
671 if ( xSheet.is() )
672 {
673 css::awt::Point aPreservePosition( m_xAssociatedShape->getPosition() );
674 m_xShapeProperties->setPropertyValue( PROPERTY_ANCHOR, Any( xSheet ) );
675 m_xAssociatedShape->setPosition( aPreservePosition );
676 }
677 break;
678
679 case ANCHOR_TO_CELL:
680 {
681 Reference< XColumnRowRange > xColsRows( xSheet, UNO_QUERY_THROW );
682
683 // get the current anchor
684 Reference< XSpreadsheet > xCurrentAnchor;
685 OSL_VERIFY( m_xShapeProperties->getPropertyValue( PROPERTY_ANCHOR ) >>= xCurrentAnchor );
686 OSL_ENSURE( xCurrentAnchor.is(), "FormGeometryHandler::impl_setSheetAnchorType_nothrow: only to be called when currently anchored to a sheet!" );
687
688 // get the current position
689 css::awt::Point aRelativePosition( m_xAssociatedShape->getPosition() );
690
691 Reference< XTableColumns > xCols( xColsRows->getColumns(), UNO_SET_THROW );
692 sal_Int32 nNewAnchorCol = lcl_getLowerBoundRowOrColumn( xCols, false, aRelativePosition );
693
694 Reference< XTableRows > xRows( xColsRows->getRows(), UNO_SET_THROW );
695 sal_Int32 nNewAnchorRow = lcl_getLowerBoundRowOrColumn( xRows, true, aRelativePosition );
696
697 Any aNewAnchorCell( xSheet->getCellByPosition( nNewAnchorCol, nNewAnchorRow ) );
698 m_xShapeProperties->setPropertyValue( PROPERTY_ANCHOR, aNewAnchorCell );
699 }
700 break;
701
702 default:
703 OSL_FAIL( "FormGeometryHandler::impl_setSheetAnchorType_nothrow: illegal anchor type!" );
704 break;
705 }
706 }
707 catch( const Exception& )
708 {
709 DBG_UNHANDLED_EXCEPTION("extensions.propctrlr");
710 }
711 }
712
713
714 //= ShapeGeometryChangeNotifier - implementation
715
716 namespace
717 {
718 struct EventTranslation
719 {
720 OUString sPropertyName;
721 Any aNewPropertyValue;
722
723 EventTranslation( OUString _propertyName, Any _newPropertyValue )
724 :sPropertyName(std::move( _propertyName ))
725 ,aNewPropertyValue(std::move( _newPropertyValue ))
726 {
727 }
728 };
729 }
730
731
732 void SAL_CALL ShapeGeometryChangeNotifier::propertyChange( const PropertyChangeEvent& _event )
733 {
735
736 std::vector< EventTranslation > aEventTranslations;
737 aEventTranslations.reserve(2);
738
739 if ( _event.PropertyName == "Position" )
740 {
741 css::awt::Point aPos = m_xShape->getPosition();
742 aEventTranslations.push_back( EventTranslation( PROPERTY_POSITIONX, Any( aPos.X ) ) );
743 aEventTranslations.push_back( EventTranslation( PROPERTY_POSITIONY, Any( aPos.Y ) ) );
744 }
745 else if ( _event.PropertyName == "Size" )
746 {
747 css::awt::Size aSize = m_xShape->getSize();
748 aEventTranslations.push_back( EventTranslation( PROPERTY_WIDTH, Any( aSize.Width ) ) );
749 aEventTranslations.push_back( EventTranslation( PROPERTY_HEIGHT, Any( aSize.Height ) ) );
750 }
751 else if ( _event.PropertyName == PROPERTY_ANCHOR_TYPE )
752 {
753 aEventTranslations.push_back( EventTranslation( PROPERTY_TEXT_ANCHOR_TYPE, _event.NewValue ) );
754 }
755 else if ( _event.PropertyName == PROPERTY_ANCHOR )
756 {
757 aEventTranslations.push_back( EventTranslation( PROPERTY_SHEET_ANCHOR_TYPE, _event.NewValue ) );
758 }
759
760 PropertyChangeEvent aTranslatedEvent( _event );
761 aTranslatedEvent.Source = m_rParent;
762
763 aGuard.clear();
764 for (auto const& eventTranslation : aEventTranslations)
765 {
766 aTranslatedEvent.PropertyName = eventTranslation.sPropertyName;
767 aTranslatedEvent.NewValue = eventTranslation.aNewPropertyValue;
768 m_aPropertyChangeListeners.notifyEach( &XPropertyChangeListener::propertyChange, aTranslatedEvent );
769 }
770 }
771
772
773 void SAL_CALL ShapeGeometryChangeNotifier::disposing( const EventObject& /*_event*/ )
774 {
776 impl_dispose_nothrow();
777 }
778
779
780 void ShapeGeometryChangeNotifier::impl_init_nothrow()
781 {
782 osl_atomic_increment( &m_refCount );
783 try
784 {
785 Reference< XPropertySet > xShapeProperties( m_xShape, UNO_QUERY_THROW );
786 xShapeProperties->addPropertyChangeListener( OUString(), this );
787 }
788 catch( const Exception& )
789 {
790 DBG_UNHANDLED_EXCEPTION("extensions.propctrlr");
791 }
792 osl_atomic_decrement( &m_refCount );
793 }
794
795
796 void ShapeGeometryChangeNotifier::impl_dispose_nothrow()
797 {
798 try
799 {
800 Reference< XPropertySet > xShapeProperties( m_xShape, UNO_QUERY_THROW );
801 xShapeProperties->removePropertyChangeListener( OUString(), this );
802 }
803 catch( const Exception& )
804 {
805 DBG_UNHANDLED_EXCEPTION("extensions.propctrlr");
806 }
807
808 getBroadcastHelper().bDisposed = true;
809 }
810
811
812} // namespace pcr
813
814extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
816 css::uno::XComponentContext* context , css::uno::Sequence<css::uno::Any> const&)
817{
818 return cppu::acquire(new pcr::FormGeometryHandler(context));
819}
820
821/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
PropertiesInfo aProperties
XSLTFilter & m_rParent
const Any & any
sal_Int32 nElements
#define ENSURE_OR_THROW(c, m)
#define DBG_UNHANDLED_EXCEPTION(...)
#define ENSURE_OR_THROW2(c, m, ifc)
Any aHelper
Reference< XComponentContext > m_xContext
Definition: filehandler.cxx:78
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * extensions_propctrlr_FormGeometryHandler_get_implementation(css::uno::XComponentContext *context, css::uno::Sequence< css::uno::Any > const &)
#define ANCHOR_TO_SHEET
#define ANCHOR_TO_CELL
#define PROPERTY_ID_TEXT_ANCHOR_TYPE
#define PROPERTY_ID_POSITIONX
#define PROPERTY_ID_POSITIONY
#define PROPERTY_ID_WIDTH
#define PROPERTY_ID_HEIGHT
#define PROPERTY_ID_SHEET_ANCHOR_TYPE
constexpr OUStringLiteral PROPERTY_IS_VISIBLE
constexpr OUStringLiteral PROPERTY_HEIGHT
constexpr OUStringLiteral PROPERTY_POSITIONX
constexpr OUStringLiteral PROPERTY_POSITIONY
constexpr OUStringLiteral PROPERTY_ANCHOR
constexpr OUStringLiteral PROPERTY_WIDTH
Definition: formstrings.hxx:48
constexpr OUStringLiteral PROPERTY_TEXT_ANCHOR_TYPE
constexpr OUStringLiteral PROPERTY_ANCHOR_TYPE
constexpr OUStringLiteral PROPERTY_SHEET_ANCHOR_TYPE
::osl::Mutex m_aMutex
Definition: logger.cxx:98
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
css::uno::Sequence< OUString > getSupportedServiceNames()
OUString getImplementationName()
::osl::Mutex & getMutex()
VBAHELPER_DLLPUBLIC bool setPropertyValue(css::uno::Sequence< css::beans::PropertyValue > &aProp, const OUString &aName, const css::uno::Any &aValue)
a property handler for any virtual string properties
Definition: browserline.cxx:39
::comphelper::ComponentBase ShapeGeometryChangeNotifier_CBase
helper class to work around the ...unfortunate implementation of property change broadcasts in the XS...
::cppu::WeakImplHelper< css::beans::XPropertyChangeListener > ShapeGeometryChangeNotifier_IBase
bool getPropertyValue(ValueType &rValue, css::uno::Reference< css::beans::XPropertySet > const &xPropSet, OUString const &propName)
void dispose()
const XMLEventNameTranslation aEventTranslations[]
PropertyId
unsigned char sal_Bool