Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/LibreOffice/vcl/qt5/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 65 kB image not shown  

Quelle  QtAccessibleWidget.cxx   Sprache: C

 
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */


#include <QtAccessibleWidget.hxx>
#include <QtAccessibleWidget.moc>

#include <QtGui/QAccessibleInterface>

#include <QtAccessibleEventListener.hxx>
#include <QtAccessibleRegistry.hxx>
#include <QtFrame.hxx>
#include <QtTools.hxx>
#include <QtWidget.hxx>
#include <QtXAccessible.hxx>

#include <com/sun/star/accessibility/AccessibleRelationType.hpp>
#include <com/sun/star/accessibility/AccessibleRole.hpp>
#include <com/sun/star/accessibility/AccessibleScrollType.hpp>
#include <com/sun/star/accessibility/AccessibleStateType.hpp>
#include <com/sun/star/accessibility/AccessibleTextType.hpp>
#include <com/sun/star/accessibility/XAccessible.hpp>
#include <com/sun/star/accessibility/XAccessibleAction.hpp>
#include <com/sun/star/accessibility/XAccessibleComponent.hpp>
#include <com/sun/star/accessibility/XAccessibleContext.hpp>
#include <com/sun/star/accessibility/XAccessibleContext2.hpp>
#include <com/sun/star/accessibility/XAccessibleEditableText.hpp>
#include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp>
#include <com/sun/star/accessibility/XAccessibleEventListener.hpp>
#include <com/sun/star/accessibility/XAccessibleExtendedAttributes.hpp>
#include <com/sun/star/accessibility/XAccessibleKeyBinding.hpp>
#include <com/sun/star/accessibility/XAccessibleRelationSet.hpp>
#include <com/sun/star/accessibility/XAccessibleSelection.hpp>
#include <com/sun/star/accessibility/XAccessibleTable.hpp>
#include <com/sun/star/accessibility/XAccessibleTableSelection.hpp>
#include <com/sun/star/accessibility/XAccessibleText.hpp>
#include <com/sun/star/accessibility/XAccessibleValue.hpp>
#include <com/sun/star/lang/DisposedException.hpp>
#include <com/sun/star/uno/Sequence.hxx>

#include <comphelper/AccessibleImplementationHelper.hxx>
#include <sal/log.hxx>
#include <vcl/accessibility/AccessibleTextAttributeHelper.hxx>
#include <vcl/qt/QtUtils.hxx>

using namespace css;
using namespace css::accessibility;
using namespace css::uno;

// property used to specify the QtAccessibleWidget* that should be used as the
// custom accessible interface for an object
const charconst PROPERTY_ACCESSIBLE = "accessible-interface";

QtAccessibleWidget::QtAccessibleWidget(const Reference<XAccessible>& xAccessible, QObject& rObject)
    : m_xAccessible(xAccessible)
    , m_rObject(rObject)
{
    Reference<XAccessibleContext> xContext = xAccessible->getAccessibleContext();
    Reference<XAccessibleEventBroadcaster> xBroadcaster(xContext, UNO_QUERY);
    if (xBroadcaster.is())
    {
        Reference<XAccessibleEventListener> xListener(new QtAccessibleEventListener(this));
        xBroadcaster->addAccessibleEventListener(xListener);
    }
}

void QtAccessibleWidget::invalidate()
{
    QtAccessibleRegistry::remove(m_xAccessible);
    m_xAccessible.clear();
}

Reference<XAccessibleContext> QtAccessibleWidget::getAccessibleContextImpl() const
{
    Reference<XAccessibleContext> xAc;

    if (m_xAccessible.is())
    {
        try
        {
            xAc = m_xAccessible->getAccessibleContext();
        }
        catch (css::lang::DisposedException /*ex*/)
        {
            SAL_WARN("vcl.qt""Accessible context disposed already");
        }
        // sometimes getAccessibleContext throws also RuntimeException if context is no longer alive
        catch (css::uno::RuntimeException /*ex*/)
        {
            // so let's catch it here, cuz otherwise soffice falls flat on its face
            // with FatalError and nothing else
            SAL_WARN("vcl.qt""Accessible context no longer alive");
        }
    }

    return xAc;
}

css::uno::Reference<css::accessibility::XAccessibleTable>
QtAccessibleWidget::getAccessibleTableForParent() const
{
    Reference<XAccessibleContext> xAcc = getAccessibleContextImpl();
    if (!xAcc.is())
        return nullptr;

    Reference<XAccessible> xParent = xAcc->getAccessibleParent();
    if (!xParent.is())
        return nullptr;

    Reference<XAccessibleContext> xParentContext = xParent->getAccessibleContext();
    if (!xParentContext.is())
        return nullptr;

    return Reference<XAccessibleTable>(xParentContext, UNO_QUERY);
}

QWindow* QtAccessibleWidget::window() const
{
    if (m_rObject.isWidgetType())
    {
        QWidget& rWidget = static_cast<QWidget&>(m_rObject);
        QWidget* pWindow = rWidget.window();
        if (pWindow)
            return pWindow->windowHandle();
    }

    QAccessibleInterface* pParent = parent();
    if (pParent)
        return pParent->window();

    return nullptr;
}

int QtAccessibleWidget::childCount() const
{
    Reference<XAccessibleContext> xAc = getAccessibleContextImpl();
    if (!xAc.is())
        return 0;

    sal_Int64 nChildCount = xAc->getAccessibleChildCount();
    if (nChildCount > std::numeric_limits<int>::max())
    {
        SAL_WARN("vcl.qt""QtAccessibleWidget::childCount: Child count exceeds maximum int value, "
                           "returning max int.");
        nChildCount = std::numeric_limits<int>::max();
    }

    return nChildCount;
}

int QtAccessibleWidget::indexOfChild(const QAccessibleInterface* pChild) const
{
    const QtAccessibleWidget* pAccessibleWidget = dynamic_cast<const QtAccessibleWidget*>(pChild);
    if (!pAccessibleWidget)
    {
        SAL_WARN(
            "vcl.qt",
            "QtAccessibleWidget::indexOfChild called with child that is no QtAccessibleWidget");
        return -1;
    }

    Reference<XAccessibleContext> xContext = pAccessibleWidget->getAccessibleContextImpl();
    if (!xContext.is())
        return -1;

    sal_Int64 nChildIndex = xContext->getAccessibleIndexInParent();
    if (nChildIndex > std::numeric_limits<int>::max())
    {
        // use -2 when the child index is too large to fit into 32 bit to neither use the
        // valid index of another child nor -1, which would e.g. make the Orca screen reader
        // interpret the object as being a zombie
        SAL_WARN("vcl.qt",
                 "QtAccessibleWidget::indexOfChild: Child index exceeds maximum int value, "
                 "returning -2.");
        nChildIndex = -2;
    }
    return nChildIndex;
}

namespace
{
sal_Int16 lcl_matchQtTextBoundaryType(QAccessible::TextBoundaryType boundaryType)
{
    switch (boundaryType)
    {
        case QAccessible::CharBoundary:
            return css::accessibility::AccessibleTextType::CHARACTER;
        case QAccessible::WordBoundary:
            return css::accessibility::AccessibleTextType::WORD;
        case QAccessible::SentenceBoundary:
            return css::accessibility::AccessibleTextType::SENTENCE;
        case QAccessible::ParagraphBoundary:
            return css::accessibility::AccessibleTextType::PARAGRAPH;
        case QAccessible::LineBoundary:
            return css::accessibility::AccessibleTextType::LINE;
        case QAccessible::NoBoundary:
            // assert here, better handle it directly at call site
            assert(false
                   && "No match for QAccessible::NoBoundary, handle it separately at call site.");
            break;
        default:
            break;
    }

    SAL_WARN("vcl.qt""Unmatched text boundary type: " << boundaryType);
    return -1;
}

QAccessible::Relation lcl_matchUnoRelation(AccessibleRelationType eRelationType)
{
    // Qt semantics is the other way around
    switch (eRelationType)
    {
#if QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)
        case AccessibleRelationType_CONTENT_FLOWS_FROM:
            return QAccessible::FlowsTo;
        case AccessibleRelationType_CONTENT_FLOWS_TO:
            return QAccessible::FlowsFrom;
#endif
        case AccessibleRelationType_CONTROLLED_BY:
            return QAccessible::Controller;
        case AccessibleRelationType_CONTROLLER_FOR:
            return QAccessible::Controlled;
#if QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)
        case AccessibleRelationType_DESCRIBED_BY:
            return QAccessible::DescriptionFor;
#endif
        case AccessibleRelationType_LABELED_BY:
            return QAccessible::Label;
        case AccessibleRelationType_LABEL_FOR:
            return QAccessible::Labelled;
        case AccessibleRelationType_INVALID:
        case AccessibleRelationType_MEMBER_OF:
        case AccessibleRelationType_SUB_WINDOW_OF:
        case AccessibleRelationType_NODE_CHILD_OF:
        default:
            SAL_WARN("vcl.qt""Unmatched relation: " << static_cast<int>(eRelationType));
            return {};
    }
}

void lcl_appendRelation(QVector<QPair<QAccessibleInterface*, QAccessible::Relation>>* relations,
                        AccessibleRelation aRelation, QAccessible::Relation match)
{
    QAccessible::Relation aQRelation = lcl_matchUnoRelation(aRelation.RelationType);
    // skip in case there's no Qt relation matching the filter
    if (!(aQRelation & match))
        return;

    sal_uInt32 nTargetCount = aRelation.TargetSet.getLength();

    for (sal_uInt32 i = 0; i < nTargetCount; i++)
    {
        Reference<XAccessible> xAccessible = aRelation.TargetSet[i];
        relations->append(
            { QAccessible::queryAccessibleInterface(QtAccessibleRegistry::getQObject(xAccessible)),
              aQRelation });
    }
}
}

QVector<QPair<QAccessibleInterface*, QAccessible::Relation>>
QtAccessibleWidget::relations(QAccessible::Relation match) const
{
    QVector<QPair<QAccessibleInterface*, QAccessible::Relation>> relations;

    Reference<XAccessibleContext> xAc = getAccessibleContextImpl();
    if (!xAc.is())
        return relations;

    Reference<XAccessibleRelationSet> xRelationSet = xAc->getAccessibleRelationSet();
    if (xRelationSet.is())
    {
        int count = xRelationSet->getRelationCount();
        for (int i = 0; i < count; i++)
        {
            AccessibleRelation aRelation = xRelationSet->getRelation(i);
            lcl_appendRelation(&relations, aRelation, match);
        }
    }

    return relations;
}

QAccessibleInterface* QtAccessibleWidget::focusChild() const
{
    /* if (m_pWindow->HasChildPathFocus())
        return QAccessible::queryAccessibleInterface(
            new QtXAccessible(m_xAccessible->getAccessibleContext()->getAccessibleChild(index))); */

    return QAccessible::queryAccessibleInterface(object());
}

QRect QtAccessibleWidget::rect() const
{
    Reference<XAccessibleContext> xAc = getAccessibleContextImpl();
    if (!xAc.is())
        return QRect();

    Reference<XAccessibleComponent> xAccessibleComponent(xAc, UNO_QUERY);
    awt::Point aPoint = xAccessibleComponent->getLocationOnScreen();
    awt::Size aSize = xAccessibleComponent->getSize();

    return QRect(aPoint.X, aPoint.Y, aSize.Width, aSize.Height);
}

QAccessibleInterface* QtAccessibleWidget::parent() const
{
    Reference<XAccessibleContext> xAc = getAccessibleContextImpl();
    if (!xAc.is())
        return nullptr;

    if (xAc->getAccessibleParent().is())
        return QAccessible::queryAccessibleInterface(
            QtAccessibleRegistry::getQObject(xAc->getAccessibleParent()));

    // go via the QObject hierarchy; a11y objects like the application object
    // and native weld::Widgets are handled solely by Qt and have
    // no LO-internal a11y objects associated with them
    QObject* pObj = object();
    if (pObj && pObj->parent())
        return QAccessible::queryAccessibleInterface(pObj->parent());

    // return app as parent for top-level objects
    return QAccessible::queryAccessibleInterface(qApp);
}

QAccessibleInterface* QtAccessibleWidget::child(int index) const
{
    Reference<XAccessibleContext> xAc = getAccessibleContextImpl();
    if (!xAc.is())
        return nullptr;

    if (index < 0 || index >= xAc->getAccessibleChildCount())
    {
        SAL_WARN("vcl.qt""QtAccessibleWidget::child called with invalid index: " << index);
        return nullptr;
    }

    return QAccessible::queryAccessibleInterface(
        QtAccessibleRegistry::getQObject(xAc->getAccessibleChild(index)));
}

QString QtAccessibleWidget::text(QAccessible::Text text) const
{
    Reference<XAccessibleContext> xAc = getAccessibleContextImpl();
    if (!xAc.is())
        return QString();

    switch (text)
    {
        case QAccessible::Name:
            return toQString(xAc->getAccessibleName());
        case QAccessible::Description:
        case QAccessible::DebugDescription:
            return toQString(xAc->getAccessibleDescription());
#if QT_VERSION >= QT_VERSION_CHECK(6, 8, 0)
        case QAccessible::Identifier:
        {
            Reference<XAccessibleContext2> xContext(getAccessibleContextImpl(), UNO_QUERY);
            if (!xContext.is())
                return QString();
            return toQString(xContext->getAccessibleId());
        }
#endif
        case QAccessible::Value:
        case QAccessible::Help:
        case QAccessible::Accelerator:
        case QAccessible::UserText:
        default:
            return QString();
    }
}
QAccessible::Role QtAccessibleWidget::role() const
{
    Reference<XAccessibleContext> xAc = getAccessibleContextImpl();
    if (!xAc.is())
        return QAccessible::NoRole;

    switch (xAc->getAccessibleRole())
    {
        case AccessibleRole::UNKNOWN:
            return QAccessible::NoRole;
        case AccessibleRole::ALERT:
            return QAccessible::AlertMessage;
        case AccessibleRole::BLOCK_QUOTE:
#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0)
            return QAccessible::BlockQuote;
#else
            return QAccessible::Paragraph;
#endif
        case AccessibleRole::COLUMN_HEADER:
            return QAccessible::ColumnHeader;
        case AccessibleRole::CANVAS:
            return QAccessible::Canvas;
        case AccessibleRole::CHECK_BOX:
            return QAccessible::CheckBox;
        case AccessibleRole::CHECK_MENU_ITEM:
            return QAccessible::MenuItem;
        case AccessibleRole::COLOR_CHOOSER:
            return QAccessible::ColorChooser;
        case AccessibleRole::COMBO_BOX:
            return QAccessible::ComboBox;
        case AccessibleRole::DATE_EDITOR:
            return QAccessible::EditableText;
        case AccessibleRole::DESKTOP_ICON:
            return QAccessible::Graphic;
        case AccessibleRole::DESKTOP_PANE:
        case AccessibleRole::DIRECTORY_PANE:
            return QAccessible::Pane;
        case AccessibleRole::DIALOG:
            return QAccessible::Dialog;
        case AccessibleRole::DOCUMENT:
            return QAccessible::Document;
        case AccessibleRole::EMBEDDED_OBJECT:
            return QAccessible::UserRole;
        case AccessibleRole::END_NOTE:
            return QAccessible::Note;
        case AccessibleRole::FILE_CHOOSER:
            return QAccessible::Dialog;
        case AccessibleRole::FILLER:
            return QAccessible::Whitespace;
        case AccessibleRole::FONT_CHOOSER:
            return QAccessible::UserRole;
        case AccessibleRole::FOOTER:
            return QAccessible::Footer;
        case AccessibleRole::FOOTNOTE:
            return QAccessible::Note;
        case AccessibleRole::FRAME:
            // report Pane instead of Window role for a frame that's not actually
            // an accessible frame (top-level window with title bar) itself,
            // but a child of the real top-level
            if (QAccessibleInterface* pParent = parent())
            {
                const QAccessible::Role eParentRole = pParent->role();
                if (eParentRole == QAccessible::Window || eParentRole == QAccessible::Dialog)
                    return QAccessible::Pane;
            }
            return QAccessible::Window;
        case AccessibleRole::GLASS_PANE:
            return QAccessible::UserRole;
        case AccessibleRole::GRAPHIC:
            return QAccessible::Graphic;
        case AccessibleRole::GROUP_BOX:
            return QAccessible::Grouping;
        case AccessibleRole::HEADER:
            return QAccessible::UserRole;
        case AccessibleRole::HEADING:
            return QAccessible::Heading;
        case AccessibleRole::HYPER_LINK:
            return QAccessible::Link;
        case AccessibleRole::ICON:
            return QAccessible::Graphic;
        case AccessibleRole::INTERNAL_FRAME:
            return QAccessible::UserRole;
        case AccessibleRole::LABEL:
            return QAccessible::StaticText;
        case AccessibleRole::LAYERED_PANE:
            return QAccessible::Pane;
        case AccessibleRole::LIST:
            return QAccessible::List;
        case AccessibleRole::LIST_ITEM:
            return QAccessible::ListItem;
        case AccessibleRole::MENU:
        case AccessibleRole::MENU_BAR:
            return QAccessible::MenuBar;
        case AccessibleRole::MENU_ITEM:
            return QAccessible::MenuItem;
        case AccessibleRole::NOTIFICATION:
            return QAccessible::Notification;
        case AccessibleRole::OPTION_PANE:
            return QAccessible::Pane;
        case AccessibleRole::PAGE_TAB:
            return QAccessible::PageTab;
        case AccessibleRole::PAGE_TAB_LIST:
            return QAccessible::PageTabList;
        case AccessibleRole::PANEL:
            return QAccessible::Pane;
        case AccessibleRole::PARAGRAPH:
            return QAccessible::Paragraph;
        case AccessibleRole::PASSWORD_TEXT:
            // Qt API doesn't have a separate role to distinguish password edits,
            // but a 'passwordEdit' state
            return QAccessible::EditableText;
        case AccessibleRole::POPUP_MENU:
            return QAccessible::PopupMenu;
        case AccessibleRole::PUSH_BUTTON:
            return QAccessible::Button;
        case AccessibleRole::PROGRESS_BAR:
            return QAccessible::ProgressBar;
        case AccessibleRole::RADIO_BUTTON:
            return QAccessible::RadioButton;
        case AccessibleRole::RADIO_MENU_ITEM:
            return QAccessible::MenuItem;
        case AccessibleRole::ROW_HEADER:
            return QAccessible::RowHeader;
        case AccessibleRole::ROOT_PANE:
            return QAccessible::Pane;
        case AccessibleRole::SCROLL_BAR:
            return QAccessible::ScrollBar;
        case AccessibleRole::SCROLL_PANE:
            return QAccessible::Pane;
        case AccessibleRole::SHAPE:
            return QAccessible::Graphic;
        case AccessibleRole::SEPARATOR:
            return QAccessible::Separator;
        case AccessibleRole::SLIDER:
            return QAccessible::Slider;
        case AccessibleRole::SPIN_BOX:
            return QAccessible::SpinBox;
        case AccessibleRole::SPLIT_PANE:
            return QAccessible::Pane;
        case AccessibleRole::STATUS_BAR:
            return QAccessible::StatusBar;
        case AccessibleRole::TABLE:
            return QAccessible::Table;
        case AccessibleRole::TABLE_CELL:
            return QAccessible::Cell;
        case AccessibleRole::TEXT:
            return QAccessible::EditableText;
        case AccessibleRole::TEXT_FRAME:
            return QAccessible::Pane;
        case AccessibleRole::TOGGLE_BUTTON:
            return QAccessible::Button;
        case AccessibleRole::TOOL_BAR:
            return QAccessible::ToolBar;
        case AccessibleRole::TOOL_TIP:
            return QAccessible::ToolTip;
        case AccessibleRole::TREE:
            return QAccessible::Tree;
        case AccessibleRole::VIEW_PORT:
            return QAccessible::UserRole;
        case AccessibleRole::BUTTON_DROPDOWN:
            return QAccessible::ButtonDropDown;
        case AccessibleRole::BUTTON_MENU:
            return QAccessible::ButtonMenu;
        case AccessibleRole::CAPTION:
            return QAccessible::StaticText;
        case AccessibleRole::CHART:
            return QAccessible::Chart;
        case AccessibleRole::EDIT_BAR:
            return QAccessible::Equation;
        case AccessibleRole::FORM:
            return QAccessible::Form;
        case AccessibleRole::IMAGE_MAP:
            return QAccessible::Graphic;
        case AccessibleRole::NOTE:
            return QAccessible::Note;
        case AccessibleRole::RULER:
            return QAccessible::UserRole;
        case AccessibleRole::SECTION:
            return QAccessible::Section;
        case AccessibleRole::TREE_ITEM:
            return QAccessible::TreeItem;
        case AccessibleRole::TREE_TABLE:
            return QAccessible::Tree;
        case AccessibleRole::COMMENT:
            return QAccessible::Note;
        case AccessibleRole::COMMENT_END:
            return QAccessible::UserRole;
        case AccessibleRole::DOCUMENT_PRESENTATION:
            return QAccessible::Document;
        case AccessibleRole::DOCUMENT_SPREADSHEET:
            return QAccessible::Document;
        case AccessibleRole::DOCUMENT_TEXT:
            return QAccessible::Document;
        case AccessibleRole::STATIC:
            return QAccessible::StaticText;
        case AccessibleRole::WINDOW: // top-level window without title bar
            return QAccessible::Window;
    }

    SAL_WARN("vcl.qt""Unmapped role: " << getAccessibleContextImpl()->getAccessibleRole());
    return QAccessible::NoRole;
}

namespace
{
void lcl_addState(QAccessible::State* state, sal_Int64 nState)
{
    switch (nState)
    {
        case AccessibleStateType::INVALID:
            state->invalid = true;
            break;
        case AccessibleStateType::ACTIVE:
            state->active = true;
            break;
        case AccessibleStateType::ARMED:
            // No match
            break;
        case AccessibleStateType::BUSY:
            state->busy = true;
            break;
        case AccessibleStateType::CHECKABLE:
            state->checkable = true;
            break;
        case AccessibleStateType::CHECKED:
            state->checked = true;
            break;
        case AccessibleStateType::EDITABLE:
            state->editable = true;
            break;
        case AccessibleStateType::ENABLED:
            state->disabled = false;
            break;
        case AccessibleStateType::EXPANDABLE:
            state->expandable = true;
            break;
        case AccessibleStateType::EXPANDED:
            state->expanded = true;
            break;
        case AccessibleStateType::FOCUSABLE:
            state->focusable = true;
            break;
        case AccessibleStateType::FOCUSED:
            state->focused = true;
            break;
        case AccessibleStateType::HORIZONTAL:
            // No match
            break;
        case AccessibleStateType::ICONIFIED:
            // No match
            break;
        case AccessibleStateType::INDETERMINATE:
            state->checkStateMixed = true;
            break;
        case AccessibleStateType::MANAGES_DESCENDANTS:
            // No match
            break;
        case AccessibleStateType::MODAL:
            state->modal = true;
            break;
        case AccessibleStateType::MOVEABLE:
            state->movable = true;
            break;
        case AccessibleStateType::MULTI_LINE:
            state->multiLine = true;
            break;
        case AccessibleStateType::OPAQUE:
            // No match
            break;
        case AccessibleStateType::PRESSED:
            state->pressed = true;
            break;
        case AccessibleStateType::RESIZABLE:
            state->sizeable = true;
            break;
        case AccessibleStateType::SELECTABLE:
            state->selectable = true;
            break;
        case AccessibleStateType::SELECTED:
            state->selected = true;
            break;
        case AccessibleStateType::SENSITIVE:
            // No match
            break;
        case AccessibleStateType::SHOWING:
            // No match
            break;
        case AccessibleStateType::SINGLE_LINE:
            // No match
            break;
        case AccessibleStateType::STALE:
            // No match
            break;
        case AccessibleStateType::TRANSIENT:
            // No match
            break;
        case AccessibleStateType::VERTICAL:
            // No match
            break;
        case AccessibleStateType::VISIBLE:
            state->invisible = false;
            break;
        case AccessibleStateType::DEFAULT:
            // No match
            break;
        case AccessibleStateType::DEFUNC:
            state->invalid = true;
            break;
        case AccessibleStateType::MULTI_SELECTABLE:
            state->multiSelectable = true;
            break;
        default:
            SAL_WARN("vcl.qt""Unmapped state: " << nState);
            break;
    }
}
}

QAccessible::State QtAccessibleWidget::state() const
{
    QAccessible::State state;

    Reference<XAccessibleContext> xAc = getAccessibleContextImpl();
    if (!xAc.is())
        return state;

    sal_Int64 nStateSet(xAc->getAccessibleStateSet());

    for (int i = 0; i < 63; ++i)
    {
        sal_Int64 nState = sal_Int64(1) << i;
        if (nStateSet & nState)
            lcl_addState(&state, nState);
    }

    if (xAc->getAccessibleRole() == AccessibleRole::PASSWORD_TEXT)
        state.passwordEdit = true;

    return state;
}

QColor QtAccessibleWidget::foregroundColor() const
{
    Reference<XAccessibleContext> xAc = getAccessibleContextImpl();
    if (!xAc.is())
        return QColor();

    Reference<XAccessibleComponent> xAccessibleComponent(xAc, UNO_QUERY);
    return toQColor(Color(ColorTransparency, xAccessibleComponent->getForeground()));
}

QColor QtAccessibleWidget::backgroundColor() const
{
    Reference<XAccessibleContext> xAc = getAccessibleContextImpl();
    if (!xAc.is())
        return QColor();

    Reference<XAccessibleComponent> xAccessibleComponent(xAc, UNO_QUERY);
    return toQColor(Color(ColorTransparency, xAccessibleComponent->getBackground()));
}

void* QtAccessibleWidget::interface_cast(QAccessible::InterfaceType t)
{
    if (t == QAccessible::ActionInterface && accessibleProvidesInterface<XAccessibleAction>())
        return static_cast<QAccessibleActionInterface*>(this);
    if (t == QAccessible::TextInterface && accessibleProvidesInterface<XAccessibleText>())
        return static_cast<QAccessibleTextInterface*>(this);
    if (t == QAccessible::EditableTextInterface
        && accessibleProvidesInterface<XAccessibleEditableText>())
        return static_cast<QAccessibleEditableTextInterface*>(this);
    if (t == QAccessible::ValueInterface && accessibleProvidesInterface<XAccessibleValue>())
        return static_cast<QAccessibleValueInterface*>(this);
    if (t == QAccessible::TableCellInterface)
    {
        // parent must be a table
        Reference<XAccessibleTable> xTable = getAccessibleTableForParent();
        if (xTable.is())
            return static_cast<QAccessibleTableCellInterface*>(this);
    }
    if (t == QAccessible::TableInterface && accessibleProvidesInterface<XAccessibleTable>())
        return static_cast<QAccessibleTableInterface*>(this);
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
    if (t == QAccessible::SelectionInterface && accessibleProvidesInterface<XAccessibleSelection>())
        return static_cast<QAccessibleSelectionInterface*>(this);
#endif
#if QT_VERSION >= QT_VERSION_CHECK(6, 8, 0)
    if (t == QAccessible::AttributesInterface)
        return static_cast<QAccessibleAttributesInterface*>(this);
#endif
    return nullptr;
}

bool QtAccessibleWidget::isValid() const
{
    Reference<XAccessibleContext> xAc = getAccessibleContextImpl();
    return xAc.is();
}

QObject* QtAccessibleWidget::object() const { return &m_rObject; }

void QtAccessibleWidget::setText(QAccessible::Text /* t */, const QString& /* text */) {}

QAccessibleInterface* QtAccessibleWidget::childAt(int x, int y) const
{
    Reference<XAccessibleContext> xAc = getAccessibleContextImpl();
    if (!xAc.is())
        return nullptr;

    Reference<XAccessibleComponent> xAccessibleComponent(xAc, UNO_QUERY);
    // convert from screen to local coordinates
    QPoint aLocalCoords = QPoint(x, y) - rect().topLeft();
    return QAccessible::queryAccessibleInterface(
        QtAccessibleRegistry::getQObject(xAccessibleComponent->getAccessibleAtPoint(
            awt::Point(aLocalCoords.x(), aLocalCoords.y()))));
}

QAccessibleInterface* QtAccessibleWidget::customFactory(const QString& classname, QObject* pObject)
{
    if (!pObject)
        return nullptr;

    const QVariant aAccVariant = pObject->property(PROPERTY_ACCESSIBLE);
    if (aAccVariant.isValid() && aAccVariant.canConvert<QtAccessibleWidget*>())
    {
        QtAccessibleWidget* pAccessibleWidget = aAccVariant.value<QtAccessibleWidget*>();
        QtAccessibleRegistry::insert(pAccessibleWidget->m_xAccessible, pObject);
        return pAccessibleWidget;
    }

    if (classname == QLatin1String("QtWidget") && pObject->isWidgetType())
    {
        QtWidget* pWidget = static_cast<QtWidget*>(pObject);
        vcl::Window* pWindow = pWidget->frame().GetWindow();

        if (pWindow)
        {
            css::uno::Reference<XAccessible> xAcc = pWindow->GetAccessible();
            // insert into registry so the association between the XAccessible and the QtWidget
            // is remembered rather than creating a different QtXAccessible when a QObject is needed later
            QtAccessibleRegistry::insert(xAcc, pObject);
            return new QtAccessibleWidget(xAcc, *pObject);
        }
    }
    if (classname == QLatin1String("QtXAccessible"))
    {
        QtXAccessible* pXAccessible = static_cast<QtXAccessible*>(pObject);
        if (pXAccessible->m_xAccessible.is())
        {
            QtAccessibleWidget* pRet
                = new QtAccessibleWidget(pXAccessible->m_xAccessible, *pObject);
            // clear the reference in the QtXAccessible, no longer needed now that the QtAccessibleWidget holds one
            pXAccessible->m_xAccessible.clear();
            return pRet;
        }
    }

    return nullptr;
}

void QtAccessibleWidget::setCustomAccessible(QObject& rObject,
                                             const uno::Reference<XAccessible>& rxAccessible)
{
    assert(rxAccessible.is());

    // unset/delete the current/default accessible of the object
    QAccessibleInterface* pOldAccessible = QAccessible::queryAccessibleInterface(&rObject);
    const QAccessible::Id nId = QAccessible::uniqueId(pOldAccessible);
    QAccessible::deleteAccessibleInterface(nId);

    // let QtAccessibleWidget::customFactory set the custom accessible
    rObject.setProperty(PROPERTY_ACCESSIBLE,
                        QVariant::fromValue(new QtAccessibleWidget(rxAccessible, rObject)));
    QAccessible::queryAccessibleInterface(&rObject);
}

// QAccessibleActionInterface
QStringList QtAccessibleWidget::actionNames() const
{
    QStringList actionNames;
    Reference<XAccessibleAction> xAccessibleAction(getAccessibleContextImpl(), UNO_QUERY);
    if (!xAccessibleAction.is())
        return actionNames;

    int count = xAccessibleAction->getAccessibleActionCount();
    for (int i = 0; i < count; i++)
    {
        OUString desc = xAccessibleAction->getAccessibleActionDescription(i);
        actionNames.append(toQString(desc));
    }
    return actionNames;
}

void QtAccessibleWidget::doAction(const QString& actionName)
{
    Reference<XAccessibleAction> xAccessibleAction(getAccessibleContextImpl(), UNO_QUERY);
    if (!xAccessibleAction.is())
        return;

    int index = actionNames().indexOf(actionName);
    if (index == -1)
        return;
    xAccessibleAction->doAccessibleAction(index);
}

QStringList QtAccessibleWidget::keyBindingsForAction(const QString& actionName) const
{
    QStringList keyBindings;
    Reference<XAccessibleAction> xAccessibleAction(getAccessibleContextImpl(), UNO_QUERY);
    if (!xAccessibleAction.is())
        return keyBindings;

    int index = actionNames().indexOf(actionName);
    if (index == -1)
        return keyBindings;

    Reference<XAccessibleKeyBinding> xKeyBinding
        = xAccessibleAction->getAccessibleActionKeyBinding(index);

    if (!xKeyBinding.is())
        return keyBindings;

    int count = xKeyBinding->getAccessibleKeyBindingCount();
    for (int i = 0; i < count; i++)
    {
        Sequence<awt::KeyStroke> keyStroke = xKeyBinding->getAccessibleKeyBinding(i);
        keyBindings.append(toQString(comphelper::GetkeyBindingStrByXkeyBinding(keyStroke)));
    }
    return keyBindings;
}

#if QT_VERSION >= QT_VERSION_CHECK(6, 8, 0)

// QAccessibleAttributesInterface helpers
namespace
{
void lcl_insertAttribute(QHash<QAccessible::Attribute, QVariant>& rQtAttrs, const OUString& rName,
                         const OUString& rValue)
{
    if (rName == u"level"_ustr)
    {
        rQtAttrs.insert(QAccessible::Attribute::Level,
                        QVariant::fromValue(static_cast<int>(rValue.toInt32())));
    }
    else
    {
        // for now, leave not explicitly handled attributes as they are and report
        // via QAccessible::Attribute::Custom, but should consider suggesting to
        // add more specific attributes on Qt side and use those instead
        const QVariant aVariant = rQtAttrs.value(QAccessible::Attribute::Custom,
                                                 QVariant::fromValue(QHash<QString, QString>()));
        assert((aVariant.canConvert<QHash<QString, QString>>()));
        QHash<QString, QString> aAttrs = aVariant.value<QHash<QString, QString>>();
        aAttrs.insert(toQString(rName), toQString(rValue));
        rQtAttrs.insert(QAccessible::Attribute::Custom, QVariant::fromValue(aAttrs));
    }
}
}

QHash<QAccessible::Attribute, QVariant> QtAccessibleWidget::attributes() const
{
    Reference<XAccessibleContext> xContext = getAccessibleContextImpl();
    if (!xContext.is())
        return {};

    Reference<XAccessibleExtendedAttributes> xAttributes(xContext, UNO_QUERY);
    if (!xAttributes.is())
        return {};

    QHash<QAccessible::Attribute, QVariant> aQtAttrs;

#if QT_VERSION >= QT_VERSION_CHECK(6, 10, 0)
    const css::lang::Locale aLocale = xContext->getLocale();
    const QLocale aQLocale(toQString(aLocale.Language + u"_" + aLocale.Country));
    aQtAttrs.insert(QAccessible::Attribute::Locale, aQLocale);
#endif

    const OUString sAttrs = xAttributes->getExtendedAttributes();
    sal_Int32 nIndex = 0;
    do
    {
        const OUString sAttribute = sAttrs.getToken(0, ';', nIndex);
        sal_Int32 nColonPos = 0;
        const OUString sName = sAttribute.getToken(0, ':', nColonPos);
        const OUString sValue = sAttribute.getToken(0, ':', nColonPos);
        assert(nColonPos == -1
               && "Too many colons in attribute that should have \"name:value\" syntax");
        if (!sName.isEmpty())
            lcl_insertAttribute(aQtAttrs, sName, sValue);
    } while (nIndex >= 0);

    return aQtAttrs;
}

// QAccessibleAttributesInterface
QList<QAccessible::Attribute> QtAccessibleWidget::attributeKeys() const
{
    const QHash<QAccessible::Attribute, QVariant> aAttributes = attributes();
    return aAttributes.keys();
}

QVariant QtAccessibleWidget::attributeValue(QAccessible::Attribute eAttribute) const
{
    const QHash<QAccessible::Attribute, QVariant> aAllAttributes = attributes();
    return aAllAttributes.value(eAttribute);
}
#endif

// QAccessibleTextInterface
void QtAccessibleWidget::addSelection(int /* startOffset */, int /* endOffset */)
{
    SAL_INFO("vcl.qt""Unsupported QAccessibleTextInterface::addSelection");
}

// Text attributes are returned in format specified in IAccessible2 spec, since that
// is what Qt handles:
// https://wiki.linuxfoundation.org/accessibility/iaccessible2/textattributes
QString QtAccessibleWidget::attributes(int offset, int* startOffset, int* endOffset) const
{
    if (startOffset == nullptr || endOffset == nullptr)
        return QString();

    *startOffset = -1;
    *endOffset = -1;

    Reference<XAccessibleText> xText(getAccessibleContextImpl(), UNO_QUERY);
    if (!xText.is())
        return QString();

    // handle special values for offset the same way base class's QAccessibleTextWidget::attributes does
    // (as defined in IAccessible 2: -1 -> length, -2 -> cursor position)
    if (offset == -2)
        offset = cursorPosition();

    const int nTextLength = characterCount();
    if (offset == -1 || offset == nTextLength)
        offset = nTextLength - 1;

    if (offset < 0 || offset > nTextLength)
    {
        SAL_WARN("vcl.qt""QtAccessibleWidget::attributes called with invalid offset: " << offset);
        return QString();
    }

    // Qt doesn't have the strict separation into text and object attributes, but also
    // supports text-specific attributes that are object attributes according to the
    // IAccessible2 spec.
    sal_Int32 nStart = 0;
    sal_Int32 nEnd = 0;
    const OUString aRet = AccessibleTextAttributeHelper::GetIAccessible2TextAttributes(
        xText, IA2AttributeType::TextAttributes | IA2AttributeType::ObjectAttributes,
        static_cast<sal_Int32>(offset), nStart, nEnd);
    *startOffset = static_cast<int>(nStart);
    *endOffset = static_cast<int>(nEnd);
    return toQString(aRet);
}

int QtAccessibleWidget::characterCount() const
{
    Reference<XAccessibleText> xText(getAccessibleContextImpl(), UNO_QUERY);
    if (xText.is())
        return xText->getCharacterCount();
    return 0;
}

QRect QtAccessibleWidget::characterRect(int nOffset) const
{
    Reference<XAccessibleText> xText(getAccessibleContextImpl(), UNO_QUERY);
    if (!xText.is())
        return QRect();

    if (nOffset < 0 || nOffset > xText->getCharacterCount())
    {
        SAL_WARN("vcl.qt",
                 "QtAccessibleWidget::characterRect called with invalid offset: " << nOffset);
        return QRect();
    }

    const awt::Rectangle aBounds = xText->getCharacterBounds(nOffset);
    const QRect aRect(aBounds.X, aBounds.Y, aBounds.Width, aBounds.Height);
    // convert to screen coordinates
    const QRect aScreenPos = rect();
    return aRect.translated(aScreenPos.x(), aScreenPos.y());
}

int QtAccessibleWidget::cursorPosition() const
{
    Reference<XAccessibleText> xText(getAccessibleContextImpl(), UNO_QUERY);
    if (xText.is())
        return xText->getCaretPosition();
    return 0;
}

int QtAccessibleWidget::offsetAtPoint(const QPoint& rPoint) const
{
    Reference<XAccessibleText> xText(getAccessibleContextImpl(), UNO_QUERY);
    if (!xText.is())
        return -1;

    // convert from screen to local coordinates
    QPoint aLocalCoords = rPoint - rect().topLeft();
    awt::Point aPoint(aLocalCoords.x(), aLocalCoords.y());
    return xText->getIndexAtPoint(aPoint);
}

void QtAccessibleWidget::removeSelection(int /* selectionIndex */)
{
    SAL_INFO("vcl.qt""Unsupported QAccessibleTextInterface::removeSelection");
}

void QtAccessibleWidget::scrollToSubstring(int startIndex, int endIndex)
{
    Reference<XAccessibleText> xText(getAccessibleContextImpl(), UNO_QUERY);
    if (!xText.is())
        return;

    sal_Int32 nTextLength = xText->getCharacterCount();
    if (startIndex < 0 || startIndex > nTextLength || endIndex < 0 || endIndex > nTextLength)
    {
        SAL_WARN("vcl.qt""QtAccessibleWidget::scrollToSubstring called with invalid offset.");
        return;
    }

    xText->scrollSubstringTo(startIndex, endIndex, AccessibleScrollType_SCROLL_ANYWHERE);
}

void QtAccessibleWidget::selection(int selectionIndex, int* startOffset, int* endOffset) const
{
    if (!startOffset && !endOffset)
        return;

    Reference<XAccessibleText> xText;
    if (selectionIndex == 0)
        xText = Reference<XAccessibleText>(getAccessibleContextImpl(), UNO_QUERY);

    if (startOffset)
        *startOffset = xText.is() ? xText->getSelectionStart() : 0;
    if (endOffset)
        *endOffset = xText.is() ? xText->getSelectionEnd() : 0;
}

int QtAccessibleWidget::selectionCount() const
{
    Reference<XAccessibleText> xText(getAccessibleContextImpl(), UNO_QUERY);
    if (xText.is() && !xText->getSelectedText().isEmpty())
        return 1; // Only 1 selection supported atm
    return 0;
}

void QtAccessibleWidget::setCursorPosition(int position)
{
    Reference<XAccessibleText> xText(getAccessibleContextImpl(), UNO_QUERY);
    if (!xText.is())
        return;

    if (position < 0 || position > xText->getCharacterCount())
    {
        SAL_WARN("vcl.qt",
                 "QtAccessibleWidget::setCursorPosition called with invalid offset: " << position);
        return;
    }

    xText->setCaretPosition(position);
}

void QtAccessibleWidget::setSelection(int /* selectionIndex */, int startOffset, int endOffset)
{
    Reference<XAccessibleText> xText(getAccessibleContextImpl(), UNO_QUERY);
    if (!xText.is())
        return;

    sal_Int32 nTextLength = xText->getCharacterCount();
    if (startOffset < 0 || startOffset > nTextLength || endOffset < 0 || endOffset > nTextLength)
    {
        SAL_WARN("vcl.qt""QtAccessibleWidget::setSelection called with invalid offset.");
        return;
    }

    xText->setSelection(startOffset, endOffset);
}

QString QtAccessibleWidget::text(int startOffset, int endOffset) const
{
    Reference<XAccessibleText> xText(getAccessibleContextImpl(), UNO_QUERY);
    if (!xText.is())
        return QString();

    sal_Int32 nTextLength = xText->getCharacterCount();
    if (startOffset < 0 || startOffset > nTextLength || endOffset < 0 || endOffset > nTextLength)
    {
        SAL_WARN("vcl.qt""QtAccessibleWidget::text called with invalid offset.");
        return QString();
    }

    return toQString(xText->getTextRange(startOffset, endOffset));
}

QString QtAccessibleWidget::textAfterOffset(int nOffset,
                                            QAccessible::TextBoundaryType eBoundaryType,
                                            int* pStartOffset, int* pEndOffset) const
{
    if (pStartOffset == nullptr || pEndOffset == nullptr)
        return QString();

    *pStartOffset = -1;
    *pEndOffset = -1;

    Reference<XAccessibleText> xText(getAccessibleContextImpl(), UNO_QUERY);
    if (!xText.is())
        return QString();

    const int nCharCount = characterCount();
    // -1 is special value for text length
    if (nOffset == -1)
        nOffset = nCharCount;
    else if (nOffset < -1 || nOffset > nCharCount)
    {
        SAL_WARN("vcl.qt",
                 "QtAccessibleWidget::textAfterOffset called with invalid offset: " << nOffset);
        return QString();
    }

    if (eBoundaryType == QAccessible::NoBoundary)
    {
        if (nOffset == nCharCount)
            return QString();
        *pStartOffset = nOffset + 1;
        *pEndOffset = nCharCount;
        return text(nOffset + 1, nCharCount);
    }

    sal_Int16 nUnoBoundaryType = lcl_matchQtTextBoundaryType(eBoundaryType);
    assert(nUnoBoundaryType > 0);
    const TextSegment aSegment = xText->getTextBehindIndex(nOffset, nUnoBoundaryType);
    *pStartOffset = aSegment.SegmentStart;
    *pEndOffset = aSegment.SegmentEnd;
    return toQString(aSegment.SegmentText);
}

QString QtAccessibleWidget::textAtOffset(int offset, QAccessible::TextBoundaryType boundaryType,
                                         int* startOffset, int* endOffset) const
{
    if (startOffset == nullptr || endOffset == nullptr)
        return QString();

    const int nCharCount = characterCount();
    if (boundaryType == QAccessible::NoBoundary)
    {
        *startOffset = 0;
        *endOffset = nCharCount;
        return text(0, nCharCount);
    }

    Reference<XAccessibleText> xText(getAccessibleContextImpl(), UNO_QUERY);
    if (!xText.is())
        return QString();

    sal_Int16 nUnoBoundaryType = lcl_matchQtTextBoundaryType(boundaryType);
    assert(nUnoBoundaryType > 0);

    // special value of -1 for offset means text length
    if (offset == -1)
        offset = nCharCount;

    if (offset < 0 || offset > nCharCount)
    {
        SAL_WARN("vcl.qt",
                 "QtAccessibleWidget::textAtOffset called with invalid offset: " << offset);
        return QString();
    }

    const TextSegment segment = xText->getTextAtIndex(offset, nUnoBoundaryType);
    *startOffset = segment.SegmentStart;
    *endOffset = segment.SegmentEnd;
    return toQString(segment.SegmentText);
}

QString QtAccessibleWidget::textBeforeOffset(int nOffset,
                                             QAccessible::TextBoundaryType eBoundaryType,
                                             int* pStartOffset, int* pEndOffset) const
{
    if (pStartOffset == nullptr || pEndOffset == nullptr)
        return QString();

    *pStartOffset = -1;
    *pEndOffset = -1;

    Reference<XAccessibleText> xText(getAccessibleContextImpl(), UNO_QUERY);
    if (!xText.is())
        return QString();

    const int nCharCount = characterCount();
    // -1 is special value for text length
    if (nOffset == -1)
        nOffset = nCharCount;
    else if (nOffset < -1 || nOffset > nCharCount)
    {
        SAL_WARN("vcl.qt",
                 "QtAccessibleWidget::textBeforeOffset called with invalid offset: " << nOffset);
        return QString();
    }

    if (eBoundaryType == QAccessible::NoBoundary)
    {
        *pStartOffset = 0;
        *pEndOffset = nOffset;
        return text(0, nOffset);
    }

    sal_Int16 nUnoBoundaryType = lcl_matchQtTextBoundaryType(eBoundaryType);
    assert(nUnoBoundaryType > 0);
    const TextSegment aSegment = xText->getTextBeforeIndex(nOffset, nUnoBoundaryType);
    *pStartOffset = aSegment.SegmentStart;
    *pEndOffset = aSegment.SegmentEnd;
    return toQString(aSegment.SegmentText);
}

// QAccessibleEditableTextInterface

void QtAccessibleWidget::deleteText(int startOffset, int endOffset)
{
    Reference<XAccessibleContext> xAc = getAccessibleContextImpl();
    if (!xAc.is())
        return;

    Reference<XAccessibleEditableText> xEditableText(xAc, UNO_QUERY);
    if (!xEditableText.is())
        return;

    sal_Int32 nTextLength = xEditableText->getCharacterCount();
    if (startOffset < 0 || startOffset > nTextLength || endOffset < 0 || endOffset > nTextLength)
    {
        SAL_WARN("vcl.qt""QtAccessibleWidget::deleteText called with invalid offset.");
        return;
    }

    xEditableText->deleteText(startOffset, endOffset);
}

void QtAccessibleWidget::insertText(int offset, const QString& text)
{
    Reference<XAccessibleContext> xAc = getAccessibleContextImpl();
    if (!xAc.is())
        return;

    Reference<XAccessibleEditableText> xEditableText(xAc, UNO_QUERY);
    if (!xEditableText.is())
        return;

    if (offset < 0 || offset > xEditableText->getCharacterCount())
    {
        SAL_WARN("vcl.qt""QtAccessibleWidget::insertText called with invalid offset: " << offset);
        return;
    }

    xEditableText->insertText(toOUString(text), offset);
}

void QtAccessibleWidget::replaceText(int startOffset, int endOffset, const QString& ;text)
{
    Reference<XAccessibleContext> xAc = getAccessibleContextImpl();
    if (!xAc.is())
        return;

    Reference<XAccessibleEditableText> xEditableText(xAc, UNO_QUERY);
    if (!xEditableText.is())
        return;

    sal_Int32 nTextLength = xEditableText->getCharacterCount();
    if (startOffset < 0 || startOffset > nTextLength || endOffset < 0 || endOffset > nTextLength)
    {
        SAL_WARN("vcl.qt""QtAccessibleWidget::replaceText called with invalid offset.");
        return;
    }

    xEditableText->replaceText(startOffset, endOffset, toOUString(text));
}

// QAccessibleValueInterface
QVariant QtAccessibleWidget::currentValue() const
{
    Reference<XAccessibleContext> xAc = getAccessibleContextImpl();
    if (!xAc.is())
        return QVariant();

    Reference<XAccessibleValue> xValue(xAc, UNO_QUERY);
    if (!xValue.is())
        return QVariant();
    double aDouble = 0;
    xValue->getCurrentValue() >>= aDouble;
    return QVariant(aDouble);
}

QVariant QtAccessibleWidget::maximumValue() const
{
    Reference<XAccessibleContext> xAc = getAccessibleContextImpl();
    if (!xAc.is())
        return QVariant();

    Reference<XAccessibleValue> xValue(xAc, UNO_QUERY);
    if (!xValue.is())
        return QVariant();
    double aDouble = 0;
    xValue->getMaximumValue() >>= aDouble;
    return QVariant(aDouble);
}

QVariant QtAccessibleWidget::minimumStepSize() const
{
    Reference<XAccessibleContext> xAc = getAccessibleContextImpl();
    if (!xAc.is())
        return QVariant();

    Reference<XAccessibleValue> xValue(xAc, UNO_QUERY);
    if (!xValue.is())
        return QVariant();
    double dMinStep = 0;
    xValue->getMinimumIncrement() >>= dMinStep;
    return QVariant(dMinStep);
}

QVariant QtAccessibleWidget::minimumValue() const
{
    Reference<XAccessibleContext> xAc = getAccessibleContextImpl();
    if (!xAc.is())
        return QVariant();

    Reference<XAccessibleValue> xValue(xAc, UNO_QUERY);
    if (!xValue.is())
        return QVariant();
    double aDouble = 0;
    xValue->getMinimumValue() >>= aDouble;
    return QVariant(aDouble);
}

void QtAccessibleWidget::setCurrentValue(const QVariant& value)
{
    Reference<XAccessibleContext> xAc = getAccessibleContextImpl();
    if (!xAc.is())
        return;

    Reference<XAccessibleValue> xValue(xAc, UNO_QUERY);
    if (!xValue.is())
        return;

    // Different types of numerical values for XAccessibleValue are possible.
    // If current value has an integer type, also use that for the new value, to make
    // sure underlying implementations expecting that can handle the value properly.
    const Any aCurrentValue = xValue->getCurrentValue();
    if (aCurrentValue.getValueTypeClass() == css::uno::TypeClass::TypeClass_LONG)
        xValue->setCurrentValue(Any(static_cast<sal_Int32>(value.toInt())));
    else if (aCurrentValue.getValueTypeClass() == css::uno::TypeClass::TypeClass_HYPER)
        xValue->setCurrentValue(Any(static_cast<sal_Int64>(value.toLongLong())));
    else
        xValue->setCurrentValue(Any(value.toDouble()));
}

// QAccessibleTableInterface
QAccessibleInterface* QtAccessibleWidget::caption() const
{
    Reference<XAccessibleContext> xAc = getAccessibleContextImpl();
    if (!xAc.is())
        return nullptr;

    Reference<XAccessibleTable> xTable(xAc, UNO_QUERY);
    if (!xTable.is())
        return nullptr;
    return QAccessible::queryAccessibleInterface(
        QtAccessibleRegistry::getQObject(xTable->getAccessibleCaption()));
}

QAccessibleInterface* QtAccessibleWidget::cellAt(int row, int column) const
{
    Reference<XAccessibleContext> xAc = getAccessibleContextImpl();
    if (!xAc.is())
        return nullptr;

    Reference<XAccessibleTable> xTable(xAc, UNO_QUERY);
    if (!xTable.is())
        return nullptr;

    if (row < 0 || row >= xTable->getAccessibleRowCount() || column < 0
        || column >= xTable->getAccessibleColumnCount())
    {
        SAL_WARN("vcl.qt""QtAccessibleWidget::cellAt called with invalid row/column index ("
                               << row << ", " << column << ")");
        return nullptr;
    }

    return QAccessible::queryAccessibleInterface(
        QtAccessibleRegistry::getQObject(xTable->getAccessibleCellAt(row, column)));
}

int QtAccessibleWidget::columnCount() const
{
    Reference<XAccessibleContext> xAc = getAccessibleContextImpl();
    if (!xAc.is())
        return 0;

    Reference<XAccessibleTable> xTable(xAc, UNO_QUERY);
    if (!xTable.is())
        return 0;
    return xTable->getAccessibleColumnCount();
}

QString QtAccessibleWidget::columnDescription(int column) const
{
    Reference<XAccessibleContext> xAc = getAccessibleContextImpl();
    if (!xAc.is())
        return QString();

    Reference<XAccessibleTable> xTable(xAc, UNO_QUERY);
    if (!xTable.is())
        return QString();
    return toQString(xTable->getAccessibleColumnDescription(column));
}

bool QtAccessibleWidget::isColumnSelected(int nColumn) const
{
    Reference<XAccessibleContext> xAc = getAccessibleContextImpl();
    if (!xAc.is())
        return false;

    Reference<XAccessibleTable> xTable(xAc, UNO_QUERY);
    if (!xTable.is())
        return false;

    if (nColumn < 0 || nColumn >= xTable->getAccessibleColumnCount())
    {
        SAL_WARN("vcl.qt""QtAccessibleWidget::isColumnSelected called with invalid column index "
                               << nColumn);
        return false;
    }

    return xTable->isAccessibleColumnSelected(nColumn);
}

bool QtAccessibleWidget::isRowSelected(int nRow) const
{
    Reference<XAccessibleContext> xAc = getAccessibleContextImpl();
    if (!xAc.is())
        return false;

    Reference<XAccessibleTable> xTable(xAc, UNO_QUERY);
    if (!xTable.is())
        return false;

    if (nRow < 0 || nRow >= xTable->getAccessibleRowCount())
    {
        SAL_WARN("vcl.qt",
                 "QtAccessibleWidget::isRowSelected called with invalid row index " << nRow);
        return false;
    }

    return xTable->isAccessibleRowSelected(nRow);
}

void QtAccessibleWidget::modelChange(QAccessibleTableModelChangeEvent*) {}

int QtAccessibleWidget::rowCount() const
{
    Reference<XAccessibleContext> xAc = getAccessibleContextImpl();
    if (!xAc.is())
        return 0;

    Reference<XAccessibleTable> xTable(xAc, UNO_QUERY);
    if (!xTable.is())
        return 0;
    return xTable->getAccessibleRowCount();
}

QString QtAccessibleWidget::rowDescription(int row) const
{
    Reference<XAccessibleContext> xAc = getAccessibleContextImpl();
    if (!xAc.is())
        return QString();

    Reference<XAccessibleTable> xTable(xAc, UNO_QUERY);
    if (!xTable.is())
        return QString();
    return toQString(xTable->getAccessibleRowDescription(row));
}

bool QtAccessibleWidget::selectColumn(int column)
{
    Reference<XAccessibleContext> xAc = getAccessibleContextImpl();
    if (!xAc.is())
        return false;

    if (column < 0 || column >= columnCount())
    {
        SAL_WARN("vcl.qt",
                 "QtAccessibleWidget::selectColumn called with invalid column index " << column);
        return false;
    }

    Reference<XAccessibleTableSelection> xTableSelection(xAc, UNO_QUERY);
    if (!xTableSelection.is())
        return false;
    return xTableSelection->selectColumn(column);
}

bool QtAccessibleWidget::selectRow(int row)
{
    Reference<XAccessibleContext> xAc = getAccessibleContextImpl();
    if (!xAc.is())
        return false;

    if (row < 0 || row >= rowCount())
    {
        SAL_WARN("vcl.qt""QtAccessibleWidget::selectRow called with invalid row index " << row);
        return false;
    }

    Reference<XAccessibleTableSelection> xTableSelection(xAc, UNO_QUERY);
    if (!xTableSelection.is())
        return false;
    return xTableSelection->selectRow(row);
}

int QtAccessibleWidget::selectedCellCount() const { return selectedItemCount(); }

QList<QAccessibleInterface*> QtAccessibleWidget::selectedCells() const { return selectedItems(); }

int QtAccessibleWidget::selectedColumnCount() const
{
    Reference<XAccessibleContext> xAc = getAccessibleContextImpl();
    if (!xAc.is())
        return 0;

    Reference<XAccessibleTable> xTable(xAc, UNO_QUERY);
    if (!xTable.is())
        return 0;
    return xTable->getSelectedAccessibleColumns().getLength();
}

QList<int> QtAccessibleWidget::selectedColumns() const
{
    Reference<XAccessibleContext> xAc = getAccessibleContextImpl();
    if (!xAc.is())
        return QList<int>();

    Reference<XAccessibleTable> xTable(xAc, UNO_QUERY);
    if (!xTable.is())
        return QList<int>();
    return toQList(xTable->getSelectedAccessibleColumns());
}

int QtAccessibleWidget::selectedRowCount() const
{
    Reference<XAccessibleContext> xAc = getAccessibleContextImpl();
    if (!xAc.is())
        return 0;

    Reference<XAccessibleTable> xTable(xAc, UNO_QUERY);
    if (!xTable.is())
        return 0;
    return xTable->getSelectedAccessibleRows().getLength();
}

QList<int> QtAccessibleWidget::selectedRows() const
{
    Reference<XAccessibleContext> xAc = getAccessibleContextImpl();
    if (!xAc.is())
        return QList<int>();

    Reference<XAccessibleTable> xTable(xAc, UNO_QUERY);
    if (!xTable.is())
        return QList<int>();
    return toQList(xTable->getSelectedAccessibleRows());
}

QAccessibleInterface* QtAccessibleWidget::summary() const
{
    Reference<XAccessibleContext> xAc = getAccessibleContextImpl();
    if (!xAc.is())
        return nullptr;

    Reference<XAccessibleTable> xTable(xAc, UNO_QUERY);
    if (!xTable.is())
        return nullptr;
    return QAccessible::queryAccessibleInterface(
        QtAccessibleRegistry::getQObject(xTable->getAccessibleSummary()));
}

bool QtAccessibleWidget::unselectColumn(int column)
{
    Reference<XAccessibleContext> xAc = getAccessibleContextImpl();
    if (!xAc.is())
        return false;

    Reference<XAccessibleTableSelection> xTableSelection(xAc, UNO_QUERY);
    if (!xTableSelection.is())
        return false;
    return xTableSelection->unselectColumn(column);
}

bool QtAccessibleWidget::unselectRow(int row)
{
    Reference<XAccessibleContext> xAc = getAccessibleContextImpl();
    if (!xAc.is())
        return false;

    Reference<XAccessibleTableSelection> xTableSelection(xAc, UNO_QUERY);
    if (!xTableSelection.is())
        return false;
    return xTableSelection->unselectRow(row);
}

// QAccessibleTableCellInterface
QList<QAccessibleInterface*> QtAccessibleWidget::columnHeaderCells() const
{
    Reference<XAccessibleTable> xTable = getAccessibleTableForParent();
    if (!xTable.is())
        return QList<QAccessibleInterface*>();

    Reference<XAccessibleTable> xHeaders = xTable->getAccessibleColumnHeaders();
    if (!xHeaders.is())
        return QList<QAccessibleInterface*>();

    const sal_Int32 nCol = columnIndex();
    QList<QAccessibleInterface*> aHeaderCells;
    for (sal_Int32 nRow = 0; nRow < xHeaders->getAccessibleRowCount(); nRow++)
    {
        Reference<XAccessible> xCell = xHeaders->getAccessibleCellAt(nRow, nCol);
        QAccessibleInterface* pInterface
            = QAccessible::queryAccessibleInterface(QtAccessibleRegistry::getQObject(xCell));
        aHeaderCells.push_back(pInterface);
    }
    return aHeaderCells;
}

int QtAccessibleWidget::columnIndex() const
{
    Reference<XAccessibleContext> xAcc = getAccessibleContextImpl();
    if (!xAcc.is())
        return -1;

    Reference<XAccessibleTable> xTable = getAccessibleTableForParent();
    if (!xTable.is())
        return -1;

    const sal_Int64 nIndexInParent = xAcc->getAccessibleIndexInParent();
    return xTable->getAccessibleColumn(nIndexInParent);
}

bool QtAccessibleWidget::isSelected() const
{
    Reference<XAccessibleContext> xAcc = getAccessibleContextImpl();
    if (!xAcc.is())
        return false;

    Reference<XAccessibleTable> xTable = getAccessibleTableForParent();
    if (!xTable.is())
        return false;

    const sal_Int32 nColumn = columnIndex();
    const sal_Int32 nRow = rowIndex();
    return xTable->isAccessibleSelected(nRow, nColumn);
}

int QtAccessibleWidget::columnExtent() const
{
    Reference<XAccessibleContext> xAcc = getAccessibleContextImpl();
    if (!xAcc.is())
        return -1;

    Reference<XAccessibleTable> xTable = getAccessibleTableForParent();
    if (!xTable.is())
        return -1;

    const sal_Int32 nColumn = columnIndex();
    const sal_Int32 nRow = rowIndex();
    return xTable->getAccessibleColumnExtentAt(nRow, nColumn);
}

QList<QAccessibleInterface*> QtAccessibleWidget::rowHeaderCells() const
{
    Reference<XAccessibleTable> xTable = getAccessibleTableForParent();
    if (!xTable.is())
        return QList<QAccessibleInterface*>();

    Reference<XAccessibleTable> xHeaders = xTable->getAccessibleRowHeaders();
    if (!xHeaders.is())
        return QList<QAccessibleInterface*>();

    const sal_Int32 nRow = rowIndex();
    QList<QAccessibleInterface*> aHeaderCells;
    for (sal_Int32 nCol = 0; nCol < xHeaders->getAccessibleColumnCount(); nCol++)
    {
        Reference<XAccessible> xCell = xHeaders->getAccessibleCellAt(nRow, nCol);
        QAccessibleInterface* pInterface
            = QAccessible::queryAccessibleInterface(QtAccessibleRegistry::getQObject(xCell));
        aHeaderCells.push_back(pInterface);
    }
    return aHeaderCells;
}

int QtAccessibleWidget::rowExtent() const
{
    Reference<XAccessibleContext> xAcc = getAccessibleContextImpl();
    if (!xAcc.is())
        return -1;

    Reference<XAccessibleTable> xTable = getAccessibleTableForParent();
    if (!xTable.is())
        return -1;

    const sal_Int32 nColumn = columnIndex();
    const sal_Int32 nRow = rowIndex();
    return xTable->getAccessibleRowExtentAt(nRow, nColumn);
}

int QtAccessibleWidget::rowIndex() const
{
    Reference<XAccessibleContext> xAcc = getAccessibleContextImpl();
    if (!xAcc.is())
        return -1;

    Reference<XAccessibleTable> xTable = getAccessibleTableForParent();
    if (!xTable.is())
        return -1;

    const sal_Int64 nIndexInParent = xAcc->getAccessibleIndexInParent();
    return xTable->getAccessibleRow(nIndexInParent);
}

QAccessibleInterface* QtAccessibleWidget::table() const
{
    Reference<XAccessibleTable> xTable = getAccessibleTableForParent();
    if (!xTable.is())
        return nullptr;

    Reference<XAccessible> xTableAcc(xTable, UNO_QUERY);
    if (!xTableAcc.is())
        return nullptr;

    return QAccessible::queryAccessibleInterface(QtAccessibleRegistry::getQObject(xTableAcc));
}

// QAccessibleSelectionInterface
int QtAccessibleWidget::selectedItemCount() const
{
    Reference<XAccessibleContext> xAcc = getAccessibleContextImpl();
    if (!xAcc.is())
        return 0;

    Reference<XAccessibleSelection> xSelection(xAcc, UNO_QUERY);
    if (!xSelection.is())
        return 0;

    sal_Int64 nSelected = xSelection->getSelectedAccessibleChildCount();
    if (nSelected > std::numeric_limits<int>::max())
    {
        SAL_WARN("vcl.qt",
                 "QtAccessibleWidget::selectedItemCount: Cell count exceeds maximum int value, "
                 "using max int.");
        nSelected = std::numeric_limits<int>::max();
    }
    return nSelected;
}

QList<QAccessibleInterface*> QtAccessibleWidget::selectedItems() const
{
    Reference<XAccessibleContext> xAcc = getAccessibleContextImpl();
    if (!xAcc.is())
        return QList<QAccessibleInterface*>();

    Reference<XAccessibleSelection> xSelection(xAcc, UNO_QUERY);
    if (!xSelection.is())
        return QList<QAccessibleInterface*>();

    QList<QAccessibleInterface*> aSelectedItems;
    sal_Int64 nSelected = xSelection->getSelectedAccessibleChildCount();
    if (nSelected > std::numeric_limits<int>::max())
    {
        SAL_WARN("vcl.qt",
                 "QtAccessibleWidget::selectedItems: Cell count exceeds maximum int value, "
                 "using max int.");
        nSelected = std::numeric_limits<int>::max();
    }
    for (sal_Int64 i = 0; i < nSelected; i++)
    {
        Reference<XAccessible> xChild = xSelection->getSelectedAccessibleChild(i);
        QAccessibleInterface* pInterface
            = QAccessible::queryAccessibleInterface(QtAccessibleRegistry::getQObject(xChild));
        aSelectedItems.push_back(pInterface);
    }
    return aSelectedItems;
}

#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
QAccessibleInterface* QtAccessibleWidget::selectedItem(int nSelectionIndex) const
{
    Reference<XAccessibleContext> xAcc = getAccessibleContextImpl();
    if (!xAcc.is())
        return nullptr;

    Reference<XAccessibleSelection> xSelection(xAcc, UNO_QUERY);
    if (!xSelection.is())
        return nullptr;

    if (nSelectionIndex < 0 || nSelectionIndex >= xSelection->getSelectedAccessibleChildCount())
    {
        SAL_WARN("vcl.qt",
                 "QtAccessibleWidget::selectedItem called with invalid index: " << nSelectionIndex);
        return nullptr;
    }

    Reference<XAccessible> xChild = xSelection->getSelectedAccessibleChild(nSelectionIndex);
    if (!xChild)
        return nullptr;

    return QAccessible::queryAccessibleInterface(QtAccessibleRegistry::getQObject(xChild));
}

bool QtAccessibleWidget::isSelected(QAccessibleInterface* pItem) const
{
    Reference<XAccessibleContext> xAcc = getAccessibleContextImpl();
    if (!xAcc.is())
        return false;

    Reference<XAccessibleSelection> xSelection(xAcc, UNO_QUERY);
    if (!xSelection.is())
        return false;

    int nChildIndex = indexOfChild(pItem);
    if (nChildIndex < 0)
        return false;

    return xSelection->isAccessibleChildSelected(nChildIndex);
}

bool QtAccessibleWidget::select(QAccessibleInterface* pItem)
{
    Reference<XAccessibleContext> xAcc = getAccessibleContextImpl();
    if (!xAcc.is())
        return false;

    Reference<XAccessibleSelection> xSelection(xAcc, UNO_QUERY);
--> --------------------

--> maximum size reached

--> --------------------

Messung V0.5
C=87 H=99 G=93

¤ Dauer der Verarbeitung: 0.19 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.