summaryrefslogtreecommitdiff
path: root/svx/source/accessibility/AccessibleControlShape.cxx
diff options
context:
space:
mode:
authorFrank Schönheit <fs@openoffice.org>2002-04-29 15:51:40 +0000
committerFrank Schönheit <fs@openoffice.org>2002-04-29 15:51:40 +0000
commit37d471b969e35c4d4879453f26f451b758524feb (patch)
tree1410e13299c47c30fe02512d967c2edcae42d944 /svx/source/accessibility/AccessibleControlShape.cxx
parentdf457e84ae7b9a78ab115b674232f8c897917f54 (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.cxx203
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;
+}