diff options
author | Frank Schönheit <fs@openoffice.org> | 2002-04-29 15:51:40 +0000 |
---|---|---|
committer | Frank Schönheit <fs@openoffice.org> | 2002-04-29 15:51:40 +0000 |
commit | 37d471b969e35c4d4879453f26f451b758524feb (patch) | |
tree | 1410e13299c47c30fe02512d967c2edcae42d944 /svx/source/accessibility/AccessibleControlShape.cxx | |
parent | df457e84ae7b9a78ab115b674232f8c897917f54 (diff) |
preparations for #98750#: retrieve the name/description from the respective model properties, if possible
Diffstat (limited to 'svx/source/accessibility/AccessibleControlShape.cxx')
-rw-r--r-- | svx/source/accessibility/AccessibleControlShape.cxx | 203 |
1 files changed, 193 insertions, 10 deletions
diff --git a/svx/source/accessibility/AccessibleControlShape.cxx b/svx/source/accessibility/AccessibleControlShape.cxx index c88e3c696061..4c3c30e631af 100644 --- a/svx/source/accessibility/AccessibleControlShape.cxx +++ b/svx/source/accessibility/AccessibleControlShape.cxx @@ -2,9 +2,9 @@ * * $RCSfile: AccessibleControlShape.cxx,v $ * - * $Revision: 1.2 $ + * $Revision: 1.3 $ * - * last change: $Author: af $ $Date: 2002-04-18 16:31:06 $ + * last change: $Author: fs $ $Date: 2002-04-29 16:51:40 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -67,6 +67,10 @@ #ifndef _SVX_ACCESSIBILITY_DESCRIPTION_GENERATOR_HXX #include "DescriptionGenerator.hxx" #endif +#ifndef _COM_SUN_STAR_DRAWING_XCONTROLSHAPE_HPP_ +#include <com/sun/star/drawing/XControlShape.hpp> +#endif +#include <drafts/com/sun/star/accessibility/AccessibleEventId.hpp> #include "ShapeTypeHandler.hxx" #include "SvxShapeTypes.hxx" @@ -86,6 +90,8 @@ AccessibleControlShape::AccessibleControlShape (const ::com::sun::star::uno::Ref const AccessibleShapeTreeInfo& rShapeTreeInfo, long nIndex) : AccessibleShape (rxShape, rxParent, rShapeTreeInfo, nIndex) + , mbListeningForName( sal_False ) + , mbListeningForDesc( sal_False ) { } @@ -152,6 +158,24 @@ Reference<XAccessibleContext> SAL_CALL +//-------------------------------------------------------------------- +namespace +{ + //................................................................ + const ::rtl::OUString& lcl_getNamePropertyName( ) + { + static ::rtl::OUString s_sNamePropertyName( RTL_CONSTASCII_USTRINGPARAM( "Name" ) ); + return s_sNamePropertyName; + } + //................................................................ + const ::rtl::OUString& lcl_getDescPropertyName( ) + { + static ::rtl::OUString s_sDescPropertyDesc( RTL_CONSTASCII_USTRINGPARAM( "HelpText" ) ); + return s_sDescPropertyDesc; + } +} + +//-------------------------------------------------------------------- ::rtl::OUString AccessibleControlShape::CreateAccessibleDescription (void) throw (::com::sun::star::uno::RuntimeException) @@ -161,14 +185,24 @@ Reference<XAccessibleContext> SAL_CALL switch (nShapeType) { case DRAWING_CONTROL: - aDG.Initialize (OUString::createFromAscii("Control")); - aDG.AddProperty (OUString::createFromAscii ("ControlBackground"), - DescriptionGenerator::COLOR, - OUString()); - aDG.AddProperty (OUString::createFromAscii ("ControlBorder"), - DescriptionGenerator::INTEGER, - OUString()); - break; + { + // check if we can obtain the "Desc" property from the model + ::rtl::OUString sDesc( getControlModelStringProperty( lcl_getDescPropertyName() ) ); + if ( !sDesc.getLength() ) + { // no -> use the default + aDG.Initialize (OUString::createFromAscii("Control")); + aDG.AddProperty (OUString::createFromAscii ("ControlBackground"), + DescriptionGenerator::COLOR, + OUString()); + aDG.AddProperty (OUString::createFromAscii ("ControlBorder"), + DescriptionGenerator::INTEGER, + OUString()); + } + // ensure that we are listening to the Name property + mbListeningForDesc = ensureListeningState( mbListeningForDesc, sal_True, lcl_getDescPropertyName() ); + } + break; + default: aDG.Initialize (::rtl::OUString::createFromAscii ( "Unknown accessible control shape")); @@ -183,4 +217,153 @@ Reference<XAccessibleContext> SAL_CALL return aDG(); } +//-------------------------------------------------------------------- +IMPLEMENT_FORWARD_XINTERFACE2( AccessibleControlShape, AccessibleShape, AccessibleControlShape_Base ) +IMPLEMENT_FORWARD_XTYPEPROVIDER2( AccessibleControlShape, AccessibleShape, AccessibleControlShape_Base ) + // order matters in both cases: the second argument is the base class doing the ref counting + +//-------------------------------------------------------------------- +void SAL_CALL AccessibleControlShape::propertyChange( const beans::PropertyChangeEvent& _rEvent ) throw (uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( maMutex ); + + ::rtl::OUString sNewValue; + sal_Int16 nEventId = -1; + // check if it is the name or the description + if ( _rEvent.PropertyName.equals( lcl_getNamePropertyName() ) ) + { + nEventId = AccessibleEventId::ACCESSIBLE_NAME_EVENT; + sNewValue = CreateAccessibleName(); + } + else if ( _rEvent.PropertyName.equals( lcl_getDescPropertyName() ) ) + { + nEventId = AccessibleEventId::ACCESSIBLE_DESCRIPTION_EVENT; + sNewValue = CreateAccessibleDescription(); + } +#ifdef _DEBUG + else + { + OSL_ENSURE( sal_False, "AccessibleControlShape::propertyChange: where did this come from?" ); + } +#endif + if ( -1 != nEventId ) + { // notify the AccessibilityListeners + CommitChange( nEventId, uno::makeAny( sNewValue ), uno::Any() ); + // TODO: check this in reality: If the name is changed from non-empty to empty, this means + // that we remove ourself as listener _while_we_are_within_the_listener_call_. Don't know + // if the common implementation in cppuhelper can correctly handle this! + } +} + +//-------------------------------------------------------------------- +void SAL_CALL AccessibleControlShape::disposing (const lang::EventObject& _rSource) throw (uno::RuntimeException) +{ + // simply disambiguate + AccessibleShape::disposing( _rSource ); +} + +//-------------------------------------------------------------------- +sal_Bool AccessibleControlShape::ensureListeningState( + const sal_Bool _bCurrentlyListening, const sal_Bool _bNeedNewListening, + const ::rtl::OUString& _rPropertyName ) +{ + if ( ( _bCurrentlyListening == _bNeedNewListening ) || !ensureControlModelAccess() ) + // nothing to do + return _bCurrentlyListening; + + try + { + if ( !mxModelPropsMeta.is() || mxModelPropsMeta->hasPropertyByName( _rPropertyName ) ) + { + // add or revoke as listener + if ( _bNeedNewListening ) + mxControlModel->addPropertyChangeListener( _rPropertyName, static_cast< beans::XPropertyChangeListener* >( this ) ); + else + mxControlModel->removePropertyChangeListener( _rPropertyName, static_cast< beans::XPropertyChangeListener* >( this ) ); + } + } + catch( const uno::Exception& e ) + { + e; // make compiler happy + OSL_ENSURE( sal_False, "AccessibleControlShape::ensureListeningState: could not change the listening state!" ); + } + + return _bNeedNewListening; +} + +//-------------------------------------------------------------------- +::rtl::OUString AccessibleControlShape::CreateAccessibleName (void) throw (uno::RuntimeException) +{ + // check if we can obtain the "Name" property from the model + ::rtl::OUString sName( getControlModelStringProperty( lcl_getNamePropertyName() ) ); + if ( !sName.getLength() ) + { // no -> use the default + sName = AccessibleShape::CreateAccessibleName(); + } + + // now that somebody first asked us for our name, ensure that we are listening to name changes on the model + mbListeningForName = ensureListeningState( mbListeningForName, sal_True, lcl_getNamePropertyName() ); + + return sName; +} + +//-------------------------------------------------------------------- +void SAL_CALL AccessibleControlShape::disposing (void) +{ + // ensure we're not listening + mbListeningForName = ensureListeningState( mbListeningForName, sal_False, lcl_getNamePropertyName() ); + mbListeningForDesc = ensureListeningState( mbListeningForDesc, sal_False, lcl_getDescPropertyName() ); + + // release the model + mxControlModel.clear(); + mxModelPropsMeta.clear(); + + // let the base do it's stuff + AccessibleShape::dispose(); +} + +//-------------------------------------------------------------------- +sal_Bool AccessibleControlShape::ensureControlModelAccess() const SAL_THROW(()) +{ + if ( mxControlModel.is() ) + return sal_True; + + try + { + Reference< drawing::XControlShape > xShape( mxShape, uno::UNO_QUERY ); + if ( xShape.is() ) + const_cast< AccessibleControlShape* >( this )->mxControlModel = mxControlModel.query( xShape->getControl() ); + + if ( mxControlModel.is() ) + const_cast< AccessibleControlShape* >( this )->mxModelPropsMeta = mxControlModel->getPropertySetInfo(); + } + catch( const uno::Exception& e ) + { + e; // make compiler happy + OSL_ENSURE( sal_False, "AccessibleControlShape::ensureControlModelAccess: caught an exception!" ); + } + + return mxControlModel.is(); +} + +//-------------------------------------------------------------------- +::rtl::OUString AccessibleControlShape::getControlModelStringProperty( const ::rtl::OUString& _rPropertyName ) const SAL_THROW(()) +{ + ::rtl::OUString sReturn; + try + { + if ( ensureControlModelAccess() ) + { + if ( !mxModelPropsMeta.is() || mxModelPropsMeta->hasPropertyByName( _rPropertyName ) ) + // ask only if a) the control does not have a PropertySetInfo object or b) it has, and the + // property in question is available + mxControlModel->getPropertyValue( _rPropertyName ) >>= sReturn; + } + } + catch( const uno::Exception& ) + { + OSL_ENSURE( sal_False, "OAccessibleControlContext::getModelStringProperty: caught an exception!" ); + } + return sReturn; +} |