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>
22 #include <QtGui/QAccessibleInterface>
24 #include <QtAccessibleEventListener.hxx>
25 #include <QtAccessibleRegistry.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/XAccessibleSelection.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/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>
56 #include <vcl/accessibility/AccessibleTextAttributeHelper.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(new QtAccessibleEventListener(this));
72 xBroadcaster
->addAccessibleEventListener(xListener
);
76 void QtAccessibleWidget::invalidate()
78 QtAccessibleRegistry::remove(m_xAccessible
);
79 m_xAccessible
.clear();
82 Reference
<XAccessibleContext
> QtAccessibleWidget::getAccessibleContextImpl() const
84 Reference
<XAccessibleContext
> xAc
;
86 if (m_xAccessible
.is())
90 xAc
= m_xAccessible
->getAccessibleContext();
92 catch (css::lang::DisposedException
/*ex*/)
94 SAL_WARN("vcl.qt", "Accessible context disposed already");
96 // sometimes getAccessibleContext throws also RuntimeException if context is no longer alive
97 catch (css::uno::RuntimeException
/*ex*/)
99 // so let's catch it here, cuz otherwise soffice falls flat on its face
100 // with FatalError and nothing else
101 SAL_WARN("vcl.qt", "Accessible context no longer alive");
108 css::uno::Reference
<css::accessibility::XAccessibleTable
>
109 QtAccessibleWidget::getAccessibleTableForParent() const
111 Reference
<XAccessibleContext
> xAcc
= getAccessibleContextImpl();
115 Reference
<XAccessible
> xParent
= xAcc
->getAccessibleParent();
119 Reference
<XAccessibleContext
> xParentContext
= xParent
->getAccessibleContext();
120 if (!xParentContext
.is())
123 return Reference
<XAccessibleTable
>(xParentContext
, UNO_QUERY
);
126 QWindow
* QtAccessibleWidget::window() const
129 if (m_pObject
->isWidgetType())
131 QWidget
* pWidget
= static_cast<QWidget
*>(m_pObject
);
132 QWidget
* pWindow
= pWidget
->window();
134 return pWindow
->windowHandle();
137 QAccessibleInterface
* pParent
= parent();
139 return pParent
->window();
144 int QtAccessibleWidget::childCount() const
146 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
150 sal_Int64 nChildCount
= xAc
->getAccessibleChildCount();
151 if (nChildCount
> std::numeric_limits
<int>::max())
153 SAL_WARN("vcl.qt", "QtAccessibleWidget::childCount: Child count exceeds maximum int value, "
154 "returning max int.");
155 nChildCount
= std::numeric_limits
<int>::max();
161 int QtAccessibleWidget::indexOfChild(const QAccessibleInterface
* pChild
) const
163 const QtAccessibleWidget
* pAccessibleWidget
= dynamic_cast<const QtAccessibleWidget
*>(pChild
);
164 if (!pAccessibleWidget
)
168 "QtAccessibleWidget::indexOfChild called with child that is no QtAccessibleWidget");
172 Reference
<XAccessibleContext
> xContext
= pAccessibleWidget
->getAccessibleContextImpl();
176 sal_Int64 nChildIndex
= xContext
->getAccessibleIndexInParent();
177 if (nChildIndex
> std::numeric_limits
<int>::max())
179 // use -2 when the child index is too large to fit into 32 bit to neither use the
180 // valid index of another child nor -1, which would e.g. make the Orca screen reader
181 // interpret the object as being a zombie
183 "QtAccessibleWidget::indexOfChild: Child index exceeds maximum int value, "
192 sal_Int16
lcl_matchQtTextBoundaryType(QAccessible::TextBoundaryType boundaryType
)
194 switch (boundaryType
)
196 case QAccessible::CharBoundary
:
197 return com::sun::star::accessibility::AccessibleTextType::CHARACTER
;
198 case QAccessible::WordBoundary
:
199 return com::sun::star::accessibility::AccessibleTextType::WORD
;
200 case QAccessible::SentenceBoundary
:
201 return com::sun::star::accessibility::AccessibleTextType::SENTENCE
;
202 case QAccessible::ParagraphBoundary
:
203 return com::sun::star::accessibility::AccessibleTextType::PARAGRAPH
;
204 case QAccessible::LineBoundary
:
205 return com::sun::star::accessibility::AccessibleTextType::LINE
;
206 case QAccessible::NoBoundary
:
207 // assert here, better handle it directly at call site
209 && "No match for QAccessible::NoBoundary, handle it separately at call site.");
215 SAL_WARN("vcl.qt", "Unmatched text boundary type: " << boundaryType
);
219 QAccessible::Relation
lcl_matchUnoRelation(short relationType
)
221 // Qt semantics is the other way around
222 switch (relationType
)
224 #if QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)
225 case AccessibleRelationType::CONTENT_FLOWS_FROM
:
226 return QAccessible::FlowsTo
;
227 case AccessibleRelationType::CONTENT_FLOWS_TO
:
228 return QAccessible::FlowsFrom
;
230 case AccessibleRelationType::CONTROLLED_BY
:
231 return QAccessible::Controller
;
232 case AccessibleRelationType::CONTROLLER_FOR
:
233 return QAccessible::Controlled
;
234 #if QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)
235 case AccessibleRelationType::DESCRIBED_BY
:
236 return QAccessible::DescriptionFor
;
238 case AccessibleRelationType::LABELED_BY
:
239 return QAccessible::Label
;
240 case AccessibleRelationType::LABEL_FOR
:
241 return QAccessible::Labelled
;
242 case AccessibleRelationType::INVALID
:
243 case AccessibleRelationType::MEMBER_OF
:
244 case AccessibleRelationType::SUB_WINDOW_OF
:
245 case AccessibleRelationType::NODE_CHILD_OF
:
247 SAL_WARN("vcl.qt", "Unmatched relation: " << relationType
);
252 void lcl_appendRelation(QVector
<QPair
<QAccessibleInterface
*, QAccessible::Relation
>>* relations
,
253 AccessibleRelation aRelation
, QAccessible::Relation match
)
255 QAccessible::Relation aQRelation
= lcl_matchUnoRelation(aRelation
.RelationType
);
256 // skip in case there's no Qt relation matching the filter
257 if (!(aQRelation
& match
))
260 sal_uInt32 nTargetCount
= aRelation
.TargetSet
.getLength();
262 for (sal_uInt32 i
= 0; i
< nTargetCount
; i
++)
264 Reference
<XAccessible
> xAccessible(aRelation
.TargetSet
[i
], uno::UNO_QUERY
);
266 { QAccessible::queryAccessibleInterface(QtAccessibleRegistry::getQObject(xAccessible
)),
272 QVector
<QPair
<QAccessibleInterface
*, QAccessible::Relation
>>
273 QtAccessibleWidget::relations(QAccessible::Relation match
) const
275 QVector
<QPair
<QAccessibleInterface
*, QAccessible::Relation
>> relations
;
277 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
281 Reference
<XAccessibleRelationSet
> xRelationSet
= xAc
->getAccessibleRelationSet();
282 if (xRelationSet
.is())
284 int count
= xRelationSet
->getRelationCount();
285 for (int i
= 0; i
< count
; i
++)
287 AccessibleRelation aRelation
= xRelationSet
->getRelation(i
);
288 lcl_appendRelation(&relations
, aRelation
, match
);
295 QAccessibleInterface
* QtAccessibleWidget::focusChild() const
297 /* if (m_pWindow->HasChildPathFocus())
298 return QAccessible::queryAccessibleInterface(
299 new QtXAccessible(m_xAccessible->getAccessibleContext()->getAccessibleChild(index))); */
300 return QAccessible::queryAccessibleInterface(object());
303 QRect
QtAccessibleWidget::rect() const
305 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
309 Reference
<XAccessibleComponent
> xAccessibleComponent(xAc
, UNO_QUERY
);
310 awt::Point aPoint
= xAccessibleComponent
->getLocationOnScreen();
311 awt::Size aSize
= xAccessibleComponent
->getSize();
313 return QRect(aPoint
.X
, aPoint
.Y
, aSize
.Width
, aSize
.Height
);
316 QAccessibleInterface
* QtAccessibleWidget::parent() const
318 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
322 if (xAc
->getAccessibleParent().is())
323 return QAccessible::queryAccessibleInterface(
324 QtAccessibleRegistry::getQObject(xAc
->getAccessibleParent()));
326 // go via the QObject hierarchy; some a11y objects like the application
327 // (at the root of the a11y hierarchy) are handled solely by Qt and have
328 // no LO-internal a11y objects associated with them
329 QObject
* pObj
= object();
330 if (pObj
&& pObj
->parent())
331 return QAccessible::queryAccessibleInterface(pObj
->parent());
333 // return app as parent for top-level objects
334 return QAccessible::queryAccessibleInterface(qApp
);
337 QAccessibleInterface
* QtAccessibleWidget::child(int index
) const
339 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
343 if (index
< 0 || index
>= xAc
->getAccessibleChildCount())
345 SAL_WARN("vcl.qt", "QtAccessibleWidget::child called with invalid index: " << index
);
349 return QAccessible::queryAccessibleInterface(
350 QtAccessibleRegistry::getQObject(xAc
->getAccessibleChild(index
)));
353 QString
QtAccessibleWidget::text(QAccessible::Text text
) const
355 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
361 case QAccessible::Name
:
362 return toQString(xAc
->getAccessibleName());
363 case QAccessible::Description
:
364 case QAccessible::DebugDescription
:
365 return toQString(xAc
->getAccessibleDescription());
366 case QAccessible::Value
:
367 case QAccessible::Help
:
368 case QAccessible::Accelerator
:
369 case QAccessible::UserText
:
371 return QString("Unknown");
374 QAccessible::Role
QtAccessibleWidget::role() const
376 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
378 return QAccessible::NoRole
;
380 switch (xAc
->getAccessibleRole())
382 case AccessibleRole::UNKNOWN
:
383 return QAccessible::NoRole
;
384 case AccessibleRole::ALERT
:
385 return QAccessible::AlertMessage
;
386 case AccessibleRole::COLUMN_HEADER
:
387 return QAccessible::ColumnHeader
;
388 case AccessibleRole::CANVAS
:
389 return QAccessible::Canvas
;
390 case AccessibleRole::CHECK_BOX
:
391 return QAccessible::CheckBox
;
392 case AccessibleRole::CHECK_MENU_ITEM
:
393 return QAccessible::MenuItem
;
394 case AccessibleRole::COLOR_CHOOSER
:
395 return QAccessible::ColorChooser
;
396 case AccessibleRole::COMBO_BOX
:
397 return QAccessible::ComboBox
;
398 case AccessibleRole::DATE_EDITOR
:
399 return QAccessible::EditableText
;
400 case AccessibleRole::DESKTOP_ICON
:
401 return QAccessible::Graphic
;
402 case AccessibleRole::DESKTOP_PANE
:
403 case AccessibleRole::DIRECTORY_PANE
:
404 return QAccessible::Pane
;
405 case AccessibleRole::DIALOG
:
406 return QAccessible::Dialog
;
407 case AccessibleRole::DOCUMENT
:
408 return QAccessible::Document
;
409 case AccessibleRole::EMBEDDED_OBJECT
:
410 return QAccessible::UserRole
;
411 case AccessibleRole::END_NOTE
:
412 return QAccessible::Note
;
413 case AccessibleRole::FILE_CHOOSER
:
414 return QAccessible::Dialog
;
415 case AccessibleRole::FILLER
:
416 return QAccessible::Whitespace
;
417 case AccessibleRole::FONT_CHOOSER
:
418 return QAccessible::UserRole
;
419 case AccessibleRole::FOOTER
:
420 return QAccessible::Footer
;
421 case AccessibleRole::FOOTNOTE
:
422 return QAccessible::Note
;
423 case AccessibleRole::FRAME
: // top-level window with title bar
424 return QAccessible::Window
;
425 case AccessibleRole::GLASS_PANE
:
426 return QAccessible::UserRole
;
427 case AccessibleRole::GRAPHIC
:
428 return QAccessible::Graphic
;
429 case AccessibleRole::GROUP_BOX
:
430 return QAccessible::Grouping
;
431 case AccessibleRole::HEADER
:
432 return QAccessible::UserRole
;
433 case AccessibleRole::HEADING
:
434 return QAccessible::Heading
;
435 case AccessibleRole::HYPER_LINK
:
436 return QAccessible::Link
;
437 case AccessibleRole::ICON
:
438 return QAccessible::Graphic
;
439 case AccessibleRole::INTERNAL_FRAME
:
440 return QAccessible::UserRole
;
441 case AccessibleRole::LABEL
:
442 return QAccessible::StaticText
;
443 case AccessibleRole::LAYERED_PANE
:
444 return QAccessible::Pane
;
445 case AccessibleRole::LIST
:
446 return QAccessible::List
;
447 case AccessibleRole::LIST_ITEM
:
448 return QAccessible::ListItem
;
449 case AccessibleRole::MENU
:
450 case AccessibleRole::MENU_BAR
:
451 return QAccessible::MenuBar
;
452 case AccessibleRole::MENU_ITEM
:
453 return QAccessible::MenuItem
;
454 case AccessibleRole::NOTIFICATION
:
455 return QAccessible::Notification
;
456 case AccessibleRole::OPTION_PANE
:
457 return QAccessible::Pane
;
458 case AccessibleRole::PAGE_TAB
:
459 return QAccessible::PageTab
;
460 case AccessibleRole::PAGE_TAB_LIST
:
461 return QAccessible::PageTabList
;
462 case AccessibleRole::PANEL
:
463 return QAccessible::Pane
;
464 case AccessibleRole::PARAGRAPH
:
465 case AccessibleRole::BLOCK_QUOTE
:
466 return QAccessible::Paragraph
;
467 case AccessibleRole::PASSWORD_TEXT
:
468 // Qt API doesn't have a separate role to distinguish password edits,
469 // but a 'passwordEdit' state
470 return QAccessible::EditableText
;
471 case AccessibleRole::POPUP_MENU
:
472 return QAccessible::PopupMenu
;
473 case AccessibleRole::PUSH_BUTTON
:
474 return QAccessible::Button
;
475 case AccessibleRole::PROGRESS_BAR
:
476 return QAccessible::ProgressBar
;
477 case AccessibleRole::RADIO_BUTTON
:
478 return QAccessible::RadioButton
;
479 case AccessibleRole::RADIO_MENU_ITEM
:
480 return QAccessible::MenuItem
;
481 case AccessibleRole::ROW_HEADER
:
482 return QAccessible::RowHeader
;
483 case AccessibleRole::ROOT_PANE
:
484 return QAccessible::Pane
;
485 case AccessibleRole::SCROLL_BAR
:
486 return QAccessible::ScrollBar
;
487 case AccessibleRole::SCROLL_PANE
:
488 return QAccessible::Pane
;
489 case AccessibleRole::SHAPE
:
490 return QAccessible::Graphic
;
491 case AccessibleRole::SEPARATOR
:
492 return QAccessible::Separator
;
493 case AccessibleRole::SLIDER
:
494 return QAccessible::Slider
;
495 case AccessibleRole::SPIN_BOX
:
496 return QAccessible::SpinBox
;
497 case AccessibleRole::SPLIT_PANE
:
498 return QAccessible::Pane
;
499 case AccessibleRole::STATUS_BAR
:
500 return QAccessible::StatusBar
;
501 case AccessibleRole::TABLE
:
502 return QAccessible::Table
;
503 case AccessibleRole::TABLE_CELL
:
504 return QAccessible::Cell
;
505 case AccessibleRole::TEXT
:
506 return QAccessible::EditableText
;
507 case AccessibleRole::TEXT_FRAME
:
508 return QAccessible::UserRole
;
509 case AccessibleRole::TOGGLE_BUTTON
:
510 return QAccessible::Button
;
511 case AccessibleRole::TOOL_BAR
:
512 return QAccessible::ToolBar
;
513 case AccessibleRole::TOOL_TIP
:
514 return QAccessible::ToolTip
;
515 case AccessibleRole::TREE
:
516 return QAccessible::Tree
;
517 case AccessibleRole::VIEW_PORT
:
518 return QAccessible::UserRole
;
519 case AccessibleRole::BUTTON_DROPDOWN
:
520 return QAccessible::ButtonDropDown
;
521 case AccessibleRole::BUTTON_MENU
:
522 return QAccessible::ButtonMenu
;
523 case AccessibleRole::CAPTION
:
524 return QAccessible::StaticText
;
525 case AccessibleRole::CHART
:
526 return QAccessible::Chart
;
527 case AccessibleRole::EDIT_BAR
:
528 return QAccessible::Equation
;
529 case AccessibleRole::FORM
:
530 return QAccessible::Form
;
531 case AccessibleRole::IMAGE_MAP
:
532 return QAccessible::Graphic
;
533 case AccessibleRole::NOTE
:
534 return QAccessible::Note
;
535 case AccessibleRole::RULER
:
536 return QAccessible::UserRole
;
537 case AccessibleRole::SECTION
:
538 return QAccessible::Section
;
539 case AccessibleRole::TREE_ITEM
:
540 return QAccessible::TreeItem
;
541 case AccessibleRole::TREE_TABLE
:
542 return QAccessible::Tree
;
543 case AccessibleRole::COMMENT
:
544 return QAccessible::Note
;
545 case AccessibleRole::COMMENT_END
:
546 return QAccessible::UserRole
;
547 case AccessibleRole::DOCUMENT_PRESENTATION
:
548 return QAccessible::Document
;
549 case AccessibleRole::DOCUMENT_SPREADSHEET
:
550 return QAccessible::Document
;
551 case AccessibleRole::DOCUMENT_TEXT
:
552 return QAccessible::Document
;
553 case AccessibleRole::STATIC
:
554 return QAccessible::StaticText
;
555 case AccessibleRole::WINDOW
: // top-level window without title bar
556 return QAccessible::Window
;
559 SAL_WARN("vcl.qt", "Unmapped role: " << getAccessibleContextImpl()->getAccessibleRole());
560 return QAccessible::NoRole
;
565 void lcl_addState(QAccessible::State
* state
, sal_Int64 nState
)
569 case AccessibleStateType::INVALID
:
570 state
->invalid
= true;
572 case AccessibleStateType::ACTIVE
:
573 state
->active
= true;
575 case AccessibleStateType::ARMED
:
578 case AccessibleStateType::BUSY
:
581 case AccessibleStateType::CHECKABLE
:
582 state
->checkable
= true;
584 case AccessibleStateType::CHECKED
:
585 state
->checked
= true;
587 case AccessibleStateType::EDITABLE
:
588 state
->editable
= true;
590 case AccessibleStateType::ENABLED
:
591 state
->disabled
= false;
593 case AccessibleStateType::EXPANDABLE
:
594 state
->expandable
= true;
596 case AccessibleStateType::EXPANDED
:
597 state
->expanded
= true;
599 case AccessibleStateType::FOCUSABLE
:
600 state
->focusable
= true;
602 case AccessibleStateType::FOCUSED
:
603 state
->focused
= true;
605 case AccessibleStateType::HORIZONTAL
:
608 case AccessibleStateType::ICONIFIED
:
611 case AccessibleStateType::INDETERMINATE
:
612 state
->checkStateMixed
= true;
614 case AccessibleStateType::MANAGES_DESCENDANTS
:
617 case AccessibleStateType::MODAL
:
620 case AccessibleStateType::MOVEABLE
:
621 state
->movable
= true;
623 case AccessibleStateType::MULTI_LINE
:
624 state
->multiLine
= true;
626 case AccessibleStateType::OPAQUE
:
629 case AccessibleStateType::PRESSED
:
630 state
->pressed
= true;
632 case AccessibleStateType::RESIZABLE
:
633 state
->sizeable
= true;
635 case AccessibleStateType::SELECTABLE
:
636 state
->selectable
= true;
638 case AccessibleStateType::SELECTED
:
639 state
->selected
= true;
641 case AccessibleStateType::SENSITIVE
:
644 case AccessibleStateType::SHOWING
:
647 case AccessibleStateType::SINGLE_LINE
:
650 case AccessibleStateType::STALE
:
653 case AccessibleStateType::TRANSIENT
:
656 case AccessibleStateType::VERTICAL
:
659 case AccessibleStateType::VISIBLE
:
660 state
->invisible
= false;
662 case AccessibleStateType::DEFAULT
:
665 case AccessibleStateType::DEFUNC
:
666 state
->invalid
= true;
668 case AccessibleStateType::MULTI_SELECTABLE
:
669 state
->multiSelectable
= true;
672 SAL_WARN("vcl.qt", "Unmapped state: " << nState
);
678 QAccessible::State
QtAccessibleWidget::state() const
680 QAccessible::State state
;
682 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
686 sal_Int64
nStateSet(xAc
->getAccessibleStateSet());
688 for (int i
= 0; i
< 63; ++i
)
690 sal_Int64 nState
= sal_Int64(1) << i
;
691 if (nStateSet
& nState
)
692 lcl_addState(&state
, nState
);
695 if (xAc
->getAccessibleRole() == AccessibleRole::PASSWORD_TEXT
)
696 state
.passwordEdit
= true;
701 QColor
QtAccessibleWidget::foregroundColor() const
703 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
707 Reference
<XAccessibleComponent
> xAccessibleComponent(xAc
, UNO_QUERY
);
708 return toQColor(Color(ColorTransparency
, xAccessibleComponent
->getForeground()));
711 QColor
QtAccessibleWidget::backgroundColor() const
713 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
717 Reference
<XAccessibleComponent
> xAccessibleComponent(xAc
, UNO_QUERY
);
718 return toQColor(Color(ColorTransparency
, xAccessibleComponent
->getBackground()));
721 void* QtAccessibleWidget::interface_cast(QAccessible::InterfaceType t
)
723 if (t
== QAccessible::ActionInterface
&& accessibleProvidesInterface
<XAccessibleAction
>())
724 return static_cast<QAccessibleActionInterface
*>(this);
725 if (t
== QAccessible::TextInterface
&& accessibleProvidesInterface
<XAccessibleText
>())
726 return static_cast<QAccessibleTextInterface
*>(this);
727 if (t
== QAccessible::EditableTextInterface
728 && accessibleProvidesInterface
<XAccessibleEditableText
>())
729 return static_cast<QAccessibleEditableTextInterface
*>(this);
730 if (t
== QAccessible::ValueInterface
&& accessibleProvidesInterface
<XAccessibleValue
>())
731 return static_cast<QAccessibleValueInterface
*>(this);
732 if (t
== QAccessible::TableCellInterface
)
734 // parent must be a table
735 Reference
<XAccessibleTable
> xTable
= getAccessibleTableForParent();
737 return static_cast<QAccessibleTableCellInterface
*>(this);
739 if (t
== QAccessible::TableInterface
&& accessibleProvidesInterface
<XAccessibleTable
>())
740 return static_cast<QAccessibleTableInterface
*>(this);
741 #if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
742 if (t
== QAccessible::SelectionInterface
&& accessibleProvidesInterface
<XAccessibleSelection
>())
743 return static_cast<QAccessibleSelectionInterface
*>(this);
748 bool QtAccessibleWidget::isValid() const
750 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
754 QObject
* QtAccessibleWidget::object() const { return m_pObject
; }
756 void QtAccessibleWidget::setText(QAccessible::Text
/* t */, const QString
& /* text */) {}
758 QAccessibleInterface
* QtAccessibleWidget::childAt(int x
, int y
) const
760 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
764 Reference
<XAccessibleComponent
> xAccessibleComponent(xAc
, UNO_QUERY
);
765 // convert from screen to local coordinates
766 QPoint aLocalCoords
= QPoint(x
, y
) - rect().topLeft();
767 return QAccessible::queryAccessibleInterface(
768 QtAccessibleRegistry::getQObject(xAccessibleComponent
->getAccessibleAtPoint(
769 awt::Point(aLocalCoords
.x(), aLocalCoords
.y()))));
772 QAccessibleInterface
* QtAccessibleWidget::customFactory(const QString
& classname
, QObject
* object
)
774 if (classname
== QLatin1String("QtWidget") && object
&& object
->isWidgetType())
776 QtWidget
* pWidget
= static_cast<QtWidget
*>(object
);
777 vcl::Window
* pWindow
= pWidget
->frame().GetWindow();
781 css::uno::Reference
<XAccessible
> xAcc
= pWindow
->GetAccessible();
782 // insert into registry so the association between the XAccessible and the QtWidget
783 // is remembered rather than creating a different QtXAccessible when a QObject is needed later
784 QtAccessibleRegistry::insert(xAcc
, object
);
785 return new QtAccessibleWidget(xAcc
, object
);
788 if (classname
== QLatin1String("QtXAccessible") && object
)
790 QtXAccessible
* pXAccessible
= static_cast<QtXAccessible
*>(object
);
791 if (pXAccessible
->m_xAccessible
.is())
793 QtAccessibleWidget
* pRet
= new QtAccessibleWidget(pXAccessible
->m_xAccessible
, object
);
794 // clear the reference in the QtXAccessible, no longer needed now that the QtAccessibleWidget holds one
795 pXAccessible
->m_xAccessible
.clear();
803 // QAccessibleActionInterface
804 QStringList
QtAccessibleWidget::actionNames() const
806 QStringList actionNames
;
807 Reference
<XAccessibleAction
> xAccessibleAction(getAccessibleContextImpl(), UNO_QUERY
);
808 if (!xAccessibleAction
.is())
811 int count
= xAccessibleAction
->getAccessibleActionCount();
812 for (int i
= 0; i
< count
; i
++)
814 OUString desc
= xAccessibleAction
->getAccessibleActionDescription(i
);
815 actionNames
.append(toQString(desc
));
820 void QtAccessibleWidget::doAction(const QString
& actionName
)
822 Reference
<XAccessibleAction
> xAccessibleAction(getAccessibleContextImpl(), UNO_QUERY
);
823 if (!xAccessibleAction
.is())
826 int index
= actionNames().indexOf(actionName
);
829 xAccessibleAction
->doAccessibleAction(index
);
832 QStringList
QtAccessibleWidget::keyBindingsForAction(const QString
& actionName
) const
834 QStringList keyBindings
;
835 Reference
<XAccessibleAction
> xAccessibleAction(getAccessibleContextImpl(), UNO_QUERY
);
836 if (!xAccessibleAction
.is())
839 int index
= actionNames().indexOf(actionName
);
843 Reference
<XAccessibleKeyBinding
> xKeyBinding
844 = xAccessibleAction
->getAccessibleActionKeyBinding(index
);
846 if (!xKeyBinding
.is())
849 int count
= xKeyBinding
->getAccessibleKeyBindingCount();
850 for (int i
= 0; i
< count
; i
++)
852 Sequence
<awt::KeyStroke
> keyStroke
= xKeyBinding
->getAccessibleKeyBinding(i
);
853 keyBindings
.append(toQString(comphelper::GetkeyBindingStrByXkeyBinding(keyStroke
)));
858 // QAccessibleTextInterface
859 void QtAccessibleWidget::addSelection(int /* startOffset */, int /* endOffset */)
861 SAL_INFO("vcl.qt", "Unsupported QAccessibleTextInterface::addSelection");
864 // Text attributes are returned in format specified in IAccessible2 spec, since that
865 // is what Qt handles:
866 // https://wiki.linuxfoundation.org/accessibility/iaccessible2/textattributes
867 QString
QtAccessibleWidget::attributes(int offset
, int* startOffset
, int* endOffset
) const
869 if (startOffset
== nullptr || endOffset
== nullptr)
875 Reference
<XAccessibleText
> xText(getAccessibleContextImpl(), UNO_QUERY
);
879 // handle special values for offset the same way base class's QAccessibleTextWidget::attributes does
880 // (as defined in IAccessible 2: -1 -> length, -2 -> cursor position)
882 offset
= cursorPosition();
884 const int nTextLength
= characterCount();
885 if (offset
== -1 || offset
== nTextLength
)
886 offset
= nTextLength
- 1;
888 if (offset
< 0 || offset
> nTextLength
)
890 SAL_WARN("vcl.qt", "QtAccessibleWidget::attributes called with invalid offset: " << offset
);
894 // Qt doesn't have the strict separation into text and object attributes, but also
895 // supports text-specific attributes that are object attributes according to the
896 // IAccessible2 spec.
897 sal_Int32 nStart
= 0;
899 const OUString aRet
= AccessibleTextAttributeHelper::GetIAccessible2TextAttributes(
900 xText
, IA2AttributeType::TextAttributes
| IA2AttributeType::ObjectAttributes
,
901 static_cast<sal_Int32
>(offset
), nStart
, nEnd
);
902 *startOffset
= static_cast<int>(nStart
);
903 *endOffset
= static_cast<int>(nEnd
);
904 return toQString(aRet
);
907 int QtAccessibleWidget::characterCount() const
909 Reference
<XAccessibleText
> xText(getAccessibleContextImpl(), UNO_QUERY
);
911 return xText
->getCharacterCount();
915 QRect
QtAccessibleWidget::characterRect(int nOffset
) const
917 Reference
<XAccessibleText
> xText(getAccessibleContextImpl(), UNO_QUERY
);
921 if (nOffset
< 0 || nOffset
> xText
->getCharacterCount())
924 "QtAccessibleWidget::characterRect called with invalid offset: " << nOffset
);
928 const awt::Rectangle aBounds
= xText
->getCharacterBounds(nOffset
);
929 const QRect
aRect(aBounds
.X
, aBounds
.Y
, aBounds
.Width
, aBounds
.Height
);
930 // convert to screen coordinates
931 const QRect aScreenPos
= rect();
932 return aRect
.translated(aScreenPos
.x(), aScreenPos
.y());
935 int QtAccessibleWidget::cursorPosition() const
937 Reference
<XAccessibleText
> xText(getAccessibleContextImpl(), UNO_QUERY
);
939 return xText
->getCaretPosition();
943 int QtAccessibleWidget::offsetAtPoint(const QPoint
& rPoint
) const
945 Reference
<XAccessibleText
> xText(getAccessibleContextImpl(), UNO_QUERY
);
949 // convert from screen to local coordinates
950 QPoint aLocalCoords
= rPoint
- rect().topLeft();
951 awt::Point
aPoint(aLocalCoords
.x(), aLocalCoords
.y());
952 return xText
->getIndexAtPoint(aPoint
);
955 void QtAccessibleWidget::removeSelection(int /* selectionIndex */)
957 SAL_INFO("vcl.qt", "Unsupported QAccessibleTextInterface::removeSelection");
960 void QtAccessibleWidget::scrollToSubstring(int startIndex
, int endIndex
)
962 Reference
<XAccessibleText
> xText(getAccessibleContextImpl(), UNO_QUERY
);
966 sal_Int32 nTextLength
= xText
->getCharacterCount();
967 if (startIndex
< 0 || startIndex
> nTextLength
|| endIndex
< 0 || endIndex
> nTextLength
)
969 SAL_WARN("vcl.qt", "QtAccessibleWidget::scrollToSubstring called with invalid offset.");
973 xText
->scrollSubstringTo(startIndex
, endIndex
, AccessibleScrollType_SCROLL_ANYWHERE
);
976 void QtAccessibleWidget::selection(int selectionIndex
, int* startOffset
, int* endOffset
) const
978 if (!startOffset
&& !endOffset
)
981 Reference
<XAccessibleText
> xText
;
982 if (selectionIndex
== 0)
983 xText
= Reference
<XAccessibleText
>(getAccessibleContextImpl(), UNO_QUERY
);
986 *startOffset
= xText
.is() ? xText
->getSelectionStart() : 0;
988 *endOffset
= xText
.is() ? xText
->getSelectionEnd() : 0;
991 int QtAccessibleWidget::selectionCount() const
993 Reference
<XAccessibleText
> xText(getAccessibleContextImpl(), UNO_QUERY
);
994 if (xText
.is() && !xText
->getSelectedText().isEmpty())
995 return 1; // Only 1 selection supported atm
999 void QtAccessibleWidget::setCursorPosition(int position
)
1001 Reference
<XAccessibleText
> xText(getAccessibleContextImpl(), UNO_QUERY
);
1005 if (position
< 0 || position
> xText
->getCharacterCount())
1008 "QtAccessibleWidget::setCursorPosition called with invalid offset: " << position
);
1012 xText
->setCaretPosition(position
);
1015 void QtAccessibleWidget::setSelection(int /* selectionIndex */, int startOffset
, int endOffset
)
1017 Reference
<XAccessibleText
> xText(getAccessibleContextImpl(), UNO_QUERY
);
1021 sal_Int32 nTextLength
= xText
->getCharacterCount();
1022 if (startOffset
< 0 || startOffset
> nTextLength
|| endOffset
< 0 || endOffset
> nTextLength
)
1024 SAL_WARN("vcl.qt", "QtAccessibleWidget::setSelection called with invalid offset.");
1028 xText
->setSelection(startOffset
, endOffset
);
1031 QString
QtAccessibleWidget::text(int startOffset
, int endOffset
) const
1033 Reference
<XAccessibleText
> xText(getAccessibleContextImpl(), UNO_QUERY
);
1037 sal_Int32 nTextLength
= xText
->getCharacterCount();
1038 if (startOffset
< 0 || startOffset
> nTextLength
|| endOffset
< 0 || endOffset
> nTextLength
)
1040 SAL_WARN("vcl.qt", "QtAccessibleWidget::text called with invalid offset.");
1044 return toQString(xText
->getTextRange(startOffset
, endOffset
));
1047 QString
QtAccessibleWidget::textAfterOffset(int nOffset
,
1048 QAccessible::TextBoundaryType eBoundaryType
,
1049 int* pStartOffset
, int* pEndOffset
) const
1051 if (pStartOffset
== nullptr || pEndOffset
== nullptr)
1057 Reference
<XAccessibleText
> xText(getAccessibleContextImpl(), UNO_QUERY
);
1061 const int nCharCount
= characterCount();
1062 // -1 is special value for text length
1064 nOffset
= nCharCount
;
1065 else if (nOffset
< -1 || nOffset
> nCharCount
)
1068 "QtAccessibleWidget::textAfterOffset called with invalid offset: " << nOffset
);
1072 if (eBoundaryType
== QAccessible::NoBoundary
)
1074 if (nOffset
== nCharCount
)
1076 *pStartOffset
= nOffset
+ 1;
1077 *pEndOffset
= nCharCount
;
1078 return text(nOffset
+ 1, nCharCount
);
1081 sal_Int16 nUnoBoundaryType
= lcl_matchQtTextBoundaryType(eBoundaryType
);
1082 assert(nUnoBoundaryType
> 0);
1083 const TextSegment aSegment
= xText
->getTextBehindIndex(nOffset
, nUnoBoundaryType
);
1084 *pStartOffset
= aSegment
.SegmentStart
;
1085 *pEndOffset
= aSegment
.SegmentEnd
;
1086 return toQString(aSegment
.SegmentText
);
1089 QString
QtAccessibleWidget::textAtOffset(int offset
, QAccessible::TextBoundaryType boundaryType
,
1090 int* startOffset
, int* endOffset
) const
1092 if (startOffset
== nullptr || endOffset
== nullptr)
1095 const int nCharCount
= characterCount();
1096 if (boundaryType
== QAccessible::NoBoundary
)
1099 *endOffset
= nCharCount
;
1100 return text(0, nCharCount
);
1103 Reference
<XAccessibleText
> xText(getAccessibleContextImpl(), UNO_QUERY
);
1107 sal_Int16 nUnoBoundaryType
= lcl_matchQtTextBoundaryType(boundaryType
);
1108 assert(nUnoBoundaryType
> 0);
1110 // special value of -1 for offset means text length
1112 offset
= nCharCount
;
1114 if (offset
< 0 || offset
> nCharCount
)
1117 "QtAccessibleWidget::textAtOffset called with invalid offset: " << offset
);
1121 const TextSegment segment
= xText
->getTextAtIndex(offset
, nUnoBoundaryType
);
1122 *startOffset
= segment
.SegmentStart
;
1123 *endOffset
= segment
.SegmentEnd
;
1124 return toQString(segment
.SegmentText
);
1127 QString
QtAccessibleWidget::textBeforeOffset(int nOffset
,
1128 QAccessible::TextBoundaryType eBoundaryType
,
1129 int* pStartOffset
, int* pEndOffset
) const
1131 if (pStartOffset
== nullptr || pEndOffset
== nullptr)
1137 Reference
<XAccessibleText
> xText(getAccessibleContextImpl(), UNO_QUERY
);
1141 const int nCharCount
= characterCount();
1142 // -1 is special value for text length
1144 nOffset
= nCharCount
;
1145 else if (nOffset
< -1 || nOffset
> nCharCount
)
1148 "QtAccessibleWidget::textBeforeOffset called with invalid offset: " << nOffset
);
1152 if (eBoundaryType
== QAccessible::NoBoundary
)
1155 *pEndOffset
= nOffset
;
1156 return text(0, nOffset
);
1159 sal_Int16 nUnoBoundaryType
= lcl_matchQtTextBoundaryType(eBoundaryType
);
1160 assert(nUnoBoundaryType
> 0);
1161 const TextSegment aSegment
= xText
->getTextBeforeIndex(nOffset
, nUnoBoundaryType
);
1162 *pStartOffset
= aSegment
.SegmentStart
;
1163 *pEndOffset
= aSegment
.SegmentEnd
;
1164 return toQString(aSegment
.SegmentText
);
1167 // QAccessibleEditableTextInterface
1169 void QtAccessibleWidget::deleteText(int startOffset
, int endOffset
)
1171 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1175 Reference
<XAccessibleEditableText
> xEditableText(xAc
, UNO_QUERY
);
1176 if (!xEditableText
.is())
1179 sal_Int32 nTextLength
= xEditableText
->getCharacterCount();
1180 if (startOffset
< 0 || startOffset
> nTextLength
|| endOffset
< 0 || endOffset
> nTextLength
)
1182 SAL_WARN("vcl.qt", "QtAccessibleWidget::deleteText called with invalid offset.");
1186 xEditableText
->deleteText(startOffset
, endOffset
);
1189 void QtAccessibleWidget::insertText(int offset
, const QString
& text
)
1191 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1195 Reference
<XAccessibleEditableText
> xEditableText(xAc
, UNO_QUERY
);
1196 if (!xEditableText
.is())
1199 if (offset
< 0 || offset
> xEditableText
->getCharacterCount())
1201 SAL_WARN("vcl.qt", "QtAccessibleWidget::insertText called with invalid offset: " << offset
);
1205 xEditableText
->insertText(toOUString(text
), offset
);
1208 void QtAccessibleWidget::replaceText(int startOffset
, int endOffset
, const QString
& text
)
1210 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1214 Reference
<XAccessibleEditableText
> xEditableText(xAc
, UNO_QUERY
);
1215 if (!xEditableText
.is())
1218 sal_Int32 nTextLength
= xEditableText
->getCharacterCount();
1219 if (startOffset
< 0 || startOffset
> nTextLength
|| endOffset
< 0 || endOffset
> nTextLength
)
1221 SAL_WARN("vcl.qt", "QtAccessibleWidget::replaceText called with invalid offset.");
1225 xEditableText
->replaceText(startOffset
, endOffset
, toOUString(text
));
1228 // QAccessibleValueInterface
1229 QVariant
QtAccessibleWidget::currentValue() const
1231 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1235 Reference
<XAccessibleValue
> xValue(xAc
, UNO_QUERY
);
1239 xValue
->getCurrentValue() >>= aDouble
;
1240 return QVariant(aDouble
);
1243 QVariant
QtAccessibleWidget::maximumValue() const
1245 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1249 Reference
<XAccessibleValue
> xValue(xAc
, UNO_QUERY
);
1253 xValue
->getMaximumValue() >>= aDouble
;
1254 return QVariant(aDouble
);
1257 QVariant
QtAccessibleWidget::minimumStepSize() const
1259 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1263 Reference
<XAccessibleValue
> xValue(xAc
, UNO_QUERY
);
1266 double dMinStep
= 0;
1267 xValue
->getMinimumIncrement() >>= dMinStep
;
1268 return QVariant(dMinStep
);
1271 QVariant
QtAccessibleWidget::minimumValue() const
1273 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1277 Reference
<XAccessibleValue
> xValue(xAc
, UNO_QUERY
);
1281 xValue
->getMinimumValue() >>= aDouble
;
1282 return QVariant(aDouble
);
1285 void QtAccessibleWidget::setCurrentValue(const QVariant
& value
)
1287 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1291 Reference
<XAccessibleValue
> xValue(xAc
, UNO_QUERY
);
1295 // Different types of numerical values for XAccessibleValue are possible.
1296 // If current value has an integer type, also use that for the new value, to make
1297 // sure underlying implementations expecting that can handle the value properly.
1298 const Any aCurrentValue
= xValue
->getCurrentValue();
1299 if (aCurrentValue
.getValueTypeClass() == css::uno::TypeClass::TypeClass_LONG
)
1300 xValue
->setCurrentValue(Any(static_cast<sal_Int32
>(value
.toInt())));
1301 else if (aCurrentValue
.getValueTypeClass() == css::uno::TypeClass::TypeClass_HYPER
)
1302 xValue
->setCurrentValue(Any(static_cast<sal_Int64
>(value
.toLongLong())));
1304 xValue
->setCurrentValue(Any(value
.toDouble()));
1307 // QAccessibleTableInterface
1308 QAccessibleInterface
* QtAccessibleWidget::caption() const
1310 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1314 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1317 return QAccessible::queryAccessibleInterface(
1318 QtAccessibleRegistry::getQObject(xTable
->getAccessibleCaption()));
1321 QAccessibleInterface
* QtAccessibleWidget::cellAt(int row
, int column
) const
1323 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1327 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1331 if (row
< 0 || row
>= xTable
->getAccessibleRowCount() || column
< 0
1332 || column
>= xTable
->getAccessibleColumnCount())
1334 SAL_WARN("vcl.qt", "QtAccessibleWidget::cellAt called with invalid row/column index ("
1335 << row
<< ", " << column
<< ")");
1339 return QAccessible::queryAccessibleInterface(
1340 QtAccessibleRegistry::getQObject(xTable
->getAccessibleCellAt(row
, column
)));
1343 int QtAccessibleWidget::columnCount() const
1345 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1349 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1352 return xTable
->getAccessibleColumnCount();
1355 QString
QtAccessibleWidget::columnDescription(int column
) const
1357 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1361 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1364 return toQString(xTable
->getAccessibleColumnDescription(column
));
1367 bool QtAccessibleWidget::isColumnSelected(int nColumn
) const
1369 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1373 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1377 if (nColumn
< 0 || nColumn
>= xTable
->getAccessibleColumnCount())
1379 SAL_WARN("vcl.qt", "QtAccessibleWidget::isColumnSelected called with invalid column index "
1384 return xTable
->isAccessibleColumnSelected(nColumn
);
1387 bool QtAccessibleWidget::isRowSelected(int nRow
) const
1389 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1393 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1397 if (nRow
< 0 || nRow
>= xTable
->getAccessibleRowCount())
1400 "QtAccessibleWidget::isRowSelected called with invalid row index " << nRow
);
1404 return xTable
->isAccessibleRowSelected(nRow
);
1407 void QtAccessibleWidget::modelChange(QAccessibleTableModelChangeEvent
*) {}
1409 int QtAccessibleWidget::rowCount() const
1411 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1415 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1418 return xTable
->getAccessibleRowCount();
1421 QString
QtAccessibleWidget::rowDescription(int row
) const
1423 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1427 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1430 return toQString(xTable
->getAccessibleRowDescription(row
));
1433 bool QtAccessibleWidget::selectColumn(int column
)
1435 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1439 if (column
< 0 || column
>= columnCount())
1442 "QtAccessibleWidget::selectColumn called with invalid column index " << column
);
1446 Reference
<XAccessibleTableSelection
> xTableSelection(xAc
, UNO_QUERY
);
1447 if (!xTableSelection
.is())
1449 return xTableSelection
->selectColumn(column
);
1452 bool QtAccessibleWidget::selectRow(int row
)
1454 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1458 if (row
< 0 || row
>= rowCount())
1460 SAL_WARN("vcl.qt", "QtAccessibleWidget::selectRow called with invalid row index " << row
);
1464 Reference
<XAccessibleTableSelection
> xTableSelection(xAc
, UNO_QUERY
);
1465 if (!xTableSelection
.is())
1467 return xTableSelection
->selectRow(row
);
1470 int QtAccessibleWidget::selectedCellCount() const { return selectedItemCount(); }
1472 QList
<QAccessibleInterface
*> QtAccessibleWidget::selectedCells() const { return selectedItems(); }
1474 int QtAccessibleWidget::selectedColumnCount() const
1476 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1480 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1483 return xTable
->getSelectedAccessibleColumns().getLength();
1486 QList
<int> QtAccessibleWidget::selectedColumns() const
1488 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1490 return QList
<int>();
1492 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1494 return QList
<int>();
1495 return toQList(xTable
->getSelectedAccessibleColumns());
1498 int QtAccessibleWidget::selectedRowCount() const
1500 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1504 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1507 return xTable
->getSelectedAccessibleRows().getLength();
1510 QList
<int> QtAccessibleWidget::selectedRows() const
1512 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1514 return QList
<int>();
1516 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1518 return QList
<int>();
1519 return toQList(xTable
->getSelectedAccessibleRows());
1522 QAccessibleInterface
* QtAccessibleWidget::summary() const
1524 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1528 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1531 return QAccessible::queryAccessibleInterface(
1532 QtAccessibleRegistry::getQObject(xTable
->getAccessibleSummary()));
1535 bool QtAccessibleWidget::unselectColumn(int column
)
1537 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1541 Reference
<XAccessibleTableSelection
> xTableSelection(xAc
, UNO_QUERY
);
1542 if (!xTableSelection
.is())
1544 return xTableSelection
->unselectColumn(column
);
1547 bool QtAccessibleWidget::unselectRow(int row
)
1549 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1553 Reference
<XAccessibleTableSelection
> xTableSelection(xAc
, UNO_QUERY
);
1554 if (!xTableSelection
.is())
1556 return xTableSelection
->unselectRow(row
);
1559 // QAccessibleTableCellInterface
1560 QList
<QAccessibleInterface
*> QtAccessibleWidget::columnHeaderCells() const
1562 Reference
<XAccessibleTable
> xTable
= getAccessibleTableForParent();
1564 return QList
<QAccessibleInterface
*>();
1566 Reference
<XAccessibleTable
> xHeaders
= xTable
->getAccessibleColumnHeaders();
1568 return QList
<QAccessibleInterface
*>();
1570 const sal_Int32 nCol
= columnIndex();
1571 QList
<QAccessibleInterface
*> aHeaderCells
;
1572 for (sal_Int32 nRow
= 0; nRow
< xHeaders
->getAccessibleRowCount(); nRow
++)
1574 Reference
<XAccessible
> xCell
= xHeaders
->getAccessibleCellAt(nRow
, nCol
);
1575 QAccessibleInterface
* pInterface
1576 = QAccessible::queryAccessibleInterface(QtAccessibleRegistry::getQObject(xCell
));
1577 aHeaderCells
.push_back(pInterface
);
1579 return aHeaderCells
;
1582 int QtAccessibleWidget::columnIndex() const
1584 Reference
<XAccessibleContext
> xAcc
= getAccessibleContextImpl();
1588 Reference
<XAccessibleTable
> xTable
= getAccessibleTableForParent();
1592 const sal_Int64 nIndexInParent
= xAcc
->getAccessibleIndexInParent();
1593 return xTable
->getAccessibleColumn(nIndexInParent
);
1596 bool QtAccessibleWidget::isSelected() const
1598 Reference
<XAccessibleContext
> xAcc
= getAccessibleContextImpl();
1602 Reference
<XAccessibleTable
> xTable
= getAccessibleTableForParent();
1606 const sal_Int32 nColumn
= columnIndex();
1607 const sal_Int32 nRow
= rowIndex();
1608 return xTable
->isAccessibleSelected(nRow
, nColumn
);
1611 int QtAccessibleWidget::columnExtent() const
1613 Reference
<XAccessibleContext
> xAcc
= getAccessibleContextImpl();
1617 Reference
<XAccessibleTable
> xTable
= getAccessibleTableForParent();
1621 const sal_Int32 nColumn
= columnIndex();
1622 const sal_Int32 nRow
= rowIndex();
1623 return xTable
->getAccessibleColumnExtentAt(nRow
, nColumn
);
1626 QList
<QAccessibleInterface
*> QtAccessibleWidget::rowHeaderCells() const
1628 Reference
<XAccessibleTable
> xTable
= getAccessibleTableForParent();
1630 return QList
<QAccessibleInterface
*>();
1632 Reference
<XAccessibleTable
> xHeaders
= xTable
->getAccessibleRowHeaders();
1634 return QList
<QAccessibleInterface
*>();
1636 const sal_Int32 nRow
= rowIndex();
1637 QList
<QAccessibleInterface
*> aHeaderCells
;
1638 for (sal_Int32 nCol
= 0; nCol
< xHeaders
->getAccessibleColumnCount(); nCol
++)
1640 Reference
<XAccessible
> xCell
= xHeaders
->getAccessibleCellAt(nRow
, nCol
);
1641 QAccessibleInterface
* pInterface
1642 = QAccessible::queryAccessibleInterface(QtAccessibleRegistry::getQObject(xCell
));
1643 aHeaderCells
.push_back(pInterface
);
1645 return aHeaderCells
;
1648 int QtAccessibleWidget::rowExtent() const
1650 Reference
<XAccessibleContext
> xAcc
= getAccessibleContextImpl();
1654 Reference
<XAccessibleTable
> xTable
= getAccessibleTableForParent();
1658 const sal_Int32 nColumn
= columnIndex();
1659 const sal_Int32 nRow
= rowIndex();
1660 return xTable
->getAccessibleRowExtentAt(nRow
, nColumn
);
1663 int QtAccessibleWidget::rowIndex() const
1665 Reference
<XAccessibleContext
> xAcc
= getAccessibleContextImpl();
1669 Reference
<XAccessibleTable
> xTable
= getAccessibleTableForParent();
1673 const sal_Int64 nIndexInParent
= xAcc
->getAccessibleIndexInParent();
1674 return xTable
->getAccessibleRow(nIndexInParent
);
1677 QAccessibleInterface
* QtAccessibleWidget::table() const
1679 Reference
<XAccessibleTable
> xTable
= getAccessibleTableForParent();
1683 Reference
<XAccessible
> xTableAcc(xTable
, UNO_QUERY
);
1684 if (!xTableAcc
.is())
1687 return QAccessible::queryAccessibleInterface(QtAccessibleRegistry::getQObject(xTableAcc
));
1690 // QAccessibleSelectionInterface
1691 int QtAccessibleWidget::selectedItemCount() const
1693 Reference
<XAccessibleContext
> xAcc
= getAccessibleContextImpl();
1697 Reference
<XAccessibleSelection
> xSelection(xAcc
, UNO_QUERY
);
1698 if (!xSelection
.is())
1701 sal_Int64 nSelected
= xSelection
->getSelectedAccessibleChildCount();
1702 if (nSelected
> std::numeric_limits
<int>::max())
1705 "QtAccessibleWidget::selectedItemCount: Cell count exceeds maximum int value, "
1707 nSelected
= std::numeric_limits
<int>::max();
1712 QList
<QAccessibleInterface
*> QtAccessibleWidget::selectedItems() const
1714 Reference
<XAccessibleContext
> xAcc
= getAccessibleContextImpl();
1716 return QList
<QAccessibleInterface
*>();
1718 Reference
<XAccessibleSelection
> xSelection(xAcc
, UNO_QUERY
);
1719 if (!xSelection
.is())
1720 return QList
<QAccessibleInterface
*>();
1722 QList
<QAccessibleInterface
*> aSelectedItems
;
1723 sal_Int64 nSelected
= xSelection
->getSelectedAccessibleChildCount();
1724 if (nSelected
> std::numeric_limits
<int>::max())
1727 "QtAccessibleWidget::selectedItems: Cell count exceeds maximum int value, "
1729 nSelected
= std::numeric_limits
<int>::max();
1731 for (sal_Int64 i
= 0; i
< nSelected
; i
++)
1733 Reference
<XAccessible
> xChild
= xSelection
->getSelectedAccessibleChild(i
);
1734 QAccessibleInterface
* pInterface
1735 = QAccessible::queryAccessibleInterface(QtAccessibleRegistry::getQObject(xChild
));
1736 aSelectedItems
.push_back(pInterface
);
1738 return aSelectedItems
;
1741 #if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
1742 QAccessibleInterface
* QtAccessibleWidget::selectedItem(int nSelectionIndex
) const
1744 Reference
<XAccessibleContext
> xAcc
= getAccessibleContextImpl();
1748 Reference
<XAccessibleSelection
> xSelection(xAcc
, UNO_QUERY
);
1749 if (!xSelection
.is())
1752 if (nSelectionIndex
< 0 || nSelectionIndex
>= xSelection
->getSelectedAccessibleChildCount())
1755 "QtAccessibleWidget::selectedItem called with invalid index: " << nSelectionIndex
);
1759 Reference
<XAccessible
> xChild
= xSelection
->getSelectedAccessibleChild(nSelectionIndex
);
1763 return QAccessible::queryAccessibleInterface(QtAccessibleRegistry::getQObject(xChild
));
1766 bool QtAccessibleWidget::isSelected(QAccessibleInterface
* pItem
) const
1768 Reference
<XAccessibleContext
> xAcc
= getAccessibleContextImpl();
1772 Reference
<XAccessibleSelection
> xSelection(xAcc
, UNO_QUERY
);
1773 if (!xSelection
.is())
1776 int nChildIndex
= indexOfChild(pItem
);
1777 if (nChildIndex
< 0)
1780 return xSelection
->isAccessibleChildSelected(nChildIndex
);
1783 bool QtAccessibleWidget::select(QAccessibleInterface
* pItem
)
1785 Reference
<XAccessibleContext
> xAcc
= getAccessibleContextImpl();
1789 Reference
<XAccessibleSelection
> xSelection(xAcc
, UNO_QUERY
);
1790 if (!xSelection
.is())
1793 int nChildIndex
= indexOfChild(pItem
);
1794 if (nChildIndex
< 0)
1797 xSelection
->selectAccessibleChild(nChildIndex
);
1801 bool QtAccessibleWidget::unselect(QAccessibleInterface
* pItem
)
1803 Reference
<XAccessibleContext
> xAcc
= getAccessibleContextImpl();
1807 Reference
<XAccessibleSelection
> xSelection(xAcc
, UNO_QUERY
);
1808 if (!xSelection
.is())
1811 int nChildIndex
= indexOfChild(pItem
);
1812 if (nChildIndex
< 0)
1815 xSelection
->deselectAccessibleChild(nChildIndex
);
1819 bool QtAccessibleWidget::selectAll()
1821 Reference
<XAccessibleContext
> xAcc
= getAccessibleContextImpl();
1825 Reference
<XAccessibleSelection
> xSelection(xAcc
, UNO_QUERY
);
1826 if (!xSelection
.is())
1829 xSelection
->selectAllAccessibleChildren();
1833 bool QtAccessibleWidget::clear()
1835 Reference
<XAccessibleContext
> xAcc
= getAccessibleContextImpl();
1839 Reference
<XAccessibleSelection
> xSelection(xAcc
, UNO_QUERY
);
1840 if (!xSelection
.is())
1843 xSelection
->clearAccessibleSelection();
1848 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */