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