xref: /core/vcl/osx/a11yrolehelper.mm (revision 0735a430)
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 */
19
20
21#include <osx/a11yfactory.h>
22
23#include "a11yrolehelper.h"
24
25#include <com/sun/star/accessibility/AccessibleRole.hpp>
26#include <com/sun/star/accessibility/AccessibleStateType.hpp>
27#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
28
29#include <sal/log.hxx>
30
31using namespace ::com::sun::star::accessibility;
32using namespace ::com::sun::star::lang;
33using namespace ::com::sun::star::uno;
34
35@implementation AquaA11yRoleHelper
36
37+(id)simpleMapNativeRoleFrom: (XAccessibleContext *) accessibleContext {
38    id nativeRole = nil;
39
40    if (accessibleContext == nullptr)
41        return nativeRole;
42
43    switch( accessibleContext -> getAccessibleRole() ) {
44#define MAP(a,b) \
45        case a: nativeRole = b; break
46
47        MAP( AccessibleRole::UNKNOWN, NSAccessibilityUnknownRole );
48        MAP( AccessibleRole::ALERT, NSAccessibilityUnknownRole ); // FIXME
49        MAP( AccessibleRole::BLOCK_QUOTE, NSAccessibilityTextAreaRole );
50        MAP( AccessibleRole::COLUMN_HEADER, NSAccessibilityColumnRole );
51        MAP( AccessibleRole::CANVAS, NSAccessibilityUnknownRole ); // FIXME
52        MAP( AccessibleRole::CHECK_BOX, NSAccessibilityCheckBoxRole );
53        MAP( AccessibleRole::CHECK_MENU_ITEM, NSAccessibilityUnknownRole ); // FIXME
54        MAP( AccessibleRole::COLOR_CHOOSER, NSAccessibilityColorWellRole ); // FIXME
55        MAP( AccessibleRole::COMBO_BOX, NSAccessibilityComboBoxRole );
56        MAP( AccessibleRole::DATE_EDITOR, NSAccessibilityUnknownRole ); // FIXME
57        MAP( AccessibleRole::DESKTOP_ICON, NSAccessibilityUnknownRole ); // FIXME
58        MAP( AccessibleRole::DESKTOP_PANE, NSAccessibilityUnknownRole ); // FIXME
59        MAP( AccessibleRole::DIRECTORY_PANE, NSAccessibilityUnknownRole ); // FIXME
60        MAP( AccessibleRole::DIALOG, NSAccessibilityGroupRole );
61        MAP( AccessibleRole::DOCUMENT, NSAccessibilityGroupRole );
62        MAP( AccessibleRole::EMBEDDED_OBJECT, NSAccessibilityUnknownRole ); // FIXME
63        MAP( AccessibleRole::END_NOTE, NSAccessibilityUnknownRole ); // FIXME
64        MAP( AccessibleRole::FILE_CHOOSER, NSAccessibilityUnknownRole ); // FIXME
65        MAP( AccessibleRole::FILLER, NSAccessibilityUnknownRole ); // FIXME
66        MAP( AccessibleRole::FONT_CHOOSER, NSAccessibilityUnknownRole ); // FIXME
67        MAP( AccessibleRole::FOOTER, NSAccessibilityGroupRole ); // FIXME
68        MAP( AccessibleRole::FOOTNOTE, NSAccessibilityUnknownRole ); // FIXME
69        MAP( AccessibleRole::FRAME, NSAccessibilityWindowRole );
70        MAP( AccessibleRole::GLASS_PANE, NSAccessibilityUnknownRole ); // FIXME
71        MAP( AccessibleRole::GRAPHIC, NSAccessibilityImageRole );
72        MAP( AccessibleRole::GROUP_BOX, NSAccessibilityGroupRole );
73        MAP( AccessibleRole::HEADER, NSAccessibilityGroupRole ); // FIXME
74        MAP( AccessibleRole::HEADING, NSAccessibilityTextAreaRole ); // FIXME
75        MAP( AccessibleRole::HYPER_LINK, NSAccessibilityLinkRole );
76        MAP( AccessibleRole::ICON, NSAccessibilityImageRole );
77        MAP( AccessibleRole::INTERNAL_FRAME, NSAccessibilityUnknownRole ); // FIXME
78        MAP( AccessibleRole::LABEL, NSAccessibilityStaticTextRole );
79        MAP( AccessibleRole::LAYERED_PANE, NSAccessibilityUnknownRole ); // FIXME
80        MAP( AccessibleRole::LIST, NSAccessibilityMenuRole );
81        MAP( AccessibleRole::LIST_ITEM, NSAccessibilityMenuItemRole );
82        MAP( AccessibleRole::MENU, NSAccessibilityMenuRole );
83        MAP( AccessibleRole::MENU_BAR, NSAccessibilityMenuBarRole );
84        MAP( AccessibleRole::MENU_ITEM, NSAccessibilityMenuItemRole );
85        MAP( AccessibleRole::OPTION_PANE, NSAccessibilityUnknownRole ); // FIXME
86        MAP( AccessibleRole::PAGE_TAB, NSAccessibilityButtonRole );
87        MAP( AccessibleRole::PAGE_TAB_LIST, NSAccessibilityTabGroupRole );
88        MAP( AccessibleRole::PANEL, NSAccessibilityGroupRole );
89        MAP( AccessibleRole::PARAGRAPH, NSAccessibilityTextAreaRole );
90        MAP( AccessibleRole::PASSWORD_TEXT, NSAccessibilityTextFieldRole );
91        MAP( AccessibleRole::POPUP_MENU, NSAccessibilityMenuRole );
92        MAP( AccessibleRole::PUSH_BUTTON, NSAccessibilityButtonRole );
93        MAP( AccessibleRole::PROGRESS_BAR, NSAccessibilityProgressIndicatorRole );
94        MAP( AccessibleRole::RADIO_BUTTON, NSAccessibilityRadioButtonRole );
95        MAP( AccessibleRole::RADIO_MENU_ITEM, NSAccessibilityUnknownRole ); // FIXME
96        MAP( AccessibleRole::ROW_HEADER, NSAccessibilityRowRole );
97        MAP( AccessibleRole::ROOT_PANE, NSAccessibilityUnknownRole ); // FIXME
98        MAP( AccessibleRole::SCROLL_BAR, NSAccessibilityScrollBarRole );
99        MAP( AccessibleRole::SCROLL_PANE, NSAccessibilityScrollAreaRole );
100        MAP( AccessibleRole::SHAPE, NSAccessibilityUnknownRole ); // FIXME
101        MAP( AccessibleRole::SEPARATOR, NSAccessibilitySplitterRole ); // FIXME
102        MAP( AccessibleRole::SLIDER, NSAccessibilitySliderRole );
103        MAP( AccessibleRole::SPIN_BOX, NSAccessibilityUnknownRole ); // FIXME
104        MAP( AccessibleRole::SPLIT_PANE, NSAccessibilitySplitGroupRole );
105        MAP( AccessibleRole::STATUS_BAR, NSAccessibilityGroupRole ); // FIXME
106        MAP( AccessibleRole::TABLE, NSAccessibilityTableRole );
107        MAP( AccessibleRole::TABLE_CELL, NSAccessibilityTextFieldRole );
108        MAP( AccessibleRole::TEXT, NSAccessibilityTextAreaRole );
109        MAP( AccessibleRole::TEXT_FRAME, NSAccessibilityGroupRole );
110        MAP( AccessibleRole::TOGGLE_BUTTON, NSAccessibilityCheckBoxRole );
111        MAP( AccessibleRole::TOOL_BAR, NSAccessibilityToolbarRole );
112        MAP( AccessibleRole::TOOL_TIP, NSAccessibilityUnknownRole ); // FIXME
113        MAP( AccessibleRole::TREE, NSAccessibilityGroupRole );
114        MAP( AccessibleRole::VIEW_PORT, NSAccessibilityUnknownRole ); // FIXME
115        MAP( AccessibleRole::WINDOW, NSAccessibilityWindowRole );
116
117        MAP( AccessibleRole::BUTTON_DROPDOWN, NSAccessibilityMenuButtonRole );
118        MAP( AccessibleRole::BUTTON_MENU, NSAccessibilityMenuButtonRole );
119        MAP( AccessibleRole::CAPTION, NSAccessibilityUnknownRole );
120        MAP( AccessibleRole::CHART, NSAccessibilityUnknownRole );
121        MAP( AccessibleRole::FORM, NSAccessibilityUnknownRole );
122        MAP( AccessibleRole::IMAGE_MAP, NSAccessibilityUnknownRole );
123        MAP( AccessibleRole::NOTE, NSAccessibilityUnknownRole );
124        MAP( AccessibleRole::PAGE, NSAccessibilityUnknownRole );
125        MAP( AccessibleRole::RULER, NSAccessibilityUnknownRole );
126        MAP( AccessibleRole::SECTION, NSAccessibilityUnknownRole );
127        MAP( AccessibleRole::TREE_ITEM, NSAccessibilityUnknownRole );
128        MAP( AccessibleRole::TREE_TABLE, NSAccessibilityUnknownRole );
129
130        MAP( AccessibleRole::DOCUMENT_PRESENTATION, NSAccessibilityGroupRole );
131        MAP( AccessibleRole::DOCUMENT_SPREADSHEET, NSAccessibilityGroupRole );
132        MAP( AccessibleRole::DOCUMENT_TEXT, NSAccessibilityGroupRole );
133        MAP( AccessibleRole::STATIC, NSAccessibilityStaticTextRole );
134        MAP( AccessibleRole::NOTIFICATION, NSAccessibilityStaticTextRole );
135
136#undef MAP
137        default:
138            break;
139    }
140    return nativeRole;
141}
142
143+(id)getNativeRoleFrom: (XAccessibleContext *) accessibleContext {
144    id nativeRole = [ AquaA11yRoleHelper simpleMapNativeRoleFrom: accessibleContext ];
145    if ( accessibleContext -> getAccessibleRole() == AccessibleRole::LABEL ) {
146        if ( accessibleContext -> getAccessibleChildCount() > 0 ) {
147            nativeRole = NSAccessibilityOutlineRole;
148        } else if ( accessibleContext -> getAccessibleParent().is() ) {
149            Reference < XAccessibleContext > rxParentContext = accessibleContext -> getAccessibleParent() -> getAccessibleContext();
150            if ( rxParentContext.is() ) {
151                NSString * roleParent = static_cast<NSString *>([ AquaA11yRoleHelper simpleMapNativeRoleFrom: rxParentContext.get() ]);
152                if ( [ roleParent isEqualToString: NSAccessibilityOutlineRole ] ) {
153                    nativeRole = NSAccessibilityRowRole;
154                }
155            }
156        }
157    } else if ( accessibleContext -> getAccessibleRole() == AccessibleRole::COMBO_BOX ) {
158        try {
159            Reference < XAccessible > rxAccessible = accessibleContext -> getAccessibleChild(0);
160            if ( rxAccessible.is() ) {
161                Reference < XAccessibleContext > rxAccessibleContext = rxAccessible -> getAccessibleContext();
162                if ( rxAccessibleContext.is() && rxAccessibleContext -> getAccessibleRole() == AccessibleRole::TEXT ) {
163                    sal_Int64 nStateSet = rxAccessibleContext -> getAccessibleStateSet();
164                    if ( !(nStateSet & AccessibleStateType::EDITABLE ) ) {
165                        nativeRole = NSAccessibilityPopUpButtonRole;
166                    }
167                }
168            }
169        }
170        catch (const IndexOutOfBoundsException&)
171        {
172            SAL_WARN("vcl", "No valid accessible objects in parent");
173        }
174    }
175    return nativeRole;
176}
177
178+(id)getNativeSubroleFrom: (sal_Int16) nRole {
179    id nativeSubrole = nil;
180    switch( nRole ) {
181#define MAP(a,b) \
182        case a: nativeSubrole = b; break
183
184        MAP( AccessibleRole::UNKNOWN, NSAccessibilityUnknownSubrole );
185        MAP( AccessibleRole::ALERT, NSAccessibilitySystemDialogSubrole );
186        MAP( AccessibleRole::BLOCK_QUOTE, @"" );
187        MAP( AccessibleRole::COLUMN_HEADER, @"" );
188        MAP( AccessibleRole::CANVAS, @"" );
189        MAP( AccessibleRole::CHECK_BOX, @"" );
190        MAP( AccessibleRole::CHECK_MENU_ITEM, @"" );
191        MAP( AccessibleRole::COLOR_CHOOSER, @"" );
192        MAP( AccessibleRole::COMBO_BOX, @"" );
193        MAP( AccessibleRole::DATE_EDITOR, @"" );
194        MAP( AccessibleRole::DESKTOP_ICON, @"" );
195        MAP( AccessibleRole::DESKTOP_PANE, @"" );
196        MAP( AccessibleRole::DIRECTORY_PANE, @"" );
197        MAP( AccessibleRole::DIALOG, NSAccessibilityDialogSubrole );
198        MAP( AccessibleRole::DOCUMENT, @"" );
199        MAP( AccessibleRole::EMBEDDED_OBJECT, @"" );
200        MAP( AccessibleRole::END_NOTE, @"" );
201        MAP( AccessibleRole::FILE_CHOOSER, @"" );
202        MAP( AccessibleRole::FILLER, @"" );
203        MAP( AccessibleRole::FONT_CHOOSER, @"" );
204        MAP( AccessibleRole::FOOTER, @"" );
205        MAP( AccessibleRole::FOOTNOTE, @"" );
206        MAP( AccessibleRole::FRAME, @"" );
207        MAP( AccessibleRole::GLASS_PANE, @"" );
208        MAP( AccessibleRole::GRAPHIC, @"" );
209        MAP( AccessibleRole::GROUP_BOX, @"" );
210        MAP( AccessibleRole::HEADER, @"" );
211        MAP( AccessibleRole::HEADING, @"" );
212        MAP( AccessibleRole::HYPER_LINK, NSAccessibilityTextLinkSubrole );
213        MAP( AccessibleRole::ICON, @"" );
214        MAP( AccessibleRole::INTERNAL_FRAME, @"" );
215        MAP( AccessibleRole::LABEL, @"" );
216        MAP( AccessibleRole::LAYERED_PANE, @"" );
217        MAP( AccessibleRole::LIST, @"" );
218        MAP( AccessibleRole::LIST_ITEM, NSAccessibilityOutlineRowSubrole );
219        MAP( AccessibleRole::MENU, @"" );
220        MAP( AccessibleRole::MENU_BAR, @"" );
221        MAP( AccessibleRole::MENU_ITEM, @"" );
222        MAP( AccessibleRole::OPTION_PANE, @"" );
223        MAP( AccessibleRole::PAGE_TAB, @"" );
224        MAP( AccessibleRole::PAGE_TAB_LIST, @"" );
225        MAP( AccessibleRole::PANEL, @"" );
226        MAP( AccessibleRole::PARAGRAPH, @"" );
227        MAP( AccessibleRole::PASSWORD_TEXT, NSAccessibilitySecureTextFieldSubrole );
228        MAP( AccessibleRole::POPUP_MENU, @"" );
229        MAP( AccessibleRole::PUSH_BUTTON, @"" );
230        MAP( AccessibleRole::PROGRESS_BAR, @"" );
231        MAP( AccessibleRole::RADIO_BUTTON, @"" );
232        MAP( AccessibleRole::RADIO_MENU_ITEM, @"" );
233        MAP( AccessibleRole::ROW_HEADER, @"" );
234        MAP( AccessibleRole::ROOT_PANE, @"" );
235        MAP( AccessibleRole::SCROLL_BAR, @"" );
236        MAP( AccessibleRole::SCROLL_PANE, @"" );
237        MAP( AccessibleRole::SHAPE, @"" );
238        MAP( AccessibleRole::SEPARATOR, @"" );
239        MAP( AccessibleRole::SLIDER, @"" );
240        MAP( AccessibleRole::SPIN_BOX, @"" );
241        MAP( AccessibleRole::SPLIT_PANE, @"" );
242        MAP( AccessibleRole::STATUS_BAR, @"" );
243        MAP( AccessibleRole::TABLE, @"" );
244        MAP( AccessibleRole::TABLE_CELL, @"" );
245        MAP( AccessibleRole::TEXT, @"" );
246        MAP( AccessibleRole::TEXT_FRAME, @"" );
247        MAP( AccessibleRole::TOGGLE_BUTTON, @"" );
248        MAP( AccessibleRole::TOOL_BAR, @"" );
249        MAP( AccessibleRole::TOOL_TIP, @"" );
250        MAP( AccessibleRole::TREE, @"" );
251        MAP( AccessibleRole::VIEW_PORT, @"" );
252        MAP( AccessibleRole::WINDOW, NSAccessibilityStandardWindowSubrole );
253
254        MAP( AccessibleRole::BUTTON_DROPDOWN, @"" );
255        MAP( AccessibleRole::BUTTON_MENU, @"" );
256        MAP( AccessibleRole::CAPTION, @"" );
257        MAP( AccessibleRole::CHART, @"" );
258        MAP( AccessibleRole::FORM, @"" );
259        MAP( AccessibleRole::IMAGE_MAP, @"" );
260        MAP( AccessibleRole::NOTE, @"" );
261        MAP( AccessibleRole::PAGE, @"" );
262        MAP( AccessibleRole::RULER, @"" );
263        MAP( AccessibleRole::SECTION, @"" );
264        MAP( AccessibleRole::TREE_ITEM, @"" );
265        MAP( AccessibleRole::TREE_TABLE, @"" );
266
267        MAP( AccessibleRole::DOCUMENT_PRESENTATION, @"" );
268        MAP( AccessibleRole::DOCUMENT_SPREADSHEET, @"" );
269        MAP( AccessibleRole::DOCUMENT_TEXT, @"" );
270
271        MAP( AccessibleRole::STATIC, @"" );
272        MAP( AccessibleRole::NOTIFICATION, @"" );
273
274#undef MAP
275        default:
276            break;
277    }
278    return nativeSubrole;
279}
280
281+(id)getRoleDescriptionFrom: (NSString *) role with: (NSString *) subRole {
282    id roleDescription;
283    if ( [ subRole length ] == 0 )
284        roleDescription = NSAccessibilityRoleDescription( role, nil );
285    else
286        roleDescription = NSAccessibilityRoleDescription( role, subRole );
287    return roleDescription;
288}
289
290@end
291
292/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
293