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 <toolkit/awt/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::getAccessibleObjectForRole(
74 const uno::Reference
<accessibility::XAccessibleContext
>& xCtx
, sal_Int16 role
)
76 return getAccessibleObjectForPredicate(
77 xCtx
, [&role
](const uno::Reference
<accessibility::XAccessibleContext
>& xObjCtx
) {
78 return (xObjCtx
->getAccessibleRole() == role
79 && xObjCtx
->getAccessibleStateSet()
80 & accessibility::AccessibleStateType::SHOWING
);
84 css::uno::Reference
<css::accessibility::XAccessibleContext
>
85 AccessibilityTools::getAccessibleObjectForRole(
86 const css::uno::Reference
<css::accessibility::XAccessible
>& xacc
, sal_Int16 role
)
88 return getAccessibleObjectForRole(xacc
->getAccessibleContext(), role
);
91 /* this is basically the same as getAccessibleObjectForPredicate() but specialized for efficiency,
92 * and because the template version will not work with getAccessibleObjectForPredicate() anyway */
93 css::uno::Reference
<css::accessibility::XAccessibleContext
>
94 AccessibilityTools::getAccessibleObjectForName(
95 const css::uno::Reference
<css::accessibility::XAccessibleContext
>& xCtx
, const sal_Int16 role
,
96 std::u16string_view name
)
98 if (xCtx
->getAccessibleRole() == role
&& nameEquals(xCtx
, name
))
101 auto nChildren
= xCtx
->getAccessibleChildCount();
102 for (decltype(nChildren
) i
= 0; i
< nChildren
&& i
< AccessibilityTools::MAX_CHILDREN
; i
++)
104 if (auto xMatchChild
= getAccessibleObjectForName(xCtx
->getAccessibleChild(i
), role
, name
))
111 bool AccessibilityTools::equals(const uno::Reference
<accessibility::XAccessible
>& xacc1
,
112 const uno::Reference
<accessibility::XAccessible
>& xacc2
)
114 if (!xacc1
.is() || !xacc2
.is())
115 return xacc1
.is() == xacc2
.is();
116 return equals(xacc1
->getAccessibleContext(), xacc2
->getAccessibleContext());
119 bool AccessibilityTools::equals(const uno::Reference
<accessibility::XAccessibleContext
>& xctx1
,
120 const uno::Reference
<accessibility::XAccessibleContext
>& xctx2
)
122 if (!xctx1
.is() || !xctx2
.is())
123 return xctx1
.is() == xctx2
.is();
125 if (xctx1
->getAccessibleRole() != xctx2
->getAccessibleRole())
128 if (xctx1
->getAccessibleName() != xctx2
->getAccessibleName())
131 if (xctx1
->getAccessibleDescription() != xctx2
->getAccessibleDescription())
134 if (xctx1
->getAccessibleChildCount() != xctx2
->getAccessibleChildCount())
137 /* this one was not in the Java version */
138 if (xctx1
->getAccessibleIndexInParent() != xctx2
->getAccessibleIndexInParent())
141 /* because in Writer at least some children only are referenced by their relations to others
142 * objects, we need to account for that as their index in parent is incorrect (so not
143 * necessarily unique) */
144 auto relset1
= xctx1
->getAccessibleRelationSet();
145 auto relset2
= xctx2
->getAccessibleRelationSet();
146 if (relset1
.is() != relset2
.is())
148 else if (relset1
.is())
150 auto relCount1
= relset1
->getRelationCount();
151 auto relCount2
= relset2
->getRelationCount();
152 if (relCount1
!= relCount2
)
155 for (sal_Int32 i
= 0; i
< relCount1
; ++i
)
157 if (relset1
->getRelation(i
) != relset2
->getRelation(i
))
162 return equals(xctx1
->getAccessibleParent(), xctx2
->getAccessibleParent());
165 bool AccessibilityTools::nameEquals(const uno::Reference
<accessibility::XAccessibleContext
>& xCtx
,
166 const std::u16string_view name
)
168 auto ctxName
= xCtx
->getAccessibleName();
169 std::u16string_view rest
;
171 if (!o3tl::starts_with(ctxName
, name
, &rest
))
177 // see OAccessibleMenuItemComponent::GetAccessibleName():
178 // on Win32, ignore a \tSHORTCUT suffix on a menu item
179 switch (xCtx
->getAccessibleRole())
181 case accessibility::AccessibleRole::MENU_ITEM
:
182 case accessibility::AccessibleRole::RADIO_MENU_ITEM
:
183 case accessibility::AccessibleRole::CHECK_MENU_ITEM
:
184 return rest
[0] == '\t';
191 #if OSL_DEBUG_LEVEL > 0
192 // see VCLXAccessibleComponent::getAccessibleName()
193 auto pVCLXAccessibleComponent
= dynamic_cast<VCLXAccessibleComponent
*>(xCtx
.get());
194 if (pVCLXAccessibleComponent
)
196 auto windowType
= pVCLXAccessibleComponent
->GetWindow()->GetType();
198 == Concat2View(u
" (Type = " + OUString::number(static_cast<sal_Int32
>(windowType
))
206 static OUString
unknownName(const sal_Int64 value
)
208 return "unknown (" + OUString::number(value
) + ")";
211 OUString
AccessibilityTools::getRoleName(const sal_Int16 role
)
215 case accessibility::AccessibleRole::UNKNOWN
:
217 case accessibility::AccessibleRole::ALERT
:
219 case accessibility::AccessibleRole::BUTTON_DROPDOWN
:
220 return "BUTTON_DROPDOWN";
221 case accessibility::AccessibleRole::BUTTON_MENU
:
222 return "BUTTON_MENU";
223 case accessibility::AccessibleRole::CANVAS
:
225 case accessibility::AccessibleRole::CAPTION
:
227 case accessibility::AccessibleRole::CHART
:
229 case accessibility::AccessibleRole::CHECK_BOX
:
231 case accessibility::AccessibleRole::CHECK_MENU_ITEM
:
232 return "CHECK_MENU_ITEM";
233 case accessibility::AccessibleRole::COLOR_CHOOSER
:
234 return "COLOR_CHOOSER";
235 case accessibility::AccessibleRole::COLUMN_HEADER
:
236 return "COLUMN_HEADER";
237 case accessibility::AccessibleRole::COMBO_BOX
:
239 case accessibility::AccessibleRole::COMMENT
:
241 case accessibility::AccessibleRole::COMMENT_END
:
242 return "COMMENT_END";
243 case accessibility::AccessibleRole::DATE_EDITOR
:
244 return "DATE_EDITOR";
245 case accessibility::AccessibleRole::DESKTOP_ICON
:
246 return "DESKTOP_ICON";
247 case accessibility::AccessibleRole::DESKTOP_PANE
:
248 return "DESKTOP_PANE";
249 case accessibility::AccessibleRole::DIALOG
:
251 case accessibility::AccessibleRole::DIRECTORY_PANE
:
252 return "DIRECTORY_PANE";
253 case accessibility::AccessibleRole::DOCUMENT
:
255 case accessibility::AccessibleRole::DOCUMENT_PRESENTATION
:
256 return "DOCUMENT_PRESENTATION";
257 case accessibility::AccessibleRole::DOCUMENT_SPREADSHEET
:
258 return "DOCUMENT_SPREADSHEET";
259 case accessibility::AccessibleRole::DOCUMENT_TEXT
:
260 return "DOCUMENT_TEXT";
261 case accessibility::AccessibleRole::EDIT_BAR
:
263 case accessibility::AccessibleRole::EMBEDDED_OBJECT
:
264 return "EMBEDDED_OBJECT";
265 case accessibility::AccessibleRole::END_NOTE
:
267 case accessibility::AccessibleRole::FILE_CHOOSER
:
268 return "FILE_CHOOSER";
269 case accessibility::AccessibleRole::FILLER
:
271 case accessibility::AccessibleRole::FONT_CHOOSER
:
272 return "FONT_CHOOSER";
273 case accessibility::AccessibleRole::FOOTER
:
275 case accessibility::AccessibleRole::FOOTNOTE
:
277 case accessibility::AccessibleRole::FORM
:
279 case accessibility::AccessibleRole::FRAME
:
281 case accessibility::AccessibleRole::GLASS_PANE
:
283 case accessibility::AccessibleRole::GRAPHIC
:
285 case accessibility::AccessibleRole::GROUP_BOX
:
287 case accessibility::AccessibleRole::HEADER
:
289 case accessibility::AccessibleRole::HEADING
:
291 case accessibility::AccessibleRole::HYPER_LINK
:
293 case accessibility::AccessibleRole::ICON
:
295 case accessibility::AccessibleRole::IMAGE_MAP
:
297 case accessibility::AccessibleRole::INTERNAL_FRAME
:
298 return "INTERNAL_FRAME";
299 case accessibility::AccessibleRole::LABEL
:
301 case accessibility::AccessibleRole::LAYERED_PANE
:
302 return "LAYERED_PANE";
303 case accessibility::AccessibleRole::LIST
:
305 case accessibility::AccessibleRole::LIST_ITEM
:
307 case accessibility::AccessibleRole::MENU
:
309 case accessibility::AccessibleRole::MENU_BAR
:
311 case accessibility::AccessibleRole::MENU_ITEM
:
313 case accessibility::AccessibleRole::NOTE
:
315 case accessibility::AccessibleRole::OPTION_PANE
:
316 return "OPTION_PANE";
317 case accessibility::AccessibleRole::PAGE
:
319 case accessibility::AccessibleRole::PAGE_TAB
:
321 case accessibility::AccessibleRole::PAGE_TAB_LIST
:
322 return "PAGE_TAB_LIST";
323 case accessibility::AccessibleRole::PANEL
:
325 case accessibility::AccessibleRole::PARAGRAPH
:
327 case accessibility::AccessibleRole::PASSWORD_TEXT
:
328 return "PASSWORD_TEXT";
329 case accessibility::AccessibleRole::POPUP_MENU
:
331 case accessibility::AccessibleRole::PROGRESS_BAR
:
332 return "PROGRESS_BAR";
333 case accessibility::AccessibleRole::PUSH_BUTTON
:
334 return "PUSH_BUTTON";
335 case accessibility::AccessibleRole::RADIO_BUTTON
:
336 return "RADIO_BUTTON";
337 case accessibility::AccessibleRole::RADIO_MENU_ITEM
:
338 return "RADIO_MENU_ITEM";
339 case accessibility::AccessibleRole::ROOT_PANE
:
341 case accessibility::AccessibleRole::ROW_HEADER
:
343 case accessibility::AccessibleRole::RULER
:
345 case accessibility::AccessibleRole::SCROLL_BAR
:
347 case accessibility::AccessibleRole::SCROLL_PANE
:
348 return "SCROLL_PANE";
349 case accessibility::AccessibleRole::SECTION
:
351 case accessibility::AccessibleRole::SEPARATOR
:
353 case accessibility::AccessibleRole::SHAPE
:
355 case accessibility::AccessibleRole::SLIDER
:
357 case accessibility::AccessibleRole::SPIN_BOX
:
359 case accessibility::AccessibleRole::SPLIT_PANE
:
361 case accessibility::AccessibleRole::STATIC
:
363 case accessibility::AccessibleRole::STATUS_BAR
:
365 case accessibility::AccessibleRole::TABLE
:
367 case accessibility::AccessibleRole::TABLE_CELL
:
369 case accessibility::AccessibleRole::TEXT
:
371 case accessibility::AccessibleRole::TEXT_FRAME
:
373 case accessibility::AccessibleRole::TOGGLE_BUTTON
:
374 return "TOGGLE_BUTTON";
375 case accessibility::AccessibleRole::TOOL_BAR
:
377 case accessibility::AccessibleRole::TOOL_TIP
:
379 case accessibility::AccessibleRole::TREE
:
381 case accessibility::AccessibleRole::TREE_ITEM
:
383 case accessibility::AccessibleRole::TREE_TABLE
:
385 case accessibility::AccessibleRole::VIEW_PORT
:
387 case accessibility::AccessibleRole::WINDOW
:
390 return unknownName(role
);
393 OUString
AccessibilityTools::debugAccessibleStateSet(const sal_Int64 nCombinedState
)
395 OUString combinedName
;
397 for (int i
= 0; i
< 63; i
++)
399 sal_Int64 state
= sal_Int64(1) << i
;
400 if (!(state
& nCombinedState
))
405 case accessibility::AccessibleStateType::ACTIVE
:
408 case accessibility::AccessibleStateType::ARMED
:
411 case accessibility::AccessibleStateType::BUSY
:
414 case accessibility::AccessibleStateType::CHECKED
:
417 case accessibility::AccessibleStateType::COLLAPSE
:
420 case accessibility::AccessibleStateType::DEFAULT
:
423 case accessibility::AccessibleStateType::DEFUNC
:
426 case accessibility::AccessibleStateType::EDITABLE
:
429 case accessibility::AccessibleStateType::ENABLED
:
432 case accessibility::AccessibleStateType::EXPANDABLE
:
435 case accessibility::AccessibleStateType::EXPANDED
:
438 case accessibility::AccessibleStateType::FOCUSABLE
:
441 case accessibility::AccessibleStateType::FOCUSED
:
444 case accessibility::AccessibleStateType::HORIZONTAL
:
447 case accessibility::AccessibleStateType::ICONIFIED
:
450 case accessibility::AccessibleStateType::INDETERMINATE
:
451 name
= "INDETERMINATE";
453 case accessibility::AccessibleStateType::INVALID
:
456 case accessibility::AccessibleStateType::MANAGES_DESCENDANTS
:
457 name
= "MANAGES_DESCENDANTS";
459 case accessibility::AccessibleStateType::MODAL
:
462 case accessibility::AccessibleStateType::MOVEABLE
:
465 case accessibility::AccessibleStateType::MULTI_LINE
:
468 case accessibility::AccessibleStateType::MULTI_SELECTABLE
:
469 name
= "MULTI_SELECTABLE";
471 case accessibility::AccessibleStateType::OFFSCREEN
:
474 case accessibility::AccessibleStateType::OPAQUE
:
477 case accessibility::AccessibleStateType::PRESSED
:
480 case accessibility::AccessibleStateType::RESIZABLE
:
483 case accessibility::AccessibleStateType::SELECTABLE
:
486 case accessibility::AccessibleStateType::SELECTED
:
489 case accessibility::AccessibleStateType::SENSITIVE
:
492 case accessibility::AccessibleStateType::SHOWING
:
495 case accessibility::AccessibleStateType::SINGLE_LINE
:
496 name
= "SINGLE_LINE";
498 case accessibility::AccessibleStateType::STALE
:
501 case accessibility::AccessibleStateType::TRANSIENT
:
504 case accessibility::AccessibleStateType::VERTICAL
:
507 case accessibility::AccessibleStateType::VISIBLE
:
511 name
= unknownName(state
);
514 if (combinedName
.getLength())
515 combinedName
+= " | ";
516 combinedName
+= name
;
519 if (combinedName
.isEmpty())
524 OUString
AccessibilityTools::getEventIdName(const sal_Int16 event_id
)
528 case accessibility::AccessibleEventId::ACTION_CHANGED
:
529 return "ACTION_CHANGED";
530 case accessibility::AccessibleEventId::ACTIVE_DESCENDANT_CHANGED
:
531 return "ACTIVE_DESCENDANT_CHANGED";
532 case accessibility::AccessibleEventId::ACTIVE_DESCENDANT_CHANGED_NOFOCUS
:
533 return "ACTIVE_DESCENDANT_CHANGED_NOFOCUS";
534 case accessibility::AccessibleEventId::BOUNDRECT_CHANGED
:
535 return "BOUNDRECT_CHANGED";
536 case accessibility::AccessibleEventId::CARET_CHANGED
:
537 return "CARET_CHANGED";
538 case accessibility::AccessibleEventId::CHILD
:
540 case accessibility::AccessibleEventId::COLUMN_CHANGED
:
541 return "COLUMN_CHANGED";
542 case accessibility::AccessibleEventId::CONTENT_FLOWS_FROM_RELATION_CHANGED
:
543 return "CONTENT_FLOWS_FROM_RELATION_CHANGED";
544 case accessibility::AccessibleEventId::CONTENT_FLOWS_TO_RELATION_CHANGED
:
545 return "CONTENT_FLOWS_TO_RELATION_CHANGED";
546 case accessibility::AccessibleEventId::CONTROLLED_BY_RELATION_CHANGED
:
547 return "CONTROLLED_BY_RELATION_CHANGED";
548 case accessibility::AccessibleEventId::CONTROLLER_FOR_RELATION_CHANGED
:
549 return "CONTROLLER_FOR_RELATION_CHANGED";
550 case accessibility::AccessibleEventId::DESCRIPTION_CHANGED
:
551 return "DESCRIPTION_CHANGED";
552 case accessibility::AccessibleEventId::HYPERTEXT_CHANGED
:
553 return "HYPERTEXT_CHANGED";
554 case accessibility::AccessibleEventId::INVALIDATE_ALL_CHILDREN
:
555 return "INVALIDATE_ALL_CHILDREN";
556 case accessibility::AccessibleEventId::LABELED_BY_RELATION_CHANGED
:
557 return "LABELED_BY_RELATION_CHANGED";
558 case accessibility::AccessibleEventId::LABEL_FOR_RELATION_CHANGED
:
559 return "LABEL_FOR_RELATION_CHANGED";
560 case accessibility::AccessibleEventId::LISTBOX_ENTRY_COLLAPSED
:
561 return "LISTBOX_ENTRY_COLLAPSED";
562 case accessibility::AccessibleEventId::LISTBOX_ENTRY_EXPANDED
:
563 return "LISTBOX_ENTRY_EXPANDED";
564 case accessibility::AccessibleEventId::MEMBER_OF_RELATION_CHANGED
:
565 return "MEMBER_OF_RELATION_CHANGED";
566 case accessibility::AccessibleEventId::NAME_CHANGED
:
567 return "NAME_CHANGED";
568 case accessibility::AccessibleEventId::PAGE_CHANGED
:
569 return "PAGE_CHANGED";
570 case accessibility::AccessibleEventId::ROLE_CHANGED
:
571 return "ROLE_CHANGED";
572 case accessibility::AccessibleEventId::SECTION_CHANGED
:
573 return "SECTION_CHANGED";
574 case accessibility::AccessibleEventId::SELECTION_CHANGED
:
575 return "SELECTION_CHANGED";
576 case accessibility::AccessibleEventId::SELECTION_CHANGED_ADD
:
577 return "SELECTION_CHANGED_ADD";
578 case accessibility::AccessibleEventId::SELECTION_CHANGED_REMOVE
:
579 return "SELECTION_CHANGED_REMOVE";
580 case accessibility::AccessibleEventId::SELECTION_CHANGED_WITHIN
:
581 return "SELECTION_CHANGED_WITHIN";
582 case accessibility::AccessibleEventId::STATE_CHANGED
:
583 return "STATE_CHANGED";
584 case accessibility::AccessibleEventId::SUB_WINDOW_OF_RELATION_CHANGED
:
585 return "SUB_WINDOW_OF_RELATION_CHANGED";
586 case accessibility::AccessibleEventId::TABLE_CAPTION_CHANGED
:
587 return "TABLE_CAPTION_CHANGED";
588 case accessibility::AccessibleEventId::TABLE_COLUMN_DESCRIPTION_CHANGED
:
589 return "TABLE_COLUMN_DESCRIPTION_CHANGED";
590 case accessibility::AccessibleEventId::TABLE_COLUMN_HEADER_CHANGED
:
591 return "TABLE_COLUMN_HEADER_CHANGED";
592 case accessibility::AccessibleEventId::TABLE_MODEL_CHANGED
:
593 return "TABLE_MODEL_CHANGED";
594 case accessibility::AccessibleEventId::TABLE_ROW_DESCRIPTION_CHANGED
:
595 return "TABLE_ROW_DESCRIPTION_CHANGED";
596 case accessibility::AccessibleEventId::TABLE_ROW_HEADER_CHANGED
:
597 return "TABLE_ROW_HEADER_CHANGED";
598 case accessibility::AccessibleEventId::TABLE_SUMMARY_CHANGED
:
599 return "TABLE_SUMMARY_CHANGED";
600 case accessibility::AccessibleEventId::TEXT_ATTRIBUTE_CHANGED
:
601 return "TEXT_ATTRIBUTE_CHANGED";
602 case accessibility::AccessibleEventId::TEXT_CHANGED
:
603 return "TEXT_CHANGED";
604 case accessibility::AccessibleEventId::TEXT_SELECTION_CHANGED
:
605 return "TEXT_SELECTION_CHANGED";
606 case accessibility::AccessibleEventId::VALUE_CHANGED
:
607 return "VALUE_CHANGED";
608 case accessibility::AccessibleEventId::VISIBLE_DATA_CHANGED
:
609 return "VISIBLE_DATA_CHANGED";
611 return unknownName(event_id
);
614 OUString
AccessibilityTools::getRelationTypeName(const sal_Int16 rel_type
)
618 case accessibility::AccessibleRelationType::CONTENT_FLOWS_FROM
:
619 return "CONTENT_FLOWS_FROM";
620 case accessibility::AccessibleRelationType::CONTENT_FLOWS_TO
:
621 return "CONTENT_FLOWS_TO";
622 case accessibility::AccessibleRelationType::CONTROLLED_BY
:
623 return "CONTROLLED_BY";
624 case accessibility::AccessibleRelationType::CONTROLLER_FOR
:
625 return "CONTROLLER_FOR";
626 case accessibility::AccessibleRelationType::DESCRIBED_BY
:
627 return "DESCRIBED_BY";
628 case accessibility::AccessibleRelationType::INVALID
:
630 case accessibility::AccessibleRelationType::LABELED_BY
:
632 case accessibility::AccessibleRelationType::LABEL_FOR
:
634 case accessibility::AccessibleRelationType::MEMBER_OF
:
636 case accessibility::AccessibleRelationType::NODE_CHILD_OF
:
637 return "NODE_CHILD_OF";
638 case accessibility::AccessibleRelationType::SUB_WINDOW_OF
:
639 return "SUB_WINDOW_OF";
641 return unknownName(rel_type
);
644 OUString
AccessibilityTools::debugName(accessibility::XAccessibleContext
* ctx
)
646 return "role=" + AccessibilityTools::getRoleName(ctx
->getAccessibleRole()) + " name=\""
647 + ctx
->getAccessibleName() + "\" description=\"" + ctx
->getAccessibleDescription()
651 OUString
AccessibilityTools::debugName(accessibility::XAccessible
* acc
)
653 return debugName(acc
->getAccessibleContext().get());
656 OUString
AccessibilityTools::debugName(accessibility::XAccessibleAction
* xAct
)
658 OUStringBuffer r
= "actions=[";
660 const sal_Int32 nActions
= xAct
->getAccessibleActionCount();
661 for (sal_Int32 i
= 0; i
< nActions
; i
++)
666 r
.append("description=\"" + xAct
->getAccessibleActionDescription(i
) + "\"");
668 const auto& xKeyBinding
= xAct
->getAccessibleActionKeyBinding(i
);
671 r
.append(" keybindings=[");
672 const sal_Int32 nKeyBindings
= xKeyBinding
->getAccessibleKeyBindingCount();
673 for (sal_Int32 j
= 0; j
< nKeyBindings
; j
++)
679 for (const auto& keyStroke
: xKeyBinding
->getAccessibleKeyBinding(j
))
685 if (keyStroke
.Modifiers
& awt::KeyModifier::MOD1
)
687 if (keyStroke
.Modifiers
& awt::KeyModifier::MOD2
)
689 if (keyStroke
.Modifiers
& awt::KeyModifier::MOD3
)
691 if (keyStroke
.Modifiers
& awt::KeyModifier::SHIFT
)
693 r
.append(OUStringChar(keyStroke
.KeyChar
) + "\"");
700 return r
.makeStringAndClear();
703 OUString
AccessibilityTools::debugName(const accessibility::AccessibleEventObject
* evobj
)
705 return "(AccessibleEventObject) { id=" + getEventIdName(evobj
->EventId
)
706 + " old=" + evobj
->OldValue
.getValueTypeName()
707 + " new=" + evobj
->NewValue
.getValueTypeName() + " }";
710 bool AccessibilityTools::Await(const std::function
<bool()>& cUntilCallback
, sal_uInt64 nTimeoutMs
)
712 bool success
= false;
713 Timer
aTimer("wait for event");
714 aTimer
.SetTimeout(nTimeoutMs
);
718 Scheduler::ProcessEventsToIdle();
719 success
= cUntilCallback();
720 } while (!success
&& aTimer
.IsActive());
721 SAL_WARN_IF(!success
, "test", "timeout reached");
725 void AccessibilityTools::Wait(sal_uInt64 nTimeoutMs
)
727 Timer
aTimer("wait for event");
728 aTimer
.SetTimeout(nTimeoutMs
);
730 std::cout
<< "waiting for " << nTimeoutMs
<< "ms... ";
733 Scheduler::ProcessEventsToIdle();
734 } while (aTimer
.IsActive());
735 std::cout
<< "ok." << std::endl
;
738 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */