1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 <Qt5AccessibleWidget.hxx>
21 #include <Qt5AccessibleWidget.moc>
23 #include <QtGui/QAccessibleInterface>
25 #include <Qt5AccessibleEventListener.hxx>
26 #include <Qt5Frame.hxx>
27 #include <Qt5Tools.hxx>
28 #include <Qt5Widget.hxx>
29 #include <Qt5XAccessible.hxx>
31 #include <com/sun/star/accessibility/AccessibleRelationType.hpp>
32 #include <com/sun/star/accessibility/AccessibleRole.hpp>
33 #include <com/sun/star/accessibility/AccessibleScrollType.hpp>
34 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
35 #include <com/sun/star/accessibility/XAccessible.hpp>
36 #include <com/sun/star/accessibility/XAccessibleAction.hpp>
37 #include <com/sun/star/accessibility/XAccessibleComponent.hpp>
38 #include <com/sun/star/accessibility/XAccessibleEditableText.hpp>
39 #include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp>
40 #include <com/sun/star/accessibility/XAccessibleEventListener.hpp>
41 #include <com/sun/star/accessibility/XAccessibleKeyBinding.hpp>
42 #include <com/sun/star/accessibility/XAccessibleRelationSet.hpp>
43 #include <com/sun/star/accessibility/XAccessibleStateSet.hpp>
44 #include <com/sun/star/accessibility/XAccessibleTable.hpp>
45 #include <com/sun/star/accessibility/XAccessibleTableSelection.hpp>
46 #include <com/sun/star/accessibility/XAccessibleText.hpp>
47 #include <com/sun/star/accessibility/XAccessibleValue.hpp>
48 #include <com/sun/star/awt/FontWeight.hpp>
49 #include <com/sun/star/beans/PropertyValue.hpp>
50 #include <com/sun/star/lang/DisposedException.hpp>
51 #include <com/sun/star/uno/Sequence.hxx>
53 #include <comphelper/AccessibleImplementationHelper.hxx>
54 #include <o3tl/any.hxx>
55 #include <sal/log.hxx>
58 using namespace css::accessibility
;
59 using namespace css::beans
;
60 using namespace css::uno
;
62 Qt5AccessibleWidget::Qt5AccessibleWidget(const Reference
<XAccessible
> xAccessible
, QObject
* pObject
)
63 : m_xAccessible(xAccessible
)
66 Reference
<XAccessibleContext
> xContext
= xAccessible
->getAccessibleContext();
67 Reference
<XAccessibleEventBroadcaster
> xBroadcaster(xContext
, UNO_QUERY
);
68 if (xBroadcaster
.is())
70 Reference
<XAccessibleEventListener
> xListener(
71 new Qt5AccessibleEventListener(xAccessible
, this));
72 xBroadcaster
->addAccessibleEventListener(xListener
);
76 Reference
<XAccessibleContext
> Qt5AccessibleWidget::getAccessibleContextImpl() const
78 Reference
<XAccessibleContext
> xAc
;
80 if (m_xAccessible
.is())
84 xAc
= m_xAccessible
->getAccessibleContext();
86 catch (css::lang::DisposedException
/*ex*/)
88 SAL_WARN("vcl.qt5", "Accessible context disposed already");
90 // sometimes getAccessibleContext throws also RuntimeException if context is no longer alive
91 catch (css::uno::RuntimeException
/*ex*/)
93 // so let's catch it here, cuz otherwise soffice falls flat on its face
94 // with FatalError and nothing else
95 SAL_WARN("vcl.qt5", "Accessible context no longer alive");
102 QWindow
* Qt5AccessibleWidget::window() const { return nullptr; }
104 int Qt5AccessibleWidget::childCount() const
106 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
110 return xAc
->getAccessibleChildCount();
113 int Qt5AccessibleWidget::indexOfChild(const QAccessibleInterface
* /* child */) const { return 0; }
117 QAccessible::Relation
lcl_matchUnoRelation(short relationType
)
119 switch (relationType
)
121 case AccessibleRelationType::CONTROLLER_FOR
:
122 return QAccessible::Controller
;
123 case AccessibleRelationType::CONTROLLED_BY
:
124 return QAccessible::Controlled
;
125 case AccessibleRelationType::LABEL_FOR
:
126 return QAccessible::Label
;
127 case AccessibleRelationType::LABELED_BY
:
128 return QAccessible::Labelled
;
129 case AccessibleRelationType::INVALID
:
130 case AccessibleRelationType::CONTENT_FLOWS_FROM
:
131 case AccessibleRelationType::CONTENT_FLOWS_TO
:
132 case AccessibleRelationType::MEMBER_OF
:
133 case AccessibleRelationType::SUB_WINDOW_OF
:
134 case AccessibleRelationType::NODE_CHILD_OF
:
135 case AccessibleRelationType::DESCRIBED_BY
:
137 SAL_WARN("vcl.qt5", "Unmatched relation: " << relationType
);
142 short lcl_matchQtRelation(QAccessible::Relation relationType
)
144 switch (relationType
)
146 case QAccessible::Controller
:
147 return AccessibleRelationType::CONTROLLER_FOR
;
148 case QAccessible::Controlled
:
149 return AccessibleRelationType::CONTROLLED_BY
;
150 case QAccessible::Label
:
151 return AccessibleRelationType::LABEL_FOR
;
152 case QAccessible::Labelled
:
153 return AccessibleRelationType::LABELED_BY
;
155 SAL_WARN("vcl.qt5", "Unmatched relation: " << relationType
);
160 void lcl_appendRelation(QVector
<QPair
<QAccessibleInterface
*, QAccessible::Relation
>>* relations
,
161 AccessibleRelation aRelation
)
163 QAccessible::Relation aQRelation
= lcl_matchUnoRelation(aRelation
.RelationType
);
164 sal_uInt32 nTargetCount
= aRelation
.TargetSet
.getLength();
166 for (sal_uInt32 i
= 0; i
< nTargetCount
; i
++)
168 Reference
<XAccessible
> xAccessible(aRelation
.TargetSet
[i
], uno::UNO_QUERY
);
170 { QAccessible::queryAccessibleInterface(new Qt5XAccessible(xAccessible
)), aQRelation
});
175 QVector
<QPair
<QAccessibleInterface
*, QAccessible::Relation
>>
176 Qt5AccessibleWidget::relations(QAccessible::Relation match
) const
178 QVector
<QPair
<QAccessibleInterface
*, QAccessible::Relation
>> relations
;
180 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
184 Reference
<XAccessibleRelationSet
> xRelationSet
= xAc
->getAccessibleRelationSet();
185 if (xRelationSet
.is())
187 if (match
== QAccessible::AllRelations
)
189 int count
= xRelationSet
->getRelationCount();
190 for (int i
= 0; i
< count
; i
++)
192 AccessibleRelation aRelation
= xRelationSet
->getRelation(i
);
193 lcl_appendRelation(&relations
, aRelation
);
198 AccessibleRelation aRelation
= xRelationSet
->getRelation(lcl_matchQtRelation(match
));
199 lcl_appendRelation(&relations
, aRelation
);
206 QAccessibleInterface
* Qt5AccessibleWidget::focusChild() const
208 /* if (m_pWindow->HasChildPathFocus())
209 return QAccessible::queryAccessibleInterface(
210 new Qt5XAccessible(m_xAccessible->getAccessibleContext()->getAccessibleChild(index))); */
211 return QAccessible::queryAccessibleInterface(object());
214 QRect
Qt5AccessibleWidget::rect() const
216 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
220 Reference
<XAccessibleComponent
> xAccessibleComponent(xAc
, UNO_QUERY
);
221 awt::Point aPoint
= xAccessibleComponent
->getLocation();
222 awt::Size aSize
= xAccessibleComponent
->getSize();
224 return QRect(aPoint
.X
, aPoint
.Y
, aSize
.Width
, aSize
.Height
);
227 QAccessibleInterface
* Qt5AccessibleWidget::parent() const
229 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
233 return QAccessible::queryAccessibleInterface(new Qt5XAccessible(xAc
->getAccessibleParent()));
235 QAccessibleInterface
* Qt5AccessibleWidget::child(int index
) const
237 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
241 return QAccessible::queryAccessibleInterface(
242 new Qt5XAccessible(xAc
->getAccessibleChild(index
)));
245 QString
Qt5AccessibleWidget::text(QAccessible::Text text
) const
247 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
253 case QAccessible::Name
:
254 return toQString(xAc
->getAccessibleName());
255 case QAccessible::Description
:
256 case QAccessible::DebugDescription
:
257 return toQString(xAc
->getAccessibleDescription());
258 case QAccessible::Value
:
259 case QAccessible::Help
:
260 case QAccessible::Accelerator
:
261 case QAccessible::UserText
:
263 return QString("Unknown");
266 QAccessible::Role
Qt5AccessibleWidget::role() const
268 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
270 return QAccessible::NoRole
;
272 switch (xAc
->getAccessibleRole())
274 case AccessibleRole::UNKNOWN
:
275 return QAccessible::NoRole
;
277 case AccessibleRole::ALERT
:
278 return QAccessible::AlertMessage
;
280 case AccessibleRole::COLUMN_HEADER
:
281 return QAccessible::ColumnHeader
;
283 case AccessibleRole::CANVAS
:
284 return QAccessible::Canvas
;
286 case AccessibleRole::CHECK_BOX
:
287 return QAccessible::CheckBox
;
289 case AccessibleRole::CHECK_MENU_ITEM
:
290 return QAccessible::MenuItem
;
292 case AccessibleRole::COLOR_CHOOSER
:
293 return QAccessible::ColorChooser
;
295 case AccessibleRole::COMBO_BOX
:
296 return QAccessible::ComboBox
;
298 case AccessibleRole::DATE_EDITOR
:
299 return QAccessible::EditableText
;
301 case AccessibleRole::DESKTOP_ICON
:
302 return QAccessible::Graphic
;
304 case AccessibleRole::DESKTOP_PANE
:
305 case AccessibleRole::DIRECTORY_PANE
:
306 return QAccessible::Pane
;
308 case AccessibleRole::DIALOG
:
309 return QAccessible::Dialog
;
311 case AccessibleRole::DOCUMENT
:
312 return QAccessible::Document
;
314 case AccessibleRole::EMBEDDED_OBJECT
:
315 return QAccessible::UserRole
;
317 case AccessibleRole::END_NOTE
:
318 return QAccessible::Note
;
320 case AccessibleRole::FILLER
:
321 return QAccessible::Whitespace
;
323 case AccessibleRole::FONT_CHOOSER
:
324 return QAccessible::UserRole
;
326 case AccessibleRole::FOOTER
:
327 return QAccessible::Footer
;
329 case AccessibleRole::FOOTNOTE
:
330 return QAccessible::Note
;
332 case AccessibleRole::FRAME
: // top-level window with title bar
333 return QAccessible::Window
;
335 case AccessibleRole::GLASS_PANE
:
336 return QAccessible::UserRole
;
338 case AccessibleRole::GRAPHIC
:
339 return QAccessible::Graphic
;
341 case AccessibleRole::GROUP_BOX
:
342 return QAccessible::Grouping
;
344 case AccessibleRole::HEADER
:
345 return QAccessible::UserRole
;
347 case AccessibleRole::HEADING
:
348 return QAccessible::Heading
;
350 case AccessibleRole::HYPER_LINK
:
351 return QAccessible::Link
;
353 case AccessibleRole::ICON
:
354 return QAccessible::Graphic
;
356 case AccessibleRole::INTERNAL_FRAME
:
357 return QAccessible::UserRole
;
359 case AccessibleRole::LABEL
:
360 return QAccessible::StaticText
;
362 case AccessibleRole::LAYERED_PANE
:
363 return QAccessible::Pane
;
365 case AccessibleRole::LIST
:
366 return QAccessible::List
;
368 case AccessibleRole::LIST_ITEM
:
369 return QAccessible::ListItem
;
371 case AccessibleRole::MENU
:
372 case AccessibleRole::MENU_BAR
:
373 return QAccessible::MenuBar
;
375 case AccessibleRole::MENU_ITEM
:
376 return QAccessible::MenuItem
;
378 case AccessibleRole::OPTION_PANE
:
379 return QAccessible::Pane
;
381 case AccessibleRole::PAGE_TAB
:
382 return QAccessible::PageTab
;
384 case AccessibleRole::PAGE_TAB_LIST
:
385 return QAccessible::PageTabList
;
387 case AccessibleRole::PANEL
:
388 return QAccessible::Pane
;
390 case AccessibleRole::PARAGRAPH
:
391 return QAccessible::Paragraph
;
393 case AccessibleRole::PASSWORD_TEXT
:
394 return QAccessible::EditableText
;
396 case AccessibleRole::POPUP_MENU
:
397 return QAccessible::PopupMenu
;
399 case AccessibleRole::PUSH_BUTTON
:
400 return QAccessible::Button
;
402 case AccessibleRole::PROGRESS_BAR
:
403 return QAccessible::ProgressBar
;
405 case AccessibleRole::RADIO_BUTTON
:
406 return QAccessible::RadioButton
;
408 case AccessibleRole::RADIO_MENU_ITEM
:
409 return QAccessible::MenuItem
;
411 case AccessibleRole::ROW_HEADER
:
412 return QAccessible::RowHeader
;
414 case AccessibleRole::ROOT_PANE
:
415 return QAccessible::Pane
;
417 case AccessibleRole::SCROLL_BAR
:
418 return QAccessible::ScrollBar
;
420 case AccessibleRole::SCROLL_PANE
:
421 return QAccessible::Pane
;
423 case AccessibleRole::SHAPE
:
424 return QAccessible::Graphic
;
426 case AccessibleRole::SEPARATOR
:
427 return QAccessible::Separator
;
429 case AccessibleRole::SLIDER
:
430 return QAccessible::Slider
;
432 case AccessibleRole::SPIN_BOX
:
433 return QAccessible::SpinBox
;
435 case AccessibleRole::SPLIT_PANE
:
436 return QAccessible::Pane
;
438 case AccessibleRole::STATUS_BAR
:
439 return QAccessible::StatusBar
;
441 case AccessibleRole::TABLE
:
442 return QAccessible::Table
;
444 case AccessibleRole::TABLE_CELL
:
445 return QAccessible::Cell
;
447 case AccessibleRole::TEXT
:
448 return QAccessible::EditableText
;
450 case AccessibleRole::TEXT_FRAME
:
451 return QAccessible::UserRole
;
453 case AccessibleRole::TOGGLE_BUTTON
:
454 return QAccessible::Button
;
456 case AccessibleRole::TOOL_BAR
:
457 return QAccessible::ToolBar
;
459 case AccessibleRole::TOOL_TIP
:
460 return QAccessible::ToolTip
;
462 case AccessibleRole::TREE
:
463 return QAccessible::Tree
;
465 case AccessibleRole::VIEW_PORT
:
466 return QAccessible::UserRole
;
468 case AccessibleRole::BUTTON_DROPDOWN
:
469 return QAccessible::Button
;
471 case AccessibleRole::BUTTON_MENU
:
472 return QAccessible::Button
;
474 case AccessibleRole::CAPTION
:
475 return QAccessible::StaticText
;
477 case AccessibleRole::CHART
:
478 return QAccessible::Chart
;
480 case AccessibleRole::EDIT_BAR
:
481 return QAccessible::Equation
;
483 case AccessibleRole::FORM
:
484 return QAccessible::Form
;
486 case AccessibleRole::IMAGE_MAP
:
487 return QAccessible::Graphic
;
489 case AccessibleRole::NOTE
:
490 return QAccessible::Note
;
492 case AccessibleRole::RULER
:
493 return QAccessible::UserRole
;
495 case AccessibleRole::SECTION
:
496 return QAccessible::Section
;
498 case AccessibleRole::TREE_ITEM
:
499 return QAccessible::TreeItem
;
501 case AccessibleRole::TREE_TABLE
:
502 return QAccessible::Tree
;
504 case AccessibleRole::COMMENT
:
505 return QAccessible::Note
;
507 case AccessibleRole::COMMENT_END
:
508 return QAccessible::UserRole
;
510 case AccessibleRole::DOCUMENT_PRESENTATION
:
511 return QAccessible::Document
;
513 case AccessibleRole::DOCUMENT_SPREADSHEET
:
514 return QAccessible::Document
;
516 case AccessibleRole::DOCUMENT_TEXT
:
517 return QAccessible::Document
;
519 case AccessibleRole::STATIC
:
520 return QAccessible::StaticText
;
522 /* Ignore window objects for sub-menus, combo- and list boxes,
523 * which are exposed as children of their parents.
525 case AccessibleRole::WINDOW
: // top-level window without title bar
527 return QAccessible::Window
;
532 "Unmapped role: " << m_xAccessible
->getAccessibleContext()->getAccessibleRole());
533 return QAccessible::NoRole
;
538 void lcl_addState(QAccessible::State
* state
, sal_Int16 nState
)
542 case AccessibleStateType::INVALID
:
543 state
->invalid
= true;
545 case AccessibleStateType::ACTIVE
:
546 state
->active
= true;
548 case AccessibleStateType::ARMED
:
551 case AccessibleStateType::BUSY
:
554 case AccessibleStateType::CHECKED
:
555 state
->checked
= true;
557 case AccessibleStateType::EDITABLE
:
558 state
->editable
= true;
560 case AccessibleStateType::ENABLED
:
561 state
->disabled
= false;
563 case AccessibleStateType::EXPANDABLE
:
564 state
->expandable
= true;
566 case AccessibleStateType::FOCUSABLE
:
567 state
->focusable
= true;
569 case AccessibleStateType::FOCUSED
:
570 state
->focused
= true;
572 case AccessibleStateType::HORIZONTAL
:
575 case AccessibleStateType::ICONIFIED
:
578 case AccessibleStateType::INDETERMINATE
:
581 case AccessibleStateType::MANAGES_DESCENDANTS
:
584 case AccessibleStateType::MODAL
:
587 case AccessibleStateType::OPAQUE
:
590 case AccessibleStateType::PRESSED
:
591 state
->pressed
= true;
593 case AccessibleStateType::RESIZABLE
:
594 state
->sizeable
= true;
596 case AccessibleStateType::SELECTABLE
:
597 state
->selectable
= true;
599 case AccessibleStateType::SELECTED
:
600 state
->selected
= true;
602 case AccessibleStateType::SENSITIVE
:
605 case AccessibleStateType::SHOWING
:
608 case AccessibleStateType::SINGLE_LINE
:
611 case AccessibleStateType::STALE
:
614 case AccessibleStateType::TRANSIENT
:
617 case AccessibleStateType::VERTICAL
:
620 case AccessibleStateType::VISIBLE
:
621 state
->invisible
= false;
623 case AccessibleStateType::DEFAULT
:
626 case AccessibleStateType::DEFUNC
:
627 state
->invalid
= true;
629 case AccessibleStateType::MULTI_SELECTABLE
:
630 state
->multiSelectable
= true;
633 SAL_WARN("vcl.qt5", "Unmapped state: " << nState
);
639 QAccessible::State
Qt5AccessibleWidget::state() const
641 QAccessible::State state
;
643 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
647 Reference
<XAccessibleStateSet
> xStateSet(xAc
->getAccessibleStateSet());
652 Sequence
<sal_Int16
> aStates
= xStateSet
->getStates();
654 for (sal_Int32 n
= 0; n
< aStates
.getLength(); n
++)
656 lcl_addState(&state
, n
);
662 QColor
Qt5AccessibleWidget::foregroundColor() const
664 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
668 Reference
<XAccessibleComponent
> xAccessibleComponent(xAc
, UNO_QUERY
);
669 return toQColor(xAccessibleComponent
->getForeground());
672 QColor
Qt5AccessibleWidget::backgroundColor() const
674 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
678 Reference
<XAccessibleComponent
> xAccessibleComponent(xAc
, UNO_QUERY
);
679 return toQColor(xAccessibleComponent
->getBackground());
682 void* Qt5AccessibleWidget::interface_cast(QAccessible::InterfaceType t
)
684 if (t
== QAccessible::ActionInterface
)
685 return static_cast<QAccessibleActionInterface
*>(this);
686 if (t
== QAccessible::TextInterface
)
687 return static_cast<QAccessibleTextInterface
*>(this);
688 if (t
== QAccessible::EditableTextInterface
)
689 return static_cast<QAccessibleEditableTextInterface
*>(this);
690 if (t
== QAccessible::ValueInterface
)
691 return static_cast<QAccessibleValueInterface
*>(this);
692 if (t
== QAccessible::TableInterface
)
693 return static_cast<QAccessibleTableInterface
*>(this);
697 bool Qt5AccessibleWidget::isValid() const
699 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
703 QObject
* Qt5AccessibleWidget::object() const { return m_pObject
; }
705 void Qt5AccessibleWidget::setText(QAccessible::Text
/* t */, const QString
& /* text */) {}
707 QAccessibleInterface
* Qt5AccessibleWidget::childAt(int x
, int y
) const
709 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
713 Reference
<XAccessibleComponent
> xAccessibleComponent(xAc
, UNO_QUERY
);
714 return QAccessible::queryAccessibleInterface(
715 new Qt5XAccessible(xAccessibleComponent
->getAccessibleAtPoint(awt::Point(x
, y
))));
718 QAccessibleInterface
* Qt5AccessibleWidget::customFactory(const QString
& classname
, QObject
* object
)
720 if (classname
== QLatin1String("Qt5Widget") && object
&& object
->isWidgetType())
722 Qt5Widget
* pWidget
= static_cast<Qt5Widget
*>(object
);
723 vcl::Window
* pWindow
= pWidget
->frame().GetWindow();
726 return new Qt5AccessibleWidget(pWindow
->GetAccessible(), object
);
728 if (classname
== QLatin1String("Qt5XAccessible") && object
)
730 Qt5XAccessible
* pXAccessible
= dynamic_cast<Qt5XAccessible
*>(object
);
731 if (pXAccessible
&& pXAccessible
->m_xAccessible
.is())
732 return new Qt5AccessibleWidget(pXAccessible
->m_xAccessible
, object
);
738 // QAccessibleActionInterface
739 QStringList
Qt5AccessibleWidget::actionNames() const
741 QStringList actionNames
;
742 Reference
<XAccessibleAction
> xAccessibleAction(m_xAccessible
, UNO_QUERY
);
743 if (!xAccessibleAction
.is())
746 int count
= xAccessibleAction
->getAccessibleActionCount();
747 for (int i
= 0; i
< count
; i
++)
749 OUString desc
= xAccessibleAction
->getAccessibleActionDescription(i
);
750 actionNames
.append(toQString(desc
));
755 void Qt5AccessibleWidget::doAction(const QString
& actionName
)
757 Reference
<XAccessibleAction
> xAccessibleAction(m_xAccessible
, UNO_QUERY
);
758 if (!xAccessibleAction
.is())
761 int index
= actionNames().indexOf(actionName
);
764 xAccessibleAction
->doAccessibleAction(index
);
767 QStringList
Qt5AccessibleWidget::keyBindingsForAction(const QString
& actionName
) const
769 QStringList keyBindings
;
770 Reference
<XAccessibleAction
> xAccessibleAction(m_xAccessible
, UNO_QUERY
);
771 if (!xAccessibleAction
.is())
774 int index
= actionNames().indexOf(actionName
);
778 Reference
<XAccessibleKeyBinding
> xKeyBinding
779 = xAccessibleAction
->getAccessibleActionKeyBinding(index
);
781 if (!xKeyBinding
.is())
784 int count
= xKeyBinding
->getAccessibleKeyBindingCount();
785 for (int i
= 0; i
< count
; i
++)
787 Sequence
<awt::KeyStroke
> keyStroke
= xKeyBinding
->getAccessibleKeyBinding(i
);
788 keyBindings
.append(toQString(comphelper::GetkeyBindingStrByXkeyBinding(keyStroke
)));
793 QAccessibleValueInterface
* Qt5AccessibleWidget::valueInterface() { return nullptr; }
795 QAccessibleTextInterface
* Qt5AccessibleWidget::textInterface() { return nullptr; }
797 // QAccessibleTextInterface
798 void Qt5AccessibleWidget::addSelection(int /* startOffset */, int /* endOffset */)
800 SAL_INFO("vcl.qt5", "Unsupported QAccessibleTextInterface::addSelection");
805 OUString
lcl_convertFontWeight(double fontWeight
)
807 if (fontWeight
== awt::FontWeight::THIN
|| fontWeight
== awt::FontWeight::ULTRALIGHT
)
809 if (fontWeight
== awt::FontWeight::LIGHT
)
811 if (fontWeight
== awt::FontWeight::SEMILIGHT
)
813 if (fontWeight
== awt::FontWeight::NORMAL
)
815 if (fontWeight
== awt::FontWeight::SEMIBOLD
)
817 if (fontWeight
== awt::FontWeight::BOLD
)
819 if (fontWeight
== awt::FontWeight::ULTRABOLD
)
821 if (fontWeight
== awt::FontWeight::BLACK
)
824 // awt::FontWeight::DONTKNOW || fontWeight == awt::FontWeight::NORMAL
829 QString
Qt5AccessibleWidget::attributes(int offset
, int* startOffset
, int* endOffset
) const
831 Reference
<XAccessibleText
> xText(m_xAccessible
, UNO_QUERY
);
835 // handle special values for offset the same way base class's QAccessibleTextWidget::attributes does
836 // (as defined in IAccessible 2: -1 -> length, -2 -> cursor position)
838 offset
= cursorPosition(); // currently always returns 0
840 const int nTextLength
= characterCount();
841 if (offset
== -1 || offset
== nTextLength
)
842 offset
= nTextLength
- 1;
844 if (offset
< 0 || offset
> nTextLength
)
851 const Sequence
<PropertyValue
> attribs
852 = xText
->getCharacterAttributes(offset
, Sequence
<OUString
>());
854 for (PropertyValue
const& prop
: attribs
)
856 if (prop
.Name
== "CharFontName")
858 aRet
+= "font-family:" + *o3tl::doAccess
<OUString
>(prop
.Value
) + ";";
861 if (prop
.Name
== "CharHeight")
863 aRet
+= "font-size:" + OUString::number(*o3tl::doAccess
<double>(prop
.Value
)) + "pt;";
866 if (prop
.Name
== "CharWeight")
868 aRet
+= "font-weight:" + lcl_convertFontWeight(*o3tl::doAccess
<double>(prop
.Value
))
873 *startOffset
= offset
;
874 *endOffset
= offset
+ 1;
875 return toQString(aRet
);
877 int Qt5AccessibleWidget::characterCount() const
879 Reference
<XAccessibleText
> xText(m_xAccessible
, UNO_QUERY
);
881 return xText
->getCharacterCount();
884 QRect
Qt5AccessibleWidget::characterRect(int /* offset */) const
886 SAL_INFO("vcl.qt5", "Unsupported QAccessibleTextInterface::characterRect");
889 int Qt5AccessibleWidget::cursorPosition() const
891 SAL_INFO("vcl.qt5", "Unsupported QAccessibleTextInterface::cursorPosition");
894 int Qt5AccessibleWidget::offsetAtPoint(const QPoint
& /* point */) const
896 SAL_INFO("vcl.qt5", "Unsupported QAccessibleTextInterface::offsetAtPoint");
899 void Qt5AccessibleWidget::removeSelection(int /* selectionIndex */)
901 SAL_INFO("vcl.qt5", "Unsupported QAccessibleTextInterface::removeSelection");
903 void Qt5AccessibleWidget::scrollToSubstring(int startIndex
, int endIndex
)
905 Reference
<XAccessibleText
> xText(m_xAccessible
, UNO_QUERY
);
907 xText
->scrollSubstringTo(startIndex
, endIndex
, AccessibleScrollType_SCROLL_ANYWHERE
);
910 void Qt5AccessibleWidget::selection(int selectionIndex
, int* startOffset
, int* endOffset
) const
912 if (!startOffset
&& !endOffset
)
915 Reference
<XAccessibleText
> xText
;
916 if (selectionIndex
== 0)
917 xText
= Reference
<XAccessibleText
>(m_xAccessible
, UNO_QUERY
);
920 *startOffset
= xText
.is() ? xText
->getSelectionStart() : 0;
922 *endOffset
= xText
.is() ? xText
->getSelectionEnd() : 0;
925 int Qt5AccessibleWidget::selectionCount() const
927 Reference
<XAccessibleText
> xText(m_xAccessible
, UNO_QUERY
);
928 if (xText
.is() && !xText
->getSelectedText().isEmpty())
929 return 1; // Only 1 selection supported atm
932 void Qt5AccessibleWidget::setCursorPosition(int position
)
934 Reference
<XAccessibleText
> xText(m_xAccessible
, UNO_QUERY
);
936 xText
->setCaretPosition(position
);
938 void Qt5AccessibleWidget::setSelection(int /* selectionIndex */, int startOffset
, int endOffset
)
940 Reference
<XAccessibleText
> xText(m_xAccessible
, UNO_QUERY
);
942 xText
->setSelection(startOffset
, endOffset
);
944 QString
Qt5AccessibleWidget::text(int startOffset
, int endOffset
) const
946 Reference
<XAccessibleText
> xText(m_xAccessible
, UNO_QUERY
);
948 return toQString(xText
->getTextRange(startOffset
, endOffset
));
951 QString
Qt5AccessibleWidget::textAfterOffset(int /* offset */,
952 QAccessible::TextBoundaryType
/* boundaryType */,
953 int* /* startOffset */, int* /* endOffset */) const
955 SAL_INFO("vcl.qt5", "Unsupported QAccessibleTextInterface::textAfterOffset");
958 QString
Qt5AccessibleWidget::textAtOffset(int /* offset */,
959 QAccessible::TextBoundaryType
/* boundaryType */,
960 int* /* startOffset */, int* /* endOffset */) const
962 SAL_INFO("vcl.qt5", "Unsupported QAccessibleTextInterface::textAtOffset");
965 QString
Qt5AccessibleWidget::textBeforeOffset(int /* offset */,
966 QAccessible::TextBoundaryType
/* boundaryType */,
967 int* /* startOffset */, int* /* endOffset */) const
969 SAL_INFO("vcl.qt5", "Unsupported QAccessibleTextInterface::textBeforeOffset");
973 // QAccessibleEditableTextInterface
975 void Qt5AccessibleWidget::deleteText(int startOffset
, int endOffset
)
977 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
981 Reference
<XAccessibleEditableText
> xEditableText(xAc
, UNO_QUERY
);
982 if (!xEditableText
.is())
984 xEditableText
->deleteText(startOffset
, endOffset
);
987 void Qt5AccessibleWidget::insertText(int offset
, const QString
& text
)
989 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
993 Reference
<XAccessibleEditableText
> xEditableText(xAc
, UNO_QUERY
);
994 if (!xEditableText
.is())
996 xEditableText
->insertText(toOUString(text
), offset
);
999 void Qt5AccessibleWidget::replaceText(int startOffset
, int endOffset
, const QString
& text
)
1001 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1005 Reference
<XAccessibleEditableText
> xEditableText(xAc
, UNO_QUERY
);
1006 if (!xEditableText
.is())
1008 xEditableText
->replaceText(startOffset
, endOffset
, toOUString(text
));
1011 // QAccessibleValueInterface
1012 QVariant
Qt5AccessibleWidget::currentValue() const
1014 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1018 Reference
<XAccessibleValue
> xValue(xAc
, UNO_QUERY
);
1022 xValue
->getCurrentValue() >>= aDouble
;
1023 return QVariant(aDouble
);
1025 QVariant
Qt5AccessibleWidget::maximumValue() const
1027 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1031 Reference
<XAccessibleValue
> xValue(xAc
, UNO_QUERY
);
1035 xValue
->getMaximumValue() >>= aDouble
;
1036 return QVariant(aDouble
);
1038 QVariant
Qt5AccessibleWidget::minimumStepSize() const { return QVariant(); }
1039 QVariant
Qt5AccessibleWidget::minimumValue() const
1041 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1045 Reference
<XAccessibleValue
> xValue(xAc
, UNO_QUERY
);
1049 xValue
->getMinimumValue() >>= aDouble
;
1050 return QVariant(aDouble
);
1052 void Qt5AccessibleWidget::setCurrentValue(const QVariant
& value
)
1054 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1058 Reference
<XAccessibleValue
> xValue(xAc
, UNO_QUERY
);
1061 xValue
->setCurrentValue(Any(value
.toDouble()));
1065 QAccessibleInterface
* Qt5AccessibleWidget::caption() const
1067 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1071 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1074 return QAccessible::queryAccessibleInterface(
1075 new Qt5XAccessible(xTable
->getAccessibleCaption()));
1078 QAccessibleInterface
* Qt5AccessibleWidget::cellAt(int row
, int column
) const
1080 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1084 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1087 return QAccessible::queryAccessibleInterface(
1088 new Qt5XAccessible(xTable
->getAccessibleCellAt(row
, column
)));
1091 int Qt5AccessibleWidget::columnCount() const
1093 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1097 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1100 return xTable
->getAccessibleColumnCount();
1103 QString
Qt5AccessibleWidget::columnDescription(int column
) const
1105 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1109 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1112 return toQString(xTable
->getAccessibleColumnDescription(column
));
1115 bool Qt5AccessibleWidget::isColumnSelected(int /* column */) const { return true; }
1117 bool Qt5AccessibleWidget::isRowSelected(int /* row */) const { return true; }
1119 void Qt5AccessibleWidget::modelChange(QAccessibleTableModelChangeEvent
*) {}
1121 int Qt5AccessibleWidget::rowCount() const
1123 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1127 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1130 return xTable
->getAccessibleRowCount();
1133 QString
Qt5AccessibleWidget::rowDescription(int row
) const
1135 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1139 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1142 return toQString(xTable
->getAccessibleRowDescription(row
));
1145 bool Qt5AccessibleWidget::selectColumn(int column
)
1147 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1151 Reference
<XAccessibleTableSelection
> xTableSelection(xAc
, UNO_QUERY
);
1152 if (!xTableSelection
.is())
1154 return xTableSelection
->selectColumn(column
);
1157 bool Qt5AccessibleWidget::selectRow(int row
)
1159 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1163 Reference
<XAccessibleTableSelection
> xTableSelection(xAc
, UNO_QUERY
);
1164 if (!xTableSelection
.is())
1166 return xTableSelection
->selectRow(row
);
1169 int Qt5AccessibleWidget::selectedCellCount() const
1171 SAL_INFO("vcl.qt5", "Unsupported QAccessibleTableInterface::selectedCellCount");
1175 QList
<QAccessibleInterface
*> Qt5AccessibleWidget::selectedCells() const
1177 SAL_INFO("vcl.qt5", "Unsupported QAccessibleTableInterface::selectedCells");
1178 return QList
<QAccessibleInterface
*>();
1181 int Qt5AccessibleWidget::selectedColumnCount() const
1183 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1187 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1190 return xTable
->getSelectedAccessibleColumns().getLength();
1193 QList
<int> Qt5AccessibleWidget::selectedColumns() const
1195 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1197 return QList
<int>();
1199 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1201 return QList
<int>();
1202 return toQList(xTable
->getSelectedAccessibleColumns());
1205 int Qt5AccessibleWidget::selectedRowCount() const
1207 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1211 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1214 return xTable
->getSelectedAccessibleRows().getLength();
1217 QList
<int> Qt5AccessibleWidget::selectedRows() const
1219 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1221 return QList
<int>();
1223 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1225 return QList
<int>();
1226 return toQList(xTable
->getSelectedAccessibleRows());
1229 QAccessibleInterface
* Qt5AccessibleWidget::summary() const
1231 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1235 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1238 return QAccessible::queryAccessibleInterface(
1239 new Qt5XAccessible(xTable
->getAccessibleSummary()));
1242 bool Qt5AccessibleWidget::unselectColumn(int column
)
1244 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1248 Reference
<XAccessibleTableSelection
> xTableSelection(xAc
, UNO_QUERY
);
1249 if (!xTableSelection
.is())
1251 return xTableSelection
->unselectColumn(column
);
1254 bool Qt5AccessibleWidget::unselectRow(int row
)
1256 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1260 Reference
<XAccessibleTableSelection
> xTableSelection(xAc
, UNO_QUERY
);
1261 if (!xTableSelection
.is())
1263 return xTableSelection
->unselectRow(row
);
1266 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */