Update ooo320-m1
[ooovba.git] / vcl / aqua / source / a11y / aqua11yfactory.mm
bloba49bce957b3bb63a6349c9f1738149ed3cc08d91
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  * 
5  * Copyright 2008 by Sun Microsystems, Inc.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * $RCSfile: aqua11yfactory.mm,v $
10  *
11  * $Revision: 1.3 $
12  *
13  * This file is part of OpenOffice.org.
14  *
15  * OpenOffice.org is free software: you can redistribute it and/or modify
16  * it under the terms of the GNU Lesser General Public License version 3
17  * only, as published by the Free Software Foundation.
18  *
19  * OpenOffice.org is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU Lesser General Public License version 3 for more details
23  * (a copy is included in the LICENSE file that accompanied this code).
24  *
25  * You should have received a copy of the GNU Lesser General Public License
26  * version 3 along with OpenOffice.org.  If not, see
27  * <http://www.openoffice.org/license.html>
28  * for a copy of the LGPLv3 License.
29  *
30  ************************************************************************/
32 // MARKER(update_precomp.py): autogen include statement, do not remove
33 #include "precompiled_vcl.hxx"
35 #include "salinst.h"
36 #include "aqua11yfactory.h"
37 #include "aqua11yfocuslistener.hxx"
38 #include "aqua11yfocustracker.hxx"
39 #include "aqua11yrolehelper.h"
40 #include "aqua11ywrapperbutton.h"
41 #include "aqua11ywrapperstatictext.h"
42 #include "aqua11ywrappertextarea.h"
43 #include "aqua11ywrappercheckbox.h"
44 #include "aqua11ywrappercombobox.h"
45 #include "aqua11ywrappergroup.h"
46 #include "aqua11ywrapperlist.h"
47 #include "aqua11ywrapperradiobutton.h"
48 #include "aqua11ywrapperradiogroup.h"
49 #include "aqua11ywrapperrow.h"
50 #include "aqua11ywrapperscrollarea.h"
51 #include "aqua11ywrapperscrollbar.h"
52 #include "aqua11ywrappersplitter.h"
53 #include "aqua11ywrappertabgroup.h"
54 #include "aqua11ywrappertoolbar.h"
55 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
57 using namespace ::com::sun::star::accessibility;
58 using namespace ::com::sun::star::uno;
60 static bool enabled = false; 
62 @implementation AquaA11yFactory : NSObject
64 #pragma mark -
65 #pragma mark Wrapper Repository
67 +(NSMutableDictionary *)allWrapper {
68     static NSMutableDictionary * mdAllWrapper = nil;
69     if ( mdAllWrapper == nil ) {
70         mdAllWrapper = [ [ [ NSMutableDictionary alloc ] init ] retain ];
71         // initialize keyboard focus tracker
72         rtl::Reference< AquaA11yFocusListener > listener( AquaA11yFocusListener::get() );
73         AquaA11yFocusTracker::get().setFocusListener(listener.get());
74         enabled = true;      
75     }
76     return mdAllWrapper;
79 +(NSValue *)keyForAccessibleContext: (Reference < XAccessibleContext >) rxAccessibleContext {
80     return [ NSValue valueWithPointer: rxAccessibleContext.get() ];
83 +(NSValue *)keyForAccessibleContextAsRadioGroup: (Reference < XAccessibleContext >) rxAccessibleContext {
84     return [ NSValue valueWithPointer: ( rxAccessibleContext.get() + 2 ) ];
87 +(AquaA11yWrapper *)wrapperForAccessible: (Reference < XAccessible >) rxAccessible {
88     if ( rxAccessible.is() ) {
89         Reference< XAccessibleContext > xAccessibleContext = rxAccessible->getAccessibleContext();
90         if( xAccessibleContext.is() ) {
91             return [ AquaA11yFactory wrapperForAccessibleContext: xAccessibleContext ];
92         }
93     }
94     return nil;
97 +(AquaA11yWrapper *)wrapperForAccessibleContext: (Reference < XAccessibleContext >) rxAccessibleContext {
98     return [ AquaA11yFactory wrapperForAccessibleContext: rxAccessibleContext createIfNotExists: YES asRadioGroup: NO ];
101 +(AquaA11yWrapper *)wrapperForAccessibleContext: (Reference < XAccessibleContext >) rxAccessibleContext createIfNotExists:(MacOSBOOL) bCreate {
102     return [ AquaA11yFactory wrapperForAccessibleContext: rxAccessibleContext createIfNotExists: bCreate asRadioGroup: NO ];
105 +(AquaA11yWrapper *)wrapperForAccessibleContext: (Reference < XAccessibleContext >) rxAccessibleContext createIfNotExists:(MacOSBOOL) bCreate asRadioGroup:(MacOSBOOL) asRadioGroup{
106     NSMutableDictionary * dAllWrapper = [ AquaA11yFactory allWrapper ];
107     NSValue * nKey = nil;
108     if ( asRadioGroup ) {
109         nKey = [ AquaA11yFactory keyForAccessibleContextAsRadioGroup: rxAccessibleContext ];
110     } else {
111         nKey = [ AquaA11yFactory keyForAccessibleContext: rxAccessibleContext ];
112     }
113     AquaA11yWrapper * aWrapper = (AquaA11yWrapper *) [ dAllWrapper objectForKey: nKey ];
114     if ( aWrapper != nil ) {
115         [ aWrapper retain ];
116     } else if ( bCreate ) {
117         NSString * nativeRole = [ AquaA11yRoleHelper getNativeRoleFrom: rxAccessibleContext.get() ];
118         // TODO: reflection
119         if ( [ nativeRole isEqualToString: NSAccessibilityButtonRole ] ) {
120             aWrapper = [ [ AquaA11yWrapperButton alloc ] initWithAccessibleContext: rxAccessibleContext ];
121         } else if ( [ nativeRole isEqualToString: NSAccessibilityTextAreaRole ] ) {
122             aWrapper = [ [ AquaA11yWrapperTextArea alloc ] initWithAccessibleContext: rxAccessibleContext ];
123         } else if ( [ nativeRole isEqualToString: NSAccessibilityStaticTextRole ] ) {
124             aWrapper = [ [ AquaA11yWrapperStaticText alloc ] initWithAccessibleContext: rxAccessibleContext ];
125         } else if ( [ nativeRole isEqualToString: NSAccessibilityComboBoxRole ] ) {
126             aWrapper = [ [ AquaA11yWrapperComboBox alloc ] initWithAccessibleContext: rxAccessibleContext ];
127         } else if ( [ nativeRole isEqualToString: NSAccessibilityGroupRole ] ) {
128             aWrapper = [ [ AquaA11yWrapperGroup alloc ] initWithAccessibleContext: rxAccessibleContext ];
129         } else if ( [ nativeRole isEqualToString: NSAccessibilityToolbarRole ] ) {
130             aWrapper = [ [ AquaA11yWrapperToolbar alloc ] initWithAccessibleContext: rxAccessibleContext ];
131         } else if ( [ nativeRole isEqualToString: NSAccessibilityScrollAreaRole ] ) {
132             aWrapper = [ [ AquaA11yWrapperScrollArea alloc ] initWithAccessibleContext: rxAccessibleContext ];
133         } else if ( [ nativeRole isEqualToString: NSAccessibilityTabGroupRole ] ) {
134             aWrapper = [ [ AquaA11yWrapperTabGroup alloc ] initWithAccessibleContext: rxAccessibleContext ];
135         } else if ( [ nativeRole isEqualToString: NSAccessibilityScrollBarRole ] ) {
136             aWrapper = [ [ AquaA11yWrapperScrollBar alloc ] initWithAccessibleContext: rxAccessibleContext ];
137         } else if ( [ nativeRole isEqualToString: NSAccessibilityCheckBoxRole ] ) {
138             aWrapper = [ [ AquaA11yWrapperCheckBox alloc ] initWithAccessibleContext: rxAccessibleContext ];
139         } else if ( [ nativeRole isEqualToString: NSAccessibilityRadioGroupRole ] ) {
140             aWrapper = [ [ AquaA11yWrapperRadioGroup alloc ] initWithAccessibleContext: rxAccessibleContext ];
141         } else if ( [ nativeRole isEqualToString: NSAccessibilityRadioButtonRole ] ) {
142             aWrapper = [ [ AquaA11yWrapperRadioButton alloc ] initWithAccessibleContext: rxAccessibleContext ];
143         } else if ( [ nativeRole isEqualToString: NSAccessibilityRowRole ] ) {
144             aWrapper = [ [ AquaA11yWrapperRow alloc ] initWithAccessibleContext: rxAccessibleContext ];
145         } else if ( [ nativeRole isEqualToString: NSAccessibilityListRole ] ) {
146             aWrapper = [ [ AquaA11yWrapperList alloc ] initWithAccessibleContext: rxAccessibleContext ];
147         } else if ( [ nativeRole isEqualToString: NSAccessibilitySplitterRole ] ) {
148             aWrapper = [ [ AquaA11yWrapperSplitter alloc ] initWithAccessibleContext: rxAccessibleContext ];
149         } else {
150             aWrapper = [ [ AquaA11yWrapper alloc ] initWithAccessibleContext: rxAccessibleContext ];
151         }
152         [ nativeRole release ];
153         [ aWrapper setActsAsRadioGroup: asRadioGroup ];
154         #if 0
155         /* #i102033# NSAccessibility does not seemt to know an equivalent for transient children.
156            That means we need to cache this, else e.g. tree list boxes are not accessible (moreover
157            it crashes by notifying dead objects - which would seemt o be another bug)
158            
159            FIXME:
160            Unfortunately this can increase memory consumption drastically until the non transient parent
161            is destroyed an finally all the transients are released.
162         */
163         if ( ! rxAccessibleContext -> getAccessibleStateSet() -> contains ( AccessibleStateType::TRANSIENT ) )
164         #endif
165         {
166             [ dAllWrapper setObject: aWrapper forKey: nKey ];
167         }
168     }
169     return aWrapper;
172 +(void)insertIntoWrapperRepository: (NSView *) viewElement forAccessibleContext: (Reference < XAccessibleContext >) rxAccessibleContext {
173     NSMutableDictionary * dAllWrapper = [ AquaA11yFactory allWrapper ];
174     [ dAllWrapper setObject: viewElement forKey: [ AquaA11yFactory keyForAccessibleContext: rxAccessibleContext ] ];
177 +(void)removeFromWrapperRepositoryFor: (::com::sun::star::uno::Reference < ::com::sun::star::accessibility::XAccessibleContext >) rxAccessibleContext {
178     // TODO: when RADIO_BUTTON search for associated RadioGroup-wrapper and delete that as well
179     AquaA11yWrapper * theWrapper = [ AquaA11yFactory wrapperForAccessibleContext: rxAccessibleContext createIfNotExists: NO ];
180     if ( theWrapper != nil ) {
181         [ [ AquaA11yFactory allWrapper ] removeObjectForKey: [ AquaA11yFactory keyForAccessibleContext: rxAccessibleContext ] ];
182         [ theWrapper release ];
183     }
186 +(void)registerView: (NSView *) theView {
187     if ( enabled && [ theView isKindOfClass: [ AquaA11yWrapper class ] ] ) {
188         // insertIntoWrapperRepository gets called from SalFrameView itself to bootstrap the bridge initially
189         [ (AquaA11yWrapper *) theView accessibleContext ];
190     }
193 +(void)revokeView: (NSView *) theView {
194     if ( enabled && [ theView isKindOfClass: [ AquaA11yWrapper class ] ] ) {
195         [ AquaA11yFactory removeFromWrapperRepositoryFor: [ (AquaA11yWrapper *) theView accessibleContext ] ];
196     }
199 @end