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