LibreOffice Module test (master) 1
swaccessibletestbase.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
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
11
12#include <com/sun/star/accessibility/AccessibleRelationType.hpp>
13#include <com/sun/star/accessibility/XAccessibleContext.hpp>
14#include <com/sun/star/accessibility/XAccessibleText.hpp>
15#include <com/sun/star/uno/Reference.hxx>
16
17#include <rtl/ustrbuf.hxx>
18
20
21using namespace css;
22
23uno::Reference<accessibility::XAccessibleContext>
25 const uno::Reference<accessibility::XAccessibleContext>& xContext)
26{
27 return getFirstRelationTargetOfType(xContext,
28 accessibility::AccessibleRelationType::CONTENT_FLOWS_FROM);
29}
30
31uno::Reference<accessibility::XAccessibleContext> test::SwAccessibleTestBase::getNextFlowingSibling(
32 const uno::Reference<accessibility::XAccessibleContext>& xContext)
33{
34 return getFirstRelationTargetOfType(xContext,
35 accessibility::AccessibleRelationType::CONTENT_FLOWS_TO);
36}
37
38/* Care has to be taken not to walk sideways as the relation is also used
39 * with children of nested containers (possibly as the "natural"/"perceived" flow?). */
40std::deque<uno::Reference<accessibility::XAccessibleContext>>
42 const uno::Reference<accessibility::XAccessibleContext>& xContext)
43{
44 /* first, get all "natural" children */
45 auto children = AccessibleTestBase::getAllChildren(xContext);
46 if (!children.size())
47 return children;
48
49 /* then, try and find flowing siblings at the same levels that are not included in the list */
50 /* first, backwards: */
51 auto child = getPreviousFlowingSibling(children.front());
52 while (child.is() && children.size() < AccessibilityTools::MAX_CHILDREN)
53 {
54 auto childParent = child->getAccessibleParent();
55 if (childParent.is()
56 && AccessibilityTools::equals(xContext, childParent->getAccessibleContext()))
57 children.push_front(child);
58 child = getPreviousFlowingSibling(child);
59 }
60 /* then forward */
61 child = getNextFlowingSibling(children.back());
62 while (child.is() && children.size() < AccessibilityTools::MAX_CHILDREN)
63 {
64 auto childParent = child->getAccessibleParent();
65 if (childParent.is()
66 && AccessibilityTools::equals(xContext, childParent->getAccessibleContext()))
67 children.push_back(child);
68 child = getNextFlowingSibling(child);
69 }
70
71 return children;
72}
73
75 const uno::Reference<accessibility::XAccessibleContext>& xContext, rtl::OUStringBuffer& buffer,
76 bool onlyChildren)
77{
78 const auto& roleName = AccessibilityTools::getRoleName(xContext->getAccessibleRole());
79
80 std::cout << "collecting text for child of role " << roleName << "..." << std::endl;
81
82 if (!onlyChildren)
83 {
84 const struct
85 {
86 std::u16string_view name;
87 rtl::OUString value;
88 } attrs[] = {
89 { u"name", xContext->getAccessibleName() },
90 { u"description", xContext->getAccessibleDescription() },
91 };
92
93 buffer.append('<');
94 buffer.append(roleName);
95 for (auto& attr : attrs)
96 {
97 if (attr.value.getLength() == 0)
98 continue;
99 buffer.append(' ');
100 buffer.append(attr.name);
101 buffer.append(u"=\"" + attr.value.replaceAll(u"\"", u"&quot;") + "\"");
102 }
103 buffer.append('>');
104 }
105 auto openTagLength = buffer.getLength();
106
107 uno::Reference<accessibility::XAccessibleText> xText(xContext, uno::UNO_QUERY);
108 if (xText.is())
109 buffer.append(xText->getText());
110
111 for (auto& childContext : getAllChildren(xContext))
112 collectText(childContext, buffer);
113
114 if (!onlyChildren)
115 {
116 if (buffer.getLength() != openTagLength)
117 buffer.append("</" + roleName + ">");
118 else
119 {
120 /* there was no content, so make is a short tag for more concise output */
121 buffer[openTagLength - 1] = '/';
122 buffer.append('>');
123 }
124 }
125}
126
128 const uno::Reference<accessibility::XAccessibleContext>& xContext)
129{
130 rtl::OUStringBuffer buf;
131 collectText(xContext, buf, isDocumentRole(xContext->getAccessibleRole()));
132 return buf.makeStringAndClear();
133}
134
135/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
static const sal_Int32 MAX_CHILDREN
Maximum number of children to work on.
static OUString getRoleName(const sal_Int16 role)
static bool equals(const css::uno::Reference< css::accessibility::XAccessible > &xacc1, const css::uno::Reference< css::accessibility::XAccessible > &xacc2)
static css::uno::Reference< css::accessibility::XAccessibleContext > getFirstRelationTargetOfType(const css::uno::Reference< css::accessibility::XAccessibleContext > &xContext, sal_Int16 relationType)
virtual std::deque< css::uno::Reference< css::accessibility::XAccessibleContext > > getAllChildren(const css::uno::Reference< css::accessibility::XAccessibleContext > &xContext)
Tries to list all children of an accessible.
static css::uno::Reference< css::accessibility::XAccessibleContext > getPreviousFlowingSibling(const css::uno::Reference< css::accessibility::XAccessibleContext > &xContext)
virtual std::deque< css::uno::Reference< css::accessibility::XAccessibleContext > > getAllChildren(const css::uno::Reference< css::accessibility::XAccessibleContext > &xContext) override
This fetches regular children plus siblings linked with FLOWS_TO/FLOWS_FROM which are not already in ...
static css::uno::Reference< css::accessibility::XAccessibleContext > getNextFlowingSibling(const css::uno::Reference< css::accessibility::XAccessibleContext > &xContext)
OUString collectText()
Collects contents of the current document.
Any value
float u
const char * name