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