bump product version to 7.2.5.1
[LibreOffice.git] / vcl / osx / a11ywrapper.mm
blobacb254f594263baa80669912ef0ab16d740315a6
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  *   Licensed to the Apache Software Foundation (ASF) under one or more
12  *   contributor license agreements. See the NOTICE file distributed
13  *   with this work for additional information regarding copyright
14  *   ownership. The ASF licenses this file to you under the Apache
15  *   License, Version 2.0 (the "License"); you may not use this file
16  *   except in compliance with the License. You may obtain a copy of
17  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
21 #include <osx/salinst.h>
22 #include <osx/saldata.hxx>
24 #include <osx/a11ywrapper.h>
25 #include <osx/a11ylistener.hxx>
26 #include <osx/a11yfactory.h>
27 #include <osx/a11yfocustracker.hxx>
29 #include <quartz/utils.h>
31 #include "a11yfocuslistener.hxx"
32 #include "a11yactionwrapper.h"
33 #include "a11ycomponentwrapper.h"
34 #include "a11yselectionwrapper.h"
35 #include "a11ytablewrapper.h"
36 #include "a11ytextwrapper.h"
37 #include "a11yvaluewrapper.h"
38 #include "a11yrolehelper.h"
40 #include <com/sun/star/accessibility/AccessibleRole.hpp>
41 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
42 #include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp>
43 #include <com/sun/star/awt/Size.hpp>
44 #include <com/sun/star/accessibility/XAccessibleRelationSet.hpp>
45 #include <com/sun/star/accessibility/AccessibleRelationType.hpp>
46 #include <com/sun/star/lang/DisposedException.hpp>
48 #include <sal/log.hxx>
49 #include <osl/diagnose.h>
51 using namespace ::com::sun::star::accessibility;
52 using namespace ::com::sun::star::awt;
53 using namespace ::com::sun::star::lang;
54 using namespace ::com::sun::star::uno;
56 @interface SalFrameWindow : NSWindow
59 -(Reference<XAccessibleContext>)accessibleContext;
60 @end
62 static bool isPopupMenuOpen = false;
64 static std::ostream &operator<<(std::ostream &s, NSObject *obj) {
65     return s << [[obj description] UTF8String];
68 @implementation AquaA11yWrapper : NSView
70 #pragma mark -
71 #pragma mark Init and dealloc
73 -(id)initWithAccessibleContext: (Reference < XAccessibleContext >) rxAccessibleContext {
74     self = [ super init ];
75     if ( self ) {
76         [ self setDefaults: rxAccessibleContext ];
77     }
78     return self;
81 -(void) setDefaults: (Reference < XAccessibleContext >) rxAccessibleContext {
82     mpReferenceWrapper = new ReferenceWrapper;
83     mActsAsRadioGroup = NO;
84     mpReferenceWrapper -> rAccessibleContext = rxAccessibleContext;
85     mIsTableCell = NO;
86     // Querying all supported interfaces
87     try {
88         // XAccessibleComponent
89         mpReferenceWrapper->rAccessibleComponent.set( rxAccessibleContext, UNO_QUERY );
90         // XAccessibleExtendedComponent
91         mpReferenceWrapper->rAccessibleExtendedComponent.set( rxAccessibleContext, UNO_QUERY );
92         // XAccessibleSelection
93         mpReferenceWrapper->rAccessibleSelection.set( rxAccessibleContext, UNO_QUERY );
94         // XAccessibleTable
95         mpReferenceWrapper->rAccessibleTable.set( rxAccessibleContext, UNO_QUERY );
96         // XAccessibleText
97         mpReferenceWrapper->rAccessibleText.set( rxAccessibleContext, UNO_QUERY );
98         // XAccessibleEditableText
99         mpReferenceWrapper->rAccessibleEditableText.set( rxAccessibleContext, UNO_QUERY );
100         // XAccessibleValue
101         mpReferenceWrapper->rAccessibleValue.set( rxAccessibleContext, UNO_QUERY );
102         // XAccessibleAction
103         mpReferenceWrapper->rAccessibleAction.set( rxAccessibleContext, UNO_QUERY );
104         // XAccessibleTextAttributes
105         mpReferenceWrapper->rAccessibleTextAttributes.set( rxAccessibleContext, UNO_QUERY );
106         // XAccessibleMultiLineText
107         mpReferenceWrapper->rAccessibleMultiLineText.set( rxAccessibleContext, UNO_QUERY );
108         // XAccessibleTextMarkup
109         mpReferenceWrapper->rAccessibleTextMarkup.set( rxAccessibleContext, UNO_QUERY );
110         // XAccessibleEventBroadcaster
111         #if 0
112         /* #i102033# NSAccessibility does not seemt to know an equivalent for transient children.
113            That means we need to cache this, else e.g. tree list boxes are not accessible (moreover
114            it crashes by notifying dead objects - which would seemt o be another bug)
116            FIXME:
117            Unfortunately this can increase memory consumption drastically until the non transient parent
118            is destroyed and finally all the transients are released.
119         */
120         if ( ! rxAccessibleContext -> getAccessibleStateSet() -> contains ( AccessibleStateType::TRANSIENT ) )
121         #endif
122         {
123             Reference< XAccessibleEventBroadcaster > xBroadcaster(rxAccessibleContext, UNO_QUERY);
124             if( xBroadcaster.is() ) {
125                 /*
126                  * We intentionally do not hold a reference to the event listener in the wrapper object,
127                  * but let the listener control the life cycle of the wrapper instead ..
128                  */
129                 xBroadcaster->addAccessibleEventListener( new AquaA11yEventListener( self, rxAccessibleContext -> getAccessibleRole() ) );
130             }
131         }
132         // TABLE_CELL
133         if ( rxAccessibleContext -> getAccessibleRole() == AccessibleRole::TABLE_CELL ) {
134             mIsTableCell = YES;
135         }
136     } catch ( const Exception ) {
137     }
140 -(void)dealloc {
141     if ( mpReferenceWrapper ) {
142         delete mpReferenceWrapper;
143     }
144     [ super dealloc ];
147 #pragma mark -
148 #pragma mark Utility Section
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 = static_cast<SEL>(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 const 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  ) {
181         selector = static_cast<SEL>(nil);
182     }
183     [ pool release ];
184     return selector;
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 > ();
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;
206 #pragma mark -
207 #pragma mark Attribute Value Getters
208 // ( called via Reflection by accessibilityAttributeValue )
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 expressed through the hierarchy. An 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.
218 -(id)roleAttribute {
219     if ( mActsAsRadioGroup ) {
220         return NSAccessibilityRadioGroupRole;
221     }
222     else {
223         return [ AquaA11yRoleHelper getNativeRoleFrom: [ self accessibleContext ] ];
224     }
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             SAL_WNODEPRECATED_DECLARATIONS_PUSH
237                 //TODO: 10.10 accessibilityAttributeValue:
238             return [ super accessibilityAttributeValue: NSAccessibilitySubroleAttribute ];
239             SAL_WNODEPRECATED_DECLARATIONS_POP
240         }
241     }
244 -(id)titleAttribute {
245     return CreateNSString ( [ self accessibleContext ] -> getAccessibleName() );
248 -(id)descriptionAttribute {
249     if ( [ self accessibleContext ] -> getAccessibleRole() == AccessibleRole::COMBO_BOX ) {
250         return [ self titleAttribute ];
251     } else if ( [ self accessibleExtendedComponent ] ) {
252         return [ AquaA11yComponentWrapper descriptionAttributeForElement: self ];
253     } else {
254         return CreateNSString ( [ self accessibleContext ] -> getAccessibleDescription() );
255     }
258 -(id)enabledAttribute {
259     if ( [ self accessibleContext ] -> getAccessibleStateSet().is() ) {
260         return [ NSNumber numberWithBool: [ self accessibleContext ] -> getAccessibleStateSet() -> contains ( AccessibleStateType::ENABLED ) ];
261     } else {
262         return nil;
263     }
266 -(id)focusedAttribute {
267     if ( [ self accessibleContext ] -> getAccessibleRole() == AccessibleRole::COMBO_BOX ) {
268         id isFocused = nil;
269         Reference < XAccessible > rxParent = [ self accessibleContext ] -> getAccessibleParent();
270         if ( rxParent.is() ) {
271             Reference < XAccessibleContext > rxContext = rxParent -> getAccessibleContext();
272             if ( rxContext.is() && rxContext -> getAccessibleStateSet().is() ) {
273                 isFocused = [ NSNumber numberWithBool: rxContext -> getAccessibleStateSet() -> contains ( AccessibleStateType::FOCUSED ) ];
274             }
275         }
276         return isFocused;
277     } else if ( [ self accessibleContext ] -> getAccessibleStateSet().is() ) {
278         return [ NSNumber numberWithBool: [ self accessibleContext ] -> getAccessibleStateSet() -> contains ( AccessibleStateType::FOCUSED ) ];
279     } else {
280         return nil;
281     }
284 -(id)parentAttribute {
285     if ( [ self accessibleContext ] -> getAccessibleRole() == AccessibleRole::RADIO_BUTTON && ! mActsAsRadioGroup ) {
286         Reference < XAccessible > rxAccessible = [ self getFirstRadioButtonInGroup ];
287         if ( rxAccessible.is() && rxAccessible -> getAccessibleContext().is() ) {
288             Reference < XAccessibleContext > rxAccessibleContext = rxAccessible -> getAccessibleContext();
289             id parent_wrapper = [ AquaA11yFactory wrapperForAccessibleContext: rxAccessibleContext createIfNotExists: YES asRadioGroup: YES ];
290             [ parent_wrapper autorelease ];
291             return NSAccessibilityUnignoredAncestor( parent_wrapper );
292         }
293         return nil;
294     }
295     try {
296         Reference< XAccessible > xParent( [ self accessibleContext ] -> getAccessibleParent() );
297         if ( xParent.is() ) {
298             Reference< XAccessibleContext > xContext( xParent -> getAccessibleContext() );
299             if ( xContext.is() ) {
300                 id parent_wrapper = [ AquaA11yFactory wrapperForAccessibleContext: xContext ];
301                 [ parent_wrapper autorelease ];
302                 return NSAccessibilityUnignoredAncestor( parent_wrapper );
303             }
304         }
305     } catch (const Exception&) {
306     }
308     OSL_ASSERT( false );
309     return nil;
312 -(id)childrenAttribute {
313     if ( mActsAsRadioGroup ) {
314         NSMutableArray * children = [ [ NSMutableArray alloc ] init ];
315         Reference < XAccessibleRelationSet > rxAccessibleRelationSet = [ self accessibleContext ] -> getAccessibleRelationSet();
316         AccessibleRelation const relationMemberOf = rxAccessibleRelationSet -> getRelationByType ( AccessibleRelationType::MEMBER_OF );
317         if ( relationMemberOf.RelationType == AccessibleRelationType::MEMBER_OF && relationMemberOf.TargetSet.hasElements() ) {
318             for ( const auto& i : relationMemberOf.TargetSet ) {
319                 Reference < XAccessible > rMateAccessible( i, UNO_QUERY );
320                 if ( rMateAccessible.is() ) {
321                     Reference< XAccessibleContext > rMateAccessibleContext( rMateAccessible -> getAccessibleContext() );
322                     if ( rMateAccessibleContext.is() ) {
323                         id wrapper = [ AquaA11yFactory wrapperForAccessibleContext: rMateAccessibleContext ];
324                         [ children addObject: wrapper ];
325                         [ wrapper release ];
326                     }
327                 }
328             }
329         }
330         return children;
331     } else if ( [ self accessibleTable ] )
332     {
333         AquaA11yTableWrapper* pTable = [self isKindOfClass: [AquaA11yTableWrapper class]] ? static_cast<AquaA11yTableWrapper*>(self) : nil;
334         return [ AquaA11yTableWrapper childrenAttributeForElement: pTable ];
335     } else {
336         try {
337             NSMutableArray * children = [ [ NSMutableArray alloc ] init ];
338             Reference< XAccessibleContext > xContext( [ self accessibleContext ] );
340             sal_Int32 cnt = xContext -> getAccessibleChildCount();
341             for ( sal_Int32 i = 0; i < cnt; i++ ) {
342                 Reference< XAccessible > xChild( xContext -> getAccessibleChild( i ) );
343                 if( xChild.is() ) {
344                     Reference< XAccessibleContext > xChildContext( xChild -> getAccessibleContext() );
345                     // the menubar is already accessible (including Apple- and Application-Menu) through NSApplication => omit it here
346                     if ( xChildContext.is() && AccessibleRole::MENU_BAR != xChildContext -> getAccessibleRole() ) {
347                         id wrapper = [ AquaA11yFactory wrapperForAccessibleContext: xChildContext ];
348                         [ children addObject: wrapper ];
349                         [ wrapper release ];
350                     }
351                 }
352             }
354             // if not already acting as RadioGroup now is the time to replace RadioButtons with RadioGroups and remove RadioButtons
355             if ( ! mActsAsRadioGroup ) {
356                 NSEnumerator * enumerator = [ children objectEnumerator ];
357                 AquaA11yWrapper * element;
358                 while ( ( element = static_cast<AquaA11yWrapper *>([ enumerator nextObject ]) ) ) {
359                     if ( [ element accessibleContext ] -> getAccessibleRole() == AccessibleRole::RADIO_BUTTON ) {
360                         if ( [ element isFirstRadioButtonInGroup ] ) {
361                             id wrapper = [ AquaA11yFactory wrapperForAccessibleContext: [ element accessibleContext ] createIfNotExists: YES asRadioGroup: YES ];
362                             [ children replaceObjectAtIndex: [ children indexOfObjectIdenticalTo: element ] withObject: wrapper ];
363                         }
364                         [ children removeObject: element ];
365                     }
366                 }
367             }
369             [ children autorelease ];
370             return NSAccessibilityUnignoredChildren( children );
371         } catch (const Exception &) {
372             // TODO: Log
373             return nil;
374         }
375     }
378 -(id)windowAttribute {
379     // go upstairs until reaching the broken connection
380     AquaA11yWrapper * aWrapper = self;
381     int loops = 0;
382     while ( [ aWrapper accessibleContext ] -> getAccessibleParent().is() ) {
383         AquaA11yWrapper *aTentativeParentWrapper = [ AquaA11yFactory wrapperForAccessibleContext: [ aWrapper accessibleContext ] -> getAccessibleParent() -> getAccessibleContext() ];
384         // Quick-and-dirty fix for infinite loop after fixing crash in
385         // fdo#47275
386         if ( aTentativeParentWrapper == aWrapper )
387             break;
388         // Even dirtier fix for infinite loop in fdo#55156
389         if ( loops++ == 100 )
390             break;
391         aWrapper = aTentativeParentWrapper;
392         [ aWrapper autorelease ];
393     }
394     // get associated NSWindow
395     NSWindow* theWindow = [ aWrapper windowForParent ];
396     return theWindow;
399 -(id)topLevelUIElementAttribute {
400     return [ self windowAttribute ];
403 -(id)sizeAttribute {
404     if ( [ self accessibleComponent ] ) {
405         return [ AquaA11yComponentWrapper sizeAttributeForElement: self ];
406     } else {
407         return nil;
408     }
411 -(id)positionAttribute {
412     if ( [ self accessibleComponent ] ) {
413         return [ AquaA11yComponentWrapper positionAttributeForElement: self ];
414     } else {
415         return nil;
416     }
419 -(id)helpAttribute {
420     return CreateNSString ( [ self accessibleContext ] -> getAccessibleDescription() );
423 -(id)roleDescriptionAttribute {
424     if ( mActsAsRadioGroup ) {
425         return [ AquaA11yRoleHelper getRoleDescriptionFrom: NSAccessibilityRadioGroupRole with: @"" ];
426         } else if( [ self accessibleContext ] -> getAccessibleRole() == AccessibleRole::RADIO_BUTTON ) {
427                 // FIXME: VO should read this because of hierarchy, this is just a workaround
428                 // get parent and its children
429                 AquaA11yWrapper * parent = [ self parentAttribute ];
430                 NSArray * children = [ parent childrenAttribute ];
431                 // find index of self
432                 int index = 1;
433                 NSEnumerator * enumerator = [ children objectEnumerator ];
434                 AquaA11yWrapper * child = nil;
435                 while ( ( child = [ enumerator nextObject ] ) ) {
436                         if ( self == child ) {
437                                 break;
438                         }
439                         index++;
440                 }
441                 // build string
442                 NSNumber * nIndex = [ NSNumber numberWithInt: index ];
443                 NSNumber * nGroupsize = [ NSNumber numberWithInt: [ children count ] ];
444                 NSMutableString * value = [ [ NSMutableString alloc ] init ];
445                 [ value appendString: @"radio button " ];
446                 [ value appendString: [ nIndex stringValue ] ];
447                 [ value appendString: @" of " ];
448                 [ value appendString: [ nGroupsize stringValue ] ];
449                 // clean up and return string
450                 [ nIndex release ];
451                 [ nGroupsize release ];
452                 [ children release ];
453                 return value;
454     } else {
455         return [ AquaA11yRoleHelper getRoleDescriptionFrom:
456                 [ AquaA11yRoleHelper getNativeRoleFrom: [ self accessibleContext ] ]
457                 with: [ AquaA11yRoleHelper getNativeSubroleFrom: [ self accessibleContext ] -> getAccessibleRole() ] ];
458     }
461 -(id)valueAttribute {
462     if ( [ [ self roleAttribute ] isEqualToString: NSAccessibilityMenuItemRole ] ) {
463         return nil;
464     } else if ( [ self accessibleText ] ) {
465         return [ AquaA11yTextWrapper valueAttributeForElement: self ];
466     } else if ( [ self accessibleValue ] ) {
467         return [ AquaA11yValueWrapper valueAttributeForElement: self ];
468     } else {
469         return nil;
470     }
473 -(id)minValueAttribute {
474     if ( [ self accessibleValue ] ) {
475         return [ AquaA11yValueWrapper minValueAttributeForElement: self ];
476     } else {
477         return nil;
478     }
481 -(id)maxValueAttribute {
482     if ( [ self accessibleValue ] ) {
483         return [ AquaA11yValueWrapper maxValueAttributeForElement: self ];
484     } else {
485         return nil;
486     }
489 -(id)contentsAttribute {
490     return [ self childrenAttribute ];
493 -(id)selectedChildrenAttribute {
494     return [ AquaA11ySelectionWrapper selectedChildrenAttributeForElement: self ];
497 -(id)numberOfCharactersAttribute {
498     if ( [ self accessibleText ] ) {
499         return [ AquaA11yTextWrapper numberOfCharactersAttributeForElement: self ];
500     } else {
501         return nil;
502     }
505 -(id)selectedTextAttribute {
506     if ( [ self accessibleText ] ) {
507         return [ AquaA11yTextWrapper selectedTextAttributeForElement: self ];
508     } else {
509         return nil;
510     }
513 -(id)selectedTextRangeAttribute {
514     if ( [ self accessibleText ] ) {
515         return [ AquaA11yTextWrapper selectedTextRangeAttributeForElement: self ];
516     } else {
517         return nil;
518     }
521 -(id)visibleCharacterRangeAttribute {
522     if ( [ self accessibleText ] ) {
523         return [ AquaA11yTextWrapper visibleCharacterRangeAttributeForElement: self ];
524     } else {
525         return nil;
526     }
529 -(id)tabsAttribute {
530     return self; // TODO ???
533 -(id)sharedTextUIElementsAttribute {
534     if ( [ self accessibleText ] ) {
535         return [ AquaA11yTextWrapper sharedTextUIElementsAttributeForElement: self ];
536     } else {
537         return nil;
538     }
541 -(id)sharedCharacterRangeAttribute {
542     if ( [ self accessibleText ] ) {
543         return [ AquaA11yTextWrapper sharedCharacterRangeAttributeForElement: self ];
544     } else {
545         return nil;
546     }
549 -(id)expandedAttribute {
550     return [ NSNumber numberWithBool: [ self accessibleContext ] -> getAccessibleStateSet() -> contains ( AccessibleStateType::EXPANDED ) ];
553 -(id)selectedAttribute {
554     return [ NSNumber numberWithBool: [ self accessibleContext ] -> getAccessibleStateSet() -> contains ( AccessibleStateType::SELECTED ) ];
557 -(id)stringForRangeAttributeForParameter:(id)range {
558     if ( [ self accessibleText ] ) {
559         return [ AquaA11yTextWrapper stringForRangeAttributeForElement: self forParameter: range ];
560     } else {
561         return nil;
562     }
565 -(id)attributedStringForRangeAttributeForParameter:(id)range {
566     if ( [ self accessibleText ] ) {
567         return [ AquaA11yTextWrapper attributedStringForRangeAttributeForElement: self forParameter: range ];
568     } else {
569         return nil;
570     }
573 -(id)rangeForIndexAttributeForParameter:(id)index {
574     if ( [ self accessibleText ] ) {
575         return [ AquaA11yTextWrapper rangeForIndexAttributeForElement: self forParameter: index ];
576     } else {
577         return nil;
578     }
581 -(id)rangeForPositionAttributeForParameter:(id)point {
582     if ( [ self accessibleText ] ) {
583         return [ AquaA11yTextWrapper rangeForPositionAttributeForElement: self forParameter: point ];
584     } else {
585         return nil;
586     }
589 -(id)boundsForRangeAttributeForParameter:(id)range {
590     if ( [ self accessibleText ] ) {
591         return [ AquaA11yTextWrapper boundsForRangeAttributeForElement: self forParameter: range ];
592     } else {
593         return nil;
594     }
597 -(id)styleRangeForIndexAttributeForParameter:(id)index {
598     if ( [ self accessibleText ] ) {
599         return [ AquaA11yTextWrapper styleRangeForIndexAttributeForElement: self forParameter: index ];
600     } else {
601         return nil;
602     }
605 -(id)rTFForRangeAttributeForParameter:(id)range {
606     if ( [ self accessibleText ] ) {
607         return [ AquaA11yTextWrapper rTFForRangeAttributeForElement: self forParameter: range ];
608     } else {
609         return nil;
610     }
613 -(id)orientationAttribute {
614     NSString * orientation = nil;
615     Reference < XAccessibleStateSet > stateSet = [ self accessibleContext ] -> getAccessibleStateSet();
616     if ( stateSet -> contains ( AccessibleStateType::HORIZONTAL ) ) {
617         orientation = NSAccessibilityHorizontalOrientationValue;
618     } else if ( stateSet -> contains ( AccessibleStateType::VERTICAL ) ) {
619         orientation = NSAccessibilityVerticalOrientationValue;
620     }
621     return orientation;
624 -(id)titleUIElementAttribute {
625     if ( [ self accessibleContext ] -> getAccessibleRelationSet().is() ) {
626         NSString * title = [ self titleAttribute ];
627         id titleElement = nil;
628         if ( [ title length ] == 0 ) {
629             AccessibleRelation relationLabeledBy = [ self accessibleContext ] -> getAccessibleRelationSet() -> getRelationByType ( AccessibleRelationType::LABELED_BY );
630             if ( relationLabeledBy.RelationType == AccessibleRelationType::LABELED_BY && relationLabeledBy.TargetSet.hasElements()  ) {
631                 Reference < XAccessible > rxAccessible ( relationLabeledBy.TargetSet[0], UNO_QUERY );
632                 titleElement = [ AquaA11yFactory wrapperForAccessibleContext: rxAccessible -> getAccessibleContext() ];
633             }
634         }
635         if ( title ) {
636             [ title release ];
637         }
638         return titleElement;
639     } else {
640         return nil;
641     }
644 -(id)servesAsTitleForUIElementsAttribute {
645     if ( [ self accessibleContext ] -> getAccessibleRelationSet().is() ) {
646         id titleForElement = nil;
647         AccessibleRelation relationLabelFor = [ self accessibleContext ] -> getAccessibleRelationSet() -> getRelationByType ( AccessibleRelationType::LABEL_FOR );
648         if ( relationLabelFor.RelationType == AccessibleRelationType::LABEL_FOR && relationLabelFor.TargetSet.hasElements() ) {
649             Reference < XAccessible > rxAccessible ( relationLabelFor.TargetSet[0], UNO_QUERY );
650             titleForElement = [ AquaA11yFactory wrapperForAccessibleContext: rxAccessible -> getAccessibleContext() ];
651         }
652         return titleForElement;
653     } else {
654         return nil;
655     }
658 -(id)lineForIndexAttributeForParameter:(id)index {
659     if ( [ self accessibleMultiLineText ] ) {
660         return [ AquaA11yTextWrapper lineForIndexAttributeForElement: self forParameter: index ];
661     } else {
662         return nil;
663     }
666 -(id)rangeForLineAttributeForParameter:(id)line {
667     if ( [ self accessibleMultiLineText ] ) {
668         return [ AquaA11yTextWrapper rangeForLineAttributeForElement: self forParameter: line ];
669     } else {
670         return nil;
671     }
674 #pragma mark -
675 #pragma mark Accessibility Protocol
677 -(id)accessibilityAttributeValue:(NSString *)attribute {
678     SAL_INFO("vcl.a11y", "[" << self << " accessibilityAttributeValue:" << attribute << "]");
679     // #i90575# guard NSAccessibility protocol against unwanted access
680     if ( isPopupMenuOpen ) {
681         return nil;
682     }
684     id value = nil;
685     // if we are no longer in the wrapper repository, we have been disposed
686     AquaA11yWrapper * theWrapper = [ AquaA11yFactory wrapperForAccessibleContext: [ self accessibleContext ] createIfNotExists: NO ];
687     if ( theWrapper || mIsTableCell ) {
688         try {
689             SEL methodSelector = [ self selectorForAttribute: attribute asGetter: YES withGetterParameter: NO ];
690             if ( [ self respondsToSelector: methodSelector ] ) {
691                 value = [ self performSelector: methodSelector ];
692             }
693         } catch ( const DisposedException & ) {
694             mIsTableCell = NO; // just to be sure
695             [ AquaA11yFactory removeFromWrapperRepositoryFor: [ self accessibleContext ] ];
696             return nil;
697         } catch ( const Exception & ) {
698             // empty
699         }
700     }
701     if ( theWrapper ) {
702         [ theWrapper release ]; // the above called method calls retain on the returned Wrapper
703     }
704     return value;
707 -(BOOL)accessibilityIsIgnored {
708     SAL_INFO("vcl.a11y", "[" << self << " accessibilityIsIgnored]");
709     // #i90575# guard NSAccessibility protocol against unwanted access
710     if ( isPopupMenuOpen ) {
711         return NO;
712     }
713     bool ignored = false;
714     sal_Int16 nRole = [ self accessibleContext ] -> getAccessibleRole();
715     switch ( nRole ) {
716         //case AccessibleRole::PANEL:
717         case AccessibleRole::FRAME:
718         case AccessibleRole::ROOT_PANE:
719         case AccessibleRole::SEPARATOR:
720         case AccessibleRole::FILLER:
721         case AccessibleRole::DIALOG:
722             ignored = true;
723             break;
724         default:
725             ignored = ! ( [ self accessibleContext ] -> getAccessibleStateSet() -> contains ( AccessibleStateType::VISIBLE ) );
726             break;
727     }
728     return ignored; // TODO: to be completed
731 -(NSArray *)accessibilityAttributeNames {
732     SAL_INFO("vcl.a11y", "[" << self << " accessibilityAttributeNames]");
733     // #i90575# guard NSAccessibility protocol against unwanted access
734     if ( isPopupMenuOpen ) {
735         return nil;
736     }
737     NSString * nativeSubrole = nil;
738     NSString * title = nil;
739     NSMutableArray * attributeNames = nil;
740     sal_Int32 nAccessibleChildren = 0;
741     try {
742         // Default Attributes
743         attributeNames = [ NSMutableArray arrayWithObjects:
744             NSAccessibilityRoleAttribute,
745             NSAccessibilityDescriptionAttribute,
746             NSAccessibilityParentAttribute,
747             NSAccessibilityWindowAttribute,
748             NSAccessibilityHelpAttribute,
749             NSAccessibilityTopLevelUIElementAttribute,
750             NSAccessibilityRoleDescriptionAttribute,
751             nil ];
752         nativeSubrole = static_cast<NSString *>([ AquaA11yRoleHelper getNativeSubroleFrom: [ self accessibleContext ] -> getAccessibleRole() ]);
753         title = static_cast<NSString *>([ self titleAttribute ]);
754         Reference < XAccessibleRelationSet > rxRelationSet = [ self accessibleContext ] -> getAccessibleRelationSet();
755         // Special Attributes depending on attribute values
756         if ( nativeSubrole && ! [ nativeSubrole isEqualToString: @"" ] ) {
757             [ attributeNames addObject: NSAccessibilitySubroleAttribute ];
758         }
759         try
760         {
761             nAccessibleChildren = [ self accessibleContext ] -> getAccessibleChildCount();
762             if (  nAccessibleChildren > 0 ) {
763                 [ attributeNames addObject: NSAccessibilityChildrenAttribute ];
764         }
765         }
766         catch( DisposedException& ) {}
767         catch( RuntimeException& ) {}
769         if ( title && ! [ title isEqualToString: @"" ] ) {
770             [ attributeNames addObject: NSAccessibilityTitleAttribute ];
771         }
772         if ( [ title length ] == 0 && rxRelationSet.is() && rxRelationSet -> containsRelation ( AccessibleRelationType::LABELED_BY ) ) {
773             [ attributeNames addObject: NSAccessibilityTitleUIElementAttribute ];
774         }
775         if ( rxRelationSet.is() && rxRelationSet -> containsRelation ( AccessibleRelationType::LABEL_FOR ) ) {
776             [ attributeNames addObject: NSAccessibilityServesAsTitleForUIElementsAttribute ];
777         }
778         // Special Attributes depending on interface
779         if( [self accessibleContext ] -> getAccessibleRole() == AccessibleRole::TABLE )
780             [AquaA11yTableWrapper addAttributeNamesTo: attributeNames object: self];
782         if ( [ self accessibleText ] ) {
783             [ AquaA11yTextWrapper addAttributeNamesTo: attributeNames ];
784         }
785         if ( [ self accessibleComponent ] ) {
786             [ AquaA11yComponentWrapper addAttributeNamesTo: attributeNames ];
787         }
788         if ( [ self accessibleSelection ] ) {
789             [ AquaA11ySelectionWrapper addAttributeNamesTo: attributeNames ];
790         }
791         if ( [ self accessibleValue ] ) {
792             [ AquaA11yValueWrapper addAttributeNamesTo: attributeNames ];
793         }
794         [ nativeSubrole release ];
795         [ title release ];
796         return attributeNames;
797     } catch ( DisposedException & ) { // Object is no longer available
798         if ( nativeSubrole ) {
799             [ nativeSubrole release ];
800         }
801         if ( title ) {
802             [ title release ];
803         }
804         if ( attributeNames ) {
805             [ attributeNames release ];
806         }
807         [ AquaA11yFactory removeFromWrapperRepositoryFor: [ self accessibleContext ] ];
808         return [ [ NSArray alloc ] init ];
809     }
812 -(BOOL)accessibilityIsAttributeSettable:(NSString *)attribute {
813     SAL_INFO("vcl.a11y", "[" << self << " accessibilityAttributeIsSettable:" << attribute << "]");
814     bool isSettable = false;
815     if ( [ self accessibleText ] ) {
816         isSettable = [ AquaA11yTextWrapper isAttributeSettable: attribute forElement: self ];
817     }
818     if ( ! isSettable && [ self accessibleComponent ] ) {
819         isSettable = [ AquaA11yComponentWrapper isAttributeSettable: attribute forElement: self ];
820     }
821     if ( ! isSettable && [ self accessibleSelection ] ) {
822         isSettable = [ AquaA11ySelectionWrapper isAttributeSettable: attribute forElement: self ];
823     }
824     if ( ! isSettable && [ self accessibleValue ] ) {
825         isSettable = [ AquaA11yValueWrapper isAttributeSettable: attribute forElement: self ];
826     }
827     return isSettable; // TODO: to be completed
830 -(NSArray *)accessibilityParameterizedAttributeNames {
831     SAL_INFO("vcl.a11y", "[" << self << " accessibilityParameterizedAttributeNames]");
832     NSMutableArray * attributeNames = [ [ NSMutableArray alloc ] init ];
833     // Special Attributes depending on interface
834     if ( [ self accessibleText ] ) {
835         [ AquaA11yTextWrapper addParameterizedAttributeNamesTo: attributeNames ];
836     }
837     return attributeNames; // TODO: to be completed
840 -(id)accessibilityAttributeValue:(NSString *)attribute forParameter:(id)parameter {
841     SAL_INFO("vcl.a11y", "[" << self << " accessibilityAttributeValue:" << attribute << " forParameter:" << (static_cast<NSObject*>(parameter)) << "]");
842     SEL methodSelector = [ self selectorForAttribute: attribute asGetter: YES withGetterParameter: YES ];
843     if ( [ self respondsToSelector: methodSelector ] ) {
844         return [ self performSelector: methodSelector withObject: parameter ];
845     }
846     return nil; // TODO: to be completed
849 -(BOOL)accessibilitySetOverrideValue:(id)value forAttribute:(NSString *)attribute
851     SAL_INFO("vcl.a11y", "[" << self << " accessibilitySetOverrideValue:" << (static_cast<NSObject*>(value)) << " forAttribute:" << attribute << "]");
852     return NO; // TODO
855 -(void)accessibilitySetValue:(id)value forAttribute:(NSString *)attribute {
856     SAL_INFO("vcl.a11y", "[" << self << " accessibilitySetValue:" << (static_cast<NSObject*>(value)) << " forAttribute:" << attribute << "]");
857     SEL methodSelector = [ self selectorForAttribute: attribute asGetter: NO withGetterParameter: NO ];
858     if ( [ AquaA11yComponentWrapper respondsToSelector: methodSelector ] ) {
859         [ AquaA11yComponentWrapper performSelector: methodSelector withObject: self withObject: value ];
860     }
861     if ( [ AquaA11yTextWrapper respondsToSelector: methodSelector ] ) {
862         [ AquaA11yTextWrapper performSelector: methodSelector withObject: self withObject: value ];
863     }
864     if ( [ AquaA11ySelectionWrapper respondsToSelector: methodSelector ] ) {
865         [ AquaA11ySelectionWrapper performSelector: methodSelector withObject: self withObject: value ];
866     }
867     if ( [ AquaA11yValueWrapper respondsToSelector: methodSelector ] ) {
868         [ AquaA11yValueWrapper performSelector: methodSelector withObject: self withObject: value ];
869     }
872 -(id)accessibilityFocusedUIElement {
873     SAL_INFO("vcl.a11y", "[" << self << " accessibilityFocusedUIElement]");
874     // #i90575# guard NSAccessibility protocol against unwanted access
875     if ( isPopupMenuOpen ) {
876         return nil;
877     }
879     // as this seems to be the first API call on a newly created SalFrameView object,
880     // make sure self gets registered in the repository ..
881     [ self accessibleContext ];
883     AquaA11yWrapper * focusedUIElement = AquaA11yFocusListener::get()->getFocusedUIElement();
884 //    AquaA11yWrapper * ancestor = focusedUIElement;
886       // Make sure the focused object is a descendant of self
887 //    do  {
888 //       if( self == ancestor )
889     return focusedUIElement;
891 //       ancestor = [ ancestor accessibilityAttributeValue: NSAccessibilityParentAttribute ];
892 //    }  while( nil != ancestor );
894     return self;
897 -(NSString *)accessibilityActionDescription:(NSString *)action {
898     SAL_INFO("vcl.a11y", "[" << self << " accessibilityActionDescription:" << action << "]");
899     return NSAccessibilityActionDescription(action);
902 -(AquaA11yWrapper *)actionResponder {
903     AquaA11yWrapper * wrapper = nil;
904     // get some information
905     NSString * role = static_cast<NSString *>([ self accessibilityAttributeValue: NSAccessibilityRoleAttribute ]);
906     id enabledAttr = [ self enabledAttribute ];
907     bool enabled = [ enabledAttr boolValue ];
908     NSView * parent = static_cast<NSView *>([ self accessibilityAttributeValue: NSAccessibilityParentAttribute ]);
909     AquaA11yWrapper * parentAsWrapper = nil;
910     if ( [ parent isKindOfClass: [ AquaA11yWrapper class ] ] ) {
911         parentAsWrapper = static_cast<AquaA11yWrapper *>(parent);
912     }
913     SAL_WNODEPRECATED_DECLARATIONS_PUSH
914         //TODO: 10.10 accessibilityAttributeValue:
915     NSString * parentRole = static_cast<NSString *>([ parent accessibilityAttributeValue: NSAccessibilityRoleAttribute ]);
916     SAL_WNODEPRECATED_DECLARATIONS_POP
917     // if we are a textarea inside a combobox, then the combobox is the action responder
918     if ( enabled
919       && [ role isEqualToString: NSAccessibilityTextAreaRole ]
920       && [ parentRole isEqualToString: NSAccessibilityComboBoxRole ]
921       && parentAsWrapper ) {
922         wrapper = parentAsWrapper;
923     } else if ( enabled && [ self accessibleAction ] ) {
924         wrapper = self ;
925     }
926     [ parentRole release ];
927     [ enabledAttr release ];
928     [ role release ];
929     return wrapper;
932 -(void)accessibilityPerformAction:(NSString *)action {
933     SAL_INFO("vcl.a11y", "[" << self << " accessibilityPerformAction:" << action << "]");
934     AquaA11yWrapper * actionResponder = [ self actionResponder ];
935     if ( actionResponder ) {
936         [ AquaA11yActionWrapper doAction: action ofElement: actionResponder ];
937     }
940 -(NSArray *)accessibilityActionNames {
941     SAL_INFO("vcl.a11y", "[" << self << " accessibilityActionNames]");
942     NSArray * actionNames = nil;
943     AquaA11yWrapper * actionResponder = [ self actionResponder ];
944     if ( actionResponder ) {
945         actionNames = [ AquaA11yActionWrapper actionNamesForElement: actionResponder ];
946     } else {
947         actionNames = [ [ NSArray alloc ] init ];
948     }
949     return actionNames;
952 #pragma mark -
953 #pragma mark Hit Test
955 -(BOOL)isViewElement:(NSObject *)viewElement hitByPoint:(NSPoint)point {
956     bool hit = false;
957     NSAutoreleasePool * pool = [ [ NSAutoreleasePool alloc ] init ];
958     SAL_WNODEPRECATED_DECLARATIONS_PUSH
959         //TODO: 10.10 accessibilityAttributeValue:
960     NSValue * position = [ viewElement accessibilityAttributeValue: NSAccessibilityPositionAttribute ];
961     NSValue * size = [ viewElement accessibilityAttributeValue: NSAccessibilitySizeAttribute ];
962     SAL_WNODEPRECATED_DECLARATIONS_POP
963     if ( position && size ) {
964         float minX = [ position pointValue ].x;
965         float minY = [ position pointValue ].y;
966         float maxX = minX + [ size sizeValue ].width;
967         float maxY = minY + [ size sizeValue ].height;
968         if ( minX < point.x && maxX > point.x && minY < point.y && maxY > point.y ) {
969             hit = true;
970         }
971     }
972     [ pool release ];
973     return hit;
976 static Reference < XAccessibleContext > hitTestRunner ( css::awt::Point point,
977                                                  Reference < XAccessibleContext > const & rxAccessibleContext ) {
978     Reference < XAccessibleContext > hitChild;
979     Reference < XAccessibleContext > emptyReference;
980     try {
981         Reference < XAccessibleComponent > rxAccessibleComponent ( rxAccessibleContext, UNO_QUERY );
982         if ( rxAccessibleComponent.is() ) {
983             css::awt::Point location = rxAccessibleComponent -> getLocationOnScreen();
984             css::awt::Point hitPoint ( point.X - location.X , point.Y - location.Y);
985             Reference < XAccessible > rxAccessible = rxAccessibleComponent -> getAccessibleAtPoint ( hitPoint );
986             if ( rxAccessible.is() && rxAccessible -> getAccessibleContext().is() &&
987                  rxAccessible -> getAccessibleContext() -> getAccessibleChildCount() == 0 ) {
988                 hitChild = rxAccessible -> getAccessibleContext();
989             }
990         }
992         // iterate the hierarchy looking doing recursive hit testing.
993         // apparently necessary as a special treatment for e.g. comboboxes
994         if ( !hitChild.is() ) {
995             bool bSafeToIterate = true;
996             sal_Int32 nCount = rxAccessibleContext -> getAccessibleChildCount();
998             if (nCount < 0 || nCount > SAL_MAX_UINT16 /* slow enough for anyone */)
999                 bSafeToIterate = false;
1000             else { // manages descendants is an horror from the a11y standards guys.
1001                 Reference< XAccessibleStateSet > xStateSet;
1002                 xStateSet = rxAccessibleContext -> getAccessibleStateSet();
1003                 if (xStateSet.is() && xStateSet -> contains(AccessibleStateType::MANAGES_DESCENDANTS ) )
1004                     bSafeToIterate = false;
1005             }
1007             if( bSafeToIterate ) {
1008                 for ( int i = 0; i < rxAccessibleContext -> getAccessibleChildCount(); i++ ) {
1009                     Reference < XAccessible > rxAccessibleChild = rxAccessibleContext -> getAccessibleChild ( i );
1010                     if ( rxAccessibleChild.is() && rxAccessibleChild -> getAccessibleContext().is() && rxAccessibleChild -> getAccessibleContext() -> getAccessibleRole() != AccessibleRole::LIST ) {
1011                         Reference < XAccessibleContext > myHitChild = hitTestRunner ( point, rxAccessibleChild -> getAccessibleContext() );
1012                         if ( myHitChild.is() ) {
1013                             hitChild = myHitChild;
1014                             break;
1015                         }
1016                     }
1017                 }
1018             }
1019         }
1020     } catch ( RuntimeException ) {
1021         return emptyReference;
1022     }
1023     return hitChild;
1026 -(id)accessibilityHitTest:(NSPoint)point {
1027     SAL_INFO("vcl.a11y", "[" << self << " accessibilityHitTest:" << point << "]");
1028     static id wrapper = nil;
1029     if ( nil != wrapper ) {
1030         [ wrapper release ];
1031         wrapper = nil;
1032     }
1033     Reference < XAccessibleContext > hitChild;
1034     NSRect screenRect = [ [ NSScreen mainScreen ] frame ];
1035     css::awt::Point hitPoint ( static_cast<sal_Int32>(point.x) , static_cast<sal_Int32>(screenRect.size.height - point.y) );
1036     // check child windows first
1037     NSWindow * window = static_cast<NSWindow *>([ self accessibilityAttributeValue: NSAccessibilityWindowAttribute ]);
1038     NSArray * childWindows = [ window childWindows ];
1039     if ( [ childWindows count ] > 0 ) {
1040         NSWindow * element = nil;
1041         NSEnumerator * enumerator = [ childWindows objectEnumerator ];
1042         while ( ( element = [ enumerator nextObject ] ) && !hitChild.is() ) {
1043             if ( [ element isKindOfClass: [ SalFrameWindow class ] ] && [ self isViewElement: element hitByPoint: point ] ) {
1044                 // we have a child window that is hit
1045                 Reference < XAccessibleRelationSet > relationSet = [ static_cast<SalFrameWindow *>(element) accessibleContext ] -> getAccessibleRelationSet();
1046                 if ( relationSet.is() && relationSet -> containsRelation ( AccessibleRelationType::SUB_WINDOW_OF )) {
1047                     // we have a valid relation to the parent element
1048                     AccessibleRelation const relation = relationSet -> getRelationByType ( AccessibleRelationType::SUB_WINDOW_OF );
1049                     for ( const auto & i : relation.TargetSet ) {
1050                         Reference < XAccessible > rxAccessible ( i, UNO_QUERY );
1051                         if ( rxAccessible.is() && rxAccessible -> getAccessibleContext().is() ) {
1052                             // hit test for children of parent
1053                             hitChild = hitTestRunner ( hitPoint, rxAccessible -> getAccessibleContext() );
1054                             if (hitChild.is())
1055                                 break;
1056                         }
1057                     }
1058                 }
1059             }
1060         }
1061     }
1062     // nothing hit yet, so check ourself
1063     if ( ! hitChild.is() ) {
1064         if ( !mpReferenceWrapper ) {
1065             [ self setDefaults: [ self accessibleContext ] ];
1066         }
1067         hitChild = hitTestRunner ( hitPoint, mpReferenceWrapper -> rAccessibleContext );
1068     }
1069     if ( hitChild.is() ) {
1070         wrapper = [ AquaA11yFactory wrapperForAccessibleContext: hitChild ];
1071     }
1072     if ( wrapper ) {
1073         [ wrapper retain ]; // TODO: retain only when transient ?
1074     }
1075     return wrapper;
1078 #pragma mark -
1079 #pragma mark Access Methods
1081 -(XAccessibleAction *)accessibleAction {
1082     return mpReferenceWrapper -> rAccessibleAction.get();
1085 -(XAccessibleContext *)accessibleContext {
1086     return mpReferenceWrapper -> rAccessibleContext.get();
1089 -(XAccessibleComponent *)accessibleComponent {
1090     return mpReferenceWrapper -> rAccessibleComponent.get();
1093 -(XAccessibleExtendedComponent *)accessibleExtendedComponent {
1094     return mpReferenceWrapper -> rAccessibleExtendedComponent.get();
1097 -(XAccessibleSelection *)accessibleSelection {
1098     return mpReferenceWrapper -> rAccessibleSelection.get();
1101 -(XAccessibleTable *)accessibleTable {
1102     return mpReferenceWrapper -> rAccessibleTable.get();
1105 -(XAccessibleText *)accessibleText {
1106     return mpReferenceWrapper -> rAccessibleText.get();
1109 -(XAccessibleEditableText *)accessibleEditableText {
1110     return mpReferenceWrapper -> rAccessibleEditableText.get();
1113 -(XAccessibleValue *)accessibleValue {
1114     return mpReferenceWrapper -> rAccessibleValue.get();
1117 -(XAccessibleTextAttributes *)accessibleTextAttributes {
1118     return mpReferenceWrapper -> rAccessibleTextAttributes.get();
1121 -(XAccessibleMultiLineText *)accessibleMultiLineText {
1122     return mpReferenceWrapper -> rAccessibleMultiLineText.get();
1125 -(XAccessibleTextMarkup *)accessibleTextMarkup {
1126     return mpReferenceWrapper -> rAccessibleTextMarkup.get();
1129 -(NSWindow*)windowForParent {
1130     return [self window];
1133 -(void)setActsAsRadioGroup:(BOOL)actsAsRadioGroup {
1134     mActsAsRadioGroup = actsAsRadioGroup;
1137 -(BOOL)actsAsRadioGroup {
1138     return mActsAsRadioGroup;
1141 +(void)setPopupMenuOpen:(BOOL)popupMenuOpen {
1142     isPopupMenuOpen = popupMenuOpen;
1145 @end
1147 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */