1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <test/a11y/AccessibilityTools.hxx>
22 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
23 #include <com/sun/star/accessibility/AccessibleRelationType.hpp>
24 #include <com/sun/star/accessibility/AccessibleRole.hpp>
25 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
26 #include <com/sun/star/accessibility/XAccessible.hpp>
27 #include <com/sun/star/accessibility/XAccessibleAction.hpp>
28 #include <com/sun/star/accessibility/XAccessibleContext.hpp>
29 #include <com/sun/star/awt/KeyModifier.hpp>
31 #include <rtl/ustrbuf.hxx>
32 #include <sal/log.hxx>
33 #include <vcl/accessibility/vclxaccessiblecomponent.hxx>
34 #include <vcl/scheduler.hxx>
35 #include <vcl/timer.hxx>
36 #include <vcl/window.hxx>
37 #include <o3tl/string_view.hxx>
41 uno::Reference
<accessibility::XAccessibleContext
>
42 AccessibilityTools::getAccessibleObjectForPredicate(
43 const uno::Reference
<accessibility::XAccessibleContext
>& xCtx
,
44 const std::function
<bool(const uno::Reference
<accessibility::XAccessibleContext
>&)>& cPredicate
)
52 sal_Int64 count
= xCtx
->getAccessibleChildCount();
54 for (sal_Int64 i
= 0; i
< count
&& i
< AccessibilityTools::MAX_CHILDREN
; i
++)
56 uno::Reference
<accessibility::XAccessibleContext
> xCtx2
57 = getAccessibleObjectForPredicate(xCtx
->getAccessibleChild(i
), cPredicate
);
65 uno::Reference
<accessibility::XAccessibleContext
>
66 AccessibilityTools::getAccessibleObjectForPredicate(
67 const uno::Reference
<accessibility::XAccessible
>& xAcc
,
68 const std::function
<bool(const uno::Reference
<accessibility::XAccessibleContext
>&)>& cPredicate
)
70 return getAccessibleObjectForPredicate(xAcc
->getAccessibleContext(), cPredicate
);
73 uno::Reference
<accessibility::XAccessibleContext
> AccessibilityTools::getAccessibleObjectForId(
74 const uno::Reference
<accessibility::XAccessibleContext
>& xCtx
, std::u16string_view sId
)
76 return getAccessibleObjectForPredicate(
77 xCtx
, [&](const uno::Reference
<accessibility::XAccessibleContext
>& xObjCtx
) {
78 uno::Reference
<accessibility::XAccessibleContext2
> xContext2(xObjCtx
, uno::UNO_QUERY
);
79 return (xContext2
&& xContext2
->getAccessibleId() == sId
);
83 css::uno::Reference
<css::accessibility::XAccessibleContext
>
84 AccessibilityTools::getAccessibleObjectForId(
85 const css::uno::Reference
<css::accessibility::XAccessible
>& xacc
, const std::u16string_view sId
)
87 return getAccessibleObjectForId(xacc
->getAccessibleContext(), sId
);
90 uno::Reference
<accessibility::XAccessibleContext
> AccessibilityTools::getAccessibleObjectForRole(
91 const uno::Reference
<accessibility::XAccessibleContext
>& xCtx
, sal_Int16 role
)
93 return getAccessibleObjectForPredicate(
94 xCtx
, [&role
](const uno::Reference
<accessibility::XAccessibleContext
>& xObjCtx
) {
95 return (xObjCtx
->getAccessibleRole() == role
96 && xObjCtx
->getAccessibleStateSet()
97 & accessibility::AccessibleStateType::SHOWING
);
101 css::uno::Reference
<css::accessibility::XAccessibleContext
>
102 AccessibilityTools::getAccessibleObjectForRole(
103 const css::uno::Reference
<css::accessibility::XAccessible
>& xacc
, sal_Int16 role
)
105 return getAccessibleObjectForRole(xacc
->getAccessibleContext(), role
);
108 /* this is basically the same as getAccessibleObjectForPredicate() but specialized for efficiency,
109 * and because the template version will not work with getAccessibleObjectForPredicate() anyway */
110 css::uno::Reference
<css::accessibility::XAccessibleContext
>
111 AccessibilityTools::getAccessibleObjectForName(
112 const css::uno::Reference
<css::accessibility::XAccessibleContext
>& xCtx
, const sal_Int16 role
,
113 std::u16string_view name
)
115 if (xCtx
->getAccessibleRole() == role
&& nameEquals(xCtx
, name
))
118 auto nChildren
= xCtx
->getAccessibleChildCount();
119 for (decltype(nChildren
) i
= 0; i
< nChildren
&& i
< AccessibilityTools::MAX_CHILDREN
; i
++)
121 if (auto xMatchChild
= getAccessibleObjectForName(xCtx
->getAccessibleChild(i
), role
, name
))
128 bool AccessibilityTools::equals(const uno::Reference
<accessibility::XAccessible
>& xacc1
,
129 const uno::Reference
<accessibility::XAccessible
>& xacc2
)
131 if (!xacc1
.is() || !xacc2
.is())
132 return xacc1
.is() == xacc2
.is();
133 return equals(xacc1
->getAccessibleContext(), xacc2
->getAccessibleContext());
136 bool AccessibilityTools::equals(const uno::Reference
<accessibility::XAccessibleContext
>& xctx1
,
137 const uno::Reference
<accessibility::XAccessibleContext
>& xctx2
)
139 if (!xctx1
.is() || !xctx2
.is())
140 return xctx1
.is() == xctx2
.is();
142 if (xctx1
->getAccessibleRole() != xctx2
->getAccessibleRole())
145 if (xctx1
->getAccessibleName() != xctx2
->getAccessibleName())
148 if (xctx1
->getAccessibleDescription() != xctx2
->getAccessibleDescription())
151 if (xctx1
->getAccessibleChildCount() != xctx2
->getAccessibleChildCount())
154 /* this one was not in the Java version */
155 if (xctx1
->getAccessibleIndexInParent() != xctx2
->getAccessibleIndexInParent())
158 /* because in Writer at least some children only are referenced by their relations to others
159 * objects, we need to account for that as their index in parent is incorrect (so not
160 * necessarily unique) */
161 auto relset1
= xctx1
->getAccessibleRelationSet();
162 auto relset2
= xctx2
->getAccessibleRelationSet();
163 if (relset1
.is() != relset2
.is())
165 else if (relset1
.is())
167 auto relCount1
= relset1
->getRelationCount();
168 auto relCount2
= relset2
->getRelationCount();
169 if (relCount1
!= relCount2
)
172 for (sal_Int32 i
= 0; i
< relCount1
; ++i
)
174 if (relset1
->getRelation(i
) != relset2
->getRelation(i
))
179 return equals(xctx1
->getAccessibleParent(), xctx2
->getAccessibleParent());
182 bool AccessibilityTools::nameEquals(const uno::Reference
<accessibility::XAccessibleContext
>& xCtx
,
183 const std::u16string_view name
)
185 auto ctxName
= xCtx
->getAccessibleName();
186 std::u16string_view rest
;
188 if (!o3tl::starts_with(ctxName
, name
, &rest
))
194 // see OAccessibleMenuItemComponent::GetAccessibleName():
195 // on Win32, ignore a \tSHORTCUT suffix on a menu item
196 switch (xCtx
->getAccessibleRole())
198 case accessibility::AccessibleRole::MENU_ITEM
:
199 case accessibility::AccessibleRole::RADIO_MENU_ITEM
:
200 case accessibility::AccessibleRole::CHECK_MENU_ITEM
:
201 return rest
[0] == '\t';
208 #if OSL_DEBUG_LEVEL > 0
209 // see VCLXAccessibleComponent::getAccessibleName()
210 static const char* pEnvAppendType
= getenv("LIBO_APPEND_WINDOW_TYPE_TO_ACCESSIBLE_NAME");
211 if (pEnvAppendType
&& OUString::createFromAscii(pEnvAppendType
) != u
"0")
213 auto pVCLXAccessibleComponent
= dynamic_cast<VCLXAccessibleComponent
*>(xCtx
.get());
214 if (pVCLXAccessibleComponent
)
216 auto windowType
= pVCLXAccessibleComponent
->GetWindow()->GetType();
218 == Concat2View(u
" (Type = " + OUString::number(static_cast<sal_Int32
>(windowType
))
227 static OUString
unknownName(const sal_Int64 value
)
229 return "unknown (" + OUString::number(value
) + ")";
232 OUString
AccessibilityTools::getRoleName(const sal_Int16 role
)
236 case accessibility::AccessibleRole::UNKNOWN
:
237 return u
"UNKNOWN"_ustr
;
238 case accessibility::AccessibleRole::ALERT
:
239 return u
"ALERT"_ustr
;
240 case accessibility::AccessibleRole::BLOCK_QUOTE
:
241 return u
"BLOCK_QUOTE"_ustr
;
242 case accessibility::AccessibleRole::BUTTON_DROPDOWN
:
243 return u
"BUTTON_DROPDOWN"_ustr
;
244 case accessibility::AccessibleRole::BUTTON_MENU
:
245 return u
"BUTTON_MENU"_ustr
;
246 case accessibility::AccessibleRole::CANVAS
:
247 return u
"CANVAS"_ustr
;
248 case accessibility::AccessibleRole::CAPTION
:
249 return u
"CAPTION"_ustr
;
250 case accessibility::AccessibleRole::CHART
:
251 return u
"CHART"_ustr
;
252 case accessibility::AccessibleRole::CHECK_BOX
:
253 return u
"CHECK_BOX"_ustr
;
254 case accessibility::AccessibleRole::CHECK_MENU_ITEM
:
255 return u
"CHECK_MENU_ITEM"_ustr
;
256 case accessibility::AccessibleRole::COLOR_CHOOSER
:
257 return u
"COLOR_CHOOSER"_ustr
;
258 case accessibility::AccessibleRole::COLUMN_HEADER
:
259 return u
"COLUMN_HEADER"_ustr
;
260 case accessibility::AccessibleRole::COMBO_BOX
:
261 return u
"COMBO_BOX"_ustr
;
262 case accessibility::AccessibleRole::COMMENT
:
263 return u
"COMMENT"_ustr
;
264 case accessibility::AccessibleRole::COMMENT_END
:
265 return u
"COMMENT_END"_ustr
;
266 case accessibility::AccessibleRole::DATE_EDITOR
:
267 return u
"DATE_EDITOR"_ustr
;
268 case accessibility::AccessibleRole::DESKTOP_ICON
:
269 return u
"DESKTOP_ICON"_ustr
;
270 case accessibility::AccessibleRole::DESKTOP_PANE
:
271 return u
"DESKTOP_PANE"_ustr
;
272 case accessibility::AccessibleRole::DIALOG
:
273 return u
"DIALOG"_ustr
;
274 case accessibility::AccessibleRole::DIRECTORY_PANE
:
275 return u
"DIRECTORY_PANE"_ustr
;
276 case accessibility::AccessibleRole::DOCUMENT
:
277 return u
"DOCUMENT"_ustr
;
278 case accessibility::AccessibleRole::DOCUMENT_PRESENTATION
:
279 return u
"DOCUMENT_PRESENTATION"_ustr
;
280 case accessibility::AccessibleRole::DOCUMENT_SPREADSHEET
:
281 return u
"DOCUMENT_SPREADSHEET"_ustr
;
282 case accessibility::AccessibleRole::DOCUMENT_TEXT
:
283 return u
"DOCUMENT_TEXT"_ustr
;
284 case accessibility::AccessibleRole::EDIT_BAR
:
285 return u
"EDIT_BAR"_ustr
;
286 case accessibility::AccessibleRole::EMBEDDED_OBJECT
:
287 return u
"EMBEDDED_OBJECT"_ustr
;
288 case accessibility::AccessibleRole::END_NOTE
:
289 return u
"END_NOTE"_ustr
;
290 case accessibility::AccessibleRole::FILE_CHOOSER
:
291 return u
"FILE_CHOOSER"_ustr
;
292 case accessibility::AccessibleRole::FILLER
:
293 return u
"FILLER"_ustr
;
294 case accessibility::AccessibleRole::FONT_CHOOSER
:
295 return u
"FONT_CHOOSER"_ustr
;
296 case accessibility::AccessibleRole::FOOTER
:
297 return u
"FOOTER"_ustr
;
298 case accessibility::AccessibleRole::FOOTNOTE
:
299 return u
"FOOTNOTE"_ustr
;
300 case accessibility::AccessibleRole::FORM
:
302 case accessibility::AccessibleRole::FRAME
:
303 return u
"FRAME"_ustr
;
304 case accessibility::AccessibleRole::GLASS_PANE
:
305 return u
"GLASS_PANE"_ustr
;
306 case accessibility::AccessibleRole::GRAPHIC
:
307 return u
"GRAPHIC"_ustr
;
308 case accessibility::AccessibleRole::GROUP_BOX
:
309 return u
"GROUP_BOX"_ustr
;
310 case accessibility::AccessibleRole::HEADER
:
311 return u
"HEADER"_ustr
;
312 case accessibility::AccessibleRole::HEADING
:
313 return u
"HEADING"_ustr
;
314 case accessibility::AccessibleRole::HYPER_LINK
:
315 return u
"HYPER_LINK"_ustr
;
316 case accessibility::AccessibleRole::ICON
:
318 case accessibility::AccessibleRole::IMAGE_MAP
:
319 return u
"IMAGE_MAP"_ustr
;
320 case accessibility::AccessibleRole::INTERNAL_FRAME
:
321 return u
"INTERNAL_FRAME"_ustr
;
322 case accessibility::AccessibleRole::LABEL
:
323 return u
"LABEL"_ustr
;
324 case accessibility::AccessibleRole::LAYERED_PANE
:
325 return u
"LAYERED_PANE"_ustr
;
326 case accessibility::AccessibleRole::LIST
:
328 case accessibility::AccessibleRole::LIST_ITEM
:
329 return u
"LIST_ITEM"_ustr
;
330 case accessibility::AccessibleRole::MENU
:
332 case accessibility::AccessibleRole::MENU_BAR
:
333 return u
"MENU_BAR"_ustr
;
334 case accessibility::AccessibleRole::MENU_ITEM
:
335 return u
"MENU_ITEM"_ustr
;
336 case accessibility::AccessibleRole::NOTE
:
338 case accessibility::AccessibleRole::OPTION_PANE
:
339 return u
"OPTION_PANE"_ustr
;
340 case accessibility::AccessibleRole::PAGE
:
342 case accessibility::AccessibleRole::PAGE_TAB
:
343 return u
"PAGE_TAB"_ustr
;
344 case accessibility::AccessibleRole::PAGE_TAB_LIST
:
345 return u
"PAGE_TAB_LIST"_ustr
;
346 case accessibility::AccessibleRole::PANEL
:
347 return u
"PANEL"_ustr
;
348 case accessibility::AccessibleRole::PARAGRAPH
:
349 return u
"PARAGRAPH"_ustr
;
350 case accessibility::AccessibleRole::PASSWORD_TEXT
:
351 return u
"PASSWORD_TEXT"_ustr
;
352 case accessibility::AccessibleRole::POPUP_MENU
:
353 return u
"POPUP_MENU"_ustr
;
354 case accessibility::AccessibleRole::PROGRESS_BAR
:
355 return u
"PROGRESS_BAR"_ustr
;
356 case accessibility::AccessibleRole::PUSH_BUTTON
:
357 return u
"PUSH_BUTTON"_ustr
;
358 case accessibility::AccessibleRole::RADIO_BUTTON
:
359 return u
"RADIO_BUTTON"_ustr
;
360 case accessibility::AccessibleRole::RADIO_MENU_ITEM
:
361 return u
"RADIO_MENU_ITEM"_ustr
;
362 case accessibility::AccessibleRole::ROOT_PANE
:
363 return u
"ROOT_PANE"_ustr
;
364 case accessibility::AccessibleRole::ROW_HEADER
:
365 return u
"ROW_HEADER"_ustr
;
366 case accessibility::AccessibleRole::RULER
:
367 return u
"RULER"_ustr
;
368 case accessibility::AccessibleRole::SCROLL_BAR
:
369 return u
"SCROLL_BAR"_ustr
;
370 case accessibility::AccessibleRole::SCROLL_PANE
:
371 return u
"SCROLL_PANE"_ustr
;
372 case accessibility::AccessibleRole::SECTION
:
373 return u
"SECTION"_ustr
;
374 case accessibility::AccessibleRole::SEPARATOR
:
375 return u
"SEPARATOR"_ustr
;
376 case accessibility::AccessibleRole::SHAPE
:
377 return u
"SHAPE"_ustr
;
378 case accessibility::AccessibleRole::SLIDER
:
379 return u
"SLIDER"_ustr
;
380 case accessibility::AccessibleRole::SPIN_BOX
:
381 return u
"SPIN_BOX"_ustr
;
382 case accessibility::AccessibleRole::SPLIT_PANE
:
383 return u
"SPLIT_PANE"_ustr
;
384 case accessibility::AccessibleRole::STATIC
:
385 return u
"STATIC"_ustr
;
386 case accessibility::AccessibleRole::STATUS_BAR
:
387 return u
"STATUS_BAR"_ustr
;
388 case accessibility::AccessibleRole::TABLE
:
389 return u
"TABLE"_ustr
;
390 case accessibility::AccessibleRole::TABLE_CELL
:
391 return u
"TABLE_CELL"_ustr
;
392 case accessibility::AccessibleRole::TEXT
:
394 case accessibility::AccessibleRole::TEXT_FRAME
:
395 return u
"TEXT_FRAME"_ustr
;
396 case accessibility::AccessibleRole::TOGGLE_BUTTON
:
397 return u
"TOGGLE_BUTTON"_ustr
;
398 case accessibility::AccessibleRole::TOOL_BAR
:
399 return u
"TOOL_BAR"_ustr
;
400 case accessibility::AccessibleRole::TOOL_TIP
:
401 return u
"TOOL_TIP"_ustr
;
402 case accessibility::AccessibleRole::TREE
:
404 case accessibility::AccessibleRole::TREE_ITEM
:
405 return u
"TREE_ITEM"_ustr
;
406 case accessibility::AccessibleRole::TREE_TABLE
:
407 return u
"TREE_TABLE"_ustr
;
408 case accessibility::AccessibleRole::VIEW_PORT
:
409 return u
"VIEW_PORT"_ustr
;
410 case accessibility::AccessibleRole::WINDOW
:
411 return u
"WINDOW"_ustr
;
413 return unknownName(role
);
416 OUString
AccessibilityTools::debugAccessibleStateSet(const sal_Int64 nCombinedState
)
418 OUString combinedName
;
420 for (int i
= 0; i
< 63; i
++)
422 sal_Int64 state
= sal_Int64(1) << i
;
423 if (!(state
& nCombinedState
))
428 case accessibility::AccessibleStateType::ACTIVE
:
431 case accessibility::AccessibleStateType::ARMED
:
434 case accessibility::AccessibleStateType::BUSY
:
437 case accessibility::AccessibleStateType::CHECKABLE
:
440 case accessibility::AccessibleStateType::CHECKED
:
443 case accessibility::AccessibleStateType::COLLAPSE
:
446 case accessibility::AccessibleStateType::DEFAULT
:
449 case accessibility::AccessibleStateType::DEFUNC
:
452 case accessibility::AccessibleStateType::EDITABLE
:
455 case accessibility::AccessibleStateType::ENABLED
:
458 case accessibility::AccessibleStateType::EXPANDABLE
:
461 case accessibility::AccessibleStateType::EXPANDED
:
464 case accessibility::AccessibleStateType::FOCUSABLE
:
467 case accessibility::AccessibleStateType::FOCUSED
:
470 case accessibility::AccessibleStateType::HORIZONTAL
:
473 case accessibility::AccessibleStateType::ICONIFIED
:
476 case accessibility::AccessibleStateType::INDETERMINATE
:
477 name
= "INDETERMINATE";
479 case accessibility::AccessibleStateType::INVALID
:
482 case accessibility::AccessibleStateType::MANAGES_DESCENDANTS
:
483 name
= "MANAGES_DESCENDANTS";
485 case accessibility::AccessibleStateType::MODAL
:
488 case accessibility::AccessibleStateType::MOVEABLE
:
491 case accessibility::AccessibleStateType::MULTI_LINE
:
494 case accessibility::AccessibleStateType::MULTI_SELECTABLE
:
495 name
= "MULTI_SELECTABLE";
497 case accessibility::AccessibleStateType::OFFSCREEN
:
500 case accessibility::AccessibleStateType::OPAQUE
:
503 case accessibility::AccessibleStateType::PRESSED
:
506 case accessibility::AccessibleStateType::RESIZABLE
:
509 case accessibility::AccessibleStateType::SELECTABLE
:
512 case accessibility::AccessibleStateType::SELECTED
:
515 case accessibility::AccessibleStateType::SENSITIVE
:
518 case accessibility::AccessibleStateType::SHOWING
:
521 case accessibility::AccessibleStateType::SINGLE_LINE
:
522 name
= "SINGLE_LINE";
524 case accessibility::AccessibleStateType::STALE
:
527 case accessibility::AccessibleStateType::TRANSIENT
:
530 case accessibility::AccessibleStateType::VERTICAL
:
533 case accessibility::AccessibleStateType::VISIBLE
:
537 name
= unknownName(state
);
540 if (combinedName
.getLength())
541 combinedName
+= " | ";
542 combinedName
+= name
;
545 if (combinedName
.isEmpty())
546 return u
"unknown"_ustr
;
550 OUString
AccessibilityTools::getEventIdName(const sal_Int16 event_id
)
554 case accessibility::AccessibleEventId::ACTION_CHANGED
:
555 return u
"ACTION_CHANGED"_ustr
;
556 case accessibility::AccessibleEventId::ACTIVE_DESCENDANT_CHANGED
:
557 return u
"ACTIVE_DESCENDANT_CHANGED"_ustr
;
558 case accessibility::AccessibleEventId::ACTIVE_DESCENDANT_CHANGED_NOFOCUS
:
559 return u
"ACTIVE_DESCENDANT_CHANGED_NOFOCUS"_ustr
;
560 case accessibility::AccessibleEventId::BOUNDRECT_CHANGED
:
561 return u
"BOUNDRECT_CHANGED"_ustr
;
562 case accessibility::AccessibleEventId::CARET_CHANGED
:
563 return u
"CARET_CHANGED"_ustr
;
564 case accessibility::AccessibleEventId::CHILD
:
565 return u
"CHILD"_ustr
;
566 case accessibility::AccessibleEventId::COLUMN_CHANGED
:
567 return u
"COLUMN_CHANGED"_ustr
;
568 case accessibility::AccessibleEventId::CONTENT_FLOWS_FROM_RELATION_CHANGED
:
569 return u
"CONTENT_FLOWS_FROM_RELATION_CHANGED"_ustr
;
570 case accessibility::AccessibleEventId::CONTENT_FLOWS_TO_RELATION_CHANGED
:
571 return u
"CONTENT_FLOWS_TO_RELATION_CHANGED"_ustr
;
572 case accessibility::AccessibleEventId::CONTROLLED_BY_RELATION_CHANGED
:
573 return u
"CONTROLLED_BY_RELATION_CHANGED"_ustr
;
574 case accessibility::AccessibleEventId::CONTROLLER_FOR_RELATION_CHANGED
:
575 return u
"CONTROLLER_FOR_RELATION_CHANGED"_ustr
;
576 case accessibility::AccessibleEventId::DESCRIPTION_CHANGED
:
577 return u
"DESCRIPTION_CHANGED"_ustr
;
578 case accessibility::AccessibleEventId::HYPERTEXT_CHANGED
:
579 return u
"HYPERTEXT_CHANGED"_ustr
;
580 case accessibility::AccessibleEventId::INVALIDATE_ALL_CHILDREN
:
581 return u
"INVALIDATE_ALL_CHILDREN"_ustr
;
582 case accessibility::AccessibleEventId::LABELED_BY_RELATION_CHANGED
:
583 return u
"LABELED_BY_RELATION_CHANGED"_ustr
;
584 case accessibility::AccessibleEventId::LABEL_FOR_RELATION_CHANGED
:
585 return u
"LABEL_FOR_RELATION_CHANGED"_ustr
;
586 case accessibility::AccessibleEventId::LISTBOX_ENTRY_COLLAPSED
:
587 return u
"LISTBOX_ENTRY_COLLAPSED"_ustr
;
588 case accessibility::AccessibleEventId::LISTBOX_ENTRY_EXPANDED
:
589 return u
"LISTBOX_ENTRY_EXPANDED"_ustr
;
590 case accessibility::AccessibleEventId::MEMBER_OF_RELATION_CHANGED
:
591 return u
"MEMBER_OF_RELATION_CHANGED"_ustr
;
592 case accessibility::AccessibleEventId::NAME_CHANGED
:
593 return u
"NAME_CHANGED"_ustr
;
594 case accessibility::AccessibleEventId::PAGE_CHANGED
:
595 return u
"PAGE_CHANGED"_ustr
;
596 case accessibility::AccessibleEventId::ROLE_CHANGED
:
597 return u
"ROLE_CHANGED"_ustr
;
598 case accessibility::AccessibleEventId::SECTION_CHANGED
:
599 return u
"SECTION_CHANGED"_ustr
;
600 case accessibility::AccessibleEventId::SELECTION_CHANGED
:
601 return u
"SELECTION_CHANGED"_ustr
;
602 case accessibility::AccessibleEventId::SELECTION_CHANGED_ADD
:
603 return u
"SELECTION_CHANGED_ADD"_ustr
;
604 case accessibility::AccessibleEventId::SELECTION_CHANGED_REMOVE
:
605 return u
"SELECTION_CHANGED_REMOVE"_ustr
;
606 case accessibility::AccessibleEventId::SELECTION_CHANGED_WITHIN
:
607 return u
"SELECTION_CHANGED_WITHIN"_ustr
;
608 case accessibility::AccessibleEventId::STATE_CHANGED
:
609 return u
"STATE_CHANGED"_ustr
;
610 case accessibility::AccessibleEventId::SUB_WINDOW_OF_RELATION_CHANGED
:
611 return u
"SUB_WINDOW_OF_RELATION_CHANGED"_ustr
;
612 case accessibility::AccessibleEventId::TABLE_CAPTION_CHANGED
:
613 return u
"TABLE_CAPTION_CHANGED"_ustr
;
614 case accessibility::AccessibleEventId::TABLE_COLUMN_DESCRIPTION_CHANGED
:
615 return u
"TABLE_COLUMN_DESCRIPTION_CHANGED"_ustr
;
616 case accessibility::AccessibleEventId::TABLE_COLUMN_HEADER_CHANGED
:
617 return u
"TABLE_COLUMN_HEADER_CHANGED"_ustr
;
618 case accessibility::AccessibleEventId::TABLE_MODEL_CHANGED
:
619 return u
"TABLE_MODEL_CHANGED"_ustr
;
620 case accessibility::AccessibleEventId::TABLE_ROW_DESCRIPTION_CHANGED
:
621 return u
"TABLE_ROW_DESCRIPTION_CHANGED"_ustr
;
622 case accessibility::AccessibleEventId::TABLE_ROW_HEADER_CHANGED
:
623 return u
"TABLE_ROW_HEADER_CHANGED"_ustr
;
624 case accessibility::AccessibleEventId::TABLE_SUMMARY_CHANGED
:
625 return u
"TABLE_SUMMARY_CHANGED"_ustr
;
626 case accessibility::AccessibleEventId::TEXT_ATTRIBUTE_CHANGED
:
627 return u
"TEXT_ATTRIBUTE_CHANGED"_ustr
;
628 case accessibility::AccessibleEventId::TEXT_CHANGED
:
629 return u
"TEXT_CHANGED"_ustr
;
630 case accessibility::AccessibleEventId::TEXT_SELECTION_CHANGED
:
631 return u
"TEXT_SELECTION_CHANGED"_ustr
;
632 case accessibility::AccessibleEventId::VALUE_CHANGED
:
633 return u
"VALUE_CHANGED"_ustr
;
634 case accessibility::AccessibleEventId::VISIBLE_DATA_CHANGED
:
635 return u
"VISIBLE_DATA_CHANGED"_ustr
;
637 return unknownName(event_id
);
640 OUString
AccessibilityTools::getRelationTypeName(AccessibleRelationType rel_type
)
644 case accessibility::AccessibleRelationType_CONTENT_FLOWS_FROM
:
645 return u
"CONTENT_FLOWS_FROM"_ustr
;
646 case accessibility::AccessibleRelationType_CONTENT_FLOWS_TO
:
647 return u
"CONTENT_FLOWS_TO"_ustr
;
648 case accessibility::AccessibleRelationType_CONTROLLED_BY
:
649 return u
"CONTROLLED_BY"_ustr
;
650 case accessibility::AccessibleRelationType_CONTROLLER_FOR
:
651 return u
"CONTROLLER_FOR"_ustr
;
652 case accessibility::AccessibleRelationType_DESCRIBED_BY
:
653 return u
"DESCRIBED_BY"_ustr
;
654 case accessibility::AccessibleRelationType_INVALID
:
655 return u
"INVALID"_ustr
;
656 case accessibility::AccessibleRelationType_LABELED_BY
:
657 return u
"LABELED_BY"_ustr
;
658 case accessibility::AccessibleRelationType_LABEL_FOR
:
659 return u
"LABEL_FOR"_ustr
;
660 case accessibility::AccessibleRelationType_MEMBER_OF
:
661 return u
"MEMBER_OF"_ustr
;
662 case accessibility::AccessibleRelationType_NODE_CHILD_OF
:
663 return u
"NODE_CHILD_OF"_ustr
;
664 case accessibility::AccessibleRelationType_SUB_WINDOW_OF
:
665 return u
"SUB_WINDOW_OF"_ustr
;
667 return unknownName(static_cast<sal_Int64
>(rel_type
));
671 OUString
AccessibilityTools::debugName(accessibility::XAccessibleContext
* ctx
)
673 return "role=" + AccessibilityTools::getRoleName(ctx
->getAccessibleRole()) + " name=\""
674 + ctx
->getAccessibleName() + "\" description=\"" + ctx
->getAccessibleDescription()
678 OUString
AccessibilityTools::debugName(accessibility::XAccessible
* acc
)
680 return debugName(acc
->getAccessibleContext().get());
683 OUString
AccessibilityTools::debugName(accessibility::XAccessibleAction
* xAct
)
685 OUStringBuffer r
= "actions=[";
687 const sal_Int32 nActions
= xAct
->getAccessibleActionCount();
688 for (sal_Int32 i
= 0; i
< nActions
; i
++)
693 r
.append("description=\"" + xAct
->getAccessibleActionDescription(i
) + "\"");
695 const auto xKeyBinding
= xAct
->getAccessibleActionKeyBinding(i
);
698 r
.append(" keybindings=[");
699 const sal_Int32 nKeyBindings
= xKeyBinding
->getAccessibleKeyBindingCount();
700 for (sal_Int32 j
= 0; j
< nKeyBindings
; j
++)
706 for (const auto& keyStroke
: xKeyBinding
->getAccessibleKeyBinding(j
))
712 if (keyStroke
.Modifiers
& awt::KeyModifier::MOD1
)
714 if (keyStroke
.Modifiers
& awt::KeyModifier::MOD2
)
716 if (keyStroke
.Modifiers
& awt::KeyModifier::MOD3
)
718 if (keyStroke
.Modifiers
& awt::KeyModifier::SHIFT
)
720 r
.append(OUStringChar(keyStroke
.KeyChar
) + "\"");
727 return r
.makeStringAndClear();
730 OUString
AccessibilityTools::debugName(accessibility::XAccessibleText
* xTxt
)
732 uno::Reference
<accessibility::XAccessibleContext
> xCtx(xTxt
, uno::UNO_QUERY
);
733 return debugName(xCtx
.get());
736 OUString
AccessibilityTools::debugName(const accessibility::AccessibleEventObject
* evobj
)
738 return "(AccessibleEventObject) { id=" + getEventIdName(evobj
->EventId
)
739 + " old=" + evobj
->OldValue
.getValueTypeName()
740 + " new=" + evobj
->NewValue
.getValueTypeName() + " }";
743 bool AccessibilityTools::Await(const std::function
<bool()>& cUntilCallback
, sal_uInt64 nTimeoutMs
)
745 bool success
= false;
746 Timer
aTimer("wait for event");
747 aTimer
.SetTimeout(nTimeoutMs
);
751 Scheduler::ProcessEventsToIdle();
752 success
= cUntilCallback();
753 } while (!success
&& aTimer
.IsActive());
754 SAL_WARN_IF(!success
, "test", "timeout reached");
758 void AccessibilityTools::Wait(sal_uInt64 nTimeoutMs
)
760 Timer
aTimer("wait for event");
761 aTimer
.SetTimeout(nTimeoutMs
);
763 std::cout
<< "waiting for " << nTimeoutMs
<< "ms... ";
766 Scheduler::ProcessEventsToIdle();
767 } while (aTimer
.IsActive());
768 std::cout
<< "ok." << std::endl
;
771 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */