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>
41uno::Reference<accessibility::XAccessibleContext>
43 const uno::Reference<accessibility::XAccessibleContext>& xCtx,
44 const std::function<
bool(
const uno::Reference<accessibility::XAccessibleContext>&)>& cPredicate)
52 sal_Int64
count = xCtx->getAccessibleChildCount();
56 uno::Reference<accessibility::XAccessibleContext> xCtx2
65uno::Reference<accessibility::XAccessibleContext>
67 const uno::Reference<accessibility::XAccessible>& xAcc,
68 const std::function<
bool(
const uno::Reference<accessibility::XAccessibleContext>&)>& cPredicate)
74 const uno::Reference<accessibility::XAccessibleContext>& xCtx, sal_Int16 role)
77 xCtx, [&role](
const uno::Reference<accessibility::XAccessibleContext>& xObjCtx) {
78 return (xObjCtx->getAccessibleRole() == role
79 && xObjCtx->getAccessibleStateSet()
80 & accessibility::AccessibleStateType::SHOWING);
84css::uno::Reference<css::accessibility::XAccessibleContext>
86 const css::uno::Reference<css::accessibility::XAccessible>& xacc, sal_Int16 role)
93css::uno::Reference<css::accessibility::XAccessibleContext>
95 const css::uno::Reference<css::accessibility::XAccessibleContext>& xCtx,
const sal_Int16 role,
96 std::u16string_view name)
101 auto nChildren = xCtx->getAccessibleChildCount();
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());
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())
138 if (xctx1->getAccessibleIndexInParent() != xctx2->getAccessibleIndexInParent())
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());
166 const std::u16string_view name)
168 auto ctxName = xCtx->getAccessibleName();
169 std::u16string_view rest;
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
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))
208 return "unknown (" + OUString::number(
value) +
")";
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:
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:
514 if (combinedName.getLength())
515 combinedName +=
" | ";
516 combinedName +=
name;
519 if (combinedName.isEmpty())
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";
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";
647 +
ctx->getAccessibleName() +
"\" description=\"" +
ctx->getAccessibleDescription()
653 return debugName(acc->getAccessibleContext().get());
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();
705 uno::Reference<accessibility::XAccessibleContext> xCtx(xTxt, uno::UNO_QUERY);
711 return "(AccessibleEventObject) { id=" +
getEventIdName(evobj->EventId)
712 +
" old=" + evobj->OldValue.getValueTypeName()
713 +
" new=" + evobj->NewValue.getValueTypeName() +
" }";
718 bool success =
false;
719 Timer aTimer(
"wait for event");
725 success = cUntilCallback();
726 }
while (!success && aTimer.
IsActive());
733 Timer aTimer(
"wait for event");
736 std::cout <<
"waiting for " << nTimeoutMs <<
"ms... ";
741 std::cout <<
"ok." << std::endl;
static void ProcessEventsToIdle()
void SetTimeout(sal_uInt64 nTimeoutMs)
virtual void Start(bool bStartTimer=true) override
#define SAL_WARN_IF(condition, area, stream)
constexpr bool starts_with(std::basic_string_view< charT, traits > sv, std::basic_string_view< charT, traits > x) noexcept