Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 : : *
5 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
6 : : *
7 : : * OpenOffice.org - a multi-platform office productivity suite
8 : : *
9 : : * This file is part of OpenOffice.org.
10 : : *
11 : : * OpenOffice.org is free software: you can redistribute it and/or modify
12 : : * it under the terms of the GNU Lesser General Public License version 3
13 : : * only, as published by the Free Software Foundation.
14 : : *
15 : : * OpenOffice.org is distributed in the hope that it will be useful,
16 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 : : * GNU Lesser General Public License version 3 for more details
19 : : * (a copy is included in the LICENSE file that accompanied this code).
20 : : *
21 : : * You should have received a copy of the GNU Lesser General Public License
22 : : * version 3 along with OpenOffice.org. If not, see
23 : : * <http://www.openoffice.org/license.html>
24 : : * for a copy of the LGPLv3 License.
25 : : *
26 : : ************************************************************************/
27 : :
28 : :
29 : : #include "propertyhandler.hxx"
30 : : #include "formmetadata.hxx"
31 : : #include "formstrings.hxx"
32 : : #include "handlerhelper.hxx"
33 : : #include "cellbindinghelper.hxx"
34 : :
35 : : #include <com/sun/star/inspection/XObjectInspectorUI.hpp>
36 : : #include <com/sun/star/awt/XControlModel.hpp>
37 : : #include <com/sun/star/drawing/XControlShape.hpp>
38 : : #include <com/sun/star/container/XMap.hpp>
39 : : #include <com/sun/star/inspection/XNumericControl.hpp>
40 : : #include <com/sun/star/util/MeasureUnit.hpp>
41 : : #include <com/sun/star/text/TextContentAnchorType.hpp>
42 : : #include <com/sun/star/lang/XServiceInfo.hpp>
43 : : #include <com/sun/star/sheet/XSpreadsheet.hpp>
44 : : #include <com/sun/star/table/XColumnRowRange.hpp>
45 : : #include <com/sun/star/table/XCellRange.hpp>
46 : : #include <com/sun/star/container/XChild.hpp>
47 : : #include <com/sun/star/form/XGridColumnFactory.hpp>
48 : :
49 : : #include <cppuhelper/interfacecontainer.hxx>
50 : : #include <comphelper/componentbase.hxx>
51 : : #include <tools/debug.hxx>
52 : : #include <tools/diagnose_ex.h>
53 : :
54 : : //........................................................................
55 : : namespace pcr
56 : : {
57 : : //........................................................................
58 : :
59 : : /** === begin UNO using === **/
60 : : using ::com::sun::star::uno::Reference;
61 : : using ::com::sun::star::uno::XInterface;
62 : : using ::com::sun::star::uno::UNO_QUERY;
63 : : using ::com::sun::star::uno::UNO_QUERY_THROW;
64 : : using ::com::sun::star::uno::UNO_SET_THROW;
65 : : using ::com::sun::star::uno::Exception;
66 : : using ::com::sun::star::uno::RuntimeException;
67 : : using ::com::sun::star::uno::Any;
68 : : using ::com::sun::star::uno::makeAny;
69 : : using ::com::sun::star::uno::Sequence;
70 : : using ::com::sun::star::uno::Type;
71 : : using ::com::sun::star::uno::XComponentContext;
72 : : using ::com::sun::star::beans::UnknownPropertyException;
73 : : using ::com::sun::star::beans::Property;
74 : : using ::com::sun::star::awt::XControlModel;
75 : : using ::com::sun::star::drawing::XControlShape;
76 : : using ::com::sun::star::container::XMap;
77 : : using ::com::sun::star::inspection::LineDescriptor;
78 : : using ::com::sun::star::inspection::XPropertyControlFactory;
79 : : using ::com::sun::star::lang::NullPointerException;
80 : : using ::com::sun::star::beans::Optional;
81 : : using ::com::sun::star::inspection::XNumericControl;
82 : : using ::com::sun::star::drawing::XShape;
83 : : using ::com::sun::star::beans::PropertyChangeEvent;
84 : : using ::com::sun::star::lang::EventObject;
85 : : using ::com::sun::star::beans::XPropertySet;
86 : : using ::com::sun::star::beans::XPropertyChangeListener;
87 : : using ::com::sun::star::text::TextContentAnchorType;
88 : : using ::com::sun::star::text::TextContentAnchorType_AT_PARAGRAPH;
89 : : using ::com::sun::star::text::TextContentAnchorType_AS_CHARACTER;
90 : : using ::com::sun::star::beans::XPropertySetInfo;
91 : : using ::com::sun::star::inspection::XObjectInspectorUI;
92 : : using ::com::sun::star::lang::XServiceInfo;
93 : : using ::com::sun::star::sheet::XSpreadsheet;
94 : : using ::com::sun::star::table::XColumnRowRange;
95 : : using ::com::sun::star::table::XTableColumns;
96 : : using ::com::sun::star::table::XTableRows;
97 : : using ::com::sun::star::table::XCellRange;
98 : : using ::com::sun::star::container::XIndexAccess;
99 : : using ::com::sun::star::container::XChild;
100 : : using ::com::sun::star::form::XGridColumnFactory;
101 : : /** === end UNO using === **/
102 : : namespace MeasureUnit = ::com::sun::star::util::MeasureUnit;
103 : :
104 : : typedef ::com::sun::star::awt::Point AwtPoint;
105 : : typedef ::com::sun::star::awt::Size AwtSize;
106 : :
107 : : #define ANCHOR_TO_SHEET 0
108 : : #define ANCHOR_TO_CELL 1
109 : :
110 : : //====================================================================
111 : : //= BroadcastHelperBase
112 : : //====================================================================
113 : 0 : class BroadcastHelperBase
114 : : {
115 : : protected:
116 : 0 : BroadcastHelperBase( ::osl::Mutex& _rMutex )
117 : 0 : :maBHelper( _rMutex )
118 : : {
119 : 0 : }
120 : :
121 : : protected:
122 : 0 : ::cppu::OBroadcastHelper& getBroadcastHelper() { return maBHelper; }
123 : :
124 : : private:
125 : : ::cppu::OBroadcastHelper maBHelper;
126 : : };
127 : :
128 : : //====================================================================
129 : : //= ShapeGeometryChangeNotifier - declaration
130 : : //====================================================================
131 : : /** helper class to work around the ...unfortunate implementation of property change broadcasts
132 : : in the XShape implementation, which broadcasts way too generous and unspecified
133 : : */
134 : : typedef ::comphelper::ComponentBase ShapeGeometryChangeNotifier_CBase;
135 : : typedef ::cppu::WeakImplHelper1 < ::com::sun::star::beans::XPropertyChangeListener
136 : : > ShapeGeometryChangeNotifier_IBase;
137 : :
138 : : class ShapeGeometryChangeNotifier :public BroadcastHelperBase
139 : : ,public ShapeGeometryChangeNotifier_CBase
140 : : ,public ShapeGeometryChangeNotifier_IBase
141 : : {
142 : : public:
143 : 0 : ShapeGeometryChangeNotifier( ::cppu::OWeakObject& _rParent, ::osl::Mutex& _rParentMutex, const Reference< XShape >& _shape )
144 : : :BroadcastHelperBase( _rParentMutex )
145 : 0 : ,ShapeGeometryChangeNotifier_CBase( BroadcastHelperBase::getBroadcastHelper(), ::comphelper::ComponentBase::NoInitializationNeeded() )
146 : : ,ShapeGeometryChangeNotifier_IBase()
147 : : ,m_rParent( _rParent )
148 : : ,m_aPropertyChangeListeners( _rParentMutex )
149 : 0 : ,m_xShape( _shape )
150 : : {
151 : 0 : ENSURE_OR_THROW( m_xShape.is(), "illegal shape!" );
152 : 0 : impl_init_nothrow();
153 : 0 : }
154 : :
155 : : // property change broadcasting
156 : 0 : void addPropertyChangeListener( const Reference< XPropertyChangeListener >& _listener )
157 : : {
158 : 0 : m_aPropertyChangeListeners.addInterface( _listener );
159 : 0 : }
160 : 0 : void removePropertyChangeListener( const Reference< XPropertyChangeListener >& _listener )
161 : : {
162 : 0 : m_aPropertyChangeListeners.removeInterface( _listener );
163 : 0 : }
164 : :
165 : : // XComponent equivalent
166 : 0 : void dispose()
167 : : {
168 : 0 : ::osl::MutexGuard aGuard( getMutex() );
169 : 0 : impl_dispose_nothrow();
170 : 0 : }
171 : :
172 : : // XInterface
173 : 0 : virtual void SAL_CALL acquire( ) throw ()
174 : : {
175 : 0 : m_rParent.acquire();
176 : 0 : }
177 : :
178 : 0 : virtual void SAL_CALL release( ) throw ()
179 : : {
180 : 0 : m_rParent.release();
181 : 0 : }
182 : :
183 : : // XPropertyChangeListener
184 : : virtual void SAL_CALL propertyChange( const PropertyChangeEvent& _event ) throw (RuntimeException);
185 : :
186 : : // XEventListener
187 : : virtual void SAL_CALL disposing( const EventObject& _event ) throw (RuntimeException);
188 : :
189 : : protected:
190 : 0 : virtual ~ShapeGeometryChangeNotifier()
191 : 0 : {
192 : 0 : if ( !getBroadcastHelper().bDisposed )
193 : : {
194 : 0 : acquire();
195 : 0 : dispose();
196 : : }
197 : 0 : }
198 : :
199 : : protected:
200 : 0 : ::cppu::OBroadcastHelper& getBroadcastHelper() { return BroadcastHelperBase::getBroadcastHelper(); }
201 : :
202 : : private:
203 : : void impl_init_nothrow();
204 : : void impl_dispose_nothrow();
205 : :
206 : : private:
207 : : ::cppu::OWeakObject& m_rParent;
208 : : ::cppu::OInterfaceContainerHelper m_aPropertyChangeListeners;
209 : : Reference< XShape > m_xShape;
210 : : };
211 : :
212 : : //====================================================================
213 : : //= FormGeometryHandler - declaration
214 : : //====================================================================
215 : : class FormGeometryHandler;
216 : : typedef HandlerComponentBase< FormGeometryHandler > FormGeometryHandler_Base;
217 : : /** a property handler for any virtual string properties
218 : : */
219 : : class FormGeometryHandler : public FormGeometryHandler_Base
220 : : {
221 : : public:
222 : : FormGeometryHandler(
223 : : const Reference< XComponentContext >& _rxContext
224 : : );
225 : :
226 : : static ::rtl::OUString SAL_CALL getImplementationName_static( ) throw (RuntimeException);
227 : : static Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames_static( ) throw (RuntimeException);
228 : :
229 : : protected:
230 : : ~FormGeometryHandler();
231 : :
232 : : protected:
233 : : // XPropertyHandler overriables
234 : : virtual Any SAL_CALL getPropertyValue( const ::rtl::OUString& _rPropertyName ) throw (UnknownPropertyException, RuntimeException);
235 : : virtual void SAL_CALL setPropertyValue( const ::rtl::OUString& _rPropertyName, const Any& _rValue ) throw (UnknownPropertyException, RuntimeException);
236 : : 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);
237 : : virtual void SAL_CALL addPropertyChangeListener( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& _rxListener ) throw (::com::sun::star::uno::RuntimeException);
238 : : virtual void SAL_CALL removePropertyChangeListener( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& _rxListener ) throw (::com::sun::star::uno::RuntimeException);
239 : : virtual Sequence< ::rtl::OUString > SAL_CALL getActuatingProperties( ) throw (RuntimeException);
240 : : 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);
241 : :
242 : : // OComponentHandler overridables
243 : : virtual void SAL_CALL disposing();
244 : :
245 : : // PropertyHandler overridables
246 : : virtual Sequence< Property > SAL_CALL doDescribeSupportedProperties() const;
247 : :
248 : : protected:
249 : : virtual void onNewComponent();
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;
259 : : ::rtl::Reference< ShapeGeometryChangeNotifier > m_xChangeNotifier;
260 : : };
261 : :
262 : : //====================================================================
263 : : //= FormGeometryHandler - implementation
264 : : //====================================================================
265 : : DBG_NAME( FormGeometryHandler )
266 : : //--------------------------------------------------------------------
267 : 0 : FormGeometryHandler::FormGeometryHandler( const Reference< XComponentContext >& _rxContext )
268 : 0 : :FormGeometryHandler_Base( _rxContext )
269 : : {
270 : : DBG_CTOR( FormGeometryHandler, NULL );
271 : 0 : }
272 : :
273 : : //--------------------------------------------------------------------
274 : 0 : FormGeometryHandler::~FormGeometryHandler( )
275 : : {
276 : 0 : if ( !rBHelper.bDisposed )
277 : : {
278 : 0 : acquire();
279 : 0 : dispose();
280 : : }
281 : :
282 : : DBG_DTOR( FormGeometryHandler, NULL );
283 : 0 : }
284 : :
285 : : //--------------------------------------------------------------------
286 : 0 : void FormGeometryHandler::onNewComponent()
287 : : {
288 : 0 : if ( m_xChangeNotifier.is() )
289 : : {
290 : 0 : m_xChangeNotifier->dispose();
291 : 0 : m_xChangeNotifier.clear();
292 : : }
293 : 0 : m_xAssociatedShape.clear();
294 : 0 : m_xShapeProperties.clear();
295 : :
296 : 0 : FormGeometryHandler_Base::onNewComponent();
297 : :
298 : : try
299 : : {
300 : 0 : Reference< XControlModel > xControlModel( m_xComponent, UNO_QUERY );
301 : 0 : if ( xControlModel.is() )
302 : : {
303 : : // do not ask the map for shapes for grid control columns ....
304 : 0 : Reference< XChild > xCompChild( m_xComponent, UNO_QUERY_THROW );
305 : 0 : Reference< XGridColumnFactory > xCheckGrid( xCompChild->getParent(), UNO_QUERY );
306 : 0 : if ( !xCheckGrid.is() )
307 : : {
308 : 0 : Reference< XMap > xControlMap( m_aContext.getContextValueByAsciiName( "ControlShapeAccess" ), UNO_QUERY_THROW );
309 : 0 : m_xAssociatedShape.set( xControlMap->get( makeAny( xControlModel ) ), UNO_QUERY_THROW );
310 : 0 : m_xShapeProperties.set( m_xAssociatedShape, UNO_QUERY_THROW );
311 : 0 : }
312 : 0 : }
313 : : }
314 : 0 : catch( const Exception& )
315 : : {
316 : : DBG_UNHANDLED_EXCEPTION();
317 : : }
318 : :
319 : 0 : if ( m_xAssociatedShape.is() )
320 : 0 : m_xChangeNotifier = new ShapeGeometryChangeNotifier( *this, m_aMutex, m_xAssociatedShape.get() );
321 : 0 : }
322 : :
323 : : //--------------------------------------------------------------------
324 : 0 : ::rtl::OUString SAL_CALL FormGeometryHandler::getImplementationName_static( ) throw (RuntimeException)
325 : : {
326 : 0 : return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.extensions.FormGeometryHandler" ) );
327 : : }
328 : :
329 : : //--------------------------------------------------------------------
330 : 0 : Sequence< ::rtl::OUString > SAL_CALL FormGeometryHandler::getSupportedServiceNames_static( ) throw (RuntimeException)
331 : : {
332 : 0 : Sequence< ::rtl::OUString > aSupported( 1 );
333 : 0 : aSupported[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.form.inspection.FormGeometryHandler" ) );
334 : 0 : return aSupported;
335 : : }
336 : :
337 : : //--------------------------------------------------------------------
338 : 0 : Any SAL_CALL FormGeometryHandler::getPropertyValue( const ::rtl::OUString& _rPropertyName ) throw (UnknownPropertyException, RuntimeException)
339 : : {
340 : 0 : ::osl::MutexGuard aGuard( m_aMutex );
341 : 0 : PropertyId nPropId( impl_getPropertyId_throw( _rPropertyName ) );
342 : :
343 : 0 : ENSURE_OR_THROW2( m_xAssociatedShape.is(), "internal error: properties, but no shape!", *this );
344 : 0 : ENSURE_OR_THROW2( m_xShapeProperties.is(), "internal error: no shape properties!", *this );
345 : :
346 : 0 : Any aReturn;
347 : : try
348 : : {
349 : 0 : switch ( nPropId )
350 : : {
351 : : case PROPERTY_ID_POSITIONX:
352 : 0 : aReturn <<= m_xAssociatedShape->getPosition().X;
353 : 0 : break;
354 : : case PROPERTY_ID_POSITIONY:
355 : 0 : aReturn <<= m_xAssociatedShape->getPosition().Y;
356 : 0 : break;
357 : : case PROPERTY_ID_WIDTH:
358 : 0 : aReturn <<= m_xAssociatedShape->getSize().Width;
359 : 0 : break;
360 : : case PROPERTY_ID_HEIGHT:
361 : 0 : aReturn <<= m_xAssociatedShape->getSize().Height;
362 : 0 : break;
363 : : case PROPERTY_ID_TEXT_ANCHOR_TYPE:
364 : 0 : aReturn = m_xShapeProperties->getPropertyValue( PROPERTY_ANCHOR_TYPE );
365 : : OSL_ENSURE( aReturn.hasValue(), "FormGeometryHandler::getPropertyValue: illegal anchor type!" );
366 : 0 : break;
367 : : case PROPERTY_ID_SHEET_ANCHOR_TYPE:
368 : : {
369 : 0 : Reference< XSpreadsheet > xAnchorSheet( m_xShapeProperties->getPropertyValue( PROPERTY_ANCHOR ), UNO_QUERY );
370 : 0 : aReturn <<= sal_Int32( xAnchorSheet.is() ? ANCHOR_TO_SHEET : ANCHOR_TO_CELL );
371 : : }
372 : 0 : break;
373 : :
374 : : default:
375 : : OSL_FAIL( "FormGeometryHandler::getPropertyValue: huh?" );
376 : 0 : break;
377 : : }
378 : : }
379 : 0 : catch( const Exception& )
380 : : {
381 : : DBG_UNHANDLED_EXCEPTION();
382 : : }
383 : 0 : return aReturn;
384 : : }
385 : :
386 : : //--------------------------------------------------------------------
387 : 0 : void SAL_CALL FormGeometryHandler::setPropertyValue( const ::rtl::OUString& _rPropertyName, const Any& _rValue ) throw (UnknownPropertyException, RuntimeException)
388 : : {
389 : 0 : ::osl::MutexGuard aGuard( m_aMutex );
390 : 0 : PropertyId nPropId( impl_getPropertyId_throw( _rPropertyName ) );
391 : :
392 : 0 : ENSURE_OR_THROW2( m_xAssociatedShape.is(), "internal error: properties, but no shape!", *this );
393 : 0 : ENSURE_OR_THROW2( m_xShapeProperties.is(), "internal error: properties, but no shape!", *this );
394 : :
395 : : try
396 : : {
397 : 0 : switch ( nPropId )
398 : : {
399 : : case PROPERTY_ID_POSITIONX:
400 : : case PROPERTY_ID_POSITIONY:
401 : : {
402 : 0 : sal_Int32 nPosition(0);
403 : 0 : OSL_VERIFY( _rValue >>= nPosition );
404 : :
405 : 0 : AwtPoint aPos( m_xAssociatedShape->getPosition() );
406 : 0 : if ( nPropId == PROPERTY_ID_POSITIONX )
407 : 0 : aPos.X = nPosition;
408 : : else
409 : 0 : aPos.Y = nPosition;
410 : 0 : m_xAssociatedShape->setPosition( aPos );
411 : : }
412 : 0 : break;
413 : :
414 : : case PROPERTY_ID_WIDTH:
415 : : case PROPERTY_ID_HEIGHT:
416 : : {
417 : 0 : sal_Int32 nSize(0);
418 : 0 : OSL_VERIFY( _rValue >>= nSize );
419 : :
420 : 0 : AwtSize aSize( m_xAssociatedShape->getSize() );
421 : 0 : if ( nPropId == PROPERTY_ID_WIDTH )
422 : 0 : aSize.Width = nSize;
423 : : else
424 : 0 : aSize.Height = nSize;
425 : 0 : m_xAssociatedShape->setSize( aSize );
426 : : }
427 : 0 : break;
428 : :
429 : : case PROPERTY_ID_TEXT_ANCHOR_TYPE:
430 : 0 : m_xShapeProperties->setPropertyValue( PROPERTY_ANCHOR_TYPE, _rValue );
431 : 0 : break;
432 : :
433 : : case PROPERTY_ID_SHEET_ANCHOR_TYPE:
434 : : {
435 : 0 : sal_Int32 nSheetAnchorType = 0;
436 : 0 : OSL_VERIFY( _rValue >>= nSheetAnchorType );
437 : 0 : impl_setSheetAnchorType_nothrow( nSheetAnchorType );
438 : : }
439 : 0 : break;
440 : :
441 : : default:
442 : : OSL_FAIL( "FormGeometryHandler::getPropertyValue: huh?" );
443 : 0 : break;
444 : : }
445 : : }
446 : 0 : catch( const Exception& )
447 : : {
448 : : DBG_UNHANDLED_EXCEPTION();
449 : 0 : }
450 : 0 : }
451 : :
452 : : //--------------------------------------------------------------------
453 : 0 : LineDescriptor SAL_CALL FormGeometryHandler::describePropertyLine( const ::rtl::OUString& _rPropertyName,
454 : : const Reference< XPropertyControlFactory >& _rxControlFactory )
455 : : throw (UnknownPropertyException, NullPointerException, RuntimeException)
456 : : {
457 : 0 : ::osl::MutexGuard aGuard( m_aMutex );
458 : 0 : PropertyId nPropId( impl_getPropertyId_throw( _rPropertyName ) );
459 : :
460 : 0 : LineDescriptor aLineDesc( PropertyHandler::describePropertyLine( _rPropertyName, _rxControlFactory ) );
461 : : try
462 : : {
463 : 0 : bool bIsSize = false;
464 : 0 : switch ( nPropId )
465 : : {
466 : : case PROPERTY_ID_WIDTH:
467 : : case PROPERTY_ID_HEIGHT:
468 : 0 : bIsSize = true;
469 : : // NO break!
470 : : case PROPERTY_ID_POSITIONX:
471 : : case PROPERTY_ID_POSITIONY:
472 : : {
473 : 0 : Optional< double > aZero( sal_True, 0 );
474 : 0 : Optional< double > aValueNotPresent( sal_False, 0 );
475 : : aLineDesc.Control = PropertyHandlerHelper::createNumericControl(
476 : 0 : _rxControlFactory, 2, bIsSize ? aZero : aValueNotPresent, aValueNotPresent, sal_False );
477 : :
478 : 0 : Reference< XNumericControl > xNumericControl( aLineDesc.Control, UNO_QUERY_THROW );
479 : 0 : xNumericControl->setValueUnit( MeasureUnit::MM_100TH );
480 : 0 : xNumericControl->setDisplayUnit( impl_getDocumentMeasurementUnit_throw() );
481 : : }
482 : 0 : break;
483 : :
484 : : case PROPERTY_ID_TEXT_ANCHOR_TYPE:
485 : : case PROPERTY_ID_SHEET_ANCHOR_TYPE:
486 : : // default handling from PropertyHandler is sufficient
487 : 0 : break;
488 : :
489 : : default:
490 : : OSL_FAIL( "FormGeometryHandler::describePropertyLine: huh?" );
491 : 0 : break;
492 : : }
493 : : }
494 : 0 : catch( const Exception& )
495 : : {
496 : : DBG_UNHANDLED_EXCEPTION();
497 : : }
498 : 0 : return aLineDesc;
499 : : }
500 : :
501 : : //--------------------------------------------------------------------
502 : 0 : void SAL_CALL FormGeometryHandler::addPropertyChangeListener( const Reference< XPropertyChangeListener >& _listener ) throw (RuntimeException)
503 : : {
504 : 0 : ::osl::MutexGuard aGuard( m_aMutex );
505 : : OSL_PRECOND( m_xChangeNotifier.is(), "FormGeometryHandler::addPropertyChangeListener: no notified, implies no shape!?" );
506 : 0 : if ( m_xChangeNotifier.is() )
507 : 0 : m_xChangeNotifier->addPropertyChangeListener( _listener );
508 : 0 : }
509 : :
510 : : //--------------------------------------------------------------------
511 : 0 : void SAL_CALL FormGeometryHandler::removePropertyChangeListener( const Reference< XPropertyChangeListener >& _listener ) throw (RuntimeException)
512 : : {
513 : 0 : ::osl::MutexGuard aGuard( m_aMutex );
514 : : OSL_PRECOND( m_xChangeNotifier.is(), "FormGeometryHandler::removePropertyChangeListener: no notified, implies no shape!?" );
515 : 0 : if ( m_xChangeNotifier.is() )
516 : 0 : m_xChangeNotifier->removePropertyChangeListener( _listener );
517 : 0 : }
518 : :
519 : : //--------------------------------------------------------------------
520 : 0 : Sequence< ::rtl::OUString > SAL_CALL FormGeometryHandler::getActuatingProperties( ) throw (RuntimeException)
521 : : {
522 : 0 : Sequence< ::rtl::OUString > aInterestedIn(1);
523 : 0 : aInterestedIn[0] = PROPERTY_TEXT_ANCHOR_TYPE;
524 : 0 : return aInterestedIn;
525 : : }
526 : :
527 : : //--------------------------------------------------------------------
528 : 0 : 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)
529 : : {
530 : 0 : if ( !_rxInspectorUI.is() )
531 : 0 : throw NullPointerException();
532 : :
533 : 0 : ::osl::MutexGuard aGuard( m_aMutex );
534 : 0 : PropertyId nActuatingPropId( impl_getPropertyId_throw( _rActuatingPropertyName ) );
535 : :
536 : 0 : switch ( nActuatingPropId )
537 : : {
538 : : case PROPERTY_ID_TEXT_ANCHOR_TYPE:
539 : : {
540 : 0 : TextContentAnchorType eAnchorType( TextContentAnchorType_AT_PARAGRAPH );
541 : 0 : OSL_VERIFY( _rNewValue >>= eAnchorType );
542 : 0 : _rxInspectorUI->enablePropertyUI( PROPERTY_POSITIONX, eAnchorType != TextContentAnchorType_AS_CHARACTER );
543 : : }
544 : 0 : break;
545 : : default:
546 : : OSL_FAIL( "FormGeometryHandler::actuatingPropertyChanged: not registered for this property!" );
547 : 0 : break;
548 : 0 : }
549 : 0 : }
550 : :
551 : : //--------------------------------------------------------------------
552 : 0 : Sequence< Property > SAL_CALL FormGeometryHandler::doDescribeSupportedProperties() const
553 : : {
554 : 0 : if ( !m_xAssociatedShape.is() )
555 : 0 : return Sequence< Property >();
556 : :
557 : 0 : ::std::vector< Property > aProperties;
558 : :
559 : 0 : addInt32PropertyDescription( aProperties, PROPERTY_POSITIONX );
560 : 0 : addInt32PropertyDescription( aProperties, PROPERTY_POSITIONY );
561 : 0 : addInt32PropertyDescription( aProperties, PROPERTY_WIDTH );
562 : 0 : addInt32PropertyDescription( aProperties, PROPERTY_HEIGHT );
563 : :
564 : 0 : if ( impl_haveTextAnchorType_nothrow() )
565 : 0 : implAddPropertyDescription( aProperties, PROPERTY_TEXT_ANCHOR_TYPE, ::cppu::UnoType< TextContentAnchorType >::get() );
566 : :
567 : 0 : if ( impl_haveSheetAnchorType_nothrow() )
568 : 0 : addInt32PropertyDescription( aProperties, PROPERTY_SHEET_ANCHOR_TYPE );
569 : :
570 : 0 : return Sequence< Property >( &(*aProperties.begin()), aProperties.size() );
571 : : }
572 : :
573 : : //--------------------------------------------------------------------
574 : 0 : void SAL_CALL FormGeometryHandler::disposing()
575 : : {
576 : 0 : FormGeometryHandler_Base::disposing();
577 : :
578 : 0 : if ( m_xChangeNotifier.is() )
579 : : {
580 : 0 : m_xChangeNotifier->dispose();
581 : 0 : m_xChangeNotifier.clear();
582 : : }
583 : 0 : }
584 : :
585 : : //--------------------------------------------------------------------
586 : 0 : bool FormGeometryHandler::impl_haveTextAnchorType_nothrow() const
587 : : {
588 : 0 : ENSURE_OR_THROW( m_xShapeProperties.is(), "not to be called without shape properties" );
589 : : try
590 : : {
591 : 0 : Reference< XPropertySetInfo > xPSI( m_xShapeProperties->getPropertySetInfo(), UNO_SET_THROW );
592 : 0 : if ( xPSI->hasPropertyByName( PROPERTY_ANCHOR_TYPE ) )
593 : 0 : return true;
594 : : }
595 : 0 : catch( const Exception& )
596 : : {
597 : : DBG_UNHANDLED_EXCEPTION();
598 : : }
599 : 0 : return false;
600 : : }
601 : :
602 : : //--------------------------------------------------------------------
603 : 0 : bool FormGeometryHandler::impl_haveSheetAnchorType_nothrow() const
604 : : {
605 : 0 : ENSURE_OR_THROW( m_xShapeProperties.is(), "not to be called without shape properties" );
606 : : try
607 : : {
608 : 0 : Reference< XPropertySetInfo > xPSI( m_xShapeProperties->getPropertySetInfo(), UNO_SET_THROW );
609 : 0 : if ( !xPSI->hasPropertyByName( PROPERTY_ANCHOR ) )
610 : 0 : return false;
611 : 0 : Reference< XServiceInfo > xSI( m_xAssociatedShape, UNO_QUERY_THROW );
612 : 0 : if ( xSI->supportsService( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.Shape" ) ) ) )
613 : 0 : return true;
614 : : }
615 : 0 : catch( const Exception& )
616 : : {
617 : : DBG_UNHANDLED_EXCEPTION();
618 : : }
619 : 0 : return false;
620 : : }
621 : :
622 : : //--------------------------------------------------------------------
623 : : namespace
624 : : {
625 : 0 : static sal_Int32 lcl_getLowerBoundRowOrColumn( const Reference< XIndexAccess >& _rxRowsOrColumns, const bool _bRows,
626 : : const AwtPoint& _rRelativePosition )
627 : : {
628 : 0 : sal_Int32 nAccumulated = 0;
629 : :
630 : 0 : const sal_Int32& rRelativePos = _bRows ? _rRelativePosition.Y : _rRelativePosition.X;
631 : :
632 : 0 : sal_Int32 nElements = _rxRowsOrColumns->getCount();
633 : 0 : sal_Int32 currentPos = 0;
634 : 0 : for ( currentPos=0; currentPos<nElements; ++currentPos )
635 : : {
636 : 0 : Reference< XPropertySet > xRowOrColumn( _rxRowsOrColumns->getByIndex( currentPos ), UNO_QUERY_THROW );
637 : :
638 : 0 : sal_Bool bIsVisible = sal_True;
639 : 0 : OSL_VERIFY( xRowOrColumn->getPropertyValue( PROPERTY_IS_VISIBLE ) >>= bIsVisible );
640 : 0 : if ( !bIsVisible )
641 : 0 : continue;
642 : :
643 : 0 : sal_Int32 nHeightOrWidth( 0 );
644 : 0 : OSL_VERIFY( xRowOrColumn->getPropertyValue( _bRows ? PROPERTY_HEIGHT : PROPERTY_WIDTH ) >>= nHeightOrWidth );
645 : :
646 : 0 : if ( nAccumulated + nHeightOrWidth > rRelativePos )
647 : : break;
648 : :
649 : 0 : nAccumulated += nHeightOrWidth;
650 : 0 : }
651 : :
652 : 0 : return currentPos;
653 : : }
654 : : }
655 : :
656 : : //--------------------------------------------------------------------
657 : 0 : void FormGeometryHandler::impl_setSheetAnchorType_nothrow( const sal_Int32 _nAnchorType ) const
658 : : {
659 : 0 : ENSURE_OR_THROW( m_xShapeProperties.is(), "illegal to be called without shape properties." );
660 : : try
661 : : {
662 : 0 : CellBindingHelper aHelper( m_xComponent, impl_getContextDocument_nothrow() );
663 : : // find the sheet which the control belongs to
664 : 0 : Reference< XSpreadsheet > xSheet;
665 : 0 : aHelper.getControlSheetIndex( xSheet );
666 : :
667 : 0 : switch ( _nAnchorType )
668 : : {
669 : : case ANCHOR_TO_SHEET:
670 : : OSL_ENSURE( xSheet.is(),
671 : : "FormGeometryHandler::impl_setSheetAnchorType_nothrow: sheet not found!" );
672 : 0 : if ( xSheet.is() )
673 : : {
674 : 0 : AwtPoint aPreservePosition( m_xAssociatedShape->getPosition() );
675 : 0 : m_xShapeProperties->setPropertyValue( PROPERTY_ANCHOR, makeAny( xSheet ) );
676 : 0 : m_xAssociatedShape->setPosition( aPreservePosition );
677 : : }
678 : 0 : break;
679 : :
680 : : case ANCHOR_TO_CELL:
681 : : {
682 : 0 : Reference< XColumnRowRange > xColsRows( xSheet, UNO_QUERY_THROW );
683 : :
684 : : // get the current anchor
685 : 0 : Reference< XSpreadsheet > xCurrentAnchor;
686 : 0 : OSL_VERIFY( m_xShapeProperties->getPropertyValue( PROPERTY_ANCHOR ) >>= xCurrentAnchor );
687 : : OSL_ENSURE( xCurrentAnchor.is(), "FormGeometryHandler::impl_setSheetAnchorType_nothrow: only to be called when currently anchored to a sheet!" );
688 : :
689 : : // get the current position
690 : 0 : AwtPoint aRelativePosition( m_xAssociatedShape->getPosition() );
691 : :
692 : 0 : Reference< XTableColumns > xCols( xColsRows->getColumns(), UNO_SET_THROW );
693 : 0 : sal_Int32 nNewAnchorCol = lcl_getLowerBoundRowOrColumn( xCols.get(), false, aRelativePosition );
694 : :
695 : 0 : Reference< XTableRows > xRows( xColsRows->getRows(), UNO_SET_THROW );
696 : 0 : sal_Int32 nNewAnchorRow = lcl_getLowerBoundRowOrColumn( xRows.get(), true, aRelativePosition );
697 : :
698 : 0 : Reference< XCellRange > xSheetCellRange( xSheet, UNO_QUERY_THROW );
699 : 0 : Any aNewAnchorCell( xSheetCellRange->getCellByPosition( nNewAnchorCol, nNewAnchorRow ) );
700 : 0 : m_xShapeProperties->setPropertyValue( PROPERTY_ANCHOR, aNewAnchorCell );
701 : : }
702 : 0 : break;
703 : :
704 : : default:
705 : : OSL_FAIL( "FormGeometryHandler::impl_setSheetAnchorType_nothrow: illegal anchor type!" );
706 : 0 : break;
707 : 0 : }
708 : : }
709 : 0 : catch( const Exception& )
710 : : {
711 : : DBG_UNHANDLED_EXCEPTION();
712 : : }
713 : 0 : }
714 : :
715 : : //====================================================================
716 : : //= ShapeGeometryChangeNotifier - implementation
717 : : //====================================================================
718 : : namespace
719 : : {
720 : 0 : struct EventTranslation
721 : : {
722 : : ::rtl::OUString sPropertyName;
723 : : Any aNewPropertyValue;
724 : :
725 : 0 : EventTranslation( const ::rtl::OUString& _propertyName, const Any& _newPropertyValue )
726 : : :sPropertyName( _propertyName )
727 : 0 : ,aNewPropertyValue( _newPropertyValue )
728 : : {
729 : 0 : }
730 : : };
731 : : }
732 : :
733 : : //--------------------------------------------------------------------
734 : 0 : void SAL_CALL ShapeGeometryChangeNotifier::propertyChange( const PropertyChangeEvent& _event ) throw (RuntimeException)
735 : : {
736 : 0 : ::comphelper::ComponentMethodGuard aGuard( *this );
737 : :
738 : 0 : ::std::vector< EventTranslation > aEventTranslations;
739 : 0 : aEventTranslations.reserve(2);
740 : :
741 : 0 : if ( _event.PropertyName == "Position" )
742 : : {
743 : 0 : AwtPoint aPos = m_xShape->getPosition();
744 : 0 : aEventTranslations.push_back( EventTranslation( PROPERTY_POSITIONX, makeAny( aPos.X ) ) );
745 : 0 : aEventTranslations.push_back( EventTranslation( PROPERTY_POSITIONY, makeAny( aPos.Y ) ) );
746 : : }
747 : 0 : else if ( _event.PropertyName == "Size" )
748 : : {
749 : 0 : AwtSize aSize = m_xShape->getSize();
750 : 0 : aEventTranslations.push_back( EventTranslation( PROPERTY_WIDTH, makeAny( aSize.Width ) ) );
751 : 0 : aEventTranslations.push_back( EventTranslation( PROPERTY_HEIGHT, makeAny( aSize.Height ) ) );
752 : : }
753 : 0 : else if ( _event.PropertyName == PROPERTY_ANCHOR_TYPE )
754 : : {
755 : 0 : aEventTranslations.push_back( EventTranslation( PROPERTY_TEXT_ANCHOR_TYPE, makeAny( _event.NewValue ) ) );
756 : : }
757 : 0 : else if ( _event.PropertyName == PROPERTY_ANCHOR )
758 : : {
759 : 0 : aEventTranslations.push_back( EventTranslation( PROPERTY_SHEET_ANCHOR_TYPE, makeAny( _event.NewValue ) ) );
760 : : }
761 : :
762 : 0 : PropertyChangeEvent aTranslatedEvent( _event );
763 : 0 : aTranslatedEvent.Source = m_rParent;
764 : :
765 : 0 : aGuard.clear();
766 : 0 : for ( ::std::vector< EventTranslation >::const_iterator t = aEventTranslations.begin();
767 : 0 : t != aEventTranslations.end();
768 : : ++t
769 : : )
770 : : {
771 : 0 : aTranslatedEvent.PropertyName = t->sPropertyName;
772 : 0 : aTranslatedEvent.NewValue = t->aNewPropertyValue;
773 : 0 : m_aPropertyChangeListeners.notifyEach( &XPropertyChangeListener::propertyChange, aTranslatedEvent );
774 : 0 : }
775 : 0 : }
776 : :
777 : : //--------------------------------------------------------------------
778 : 0 : void SAL_CALL ShapeGeometryChangeNotifier::disposing( const EventObject& /*_event*/ ) throw (RuntimeException)
779 : : {
780 : 0 : ::comphelper::ComponentMethodGuard aGuard( *this );
781 : 0 : impl_dispose_nothrow();
782 : 0 : }
783 : :
784 : : //--------------------------------------------------------------------
785 : 0 : void ShapeGeometryChangeNotifier::impl_init_nothrow()
786 : : {
787 : 0 : osl_incrementInterlockedCount( &m_refCount );
788 : : try
789 : : {
790 : 0 : Reference< XPropertySet > xShapeProperties( m_xShape, UNO_QUERY_THROW );
791 : 0 : xShapeProperties->addPropertyChangeListener( ::rtl::OUString(), this );
792 : : }
793 : 0 : catch( const Exception& )
794 : : {
795 : : DBG_UNHANDLED_EXCEPTION();
796 : : }
797 : 0 : osl_decrementInterlockedCount( &m_refCount );
798 : 0 : }
799 : :
800 : : //--------------------------------------------------------------------
801 : 0 : void ShapeGeometryChangeNotifier::impl_dispose_nothrow()
802 : : {
803 : : try
804 : : {
805 : 0 : Reference< XPropertySet > xShapeProperties( m_xShape, UNO_QUERY_THROW );
806 : 0 : xShapeProperties->removePropertyChangeListener( ::rtl::OUString(), this );
807 : : }
808 : 0 : catch( const Exception& )
809 : : {
810 : : DBG_UNHANDLED_EXCEPTION();
811 : : }
812 : :
813 : 0 : getBroadcastHelper().bDisposed = true;
814 : 0 : }
815 : :
816 : : //........................................................................
817 : : } // namespace pcr
818 : : //........................................................................
819 : :
820 : 0 : extern "C" void SAL_CALL createRegistryInfo_FormGeometryHandler()
821 : : {
822 : 0 : ::pcr::FormGeometryHandler::registerImplementation();
823 : 0 : }
824 : :
825 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|