1323de322SAndrew Rist/************************************************************** 2cdf0e10cSrcweir * 3323de322SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4323de322SAndrew Rist * or more contributor license agreements. See the NOTICE file 5323de322SAndrew Rist * distributed with this work for additional information 6323de322SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7323de322SAndrew Rist * to you under the Apache License, Version 2.0 (the 8323de322SAndrew Rist * "License"); you may not use this file except in compliance 9323de322SAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11323de322SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13323de322SAndrew Rist * Unless required by applicable law or agreed to in writing, 14323de322SAndrew Rist * software distributed under the License is distributed on an 15323de322SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16323de322SAndrew Rist * KIND, either express or implied. See the License for the 17323de322SAndrew Rist * specific language governing permissions and limitations 18323de322SAndrew Rist * under the License. 19cdf0e10cSrcweir * 20323de322SAndrew Rist *************************************************************/ 21323de322SAndrew Rist 22323de322SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir// MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir#include "precompiled_vcl.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir#include "aqua/salinst.h" 28cdf0e10cSrcweir#include "aqua/saldata.hxx" 29cdf0e10cSrcweir 30cdf0e10cSrcweir#include "aqua/aqua11ywrapper.h" 31cdf0e10cSrcweir#include "aqua/aqua11ylistener.hxx" 32cdf0e10cSrcweir#include "aqua/aqua11yfactory.h" 33cdf0e10cSrcweir#include "aqua/aqua11yfocustracker.hxx" 34cdf0e10cSrcweir 35cdf0e10cSrcweir#include "aqua11yfocuslistener.hxx" 36cdf0e10cSrcweir#include "aqua11yactionwrapper.h" 37cdf0e10cSrcweir#include "aqua11ycomponentwrapper.h" 38cdf0e10cSrcweir#include "aqua11yselectionwrapper.h" 39cdf0e10cSrcweir#include "aqua11ytablewrapper.h" 40cdf0e10cSrcweir#include "aqua11ytextwrapper.h" 41cdf0e10cSrcweir#include "aqua11yvaluewrapper.h" 42cdf0e10cSrcweir#include "aqua11yrolehelper.h" 43cdf0e10cSrcweir 44cdf0e10cSrcweir#include <com/sun/star/accessibility/AccessibleRole.hpp> 45cdf0e10cSrcweir#include <com/sun/star/accessibility/AccessibleStateType.hpp> 46cdf0e10cSrcweir#include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp> 47cdf0e10cSrcweir#include <com/sun/star/awt/Size.hpp> 48cdf0e10cSrcweir#include <com/sun/star/accessibility/XAccessibleRelationSet.hpp> 49cdf0e10cSrcweir#include <com/sun/star/accessibility/AccessibleRelationType.hpp> 50cdf0e10cSrcweir#include <com/sun/star/lang/DisposedException.hpp> 51cdf0e10cSrcweir 52cdf0e10cSrcweirusing namespace ::com::sun::star::accessibility; 53cdf0e10cSrcweirusing namespace ::com::sun::star::awt; 54cdf0e10cSrcweirusing namespace ::com::sun::star::lang; 55cdf0e10cSrcweirusing namespace ::com::sun::star::uno; 56cdf0e10cSrcweir 57cdf0e10cSrcweir@interface SalFrameWindow : NSWindow 58cdf0e10cSrcweir{ 59cdf0e10cSrcweir} 60cdf0e10cSrcweir-(Reference<XAccessibleContext>)accessibleContext; 61cdf0e10cSrcweir@end 62cdf0e10cSrcweir 63cdf0e10cSrcweirstatic BOOL isPopupMenuOpen = NO; 64cdf0e10cSrcweir 65cdf0e10cSrcweir@implementation AquaA11yWrapper : NSView 66cdf0e10cSrcweir 67cdf0e10cSrcweir#pragma mark - 68cdf0e10cSrcweir#pragma mark Init and dealloc 69cdf0e10cSrcweir 70cdf0e10cSrcweir-(id)initWithAccessibleContext: (Reference < XAccessibleContext >) rxAccessibleContext { 71cdf0e10cSrcweir self = [ super init ]; 72cdf0e10cSrcweir if ( self != nil ) { 73cdf0e10cSrcweir [ self setDefaults: rxAccessibleContext ]; 74cdf0e10cSrcweir } 75cdf0e10cSrcweir return self; 76cdf0e10cSrcweir} 77cdf0e10cSrcweir 78cdf0e10cSrcweir-(void) setDefaults: (Reference < XAccessibleContext >) rxAccessibleContext { 79cdf0e10cSrcweir mDefaultFontsize = 0.0; 80cdf0e10cSrcweir mpDefaultFontname = nil; 81cdf0e10cSrcweir mpReferenceWrapper = new ReferenceWrapper; 82cdf0e10cSrcweir mActsAsRadioGroup = NO; 83cdf0e10cSrcweir mpReferenceWrapper -> rAccessibleContext = rxAccessibleContext; 84cdf0e10cSrcweir mIsTableCell = NO; 85cdf0e10cSrcweir // Querying all supported interfaces 86cdf0e10cSrcweir try { 87cdf0e10cSrcweir // XAccessibleComponent 88cdf0e10cSrcweir mpReferenceWrapper -> rAccessibleComponent = Reference < XAccessibleComponent > ( rxAccessibleContext, UNO_QUERY ); 89cdf0e10cSrcweir // XAccessibleExtendedComponent 90cdf0e10cSrcweir mpReferenceWrapper -> rAccessibleExtendedComponent = Reference < XAccessibleExtendedComponent > ( rxAccessibleContext, UNO_QUERY ); 91cdf0e10cSrcweir // XAccessibleSelection 92cdf0e10cSrcweir mpReferenceWrapper -> rAccessibleSelection = Reference< XAccessibleSelection > ( rxAccessibleContext, UNO_QUERY ); 93cdf0e10cSrcweir // XAccessibleTable 94cdf0e10cSrcweir mpReferenceWrapper -> rAccessibleTable = Reference < XAccessibleTable > ( rxAccessibleContext, UNO_QUERY ); 95cdf0e10cSrcweir // XAccessibleText 96cdf0e10cSrcweir mpReferenceWrapper -> rAccessibleText = Reference < XAccessibleText > ( rxAccessibleContext, UNO_QUERY ); 97cdf0e10cSrcweir // XAccessibleEditableText 98cdf0e10cSrcweir mpReferenceWrapper -> rAccessibleEditableText = Reference < XAccessibleEditableText > ( rxAccessibleContext, UNO_QUERY ); 99cdf0e10cSrcweir // XAccessibleValue 100cdf0e10cSrcweir mpReferenceWrapper -> rAccessibleValue = Reference < XAccessibleValue > ( rxAccessibleContext, UNO_QUERY ); 101cdf0e10cSrcweir // XAccessibleAction 102cdf0e10cSrcweir mpReferenceWrapper -> rAccessibleAction = Reference < XAccessibleAction > ( rxAccessibleContext, UNO_QUERY ); 103cdf0e10cSrcweir // XAccessibleTextAttributes 104cdf0e10cSrcweir mpReferenceWrapper -> rAccessibleTextAttributes = Reference < XAccessibleTextAttributes > ( rxAccessibleContext, UNO_QUERY ); 105cdf0e10cSrcweir // XAccessibleMultiLineText 106cdf0e10cSrcweir mpReferenceWrapper -> rAccessibleMultiLineText = Reference < XAccessibleMultiLineText > ( rxAccessibleContext, UNO_QUERY ); 107cdf0e10cSrcweir // XAccessibleEventBroadcaster 108cdf0e10cSrcweir #if 0 109cdf0e10cSrcweir /* #i102033# NSAccessibility does not seemt to know an equivalent for transient children. 110cdf0e10cSrcweir That means we need to cache this, else e.g. tree list boxes are not accessible (moreover 111cdf0e10cSrcweir it crashes by notifying dead objects - which would seemt o be another bug) 112cdf0e10cSrcweir 113cdf0e10cSrcweir FIXME: 114cdf0e10cSrcweir Unfortunately this can increase memory consumption drastically until the non transient parent 115cdf0e10cSrcweir is destroyed an finally all the transients are released. 116cdf0e10cSrcweir */ 117cdf0e10cSrcweir if ( ! rxAccessibleContext -> getAccessibleStateSet() -> contains ( AccessibleStateType::TRANSIENT ) ) 118cdf0e10cSrcweir #endif 119cdf0e10cSrcweir { 120cdf0e10cSrcweir Reference< XAccessibleEventBroadcaster > xBroadcaster(rxAccessibleContext, UNO_QUERY); 121cdf0e10cSrcweir if( xBroadcaster.is() ) { 122cdf0e10cSrcweir /* 123cdf0e10cSrcweir * We intentionally do not hold a reference to the event listener in the wrapper object, 124cdf0e10cSrcweir * but let the listener control the life cycle of the wrapper instead .. 125cdf0e10cSrcweir */ 126cdf0e10cSrcweir xBroadcaster->addEventListener( new AquaA11yEventListener( self, rxAccessibleContext -> getAccessibleRole() ) ); 127cdf0e10cSrcweir } 128cdf0e10cSrcweir } 129cdf0e10cSrcweir // TABLE_CELL 130cdf0e10cSrcweir if ( rxAccessibleContext -> getAccessibleRole() == AccessibleRole::TABLE_CELL ) { 131cdf0e10cSrcweir mIsTableCell = YES; 132cdf0e10cSrcweir } 133cdf0e10cSrcweir } catch ( const Exception ) { 134cdf0e10cSrcweir } 135cdf0e10cSrcweir} 136cdf0e10cSrcweir 137cdf0e10cSrcweir-(void)dealloc { 138cdf0e10cSrcweir if ( mpReferenceWrapper != nil ) { 139cdf0e10cSrcweir delete mpReferenceWrapper; 140cdf0e10cSrcweir } 141cdf0e10cSrcweir if ( mpDefaultFontname != nil ) { 142cdf0e10cSrcweir [ mpDefaultFontname release ]; 143cdf0e10cSrcweir } 144cdf0e10cSrcweir [ super dealloc ]; 145cdf0e10cSrcweir} 146cdf0e10cSrcweir 147cdf0e10cSrcweir#pragma mark - 148cdf0e10cSrcweir#pragma mark Utility Section 149cdf0e10cSrcweir 150cdf0e10cSrcweir// generates selectors for attribute name AXAttributeNameHere 151cdf0e10cSrcweir// (getter without parameter) attributeNameHereAttribute 152cdf0e10cSrcweir// (getter with parameter) attributeNameHereAttributeForParameter: 153cdf0e10cSrcweir// (setter) setAttributeNameHereAttributeForElement:to: 154cdf0e10cSrcweir-(SEL)selectorForAttribute:(NSString *)attribute asGetter:(BOOL)asGetter withGetterParameter:(BOOL)withGetterParameter { 155cdf0e10cSrcweir SEL selector = nil; 156cdf0e10cSrcweir NSAutoreleasePool * pool = [ [ NSAutoreleasePool alloc ] init ]; 157cdf0e10cSrcweir @try { 158cdf0e10cSrcweir // step 1: create method name from attribute name 159cdf0e10cSrcweir NSMutableString * methodName = [ NSMutableString string ]; 160cdf0e10cSrcweir if ( ! asGetter ) { 161cdf0e10cSrcweir [ methodName appendString: @"set" ]; 162cdf0e10cSrcweir } 163cdf0e10cSrcweir NSRange aRange = { 2, 1 }; 164cdf0e10cSrcweir NSString * firstChar = [ attribute substringWithRange: aRange ]; // drop leading "AX" and get first char 165cdf0e10cSrcweir if ( asGetter ) { 166cdf0e10cSrcweir [ methodName appendString: [ firstChar lowercaseString ] ]; 167cdf0e10cSrcweir } else { 168cdf0e10cSrcweir [ methodName appendString: firstChar ]; 169cdf0e10cSrcweir } 170cdf0e10cSrcweir [ methodName appendString: [ attribute substringFromIndex: 3 ] ]; // append rest of attribute name 171cdf0e10cSrcweir // append rest of method name 172cdf0e10cSrcweir [ methodName appendString: @"Attribute" ]; 173cdf0e10cSrcweir if ( ! asGetter ) { 174cdf0e10cSrcweir [ methodName appendString: @"ForElement:to:" ]; 175cdf0e10cSrcweir } else if ( asGetter && withGetterParameter ) { 176cdf0e10cSrcweir [ methodName appendString: @"ForParameter:" ]; 177cdf0e10cSrcweir } 178cdf0e10cSrcweir // step 2: create selector 179cdf0e10cSrcweir selector = NSSelectorFromString ( methodName ); 180cdf0e10cSrcweir } @catch ( id exception ) { 181cdf0e10cSrcweir selector = nil; 182cdf0e10cSrcweir } 183cdf0e10cSrcweir [ pool release ]; 184cdf0e10cSrcweir return selector; 185cdf0e10cSrcweir} 186cdf0e10cSrcweir 187cdf0e10cSrcweir-(Reference < XAccessible >)getFirstRadioButtonInGroup { 188cdf0e10cSrcweir Reference < XAccessibleRelationSet > rxAccessibleRelationSet = [ self accessibleContext ] -> getAccessibleRelationSet(); 189cdf0e10cSrcweir if( rxAccessibleRelationSet.is() ) 190cdf0e10cSrcweir { 191cdf0e10cSrcweir AccessibleRelation relationMemberOf = rxAccessibleRelationSet -> getRelationByType ( AccessibleRelationType::MEMBER_OF ); 192cdf0e10cSrcweir if ( relationMemberOf.RelationType == AccessibleRelationType::MEMBER_OF && relationMemberOf.TargetSet.hasElements() ) 193cdf0e10cSrcweir return Reference < XAccessible > ( relationMemberOf.TargetSet[0], UNO_QUERY ); 194cdf0e10cSrcweir } 195cdf0e10cSrcweir return Reference < XAccessible > (); 196cdf0e10cSrcweir} 197cdf0e10cSrcweir 198cdf0e10cSrcweir-(BOOL)isFirstRadioButtonInGroup { 199cdf0e10cSrcweir Reference < XAccessible > rFirstMateAccessible = [ self getFirstRadioButtonInGroup ]; 200cdf0e10cSrcweir if ( rFirstMateAccessible.is() && rFirstMateAccessible -> getAccessibleContext().get() == [ self accessibleContext ] ) { 201cdf0e10cSrcweir return YES; 202cdf0e10cSrcweir } 203cdf0e10cSrcweir return NO; 204cdf0e10cSrcweir} 205cdf0e10cSrcweir 206cdf0e10cSrcweir#pragma mark - 207cdf0e10cSrcweir#pragma mark Attribute Value Getters 208cdf0e10cSrcweir// ( called via Reflection by accessibilityAttributeValue ) 209cdf0e10cSrcweir 210cdf0e10cSrcweir/* 211cdf0e10cSrcweir Radiobutton grouping is done differently in NSAccessibility and the UNO-API. In UNO related radio buttons share an entry in their 212cdf0e10cSrcweir RelationSet. In NSAccessibility the relationship is axpressed through the hierarchy. A AXRadioGroup contains two or more AXRadioButton 213cdf0e10cSrcweir objects. Since this group is not available in the UNO hierarchy, an extra wrapper is used for it. This wrapper shares almost all 214cdf0e10cSrcweir attributes with the first radio button of the group, except for the role, subrole, role description, parent and children attributes. 215cdf0e10cSrcweir So in this five methods there is a special treatment for radio buttons and groups. 216cdf0e10cSrcweir*/ 217cdf0e10cSrcweir 218cdf0e10cSrcweir-(id)roleAttribute { 219cdf0e10cSrcweir if ( mActsAsRadioGroup ) { 220cdf0e10cSrcweir return NSAccessibilityRadioGroupRole; 221cdf0e10cSrcweir } 222cdf0e10cSrcweir else { 223cdf0e10cSrcweir return [ AquaA11yRoleHelper getNativeRoleFrom: [ self accessibleContext ] ]; 224cdf0e10cSrcweir } 225cdf0e10cSrcweir} 226cdf0e10cSrcweir 227cdf0e10cSrcweir-(id)subroleAttribute { 228cdf0e10cSrcweir if ( mActsAsRadioGroup ) { 229cdf0e10cSrcweir return @""; 230cdf0e10cSrcweir } else { 231cdf0e10cSrcweir NSString * subRole = [ AquaA11yRoleHelper getNativeSubroleFrom: [ self accessibleContext ] -> getAccessibleRole() ]; 232cdf0e10cSrcweir if ( ! [ subRole isEqualToString: @"" ] ) { 233cdf0e10cSrcweir return subRole; 234cdf0e10cSrcweir } else { 235cdf0e10cSrcweir [ subRole release ]; 236cdf0e10cSrcweir return [ super accessibilityAttributeValue: NSAccessibilitySubroleAttribute ]; 237cdf0e10cSrcweir } 238cdf0e10cSrcweir } 239cdf0e10cSrcweir} 240cdf0e10cSrcweir 241cdf0e10cSrcweir-(id)titleAttribute { 242cdf0e10cSrcweir return CreateNSString ( [ self accessibleContext ] -> getAccessibleName() ); 243cdf0e10cSrcweir} 244cdf0e10cSrcweir 245cdf0e10cSrcweir-(id)descriptionAttribute { 246cdf0e10cSrcweir if ( [ self accessibleContext ] -> getAccessibleRole() == AccessibleRole::COMBO_BOX ) { 247cdf0e10cSrcweir return [ self titleAttribute ]; 248cdf0e10cSrcweir } else if ( [ self accessibleExtendedComponent ] != nil ) { 249cdf0e10cSrcweir return [ AquaA11yComponentWrapper descriptionAttributeForElement: self ]; 250cdf0e10cSrcweir } else { 251cdf0e10cSrcweir return CreateNSString ( [ self accessibleContext ] -> getAccessibleDescription() ); 252cdf0e10cSrcweir } 253cdf0e10cSrcweir} 254cdf0e10cSrcweir 255cdf0e10cSrcweir-(id)enabledAttribute { 256cdf0e10cSrcweir if ( [ self accessibleContext ] -> getAccessibleStateSet().is() ) { 257cdf0e10cSrcweir return [ NSNumber numberWithBool: [ self accessibleContext ] -> getAccessibleStateSet() -> contains ( AccessibleStateType::ENABLED ) ]; 258cdf0e10cSrcweir } else { 259cdf0e10cSrcweir return nil; 260cdf0e10cSrcweir } 261cdf0e10cSrcweir} 262cdf0e10cSrcweir 263cdf0e10cSrcweir-(id)focusedAttribute { 264cdf0e10cSrcweir if ( [ self accessibleContext ] -> getAccessibleRole() == AccessibleRole::COMBO_BOX ) { 265cdf0e10cSrcweir id isFocused = nil; 266cdf0e10cSrcweir Reference < XAccessible > rxParent = [ self accessibleContext ] -> getAccessibleParent(); 267cdf0e10cSrcweir if ( rxParent.is() ) { 268cdf0e10cSrcweir Reference < XAccessibleContext > rxContext = rxParent -> getAccessibleContext(); 269cdf0e10cSrcweir if ( rxContext.is() && rxContext -> getAccessibleStateSet().is() ) { 270cdf0e10cSrcweir isFocused = [ NSNumber numberWithBool: rxContext -> getAccessibleStateSet() -> contains ( AccessibleStateType::FOCUSED ) ]; 271cdf0e10cSrcweir } 272cdf0e10cSrcweir } 273cdf0e10cSrcweir return isFocused; 274cdf0e10cSrcweir } else if ( [ self accessibleContext ] -> getAccessibleStateSet().is() ) { 275cdf0e10cSrcweir return [ NSNumber numberWithBool: [ self accessibleContext ] -> getAccessibleStateSet() -> contains ( AccessibleStateType::FOCUSED ) ]; 276cdf0e10cSrcweir } else { 277cdf0e10cSrcweir return nil; 278cdf0e10cSrcweir } 279cdf0e10cSrcweir} 280cdf0e10cSrcweir 281cdf0e10cSrcweir-(id)parentAttribute { 282cdf0e10cSrcweir if ( [ self accessibleContext ] -> getAccessibleRole() == AccessibleRole::RADIO_BUTTON && ! mActsAsRadioGroup ) { 283cdf0e10cSrcweir Reference < XAccessible > rxAccessible = [ self getFirstRadioButtonInGroup ]; 284cdf0e10cSrcweir if ( rxAccessible.is() && rxAccessible -> getAccessibleContext().is() ) { 285cdf0e10cSrcweir Reference < XAccessibleContext > rxAccessibleContext = rxAccessible -> getAccessibleContext(); 286cdf0e10cSrcweir id parent_wrapper = [ AquaA11yFactory wrapperForAccessibleContext: rxAccessibleContext createIfNotExists: YES asRadioGroup: YES ]; 287cdf0e10cSrcweir [ parent_wrapper autorelease ]; 288cdf0e10cSrcweir return NSAccessibilityUnignoredAncestor( parent_wrapper ); 289cdf0e10cSrcweir } 290cdf0e10cSrcweir return nil; 291cdf0e10cSrcweir } 292cdf0e10cSrcweir try { 293cdf0e10cSrcweir Reference< XAccessible > xParent( [ self accessibleContext ] -> getAccessibleParent() ); 294cdf0e10cSrcweir if ( xParent.is() ) { 295cdf0e10cSrcweir Reference< XAccessibleContext > xContext( xParent -> getAccessibleContext() ); 296cdf0e10cSrcweir if ( xContext.is() ) { 297cdf0e10cSrcweir id parent_wrapper = [ AquaA11yFactory wrapperForAccessibleContext: xContext ]; 298cdf0e10cSrcweir [ parent_wrapper autorelease ]; 299cdf0e10cSrcweir return NSAccessibilityUnignoredAncestor( parent_wrapper ); 300cdf0e10cSrcweir } 301cdf0e10cSrcweir } 302cdf0e10cSrcweir } catch (const Exception&) { 303cdf0e10cSrcweir } 304cdf0e10cSrcweir 305cdf0e10cSrcweir OSL_ASSERT( 0 ); 306cdf0e10cSrcweir return nil; 307cdf0e10cSrcweir} 308cdf0e10cSrcweir 309cdf0e10cSrcweir-(id)childrenAttribute { 310cdf0e10cSrcweir if ( mActsAsRadioGroup ) { 311cdf0e10cSrcweir NSMutableArray * children = [ [ NSMutableArray alloc ] init ]; 312cdf0e10cSrcweir Reference < XAccessibleRelationSet > rxAccessibleRelationSet = [ self accessibleContext ] -> getAccessibleRelationSet(); 313cdf0e10cSrcweir AccessibleRelation relationMemberOf = rxAccessibleRelationSet -> getRelationByType ( AccessibleRelationType::MEMBER_OF ); 314cdf0e10cSrcweir if ( relationMemberOf.RelationType == AccessibleRelationType::MEMBER_OF && relationMemberOf.TargetSet.hasElements() ) { 315cdf0e10cSrcweir for ( int index = 0; index < relationMemberOf.TargetSet.getLength(); index++ ) { 316cdf0e10cSrcweir Reference < XAccessible > rMateAccessible = Reference < XAccessible > ( relationMemberOf.TargetSet[index], UNO_QUERY ); 317cdf0e10cSrcweir if ( rMateAccessible.is() ) { 318cdf0e10cSrcweir Reference< XAccessibleContext > rMateAccessibleContext( rMateAccessible -> getAccessibleContext() ); 319cdf0e10cSrcweir if ( rMateAccessibleContext.is() ) { 320cdf0e10cSrcweir id wrapper = [ AquaA11yFactory wrapperForAccessibleContext: rMateAccessibleContext ]; 321cdf0e10cSrcweir [ children addObject: wrapper ]; 322cdf0e10cSrcweir [ wrapper release ]; 323cdf0e10cSrcweir } 324cdf0e10cSrcweir } 325cdf0e10cSrcweir } 326cdf0e10cSrcweir } 327cdf0e10cSrcweir return children; 328cdf0e10cSrcweir } else if ( [ self accessibleTable ] != nil ) 329cdf0e10cSrcweir { 330cdf0e10cSrcweir AquaA11yTableWrapper* pTable = [self isKindOfClass: [AquaA11yTableWrapper class]] ? (AquaA11yTableWrapper*)self : nil; 331cdf0e10cSrcweir return [ AquaA11yTableWrapper childrenAttributeForElement: pTable ]; 332cdf0e10cSrcweir } else { 333cdf0e10cSrcweir try { 334cdf0e10cSrcweir NSMutableArray * children = [ [ NSMutableArray alloc ] init ]; 335cdf0e10cSrcweir Reference< XAccessibleContext > xContext( [ self accessibleContext ] ); 336cdf0e10cSrcweir 337cdf0e10cSrcweir sal_Int32 cnt = xContext -> getAccessibleChildCount(); 338cdf0e10cSrcweir for ( sal_Int32 i = 0; i < cnt; i++ ) { 339cdf0e10cSrcweir Reference< XAccessible > xChild( xContext -> getAccessibleChild( i ) ); 340cdf0e10cSrcweir if( xChild.is() ) { 341cdf0e10cSrcweir Reference< XAccessibleContext > xChildContext( xChild -> getAccessibleContext() ); 342cdf0e10cSrcweir // the menubar is already accessible (including Apple- and Application-Menu) through NSApplication => omit it here 343cdf0e10cSrcweir if ( xChildContext.is() && AccessibleRole::MENU_BAR != xChildContext -> getAccessibleRole() ) { 344cdf0e10cSrcweir id wrapper = [ AquaA11yFactory wrapperForAccessibleContext: xChildContext ]; 345cdf0e10cSrcweir [ children addObject: wrapper ]; 346cdf0e10cSrcweir [ wrapper release ]; 347cdf0e10cSrcweir } 348cdf0e10cSrcweir } 349cdf0e10cSrcweir } 350cdf0e10cSrcweir 351cdf0e10cSrcweir // if not already acting as RadioGroup now is the time to replace RadioButtons with RadioGroups and remove RadioButtons 352cdf0e10cSrcweir if ( ! mActsAsRadioGroup ) { 353cdf0e10cSrcweir NSEnumerator * enumerator = [ children objectEnumerator ]; 354cdf0e10cSrcweir AquaA11yWrapper * element; 355cdf0e10cSrcweir while ( ( element = ( (AquaA11yWrapper *) [ enumerator nextObject ] ) ) ) { 356cdf0e10cSrcweir if ( [ element accessibleContext ] -> getAccessibleRole() == AccessibleRole::RADIO_BUTTON ) { 357cdf0e10cSrcweir if ( [ element isFirstRadioButtonInGroup ] ) { 358cdf0e10cSrcweir id wrapper = [ AquaA11yFactory wrapperForAccessibleContext: [ element accessibleContext ] createIfNotExists: YES asRadioGroup: YES ]; 359cdf0e10cSrcweir [ children replaceObjectAtIndex: [ children indexOfObjectIdenticalTo: element ] withObject: wrapper ]; 360cdf0e10cSrcweir } 361cdf0e10cSrcweir [ children removeObject: element ]; 362cdf0e10cSrcweir } 363cdf0e10cSrcweir } 364cdf0e10cSrcweir } 365cdf0e10cSrcweir 366cdf0e10cSrcweir [ children autorelease ]; 367cdf0e10cSrcweir return NSAccessibilityUnignoredChildren( children ); 368cdf0e10cSrcweir } catch (const Exception &e) { 369cdf0e10cSrcweir // TODO: Log 370cdf0e10cSrcweir return nil; 371cdf0e10cSrcweir } 372cdf0e10cSrcweir } 373cdf0e10cSrcweir} 374cdf0e10cSrcweir 375cdf0e10cSrcweir-(id)windowAttribute { 376cdf0e10cSrcweir // go upstairs until reaching the broken connection 377cdf0e10cSrcweir AquaA11yWrapper * aWrapper = self; 378cdf0e10cSrcweir while ( [ aWrapper accessibleContext ] -> getAccessibleParent().is() ) { 379cdf0e10cSrcweir aWrapper = [ AquaA11yFactory wrapperForAccessibleContext: [ aWrapper accessibleContext ] -> getAccessibleParent() -> getAccessibleContext() ]; 380cdf0e10cSrcweir [ aWrapper autorelease ]; 381cdf0e10cSrcweir } 382cdf0e10cSrcweir // get associated NSWindow 38397dacec1SHerbert Dürr NSWindow* theWindow = [ aWrapper windowForParent ]; 38497dacec1SHerbert Dürr return theWindow; 385cdf0e10cSrcweir} 386cdf0e10cSrcweir 387cdf0e10cSrcweir-(id)topLevelUIElementAttribute { 388cdf0e10cSrcweir return [ self windowAttribute ]; 389cdf0e10cSrcweir} 390cdf0e10cSrcweir 391cdf0e10cSrcweir-(id)sizeAttribute { 392cdf0e10cSrcweir if ( [ self accessibleComponent ] != nil ) { 393cdf0e10cSrcweir return [ AquaA11yComponentWrapper sizeAttributeForElement: self ]; 394cdf0e10cSrcweir } else { 395cdf0e10cSrcweir return nil; 396cdf0e10cSrcweir } 397cdf0e10cSrcweir} 398cdf0e10cSrcweir 399cdf0e10cSrcweir-(id)positionAttribute { 400cdf0e10cSrcweir if ( [ self accessibleComponent ] != nil ) { 401cdf0e10cSrcweir return [ AquaA11yComponentWrapper positionAttributeForElement: self ]; 402cdf0e10cSrcweir } else { 403cdf0e10cSrcweir return nil; 404cdf0e10cSrcweir } 405cdf0e10cSrcweir} 406cdf0e10cSrcweir 407cdf0e10cSrcweir-(id)helpAttribute { 408cdf0e10cSrcweir return CreateNSString ( [ self accessibleContext ] -> getAccessibleDescription() ); 409cdf0e10cSrcweir} 410cdf0e10cSrcweir 411cdf0e10cSrcweir-(id)roleDescriptionAttribute { 412cdf0e10cSrcweir if ( mActsAsRadioGroup ) { 413cdf0e10cSrcweir return [ AquaA11yRoleHelper getRoleDescriptionFrom: NSAccessibilityRadioGroupRole with: @"" ]; 414cdf0e10cSrcweir } else if( [ self accessibleContext ] -> getAccessibleRole() == AccessibleRole::RADIO_BUTTON ) { 415cdf0e10cSrcweir // FIXME: VO should read this because of hierarchy, this is just a workaround 416cdf0e10cSrcweir // get parent and its children 417cdf0e10cSrcweir AquaA11yWrapper * parent = [ self parentAttribute ]; 418cdf0e10cSrcweir NSArray * children = [ parent childrenAttribute ]; 419cdf0e10cSrcweir // find index of self 420cdf0e10cSrcweir int index = 1; 421cdf0e10cSrcweir NSEnumerator * enumerator = [ children objectEnumerator ]; 422cdf0e10cSrcweir AquaA11yWrapper * child = nil; 423cdf0e10cSrcweir while ( ( child = [ enumerator nextObject ] ) ) { 424cdf0e10cSrcweir if ( self == child ) { 425cdf0e10cSrcweir break; 426cdf0e10cSrcweir } 427cdf0e10cSrcweir index++; 428cdf0e10cSrcweir } 429cdf0e10cSrcweir // build string 430cdf0e10cSrcweir NSNumber * nIndex = [ NSNumber numberWithInt: index ]; 431cdf0e10cSrcweir NSNumber * nGroupsize = [ NSNumber numberWithInt: [ children count ] ]; 432cdf0e10cSrcweir NSMutableString * value = [ [ NSMutableString alloc ] init ]; 433cdf0e10cSrcweir [ value appendString: @"radio button " ]; 434cdf0e10cSrcweir [ value appendString: [ nIndex stringValue ] ]; 435cdf0e10cSrcweir [ value appendString: @" of " ]; 436cdf0e10cSrcweir [ value appendString: [ nGroupsize stringValue ] ]; 437cdf0e10cSrcweir // clean up and return string 438cdf0e10cSrcweir [ nIndex release ]; 439cdf0e10cSrcweir [ nGroupsize release ]; 440cdf0e10cSrcweir [ children release ]; 441cdf0e10cSrcweir return value; 442cdf0e10cSrcweir } else { 443cdf0e10cSrcweir return [ AquaA11yRoleHelper getRoleDescriptionFrom: 444cdf0e10cSrcweir [ AquaA11yRoleHelper getNativeRoleFrom: [ self accessibleContext ] ] 445cdf0e10cSrcweir with: [ AquaA11yRoleHelper getNativeSubroleFrom: [ self accessibleContext ] -> getAccessibleRole() ] ]; 446cdf0e10cSrcweir } 447cdf0e10cSrcweir} 448cdf0e10cSrcweir 449cdf0e10cSrcweir-(id)valueAttribute { 450cdf0e10cSrcweir if ( [ [ self roleAttribute ] isEqualToString: NSAccessibilityMenuItemRole ] ) { 451cdf0e10cSrcweir return nil; 452cdf0e10cSrcweir } else if ( [ self accessibleText ] != nil ) { 453cdf0e10cSrcweir return [ AquaA11yTextWrapper valueAttributeForElement: self ]; 454cdf0e10cSrcweir } else if ( [ self accessibleValue ] != nil ) { 455cdf0e10cSrcweir return [ AquaA11yValueWrapper valueAttributeForElement: self ]; 456cdf0e10cSrcweir } else { 457cdf0e10cSrcweir return nil; 458cdf0e10cSrcweir } 459cdf0e10cSrcweir} 460cdf0e10cSrcweir 461cdf0e10cSrcweir-(id)minValueAttribute { 462cdf0e10cSrcweir if ( [ self accessibleValue ] != nil ) { 463cdf0e10cSrcweir return [ AquaA11yValueWrapper minValueAttributeForElement: self ]; 464cdf0e10cSrcweir } else { 465cdf0e10cSrcweir return nil; 466cdf0e10cSrcweir } 467cdf0e10cSrcweir} 468cdf0e10cSrcweir 469cdf0e10cSrcweir-(id)maxValueAttribute { 470cdf0e10cSrcweir if ( [ self accessibleValue ] != nil ) { 471cdf0e10cSrcweir return [ AquaA11yValueWrapper maxValueAttributeForElement: self ]; 472cdf0e10cSrcweir } else { 473cdf0e10cSrcweir return nil; 474cdf0e10cSrcweir } 475cdf0e10cSrcweir} 476cdf0e10cSrcweir 477cdf0e10cSrcweir-(id)contentsAttribute { 478cdf0e10cSrcweir return [ self childrenAttribute ]; 479cdf0e10cSrcweir} 480cdf0e10cSrcweir 481cdf0e10cSrcweir-(id)selectedChildrenAttribute { 482cdf0e10cSrcweir return [ AquaA11ySelectionWrapper selectedChildrenAttributeForElement: self ]; 483cdf0e10cSrcweir} 484cdf0e10cSrcweir 485cdf0e10cSrcweir-(id)numberOfCharactersAttribute { 486cdf0e10cSrcweir if ( [ self accessibleText ] != nil ) { 487cdf0e10cSrcweir return [ AquaA11yTextWrapper numberOfCharactersAttributeForElement: self ]; 488cdf0e10cSrcweir } else { 489cdf0e10cSrcweir return nil; 490cdf0e10cSrcweir } 491cdf0e10cSrcweir} 492cdf0e10cSrcweir 493cdf0e10cSrcweir-(id)selectedTextAttribute { 494cdf0e10cSrcweir if ( [ self accessibleText ] != nil ) { 495cdf0e10cSrcweir return [ AquaA11yTextWrapper selectedTextAttributeForElement: self ]; 496cdf0e10cSrcweir } else { 497cdf0e10cSrcweir return nil; 498cdf0e10cSrcweir } 499cdf0e10cSrcweir} 500cdf0e10cSrcweir 501cdf0e10cSrcweir-(id)selectedTextRangeAttribute { 502cdf0e10cSrcweir if ( [ self accessibleText ] != nil ) { 503cdf0e10cSrcweir return [ AquaA11yTextWrapper selectedTextRangeAttributeForElement: self ]; 504cdf0e10cSrcweir } else { 505cdf0e10cSrcweir return nil; 506cdf0e10cSrcweir } 507cdf0e10cSrcweir} 508cdf0e10cSrcweir 509cdf0e10cSrcweir-(id)visibleCharacterRangeAttribute { 510cdf0e10cSrcweir if ( [ self accessibleText ] != nil ) { 511cdf0e10cSrcweir return [ AquaA11yTextWrapper visibleCharacterRangeAttributeForElement: self ]; 512cdf0e10cSrcweir } else { 513cdf0e10cSrcweir return nil; 514cdf0e10cSrcweir } 515cdf0e10cSrcweir} 516cdf0e10cSrcweir 517cdf0e10cSrcweir-(id)tabsAttribute { 518cdf0e10cSrcweir return self; // TODO ??? 519cdf0e10cSrcweir} 520cdf0e10cSrcweir 521cdf0e10cSrcweir-(id)sharedTextUIElementsAttribute { 522cdf0e10cSrcweir if ( [ self accessibleText ] != nil ) { 523cdf0e10cSrcweir return [ AquaA11yTextWrapper sharedTextUIElementsAttributeForElement: self ]; 524cdf0e10cSrcweir } else { 525cdf0e10cSrcweir return nil; 526cdf0e10cSrcweir } 527cdf0e10cSrcweir} 528cdf0e10cSrcweir 529cdf0e10cSrcweir-(id)sharedCharacterRangeAttribute { 530cdf0e10cSrcweir if ( [ self accessibleText ] != nil ) { 531cdf0e10cSrcweir return [ AquaA11yTextWrapper sharedCharacterRangeAttributeForElement: self ]; 532cdf0e10cSrcweir } else { 533cdf0e10cSrcweir return nil; 534cdf0e10cSrcweir } 535cdf0e10cSrcweir} 536cdf0e10cSrcweir 537cdf0e10cSrcweir-(id)expandedAttribute { 538cdf0e10cSrcweir return [ NSNumber numberWithBool: [ self accessibleContext ] -> getAccessibleStateSet() -> contains ( AccessibleStateType::EXPANDED ) ]; 539cdf0e10cSrcweir} 540cdf0e10cSrcweir 541cdf0e10cSrcweir-(id)selectedAttribute { 542cdf0e10cSrcweir return [ NSNumber numberWithBool: [ self accessibleContext ] -> getAccessibleStateSet() -> contains ( AccessibleStateType::SELECTED ) ]; 543cdf0e10cSrcweir} 544cdf0e10cSrcweir 545cdf0e10cSrcweir-(id)stringForRangeAttributeForParameter:(id)range { 546cdf0e10cSrcweir if ( [ self accessibleText ] != nil ) { 547cdf0e10cSrcweir return [ AquaA11yTextWrapper stringForRangeAttributeForElement: self forParameter: range ]; 548cdf0e10cSrcweir } else { 549cdf0e10cSrcweir return nil; 550cdf0e10cSrcweir } 551cdf0e10cSrcweir} 552cdf0e10cSrcweir 553cdf0e10cSrcweir-(id)attributedStringForRangeAttributeForParameter:(id)range { 554cdf0e10cSrcweir if ( [ self accessibleText ] != nil ) { 555cdf0e10cSrcweir return [ AquaA11yTextWrapper attributedStringForRangeAttributeForElement: self forParameter: range ]; 556cdf0e10cSrcweir } else { 557cdf0e10cSrcweir return nil; 558cdf0e10cSrcweir } 559cdf0e10cSrcweir} 560cdf0e10cSrcweir 561cdf0e10cSrcweir-(id)rangeForIndexAttributeForParameter:(id)index { 562cdf0e10cSrcweir if ( [ self accessibleText ] != nil ) { 563cdf0e10cSrcweir return [ AquaA11yTextWrapper rangeForIndexAttributeForElement: self forParameter: index ]; 564cdf0e10cSrcweir } else { 565cdf0e10cSrcweir return nil; 566cdf0e10cSrcweir } 567cdf0e10cSrcweir} 568cdf0e10cSrcweir 569cdf0e10cSrcweir-(id)rangeForPositionAttributeForParameter:(id)point { 570cdf0e10cSrcweir if ( [ self accessibleText ] != nil ) { 571cdf0e10cSrcweir return [ AquaA11yTextWrapper rangeForPositionAttributeForElement: self forParameter: point ]; 572cdf0e10cSrcweir } else { 573cdf0e10cSrcweir return nil; 574cdf0e10cSrcweir } 575cdf0e10cSrcweir} 576cdf0e10cSrcweir 577cdf0e10cSrcweir-(id)boundsForRangeAttributeForParameter:(id)range { 578cdf0e10cSrcweir if ( [ self accessibleText ] != nil ) { 579cdf0e10cSrcweir return [ AquaA11yTextWrapper boundsForRangeAttributeForElement: self forParameter: range ]; 580cdf0e10cSrcweir } else { 581cdf0e10cSrcweir return nil; 582cdf0e10cSrcweir } 583cdf0e10cSrcweir} 584cdf0e10cSrcweir 585cdf0e10cSrcweir-(id)styleRangeForIndexAttributeForParameter:(id)index { 586cdf0e10cSrcweir if ( [ self accessibleText ] != nil ) { 587cdf0e10cSrcweir return [ AquaA11yTextWrapper styleRangeForIndexAttributeForElement: self forParameter: index ]; 588cdf0e10cSrcweir } else { 589cdf0e10cSrcweir return nil; 590cdf0e10cSrcweir } 591cdf0e10cSrcweir} 592cdf0e10cSrcweir 593cdf0e10cSrcweir-(id)rTFForRangeAttributeForParameter:(id)range { 594cdf0e10cSrcweir if ( [ self accessibleText ] != nil ) { 595cdf0e10cSrcweir return [ AquaA11yTextWrapper rTFForRangeAttributeForElement: self forParameter: range ]; 596cdf0e10cSrcweir } else { 597cdf0e10cSrcweir return nil; 598cdf0e10cSrcweir } 599cdf0e10cSrcweir} 600cdf0e10cSrcweir 601cdf0e10cSrcweir-(id)orientationAttribute { 602cdf0e10cSrcweir NSString * orientation = nil; 603cdf0e10cSrcweir Reference < XAccessibleStateSet > stateSet = [ self accessibleContext ] -> getAccessibleStateSet(); 604cdf0e10cSrcweir if ( stateSet -> contains ( AccessibleStateType::HORIZONTAL ) ) { 605cdf0e10cSrcweir orientation = NSAccessibilityHorizontalOrientationValue; 606cdf0e10cSrcweir } else if ( stateSet -> contains ( AccessibleStateType::VERTICAL ) ) { 607cdf0e10cSrcweir orientation = NSAccessibilityVerticalOrientationValue; 608cdf0e10cSrcweir } 609cdf0e10cSrcweir return orientation; 610cdf0e10cSrcweir} 611cdf0e10cSrcweir 612cdf0e10cSrcweir-(id)titleUIElementAttribute { 613cdf0e10cSrcweir if ( [ self accessibleContext ] -> getAccessibleRelationSet().is() ) { 614cdf0e10cSrcweir NSString * title = [ self titleAttribute ]; 615cdf0e10cSrcweir id titleElement = nil; 616cdf0e10cSrcweir if ( [ title length ] == 0 ) { 617cdf0e10cSrcweir AccessibleRelation relationLabeledBy = [ self accessibleContext ] -> getAccessibleRelationSet() -> getRelationByType ( AccessibleRelationType::LABELED_BY ); 618cdf0e10cSrcweir if ( relationLabeledBy.RelationType == AccessibleRelationType::LABELED_BY && relationLabeledBy.TargetSet.hasElements() ) { 619cdf0e10cSrcweir Reference < XAccessible > rxAccessible ( relationLabeledBy.TargetSet[0], UNO_QUERY ); 620cdf0e10cSrcweir titleElement = [ AquaA11yFactory wrapperForAccessibleContext: rxAccessible -> getAccessibleContext() ]; 621cdf0e10cSrcweir } 622cdf0e10cSrcweir } 623cdf0e10cSrcweir if ( title != nil ) { 624cdf0e10cSrcweir [ title release ]; 625cdf0e10cSrcweir } 626cdf0e10cSrcweir return titleElement; 627cdf0e10cSrcweir } else { 628cdf0e10cSrcweir return nil; 629cdf0e10cSrcweir } 630cdf0e10cSrcweir} 631cdf0e10cSrcweir 632cdf0e10cSrcweir-(id)servesAsTitleForUIElementsAttribute { 633cdf0e10cSrcweir if ( [ self accessibleContext ] -> getAccessibleRelationSet().is() ) { 634cdf0e10cSrcweir id titleForElement = nil; 635cdf0e10cSrcweir AccessibleRelation relationLabelFor = [ self accessibleContext ] -> getAccessibleRelationSet() -> getRelationByType ( AccessibleRelationType::LABEL_FOR ); 636cdf0e10cSrcweir if ( relationLabelFor.RelationType == AccessibleRelationType::LABEL_FOR && relationLabelFor.TargetSet.hasElements() ) { 637cdf0e10cSrcweir Reference < XAccessible > rxAccessible ( relationLabelFor.TargetSet[0], UNO_QUERY ); 638cdf0e10cSrcweir titleForElement = [ AquaA11yFactory wrapperForAccessibleContext: rxAccessible -> getAccessibleContext() ]; 639cdf0e10cSrcweir } 640cdf0e10cSrcweir return titleForElement; 641cdf0e10cSrcweir } else { 642cdf0e10cSrcweir return nil; 643cdf0e10cSrcweir } 644cdf0e10cSrcweir} 645cdf0e10cSrcweir 646cdf0e10cSrcweir-(id)lineForIndexAttributeForParameter:(id)index { 647cdf0e10cSrcweir if ( [ self accessibleMultiLineText ] != nil ) { 648cdf0e10cSrcweir return [ AquaA11yTextWrapper lineForIndexAttributeForElement: self forParameter: index ]; 649cdf0e10cSrcweir } else { 650cdf0e10cSrcweir return nil; 651cdf0e10cSrcweir } 652cdf0e10cSrcweir} 653cdf0e10cSrcweir 654cdf0e10cSrcweir-(id)rangeForLineAttributeForParameter:(id)line { 655cdf0e10cSrcweir if ( [ self accessibleMultiLineText ] != nil ) { 656cdf0e10cSrcweir return [ AquaA11yTextWrapper rangeForLineAttributeForElement: self forParameter: line ]; 657cdf0e10cSrcweir } else { 658cdf0e10cSrcweir return nil; 659cdf0e10cSrcweir } 660cdf0e10cSrcweir} 661cdf0e10cSrcweir 662cdf0e10cSrcweir#pragma mark - 663cdf0e10cSrcweir#pragma mark Accessibility Protocol 664cdf0e10cSrcweir 665cdf0e10cSrcweir-(id)accessibilityAttributeValue:(NSString *)attribute { 666cdf0e10cSrcweir // #i90575# guard NSAccessibility protocol against unwanted access 667cdf0e10cSrcweir if ( isPopupMenuOpen ) { 668cdf0e10cSrcweir return nil; 669cdf0e10cSrcweir } 670cdf0e10cSrcweir 671cdf0e10cSrcweir id value = nil; 672cdf0e10cSrcweir // if we are no longer in the wrapper repository, we have been disposed 673cdf0e10cSrcweir AquaA11yWrapper * theWrapper = [ AquaA11yFactory wrapperForAccessibleContext: [ self accessibleContext ] createIfNotExists: NO ]; 674cdf0e10cSrcweir if ( theWrapper != nil || mIsTableCell ) { 675cdf0e10cSrcweir try { 676cdf0e10cSrcweir SEL methodSelector = [ self selectorForAttribute: attribute asGetter: YES withGetterParameter: NO ]; 677cdf0e10cSrcweir if ( [ self respondsToSelector: methodSelector ] ) { 678cdf0e10cSrcweir value = [ self performSelector: methodSelector ]; 679cdf0e10cSrcweir } 680cdf0e10cSrcweir } catch ( const DisposedException & e ) { 681cdf0e10cSrcweir mIsTableCell = NO; // just to be sure 682cdf0e10cSrcweir [ AquaA11yFactory removeFromWrapperRepositoryFor: [ self accessibleContext ] ]; 683cdf0e10cSrcweir return nil; 684cdf0e10cSrcweir } catch ( const Exception & e ) { 685cdf0e10cSrcweir // empty 686cdf0e10cSrcweir } 687cdf0e10cSrcweir } 688cdf0e10cSrcweir if ( theWrapper != nil ) { 689cdf0e10cSrcweir [ theWrapper release ]; // the above called method calls retain on the returned Wrapper 690cdf0e10cSrcweir } 691cdf0e10cSrcweir return value; 692cdf0e10cSrcweir} 693cdf0e10cSrcweir 694cdf0e10cSrcweir-(BOOL)accessibilityIsIgnored { 695cdf0e10cSrcweir // #i90575# guard NSAccessibility protocol against unwanted access 696cdf0e10cSrcweir if ( isPopupMenuOpen ) { 697*eae433d6SAndrea Pescetti return FALSE; 698cdf0e10cSrcweir } 699cdf0e10cSrcweir BOOL ignored = NO; 700cdf0e10cSrcweir sal_Int16 nRole = [ self accessibleContext ] -> getAccessibleRole(); 701cdf0e10cSrcweir switch ( nRole ) { 702cdf0e10cSrcweir case AccessibleRole::PANEL: 703cdf0e10cSrcweir case AccessibleRole::FRAME: 704cdf0e10cSrcweir case AccessibleRole::ROOT_PANE: 705cdf0e10cSrcweir case AccessibleRole::SEPARATOR: 706cdf0e10cSrcweir case AccessibleRole::FILLER: 707cdf0e10cSrcweir case AccessibleRole::DIALOG: 708cdf0e10cSrcweir ignored = YES; 709cdf0e10cSrcweir break; 710cdf0e10cSrcweir default: 711cdf0e10cSrcweir ignored = ! ( [ self accessibleContext ] -> getAccessibleStateSet() -> contains ( AccessibleStateType::VISIBLE ) ); 712cdf0e10cSrcweir break; 713cdf0e10cSrcweir } 714cdf0e10cSrcweir return ignored; // TODO: to be completed 715cdf0e10cSrcweir} 716cdf0e10cSrcweir 717cdf0e10cSrcweir-(NSArray *)accessibilityAttributeNames { 718cdf0e10cSrcweir // #i90575# guard NSAccessibility protocol against unwanted access 719cdf0e10cSrcweir if ( isPopupMenuOpen ) { 720cdf0e10cSrcweir return nil; 721cdf0e10cSrcweir } 722cdf0e10cSrcweir NSString * nativeSubrole = nil; 723cdf0e10cSrcweir NSString * title = nil; 724cdf0e10cSrcweir NSMutableArray * attributeNames = nil; 725cdf0e10cSrcweir sal_Int32 nAccessibleChildren = 0; 726cdf0e10cSrcweir try { 727cdf0e10cSrcweir // Default Attributes 728cdf0e10cSrcweir attributeNames = [ NSMutableArray arrayWithObjects: 729cdf0e10cSrcweir NSAccessibilityRoleAttribute, 730cdf0e10cSrcweir NSAccessibilityDescriptionAttribute, 731cdf0e10cSrcweir NSAccessibilityParentAttribute, 732cdf0e10cSrcweir NSAccessibilityWindowAttribute, 733cdf0e10cSrcweir NSAccessibilityHelpAttribute, 734cdf0e10cSrcweir NSAccessibilityTopLevelUIElementAttribute, 735cdf0e10cSrcweir NSAccessibilityRoleDescriptionAttribute, 736cdf0e10cSrcweir nil ]; 737cdf0e10cSrcweir nativeSubrole = (NSString *) [ AquaA11yRoleHelper getNativeSubroleFrom: [ self accessibleContext ] -> getAccessibleRole() ]; 738cdf0e10cSrcweir title = (NSString *) [ self titleAttribute ]; 739cdf0e10cSrcweir Reference < XAccessibleRelationSet > rxRelationSet = [ self accessibleContext ] -> getAccessibleRelationSet(); 740cdf0e10cSrcweir // Special Attributes depending on attribute values 741cdf0e10cSrcweir if ( nativeSubrole != nil && ! [ nativeSubrole isEqualToString: @"" ] ) { 742cdf0e10cSrcweir [ attributeNames addObject: NSAccessibilitySubroleAttribute ]; 743cdf0e10cSrcweir } 744cdf0e10cSrcweir try 745cdf0e10cSrcweir { 746cdf0e10cSrcweir nAccessibleChildren = [ self accessibleContext ] -> getAccessibleChildCount(); 747cdf0e10cSrcweir if ( nAccessibleChildren > 0 ) { 748cdf0e10cSrcweir [ attributeNames addObject: NSAccessibilityChildrenAttribute ]; 749cdf0e10cSrcweir } 750cdf0e10cSrcweir } 751cdf0e10cSrcweir catch( DisposedException& ) {} 752cdf0e10cSrcweir catch( RuntimeException& ) {} 753cdf0e10cSrcweir 754cdf0e10cSrcweir if ( title != nil && ! [ title isEqualToString: @"" ] ) { 755cdf0e10cSrcweir [ attributeNames addObject: NSAccessibilityTitleAttribute ]; 756cdf0e10cSrcweir } 757cdf0e10cSrcweir if ( [ title length ] == 0 && rxRelationSet.is() && rxRelationSet -> containsRelation ( AccessibleRelationType::LABELED_BY ) ) { 758cdf0e10cSrcweir [ attributeNames addObject: NSAccessibilityTitleUIElementAttribute ]; 759cdf0e10cSrcweir } 760cdf0e10cSrcweir if ( rxRelationSet.is() && rxRelationSet -> containsRelation ( AccessibleRelationType::LABEL_FOR ) ) { 761cdf0e10cSrcweir [ attributeNames addObject: NSAccessibilityServesAsTitleForUIElementsAttribute ]; 762cdf0e10cSrcweir } 763cdf0e10cSrcweir // Special Attributes depending on interface 764cdf0e10cSrcweir if( [self accessibleContext ] -> getAccessibleRole() == AccessibleRole::TABLE ) 765cdf0e10cSrcweir [AquaA11yTableWrapper addAttributeNamesTo: attributeNames object: self]; 766cdf0e10cSrcweir 767cdf0e10cSrcweir if ( [ self accessibleText ] != nil ) { 768cdf0e10cSrcweir [ AquaA11yTextWrapper addAttributeNamesTo: attributeNames ]; 769cdf0e10cSrcweir } 770cdf0e10cSrcweir if ( [ self accessibleComponent ] != nil ) { 771cdf0e10cSrcweir [ AquaA11yComponentWrapper addAttributeNamesTo: attributeNames ]; 772cdf0e10cSrcweir } 773cdf0e10cSrcweir if ( [ self accessibleSelection ] != nil ) { 774cdf0e10cSrcweir [ AquaA11ySelectionWrapper addAttributeNamesTo: attributeNames ]; 775cdf0e10cSrcweir } 776cdf0e10cSrcweir if ( [ self accessibleValue ] != nil ) { 777cdf0e10cSrcweir [ AquaA11yValueWrapper addAttributeNamesTo: attributeNames ]; 778cdf0e10cSrcweir } 779cdf0e10cSrcweir [ nativeSubrole release ]; 780cdf0e10cSrcweir [ title release ]; 781cdf0e10cSrcweir return attributeNames; 782cdf0e10cSrcweir } catch ( DisposedException & e ) { // Object is no longer available 783cdf0e10cSrcweir if ( nativeSubrole != nil ) { 784cdf0e10cSrcweir [ nativeSubrole release ]; 785cdf0e10cSrcweir } 786cdf0e10cSrcweir if ( title != nil ) { 787cdf0e10cSrcweir [ title release ]; 788cdf0e10cSrcweir } 789cdf0e10cSrcweir if ( attributeNames != nil ) { 790cdf0e10cSrcweir [ attributeNames release ]; 791cdf0e10cSrcweir } 792cdf0e10cSrcweir [ AquaA11yFactory removeFromWrapperRepositoryFor: [ self accessibleContext ] ]; 793cdf0e10cSrcweir return [ [ NSArray alloc ] init ]; 794cdf0e10cSrcweir } 795cdf0e10cSrcweir} 796cdf0e10cSrcweir 797cdf0e10cSrcweir-(BOOL)accessibilityIsAttributeSettable:(NSString *)attribute { 798cdf0e10cSrcweir BOOL isSettable = NO; 799cdf0e10cSrcweir if ( [ self accessibleText ] != nil ) { 800cdf0e10cSrcweir isSettable = [ AquaA11yTextWrapper isAttributeSettable: attribute forElement: self ]; 801cdf0e10cSrcweir } 802cdf0e10cSrcweir if ( ! isSettable && [ self accessibleComponent ] != nil ) { 803cdf0e10cSrcweir isSettable = [ AquaA11yComponentWrapper isAttributeSettable: attribute forElement: self ]; 804cdf0e10cSrcweir } 805cdf0e10cSrcweir if ( ! isSettable && [ self accessibleSelection ] != nil ) { 806cdf0e10cSrcweir isSettable = [ AquaA11ySelectionWrapper isAttributeSettable: attribute forElement: self ]; 807cdf0e10cSrcweir } 808cdf0e10cSrcweir if ( ! isSettable && [ self accessibleValue ] != nil ) { 809cdf0e10cSrcweir isSettable = [ AquaA11yValueWrapper isAttributeSettable: attribute forElement: self ]; 810cdf0e10cSrcweir } 811cdf0e10cSrcweir return isSettable; // TODO: to be completed 812cdf0e10cSrcweir} 813cdf0e10cSrcweir 814cdf0e10cSrcweir-(NSArray *)accessibilityParameterizedAttributeNames { 815cdf0e10cSrcweir NSMutableArray * attributeNames = [ [ NSMutableArray alloc ] init ]; 816cdf0e10cSrcweir // Special Attributes depending on interface 817cdf0e10cSrcweir if ( [ self accessibleText ] != nil ) { 818cdf0e10cSrcweir [ AquaA11yTextWrapper addParameterizedAttributeNamesTo: attributeNames ]; 819cdf0e10cSrcweir } 820cdf0e10cSrcweir return attributeNames; // TODO: to be completed 821cdf0e10cSrcweir} 822cdf0e10cSrcweir 823cdf0e10cSrcweir-(id)accessibilityAttributeValue:(NSString *)attribute forParameter:(id)parameter { 824cdf0e10cSrcweir SEL methodSelector = [ self selectorForAttribute: attribute asGetter: YES withGetterParameter: YES ]; 825cdf0e10cSrcweir if ( [ self respondsToSelector: methodSelector ] ) { 826cdf0e10cSrcweir return [ self performSelector: methodSelector withObject: parameter ]; 827cdf0e10cSrcweir } 828cdf0e10cSrcweir return nil; // TODO: to be completed 829cdf0e10cSrcweir} 830cdf0e10cSrcweir 831cdf0e10cSrcweir-(BOOL)accessibilitySetOverrideValue:(id)value forAttribute:(NSString *)attribute 832cdf0e10cSrcweir{ 833cdf0e10cSrcweir (void)value; 834cdf0e10cSrcweir (void)attribute; 835cdf0e10cSrcweir return NO; // TODO 836cdf0e10cSrcweir} 837cdf0e10cSrcweir 838cdf0e10cSrcweir-(void)accessibilitySetValue:(id)value forAttribute:(NSString *)attribute { 839cdf0e10cSrcweir SEL methodSelector = [ self selectorForAttribute: attribute asGetter: NO withGetterParameter: NO ]; 840cdf0e10cSrcweir if ( [ AquaA11yComponentWrapper respondsToSelector: methodSelector ] ) { 841cdf0e10cSrcweir [ AquaA11yComponentWrapper performSelector: methodSelector withObject: self withObject: value ]; 842cdf0e10cSrcweir } 843cdf0e10cSrcweir if ( [ AquaA11yTextWrapper respondsToSelector: methodSelector ] ) { 844cdf0e10cSrcweir [ AquaA11yTextWrapper performSelector: methodSelector withObject: self withObject: value ]; 845cdf0e10cSrcweir } 846cdf0e10cSrcweir if ( [ AquaA11ySelectionWrapper respondsToSelector: methodSelector ] ) { 847cdf0e10cSrcweir [ AquaA11ySelectionWrapper performSelector: methodSelector withObject: self withObject: value ]; 848cdf0e10cSrcweir } 849cdf0e10cSrcweir if ( [ AquaA11yValueWrapper respondsToSelector: methodSelector ] ) { 850cdf0e10cSrcweir [ AquaA11yValueWrapper performSelector: methodSelector withObject: self withObject: value ]; 851cdf0e10cSrcweir } 852cdf0e10cSrcweir} 853cdf0e10cSrcweir 854cdf0e10cSrcweir-(id)accessibilityFocusedUIElement { 855cdf0e10cSrcweir // #i90575# guard NSAccessibility protocol against unwanted access 856cdf0e10cSrcweir if ( isPopupMenuOpen ) { 857cdf0e10cSrcweir return nil; 858cdf0e10cSrcweir } 859cdf0e10cSrcweir 860cdf0e10cSrcweir // as this seems to be the first API call on a newly created SalFrameView object, 861cdf0e10cSrcweir // make sure self gets registered in the repository .. 862cdf0e10cSrcweir [ self accessibleContext ]; 863cdf0e10cSrcweir 864cdf0e10cSrcweir AquaA11yWrapper * focusedUIElement = AquaA11yFocusListener::get()->getFocusedUIElement(); 865cdf0e10cSrcweir// AquaA11yWrapper * ancestor = focusedUIElement; 866cdf0e10cSrcweir 867cdf0e10cSrcweir // Make sure the focused object is a descendant of self 868cdf0e10cSrcweir// do { 869cdf0e10cSrcweir// if( self == ancestor ) 870cdf0e10cSrcweir return focusedUIElement; 871cdf0e10cSrcweir 872cdf0e10cSrcweir// ancestor = [ ancestor accessibilityAttributeValue: NSAccessibilityParentAttribute ]; 873cdf0e10cSrcweir// } while( nil != ancestor ); 874cdf0e10cSrcweir 875cdf0e10cSrcweir return self; 876cdf0e10cSrcweir} 877cdf0e10cSrcweir 878cdf0e10cSrcweir// TODO: hard-coded like the role descriptions. is there a better way? 879cdf0e10cSrcweir-(NSString *)accessibilityActionDescription:(NSString *)action { 880cdf0e10cSrcweir if ( [ action isEqualToString: NSAccessibilityConfirmAction ] ) { 881cdf0e10cSrcweir return @"confirm"; 882cdf0e10cSrcweir } else if ( [ action isEqualToString: NSAccessibilityDecrementAction ] ) { 883cdf0e10cSrcweir return @"decrement"; 884cdf0e10cSrcweir } else if ( [ action isEqualToString: NSAccessibilityDeleteAction ] ) { 885cdf0e10cSrcweir return @"delete"; 886cdf0e10cSrcweir } else if ( [ action isEqualToString: NSAccessibilityIncrementAction ] ) { 887cdf0e10cSrcweir return @"increment"; 888cdf0e10cSrcweir } else if ( [ action isEqualToString: NSAccessibilityPickAction ] ) { 889cdf0e10cSrcweir return @"pick"; 890cdf0e10cSrcweir } else if ( [ action isEqualToString: NSAccessibilityPressAction ] ) { 891cdf0e10cSrcweir return @"press"; 892cdf0e10cSrcweir } else if ( [ action isEqualToString: NSAccessibilityCancelAction ] ) { 893cdf0e10cSrcweir return @"cancel"; 894cdf0e10cSrcweir } else if ( [ action isEqualToString: NSAccessibilityRaiseAction ] ) { 895cdf0e10cSrcweir return @"raise"; 896cdf0e10cSrcweir } else if ( [ action isEqualToString: NSAccessibilityShowMenuAction ] ) { 897cdf0e10cSrcweir return @"show menu"; 898cdf0e10cSrcweir } else { 899cdf0e10cSrcweir return [ NSString string ]; 900cdf0e10cSrcweir } 901cdf0e10cSrcweir} 902cdf0e10cSrcweir 903cdf0e10cSrcweir-(AquaA11yWrapper *)actionResponder { 904cdf0e10cSrcweir AquaA11yWrapper * wrapper = nil; 905cdf0e10cSrcweir // get some information 906cdf0e10cSrcweir NSString * role = (NSString *) [ self accessibilityAttributeValue: NSAccessibilityRoleAttribute ]; 907cdf0e10cSrcweir id enabledAttr = [ self enabledAttribute ]; 908cdf0e10cSrcweir BOOL enabled = [ enabledAttr boolValue ]; 909cdf0e10cSrcweir NSView * parent = (NSView *) [ self accessibilityAttributeValue: NSAccessibilityParentAttribute ]; 910cdf0e10cSrcweir AquaA11yWrapper * parentAsWrapper = nil; 911cdf0e10cSrcweir if ( [ parent isKindOfClass: [ AquaA11yWrapper class ] ] ) { 912cdf0e10cSrcweir parentAsWrapper = (AquaA11yWrapper *) parent; 913cdf0e10cSrcweir } 914cdf0e10cSrcweir NSString * parentRole = (NSString *) [ parent accessibilityAttributeValue: NSAccessibilityRoleAttribute ]; 915cdf0e10cSrcweir // if we are a textarea inside a combobox, then the combobox is the action responder 916cdf0e10cSrcweir if ( enabled 917cdf0e10cSrcweir && [ role isEqualToString: NSAccessibilityTextAreaRole ] 918cdf0e10cSrcweir && [ parentRole isEqualToString: NSAccessibilityComboBoxRole ] 919cdf0e10cSrcweir && parentAsWrapper != nil ) { 920cdf0e10cSrcweir wrapper = parentAsWrapper; 921cdf0e10cSrcweir } else if ( enabled && [ self accessibleAction ] != nil ) { 922cdf0e10cSrcweir wrapper = self ; 923cdf0e10cSrcweir } 924cdf0e10cSrcweir [ parentRole release ]; 925cdf0e10cSrcweir [ enabledAttr release ]; 926cdf0e10cSrcweir [ role release ]; 927cdf0e10cSrcweir return wrapper; 928cdf0e10cSrcweir} 929cdf0e10cSrcweir 930cdf0e10cSrcweir-(void)accessibilityPerformAction:(NSString *)action { 931cdf0e10cSrcweir AquaA11yWrapper * actionResponder = [ self actionResponder ]; 932cdf0e10cSrcweir if ( actionResponder != nil ) { 933cdf0e10cSrcweir [ AquaA11yActionWrapper doAction: action ofElement: actionResponder ]; 934cdf0e10cSrcweir } 935cdf0e10cSrcweir} 936cdf0e10cSrcweir 937cdf0e10cSrcweir-(NSArray *)accessibilityActionNames { 938cdf0e10cSrcweir NSArray * actionNames = nil; 939cdf0e10cSrcweir AquaA11yWrapper * actionResponder = [ self actionResponder ]; 940cdf0e10cSrcweir if ( actionResponder != nil ) { 941cdf0e10cSrcweir actionNames = [ AquaA11yActionWrapper actionNamesForElement: actionResponder ]; 942cdf0e10cSrcweir } else { 943cdf0e10cSrcweir actionNames = [ [ NSArray alloc ] init ]; 944cdf0e10cSrcweir } 945cdf0e10cSrcweir return actionNames; 946cdf0e10cSrcweir} 947cdf0e10cSrcweir 948cdf0e10cSrcweir#pragma mark - 949cdf0e10cSrcweir#pragma mark Hit Test 950cdf0e10cSrcweir 951cdf0e10cSrcweir-(BOOL)isViewElement:(NSObject *)viewElement hitByPoint:(NSPoint)point { 952cdf0e10cSrcweir BOOL hit = NO; 953cdf0e10cSrcweir NSAutoreleasePool * pool = [ [ NSAutoreleasePool alloc ] init ]; 954cdf0e10cSrcweir NSValue * position = [ viewElement accessibilityAttributeValue: NSAccessibilityPositionAttribute ]; 955cdf0e10cSrcweir NSValue * size = [ viewElement accessibilityAttributeValue: NSAccessibilitySizeAttribute ]; 956cdf0e10cSrcweir if ( position != nil && size != nil ) { 957cdf0e10cSrcweir float minX = [ position pointValue ].x; 958cdf0e10cSrcweir float minY = [ position pointValue ].y; 959cdf0e10cSrcweir float maxX = minX + [ size sizeValue ].width; 960cdf0e10cSrcweir float maxY = minY + [ size sizeValue ].height; 961cdf0e10cSrcweir if ( minX < point.x && maxX > point.x && minY < point.y && maxY > point.y ) { 962cdf0e10cSrcweir hit = YES; 963cdf0e10cSrcweir } 964cdf0e10cSrcweir } 965cdf0e10cSrcweir [ pool release ]; 966cdf0e10cSrcweir return hit; 967cdf0e10cSrcweir} 968cdf0e10cSrcweir 969cdf0e10cSrcweirReference < XAccessibleContext > hitTestRunner ( com::sun::star::awt::Point point, 970cdf0e10cSrcweir Reference < XAccessibleContext > rxAccessibleContext ) { 971cdf0e10cSrcweir Reference < XAccessibleContext > hitChild; 972cdf0e10cSrcweir Reference < XAccessibleContext > emptyReference; 973cdf0e10cSrcweir try { 974cdf0e10cSrcweir Reference < XAccessibleComponent > rxAccessibleComponent ( rxAccessibleContext, UNO_QUERY ); 975cdf0e10cSrcweir if ( rxAccessibleComponent.is() ) { 976cdf0e10cSrcweir com::sun::star::awt::Point location = rxAccessibleComponent -> getLocationOnScreen(); 977cdf0e10cSrcweir com::sun::star::awt::Point hitPoint ( point.X - location.X , point.Y - location.Y); 978cdf0e10cSrcweir Reference < XAccessible > rxAccessible = rxAccessibleComponent -> getAccessibleAtPoint ( hitPoint ); 979cdf0e10cSrcweir if ( rxAccessible.is() && rxAccessible -> getAccessibleContext().is() ) { 980cdf0e10cSrcweir if ( rxAccessible -> getAccessibleContext() -> getAccessibleChildCount() > 0 ) { 981cdf0e10cSrcweir hitChild = hitTestRunner ( point, rxAccessible -> getAccessibleContext() ); 982cdf0e10cSrcweir if ( ! hitChild.is() ) { 983cdf0e10cSrcweir hitChild = rxAccessible -> getAccessibleContext(); 984cdf0e10cSrcweir } 985cdf0e10cSrcweir } else { 986cdf0e10cSrcweir hitChild = rxAccessible -> getAccessibleContext(); 987cdf0e10cSrcweir } 988cdf0e10cSrcweir } 989cdf0e10cSrcweir } 990cdf0e10cSrcweir if ( !hitChild.is() && rxAccessibleContext -> getAccessibleChildCount() > 0 ) { // special treatment for e.g. comboboxes 991cdf0e10cSrcweir for ( int i = 0; i < rxAccessibleContext -> getAccessibleChildCount(); i++ ) { 992cdf0e10cSrcweir Reference < XAccessible > rxAccessibleChild = rxAccessibleContext -> getAccessibleChild ( i ); 993cdf0e10cSrcweir if ( rxAccessibleChild.is() && rxAccessibleChild -> getAccessibleContext().is() && rxAccessibleChild -> getAccessibleContext() -> getAccessibleRole() != AccessibleRole::LIST ) { 994cdf0e10cSrcweir Reference < XAccessibleContext > myHitChild = hitTestRunner ( point, rxAccessibleChild -> getAccessibleContext() ); 995cdf0e10cSrcweir if ( myHitChild.is() ) { 996cdf0e10cSrcweir hitChild = myHitChild; 997cdf0e10cSrcweir break; 998cdf0e10cSrcweir } 999cdf0e10cSrcweir } 1000cdf0e10cSrcweir } 1001cdf0e10cSrcweir } 1002cdf0e10cSrcweir } catch ( RuntimeException ) { 1003cdf0e10cSrcweir return emptyReference; 1004cdf0e10cSrcweir } 1005cdf0e10cSrcweir return hitChild; 1006cdf0e10cSrcweir} 1007cdf0e10cSrcweir 1008cdf0e10cSrcweir-(id)accessibilityHitTest:(NSPoint)point { 1009cdf0e10cSrcweir static id wrapper = nil; 1010cdf0e10cSrcweir if ( nil != wrapper ) { 1011cdf0e10cSrcweir [ wrapper release ]; 1012cdf0e10cSrcweir wrapper = nil; 1013cdf0e10cSrcweir } 1014cdf0e10cSrcweir Reference < XAccessibleContext > hitChild; 1015cdf0e10cSrcweir NSRect screenRect = [ [ NSScreen mainScreen ] frame ]; 1016cdf0e10cSrcweir com::sun::star::awt::Point hitPoint ( static_cast<long>(point.x) , static_cast<long>(screenRect.size.height - point.y) ); 1017cdf0e10cSrcweir // check child windows first 1018cdf0e10cSrcweir NSWindow * window = (NSWindow *) [ self accessibilityAttributeValue: NSAccessibilityWindowAttribute ]; 1019cdf0e10cSrcweir NSArray * childWindows = [ window childWindows ]; 1020cdf0e10cSrcweir if ( [ childWindows count ] > 0 ) { 1021cdf0e10cSrcweir NSWindow * element = nil; 1022cdf0e10cSrcweir NSEnumerator * enumerator = [ childWindows objectEnumerator ]; 1023cdf0e10cSrcweir while ( ( element = [ enumerator nextObject ] ) && hitChild == nil ) { 1024cdf0e10cSrcweir if ( [ element isKindOfClass: [ SalFrameWindow class ] ] && [ self isViewElement: element hitByPoint: point ] ) { 1025cdf0e10cSrcweir // we have a child window that is hit 1026cdf0e10cSrcweir Reference < XAccessibleRelationSet > relationSet = [ ( ( SalFrameWindow * ) element ) accessibleContext ] -> getAccessibleRelationSet(); 1027cdf0e10cSrcweir if ( relationSet.is() && relationSet -> containsRelation ( AccessibleRelationType::SUB_WINDOW_OF )) { 1028cdf0e10cSrcweir // we have a valid relation to the parent element 1029cdf0e10cSrcweir AccessibleRelation relation = relationSet -> getRelationByType ( AccessibleRelationType::SUB_WINDOW_OF ); 1030cdf0e10cSrcweir for ( int i = 0; i < relation.TargetSet.getLength() && !hitChild.is(); i++ ) { 1031cdf0e10cSrcweir Reference < XAccessible > rxAccessible ( relation.TargetSet [ i ], UNO_QUERY ); 1032cdf0e10cSrcweir if ( rxAccessible.is() && rxAccessible -> getAccessibleContext().is() ) { 1033cdf0e10cSrcweir // hit test for children of parent 1034cdf0e10cSrcweir hitChild = hitTestRunner ( hitPoint, rxAccessible -> getAccessibleContext() ); 1035cdf0e10cSrcweir } 1036cdf0e10cSrcweir } 1037cdf0e10cSrcweir } 1038cdf0e10cSrcweir } 1039cdf0e10cSrcweir } 1040cdf0e10cSrcweir } 1041cdf0e10cSrcweir // nothing hit yet, so check ourself 1042cdf0e10cSrcweir if ( ! hitChild.is() ) { 1043cdf0e10cSrcweir if ( mpReferenceWrapper == nil ) { 1044cdf0e10cSrcweir [ self setDefaults: [ self accessibleContext ] ]; 1045cdf0e10cSrcweir } 1046cdf0e10cSrcweir hitChild = hitTestRunner ( hitPoint, mpReferenceWrapper -> rAccessibleContext ); 1047cdf0e10cSrcweir } 1048cdf0e10cSrcweir if ( hitChild.is() ) { 1049cdf0e10cSrcweir wrapper = [ AquaA11yFactory wrapperForAccessibleContext: hitChild ]; 1050cdf0e10cSrcweir } 1051cdf0e10cSrcweir if ( wrapper != nil ) { 1052cdf0e10cSrcweir [ wrapper retain ]; // TODO: retain only when transient ? 1053cdf0e10cSrcweir } 1054cdf0e10cSrcweir return wrapper; 1055cdf0e10cSrcweir} 1056cdf0e10cSrcweir 1057cdf0e10cSrcweir#pragma mark - 1058cdf0e10cSrcweir#pragma mark Access Methods 1059cdf0e10cSrcweir 1060cdf0e10cSrcweir-(XAccessibleAction *)accessibleAction { 1061cdf0e10cSrcweir return mpReferenceWrapper -> rAccessibleAction.get(); 1062cdf0e10cSrcweir} 1063cdf0e10cSrcweir 1064cdf0e10cSrcweir-(XAccessibleContext *)accessibleContext { 1065cdf0e10cSrcweir return mpReferenceWrapper -> rAccessibleContext.get(); 1066cdf0e10cSrcweir} 1067cdf0e10cSrcweir 1068cdf0e10cSrcweir-(XAccessibleComponent *)accessibleComponent { 1069cdf0e10cSrcweir return mpReferenceWrapper -> rAccessibleComponent.get(); 1070cdf0e10cSrcweir} 1071cdf0e10cSrcweir 1072cdf0e10cSrcweir-(XAccessibleExtendedComponent *)accessibleExtendedComponent { 1073cdf0e10cSrcweir return mpReferenceWrapper -> rAccessibleExtendedComponent.get(); 1074cdf0e10cSrcweir} 1075cdf0e10cSrcweir 1076cdf0e10cSrcweir-(XAccessibleSelection *)accessibleSelection { 1077cdf0e10cSrcweir return mpReferenceWrapper -> rAccessibleSelection.get(); 1078cdf0e10cSrcweir} 1079cdf0e10cSrcweir 1080cdf0e10cSrcweir-(XAccessibleTable *)accessibleTable { 1081cdf0e10cSrcweir return mpReferenceWrapper -> rAccessibleTable.get(); 1082cdf0e10cSrcweir} 1083cdf0e10cSrcweir 1084cdf0e10cSrcweir-(XAccessibleText *)accessibleText { 1085cdf0e10cSrcweir return mpReferenceWrapper -> rAccessibleText.get(); 1086cdf0e10cSrcweir} 1087cdf0e10cSrcweir 1088cdf0e10cSrcweir-(XAccessibleEditableText *)accessibleEditableText { 1089cdf0e10cSrcweir return mpReferenceWrapper -> rAccessibleEditableText.get(); 1090cdf0e10cSrcweir} 1091cdf0e10cSrcweir 1092cdf0e10cSrcweir-(XAccessibleValue *)accessibleValue { 1093cdf0e10cSrcweir return mpReferenceWrapper -> rAccessibleValue.get(); 1094cdf0e10cSrcweir} 1095cdf0e10cSrcweir 1096cdf0e10cSrcweir-(XAccessibleTextAttributes *)accessibleTextAttributes { 1097cdf0e10cSrcweir return mpReferenceWrapper -> rAccessibleTextAttributes.get(); 1098cdf0e10cSrcweir} 1099cdf0e10cSrcweir 1100cdf0e10cSrcweir-(XAccessibleMultiLineText *)accessibleMultiLineText { 1101cdf0e10cSrcweir return mpReferenceWrapper -> rAccessibleMultiLineText.get(); 1102cdf0e10cSrcweir} 1103cdf0e10cSrcweir 110497dacec1SHerbert Dürr-(NSWindow*)windowForParent { 110597dacec1SHerbert Dürr return [self window]; 1106cdf0e10cSrcweir} 1107cdf0e10cSrcweir 1108cdf0e10cSrcweir// These four are for AXTextAreas only. They are needed, because bold and italic 1109cdf0e10cSrcweir// attributes have to be bound to a font on the Mac. Our UNO-API instead handles 1110cdf0e10cSrcweir// and reports them independently. When they occur we bundle them to a font with 1111cdf0e10cSrcweir// this information here to create a according NSFont. 1112cdf0e10cSrcweir-(void)setDefaultFontname:(NSString *)fontname { 1113cdf0e10cSrcweir if ( mpDefaultFontname != nil ) { 1114cdf0e10cSrcweir [ mpDefaultFontname release ]; 1115cdf0e10cSrcweir } 1116cdf0e10cSrcweir mpDefaultFontname = fontname; 1117cdf0e10cSrcweir} 1118cdf0e10cSrcweir 1119cdf0e10cSrcweir-(NSString *)defaultFontname { 1120cdf0e10cSrcweir return mpDefaultFontname; 1121cdf0e10cSrcweir} 1122cdf0e10cSrcweir 1123cdf0e10cSrcweir-(void)setDefaultFontsize:(float)fontsize { 1124cdf0e10cSrcweir mDefaultFontsize = fontsize; 1125cdf0e10cSrcweir} 1126cdf0e10cSrcweir 1127cdf0e10cSrcweir-(float)defaultFontsize { 1128cdf0e10cSrcweir return mDefaultFontsize; 1129cdf0e10cSrcweir} 1130cdf0e10cSrcweir 1131cdf0e10cSrcweir-(void)setActsAsRadioGroup:(BOOL)actsAsRadioGroup { 1132cdf0e10cSrcweir mActsAsRadioGroup = actsAsRadioGroup; 1133cdf0e10cSrcweir} 1134cdf0e10cSrcweir 1135cdf0e10cSrcweir-(BOOL)actsAsRadioGroup { 1136cdf0e10cSrcweir return mActsAsRadioGroup; 1137cdf0e10cSrcweir} 1138cdf0e10cSrcweir 1139cdf0e10cSrcweir+(void)setPopupMenuOpen:(BOOL)popupMenuOpen { 1140cdf0e10cSrcweir isPopupMenuOpen = popupMenuOpen; 1141cdf0e10cSrcweir} 1142cdf0e10cSrcweir 1143cdf0e10cSrcweir@end 1144