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/awt/FontSlant.hpp>
50 #include <com/sun/star/awt/FontUnderline.hpp>
51 #include <com/sun/star/awt/FontWeight.hpp>
52 #include <com/sun/star/beans/PropertyValue.hpp>
53 #include <com/sun/star/lang/DisposedException.hpp>
54 #include <com/sun/star/uno/Sequence.hxx>
56 #include <comphelper/AccessibleImplementationHelper.hxx>
57 #include <o3tl/any.hxx>
58 #include <sal/log.hxx>
61 using namespace css::accessibility
;
62 using namespace css::beans
;
63 using namespace css::uno
;
65 QtAccessibleWidget::QtAccessibleWidget(const Reference
<XAccessible
> xAccessible
, QObject
* pObject
)
66 : m_xAccessible(xAccessible
)
69 Reference
<XAccessibleContext
> xContext
= xAccessible
->getAccessibleContext();
70 Reference
<XAccessibleEventBroadcaster
> xBroadcaster(xContext
, UNO_QUERY
);
71 if (xBroadcaster
.is())
73 Reference
<XAccessibleEventListener
> xListener(new QtAccessibleEventListener(this));
74 xBroadcaster
->addAccessibleEventListener(xListener
);
78 void QtAccessibleWidget::invalidate()
80 QtAccessibleRegistry::remove(m_xAccessible
);
81 m_xAccessible
.clear();
84 Reference
<XAccessibleContext
> QtAccessibleWidget::getAccessibleContextImpl() const
86 Reference
<XAccessibleContext
> xAc
;
88 if (m_xAccessible
.is())
92 xAc
= m_xAccessible
->getAccessibleContext();
94 catch (css::lang::DisposedException
/*ex*/)
96 SAL_WARN("vcl.qt", "Accessible context disposed already");
98 // sometimes getAccessibleContext throws also RuntimeException if context is no longer alive
99 catch (css::uno::RuntimeException
/*ex*/)
101 // so let's catch it here, cuz otherwise soffice falls flat on its face
102 // with FatalError and nothing else
103 SAL_WARN("vcl.qt", "Accessible context no longer alive");
110 css::uno::Reference
<css::accessibility::XAccessibleTable
>
111 QtAccessibleWidget::getAccessibleTableForParent() const
113 Reference
<XAccessibleContext
> xAcc
= getAccessibleContextImpl();
117 Reference
<XAccessible
> xParent
= xAcc
->getAccessibleParent();
121 Reference
<XAccessibleContext
> xParentContext
= xParent
->getAccessibleContext();
122 if (!xParentContext
.is())
125 return Reference
<XAccessibleTable
>(xParentContext
, UNO_QUERY
);
128 QWindow
* QtAccessibleWidget::window() const
131 if (m_pObject
->isWidgetType())
133 QWidget
* pWidget
= static_cast<QWidget
*>(m_pObject
);
134 QWidget
* pWindow
= pWidget
->window();
136 return pWindow
->windowHandle();
139 QAccessibleInterface
* pParent
= parent();
141 return pParent
->window();
146 int QtAccessibleWidget::childCount() const
148 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
152 sal_Int64 nChildCount
= xAc
->getAccessibleChildCount();
153 if (nChildCount
> std::numeric_limits
<int>::max())
155 SAL_WARN("vcl.qt", "QtAccessibleWidget::childCount: Child count exceeds maximum int value, "
156 "returning max int.");
157 nChildCount
= std::numeric_limits
<int>::max();
163 int QtAccessibleWidget::indexOfChild(const QAccessibleInterface
* pChild
) const
165 const QtAccessibleWidget
* pAccessibleWidget
= dynamic_cast<const QtAccessibleWidget
*>(pChild
);
166 if (!pAccessibleWidget
)
170 "QtAccessibleWidget::indexOfChild called with child that is no QtAccessibleWidget");
174 Reference
<XAccessibleContext
> xContext
= pAccessibleWidget
->getAccessibleContextImpl();
178 sal_Int64 nChildIndex
= xContext
->getAccessibleIndexInParent();
179 if (nChildIndex
> std::numeric_limits
<int>::max())
181 // use -2 when the child index is too large to fit into 32 bit to neither use the
182 // valid index of another child nor -1, which would e.g. make the Orca screen reader
183 // interpret the object as being a zombie
185 "QtAccessibleWidget::indexOfChild: Child index exceeds maximum int value, "
194 sal_Int16
lcl_matchQtTextBoundaryType(QAccessible::TextBoundaryType boundaryType
)
196 switch (boundaryType
)
198 case QAccessible::CharBoundary
:
199 return com::sun::star::accessibility::AccessibleTextType::CHARACTER
;
200 case QAccessible::WordBoundary
:
201 return com::sun::star::accessibility::AccessibleTextType::WORD
;
202 case QAccessible::SentenceBoundary
:
203 return com::sun::star::accessibility::AccessibleTextType::SENTENCE
;
204 case QAccessible::ParagraphBoundary
:
205 return com::sun::star::accessibility::AccessibleTextType::PARAGRAPH
;
206 case QAccessible::LineBoundary
:
207 return com::sun::star::accessibility::AccessibleTextType::LINE
;
208 case QAccessible::NoBoundary
:
209 // assert here, better handle it directly at call site
211 && "No match for QAccessible::NoBoundary, handle it separately at call site.");
217 SAL_WARN("vcl.qt", "Unmatched text boundary type: " << boundaryType
);
221 QAccessible::Relation
lcl_matchUnoRelation(short relationType
)
223 switch (relationType
)
225 case AccessibleRelationType::CONTROLLER_FOR
:
226 return QAccessible::Controller
;
227 case AccessibleRelationType::CONTROLLED_BY
:
228 return QAccessible::Controlled
;
229 case AccessibleRelationType::LABEL_FOR
:
230 return QAccessible::Label
;
231 case AccessibleRelationType::LABELED_BY
:
232 return QAccessible::Labelled
;
233 case AccessibleRelationType::INVALID
:
234 case AccessibleRelationType::CONTENT_FLOWS_FROM
:
235 case AccessibleRelationType::CONTENT_FLOWS_TO
:
236 case AccessibleRelationType::MEMBER_OF
:
237 case AccessibleRelationType::SUB_WINDOW_OF
:
238 case AccessibleRelationType::NODE_CHILD_OF
:
239 case AccessibleRelationType::DESCRIBED_BY
:
241 SAL_WARN("vcl.qt", "Unmatched relation: " << relationType
);
246 short lcl_matchQtRelation(QAccessible::Relation relationType
)
248 switch (relationType
)
250 case QAccessible::Controller
:
251 return AccessibleRelationType::CONTROLLER_FOR
;
252 case QAccessible::Controlled
:
253 return AccessibleRelationType::CONTROLLED_BY
;
254 case QAccessible::Label
:
255 return AccessibleRelationType::LABEL_FOR
;
256 case QAccessible::Labelled
:
257 return AccessibleRelationType::LABELED_BY
;
259 SAL_WARN("vcl.qt", "Unmatched relation: " << relationType
);
264 void lcl_appendRelation(QVector
<QPair
<QAccessibleInterface
*, QAccessible::Relation
>>* relations
,
265 AccessibleRelation aRelation
)
267 QAccessible::Relation aQRelation
= lcl_matchUnoRelation(aRelation
.RelationType
);
268 // skip in case there's no matching Qt relation
269 if (!(aQRelation
& QAccessible::AllRelations
))
272 sal_uInt32 nTargetCount
= aRelation
.TargetSet
.getLength();
274 for (sal_uInt32 i
= 0; i
< nTargetCount
; i
++)
276 Reference
<XAccessible
> xAccessible(aRelation
.TargetSet
[i
], uno::UNO_QUERY
);
278 { QAccessible::queryAccessibleInterface(QtAccessibleRegistry::getQObject(xAccessible
)),
284 QVector
<QPair
<QAccessibleInterface
*, QAccessible::Relation
>>
285 QtAccessibleWidget::relations(QAccessible::Relation match
) const
287 QVector
<QPair
<QAccessibleInterface
*, QAccessible::Relation
>> relations
;
289 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
293 Reference
<XAccessibleRelationSet
> xRelationSet
= xAc
->getAccessibleRelationSet();
294 if (xRelationSet
.is())
296 if (match
== QAccessible::AllRelations
)
298 int count
= xRelationSet
->getRelationCount();
299 for (int i
= 0; i
< count
; i
++)
301 AccessibleRelation aRelation
= xRelationSet
->getRelation(i
);
302 lcl_appendRelation(&relations
, aRelation
);
307 AccessibleRelation aRelation
= xRelationSet
->getRelation(lcl_matchQtRelation(match
));
308 lcl_appendRelation(&relations
, aRelation
);
315 QAccessibleInterface
* QtAccessibleWidget::focusChild() const
317 /* if (m_pWindow->HasChildPathFocus())
318 return QAccessible::queryAccessibleInterface(
319 new QtXAccessible(m_xAccessible->getAccessibleContext()->getAccessibleChild(index))); */
320 return QAccessible::queryAccessibleInterface(object());
323 QRect
QtAccessibleWidget::rect() const
325 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
329 Reference
<XAccessibleComponent
> xAccessibleComponent(xAc
, UNO_QUERY
);
330 awt::Point aPoint
= xAccessibleComponent
->getLocationOnScreen();
331 awt::Size aSize
= xAccessibleComponent
->getSize();
333 return QRect(aPoint
.X
, aPoint
.Y
, aSize
.Width
, aSize
.Height
);
336 QAccessibleInterface
* QtAccessibleWidget::parent() const
338 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
342 if (xAc
->getAccessibleParent().is())
343 return QAccessible::queryAccessibleInterface(
344 QtAccessibleRegistry::getQObject(xAc
->getAccessibleParent()));
346 // go via the QObject hierarchy; some a11y objects like the application
347 // (at the root of the a11y hierarchy) are handled solely by Qt and have
348 // no LO-internal a11y objects associated with them
349 QObject
* pObj
= object();
350 if (pObj
&& pObj
->parent())
351 return QAccessible::queryAccessibleInterface(pObj
->parent());
356 QAccessibleInterface
* QtAccessibleWidget::child(int index
) const
358 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
361 return QAccessible::queryAccessibleInterface(
362 QtAccessibleRegistry::getQObject(xAc
->getAccessibleChild(index
)));
365 QString
QtAccessibleWidget::text(QAccessible::Text text
) const
367 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
373 case QAccessible::Name
:
374 return toQString(xAc
->getAccessibleName());
375 case QAccessible::Description
:
376 case QAccessible::DebugDescription
:
377 return toQString(xAc
->getAccessibleDescription());
378 case QAccessible::Value
:
379 case QAccessible::Help
:
380 case QAccessible::Accelerator
:
381 case QAccessible::UserText
:
383 return QString("Unknown");
386 QAccessible::Role
QtAccessibleWidget::role() const
388 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
390 return QAccessible::NoRole
;
392 switch (xAc
->getAccessibleRole())
394 case AccessibleRole::UNKNOWN
:
395 return QAccessible::NoRole
;
396 case AccessibleRole::ALERT
:
397 return QAccessible::AlertMessage
;
398 case AccessibleRole::COLUMN_HEADER
:
399 return QAccessible::ColumnHeader
;
400 case AccessibleRole::CANVAS
:
401 return QAccessible::Canvas
;
402 case AccessibleRole::CHECK_BOX
:
403 return QAccessible::CheckBox
;
404 case AccessibleRole::CHECK_MENU_ITEM
:
405 return QAccessible::MenuItem
;
406 case AccessibleRole::COLOR_CHOOSER
:
407 return QAccessible::ColorChooser
;
408 case AccessibleRole::COMBO_BOX
:
409 return QAccessible::ComboBox
;
410 case AccessibleRole::DATE_EDITOR
:
411 return QAccessible::EditableText
;
412 case AccessibleRole::DESKTOP_ICON
:
413 return QAccessible::Graphic
;
414 case AccessibleRole::DESKTOP_PANE
:
415 case AccessibleRole::DIRECTORY_PANE
:
416 return QAccessible::Pane
;
417 case AccessibleRole::DIALOG
:
418 return QAccessible::Dialog
;
419 case AccessibleRole::DOCUMENT
:
420 return QAccessible::Document
;
421 case AccessibleRole::EMBEDDED_OBJECT
:
422 return QAccessible::UserRole
;
423 case AccessibleRole::END_NOTE
:
424 return QAccessible::Note
;
425 case AccessibleRole::FILE_CHOOSER
:
426 return QAccessible::Dialog
;
427 case AccessibleRole::FILLER
:
428 return QAccessible::Whitespace
;
429 case AccessibleRole::FONT_CHOOSER
:
430 return QAccessible::UserRole
;
431 case AccessibleRole::FOOTER
:
432 return QAccessible::Footer
;
433 case AccessibleRole::FOOTNOTE
:
434 return QAccessible::Note
;
435 case AccessibleRole::FRAME
: // top-level window with title bar
436 return QAccessible::Window
;
437 case AccessibleRole::GLASS_PANE
:
438 return QAccessible::UserRole
;
439 case AccessibleRole::GRAPHIC
:
440 return QAccessible::Graphic
;
441 case AccessibleRole::GROUP_BOX
:
442 return QAccessible::Grouping
;
443 case AccessibleRole::HEADER
:
444 return QAccessible::UserRole
;
445 case AccessibleRole::HEADING
:
446 return QAccessible::Heading
;
447 case AccessibleRole::HYPER_LINK
:
448 return QAccessible::Link
;
449 case AccessibleRole::ICON
:
450 return QAccessible::Graphic
;
451 case AccessibleRole::INTERNAL_FRAME
:
452 return QAccessible::UserRole
;
453 case AccessibleRole::LABEL
:
454 return QAccessible::StaticText
;
455 case AccessibleRole::LAYERED_PANE
:
456 return QAccessible::Pane
;
457 case AccessibleRole::LIST
:
458 return QAccessible::List
;
459 case AccessibleRole::LIST_ITEM
:
460 return QAccessible::ListItem
;
461 case AccessibleRole::MENU
:
462 case AccessibleRole::MENU_BAR
:
463 return QAccessible::MenuBar
;
464 case AccessibleRole::MENU_ITEM
:
465 return QAccessible::MenuItem
;
466 case AccessibleRole::NOTIFICATION
:
467 #if QT_VERSION >= QT_VERSION_CHECK(5, 12, 5)
468 return QAccessible::Notification
;
470 return QAccessible::StaticText
;
472 case AccessibleRole::OPTION_PANE
:
473 return QAccessible::Pane
;
474 case AccessibleRole::PAGE_TAB
:
475 return QAccessible::PageTab
;
476 case AccessibleRole::PAGE_TAB_LIST
:
477 return QAccessible::PageTabList
;
478 case AccessibleRole::PANEL
:
479 return QAccessible::Pane
;
480 case AccessibleRole::PARAGRAPH
:
481 return QAccessible::Paragraph
;
482 case AccessibleRole::PASSWORD_TEXT
:
483 return QAccessible::EditableText
;
484 case AccessibleRole::POPUP_MENU
:
485 return QAccessible::PopupMenu
;
486 case AccessibleRole::PUSH_BUTTON
:
487 return QAccessible::Button
;
488 case AccessibleRole::PROGRESS_BAR
:
489 return QAccessible::ProgressBar
;
490 case AccessibleRole::RADIO_BUTTON
:
491 return QAccessible::RadioButton
;
492 case AccessibleRole::RADIO_MENU_ITEM
:
493 return QAccessible::MenuItem
;
494 case AccessibleRole::ROW_HEADER
:
495 return QAccessible::RowHeader
;
496 case AccessibleRole::ROOT_PANE
:
497 return QAccessible::Pane
;
498 case AccessibleRole::SCROLL_BAR
:
499 return QAccessible::ScrollBar
;
500 case AccessibleRole::SCROLL_PANE
:
501 return QAccessible::Pane
;
502 case AccessibleRole::SHAPE
:
503 return QAccessible::Graphic
;
504 case AccessibleRole::SEPARATOR
:
505 return QAccessible::Separator
;
506 case AccessibleRole::SLIDER
:
507 return QAccessible::Slider
;
508 case AccessibleRole::SPIN_BOX
:
509 return QAccessible::SpinBox
;
510 case AccessibleRole::SPLIT_PANE
:
511 return QAccessible::Pane
;
512 case AccessibleRole::STATUS_BAR
:
513 return QAccessible::StatusBar
;
514 case AccessibleRole::TABLE
:
515 return QAccessible::Table
;
516 case AccessibleRole::TABLE_CELL
:
517 return QAccessible::Cell
;
518 case AccessibleRole::TEXT
:
519 return QAccessible::EditableText
;
520 case AccessibleRole::TEXT_FRAME
:
521 return QAccessible::UserRole
;
522 case AccessibleRole::TOGGLE_BUTTON
:
523 return QAccessible::Button
;
524 case AccessibleRole::TOOL_BAR
:
525 return QAccessible::ToolBar
;
526 case AccessibleRole::TOOL_TIP
:
527 return QAccessible::ToolTip
;
528 case AccessibleRole::TREE
:
529 return QAccessible::Tree
;
530 case AccessibleRole::VIEW_PORT
:
531 return QAccessible::UserRole
;
532 case AccessibleRole::BUTTON_DROPDOWN
:
533 return QAccessible::ButtonDropDown
;
534 case AccessibleRole::BUTTON_MENU
:
535 return QAccessible::ButtonMenu
;
536 case AccessibleRole::CAPTION
:
537 return QAccessible::StaticText
;
538 case AccessibleRole::CHART
:
539 return QAccessible::Chart
;
540 case AccessibleRole::EDIT_BAR
:
541 return QAccessible::Equation
;
542 case AccessibleRole::FORM
:
543 return QAccessible::Form
;
544 case AccessibleRole::IMAGE_MAP
:
545 return QAccessible::Graphic
;
546 case AccessibleRole::NOTE
:
547 return QAccessible::Note
;
548 case AccessibleRole::RULER
:
549 return QAccessible::UserRole
;
550 case AccessibleRole::SECTION
:
551 return QAccessible::Section
;
552 case AccessibleRole::TREE_ITEM
:
553 return QAccessible::TreeItem
;
554 case AccessibleRole::TREE_TABLE
:
555 return QAccessible::Tree
;
556 case AccessibleRole::COMMENT
:
557 return QAccessible::Note
;
558 case AccessibleRole::COMMENT_END
:
559 return QAccessible::UserRole
;
560 case AccessibleRole::DOCUMENT_PRESENTATION
:
561 return QAccessible::Document
;
562 case AccessibleRole::DOCUMENT_SPREADSHEET
:
563 return QAccessible::Document
;
564 case AccessibleRole::DOCUMENT_TEXT
:
565 return QAccessible::Document
;
566 case AccessibleRole::STATIC
:
567 return QAccessible::StaticText
;
568 case AccessibleRole::WINDOW
: // top-level window without title bar
569 return QAccessible::Window
;
572 SAL_WARN("vcl.qt", "Unmapped role: " << getAccessibleContextImpl()->getAccessibleRole());
573 return QAccessible::NoRole
;
578 void lcl_addState(QAccessible::State
* state
, sal_Int64 nState
)
582 case AccessibleStateType::INVALID
:
583 state
->invalid
= true;
585 case AccessibleStateType::ACTIVE
:
586 state
->active
= true;
588 case AccessibleStateType::ARMED
:
591 case AccessibleStateType::BUSY
:
594 case AccessibleStateType::CHECKED
:
595 state
->checked
= true;
597 case AccessibleStateType::EDITABLE
:
598 state
->editable
= true;
600 case AccessibleStateType::ENABLED
:
601 state
->disabled
= false;
603 case AccessibleStateType::EXPANDABLE
:
604 state
->expandable
= true;
606 case AccessibleStateType::EXPANDED
:
607 state
->expanded
= true;
609 case AccessibleStateType::FOCUSABLE
:
610 state
->focusable
= true;
612 case AccessibleStateType::FOCUSED
:
613 state
->focused
= true;
615 case AccessibleStateType::HORIZONTAL
:
618 case AccessibleStateType::ICONIFIED
:
621 case AccessibleStateType::INDETERMINATE
:
624 case AccessibleStateType::MANAGES_DESCENDANTS
:
627 case AccessibleStateType::MODAL
:
630 case AccessibleStateType::MOVEABLE
:
631 state
->movable
= true;
633 case AccessibleStateType::MULTI_LINE
:
634 state
->multiLine
= true;
636 case AccessibleStateType::OPAQUE
:
639 case AccessibleStateType::PRESSED
:
640 state
->pressed
= true;
642 case AccessibleStateType::RESIZABLE
:
643 state
->sizeable
= true;
645 case AccessibleStateType::SELECTABLE
:
646 state
->selectable
= true;
648 case AccessibleStateType::SELECTED
:
649 state
->selected
= true;
651 case AccessibleStateType::SENSITIVE
:
654 case AccessibleStateType::SHOWING
:
657 case AccessibleStateType::SINGLE_LINE
:
660 case AccessibleStateType::STALE
:
663 case AccessibleStateType::TRANSIENT
:
666 case AccessibleStateType::VERTICAL
:
669 case AccessibleStateType::VISIBLE
:
670 state
->invisible
= false;
672 case AccessibleStateType::DEFAULT
:
675 case AccessibleStateType::DEFUNC
:
676 state
->invalid
= true;
678 case AccessibleStateType::MULTI_SELECTABLE
:
679 state
->multiSelectable
= true;
682 SAL_WARN("vcl.qt", "Unmapped state: " << nState
);
688 QAccessible::State
QtAccessibleWidget::state() const
690 QAccessible::State state
;
692 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
696 sal_Int64
nStateSet(xAc
->getAccessibleStateSet());
698 for (int i
= 0; i
< 63; ++i
)
700 sal_Int64 nState
= sal_Int64(1) << i
;
701 if (nStateSet
& nState
)
702 lcl_addState(&state
, nState
);
708 QColor
QtAccessibleWidget::foregroundColor() const
710 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
714 Reference
<XAccessibleComponent
> xAccessibleComponent(xAc
, UNO_QUERY
);
715 return toQColor(Color(ColorTransparency
, xAccessibleComponent
->getForeground()));
718 QColor
QtAccessibleWidget::backgroundColor() const
720 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
724 Reference
<XAccessibleComponent
> xAccessibleComponent(xAc
, UNO_QUERY
);
725 return toQColor(Color(ColorTransparency
, xAccessibleComponent
->getBackground()));
728 void* QtAccessibleWidget::interface_cast(QAccessible::InterfaceType t
)
730 if (t
== QAccessible::ActionInterface
&& accessibleProvidesInterface
<XAccessibleAction
>())
731 return static_cast<QAccessibleActionInterface
*>(this);
732 if (t
== QAccessible::TextInterface
&& accessibleProvidesInterface
<XAccessibleText
>())
733 return static_cast<QAccessibleTextInterface
*>(this);
734 if (t
== QAccessible::EditableTextInterface
735 && accessibleProvidesInterface
<XAccessibleEditableText
>())
736 return static_cast<QAccessibleEditableTextInterface
*>(this);
737 if (t
== QAccessible::ValueInterface
&& accessibleProvidesInterface
<XAccessibleValue
>())
738 return static_cast<QAccessibleValueInterface
*>(this);
739 if (t
== QAccessible::TableCellInterface
)
741 // parent must be a table
742 Reference
<XAccessibleTable
> xTable
= getAccessibleTableForParent();
744 return static_cast<QAccessibleTableCellInterface
*>(this);
746 if (t
== QAccessible::TableInterface
&& accessibleProvidesInterface
<XAccessibleTable
>())
747 return static_cast<QAccessibleTableInterface
*>(this);
751 bool QtAccessibleWidget::isValid() const
753 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
757 QObject
* QtAccessibleWidget::object() const { return m_pObject
; }
759 void QtAccessibleWidget::setText(QAccessible::Text
/* t */, const QString
& /* text */) {}
761 QAccessibleInterface
* QtAccessibleWidget::childAt(int x
, int y
) const
763 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
767 Reference
<XAccessibleComponent
> xAccessibleComponent(xAc
, UNO_QUERY
);
768 // convert from screen to local coordinates
769 QPoint aLocalCoords
= QPoint(x
, y
) - rect().topLeft();
770 return QAccessible::queryAccessibleInterface(
771 QtAccessibleRegistry::getQObject(xAccessibleComponent
->getAccessibleAtPoint(
772 awt::Point(aLocalCoords
.x(), aLocalCoords
.y()))));
775 QAccessibleInterface
* QtAccessibleWidget::customFactory(const QString
& classname
, QObject
* object
)
777 if (classname
== QLatin1String("QtWidget") && object
&& object
->isWidgetType())
779 QtWidget
* pWidget
= static_cast<QtWidget
*>(object
);
780 vcl::Window
* pWindow
= pWidget
->frame().GetWindow();
784 css::uno::Reference
<XAccessible
> xAcc
= pWindow
->GetAccessible();
785 // insert into registry so the association between the XAccessible and the QtWidget
786 // is remembered rather than creating a different QtXAccessible when a QObject is needed later
787 QtAccessibleRegistry::insert(xAcc
, object
);
788 return new QtAccessibleWidget(xAcc
, object
);
791 if (classname
== QLatin1String("QtXAccessible") && object
)
793 QtXAccessible
* pXAccessible
= static_cast<QtXAccessible
*>(object
);
794 if (pXAccessible
->m_xAccessible
.is())
796 QtAccessibleWidget
* pRet
= new QtAccessibleWidget(pXAccessible
->m_xAccessible
, object
);
797 // clear the reference in the QtXAccessible, no longer needed now that the QtAccessibleWidget holds one
798 pXAccessible
->m_xAccessible
.clear();
806 // QAccessibleActionInterface
807 QStringList
QtAccessibleWidget::actionNames() const
809 QStringList actionNames
;
810 Reference
<XAccessibleAction
> xAccessibleAction(getAccessibleContextImpl(), UNO_QUERY
);
811 if (!xAccessibleAction
.is())
814 int count
= xAccessibleAction
->getAccessibleActionCount();
815 for (int i
= 0; i
< count
; i
++)
817 OUString desc
= xAccessibleAction
->getAccessibleActionDescription(i
);
818 actionNames
.append(toQString(desc
));
823 void QtAccessibleWidget::doAction(const QString
& actionName
)
825 Reference
<XAccessibleAction
> xAccessibleAction(getAccessibleContextImpl(), UNO_QUERY
);
826 if (!xAccessibleAction
.is())
829 int index
= actionNames().indexOf(actionName
);
832 xAccessibleAction
->doAccessibleAction(index
);
835 QStringList
QtAccessibleWidget::keyBindingsForAction(const QString
& actionName
) const
837 QStringList keyBindings
;
838 Reference
<XAccessibleAction
> xAccessibleAction(getAccessibleContextImpl(), UNO_QUERY
);
839 if (!xAccessibleAction
.is())
842 int index
= actionNames().indexOf(actionName
);
846 Reference
<XAccessibleKeyBinding
> xKeyBinding
847 = xAccessibleAction
->getAccessibleActionKeyBinding(index
);
849 if (!xKeyBinding
.is())
852 int count
= xKeyBinding
->getAccessibleKeyBindingCount();
853 for (int i
= 0; i
< count
; i
++)
855 Sequence
<awt::KeyStroke
> keyStroke
= xKeyBinding
->getAccessibleKeyBinding(i
);
856 keyBindings
.append(toQString(comphelper::GetkeyBindingStrByXkeyBinding(keyStroke
)));
861 // QAccessibleTextInterface
862 void QtAccessibleWidget::addSelection(int /* startOffset */, int /* endOffset */)
864 SAL_INFO("vcl.qt", "Unsupported QAccessibleTextInterface::addSelection");
869 OUString
lcl_convertFontWeight(double fontWeight
)
871 if (fontWeight
== awt::FontWeight::THIN
|| fontWeight
== awt::FontWeight::ULTRALIGHT
)
873 if (fontWeight
== awt::FontWeight::LIGHT
)
875 if (fontWeight
== awt::FontWeight::SEMILIGHT
)
877 if (fontWeight
== awt::FontWeight::NORMAL
)
879 if (fontWeight
== awt::FontWeight::SEMIBOLD
)
881 if (fontWeight
== awt::FontWeight::BOLD
)
883 if (fontWeight
== awt::FontWeight::ULTRABOLD
)
885 if (fontWeight
== awt::FontWeight::BLACK
)
888 // awt::FontWeight::DONTKNOW || fontWeight == awt::FontWeight::NORMAL
892 OUString
lcl_ConvertFontSlant(awt::FontSlant eFontSlant
)
896 case awt::FontSlant::FontSlant_NONE
:
898 case awt::FontSlant::FontSlant_OBLIQUE
:
899 case awt::FontSlant::FontSlant_REVERSE_OBLIQUE
:
901 case awt::FontSlant::FontSlant_ITALIC
:
902 case awt::FontSlant::FontSlant_REVERSE_ITALIC
:
904 case awt::FontSlant::FontSlant_DONTKNOW
:
905 case awt::FontSlant::FontSlant_MAKE_FIXED_SIZE
:
911 // s. https://wiki.linuxfoundation.org/accessibility/iaccessible2/textattributes
913 void lcl_ConvertFontUnderline(sal_Int16 nFontUnderline
, OUString
& rUnderlineStyle
,
914 OUString
& rUnderlineType
, OUString
& rUnderlineWidth
)
916 rUnderlineStyle
= u
"";
917 rUnderlineType
= u
"single";
918 rUnderlineWidth
= u
"auto";
920 switch (nFontUnderline
)
922 case awt::FontUnderline::BOLD
:
923 rUnderlineWidth
= u
"bold";
925 case awt::FontUnderline::BOLDDASH
:
926 rUnderlineWidth
= u
"bold";
927 rUnderlineStyle
= u
"dash";
929 case awt::FontUnderline::BOLDDASHDOT
:
930 rUnderlineWidth
= u
"bold";
931 rUnderlineStyle
= u
"dot-dash";
933 case awt::FontUnderline::BOLDDASHDOTDOT
:
934 rUnderlineWidth
= u
"bold";
935 rUnderlineStyle
= u
"dot-dot-dash";
937 case awt::FontUnderline::BOLDDOTTED
:
938 rUnderlineWidth
= u
"bold";
939 rUnderlineStyle
= u
"dotted";
941 case awt::FontUnderline::BOLDLONGDASH
:
942 rUnderlineWidth
= u
"bold";
943 rUnderlineStyle
= u
"long-dash";
945 case awt::FontUnderline::BOLDWAVE
:
946 rUnderlineWidth
= u
"bold";
947 rUnderlineStyle
= u
"wave";
949 case awt::FontUnderline::DASH
:
950 rUnderlineStyle
= u
"dash";
952 case awt::FontUnderline::DASHDOT
:
953 rUnderlineStyle
= u
"dot-dash";
955 case awt::FontUnderline::DASHDOTDOT
:
956 rUnderlineStyle
= u
"dot-dot-dash";
958 case awt::FontUnderline::DONTKNOW
:
959 rUnderlineWidth
= u
"";
960 rUnderlineStyle
= u
"";
961 rUnderlineType
= u
"";
963 case awt::FontUnderline::DOTTED
:
964 rUnderlineStyle
= u
"dotted";
966 case awt::FontUnderline::DOUBLE
:
967 rUnderlineType
= u
"double";
969 case awt::FontUnderline::DOUBLEWAVE
:
970 rUnderlineStyle
= u
"wave";
971 rUnderlineType
= u
"double";
973 case awt::FontUnderline::LONGDASH
:
974 rUnderlineStyle
= u
"long-dash";
976 case awt::FontUnderline::NONE
:
977 rUnderlineWidth
= u
"none";
978 rUnderlineStyle
= u
"none";
979 rUnderlineType
= u
"none";
981 case awt::FontUnderline::SINGLE
:
982 rUnderlineType
= u
"single";
984 case awt::FontUnderline::SMALLWAVE
:
985 case awt::FontUnderline::WAVE
:
986 rUnderlineStyle
= u
"wave";
989 assert(false && "Unhandled font underline type");
993 /** Converts Color to "rgb(r,g,b)" as specified in https://wiki.linuxfoundation.org/accessibility/iaccessible2/textattributes. */
994 OUString
lcl_ConvertColor(Color aColor
)
996 return u
"rgb(" + OUString::number(aColor
.GetRed()) + u
"," + OUString::number(aColor
.GetGreen())
997 + u
"," + OUString::number(aColor
.GetBlue()) + u
")";
1001 // Text attributes are returned in format specified in IAccessible2 spec, since that
1002 // is what Qt handles:
1003 // https://wiki.linuxfoundation.org/accessibility/iaccessible2/textattributes
1004 QString
QtAccessibleWidget::attributes(int offset
, int* startOffset
, int* endOffset
) const
1006 if (startOffset
== nullptr || endOffset
== nullptr)
1012 Reference
<XAccessibleText
> xText(getAccessibleContextImpl(), UNO_QUERY
);
1016 // handle special values for offset the same way base class's QAccessibleTextWidget::attributes does
1017 // (as defined in IAccessible 2: -1 -> length, -2 -> cursor position)
1019 offset
= cursorPosition();
1021 const int nTextLength
= characterCount();
1022 if (offset
== -1 || offset
== nTextLength
)
1023 offset
= nTextLength
- 1;
1025 if (offset
< 0 || offset
> nTextLength
)
1027 SAL_WARN("vcl.qt", "QtAccessibleWidget::attributes called with invalid offset: " << offset
);
1031 const Sequence
<PropertyValue
> attribs
1032 = xText
->getCharacterAttributes(offset
, Sequence
<OUString
>());
1034 for (PropertyValue
const& prop
: attribs
)
1036 OUString sAttribute
;
1038 if (prop
.Name
== "CharBackColor")
1040 sAttribute
= "background-color";
1041 sValue
= lcl_ConvertColor(
1042 Color(ColorTransparency
, *o3tl::doAccess
<sal_Int32
>(prop
.Value
)));
1044 else if (prop
.Name
== "CharColor")
1046 sAttribute
= "color";
1047 sValue
= lcl_ConvertColor(
1048 Color(ColorTransparency
, *o3tl::doAccess
<sal_Int32
>(prop
.Value
)));
1050 else if (prop
.Name
== "CharFontName")
1052 sAttribute
= "font-family";
1053 sValue
= *o3tl::doAccess
<OUString
>(prop
.Value
);
1055 else if (prop
.Name
== "CharHeight")
1057 sAttribute
= "font-size";
1058 sValue
= OUString::number(*o3tl::doAccess
<double>(prop
.Value
)) + "pt";
1060 else if (prop
.Name
== "CharPosture")
1062 sAttribute
= "font-style";
1063 const awt::FontSlant eFontSlant
= *o3tl::doAccess
<awt::FontSlant
>(prop
.Value
);
1064 sValue
= lcl_ConvertFontSlant(eFontSlant
);
1066 else if (prop
.Name
== "CharUnderline")
1068 OUString sUnderlineStyle
;
1069 OUString sUnderlineType
;
1070 OUString sUnderlineWidth
;
1071 const sal_Int16 nUnderline
= *o3tl::doAccess
<sal_Int16
>(prop
.Value
);
1072 lcl_ConvertFontUnderline(nUnderline
, sUnderlineStyle
, sUnderlineType
, sUnderlineWidth
);
1074 // leave 'sAttribute' and 'sName' empty, set all attributes here
1075 if (!sUnderlineStyle
.isEmpty())
1076 aRet
+= u
"text-underline-style:" + sUnderlineStyle
+ ";";
1077 if (!sUnderlineType
.isEmpty())
1078 aRet
+= u
"text-underline-type:" + sUnderlineType
+ ";";
1079 if (!sUnderlineWidth
.isEmpty())
1080 aRet
+= u
"text-underline-width:" + sUnderlineWidth
+ ";";
1082 else if (prop
.Name
== "CharWeight")
1084 sAttribute
= "font-weight";
1085 sValue
= lcl_convertFontWeight(*o3tl::doAccess
<double>(prop
.Value
));
1088 if (!sAttribute
.isEmpty() && !sValue
.isEmpty())
1089 aRet
+= sAttribute
+ ":" + sValue
+ ";";
1092 accessibility::TextSegment aAttributeRun
1093 = xText
->getTextAtIndex(offset
, accessibility::AccessibleTextType::ATTRIBUTE_RUN
);
1094 *startOffset
= aAttributeRun
.SegmentStart
;
1095 *endOffset
= aAttributeRun
.SegmentEnd
;
1096 return toQString(aRet
);
1099 int QtAccessibleWidget::characterCount() const
1101 Reference
<XAccessibleText
> xText(getAccessibleContextImpl(), UNO_QUERY
);
1103 return xText
->getCharacterCount();
1107 QRect
QtAccessibleWidget::characterRect(int nOffset
) const
1109 Reference
<XAccessibleText
> xText(getAccessibleContextImpl(), UNO_QUERY
);
1113 if (nOffset
< 0 || nOffset
> xText
->getCharacterCount())
1116 "QtAccessibleWidget::characterRect called with invalid offset: " << nOffset
);
1120 const awt::Rectangle aBounds
= xText
->getCharacterBounds(nOffset
);
1121 const QRect
aRect(aBounds
.X
, aBounds
.Y
, aBounds
.Width
, aBounds
.Height
);
1122 // convert to screen coordinates
1123 const QRect aScreenPos
= rect();
1124 return aRect
.translated(aScreenPos
.x(), aScreenPos
.y());
1127 int QtAccessibleWidget::cursorPosition() const
1129 Reference
<XAccessibleText
> xText(getAccessibleContextImpl(), UNO_QUERY
);
1131 return xText
->getCaretPosition();
1135 int QtAccessibleWidget::offsetAtPoint(const QPoint
& rPoint
) const
1137 Reference
<XAccessibleText
> xText(getAccessibleContextImpl(), UNO_QUERY
);
1141 // convert from screen to local coordinates
1142 QPoint aLocalCoords
= rPoint
- rect().topLeft();
1143 awt::Point
aPoint(aLocalCoords
.x(), aLocalCoords
.y());
1144 return xText
->getIndexAtPoint(aPoint
);
1147 void QtAccessibleWidget::removeSelection(int /* selectionIndex */)
1149 SAL_INFO("vcl.qt", "Unsupported QAccessibleTextInterface::removeSelection");
1152 void QtAccessibleWidget::scrollToSubstring(int startIndex
, int endIndex
)
1154 Reference
<XAccessibleText
> xText(getAccessibleContextImpl(), UNO_QUERY
);
1158 sal_Int32 nTextLength
= xText
->getCharacterCount();
1159 if (startIndex
< 0 || startIndex
> nTextLength
|| endIndex
< 0 || endIndex
> nTextLength
)
1161 SAL_WARN("vcl.qt", "QtAccessibleWidget::scrollToSubstring called with invalid offset.");
1165 xText
->scrollSubstringTo(startIndex
, endIndex
, AccessibleScrollType_SCROLL_ANYWHERE
);
1168 void QtAccessibleWidget::selection(int selectionIndex
, int* startOffset
, int* endOffset
) const
1170 if (!startOffset
&& !endOffset
)
1173 Reference
<XAccessibleText
> xText
;
1174 if (selectionIndex
== 0)
1175 xText
= Reference
<XAccessibleText
>(getAccessibleContextImpl(), UNO_QUERY
);
1178 *startOffset
= xText
.is() ? xText
->getSelectionStart() : 0;
1180 *endOffset
= xText
.is() ? xText
->getSelectionEnd() : 0;
1183 int QtAccessibleWidget::selectionCount() const
1185 Reference
<XAccessibleText
> xText(getAccessibleContextImpl(), UNO_QUERY
);
1186 if (xText
.is() && !xText
->getSelectedText().isEmpty())
1187 return 1; // Only 1 selection supported atm
1191 void QtAccessibleWidget::setCursorPosition(int position
)
1193 Reference
<XAccessibleText
> xText(getAccessibleContextImpl(), UNO_QUERY
);
1197 if (position
< 0 || position
> xText
->getCharacterCount())
1200 "QtAccessibleWidget::setCursorPosition called with invalid offset: " << position
);
1204 xText
->setCaretPosition(position
);
1207 void QtAccessibleWidget::setSelection(int /* selectionIndex */, int startOffset
, int endOffset
)
1209 Reference
<XAccessibleText
> xText(getAccessibleContextImpl(), UNO_QUERY
);
1213 sal_Int32 nTextLength
= xText
->getCharacterCount();
1214 if (startOffset
< 0 || startOffset
> nTextLength
|| endOffset
< 0 || endOffset
> nTextLength
)
1216 SAL_WARN("vcl.qt", "QtAccessibleWidget::setSelection called with invalid offset.");
1220 xText
->setSelection(startOffset
, endOffset
);
1223 QString
QtAccessibleWidget::text(int startOffset
, int endOffset
) const
1225 Reference
<XAccessibleText
> xText(getAccessibleContextImpl(), UNO_QUERY
);
1229 sal_Int32 nTextLength
= xText
->getCharacterCount();
1230 if (startOffset
< 0 || startOffset
> nTextLength
|| endOffset
< 0 || endOffset
> nTextLength
)
1232 SAL_WARN("vcl.qt", "QtAccessibleWidget::text called with invalid offset.");
1236 return toQString(xText
->getTextRange(startOffset
, endOffset
));
1239 QString
QtAccessibleWidget::textAfterOffset(int nOffset
,
1240 QAccessible::TextBoundaryType eBoundaryType
,
1241 int* pStartOffset
, int* pEndOffset
) const
1243 if (pStartOffset
== nullptr || pEndOffset
== nullptr)
1249 Reference
<XAccessibleText
> xText(getAccessibleContextImpl(), UNO_QUERY
);
1253 const int nCharCount
= characterCount();
1254 // -1 is special value for text length
1256 nOffset
= nCharCount
;
1257 else if (nOffset
< -1 || nOffset
> nCharCount
)
1260 "QtAccessibleWidget::textAfterOffset called with invalid offset: " << nOffset
);
1264 if (eBoundaryType
== QAccessible::NoBoundary
)
1266 if (nOffset
== nCharCount
)
1268 *pStartOffset
= nOffset
+ 1;
1269 *pEndOffset
= nCharCount
;
1270 return text(nOffset
+ 1, nCharCount
);
1273 sal_Int16 nUnoBoundaryType
= lcl_matchQtTextBoundaryType(eBoundaryType
);
1274 assert(nUnoBoundaryType
> 0);
1275 const TextSegment aSegment
= xText
->getTextBehindIndex(nOffset
, nUnoBoundaryType
);
1276 *pStartOffset
= aSegment
.SegmentStart
;
1277 *pEndOffset
= aSegment
.SegmentEnd
;
1278 return toQString(aSegment
.SegmentText
);
1281 QString
QtAccessibleWidget::textAtOffset(int offset
, QAccessible::TextBoundaryType boundaryType
,
1282 int* startOffset
, int* endOffset
) const
1284 if (startOffset
== nullptr || endOffset
== nullptr)
1287 const int nCharCount
= characterCount();
1288 if (boundaryType
== QAccessible::NoBoundary
)
1291 *endOffset
= nCharCount
;
1292 return text(0, nCharCount
);
1295 Reference
<XAccessibleText
> xText(getAccessibleContextImpl(), UNO_QUERY
);
1299 sal_Int16 nUnoBoundaryType
= lcl_matchQtTextBoundaryType(boundaryType
);
1300 assert(nUnoBoundaryType
> 0);
1302 // special value of -1 for offset means text length
1304 offset
= nCharCount
;
1306 if (offset
< 0 || offset
> nCharCount
)
1309 "QtAccessibleWidget::textAtOffset called with invalid offset: " << offset
);
1313 const TextSegment segment
= xText
->getTextAtIndex(offset
, nUnoBoundaryType
);
1314 *startOffset
= segment
.SegmentStart
;
1315 *endOffset
= segment
.SegmentEnd
;
1316 return toQString(segment
.SegmentText
);
1319 QString
QtAccessibleWidget::textBeforeOffset(int nOffset
,
1320 QAccessible::TextBoundaryType eBoundaryType
,
1321 int* pStartOffset
, int* pEndOffset
) const
1323 if (pStartOffset
== nullptr || pEndOffset
== nullptr)
1329 Reference
<XAccessibleText
> xText(getAccessibleContextImpl(), UNO_QUERY
);
1333 const int nCharCount
= characterCount();
1334 // -1 is special value for text length
1336 nOffset
= nCharCount
;
1337 else if (nOffset
< -1 || nOffset
> nCharCount
)
1340 "QtAccessibleWidget::textBeforeOffset called with invalid offset: " << nOffset
);
1344 if (eBoundaryType
== QAccessible::NoBoundary
)
1347 *pEndOffset
= nOffset
;
1348 return text(0, nOffset
);
1351 sal_Int16 nUnoBoundaryType
= lcl_matchQtTextBoundaryType(eBoundaryType
);
1352 assert(nUnoBoundaryType
> 0);
1353 const TextSegment aSegment
= xText
->getTextBeforeIndex(nOffset
, nUnoBoundaryType
);
1354 *pStartOffset
= aSegment
.SegmentStart
;
1355 *pEndOffset
= aSegment
.SegmentEnd
;
1356 return toQString(aSegment
.SegmentText
);
1359 // QAccessibleEditableTextInterface
1361 void QtAccessibleWidget::deleteText(int startOffset
, int endOffset
)
1363 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1367 Reference
<XAccessibleEditableText
> xEditableText(xAc
, UNO_QUERY
);
1368 if (!xEditableText
.is())
1371 sal_Int32 nTextLength
= xEditableText
->getCharacterCount();
1372 if (startOffset
< 0 || startOffset
> nTextLength
|| endOffset
< 0 || endOffset
> nTextLength
)
1374 SAL_WARN("vcl.qt", "QtAccessibleWidget::deleteText called with invalid offset.");
1378 xEditableText
->deleteText(startOffset
, endOffset
);
1381 void QtAccessibleWidget::insertText(int offset
, const QString
& text
)
1383 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1387 Reference
<XAccessibleEditableText
> xEditableText(xAc
, UNO_QUERY
);
1388 if (!xEditableText
.is())
1391 if (offset
< 0 || offset
> xEditableText
->getCharacterCount())
1393 SAL_WARN("vcl.qt", "QtAccessibleWidget::insertText called with invalid offset: " << offset
);
1397 xEditableText
->insertText(toOUString(text
), offset
);
1400 void QtAccessibleWidget::replaceText(int startOffset
, int endOffset
, const QString
& text
)
1402 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1406 Reference
<XAccessibleEditableText
> xEditableText(xAc
, UNO_QUERY
);
1407 if (!xEditableText
.is())
1410 sal_Int32 nTextLength
= xEditableText
->getCharacterCount();
1411 if (startOffset
< 0 || startOffset
> nTextLength
|| endOffset
< 0 || endOffset
> nTextLength
)
1413 SAL_WARN("vcl.qt", "QtAccessibleWidget::replaceText called with invalid offset.");
1417 xEditableText
->replaceText(startOffset
, endOffset
, toOUString(text
));
1420 // QAccessibleValueInterface
1421 QVariant
QtAccessibleWidget::currentValue() const
1423 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1427 Reference
<XAccessibleValue
> xValue(xAc
, UNO_QUERY
);
1431 xValue
->getCurrentValue() >>= aDouble
;
1432 return QVariant(aDouble
);
1435 QVariant
QtAccessibleWidget::maximumValue() const
1437 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1441 Reference
<XAccessibleValue
> xValue(xAc
, UNO_QUERY
);
1445 xValue
->getMaximumValue() >>= aDouble
;
1446 return QVariant(aDouble
);
1449 QVariant
QtAccessibleWidget::minimumStepSize() const
1451 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1455 Reference
<XAccessibleValue
> xValue(xAc
, UNO_QUERY
);
1458 double dMinStep
= 0;
1459 xValue
->getMinimumIncrement() >>= dMinStep
;
1460 return QVariant(dMinStep
);
1463 QVariant
QtAccessibleWidget::minimumValue() const
1465 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1469 Reference
<XAccessibleValue
> xValue(xAc
, UNO_QUERY
);
1473 xValue
->getMinimumValue() >>= aDouble
;
1474 return QVariant(aDouble
);
1477 void QtAccessibleWidget::setCurrentValue(const QVariant
& value
)
1479 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1483 Reference
<XAccessibleValue
> xValue(xAc
, UNO_QUERY
);
1486 xValue
->setCurrentValue(Any(value
.toDouble()));
1489 // QAccessibleTableInterface
1490 QAccessibleInterface
* QtAccessibleWidget::caption() const
1492 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1496 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1499 return QAccessible::queryAccessibleInterface(
1500 QtAccessibleRegistry::getQObject(xTable
->getAccessibleCaption()));
1503 QAccessibleInterface
* QtAccessibleWidget::cellAt(int row
, int column
) const
1505 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1509 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1513 if (row
< 0 || row
>= xTable
->getAccessibleRowCount() || column
< 0
1514 || column
>= xTable
->getAccessibleColumnCount())
1516 SAL_WARN("vcl.qt", "QtAccessibleWidget::cellAt called with invalid row/column index ("
1517 << row
<< ", " << column
<< ")");
1521 return QAccessible::queryAccessibleInterface(
1522 QtAccessibleRegistry::getQObject(xTable
->getAccessibleCellAt(row
, column
)));
1525 int QtAccessibleWidget::columnCount() const
1527 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1531 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1534 return xTable
->getAccessibleColumnCount();
1537 QString
QtAccessibleWidget::columnDescription(int column
) const
1539 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1543 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1546 return toQString(xTable
->getAccessibleColumnDescription(column
));
1549 bool QtAccessibleWidget::isColumnSelected(int nColumn
) const
1551 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1555 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1559 if (nColumn
< 0 || nColumn
>= xTable
->getAccessibleColumnCount())
1561 SAL_WARN("vcl.qt", "QtAccessibleWidget::isColumnSelected called with invalid column index "
1566 return xTable
->isAccessibleColumnSelected(nColumn
);
1569 bool QtAccessibleWidget::isRowSelected(int nRow
) const
1571 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1575 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1579 if (nRow
< 0 || nRow
>= xTable
->getAccessibleRowCount())
1582 "QtAccessibleWidget::isRowSelected called with invalid row index " << nRow
);
1586 return xTable
->isAccessibleRowSelected(nRow
);
1589 void QtAccessibleWidget::modelChange(QAccessibleTableModelChangeEvent
*) {}
1591 int QtAccessibleWidget::rowCount() const
1593 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1597 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1600 return xTable
->getAccessibleRowCount();
1603 QString
QtAccessibleWidget::rowDescription(int row
) const
1605 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1609 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1612 return toQString(xTable
->getAccessibleRowDescription(row
));
1615 bool QtAccessibleWidget::selectColumn(int column
)
1617 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1621 if (column
< 0 || column
>= columnCount())
1624 "QtAccessibleWidget::selectColumn called with invalid column index " << column
);
1628 Reference
<XAccessibleTableSelection
> xTableSelection(xAc
, UNO_QUERY
);
1629 if (!xTableSelection
.is())
1631 return xTableSelection
->selectColumn(column
);
1634 bool QtAccessibleWidget::selectRow(int row
)
1636 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1640 if (row
< 0 || row
>= rowCount())
1642 SAL_WARN("vcl.qt", "QtAccessibleWidget::selectRow called with invalid row index " << row
);
1646 Reference
<XAccessibleTableSelection
> xTableSelection(xAc
, UNO_QUERY
);
1647 if (!xTableSelection
.is())
1649 return xTableSelection
->selectRow(row
);
1652 int QtAccessibleWidget::selectedCellCount() const
1654 Reference
<XAccessibleContext
> xAcc
= getAccessibleContextImpl();
1658 Reference
<XAccessibleSelection
> xSelection(xAcc
, UNO_QUERY
);
1659 if (!xSelection
.is())
1662 sal_Int64 nSelected
= xSelection
->getSelectedAccessibleChildCount();
1663 if (nSelected
> std::numeric_limits
<int>::max())
1666 "QtAccessibleWidget::selectedCellCount: Cell count exceeds maximum int value, "
1668 nSelected
= std::numeric_limits
<int>::max();
1673 QList
<QAccessibleInterface
*> QtAccessibleWidget::selectedCells() const
1675 Reference
<XAccessibleContext
> xAcc
= getAccessibleContextImpl();
1677 return QList
<QAccessibleInterface
*>();
1679 Reference
<XAccessibleSelection
> xSelection(xAcc
, UNO_QUERY
);
1680 if (!xSelection
.is())
1681 return QList
<QAccessibleInterface
*>();
1683 QList
<QAccessibleInterface
*> aSelectedCells
;
1684 sal_Int64 nSelected
= xSelection
->getSelectedAccessibleChildCount();
1685 if (nSelected
> std::numeric_limits
<int>::max())
1688 "QtAccessibleWidget::selectedCells: Cell count exceeds maximum int value, "
1690 nSelected
= std::numeric_limits
<int>::max();
1692 for (sal_Int64 i
= 0; i
< nSelected
; i
++)
1694 Reference
<XAccessible
> xChild
= xSelection
->getSelectedAccessibleChild(i
);
1695 QAccessibleInterface
* pInterface
1696 = QAccessible::queryAccessibleInterface(QtAccessibleRegistry::getQObject(xChild
));
1697 aSelectedCells
.push_back(pInterface
);
1699 return aSelectedCells
;
1702 int QtAccessibleWidget::selectedColumnCount() const
1704 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1708 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1711 return xTable
->getSelectedAccessibleColumns().getLength();
1714 QList
<int> QtAccessibleWidget::selectedColumns() const
1716 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1718 return QList
<int>();
1720 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1722 return QList
<int>();
1723 return toQList(xTable
->getSelectedAccessibleColumns());
1726 int QtAccessibleWidget::selectedRowCount() const
1728 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1732 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1735 return xTable
->getSelectedAccessibleRows().getLength();
1738 QList
<int> QtAccessibleWidget::selectedRows() const
1740 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1742 return QList
<int>();
1744 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1746 return QList
<int>();
1747 return toQList(xTable
->getSelectedAccessibleRows());
1750 QAccessibleInterface
* QtAccessibleWidget::summary() const
1752 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1756 Reference
<XAccessibleTable
> xTable(xAc
, UNO_QUERY
);
1759 return QAccessible::queryAccessibleInterface(
1760 QtAccessibleRegistry::getQObject(xTable
->getAccessibleSummary()));
1763 bool QtAccessibleWidget::unselectColumn(int column
)
1765 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1769 Reference
<XAccessibleTableSelection
> xTableSelection(xAc
, UNO_QUERY
);
1770 if (!xTableSelection
.is())
1772 return xTableSelection
->unselectColumn(column
);
1775 bool QtAccessibleWidget::unselectRow(int row
)
1777 Reference
<XAccessibleContext
> xAc
= getAccessibleContextImpl();
1781 Reference
<XAccessibleTableSelection
> xTableSelection(xAc
, UNO_QUERY
);
1782 if (!xTableSelection
.is())
1784 return xTableSelection
->unselectRow(row
);
1787 // QAccessibleTableCellInterface
1788 QList
<QAccessibleInterface
*> QtAccessibleWidget::columnHeaderCells() const
1790 Reference
<XAccessibleTable
> xTable
= getAccessibleTableForParent();
1792 return QList
<QAccessibleInterface
*>();
1794 Reference
<XAccessibleTable
> xHeaders
= xTable
->getAccessibleColumnHeaders();
1796 return QList
<QAccessibleInterface
*>();
1798 const sal_Int32 nCol
= columnIndex();
1799 QList
<QAccessibleInterface
*> aHeaderCells
;
1800 for (sal_Int32 nRow
= 0; nRow
< xHeaders
->getAccessibleRowCount(); nRow
++)
1802 Reference
<XAccessible
> xCell
= xHeaders
->getAccessibleCellAt(nRow
, nCol
);
1803 QAccessibleInterface
* pInterface
1804 = QAccessible::queryAccessibleInterface(QtAccessibleRegistry::getQObject(xCell
));
1805 aHeaderCells
.push_back(pInterface
);
1807 return aHeaderCells
;
1810 int QtAccessibleWidget::columnIndex() const
1812 Reference
<XAccessibleContext
> xAcc
= getAccessibleContextImpl();
1816 Reference
<XAccessibleTable
> xTable
= getAccessibleTableForParent();
1820 const sal_Int64 nIndexInParent
= xAcc
->getAccessibleIndexInParent();
1821 return xTable
->getAccessibleColumn(nIndexInParent
);
1824 bool QtAccessibleWidget::isSelected() const
1826 Reference
<XAccessibleContext
> xAcc
= getAccessibleContextImpl();
1830 Reference
<XAccessibleTable
> xTable
= getAccessibleTableForParent();
1834 const sal_Int32 nColumn
= columnIndex();
1835 const sal_Int32 nRow
= rowIndex();
1836 return xTable
->isAccessibleSelected(nRow
, nColumn
);
1839 int QtAccessibleWidget::columnExtent() const
1841 Reference
<XAccessibleContext
> xAcc
= getAccessibleContextImpl();
1845 Reference
<XAccessibleTable
> xTable
= getAccessibleTableForParent();
1849 const sal_Int32 nColumn
= columnIndex();
1850 const sal_Int32 nRow
= rowIndex();
1851 return xTable
->getAccessibleColumnExtentAt(nRow
, nColumn
);
1854 QList
<QAccessibleInterface
*> QtAccessibleWidget::rowHeaderCells() const
1856 Reference
<XAccessibleTable
> xTable
= getAccessibleTableForParent();
1858 return QList
<QAccessibleInterface
*>();
1860 Reference
<XAccessibleTable
> xHeaders
= xTable
->getAccessibleRowHeaders();
1862 return QList
<QAccessibleInterface
*>();
1864 const sal_Int32 nRow
= rowIndex();
1865 QList
<QAccessibleInterface
*> aHeaderCells
;
1866 for (sal_Int32 nCol
= 0; nCol
< xHeaders
->getAccessibleColumnCount(); nCol
++)
1868 Reference
<XAccessible
> xCell
= xHeaders
->getAccessibleCellAt(nRow
, nCol
);
1869 QAccessibleInterface
* pInterface
1870 = QAccessible::queryAccessibleInterface(QtAccessibleRegistry::getQObject(xCell
));
1871 aHeaderCells
.push_back(pInterface
);
1873 return aHeaderCells
;
1876 int QtAccessibleWidget::rowExtent() const
1878 Reference
<XAccessibleContext
> xAcc
= getAccessibleContextImpl();
1882 Reference
<XAccessibleTable
> xTable
= getAccessibleTableForParent();
1886 const sal_Int32 nColumn
= columnIndex();
1887 const sal_Int32 nRow
= rowIndex();
1888 return xTable
->getAccessibleRowExtentAt(nRow
, nColumn
);
1891 int QtAccessibleWidget::rowIndex() const
1893 Reference
<XAccessibleContext
> xAcc
= getAccessibleContextImpl();
1897 Reference
<XAccessibleTable
> xTable
= getAccessibleTableForParent();
1901 const sal_Int64 nIndexInParent
= xAcc
->getAccessibleIndexInParent();
1902 return xTable
->getAccessibleRow(nIndexInParent
);
1905 QAccessibleInterface
* QtAccessibleWidget::table() const
1907 Reference
<XAccessibleTable
> xTable
= getAccessibleTableForParent();
1911 Reference
<XAccessible
> xTableAcc(xTable
, UNO_QUERY
);
1912 if (!xTableAcc
.is())
1915 return QAccessible::queryAccessibleInterface(QtAccessibleRegistry::getQObject(xTableAcc
));
1918 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */