1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_editeng.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir 32*cdf0e10cSrcweir #include <editeng/AccessibleContextBase.hxx> 33*cdf0e10cSrcweir 34*cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleRole.hpp> 35*cdf0e10cSrcweir #include <com/sun/star/beans/PropertyChangeEvent.hpp> 36*cdf0e10cSrcweir #include <com/sun/star/accessibility/XAccessibleEventListener.hpp> 37*cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleStateType.hpp> 38*cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleRelationType.hpp> 39*cdf0e10cSrcweir 40*cdf0e10cSrcweir #include <unotools/accessiblestatesethelper.hxx> 41*cdf0e10cSrcweir #include <unotools/accessiblerelationsethelper.hxx> 42*cdf0e10cSrcweir #include <comphelper/accessibleeventnotifier.hxx> 43*cdf0e10cSrcweir #include <rtl/uuid.h> 44*cdf0e10cSrcweir #include <vos/mutex.hxx> 45*cdf0e10cSrcweir //#include <vcl/svapp.hxx> 46*cdf0e10cSrcweir 47*cdf0e10cSrcweir #include <utility> 48*cdf0e10cSrcweir 49*cdf0e10cSrcweir using namespace ::rtl; 50*cdf0e10cSrcweir using namespace ::com::sun::star; 51*cdf0e10cSrcweir using namespace ::com::sun::star::accessibility; 52*cdf0e10cSrcweir using ::com::sun::star::uno::Reference; 53*cdf0e10cSrcweir 54*cdf0e10cSrcweir namespace accessibility { 55*cdf0e10cSrcweir 56*cdf0e10cSrcweir //===== internal ============================================================ 57*cdf0e10cSrcweir 58*cdf0e10cSrcweir // Define a shortcut for the somewhot longish base class name. 59*cdf0e10cSrcweir typedef ::cppu::WeakComponentImplHelper4< 60*cdf0e10cSrcweir ::com::sun::star::accessibility::XAccessible, 61*cdf0e10cSrcweir ::com::sun::star::accessibility::XAccessibleContext, 62*cdf0e10cSrcweir ::com::sun::star::accessibility::XAccessibleEventBroadcaster, 63*cdf0e10cSrcweir ::com::sun::star::lang::XServiceInfo> BaseClass; 64*cdf0e10cSrcweir 65*cdf0e10cSrcweir AccessibleContextBase::AccessibleContextBase ( 66*cdf0e10cSrcweir const uno::Reference<XAccessible>& rxParent, 67*cdf0e10cSrcweir const sal_Int16 aRole) 68*cdf0e10cSrcweir : BaseClass (MutexOwner::maMutex), 69*cdf0e10cSrcweir mxStateSet (NULL), 70*cdf0e10cSrcweir mxRelationSet (NULL), 71*cdf0e10cSrcweir mxParent(rxParent), 72*cdf0e10cSrcweir msDescription(), 73*cdf0e10cSrcweir meDescriptionOrigin(NotSet), 74*cdf0e10cSrcweir msName(), 75*cdf0e10cSrcweir meNameOrigin(NotSet), 76*cdf0e10cSrcweir mnClientId(0), 77*cdf0e10cSrcweir maRole(aRole) 78*cdf0e10cSrcweir { 79*cdf0e10cSrcweir // Create the state set. 80*cdf0e10cSrcweir ::utl::AccessibleStateSetHelper* pStateSet = new ::utl::AccessibleStateSetHelper (); 81*cdf0e10cSrcweir mxStateSet = pStateSet; 82*cdf0e10cSrcweir 83*cdf0e10cSrcweir // Set some states. Don't use the SetState method because no events 84*cdf0e10cSrcweir // shall be broadcastet (that is not yet initialized anyway). 85*cdf0e10cSrcweir if (pStateSet != NULL) 86*cdf0e10cSrcweir { 87*cdf0e10cSrcweir pStateSet->AddState (AccessibleStateType::ENABLED); 88*cdf0e10cSrcweir pStateSet->AddState (AccessibleStateType::SENSITIVE); 89*cdf0e10cSrcweir pStateSet->AddState (AccessibleStateType::SHOWING); 90*cdf0e10cSrcweir pStateSet->AddState (AccessibleStateType::VISIBLE); 91*cdf0e10cSrcweir pStateSet->AddState (AccessibleStateType::FOCUSABLE); 92*cdf0e10cSrcweir pStateSet->AddState (AccessibleStateType::SELECTABLE); 93*cdf0e10cSrcweir } 94*cdf0e10cSrcweir 95*cdf0e10cSrcweir // Create the relation set. 96*cdf0e10cSrcweir ::utl::AccessibleRelationSetHelper* pRelationSet = new ::utl::AccessibleRelationSetHelper (); 97*cdf0e10cSrcweir mxRelationSet = pRelationSet; 98*cdf0e10cSrcweir } 99*cdf0e10cSrcweir 100*cdf0e10cSrcweir 101*cdf0e10cSrcweir 102*cdf0e10cSrcweir 103*cdf0e10cSrcweir AccessibleContextBase::~AccessibleContextBase(void) 104*cdf0e10cSrcweir { 105*cdf0e10cSrcweir } 106*cdf0e10cSrcweir 107*cdf0e10cSrcweir 108*cdf0e10cSrcweir 109*cdf0e10cSrcweir 110*cdf0e10cSrcweir sal_Bool AccessibleContextBase::SetState (sal_Int16 aState) 111*cdf0e10cSrcweir { 112*cdf0e10cSrcweir ::osl::ClearableMutexGuard aGuard (maMutex); 113*cdf0e10cSrcweir ::utl::AccessibleStateSetHelper* pStateSet = 114*cdf0e10cSrcweir static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get()); 115*cdf0e10cSrcweir if ((pStateSet != NULL) && !pStateSet->contains(aState)) 116*cdf0e10cSrcweir { 117*cdf0e10cSrcweir pStateSet->AddState (aState); 118*cdf0e10cSrcweir // Clear the mutex guard so that it is not locked during calls to 119*cdf0e10cSrcweir // listeners. 120*cdf0e10cSrcweir aGuard.clear(); 121*cdf0e10cSrcweir 122*cdf0e10cSrcweir // Send event for all states except the DEFUNC state. 123*cdf0e10cSrcweir if (aState != AccessibleStateType::DEFUNC) 124*cdf0e10cSrcweir { 125*cdf0e10cSrcweir uno::Any aNewValue; 126*cdf0e10cSrcweir aNewValue <<= aState; 127*cdf0e10cSrcweir CommitChange( 128*cdf0e10cSrcweir AccessibleEventId::STATE_CHANGED, 129*cdf0e10cSrcweir aNewValue, 130*cdf0e10cSrcweir uno::Any()); 131*cdf0e10cSrcweir } 132*cdf0e10cSrcweir return sal_True; 133*cdf0e10cSrcweir } 134*cdf0e10cSrcweir else 135*cdf0e10cSrcweir return sal_False; 136*cdf0e10cSrcweir } 137*cdf0e10cSrcweir 138*cdf0e10cSrcweir 139*cdf0e10cSrcweir 140*cdf0e10cSrcweir 141*cdf0e10cSrcweir sal_Bool AccessibleContextBase::ResetState (sal_Int16 aState) 142*cdf0e10cSrcweir { 143*cdf0e10cSrcweir ::osl::ClearableMutexGuard aGuard (maMutex); 144*cdf0e10cSrcweir ::utl::AccessibleStateSetHelper* pStateSet = 145*cdf0e10cSrcweir static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get()); 146*cdf0e10cSrcweir if ((pStateSet != NULL) && pStateSet->contains(aState)) 147*cdf0e10cSrcweir { 148*cdf0e10cSrcweir pStateSet->RemoveState (aState); 149*cdf0e10cSrcweir // Clear the mutex guard so that it is not locked during calls to listeners. 150*cdf0e10cSrcweir aGuard.clear(); 151*cdf0e10cSrcweir 152*cdf0e10cSrcweir uno::Any aOldValue; 153*cdf0e10cSrcweir aOldValue <<= aState; 154*cdf0e10cSrcweir CommitChange( 155*cdf0e10cSrcweir AccessibleEventId::STATE_CHANGED, 156*cdf0e10cSrcweir uno::Any(), 157*cdf0e10cSrcweir aOldValue); 158*cdf0e10cSrcweir return sal_True; 159*cdf0e10cSrcweir } 160*cdf0e10cSrcweir else 161*cdf0e10cSrcweir return sal_False; 162*cdf0e10cSrcweir } 163*cdf0e10cSrcweir 164*cdf0e10cSrcweir 165*cdf0e10cSrcweir 166*cdf0e10cSrcweir 167*cdf0e10cSrcweir sal_Bool AccessibleContextBase::GetState (sal_Int16 aState) 168*cdf0e10cSrcweir { 169*cdf0e10cSrcweir ::osl::MutexGuard aGuard (maMutex); 170*cdf0e10cSrcweir ::utl::AccessibleStateSetHelper* pStateSet = 171*cdf0e10cSrcweir static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get()); 172*cdf0e10cSrcweir if (pStateSet != NULL) 173*cdf0e10cSrcweir return pStateSet->contains(aState); 174*cdf0e10cSrcweir else 175*cdf0e10cSrcweir // If there is no state set then return false as a default value. 176*cdf0e10cSrcweir return sal_False; 177*cdf0e10cSrcweir } 178*cdf0e10cSrcweir 179*cdf0e10cSrcweir 180*cdf0e10cSrcweir 181*cdf0e10cSrcweir 182*cdf0e10cSrcweir void AccessibleContextBase::SetRelationSet ( 183*cdf0e10cSrcweir const uno::Reference<XAccessibleRelationSet>& rxNewRelationSet) 184*cdf0e10cSrcweir throw (::com::sun::star::uno::RuntimeException) 185*cdf0e10cSrcweir { 186*cdf0e10cSrcweir OSL_TRACE ("setting relation set"); 187*cdf0e10cSrcweir 188*cdf0e10cSrcweir // Try to emit some meaningfull events indicating differing relations in 189*cdf0e10cSrcweir // both sets. 190*cdf0e10cSrcweir typedef std::pair<short int,short int> RD; 191*cdf0e10cSrcweir const RD aRelationDescriptors[] = { 192*cdf0e10cSrcweir RD(AccessibleRelationType::CONTROLLED_BY, AccessibleEventId::CONTROLLED_BY_RELATION_CHANGED), 193*cdf0e10cSrcweir RD(AccessibleRelationType::CONTROLLER_FOR, AccessibleEventId::CONTROLLER_FOR_RELATION_CHANGED), 194*cdf0e10cSrcweir RD(AccessibleRelationType::LABELED_BY, AccessibleEventId::LABELED_BY_RELATION_CHANGED), 195*cdf0e10cSrcweir RD(AccessibleRelationType::LABEL_FOR, AccessibleEventId::LABEL_FOR_RELATION_CHANGED), 196*cdf0e10cSrcweir RD(AccessibleRelationType::MEMBER_OF, AccessibleEventId::MEMBER_OF_RELATION_CHANGED), 197*cdf0e10cSrcweir RD(AccessibleRelationType::INVALID, -1), 198*cdf0e10cSrcweir }; 199*cdf0e10cSrcweir for (int i=0; aRelationDescriptors[i].first!=AccessibleRelationType::INVALID; i++) 200*cdf0e10cSrcweir if (mxRelationSet->containsRelation(aRelationDescriptors[i].first) 201*cdf0e10cSrcweir != rxNewRelationSet->containsRelation(aRelationDescriptors[i].first)) 202*cdf0e10cSrcweir CommitChange (aRelationDescriptors[i].second, uno::Any(), uno::Any()); 203*cdf0e10cSrcweir 204*cdf0e10cSrcweir mxRelationSet = rxNewRelationSet; 205*cdf0e10cSrcweir } 206*cdf0e10cSrcweir 207*cdf0e10cSrcweir 208*cdf0e10cSrcweir 209*cdf0e10cSrcweir 210*cdf0e10cSrcweir //===== XAccessible ========================================================= 211*cdf0e10cSrcweir 212*cdf0e10cSrcweir uno::Reference< XAccessibleContext> SAL_CALL 213*cdf0e10cSrcweir AccessibleContextBase::getAccessibleContext (void) 214*cdf0e10cSrcweir throw (uno::RuntimeException) 215*cdf0e10cSrcweir { 216*cdf0e10cSrcweir ThrowIfDisposed (); 217*cdf0e10cSrcweir return this; 218*cdf0e10cSrcweir } 219*cdf0e10cSrcweir 220*cdf0e10cSrcweir 221*cdf0e10cSrcweir 222*cdf0e10cSrcweir 223*cdf0e10cSrcweir //===== XAccessibleContext ================================================== 224*cdf0e10cSrcweir 225*cdf0e10cSrcweir /** No children. 226*cdf0e10cSrcweir */ 227*cdf0e10cSrcweir sal_Int32 SAL_CALL 228*cdf0e10cSrcweir AccessibleContextBase::getAccessibleChildCount (void) 229*cdf0e10cSrcweir throw (uno::RuntimeException) 230*cdf0e10cSrcweir { 231*cdf0e10cSrcweir ThrowIfDisposed (); 232*cdf0e10cSrcweir return 0; 233*cdf0e10cSrcweir } 234*cdf0e10cSrcweir 235*cdf0e10cSrcweir 236*cdf0e10cSrcweir 237*cdf0e10cSrcweir 238*cdf0e10cSrcweir /** Forward the request to the shape. Return the requested shape or throw 239*cdf0e10cSrcweir an exception for a wrong index. 240*cdf0e10cSrcweir */ 241*cdf0e10cSrcweir uno::Reference<XAccessible> SAL_CALL 242*cdf0e10cSrcweir AccessibleContextBase::getAccessibleChild (sal_Int32 nIndex) 243*cdf0e10cSrcweir throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) 244*cdf0e10cSrcweir { 245*cdf0e10cSrcweir ThrowIfDisposed (); 246*cdf0e10cSrcweir throw lang::IndexOutOfBoundsException ( 247*cdf0e10cSrcweir ::rtl::OUString::createFromAscii ("no child with index " + nIndex), 248*cdf0e10cSrcweir NULL); 249*cdf0e10cSrcweir } 250*cdf0e10cSrcweir 251*cdf0e10cSrcweir 252*cdf0e10cSrcweir 253*cdf0e10cSrcweir 254*cdf0e10cSrcweir uno::Reference<XAccessible> SAL_CALL 255*cdf0e10cSrcweir AccessibleContextBase::getAccessibleParent (void) 256*cdf0e10cSrcweir throw (::com::sun::star::uno::RuntimeException) 257*cdf0e10cSrcweir { 258*cdf0e10cSrcweir ThrowIfDisposed (); 259*cdf0e10cSrcweir return mxParent; 260*cdf0e10cSrcweir } 261*cdf0e10cSrcweir 262*cdf0e10cSrcweir 263*cdf0e10cSrcweir 264*cdf0e10cSrcweir 265*cdf0e10cSrcweir sal_Int32 SAL_CALL 266*cdf0e10cSrcweir AccessibleContextBase::getAccessibleIndexInParent (void) 267*cdf0e10cSrcweir throw (::com::sun::star::uno::RuntimeException) 268*cdf0e10cSrcweir { 269*cdf0e10cSrcweir ThrowIfDisposed (); 270*cdf0e10cSrcweir // Use a simple but slow solution for now. Optimize later. 271*cdf0e10cSrcweir 272*cdf0e10cSrcweir // Iterate over all the parent's children and search for this object. 273*cdf0e10cSrcweir if (mxParent.is()) 274*cdf0e10cSrcweir { 275*cdf0e10cSrcweir uno::Reference<XAccessibleContext> xParentContext ( 276*cdf0e10cSrcweir mxParent->getAccessibleContext()); 277*cdf0e10cSrcweir if (xParentContext.is()) 278*cdf0e10cSrcweir { 279*cdf0e10cSrcweir sal_Int32 nChildCount = xParentContext->getAccessibleChildCount(); 280*cdf0e10cSrcweir for (sal_Int32 i=0; i<nChildCount; i++) 281*cdf0e10cSrcweir { 282*cdf0e10cSrcweir uno::Reference<XAccessible> xChild (xParentContext->getAccessibleChild (i)); 283*cdf0e10cSrcweir if (xChild.is()) 284*cdf0e10cSrcweir { 285*cdf0e10cSrcweir uno::Reference<XAccessibleContext> xChildContext = xChild->getAccessibleContext(); 286*cdf0e10cSrcweir if (xChildContext == (XAccessibleContext*)this) 287*cdf0e10cSrcweir return i; 288*cdf0e10cSrcweir } 289*cdf0e10cSrcweir } 290*cdf0e10cSrcweir } 291*cdf0e10cSrcweir } 292*cdf0e10cSrcweir 293*cdf0e10cSrcweir // Return -1 to indicate that this object's parent does not know about the 294*cdf0e10cSrcweir // object. 295*cdf0e10cSrcweir return -1; 296*cdf0e10cSrcweir } 297*cdf0e10cSrcweir 298*cdf0e10cSrcweir 299*cdf0e10cSrcweir 300*cdf0e10cSrcweir 301*cdf0e10cSrcweir sal_Int16 SAL_CALL 302*cdf0e10cSrcweir AccessibleContextBase::getAccessibleRole (void) 303*cdf0e10cSrcweir throw (::com::sun::star::uno::RuntimeException) 304*cdf0e10cSrcweir { 305*cdf0e10cSrcweir ThrowIfDisposed (); 306*cdf0e10cSrcweir return maRole; 307*cdf0e10cSrcweir } 308*cdf0e10cSrcweir 309*cdf0e10cSrcweir 310*cdf0e10cSrcweir 311*cdf0e10cSrcweir 312*cdf0e10cSrcweir ::rtl::OUString SAL_CALL 313*cdf0e10cSrcweir AccessibleContextBase::getAccessibleDescription (void) 314*cdf0e10cSrcweir throw (::com::sun::star::uno::RuntimeException) 315*cdf0e10cSrcweir { 316*cdf0e10cSrcweir ThrowIfDisposed (); 317*cdf0e10cSrcweir 318*cdf0e10cSrcweir return msDescription; 319*cdf0e10cSrcweir } 320*cdf0e10cSrcweir 321*cdf0e10cSrcweir 322*cdf0e10cSrcweir 323*cdf0e10cSrcweir 324*cdf0e10cSrcweir OUString SAL_CALL 325*cdf0e10cSrcweir AccessibleContextBase::getAccessibleName (void) 326*cdf0e10cSrcweir throw (::com::sun::star::uno::RuntimeException) 327*cdf0e10cSrcweir { 328*cdf0e10cSrcweir ThrowIfDisposed (); 329*cdf0e10cSrcweir 330*cdf0e10cSrcweir if (meNameOrigin == NotSet) 331*cdf0e10cSrcweir { 332*cdf0e10cSrcweir // Do not send an event because this is the first time it has been 333*cdf0e10cSrcweir // requested. 334*cdf0e10cSrcweir msName = CreateAccessibleName(); 335*cdf0e10cSrcweir meNameOrigin = AutomaticallyCreated; 336*cdf0e10cSrcweir } 337*cdf0e10cSrcweir 338*cdf0e10cSrcweir return msName; 339*cdf0e10cSrcweir } 340*cdf0e10cSrcweir 341*cdf0e10cSrcweir 342*cdf0e10cSrcweir 343*cdf0e10cSrcweir 344*cdf0e10cSrcweir /** Return a copy of the relation set. 345*cdf0e10cSrcweir */ 346*cdf0e10cSrcweir uno::Reference<XAccessibleRelationSet> SAL_CALL 347*cdf0e10cSrcweir AccessibleContextBase::getAccessibleRelationSet (void) 348*cdf0e10cSrcweir throw (::com::sun::star::uno::RuntimeException) 349*cdf0e10cSrcweir { 350*cdf0e10cSrcweir ThrowIfDisposed (); 351*cdf0e10cSrcweir 352*cdf0e10cSrcweir // Create a copy of the relation set and return it. 353*cdf0e10cSrcweir ::utl::AccessibleRelationSetHelper* pRelationSet = 354*cdf0e10cSrcweir static_cast< ::utl::AccessibleRelationSetHelper*>(mxRelationSet.get()); 355*cdf0e10cSrcweir if (pRelationSet != NULL) 356*cdf0e10cSrcweir { 357*cdf0e10cSrcweir return uno::Reference<XAccessibleRelationSet> ( 358*cdf0e10cSrcweir new ::utl::AccessibleRelationSetHelper (*pRelationSet)); 359*cdf0e10cSrcweir } 360*cdf0e10cSrcweir else 361*cdf0e10cSrcweir return uno::Reference<XAccessibleRelationSet>(NULL); 362*cdf0e10cSrcweir } 363*cdf0e10cSrcweir 364*cdf0e10cSrcweir 365*cdf0e10cSrcweir 366*cdf0e10cSrcweir 367*cdf0e10cSrcweir /** Return a copy of the state set. 368*cdf0e10cSrcweir Possible states are: 369*cdf0e10cSrcweir ENABLED 370*cdf0e10cSrcweir SHOWING 371*cdf0e10cSrcweir VISIBLE 372*cdf0e10cSrcweir */ 373*cdf0e10cSrcweir uno::Reference<XAccessibleStateSet> SAL_CALL 374*cdf0e10cSrcweir AccessibleContextBase::getAccessibleStateSet (void) 375*cdf0e10cSrcweir throw (::com::sun::star::uno::RuntimeException) 376*cdf0e10cSrcweir { 377*cdf0e10cSrcweir ::utl::AccessibleStateSetHelper* pStateSet = NULL; 378*cdf0e10cSrcweir 379*cdf0e10cSrcweir if (rBHelper.bDisposed) 380*cdf0e10cSrcweir { 381*cdf0e10cSrcweir // We are already disposed! 382*cdf0e10cSrcweir // Create a new state set that has only set the DEFUNC state. 383*cdf0e10cSrcweir pStateSet = new ::utl::AccessibleStateSetHelper (); 384*cdf0e10cSrcweir if (pStateSet != NULL) 385*cdf0e10cSrcweir pStateSet->AddState (AccessibleStateType::DEFUNC); 386*cdf0e10cSrcweir } 387*cdf0e10cSrcweir else 388*cdf0e10cSrcweir { 389*cdf0e10cSrcweir // Create a copy of the state set and return it. 390*cdf0e10cSrcweir pStateSet = static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get()); 391*cdf0e10cSrcweir 392*cdf0e10cSrcweir // Merge current focused state from edit engine. 393*cdf0e10cSrcweir #if 0 394*cdf0e10cSrcweir if (aState == AccessibleStateType::FOCUSED 395*cdf0e10cSrcweir && pStateSet != NULL 396*cdf0e10cSrcweir && mpText != NULL) 397*cdf0e10cSrcweir { 398*cdf0e10cSrcweir if (mpText->GetFocusedState ()) 399*cdf0e10cSrcweir pStateSet->AddState (aState); 400*cdf0e10cSrcweir else 401*cdf0e10cSrcweir pStateSet->RemoveState (aState); 402*cdf0e10cSrcweir } 403*cdf0e10cSrcweir #endif 404*cdf0e10cSrcweir if (pStateSet != NULL) 405*cdf0e10cSrcweir pStateSet = new ::utl::AccessibleStateSetHelper (*pStateSet); 406*cdf0e10cSrcweir } 407*cdf0e10cSrcweir 408*cdf0e10cSrcweir return uno::Reference<XAccessibleStateSet>(pStateSet); 409*cdf0e10cSrcweir } 410*cdf0e10cSrcweir 411*cdf0e10cSrcweir 412*cdf0e10cSrcweir 413*cdf0e10cSrcweir 414*cdf0e10cSrcweir lang::Locale SAL_CALL 415*cdf0e10cSrcweir AccessibleContextBase::getLocale (void) 416*cdf0e10cSrcweir throw (IllegalAccessibleComponentStateException, 417*cdf0e10cSrcweir ::com::sun::star::uno::RuntimeException) 418*cdf0e10cSrcweir { 419*cdf0e10cSrcweir ThrowIfDisposed (); 420*cdf0e10cSrcweir // Delegate request to parent. 421*cdf0e10cSrcweir if (mxParent.is()) 422*cdf0e10cSrcweir { 423*cdf0e10cSrcweir uno::Reference<XAccessibleContext> xParentContext ( 424*cdf0e10cSrcweir mxParent->getAccessibleContext()); 425*cdf0e10cSrcweir if (xParentContext.is()) 426*cdf0e10cSrcweir return xParentContext->getLocale (); 427*cdf0e10cSrcweir } 428*cdf0e10cSrcweir 429*cdf0e10cSrcweir // No locale and no parent. Therefore throw exception to indicate this 430*cdf0e10cSrcweir // cluelessness. 431*cdf0e10cSrcweir throw IllegalAccessibleComponentStateException (); 432*cdf0e10cSrcweir } 433*cdf0e10cSrcweir 434*cdf0e10cSrcweir 435*cdf0e10cSrcweir 436*cdf0e10cSrcweir 437*cdf0e10cSrcweir //===== XAccessibleEventListener ============================================ 438*cdf0e10cSrcweir 439*cdf0e10cSrcweir void SAL_CALL 440*cdf0e10cSrcweir AccessibleContextBase::addEventListener ( 441*cdf0e10cSrcweir const uno::Reference<XAccessibleEventListener >& rxListener) 442*cdf0e10cSrcweir throw (uno::RuntimeException) 443*cdf0e10cSrcweir { 444*cdf0e10cSrcweir if (rxListener.is()) 445*cdf0e10cSrcweir { 446*cdf0e10cSrcweir if (rBHelper.bDisposed || rBHelper.bInDispose) 447*cdf0e10cSrcweir { 448*cdf0e10cSrcweir uno::Reference<uno::XInterface> x ((lang::XComponent *)this, uno::UNO_QUERY); 449*cdf0e10cSrcweir rxListener->disposing (lang::EventObject (x)); 450*cdf0e10cSrcweir } 451*cdf0e10cSrcweir else 452*cdf0e10cSrcweir { 453*cdf0e10cSrcweir if (!mnClientId) 454*cdf0e10cSrcweir mnClientId = comphelper::AccessibleEventNotifier::registerClient( ); 455*cdf0e10cSrcweir comphelper::AccessibleEventNotifier::addEventListener( mnClientId, rxListener ); 456*cdf0e10cSrcweir } 457*cdf0e10cSrcweir } 458*cdf0e10cSrcweir } 459*cdf0e10cSrcweir 460*cdf0e10cSrcweir 461*cdf0e10cSrcweir 462*cdf0e10cSrcweir 463*cdf0e10cSrcweir void SAL_CALL 464*cdf0e10cSrcweir AccessibleContextBase::removeEventListener ( 465*cdf0e10cSrcweir const uno::Reference<XAccessibleEventListener >& rxListener ) 466*cdf0e10cSrcweir throw (uno::RuntimeException) 467*cdf0e10cSrcweir { 468*cdf0e10cSrcweir ThrowIfDisposed (); 469*cdf0e10cSrcweir if (rxListener.is()) 470*cdf0e10cSrcweir { 471*cdf0e10cSrcweir sal_Int32 nListenerCount = comphelper::AccessibleEventNotifier::removeEventListener( mnClientId, rxListener ); 472*cdf0e10cSrcweir if ( !nListenerCount ) 473*cdf0e10cSrcweir { 474*cdf0e10cSrcweir // no listeners anymore 475*cdf0e10cSrcweir // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client), 476*cdf0e10cSrcweir // and at least to us not firing any events anymore, in case somebody calls 477*cdf0e10cSrcweir // NotifyAccessibleEvent, again 478*cdf0e10cSrcweir comphelper::AccessibleEventNotifier::revokeClient( mnClientId ); 479*cdf0e10cSrcweir mnClientId = 0; 480*cdf0e10cSrcweir } 481*cdf0e10cSrcweir } 482*cdf0e10cSrcweir } 483*cdf0e10cSrcweir 484*cdf0e10cSrcweir 485*cdf0e10cSrcweir 486*cdf0e10cSrcweir 487*cdf0e10cSrcweir //===== XServiceInfo ======================================================== 488*cdf0e10cSrcweir 489*cdf0e10cSrcweir ::rtl::OUString SAL_CALL 490*cdf0e10cSrcweir AccessibleContextBase::getImplementationName (void) 491*cdf0e10cSrcweir throw (::com::sun::star::uno::RuntimeException) 492*cdf0e10cSrcweir { 493*cdf0e10cSrcweir ThrowIfDisposed (); 494*cdf0e10cSrcweir return OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleContextBase")); 495*cdf0e10cSrcweir } 496*cdf0e10cSrcweir 497*cdf0e10cSrcweir 498*cdf0e10cSrcweir 499*cdf0e10cSrcweir 500*cdf0e10cSrcweir sal_Bool SAL_CALL 501*cdf0e10cSrcweir AccessibleContextBase::supportsService (const OUString& sServiceName) 502*cdf0e10cSrcweir throw (::com::sun::star::uno::RuntimeException) 503*cdf0e10cSrcweir { 504*cdf0e10cSrcweir ThrowIfDisposed (); 505*cdf0e10cSrcweir // Iterate over all supported service names and return true if on of them 506*cdf0e10cSrcweir // matches the given name. 507*cdf0e10cSrcweir uno::Sequence< ::rtl::OUString> aSupportedServices ( 508*cdf0e10cSrcweir getSupportedServiceNames ()); 509*cdf0e10cSrcweir for (int i=0; i<aSupportedServices.getLength(); i++) 510*cdf0e10cSrcweir if (sServiceName == aSupportedServices[i]) 511*cdf0e10cSrcweir return sal_True; 512*cdf0e10cSrcweir return sal_False; 513*cdf0e10cSrcweir } 514*cdf0e10cSrcweir 515*cdf0e10cSrcweir 516*cdf0e10cSrcweir 517*cdf0e10cSrcweir 518*cdf0e10cSrcweir uno::Sequence< ::rtl::OUString> SAL_CALL 519*cdf0e10cSrcweir AccessibleContextBase::getSupportedServiceNames (void) 520*cdf0e10cSrcweir throw (::com::sun::star::uno::RuntimeException) 521*cdf0e10cSrcweir { 522*cdf0e10cSrcweir ThrowIfDisposed (); 523*cdf0e10cSrcweir static const OUString sServiceNames[2] = { 524*cdf0e10cSrcweir OUString(RTL_CONSTASCII_USTRINGPARAM( 525*cdf0e10cSrcweir "com.sun.star.accessibility.Accessible")), 526*cdf0e10cSrcweir OUString(RTL_CONSTASCII_USTRINGPARAM( 527*cdf0e10cSrcweir "com.sun.star.accessibility.AccessibleContext")) 528*cdf0e10cSrcweir }; 529*cdf0e10cSrcweir return uno::Sequence<OUString> (sServiceNames, 2); 530*cdf0e10cSrcweir } 531*cdf0e10cSrcweir 532*cdf0e10cSrcweir 533*cdf0e10cSrcweir 534*cdf0e10cSrcweir 535*cdf0e10cSrcweir //===== XTypeProvider ======================================================= 536*cdf0e10cSrcweir 537*cdf0e10cSrcweir uno::Sequence< ::com::sun::star::uno::Type> 538*cdf0e10cSrcweir AccessibleContextBase::getTypes (void) 539*cdf0e10cSrcweir throw (::com::sun::star::uno::RuntimeException) 540*cdf0e10cSrcweir { 541*cdf0e10cSrcweir ThrowIfDisposed (); 542*cdf0e10cSrcweir 543*cdf0e10cSrcweir // This class supports no interfaces on its own. Just return those 544*cdf0e10cSrcweir // supported by the base class. 545*cdf0e10cSrcweir return BaseClass::getTypes(); 546*cdf0e10cSrcweir } 547*cdf0e10cSrcweir 548*cdf0e10cSrcweir 549*cdf0e10cSrcweir 550*cdf0e10cSrcweir 551*cdf0e10cSrcweir uno::Sequence<sal_Int8> SAL_CALL 552*cdf0e10cSrcweir AccessibleContextBase::getImplementationId (void) 553*cdf0e10cSrcweir throw (::com::sun::star::uno::RuntimeException) 554*cdf0e10cSrcweir { 555*cdf0e10cSrcweir ThrowIfDisposed (); 556*cdf0e10cSrcweir static uno::Sequence<sal_Int8> aId; 557*cdf0e10cSrcweir if (aId.getLength() == 0) 558*cdf0e10cSrcweir { 559*cdf0e10cSrcweir ::osl::MutexGuard aGuard (maMutex); 560*cdf0e10cSrcweir aId.realloc (16); 561*cdf0e10cSrcweir rtl_createUuid ((sal_uInt8 *)aId.getArray(), 0, sal_True); 562*cdf0e10cSrcweir } 563*cdf0e10cSrcweir return aId; 564*cdf0e10cSrcweir } 565*cdf0e10cSrcweir 566*cdf0e10cSrcweir 567*cdf0e10cSrcweir 568*cdf0e10cSrcweir 569*cdf0e10cSrcweir //===== internal ============================================================ 570*cdf0e10cSrcweir 571*cdf0e10cSrcweir void SAL_CALL AccessibleContextBase::disposing (void) 572*cdf0e10cSrcweir { 573*cdf0e10cSrcweir SetState (AccessibleStateType::DEFUNC); 574*cdf0e10cSrcweir 575*cdf0e10cSrcweir ::osl::MutexGuard aGuard (maMutex); 576*cdf0e10cSrcweir 577*cdf0e10cSrcweir // Send a disposing to all listeners. 578*cdf0e10cSrcweir if ( mnClientId ) 579*cdf0e10cSrcweir { 580*cdf0e10cSrcweir comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( mnClientId, *this ); 581*cdf0e10cSrcweir mnClientId = 0; 582*cdf0e10cSrcweir } 583*cdf0e10cSrcweir } 584*cdf0e10cSrcweir 585*cdf0e10cSrcweir 586*cdf0e10cSrcweir 587*cdf0e10cSrcweir 588*cdf0e10cSrcweir void AccessibleContextBase::SetAccessibleDescription ( 589*cdf0e10cSrcweir const ::rtl::OUString& rDescription, 590*cdf0e10cSrcweir StringOrigin eDescriptionOrigin) 591*cdf0e10cSrcweir throw (uno::RuntimeException) 592*cdf0e10cSrcweir { 593*cdf0e10cSrcweir if (eDescriptionOrigin < meDescriptionOrigin 594*cdf0e10cSrcweir || (eDescriptionOrigin == meDescriptionOrigin && msDescription != rDescription)) 595*cdf0e10cSrcweir { 596*cdf0e10cSrcweir uno::Any aOldValue, aNewValue; 597*cdf0e10cSrcweir aOldValue <<= msDescription; 598*cdf0e10cSrcweir aNewValue <<= rDescription; 599*cdf0e10cSrcweir 600*cdf0e10cSrcweir msDescription = rDescription; 601*cdf0e10cSrcweir meDescriptionOrigin = eDescriptionOrigin; 602*cdf0e10cSrcweir 603*cdf0e10cSrcweir CommitChange( 604*cdf0e10cSrcweir AccessibleEventId::DESCRIPTION_CHANGED, 605*cdf0e10cSrcweir aNewValue, 606*cdf0e10cSrcweir aOldValue); 607*cdf0e10cSrcweir } 608*cdf0e10cSrcweir } 609*cdf0e10cSrcweir 610*cdf0e10cSrcweir 611*cdf0e10cSrcweir 612*cdf0e10cSrcweir 613*cdf0e10cSrcweir void AccessibleContextBase::SetAccessibleName ( 614*cdf0e10cSrcweir const ::rtl::OUString& rName, 615*cdf0e10cSrcweir StringOrigin eNameOrigin) 616*cdf0e10cSrcweir throw (uno::RuntimeException) 617*cdf0e10cSrcweir { 618*cdf0e10cSrcweir if (eNameOrigin < meNameOrigin 619*cdf0e10cSrcweir || (eNameOrigin == meNameOrigin && msName != rName)) 620*cdf0e10cSrcweir { 621*cdf0e10cSrcweir uno::Any aOldValue, aNewValue; 622*cdf0e10cSrcweir aOldValue <<= msName; 623*cdf0e10cSrcweir aNewValue <<= rName; 624*cdf0e10cSrcweir 625*cdf0e10cSrcweir msName = rName; 626*cdf0e10cSrcweir meNameOrigin = eNameOrigin; 627*cdf0e10cSrcweir 628*cdf0e10cSrcweir CommitChange( 629*cdf0e10cSrcweir AccessibleEventId::NAME_CHANGED, 630*cdf0e10cSrcweir aNewValue, 631*cdf0e10cSrcweir aOldValue); 632*cdf0e10cSrcweir } 633*cdf0e10cSrcweir } 634*cdf0e10cSrcweir 635*cdf0e10cSrcweir 636*cdf0e10cSrcweir 637*cdf0e10cSrcweir 638*cdf0e10cSrcweir ::rtl::OUString AccessibleContextBase::CreateAccessibleDescription (void) 639*cdf0e10cSrcweir throw (::com::sun::star::uno::RuntimeException) 640*cdf0e10cSrcweir { 641*cdf0e10cSrcweir return ::rtl::OUString::createFromAscii ("Empty Description"); 642*cdf0e10cSrcweir } 643*cdf0e10cSrcweir 644*cdf0e10cSrcweir 645*cdf0e10cSrcweir 646*cdf0e10cSrcweir 647*cdf0e10cSrcweir ::rtl::OUString AccessibleContextBase::CreateAccessibleName (void) 648*cdf0e10cSrcweir throw (::com::sun::star::uno::RuntimeException) 649*cdf0e10cSrcweir { 650*cdf0e10cSrcweir return ::rtl::OUString::createFromAscii ("Empty Name"); 651*cdf0e10cSrcweir } 652*cdf0e10cSrcweir 653*cdf0e10cSrcweir 654*cdf0e10cSrcweir 655*cdf0e10cSrcweir 656*cdf0e10cSrcweir void AccessibleContextBase::CommitChange ( 657*cdf0e10cSrcweir sal_Int16 nEventId, 658*cdf0e10cSrcweir const uno::Any& rNewValue, 659*cdf0e10cSrcweir const uno::Any& rOldValue) 660*cdf0e10cSrcweir { 661*cdf0e10cSrcweir // Do not call FireEvent and do not even create the event object when no 662*cdf0e10cSrcweir // listener has been registered yet. Creating the event object can 663*cdf0e10cSrcweir // otherwise lead to a crash. See issue 93419 for details. 664*cdf0e10cSrcweir if (mnClientId != 0) 665*cdf0e10cSrcweir { 666*cdf0e10cSrcweir AccessibleEventObject aEvent ( 667*cdf0e10cSrcweir static_cast<XAccessibleContext*>(this), 668*cdf0e10cSrcweir nEventId, 669*cdf0e10cSrcweir rNewValue, 670*cdf0e10cSrcweir rOldValue); 671*cdf0e10cSrcweir 672*cdf0e10cSrcweir FireEvent (aEvent); 673*cdf0e10cSrcweir } 674*cdf0e10cSrcweir } 675*cdf0e10cSrcweir 676*cdf0e10cSrcweir 677*cdf0e10cSrcweir 678*cdf0e10cSrcweir 679*cdf0e10cSrcweir void AccessibleContextBase::FireEvent (const AccessibleEventObject& aEvent) 680*cdf0e10cSrcweir { 681*cdf0e10cSrcweir if (mnClientId) 682*cdf0e10cSrcweir comphelper::AccessibleEventNotifier::addEvent( mnClientId, aEvent ); 683*cdf0e10cSrcweir } 684*cdf0e10cSrcweir 685*cdf0e10cSrcweir 686*cdf0e10cSrcweir 687*cdf0e10cSrcweir 688*cdf0e10cSrcweir void AccessibleContextBase::ThrowIfDisposed (void) 689*cdf0e10cSrcweir throw (::com::sun::star::lang::DisposedException) 690*cdf0e10cSrcweir { 691*cdf0e10cSrcweir if (rBHelper.bDisposed || rBHelper.bInDispose) 692*cdf0e10cSrcweir { 693*cdf0e10cSrcweir OSL_TRACE ("Calling disposed object. Throwing exception:"); 694*cdf0e10cSrcweir throw lang::DisposedException ( 695*cdf0e10cSrcweir OUString(RTL_CONSTASCII_USTRINGPARAM("object has been already disposed")), 696*cdf0e10cSrcweir static_cast<uno::XWeak*>(this)); 697*cdf0e10cSrcweir } 698*cdf0e10cSrcweir } 699*cdf0e10cSrcweir 700*cdf0e10cSrcweir 701*cdf0e10cSrcweir 702*cdf0e10cSrcweir sal_Bool AccessibleContextBase::IsDisposed (void) 703*cdf0e10cSrcweir { 704*cdf0e10cSrcweir return (rBHelper.bDisposed || rBHelper.bInDispose); 705*cdf0e10cSrcweir } 706*cdf0e10cSrcweir 707*cdf0e10cSrcweir 708*cdf0e10cSrcweir 709*cdf0e10cSrcweir void AccessibleContextBase::SetAccessibleRole( sal_Int16 _nRole ) 710*cdf0e10cSrcweir { 711*cdf0e10cSrcweir maRole = _nRole; 712*cdf0e10cSrcweir } 713*cdf0e10cSrcweir 714*cdf0e10cSrcweir 715*cdf0e10cSrcweir } // end of namespace accessibility 716