1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: aqua11yfactory.mm,v $
13 * This file is part of OpenOffice.org.
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.
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).
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.
30 ************************************************************************/
32 // MARKER(update_precomp.py): autogen include statement, do not remove
33 #include "precompiled_vcl.hxx"
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
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());
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 ];
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 ];
111 nKey = [ AquaA11yFactory keyForAccessibleContext: rxAccessibleContext ];
113 AquaA11yWrapper * aWrapper = (AquaA11yWrapper *) [ dAllWrapper objectForKey: nKey ];
114 if ( aWrapper != nil ) {
116 } else if ( bCreate ) {
117 NSString * nativeRole = [ AquaA11yRoleHelper getNativeRoleFrom: rxAccessibleContext.get() ];
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 ];
150 aWrapper = [ [ AquaA11yWrapper alloc ] initWithAccessibleContext: rxAccessibleContext ];
152 [ nativeRole release ];
153 [ aWrapper setActsAsRadioGroup: asRadioGroup ];
154 if ( ! rxAccessibleContext -> getAccessibleStateSet() -> contains ( AccessibleStateType::TRANSIENT ) ) {
155 [ dAllWrapper setObject: aWrapper forKey: nKey ];
161 +(void)insertIntoWrapperRepository: (NSView *) viewElement forAccessibleContext: (Reference < XAccessibleContext >) rxAccessibleContext {
162 NSMutableDictionary * dAllWrapper = [ AquaA11yFactory allWrapper ];
163 [ dAllWrapper setObject: viewElement forKey: [ AquaA11yFactory keyForAccessibleContext: rxAccessibleContext ] ];
166 +(void)removeFromWrapperRepositoryFor: (::com::sun::star::uno::Reference < ::com::sun::star::accessibility::XAccessibleContext >) rxAccessibleContext {
167 // TODO: when RADIO_BUTTON search for associated RadioGroup-wrapper and delete that as well
168 AquaA11yWrapper * theWrapper = [ AquaA11yFactory wrapperForAccessibleContext: rxAccessibleContext createIfNotExists: NO ];
169 if ( theWrapper != nil ) {
170 [ [ AquaA11yFactory allWrapper ] removeObjectForKey: [ AquaA11yFactory keyForAccessibleContext: rxAccessibleContext ] ];
171 [ theWrapper release ];
175 +(void)registerView: (NSView *) theView {
176 if ( enabled && [ theView isKindOfClass: [ AquaA11yWrapper class ] ] ) {
177 // insertIntoWrapperRepository gets called from SalFrameView itself to bootstrap the bridge initially
178 [ (AquaA11yWrapper *) theView accessibleContext ];
182 +(void)revokeView: (NSView *) theView {
183 if ( enabled && [ theView isKindOfClass: [ AquaA11yWrapper class ] ] ) {
184 [ AquaA11yFactory removeFromWrapperRepositoryFor: [ (AquaA11yWrapper *) theView accessibleContext ] ];