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/AccessibleStateType.hpp>
34 #include <com/sun/star/accessibility/XAccessible.hpp>
35 #include <com/sun/star/accessibility/XAccessibleAction.hpp>
36 #include <com/sun/star/accessibility/XAccessibleComponent.hpp>
37 #include <com/sun/star/accessibility/XAccessibleEditableText.hpp>
38 #include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp>
39 #include <com/sun/star/accessibility/XAccessibleEventListener.hpp>
40 #include <com/sun/star/accessibility/XAccessibleKeyBinding.hpp>
41 #include <com/sun/star/accessibility/XAccessibleRelationSet.hpp>
42 #include <com/sun/star/accessibility/XAccessibleStateSet.hpp>
43 #include <com/sun/star/accessibility/XAccessibleTable.hpp>
44 #include <com/sun/star/accessibility/XAccessibleTableSelection.hpp>
45 #include <com/sun/star/accessibility/XAccessibleText.hpp>
46 #include <com/sun/star/accessibility/XAccessibleValue.hpp>
47 #include <com/sun/star/awt/FontWeight.hpp>
48 #include <com/sun/star/beans/PropertyValue.hpp>
49 #include <com/sun/star/lang/DisposedException.hpp>
50 #include <com/sun/star/uno/Sequence.hxx>
52 #include <comphelper/AccessibleImplementationHelper.hxx>
53 #include <sal/log.hxx>
54 #include <vcl/popupmenuwindow.hxx>
57 using namespace css::accessibility
;
58 using namespace css::beans
;
59 using namespace css::uno
;
61 Qt5AccessibleWidget::Qt5AccessibleWidget(const Reference
<XAccessible
> xAccessible
)
62 : m_xAccessible(xAccessible
)
64 Reference
<XAccessibleContext
> xContext
= xAccessible
->getAccessibleContext();
65 Reference
<XAccessibleEventBroadcaster
> xBroadcaster(xContext
, UNO_QUERY
);
66 if (xBroadcaster
.is())
68 Reference
<XAccessibleEventListener
> xListener(
69 new Qt5AccessibleEventListener(xAccessible
, this));
70 xBroadcaster
->addAccessibleEventListener(xListener
);
74 Reference
<XAccessibleContext
> Qt5AccessibleWidget::getAccessibleContextImpl() const
76 Reference
<XAccessibleContext
> xAc
;
78 if (m_xAccessible
.is())
82 xAc
= m_xAccessible
->getAccessibleContext();
84 catch (css::lang::DisposedException
/*ex*/)
86 SAL_WARN("vcl.qt5", "Accessible context disposed already");
88 // sometimes getAccessibleContext throws also RuntimeException if context is no longer alive
89 catch (css::uno::RuntimeException
/*ex*/)
91 // so let's catch it here, cuz otherwise soffice falls flat on its face
92 // with FatalError and nothing else
93 SAL_WARN("vcl.qt5", "Accessible context no longer alive");
100 QWindow
* Qt5AccessibleWidget::window() const { return nullptr; }
102 int Qt5AccessibleWidget::childCount() const
104 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
108 return xAc
->getAccessibleChildCount();
111 int Qt5AccessibleWidget::indexOfChild(const QAccessibleInterface
* /* child */) const { return 0; }
115 QAccessible::Relation
lcl_matchUnoRelation(short relationType
)
117 switch (relationType
)
119 case AccessibleRelationType::CONTROLLER_FOR
:
120 return QAccessible::Controller
;
121 case AccessibleRelationType::CONTROLLED_BY
:
122 return QAccessible::Controlled
;
123 case AccessibleRelationType::LABEL_FOR
:
124 return QAccessible::Label
;
125 case AccessibleRelationType::LABELED_BY
:
126 return QAccessible::Labelled
;
127 case AccessibleRelationType::INVALID
:
128 case AccessibleRelationType::CONTENT_FLOWS_FROM
:
129 case AccessibleRelationType::CONTENT_FLOWS_TO
:
130 case AccessibleRelationType::MEMBER_OF
:
131 case AccessibleRelationType::SUB_WINDOW_OF
:
132 case AccessibleRelationType::NODE_CHILD_OF
:
133 case AccessibleRelationType::DESCRIBED_BY
:
135 SAL_WARN("vcl.qt5", "Unmatched relation: " << relationType
);
140 short lcl_matchQtRelation(QAccessible::Relation relationType
)
142 switch (relationType
)
144 case QAccessible::Controller
:
145 return AccessibleRelationType::CONTROLLER_FOR
;
146 case QAccessible::Controlled
:
147 return AccessibleRelationType::CONTROLLED_BY
;
148 case QAccessible::Label
:
149 return AccessibleRelationType::LABEL_FOR
;
150 case QAccessible::Labelled
:
151 return AccessibleRelationType::LABELED_BY
;
153 SAL_WARN("vcl.qt5", "Unmatched relation: " << relationType
);
158 void lcl_appendRelation(QVector
<QPair
<QAccessibleInterface
*, QAccessible::Relation
>>* relations
,
159 AccessibleRelation aRelation
)
161 QAccessible::Relation aQRelation
= lcl_matchUnoRelation(aRelation
.RelationType
);
162 sal_uInt32 nTargetCount
= aRelation
.TargetSet
.getLength();
164 for (sal_uInt32 i
= 0; i
< nTargetCount
; i
++)
166 Reference
<XAccessible
> xAccessible(aRelation
.TargetSet
[i
], uno::UNO_QUERY
);
168 { QAccessible::queryAccessibleInterface(new Qt5XAccessible(xAccessible
)), aQRelation
});
173 QVector
<QPair
<QAccessibleInterface
*, QAccessible::Relation
>>
174 Qt5AccessibleWidget::relations(QAccessible::Relation match
) const
176 QVector
<QPair
<QAccessibleInterface
*, QAccessible::Relation
>> relations
;
178 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
182 Reference
<XAccessibleRelationSet
> xRelationSet
= xAc
->getAccessibleRelationSet();
183 if (xRelationSet
.is())
185 if (match
== QAccessible::AllRelations
)
187 int count
= xRelationSet
->getRelationCount();
188 for (int i
= 0; i
< count
; i
++)
190 AccessibleRelation aRelation
= xRelationSet
->getRelation(i
);
191 lcl_appendRelation(&relations
, aRelation
);
196 AccessibleRelation aRelation
= xRelationSet
->getRelation(lcl_matchQtRelation(match
));
197 lcl_appendRelation(&relations
, aRelation
);
204 QAccessibleInterface
* Qt5AccessibleWidget::focusChild() const
206 /* if (m_pWindow->HasChildPathFocus())
207 return QAccessible::queryAccessibleInterface(
208 new Qt5XAccessible(m_xAccessible->getAccessibleContext()->getAccessibleChild(index))); */
209 return QAccessible::queryAccessibleInterface(object());
212 QRect
Qt5AccessibleWidget::rect() const
214 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
218 Reference
<XAccessibleComponent
> xAccessibleComponent(xAc
, UNO_QUERY
);
219 awt::Point aPoint
= xAccessibleComponent
->getLocation();
220 awt::Size aSize
= xAccessibleComponent
->getSize();
222 return QRect(aPoint
.X
, aPoint
.Y
, aSize
.Width
, aSize
.Height
);
225 QAccessibleInterface
* Qt5AccessibleWidget::parent() const
227 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
231 return QAccessible::queryAccessibleInterface(new Qt5XAccessible(xAc
->getAccessibleParent()));
233 QAccessibleInterface
* Qt5AccessibleWidget::child(int index
) const
235 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
239 return QAccessible::queryAccessibleInterface(
240 new Qt5XAccessible(xAc
->getAccessibleChild(index
)));
243 QString
Qt5AccessibleWidget::text(QAccessible::Text text
) const
245 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
251 case QAccessible::Name
:
252 return toQString(xAc
->getAccessibleName());
253 case QAccessible::Description
:
254 case QAccessible::DebugDescription
:
255 return toQString(xAc
->getAccessibleDescription());
256 case QAccessible::Value
:
257 case QAccessible::Help
:
258 case QAccessible::Accelerator
:
259 case QAccessible::UserText
:
261 return QString("Unknown");
264 QAccessible::Role
Qt5AccessibleWidget::role() const
266 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
268 return QAccessible::NoRole
;
270 switch (xAc
->getAccessibleRole())
272 case AccessibleRole::UNKNOWN
:
273 return QAccessible::NoRole
;
275 case AccessibleRole::ALERT
:
276 return QAccessible::AlertMessage
;
278 case AccessibleRole::COLUMN_HEADER
:
279 return QAccessible::ColumnHeader
;
281 case AccessibleRole::CANVAS
:
282 return QAccessible::Canvas
;
284 case AccessibleRole::CHECK_BOX
:
285 return QAccessible::CheckBox
;
287 case AccessibleRole::CHECK_MENU_ITEM
:
288 return QAccessible::MenuItem
;
290 case AccessibleRole::COLOR_CHOOSER
:
291 return QAccessible::ColorChooser
;
293 case AccessibleRole::COMBO_BOX
:
294 return QAccessible::ComboBox
;
296 case AccessibleRole::DATE_EDITOR
:
297 return QAccessible::EditableText
;
299 case AccessibleRole::DESKTOP_ICON
:
300 return QAccessible::Graphic
;
302 case AccessibleRole::DESKTOP_PANE
:
303 case AccessibleRole::DIRECTORY_PANE
:
304 return QAccessible::Pane
;
306 case AccessibleRole::DIALOG
:
307 return QAccessible::Dialog
;
309 case AccessibleRole::DOCUMENT
:
310 return QAccessible::Document
;
312 case AccessibleRole::EMBEDDED_OBJECT
:
313 return QAccessible::UserRole
;
315 case AccessibleRole::END_NOTE
:
316 return QAccessible::Note
;
318 case AccessibleRole::FILLER
:
319 return QAccessible::Whitespace
;
321 case AccessibleRole::FONT_CHOOSER
:
322 return QAccessible::UserRole
;
324 case AccessibleRole::FOOTER
:
325 return QAccessible::Footer
;
327 case AccessibleRole::FOOTNOTE
:
328 return QAccessible::Note
;
330 case AccessibleRole::FRAME
: // top-level window with title bar
331 return QAccessible::Window
;
333 case AccessibleRole::GLASS_PANE
:
334 return QAccessible::UserRole
;
336 case AccessibleRole::GRAPHIC
:
337 return QAccessible::Graphic
;
339 case AccessibleRole::GROUP_BOX
:
340 return QAccessible::Grouping
;
342 case AccessibleRole::HEADER
:
343 return QAccessible::UserRole
;
345 case AccessibleRole::HEADING
:
346 return QAccessible::Heading
;
348 case AccessibleRole::HYPER_LINK
:
349 return QAccessible::Link
;
351 case AccessibleRole::ICON
:
352 return QAccessible::Graphic
;
354 case AccessibleRole::INTERNAL_FRAME
:
355 return QAccessible::UserRole
;
357 case AccessibleRole::LABEL
:
358 return QAccessible::StaticText
;
360 case AccessibleRole::LAYERED_PANE
:
361 return QAccessible::Pane
;
363 case AccessibleRole::LIST
:
364 return QAccessible::List
;
366 case AccessibleRole::LIST_ITEM
:
367 return QAccessible::ListItem
;
369 case AccessibleRole::MENU
:
370 case AccessibleRole::MENU_BAR
:
371 return QAccessible::MenuBar
;
373 case AccessibleRole::MENU_ITEM
:
374 return QAccessible::MenuItem
;
376 case AccessibleRole::OPTION_PANE
:
377 return QAccessible::Pane
;
379 case AccessibleRole::PAGE_TAB
:
380 return QAccessible::PageTab
;
382 case AccessibleRole::PAGE_TAB_LIST
:
383 return QAccessible::PageTabList
;
385 case AccessibleRole::PANEL
:
386 return QAccessible::Pane
;
388 case AccessibleRole::PARAGRAPH
:
389 return QAccessible::Paragraph
;
391 case AccessibleRole::PASSWORD_TEXT
:
392 return QAccessible::EditableText
;
394 case AccessibleRole::POPUP_MENU
:
395 return QAccessible::PopupMenu
;
397 case AccessibleRole::PUSH_BUTTON
:
398 return QAccessible::Button
;
400 case AccessibleRole::PROGRESS_BAR
:
401 return QAccessible::ProgressBar
;
403 case AccessibleRole::RADIO_BUTTON
:
404 return QAccessible::RadioButton
;
406 case AccessibleRole::RADIO_MENU_ITEM
:
407 return QAccessible::MenuItem
;
409 case AccessibleRole::ROW_HEADER
:
410 return QAccessible::RowHeader
;
412 case AccessibleRole::ROOT_PANE
:
413 return QAccessible::Pane
;
415 case AccessibleRole::SCROLL_BAR
:
416 return QAccessible::ScrollBar
;
418 case AccessibleRole::SCROLL_PANE
:
419 return QAccessible::Pane
;
421 case AccessibleRole::SHAPE
:
422 return QAccessible::Graphic
;
424 case AccessibleRole::SEPARATOR
:
425 return QAccessible::Separator
;
427 case AccessibleRole::SLIDER
:
428 return QAccessible::Slider
;
430 case AccessibleRole::SPIN_BOX
:
431 return QAccessible::SpinBox
;
433 case AccessibleRole::SPLIT_PANE
:
434 return QAccessible::Pane
;
436 case AccessibleRole::STATUS_BAR
:
437 return QAccessible::StatusBar
;
439 case AccessibleRole::TABLE
:
440 return QAccessible::Table
;
442 case AccessibleRole::TABLE_CELL
:
443 return QAccessible::Cell
;
445 case AccessibleRole::TEXT
:
446 return QAccessible::EditableText
;
448 case AccessibleRole::TEXT_FRAME
:
449 return QAccessible::UserRole
;
451 case AccessibleRole::TOGGLE_BUTTON
:
452 return QAccessible::Button
;
454 case AccessibleRole::TOOL_BAR
:
455 return QAccessible::ToolBar
;
457 case AccessibleRole::TOOL_TIP
:
458 return QAccessible::ToolTip
;
460 case AccessibleRole::TREE
:
461 return QAccessible::Tree
;
463 case AccessibleRole::VIEW_PORT
:
464 return QAccessible::UserRole
;
466 case AccessibleRole::BUTTON_DROPDOWN
:
467 return QAccessible::Button
;
469 case AccessibleRole::BUTTON_MENU
:
470 return QAccessible::Button
;
472 case AccessibleRole::CAPTION
:
473 return QAccessible::StaticText
;
475 case AccessibleRole::CHART
:
476 return QAccessible::Chart
;
478 case AccessibleRole::EDIT_BAR
:
479 return QAccessible::Equation
;
481 case AccessibleRole::FORM
:
482 return QAccessible::Form
;
484 case AccessibleRole::IMAGE_MAP
:
485 return QAccessible::Graphic
;
487 case AccessibleRole::NOTE
:
488 return QAccessible::Note
;
490 case AccessibleRole::RULER
:
491 return QAccessible::UserRole
;
493 case AccessibleRole::SECTION
:
494 return QAccessible::Section
;
496 case AccessibleRole::TREE_ITEM
:
497 return QAccessible::TreeItem
;
499 case AccessibleRole::TREE_TABLE
:
500 return QAccessible::Tree
;
502 case AccessibleRole::COMMENT
:
503 return QAccessible::Note
;
505 case AccessibleRole::COMMENT_END
:
506 return QAccessible::UserRole
;
508 case AccessibleRole::DOCUMENT_PRESENTATION
:
509 return QAccessible::Document
;
511 case AccessibleRole::DOCUMENT_SPREADSHEET
:
512 return QAccessible::Document
;
514 case AccessibleRole::DOCUMENT_TEXT
:
515 return QAccessible::Document
;
517 case AccessibleRole::STATIC
:
518 return QAccessible::StaticText
;
520 /* Ignore window objects for sub-menus, combo- and list boxes,
521 * which are exposed as children of their parents.
523 case AccessibleRole::WINDOW
: // top-level window without title bar
525 return QAccessible::Window
;
530 "Unmapped role: " << m_xAccessible
->getAccessibleContext()->getAccessibleRole());
531 return QAccessible::NoRole
;
536 void lcl_addState(QAccessible::State
* state
, sal_Int16 nState
)
540 case AccessibleStateType::INVALID
:
541 state
->invalid
= true;
543 case AccessibleStateType::ACTIVE
:
544 state
->active
= true;
546 case AccessibleStateType::ARMED
:
549 case AccessibleStateType::BUSY
:
552 case AccessibleStateType::CHECKED
:
553 state
->checked
= true;
555 case AccessibleStateType::EDITABLE
:
556 state
->editable
= true;
558 case AccessibleStateType::ENABLED
:
559 state
->disabled
= false;
561 case AccessibleStateType::EXPANDABLE
:
562 state
->expandable
= true;
564 case AccessibleStateType::FOCUSABLE
:
565 state
->focusable
= true;
567 case AccessibleStateType::FOCUSED
:
568 state
->focused
= true;
570 case AccessibleStateType::HORIZONTAL
:
573 case AccessibleStateType::ICONIFIED
:
576 case AccessibleStateType::INDETERMINATE
:
579 case AccessibleStateType::MANAGES_DESCENDANTS
:
582 case AccessibleStateType::MODAL
:
585 case AccessibleStateType::OPAQUE
:
588 case AccessibleStateType::PRESSED
:
589 state
->pressed
= true;
591 case AccessibleStateType::RESIZABLE
:
592 state
->sizeable
= true;
594 case AccessibleStateType::SELECTABLE
:
595 state
->selectable
= true;
597 case AccessibleStateType::SELECTED
:
598 state
->selected
= true;
600 case AccessibleStateType::SENSITIVE
:
603 case AccessibleStateType::SHOWING
:
606 case AccessibleStateType::SINGLE_LINE
:
609 case AccessibleStateType::STALE
:
612 case AccessibleStateType::TRANSIENT
:
615 case AccessibleStateType::VERTICAL
:
618 case AccessibleStateType::VISIBLE
:
619 state
->invisible
= false;
621 case AccessibleStateType::DEFAULT
:
624 case AccessibleStateType::DEFUNC
:
625 state
->invalid
= true;
627 case AccessibleStateType::MULTI_SELECTABLE
:
628 state
->multiSelectable
= true;
631 SAL_WARN("vcl.qt5", "Unmapped state: " << nState
);
637 QAccessible::State
Qt5AccessibleWidget::state() const
639 QAccessible::State state
;
641 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
645 Reference
<XAccessibleStateSet
> xStateSet(xAc
->getAccessibleStateSet());
650 Sequence
<sal_Int16
> aStates
= xStateSet
->getStates();
652 for (sal_Int32 n
= 0; n
< aStates
.getLength(); n
++)
654 lcl_addState(&state
, n
);
660 QColor
Qt5AccessibleWidget::foregroundColor() const
662 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
666 Reference
<XAccessibleComponent
> xAccessibleComponent(xAc
, UNO_QUERY
);
667 return toQColor(xAccessibleComponent
->getForeground());
670 QColor
Qt5AccessibleWidget::backgroundColor() const
672 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
676 Reference
<XAccessibleComponent
> xAccessibleComponent(xAc
, UNO_QUERY
);
677 return toQColor(xAccessibleComponent
->getBackground());
680 void* Qt5AccessibleWidget::interface_cast(QAccessible::InterfaceType t
)
682 if (t
== QAccessible::ActionInterface
)
683 return static_cast<QAccessibleActionInterface
*>(this);
684 if (t
== QAccessible::TextInterface
)
685 return static_cast<QAccessibleTextInterface
*>(this);
686 if (t
== QAccessible::EditableTextInterface
)
687 return static_cast<QAccessibleEditableTextInterface
*>(this);
688 if (t
== QAccessible::ValueInterface
)
689 return static_cast<QAccessibleValueInterface
*>(this);
690 if (t
== QAccessible::TableInterface
)
691 return static_cast<QAccessibleTableInterface
*>(this);
695 bool Qt5AccessibleWidget::isValid() const
697 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
701 QObject
* Qt5AccessibleWidget::object() const { return nullptr; }
703 void Qt5AccessibleWidget::setText(QAccessible::Text
/* t */, const QString
& /* text */) {}
705 QAccessibleInterface
* Qt5AccessibleWidget::childAt(int x
, int y
) const
707 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
711 Reference
<XAccessibleComponent
> xAccessibleComponent(xAc
, UNO_QUERY
);
712 return QAccessible::queryAccessibleInterface(
713 new Qt5XAccessible(xAccessibleComponent
->getAccessibleAtPoint(awt::Point(x
, y
))));
716 QAccessibleInterface
* Qt5AccessibleWidget::customFactory(const QString
& classname
, QObject
* object
)
718 if (classname
== QLatin1String("Qt5Widget") && object
&& object
->isWidgetType())
720 Qt5Widget
* pWidget
= static_cast<Qt5Widget
*>(object
);
721 vcl::Window
* pWindow
= pWidget
->frame().GetWindow();
724 return new Qt5AccessibleWidget(pWindow
->GetAccessible());
726 if (classname
== QLatin1String("Qt5XAccessible") && object
)
728 Qt5XAccessible
* pXAccessible
= dynamic_cast<Qt5XAccessible
*>(object
);
729 if (pXAccessible
&& pXAccessible
->m_xAccessible
.is())
730 return new Qt5AccessibleWidget(pXAccessible
->m_xAccessible
);
736 // QAccessibleActionInterface
737 QStringList
Qt5AccessibleWidget::actionNames() const
739 QStringList actionNames
;
740 Reference
<XAccessibleAction
> xAccessibleAction(m_xAccessible
, UNO_QUERY
);
741 if (!xAccessibleAction
.is())
744 int count
= xAccessibleAction
->getAccessibleActionCount();
745 for (int i
= 0; i
< count
; i
++)
747 OUString desc
= xAccessibleAction
->getAccessibleActionDescription(i
);
748 actionNames
.append(toQString(desc
));
753 void Qt5AccessibleWidget::doAction(const QString
& actionName
)
755 Reference
<XAccessibleAction
> xAccessibleAction(m_xAccessible
, UNO_QUERY
);
756 if (!xAccessibleAction
.is())
759 int index
= actionNames().indexOf(actionName
);
762 xAccessibleAction
->doAccessibleAction(index
);
765 QStringList
Qt5AccessibleWidget::keyBindingsForAction(const QString
& actionName
) const
767 QStringList keyBindings
;
768 Reference
<XAccessibleAction
> xAccessibleAction(m_xAccessible
, UNO_QUERY
);
769 if (!xAccessibleAction
.is())
772 int index
= actionNames().indexOf(actionName
);
776 Reference
<XAccessibleKeyBinding
> xKeyBinding
777 = xAccessibleAction
->getAccessibleActionKeyBinding(index
);
779 if (!xKeyBinding
.is())
782 int count
= xKeyBinding
->getAccessibleKeyBindingCount();
783 for (int i
= 0; i
< count
; i
++)
785 Sequence
<awt::KeyStroke
> keyStroke
= xKeyBinding
->getAccessibleKeyBinding(i
);
786 keyBindings
.append(toQString(comphelper::GetkeyBindingStrByXkeyBinding(keyStroke
)));
791 QAccessibleValueInterface
* Qt5AccessibleWidget::valueInterface() { return nullptr; }
793 QAccessibleTextInterface
* Qt5AccessibleWidget::textInterface() { return nullptr; }
795 // QAccessibleTextInterface
796 void Qt5AccessibleWidget::addSelection(int /* startOffset */, int /* endOffset */)
798 SAL_INFO("vcl.qt5", "Unsupported QAccessibleTextInterface::addSelection");
803 OUString
lcl_convertFontWeight(double fontWeight
)
805 if (fontWeight
== awt::FontWeight::THIN
|| fontWeight
== awt::FontWeight::ULTRALIGHT
)
807 if (fontWeight
== awt::FontWeight::LIGHT
)
809 if (fontWeight
== awt::FontWeight::SEMILIGHT
)
811 if (fontWeight
== awt::FontWeight::NORMAL
)
813 if (fontWeight
== awt::FontWeight::SEMIBOLD
)
815 if (fontWeight
== awt::FontWeight::BOLD
)
817 if (fontWeight
== awt::FontWeight::ULTRABOLD
)
819 if (fontWeight
== awt::FontWeight::BLACK
)
822 // awt::FontWeight::DONTKNOW || fontWeight == awt::FontWeight::NORMAL
827 QString
Qt5AccessibleWidget::attributes(int offset
, int* startOffset
, int* endOffset
) const
829 Reference
<XAccessibleText
> xText(m_xAccessible
, UNO_QUERY
);
833 // handle special values for offset the same way base class's QAccessibleTextWidget::attributes does
834 // (as defined in IAccessible 2: -1 -> length, -2 -> cursor position)
836 offset
= cursorPosition(); // currently always returns 0
838 const int nTextLength
= characterCount();
839 if (offset
== -1 || offset
== nTextLength
)
840 offset
= nTextLength
- 1;
842 if (offset
< 0 || offset
> nTextLength
)
849 Sequence
<PropertyValue
> attribs
= xText
->getCharacterAttributes(offset
, Sequence
<OUString
>());
850 const PropertyValue
* pValues
= attribs
.getConstArray();
852 for (sal_Int32 i
= 0; i
< attribs
.getLength(); i
++)
854 if (pValues
[i
].Name
== "CharFontName")
857 pValues
[i
].Value
>>= aStr
;
858 aRet
+= "font-family:" + aStr
+ ";";
861 if (pValues
[i
].Name
== "CharHeight")
864 pValues
[i
].Value
>>= fHeight
;
865 aRet
+= "font-size:" + OUString::number(fHeight
) + "pt;";
868 if (pValues
[i
].Name
== "CharWeight")
871 pValues
[i
].Value
>>= fWeight
;
872 aRet
+= "font-weight:" + lcl_convertFontWeight(fWeight
) + ";";
876 *startOffset
= offset
;
877 *endOffset
= offset
+ 1;
878 return toQString(aRet
);
880 int Qt5AccessibleWidget::characterCount() const
882 Reference
<XAccessibleText
> xText(m_xAccessible
, UNO_QUERY
);
884 return xText
->getCharacterCount();
887 QRect
Qt5AccessibleWidget::characterRect(int /* offset */) const
889 SAL_INFO("vcl.qt5", "Unsupported QAccessibleTextInterface::characterRect");
892 int Qt5AccessibleWidget::cursorPosition() const
894 SAL_INFO("vcl.qt5", "Unsupported QAccessibleTextInterface::cursorPosition");
897 int Qt5AccessibleWidget::offsetAtPoint(const QPoint
& /* point */) const
899 SAL_INFO("vcl.qt5", "Unsupported QAccessibleTextInterface::offsetAtPoint");
902 void Qt5AccessibleWidget::removeSelection(int /* selectionIndex */)
904 SAL_INFO("vcl.qt5", "Unsupported QAccessibleTextInterface::removeSelection");
906 void Qt5AccessibleWidget::scrollToSubstring(int /* startIndex */, int /* endIndex */)
908 SAL_INFO("vcl.qt5", "Unsupported QAccessibleTextInterface::scrollToSubstring");
911 void Qt5AccessibleWidget::selection(int selectionIndex
, int* startOffset
, int* endOffset
) const
913 if (!startOffset
&& !endOffset
)
916 Reference
<XAccessibleText
> xText
;
917 if (selectionIndex
== 0)
918 xText
= Reference
<XAccessibleText
>(m_xAccessible
, UNO_QUERY
);
921 *startOffset
= xText
.is() ? xText
->getSelectionStart() : 0;
923 *endOffset
= xText
.is() ? xText
->getSelectionEnd() : 0;
926 int Qt5AccessibleWidget::selectionCount() const
928 Reference
<XAccessibleText
> xText(m_xAccessible
, UNO_QUERY
);
929 if (xText
.is() && !xText
->getSelectedText().isEmpty())
930 return 1; // Only 1 selection supported atm
933 void Qt5AccessibleWidget::setCursorPosition(int position
)
935 Reference
<XAccessibleText
> xText(m_xAccessible
, UNO_QUERY
);
937 xText
->setCaretPosition(position
);
939 void Qt5AccessibleWidget::setSelection(int /* selectionIndex */, int startOffset
, int endOffset
)
941 Reference
<XAccessibleText
> xText(m_xAccessible
, UNO_QUERY
);
943 xText
->setSelection(startOffset
, endOffset
);
945 QString
Qt5AccessibleWidget::text(int startOffset
, int endOffset
) const
947 Reference
<XAccessibleText
> xText(m_xAccessible
, UNO_QUERY
);
949 return toQString(xText
->getTextRange(startOffset
, endOffset
));
952 QString
Qt5AccessibleWidget::textAfterOffset(int /* offset */,
953 QAccessible::TextBoundaryType
/* boundaryType */,
954 int* /* startOffset */, int* /* endOffset */) const
956 SAL_INFO("vcl.qt5", "Unsupported QAccessibleTextInterface::textAfterOffset");
959 QString
Qt5AccessibleWidget::textAtOffset(int /* offset */,
960 QAccessible::TextBoundaryType
/* boundaryType */,
961 int* /* startOffset */, int* /* endOffset */) const
963 SAL_INFO("vcl.qt5", "Unsupported QAccessibleTextInterface::textAtOffset");
966 QString
Qt5AccessibleWidget::textBeforeOffset(int /* offset */,
967 QAccessible::TextBoundaryType
/* boundaryType */,
968 int* /* startOffset */, int* /* endOffset */) const
970 SAL_INFO("vcl.qt5", "Unsupported QAccessibleTextInterface::textBeforeOffset");
974 // QAccessibleEditableTextInterface
976 void Qt5AccessibleWidget::deleteText(int startOffset
, int endOffset
)
978 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
982 Reference
<XAccessibleEditableText
> xEditableText(xAc
, UNO_QUERY
);
983 if (!xEditableText
.is())
985 xEditableText
->deleteText(startOffset
, endOffset
);
988 void Qt5AccessibleWidget::insertText(int offset
, const QString
& text
)
990 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
994 Reference
<XAccessibleEditableText
> xEditableText(xAc
, UNO_QUERY
);
995 if (!xEditableText
.is())
997 xEditableText
->insertText(toOUString(text
), offset
);
1000 void Qt5AccessibleWidget::replaceText(int startOffset
, int endOffset
, const QString
& text
)
1002 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1006 Reference
<XAccessibleEditableText
> xEditableText(xAc
, UNO_QUERY
);
1007 if (!xEditableText
.is())
1009 xEditableText
->replaceText(startOffset
, endOffset
, toOUString(text
));
1012 // QAccessibleValueInterface
1013 QVariant
Qt5AccessibleWidget::currentValue() const
1015 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1019 Reference
<XAccessibleValue
> xValue(xAc
, UNO_QUERY
);
1023 xValue
->getCurrentValue() >>= aDouble
;
1024 return QVariant(aDouble
);
1026 QVariant
Qt5AccessibleWidget::maximumValue() const
1028 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1032 Reference
<XAccessibleValue
> xValue(xAc
, UNO_QUERY
);
1036 xValue
->getMaximumValue() >>= aDouble
;
1037 return QVariant(aDouble
);
1039 QVariant
Qt5AccessibleWidget::minimumStepSize() const { return QVariant(); }
1040 QVariant
Qt5AccessibleWidget::minimumValue() const
1042 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1046 Reference
<XAccessibleValue
> xValue(xAc
, UNO_QUERY
);
1050 xValue
->getMinimumValue() >>= aDouble
;
1051 return QVariant(aDouble
);
1053 void Qt5AccessibleWidget::setCurrentValue(const QVariant
& value
)
1055 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1059 Reference
<XAccessibleValue
> xValue(xAc
, UNO_QUERY
);
1062 xValue
->setCurrentValue(Any(value
.toDouble()));
1066 QAccessibleInterface
* Qt5AccessibleWidget::caption() const
1068 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1072 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1075 return QAccessible::queryAccessibleInterface(
1076 new Qt5XAccessible(xTable
->getAccessibleCaption()));
1079 QAccessibleInterface
* Qt5AccessibleWidget::cellAt(int row
, int column
) const
1081 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1085 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1088 return QAccessible::queryAccessibleInterface(
1089 new Qt5XAccessible(xTable
->getAccessibleCellAt(row
, column
)));
1092 int Qt5AccessibleWidget::columnCount() const
1094 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1098 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1101 return xTable
->getAccessibleColumnCount();
1104 QString
Qt5AccessibleWidget::columnDescription(int column
) const
1106 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1110 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1113 return toQString(xTable
->getAccessibleColumnDescription(column
));
1116 bool Qt5AccessibleWidget::isColumnSelected(int /* column */) const { return true; }
1118 bool Qt5AccessibleWidget::isRowSelected(int /* row */) const { return true; }
1120 void Qt5AccessibleWidget::modelChange(QAccessibleTableModelChangeEvent
*) {}
1122 int Qt5AccessibleWidget::rowCount() const
1124 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1128 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1131 return xTable
->getAccessibleRowCount();
1134 QString
Qt5AccessibleWidget::rowDescription(int row
) const
1136 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1140 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1143 return toQString(xTable
->getAccessibleRowDescription(row
));
1146 bool Qt5AccessibleWidget::selectColumn(int column
)
1148 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1152 Reference
<XAccessibleTableSelection
> xTableSelection(xAc
, UNO_QUERY
);
1153 if (!xTableSelection
.is())
1155 return xTableSelection
->selectColumn(column
);
1158 bool Qt5AccessibleWidget::selectRow(int row
)
1160 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1164 Reference
<XAccessibleTableSelection
> xTableSelection(xAc
, UNO_QUERY
);
1165 if (!xTableSelection
.is())
1167 return xTableSelection
->selectRow(row
);
1170 int Qt5AccessibleWidget::selectedCellCount() const
1172 SAL_INFO("vcl.qt5", "Unsupported QAccessibleTableInterface::selectedCellCount");
1176 QList
<QAccessibleInterface
*> Qt5AccessibleWidget::selectedCells() const
1178 SAL_INFO("vcl.qt5", "Unsupported QAccessibleTableInterface::selectedCells");
1179 return QList
<QAccessibleInterface
*>();
1182 int Qt5AccessibleWidget::selectedColumnCount() const
1184 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1188 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1191 return xTable
->getSelectedAccessibleColumns().getLength();
1194 QList
<int> Qt5AccessibleWidget::selectedColumns() const
1196 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1198 return QList
<int>();
1200 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1202 return QList
<int>();
1203 return toQList(xTable
->getSelectedAccessibleColumns());
1206 int Qt5AccessibleWidget::selectedRowCount() const
1208 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1212 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1215 return xTable
->getSelectedAccessibleRows().getLength();
1218 QList
<int> Qt5AccessibleWidget::selectedRows() const
1220 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1222 return QList
<int>();
1224 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1226 return QList
<int>();
1227 return toQList(xTable
->getSelectedAccessibleRows());
1230 QAccessibleInterface
* Qt5AccessibleWidget::summary() const
1232 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1236 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1239 return QAccessible::queryAccessibleInterface(
1240 new Qt5XAccessible(xTable
->getAccessibleSummary()));
1243 bool Qt5AccessibleWidget::unselectColumn(int column
)
1245 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1249 Reference
<XAccessibleTableSelection
> xTableSelection(xAc
, UNO_QUERY
);
1250 if (!xTableSelection
.is())
1252 return xTableSelection
->unselectColumn(column
);
1255 bool Qt5AccessibleWidget::unselectRow(int row
)
1257 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1261 Reference
<XAccessibleTableSelection
> xTableSelection(xAc
, UNO_QUERY
);
1262 if (!xTableSelection
.is())
1264 return xTableSelection
->unselectRow(row
);
1267 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */