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 <QtAccessibleWidget.hxx>
21 #include <QtAccessibleWidget.moc>
23 #include <QtGui/QAccessibleInterface>
25 #include <QtAccessibleEventListener.hxx>
26 #include <QtFrame.hxx>
27 #include <QtTools.hxx>
28 #include <QtWidget.hxx>
29 #include <QtXAccessible.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/AccessibleTextType.hpp>
36 #include <com/sun/star/accessibility/XAccessible.hpp>
37 #include <com/sun/star/accessibility/XAccessibleAction.hpp>
38 #include <com/sun/star/accessibility/XAccessibleComponent.hpp>
39 #include <com/sun/star/accessibility/XAccessibleEditableText.hpp>
40 #include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp>
41 #include <com/sun/star/accessibility/XAccessibleEventListener.hpp>
42 #include <com/sun/star/accessibility/XAccessibleKeyBinding.hpp>
43 #include <com/sun/star/accessibility/XAccessibleRelationSet.hpp>
44 #include <com/sun/star/accessibility/XAccessibleStateSet.hpp>
45 #include <com/sun/star/accessibility/XAccessibleTable.hpp>
46 #include <com/sun/star/accessibility/XAccessibleTableSelection.hpp>
47 #include <com/sun/star/accessibility/XAccessibleText.hpp>
48 #include <com/sun/star/accessibility/XAccessibleValue.hpp>
49 #include <com/sun/star/awt/FontWeight.hpp>
50 #include <com/sun/star/beans/PropertyValue.hpp>
51 #include <com/sun/star/lang/DisposedException.hpp>
52 #include <com/sun/star/uno/Sequence.hxx>
54 #include <comphelper/AccessibleImplementationHelper.hxx>
55 #include <o3tl/any.hxx>
56 #include <sal/log.hxx>
59 using namespace css::accessibility
;
60 using namespace css::beans
;
61 using namespace css::uno
;
63 QtAccessibleWidget::QtAccessibleWidget(const Reference
<XAccessible
> xAccessible
, QObject
* pObject
)
64 : m_xAccessible(xAccessible
)
67 Reference
<XAccessibleContext
> xContext
= xAccessible
->getAccessibleContext();
68 Reference
<XAccessibleEventBroadcaster
> xBroadcaster(xContext
, UNO_QUERY
);
69 if (xBroadcaster
.is())
71 Reference
<XAccessibleEventListener
> xListener(
72 new QtAccessibleEventListener(xAccessible
, this));
73 xBroadcaster
->addAccessibleEventListener(xListener
);
77 Reference
<XAccessibleContext
> QtAccessibleWidget::getAccessibleContextImpl() const
79 Reference
<XAccessibleContext
> xAc
;
81 if (m_xAccessible
.is())
85 xAc
= m_xAccessible
->getAccessibleContext();
87 catch (css::lang::DisposedException
/*ex*/)
89 SAL_WARN("vcl.qt", "Accessible context disposed already");
91 // sometimes getAccessibleContext throws also RuntimeException if context is no longer alive
92 catch (css::uno::RuntimeException
/*ex*/)
94 // so let's catch it here, cuz otherwise soffice falls flat on its face
95 // with FatalError and nothing else
96 SAL_WARN("vcl.qt", "Accessible context no longer alive");
103 css::uno::Reference
<css::accessibility::XAccessibleTable
>
104 QtAccessibleWidget::getAccessibleTableForParent() const
106 Reference
<XAccessibleContext
> xAcc
= getAccessibleContextImpl();
110 Reference
<XAccessible
> xParent
= xAcc
->getAccessibleParent();
114 Reference
<XAccessibleContext
> xParentContext
= xParent
->getAccessibleContext();
115 if (!xParentContext
.is())
118 return Reference
<XAccessibleTable
>(xParentContext
, UNO_QUERY
);
121 QWindow
* QtAccessibleWidget::window() const { return nullptr; }
123 int QtAccessibleWidget::childCount() const
125 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
129 return xAc
->getAccessibleChildCount();
132 int QtAccessibleWidget::indexOfChild(const QAccessibleInterface
* /* child */) const { return 0; }
136 sal_Int16
lcl_matchQtTextBoundaryType(QAccessible::TextBoundaryType boundaryType
)
138 switch (boundaryType
)
140 case QAccessible::CharBoundary
:
141 return com::sun::star::accessibility::AccessibleTextType::CHARACTER
;
142 case QAccessible::WordBoundary
:
143 return com::sun::star::accessibility::AccessibleTextType::WORD
;
144 case QAccessible::SentenceBoundary
:
145 return com::sun::star::accessibility::AccessibleTextType::SENTENCE
;
146 case QAccessible::ParagraphBoundary
:
147 return com::sun::star::accessibility::AccessibleTextType::PARAGRAPH
;
148 case QAccessible::LineBoundary
:
149 return com::sun::star::accessibility::AccessibleTextType::LINE
;
150 case QAccessible::NoBoundary
:
151 // assert here, better handle it directly at call site
153 && "No match for QAccessible::NoBoundary, handle it separately at call site.");
159 SAL_WARN("vcl.qt", "Unmatched text boundary type: " << boundaryType
);
163 QAccessible::Relation
lcl_matchUnoRelation(short relationType
)
165 switch (relationType
)
167 case AccessibleRelationType::CONTROLLER_FOR
:
168 return QAccessible::Controller
;
169 case AccessibleRelationType::CONTROLLED_BY
:
170 return QAccessible::Controlled
;
171 case AccessibleRelationType::LABEL_FOR
:
172 return QAccessible::Label
;
173 case AccessibleRelationType::LABELED_BY
:
174 return QAccessible::Labelled
;
175 case AccessibleRelationType::INVALID
:
176 case AccessibleRelationType::CONTENT_FLOWS_FROM
:
177 case AccessibleRelationType::CONTENT_FLOWS_TO
:
178 case AccessibleRelationType::MEMBER_OF
:
179 case AccessibleRelationType::SUB_WINDOW_OF
:
180 case AccessibleRelationType::NODE_CHILD_OF
:
181 case AccessibleRelationType::DESCRIBED_BY
:
183 SAL_WARN("vcl.qt", "Unmatched relation: " << relationType
);
188 short lcl_matchQtRelation(QAccessible::Relation relationType
)
190 switch (relationType
)
192 case QAccessible::Controller
:
193 return AccessibleRelationType::CONTROLLER_FOR
;
194 case QAccessible::Controlled
:
195 return AccessibleRelationType::CONTROLLED_BY
;
196 case QAccessible::Label
:
197 return AccessibleRelationType::LABEL_FOR
;
198 case QAccessible::Labelled
:
199 return AccessibleRelationType::LABELED_BY
;
201 SAL_WARN("vcl.qt", "Unmatched relation: " << relationType
);
206 void lcl_appendRelation(QVector
<QPair
<QAccessibleInterface
*, QAccessible::Relation
>>* relations
,
207 AccessibleRelation aRelation
)
209 QAccessible::Relation aQRelation
= lcl_matchUnoRelation(aRelation
.RelationType
);
210 sal_uInt32 nTargetCount
= aRelation
.TargetSet
.getLength();
212 for (sal_uInt32 i
= 0; i
< nTargetCount
; i
++)
214 Reference
<XAccessible
> xAccessible(aRelation
.TargetSet
[i
], uno::UNO_QUERY
);
216 { QAccessible::queryAccessibleInterface(new QtXAccessible(xAccessible
)), aQRelation
});
221 QVector
<QPair
<QAccessibleInterface
*, QAccessible::Relation
>>
222 QtAccessibleWidget::relations(QAccessible::Relation match
) const
224 QVector
<QPair
<QAccessibleInterface
*, QAccessible::Relation
>> relations
;
226 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
230 Reference
<XAccessibleRelationSet
> xRelationSet
= xAc
->getAccessibleRelationSet();
231 if (xRelationSet
.is())
233 if (match
== QAccessible::AllRelations
)
235 int count
= xRelationSet
->getRelationCount();
236 for (int i
= 0; i
< count
; i
++)
238 AccessibleRelation aRelation
= xRelationSet
->getRelation(i
);
239 lcl_appendRelation(&relations
, aRelation
);
244 AccessibleRelation aRelation
= xRelationSet
->getRelation(lcl_matchQtRelation(match
));
245 lcl_appendRelation(&relations
, aRelation
);
252 QAccessibleInterface
* QtAccessibleWidget::focusChild() const
254 /* if (m_pWindow->HasChildPathFocus())
255 return QAccessible::queryAccessibleInterface(
256 new QtXAccessible(m_xAccessible->getAccessibleContext()->getAccessibleChild(index))); */
257 return QAccessible::queryAccessibleInterface(object());
260 QRect
QtAccessibleWidget::rect() const
262 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
266 Reference
<XAccessibleComponent
> xAccessibleComponent(xAc
, UNO_QUERY
);
267 awt::Point aPoint
= xAccessibleComponent
->getLocation();
268 awt::Size aSize
= xAccessibleComponent
->getSize();
270 return QRect(aPoint
.X
, aPoint
.Y
, aSize
.Width
, aSize
.Height
);
273 QAccessibleInterface
* QtAccessibleWidget::parent() const
275 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
279 return QAccessible::queryAccessibleInterface(new QtXAccessible(xAc
->getAccessibleParent()));
281 QAccessibleInterface
* QtAccessibleWidget::child(int index
) const
283 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
287 return QAccessible::queryAccessibleInterface(new QtXAccessible(xAc
->getAccessibleChild(index
)));
290 QString
QtAccessibleWidget::text(QAccessible::Text text
) const
292 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
298 case QAccessible::Name
:
299 return toQString(xAc
->getAccessibleName());
300 case QAccessible::Description
:
301 case QAccessible::DebugDescription
:
302 return toQString(xAc
->getAccessibleDescription());
303 case QAccessible::Value
:
304 case QAccessible::Help
:
305 case QAccessible::Accelerator
:
306 case QAccessible::UserText
:
308 return QString("Unknown");
311 QAccessible::Role
QtAccessibleWidget::role() const
313 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
315 return QAccessible::NoRole
;
317 switch (xAc
->getAccessibleRole())
319 case AccessibleRole::UNKNOWN
:
320 return QAccessible::NoRole
;
322 case AccessibleRole::ALERT
:
323 return QAccessible::AlertMessage
;
325 case AccessibleRole::COLUMN_HEADER
:
326 return QAccessible::ColumnHeader
;
328 case AccessibleRole::CANVAS
:
329 return QAccessible::Canvas
;
331 case AccessibleRole::CHECK_BOX
:
332 return QAccessible::CheckBox
;
334 case AccessibleRole::CHECK_MENU_ITEM
:
335 return QAccessible::MenuItem
;
337 case AccessibleRole::COLOR_CHOOSER
:
338 return QAccessible::ColorChooser
;
340 case AccessibleRole::COMBO_BOX
:
341 return QAccessible::ComboBox
;
343 case AccessibleRole::DATE_EDITOR
:
344 return QAccessible::EditableText
;
346 case AccessibleRole::DESKTOP_ICON
:
347 return QAccessible::Graphic
;
349 case AccessibleRole::DESKTOP_PANE
:
350 case AccessibleRole::DIRECTORY_PANE
:
351 return QAccessible::Pane
;
353 case AccessibleRole::DIALOG
:
354 return QAccessible::Dialog
;
356 case AccessibleRole::DOCUMENT
:
357 return QAccessible::Document
;
359 case AccessibleRole::EMBEDDED_OBJECT
:
360 return QAccessible::UserRole
;
362 case AccessibleRole::END_NOTE
:
363 return QAccessible::Note
;
365 case AccessibleRole::FILLER
:
366 return QAccessible::Whitespace
;
368 case AccessibleRole::FONT_CHOOSER
:
369 return QAccessible::UserRole
;
371 case AccessibleRole::FOOTER
:
372 return QAccessible::Footer
;
374 case AccessibleRole::FOOTNOTE
:
375 return QAccessible::Note
;
377 case AccessibleRole::FRAME
: // top-level window with title bar
378 return QAccessible::Window
;
380 case AccessibleRole::GLASS_PANE
:
381 return QAccessible::UserRole
;
383 case AccessibleRole::GRAPHIC
:
384 return QAccessible::Graphic
;
386 case AccessibleRole::GROUP_BOX
:
387 return QAccessible::Grouping
;
389 case AccessibleRole::HEADER
:
390 return QAccessible::UserRole
;
392 case AccessibleRole::HEADING
:
393 return QAccessible::Heading
;
395 case AccessibleRole::HYPER_LINK
:
396 return QAccessible::Link
;
398 case AccessibleRole::ICON
:
399 return QAccessible::Graphic
;
401 case AccessibleRole::INTERNAL_FRAME
:
402 return QAccessible::UserRole
;
404 case AccessibleRole::LABEL
:
405 return QAccessible::StaticText
;
407 case AccessibleRole::LAYERED_PANE
:
408 return QAccessible::Pane
;
410 case AccessibleRole::LIST
:
411 return QAccessible::List
;
413 case AccessibleRole::LIST_ITEM
:
414 return QAccessible::ListItem
;
416 case AccessibleRole::MENU
:
417 case AccessibleRole::MENU_BAR
:
418 return QAccessible::MenuBar
;
420 case AccessibleRole::MENU_ITEM
:
421 return QAccessible::MenuItem
;
423 case AccessibleRole::OPTION_PANE
:
424 return QAccessible::Pane
;
426 case AccessibleRole::PAGE_TAB
:
427 return QAccessible::PageTab
;
429 case AccessibleRole::PAGE_TAB_LIST
:
430 return QAccessible::PageTabList
;
432 case AccessibleRole::PANEL
:
433 return QAccessible::Pane
;
435 case AccessibleRole::PARAGRAPH
:
436 return QAccessible::Paragraph
;
438 case AccessibleRole::PASSWORD_TEXT
:
439 return QAccessible::EditableText
;
441 case AccessibleRole::POPUP_MENU
:
442 return QAccessible::PopupMenu
;
444 case AccessibleRole::PUSH_BUTTON
:
445 return QAccessible::Button
;
447 case AccessibleRole::PROGRESS_BAR
:
448 return QAccessible::ProgressBar
;
450 case AccessibleRole::RADIO_BUTTON
:
451 return QAccessible::RadioButton
;
453 case AccessibleRole::RADIO_MENU_ITEM
:
454 return QAccessible::MenuItem
;
456 case AccessibleRole::ROW_HEADER
:
457 return QAccessible::RowHeader
;
459 case AccessibleRole::ROOT_PANE
:
460 return QAccessible::Pane
;
462 case AccessibleRole::SCROLL_BAR
:
463 return QAccessible::ScrollBar
;
465 case AccessibleRole::SCROLL_PANE
:
466 return QAccessible::Pane
;
468 case AccessibleRole::SHAPE
:
469 return QAccessible::Graphic
;
471 case AccessibleRole::SEPARATOR
:
472 return QAccessible::Separator
;
474 case AccessibleRole::SLIDER
:
475 return QAccessible::Slider
;
477 case AccessibleRole::SPIN_BOX
:
478 return QAccessible::SpinBox
;
480 case AccessibleRole::SPLIT_PANE
:
481 return QAccessible::Pane
;
483 case AccessibleRole::STATUS_BAR
:
484 return QAccessible::StatusBar
;
486 case AccessibleRole::TABLE
:
487 return QAccessible::Table
;
489 case AccessibleRole::TABLE_CELL
:
490 return QAccessible::Cell
;
492 case AccessibleRole::TEXT
:
493 return QAccessible::EditableText
;
495 case AccessibleRole::TEXT_FRAME
:
496 return QAccessible::UserRole
;
498 case AccessibleRole::TOGGLE_BUTTON
:
499 return QAccessible::Button
;
501 case AccessibleRole::TOOL_BAR
:
502 return QAccessible::ToolBar
;
504 case AccessibleRole::TOOL_TIP
:
505 return QAccessible::ToolTip
;
507 case AccessibleRole::TREE
:
508 return QAccessible::Tree
;
510 case AccessibleRole::VIEW_PORT
:
511 return QAccessible::UserRole
;
513 case AccessibleRole::BUTTON_DROPDOWN
:
514 return QAccessible::Button
;
516 case AccessibleRole::BUTTON_MENU
:
517 return QAccessible::Button
;
519 case AccessibleRole::CAPTION
:
520 return QAccessible::StaticText
;
522 case AccessibleRole::CHART
:
523 return QAccessible::Chart
;
525 case AccessibleRole::EDIT_BAR
:
526 return QAccessible::Equation
;
528 case AccessibleRole::FORM
:
529 return QAccessible::Form
;
531 case AccessibleRole::IMAGE_MAP
:
532 return QAccessible::Graphic
;
534 case AccessibleRole::NOTE
:
535 return QAccessible::Note
;
537 case AccessibleRole::RULER
:
538 return QAccessible::UserRole
;
540 case AccessibleRole::SECTION
:
541 return QAccessible::Section
;
543 case AccessibleRole::TREE_ITEM
:
544 return QAccessible::TreeItem
;
546 case AccessibleRole::TREE_TABLE
:
547 return QAccessible::Tree
;
549 case AccessibleRole::COMMENT
:
550 return QAccessible::Note
;
552 case AccessibleRole::COMMENT_END
:
553 return QAccessible::UserRole
;
555 case AccessibleRole::DOCUMENT_PRESENTATION
:
556 return QAccessible::Document
;
558 case AccessibleRole::DOCUMENT_SPREADSHEET
:
559 return QAccessible::Document
;
561 case AccessibleRole::DOCUMENT_TEXT
:
562 return QAccessible::Document
;
564 case AccessibleRole::STATIC
:
565 return QAccessible::StaticText
;
567 /* Ignore window objects for sub-menus, combo- and list boxes,
568 * which are exposed as children of their parents.
570 case AccessibleRole::WINDOW
: // top-level window without title bar
572 return QAccessible::Window
;
576 SAL_WARN("vcl.qt", "Unmapped role: " << getAccessibleContextImpl()->getAccessibleRole());
577 return QAccessible::NoRole
;
582 void lcl_addState(QAccessible::State
* state
, sal_Int16 nState
)
586 case AccessibleStateType::INVALID
:
587 state
->invalid
= true;
589 case AccessibleStateType::ACTIVE
:
590 state
->active
= true;
592 case AccessibleStateType::ARMED
:
595 case AccessibleStateType::BUSY
:
598 case AccessibleStateType::CHECKED
:
599 state
->checked
= true;
601 case AccessibleStateType::EDITABLE
:
602 state
->editable
= true;
604 case AccessibleStateType::ENABLED
:
605 state
->disabled
= false;
607 case AccessibleStateType::EXPANDABLE
:
608 state
->expandable
= true;
610 case AccessibleStateType::EXPANDED
:
611 state
->expanded
= true;
613 case AccessibleStateType::FOCUSABLE
:
614 state
->focusable
= true;
616 case AccessibleStateType::FOCUSED
:
617 state
->focused
= true;
619 case AccessibleStateType::HORIZONTAL
:
622 case AccessibleStateType::ICONIFIED
:
625 case AccessibleStateType::INDETERMINATE
:
628 case AccessibleStateType::MANAGES_DESCENDANTS
:
631 case AccessibleStateType::MODAL
:
634 case AccessibleStateType::MOVEABLE
:
635 state
->movable
= true;
637 case AccessibleStateType::MULTI_LINE
:
638 state
->multiLine
= true;
640 case AccessibleStateType::OPAQUE
:
643 case AccessibleStateType::PRESSED
:
644 state
->pressed
= true;
646 case AccessibleStateType::RESIZABLE
:
647 state
->sizeable
= true;
649 case AccessibleStateType::SELECTABLE
:
650 state
->selectable
= true;
652 case AccessibleStateType::SELECTED
:
653 state
->selected
= true;
655 case AccessibleStateType::SENSITIVE
:
658 case AccessibleStateType::SHOWING
:
661 case AccessibleStateType::SINGLE_LINE
:
664 case AccessibleStateType::STALE
:
667 case AccessibleStateType::TRANSIENT
:
670 case AccessibleStateType::VERTICAL
:
673 case AccessibleStateType::VISIBLE
:
674 state
->invisible
= false;
676 case AccessibleStateType::DEFAULT
:
679 case AccessibleStateType::DEFUNC
:
680 state
->invalid
= true;
682 case AccessibleStateType::MULTI_SELECTABLE
:
683 state
->multiSelectable
= true;
686 SAL_WARN("vcl.qt", "Unmapped state: " << nState
);
692 QAccessible::State
QtAccessibleWidget::state() const
694 QAccessible::State state
;
696 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
700 Reference
<XAccessibleStateSet
> xStateSet(xAc
->getAccessibleStateSet());
705 const Sequence
<sal_Int16
> aStates
= xStateSet
->getStates();
707 for (const sal_Int16 nState
: aStates
)
709 lcl_addState(&state
, nState
);
715 QColor
QtAccessibleWidget::foregroundColor() const
717 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
721 Reference
<XAccessibleComponent
> xAccessibleComponent(xAc
, UNO_QUERY
);
722 return toQColor(Color(ColorTransparency
, xAccessibleComponent
->getForeground()));
725 QColor
QtAccessibleWidget::backgroundColor() const
727 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
731 Reference
<XAccessibleComponent
> xAccessibleComponent(xAc
, UNO_QUERY
);
732 return toQColor(Color(ColorTransparency
, xAccessibleComponent
->getBackground()));
735 void* QtAccessibleWidget::interface_cast(QAccessible::InterfaceType t
)
737 if (t
== QAccessible::ActionInterface
)
738 return static_cast<QAccessibleActionInterface
*>(this);
739 if (t
== QAccessible::TextInterface
)
740 return static_cast<QAccessibleTextInterface
*>(this);
741 if (t
== QAccessible::EditableTextInterface
)
742 return static_cast<QAccessibleEditableTextInterface
*>(this);
743 if (t
== QAccessible::ValueInterface
)
744 return static_cast<QAccessibleValueInterface
*>(this);
745 if (t
== QAccessible::TableCellInterface
)
746 return static_cast<QAccessibleTableCellInterface
*>(this);
747 if (t
== QAccessible::TableInterface
)
748 return static_cast<QAccessibleTableInterface
*>(this);
752 bool QtAccessibleWidget::isValid() const
754 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
758 QObject
* QtAccessibleWidget::object() const { return m_pObject
; }
760 void QtAccessibleWidget::setText(QAccessible::Text
/* t */, const QString
& /* text */) {}
762 QAccessibleInterface
* QtAccessibleWidget::childAt(int x
, int y
) const
764 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
768 Reference
<XAccessibleComponent
> xAccessibleComponent(xAc
, UNO_QUERY
);
769 return QAccessible::queryAccessibleInterface(
770 new QtXAccessible(xAccessibleComponent
->getAccessibleAtPoint(awt::Point(x
, y
))));
773 QAccessibleInterface
* QtAccessibleWidget::customFactory(const QString
& classname
, QObject
* object
)
775 if (classname
== QLatin1String("QtWidget") && object
&& object
->isWidgetType())
777 QtWidget
* pWidget
= static_cast<QtWidget
*>(object
);
778 vcl::Window
* pWindow
= pWidget
->frame().GetWindow();
781 return new QtAccessibleWidget(pWindow
->GetAccessible(), object
);
783 if (classname
== QLatin1String("QtXAccessible") && object
)
785 QtXAccessible
* pXAccessible
= dynamic_cast<QtXAccessible
*>(object
);
786 if (pXAccessible
&& pXAccessible
->m_xAccessible
.is())
787 return new QtAccessibleWidget(pXAccessible
->m_xAccessible
, object
);
793 // QAccessibleActionInterface
794 QStringList
QtAccessibleWidget::actionNames() const
796 QStringList actionNames
;
797 Reference
<XAccessibleAction
> xAccessibleAction(getAccessibleContextImpl(), UNO_QUERY
);
798 if (!xAccessibleAction
.is())
801 int count
= xAccessibleAction
->getAccessibleActionCount();
802 for (int i
= 0; i
< count
; i
++)
804 OUString desc
= xAccessibleAction
->getAccessibleActionDescription(i
);
805 actionNames
.append(toQString(desc
));
810 void QtAccessibleWidget::doAction(const QString
& actionName
)
812 Reference
<XAccessibleAction
> xAccessibleAction(getAccessibleContextImpl(), UNO_QUERY
);
813 if (!xAccessibleAction
.is())
816 int index
= actionNames().indexOf(actionName
);
819 xAccessibleAction
->doAccessibleAction(index
);
822 QStringList
QtAccessibleWidget::keyBindingsForAction(const QString
& actionName
) const
824 QStringList keyBindings
;
825 Reference
<XAccessibleAction
> xAccessibleAction(getAccessibleContextImpl(), UNO_QUERY
);
826 if (!xAccessibleAction
.is())
829 int index
= actionNames().indexOf(actionName
);
833 Reference
<XAccessibleKeyBinding
> xKeyBinding
834 = xAccessibleAction
->getAccessibleActionKeyBinding(index
);
836 if (!xKeyBinding
.is())
839 int count
= xKeyBinding
->getAccessibleKeyBindingCount();
840 for (int i
= 0; i
< count
; i
++)
842 Sequence
<awt::KeyStroke
> keyStroke
= xKeyBinding
->getAccessibleKeyBinding(i
);
843 keyBindings
.append(toQString(comphelper::GetkeyBindingStrByXkeyBinding(keyStroke
)));
848 // QAccessibleTextInterface
849 void QtAccessibleWidget::addSelection(int /* startOffset */, int /* endOffset */)
851 SAL_INFO("vcl.qt", "Unsupported QAccessibleTextInterface::addSelection");
856 OUString
lcl_convertFontWeight(double fontWeight
)
858 if (fontWeight
== awt::FontWeight::THIN
|| fontWeight
== awt::FontWeight::ULTRALIGHT
)
860 if (fontWeight
== awt::FontWeight::LIGHT
)
862 if (fontWeight
== awt::FontWeight::SEMILIGHT
)
864 if (fontWeight
== awt::FontWeight::NORMAL
)
866 if (fontWeight
== awt::FontWeight::SEMIBOLD
)
868 if (fontWeight
== awt::FontWeight::BOLD
)
870 if (fontWeight
== awt::FontWeight::ULTRABOLD
)
872 if (fontWeight
== awt::FontWeight::BLACK
)
875 // awt::FontWeight::DONTKNOW || fontWeight == awt::FontWeight::NORMAL
880 QString
QtAccessibleWidget::attributes(int offset
, int* startOffset
, int* endOffset
) const
882 if (startOffset
== nullptr || endOffset
== nullptr)
888 Reference
<XAccessibleText
> xText(getAccessibleContextImpl(), UNO_QUERY
);
892 // handle special values for offset the same way base class's QAccessibleTextWidget::attributes does
893 // (as defined in IAccessible 2: -1 -> length, -2 -> cursor position)
895 offset
= cursorPosition();
897 const int nTextLength
= characterCount();
898 if (offset
== -1 || offset
== nTextLength
)
899 offset
= nTextLength
- 1;
901 if (offset
< 0 || offset
> nTextLength
)
904 const Sequence
<PropertyValue
> attribs
905 = xText
->getCharacterAttributes(offset
, Sequence
<OUString
>());
907 for (PropertyValue
const& prop
: attribs
)
911 if (prop
.Name
== "CharFontName")
913 sAttribute
= "font-family";
914 sValue
= *o3tl::doAccess
<OUString
>(prop
.Value
);
916 else if (prop
.Name
== "CharHeight")
918 sAttribute
= "font-size";
919 sValue
= OUString::number(*o3tl::doAccess
<double>(prop
.Value
)) + "pt";
921 else if (prop
.Name
== "CharWeight")
923 sAttribute
= "font-weight";
924 sValue
= lcl_convertFontWeight(*o3tl::doAccess
<double>(prop
.Value
));
927 if (!sAttribute
.isEmpty() && !sValue
.isEmpty())
928 aRet
+= sAttribute
+ ":" + sValue
+ ";";
930 *startOffset
= offset
;
931 *endOffset
= offset
+ 1;
932 return toQString(aRet
);
935 int QtAccessibleWidget::characterCount() const
937 Reference
<XAccessibleText
> xText(getAccessibleContextImpl(), UNO_QUERY
);
939 return xText
->getCharacterCount();
942 QRect
QtAccessibleWidget::characterRect(int /* offset */) const
944 SAL_INFO("vcl.qt", "Unsupported QAccessibleTextInterface::characterRect");
948 int QtAccessibleWidget::cursorPosition() const
950 Reference
<XAccessibleText
> xText(getAccessibleContextImpl(), UNO_QUERY
);
952 return xText
->getCaretPosition();
956 int QtAccessibleWidget::offsetAtPoint(const QPoint
& /* point */) const
958 SAL_INFO("vcl.qt", "Unsupported QAccessibleTextInterface::offsetAtPoint");
961 void QtAccessibleWidget::removeSelection(int /* selectionIndex */)
963 SAL_INFO("vcl.qt", "Unsupported QAccessibleTextInterface::removeSelection");
965 void QtAccessibleWidget::scrollToSubstring(int startIndex
, int endIndex
)
967 Reference
<XAccessibleText
> xText(getAccessibleContextImpl(), UNO_QUERY
);
969 xText
->scrollSubstringTo(startIndex
, endIndex
, AccessibleScrollType_SCROLL_ANYWHERE
);
972 void QtAccessibleWidget::selection(int selectionIndex
, int* startOffset
, int* endOffset
) const
974 if (!startOffset
&& !endOffset
)
977 Reference
<XAccessibleText
> xText
;
978 if (selectionIndex
== 0)
979 xText
= Reference
<XAccessibleText
>(getAccessibleContextImpl(), UNO_QUERY
);
982 *startOffset
= xText
.is() ? xText
->getSelectionStart() : 0;
984 *endOffset
= xText
.is() ? xText
->getSelectionEnd() : 0;
987 int QtAccessibleWidget::selectionCount() const
989 Reference
<XAccessibleText
> xText(getAccessibleContextImpl(), UNO_QUERY
);
990 if (xText
.is() && !xText
->getSelectedText().isEmpty())
991 return 1; // Only 1 selection supported atm
994 void QtAccessibleWidget::setCursorPosition(int position
)
996 Reference
<XAccessibleText
> xText(getAccessibleContextImpl(), UNO_QUERY
);
998 xText
->setCaretPosition(position
);
1000 void QtAccessibleWidget::setSelection(int /* selectionIndex */, int startOffset
, int endOffset
)
1002 Reference
<XAccessibleText
> xText(getAccessibleContextImpl(), UNO_QUERY
);
1004 xText
->setSelection(startOffset
, endOffset
);
1006 QString
QtAccessibleWidget::text(int startOffset
, int endOffset
) const
1008 Reference
<XAccessibleText
> xText(getAccessibleContextImpl(), UNO_QUERY
);
1010 return toQString(xText
->getTextRange(startOffset
, endOffset
));
1013 QString
QtAccessibleWidget::textAfterOffset(int /* offset */,
1014 QAccessible::TextBoundaryType
/* boundaryType */,
1015 int* /* startOffset */, int* /* endOffset */) const
1017 SAL_INFO("vcl.qt", "Unsupported QAccessibleTextInterface::textAfterOffset");
1021 QString
QtAccessibleWidget::textAtOffset(int offset
, QAccessible::TextBoundaryType boundaryType
,
1022 int* startOffset
, int* endOffset
) const
1024 if (startOffset
== nullptr || endOffset
== nullptr)
1027 if (boundaryType
== QAccessible::NoBoundary
)
1029 const int nCharCount
= characterCount();
1031 *endOffset
= nCharCount
;
1032 return text(0, nCharCount
);
1035 Reference
<XAccessibleText
> xText(getAccessibleContextImpl(), UNO_QUERY
);
1039 sal_Int16 nUnoBoundaryType
= lcl_matchQtTextBoundaryType(boundaryType
);
1040 assert(nUnoBoundaryType
> 0);
1042 const TextSegment segment
= xText
->getTextAtIndex(offset
, nUnoBoundaryType
);
1043 *startOffset
= segment
.SegmentStart
;
1044 *endOffset
= segment
.SegmentEnd
;
1045 return toQString(segment
.SegmentText
);
1048 QString
QtAccessibleWidget::textBeforeOffset(int /* offset */,
1049 QAccessible::TextBoundaryType
/* boundaryType */,
1050 int* /* startOffset */, int* /* endOffset */) const
1052 SAL_INFO("vcl.qt", "Unsupported QAccessibleTextInterface::textBeforeOffset");
1056 // QAccessibleEditableTextInterface
1058 void QtAccessibleWidget::deleteText(int startOffset
, int endOffset
)
1060 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1064 Reference
<XAccessibleEditableText
> xEditableText(xAc
, UNO_QUERY
);
1065 if (!xEditableText
.is())
1067 xEditableText
->deleteText(startOffset
, endOffset
);
1070 void QtAccessibleWidget::insertText(int offset
, const QString
& text
)
1072 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1076 Reference
<XAccessibleEditableText
> xEditableText(xAc
, UNO_QUERY
);
1077 if (!xEditableText
.is())
1079 xEditableText
->insertText(toOUString(text
), offset
);
1082 void QtAccessibleWidget::replaceText(int startOffset
, int endOffset
, const QString
& text
)
1084 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1088 Reference
<XAccessibleEditableText
> xEditableText(xAc
, UNO_QUERY
);
1089 if (!xEditableText
.is())
1091 xEditableText
->replaceText(startOffset
, endOffset
, toOUString(text
));
1094 // QAccessibleValueInterface
1095 QVariant
QtAccessibleWidget::currentValue() const
1097 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1101 Reference
<XAccessibleValue
> xValue(xAc
, UNO_QUERY
);
1105 xValue
->getCurrentValue() >>= aDouble
;
1106 return QVariant(aDouble
);
1109 QVariant
QtAccessibleWidget::maximumValue() const
1111 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1115 Reference
<XAccessibleValue
> xValue(xAc
, UNO_QUERY
);
1119 xValue
->getMaximumValue() >>= aDouble
;
1120 return QVariant(aDouble
);
1123 QVariant
QtAccessibleWidget::minimumStepSize() const
1125 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1129 Reference
<XAccessibleValue
> xValue(xAc
, UNO_QUERY
);
1132 double dMinStep
= 0;
1133 xValue
->getMinimumIncrement() >>= dMinStep
;
1134 return QVariant(dMinStep
);
1137 QVariant
QtAccessibleWidget::minimumValue() const
1139 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1143 Reference
<XAccessibleValue
> xValue(xAc
, UNO_QUERY
);
1147 xValue
->getMinimumValue() >>= aDouble
;
1148 return QVariant(aDouble
);
1151 void QtAccessibleWidget::setCurrentValue(const QVariant
& value
)
1153 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1157 Reference
<XAccessibleValue
> xValue(xAc
, UNO_QUERY
);
1160 xValue
->setCurrentValue(Any(value
.toDouble()));
1164 QAccessibleInterface
* QtAccessibleWidget::caption() const
1166 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1170 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1173 return QAccessible::queryAccessibleInterface(new QtXAccessible(xTable
->getAccessibleCaption()));
1176 QAccessibleInterface
* QtAccessibleWidget::cellAt(int row
, int column
) const
1178 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1182 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1185 return QAccessible::queryAccessibleInterface(
1186 new QtXAccessible(xTable
->getAccessibleCellAt(row
, column
)));
1189 int QtAccessibleWidget::columnCount() const
1191 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1195 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1198 return xTable
->getAccessibleColumnCount();
1201 QString
QtAccessibleWidget::columnDescription(int column
) const
1203 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1207 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1210 return toQString(xTable
->getAccessibleColumnDescription(column
));
1213 bool QtAccessibleWidget::isColumnSelected(int nColumn
) const
1215 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1219 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1223 return xTable
->isAccessibleColumnSelected(nColumn
);
1226 bool QtAccessibleWidget::isRowSelected(int nRow
) const
1228 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1232 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1236 return xTable
->isAccessibleRowSelected(nRow
);
1239 void QtAccessibleWidget::modelChange(QAccessibleTableModelChangeEvent
*) {}
1241 int QtAccessibleWidget::rowCount() const
1243 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1247 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1250 return xTable
->getAccessibleRowCount();
1253 QString
QtAccessibleWidget::rowDescription(int row
) const
1255 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1259 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1262 return toQString(xTable
->getAccessibleRowDescription(row
));
1265 bool QtAccessibleWidget::selectColumn(int column
)
1267 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1271 Reference
<XAccessibleTableSelection
> xTableSelection(xAc
, UNO_QUERY
);
1272 if (!xTableSelection
.is())
1274 return xTableSelection
->selectColumn(column
);
1277 bool QtAccessibleWidget::selectRow(int row
)
1279 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1283 Reference
<XAccessibleTableSelection
> xTableSelection(xAc
, UNO_QUERY
);
1284 if (!xTableSelection
.is())
1286 return xTableSelection
->selectRow(row
);
1289 int QtAccessibleWidget::selectedCellCount() const
1291 SAL_INFO("vcl.qt", "Unsupported QAccessibleTableInterface::selectedCellCount");
1295 QList
<QAccessibleInterface
*> QtAccessibleWidget::selectedCells() const
1297 SAL_INFO("vcl.qt", "Unsupported QAccessibleTableInterface::selectedCells");
1298 return QList
<QAccessibleInterface
*>();
1301 int QtAccessibleWidget::selectedColumnCount() const
1303 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1307 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1310 return xTable
->getSelectedAccessibleColumns().getLength();
1313 QList
<int> QtAccessibleWidget::selectedColumns() const
1315 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1317 return QList
<int>();
1319 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1321 return QList
<int>();
1322 return toQList(xTable
->getSelectedAccessibleColumns());
1325 int QtAccessibleWidget::selectedRowCount() const
1327 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1331 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1334 return xTable
->getSelectedAccessibleRows().getLength();
1337 QList
<int> QtAccessibleWidget::selectedRows() const
1339 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1341 return QList
<int>();
1343 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1345 return QList
<int>();
1346 return toQList(xTable
->getSelectedAccessibleRows());
1349 QAccessibleInterface
* QtAccessibleWidget::summary() const
1351 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1355 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1358 return QAccessible::queryAccessibleInterface(new QtXAccessible(xTable
->getAccessibleSummary()));
1361 bool QtAccessibleWidget::unselectColumn(int column
)
1363 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1367 Reference
<XAccessibleTableSelection
> xTableSelection(xAc
, UNO_QUERY
);
1368 if (!xTableSelection
.is())
1370 return xTableSelection
->unselectColumn(column
);
1373 bool QtAccessibleWidget::unselectRow(int row
)
1375 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1379 Reference
<XAccessibleTableSelection
> xTableSelection(xAc
, UNO_QUERY
);
1380 if (!xTableSelection
.is())
1382 return xTableSelection
->unselectRow(row
);
1385 QList
<QAccessibleInterface
*> QtAccessibleWidget::columnHeaderCells() const
1387 SAL_WARN("vcl.qt", "Unsupported QAccessibleTableCellInterface::columnHeaderCells");
1388 return QList
<QAccessibleInterface
*>();
1391 int QtAccessibleWidget::columnIndex() const
1393 Reference
<XAccessibleContext
> xAcc
= getAccessibleContextImpl();
1397 Reference
<XAccessibleTable
> xTable
= getAccessibleTableForParent();
1401 const sal_Int32 nIndexInParent
= xAcc
->getAccessibleIndexInParent();
1402 return xTable
->getAccessibleColumn(nIndexInParent
);
1405 bool QtAccessibleWidget::isSelected() const
1407 Reference
<XAccessibleContext
> xAcc
= getAccessibleContextImpl();
1411 Reference
<XAccessibleTable
> xTable
= getAccessibleTableForParent();
1415 const sal_Int32 nColumn
= columnIndex();
1416 const sal_Int32 nRow
= rowIndex();
1417 return xTable
->isAccessibleSelected(nRow
, nColumn
);
1420 int QtAccessibleWidget::columnExtent() const
1422 Reference
<XAccessibleContext
> xAcc
= getAccessibleContextImpl();
1426 Reference
<XAccessibleTable
> xTable
= getAccessibleTableForParent();
1430 const sal_Int32 nColumn
= columnIndex();
1431 const sal_Int32 nRow
= rowIndex();
1432 return xTable
->getAccessibleColumnExtentAt(nRow
, nColumn
);
1435 QList
<QAccessibleInterface
*> QtAccessibleWidget::rowHeaderCells() const
1437 SAL_WARN("vcl.qt", "Unsupported QAccessibleTableCellInterface::rowHeaderCells");
1438 return QList
<QAccessibleInterface
*>();
1441 int QtAccessibleWidget::rowExtent() const
1443 Reference
<XAccessibleContext
> xAcc
= getAccessibleContextImpl();
1447 Reference
<XAccessibleTable
> xTable
= getAccessibleTableForParent();
1451 const sal_Int32 nColumn
= columnIndex();
1452 const sal_Int32 nRow
= rowIndex();
1453 return xTable
->getAccessibleRowExtentAt(nRow
, nColumn
);
1456 int QtAccessibleWidget::rowIndex() const
1458 Reference
<XAccessibleContext
> xAcc
= getAccessibleContextImpl();
1462 Reference
<XAccessibleTable
> xTable
= getAccessibleTableForParent();
1466 const sal_Int32 nIndexInParent
= xAcc
->getAccessibleIndexInParent();
1467 return xTable
->getAccessibleRow(nIndexInParent
);
1470 QAccessibleInterface
* QtAccessibleWidget::table() const
1472 SAL_WARN("vcl.qt", "Unsupported QAccessibleTableCellInterface::table");
1476 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */