/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qaccessible.h"

#include "qaccessiblecache_p.h"
#include "qaccessibleplugin.h"
#include "qaccessibleobject.h"
#include "qaccessiblebridge.h"
#include <QtCore/qtextboundaryfinder.h>
#include <QtGui/qclipboard.h>
#include <QtGui/qguiapplication.h>
#include <QtGui/qtextcursor.h>
#include <private/qguiapplication_p.h>
#include <qpa/qplatformaccessibility.h>
#include <qpa/qplatformintegration.h>

#include <QtCore/qdebug.h>
#include <QtCore/qloggingcategory.h>
#include <QtCore/qmetaobject.h>
#include <QtCore/qhash.h>
#include <private/qfactoryloader_p.h>

QT_BEGIN_NAMESPACE

Q_LOGGING_CATEGORY(lcAccessibilityCore, "qt.accessibility.core");

/*!
    \class QAccessible
    \brief The QAccessible class provides enums and static functions
    related to accessibility.

    \ingroup accessibility
    \inmodule QtGui

    This class is part of \l {Accessibility for QWidget Applications}.

    Accessible applications can be used by people who are not able to
    use applications by conventional means.

    The functions in this class are used for communication between
    accessible applications (also called AT Servers) and
    accessibility tools (AT Clients), such as screen readers and
    braille displays. Clients and servers communicate in the following way:

    \list
    \li  \e{AT Servers} notify the clients about events through calls to the
        updateAccessibility() function.

    \li  \e{AT Clients} request information about the objects in the server.
        The QAccessibleInterface class is the core interface, and encapsulates
        this information in a pure virtual API. Implementations of the interface
        are provided by Qt through the queryAccessibleInterface() API.
    \endlist

    The communication between servers and clients is initialized by
    the setRootObject() function. Function pointers can be installed
    to replace or extend the default behavior of the static functions
    in QAccessible.

    Qt supports Microsoft Active Accessibility (MSAA), \macos
    Accessibility, and the Unix/X11 AT-SPI standard. Other backends
    can be supported using QAccessibleBridge.

    In the Unix/X11 AT-SPI implementation, applications become accessible
    when two conditions are met:
    \list
    \li org.a11y.Status.IsEnabled DBus property is true
    \li org.a11y.Status.ScreenReaderEnabled DBus property is true
    \endlist
    An alternative to setting the DBus AT-SPI properties is to set
    the QT_LINUX_ACCESSIBILITY_ALWAYS_ON environment variable.

    In addition to QAccessible's static functions, Qt offers one
    generic interface, QAccessibleInterface, that can be used to wrap
    all widgets and objects (e.g., QPushButton). This single
    interface provides all the metadata necessary for the assistive
    technologies. Qt provides implementations of this interface for
    its built-in widgets as plugins.

    When you develop custom widgets, you can create custom subclasses
    of QAccessibleInterface and distribute them as plugins (using
    QAccessiblePlugin) or compile them into the application.
    Likewise, Qt's predefined accessibility support can be built as
    plugin (the default) or directly into the Qt library. The main
    advantage of using plugins is that the accessibility classes are
    only loaded into memory if they are actually used; they don't
    slow down the common case where no assistive technology is being
    used.

    Qt also includes two convenience classes, QAccessibleObject and
    QAccessibleWidget, that inherit from QAccessibleInterface and
    provide the lowest common denominator of metadata (e.g., widget
    geometry, window title, basic help text). You can use them as
    base classes when wrapping your custom QObject or QWidget
    subclasses.

    \sa QAccessibleInterface
*/


/*!
    \class QAccessible::State

    \inmodule QtGui

    This structure defines bit flags that indicate
    the state of an accessible object. The values are:

    \value active                  The object is the active window or the active sub-element in a container (that would get focus when focusing the container).
    \value adjustable              The object represents an adjustable value, e.g. sliders.
    \value animated                The object's appearance changes frequently.
    \value busy                    The object cannot accept input at the moment.
    \value checkable               The object is checkable.
    \value checked                 The object's check box is checked.
    \value checkStateMixed         The third state of checkboxes (half checked in tri-state check boxes).
    \value collapsed               The object is collapsed, e.g. a closed listview item, or an iconified window.
    \value defaultButton           The object represents the default button in a dialog.
    \value defunct                 The object no longer exists.
    \value editable                The object has a text carret (and often implements the text interface).
    \value expandable              The object is expandable, mostly used for cells in a tree view.
    \value expanded                The object is expanded, currently its children are visible.
    \value extSelectable           The object supports extended selection.
    \value focusable               The object can receive focus. Only objects in the active window can receive focus.
    \value focused                 The object has keyboard focus.
    \value hasPopup                The object opens a popup.
    \value hotTracked              The object's appearance is sensitive to the mouse cursor position.
    \value invalid                 The object is no longer valid (because it has been deleted).
    \value invalidEntry            Input validation current input invalid.
    \value invisible               The object is not visible to the user.
    \value linked                  The object is linked to another object, e.g. a hyperlink.
    \value marqueed                The object displays scrolling contents, e.g. a log view.
    \value modal                   The object blocks input from other objects.
    \value movable                 The object can be moved.
    \value multiLine               The object has multiple lines of text (word wrap), as opposed to a single line.
    \value multiSelectable         The object supports multiple selected items.
    \value offscreen               The object is clipped by the visible area. Objects that are off screen are also invisible.
    \value passwordEdit            The object is a password field, e.g. a line edit for entering a Password.
    \value playsSound              The object produces sound when interacted with.
    \value pressed                 The object is pressed.
    \value readOnly                The object can usually be edited, but is explicitly set to read-only.
    \value searchEdit              The object is a line edit that is the input for search queries.
    \value selectable              The object is selectable.
    \value selectableText          The object has text which can be selected. This is different from selectable which refers to the object's children.
    \value selected                The object is selected, this is independent of text selection.
    \value selfVoicing             The object describes itself through speech or sound.
    \value sizeable                The object can be resized, e.g. top-level windows.
    \value summaryElement          The object summarizes the state of the window and should be treated with priority.
    \value supportsAutoCompletion  The object has auto-completion, for example in line edits or combo boxes.
    \value traversed               The object is linked and has been visited.
    \value updatesFrequently       The object changes frequently and needs to be refreshed when accessing it.
    \value disabled                The object is unavailable to the user, e.g. a disabled widget.

    Implementations of QAccessibleInterface::state() return a combination
    of these flags.
*/

/*!
    \fn QAccessible::State::State()

    Constructs a new QAccessible::State with all states set to false.
*/

/*!
    \enum QAccessible::Event

    This enum type defines accessible event types.

    \omitvalue InvalidEvent                 \omit Internal: Used when creating subclasses of QAccessibleEvent. \endomit
    \value AcceleratorChanged               The keyboard accelerator for an action has been changed.
    \value ActionChanged                    An action has been changed.
    \value ActiveDescendantChanged
    \value Alert                            A system alert (e.g., a message from a QMessageBox)
    \value AttributeChanged
    \value ContextHelpEnd                   Context help (QWhatsThis) for an object is finished.
    \value ContextHelpStart                 Context help (QWhatsThis) for an object is initiated.
    \value DefaultActionChanged             The default QAccessible::Action for the accessible
                                            object has changed.
    \value DescriptionChanged               The object's QAccessible::Description changed.
    \value DialogEnd                        A dialog (QDialog) has been hidden
    \value DialogStart                      A dialog (QDialog) has been set visible.
    \value DocumentContentChanged           The contents of a text document have changed.
    \value DocumentLoadComplete             A document has been loaded.
    \value DocumentLoadStopped              A document load has been stopped.
    \value DocumentReload                   A document reload has been initiated.
    \value DragDropEnd                      A drag and drop operation is about to finished.
    \value DragDropStart                    A drag and drop operation is about to be initiated.
    \value Focus                            An object has gained keyboard focus.
    \value ForegroundChanged                A window has been activated (i.e., a new window has
                                            gained focus on the desktop).
    \value HelpChanged                      The QAccessible::Help text property of an object has
                                            changed.
    \value HyperlinkEndIndexChanged         The end position of the display text for a hypertext
                                            link has changed.
    \value HyperlinkNumberOfAnchorsChanged  The number of anchors in a hypertext link has changed,
                                            perhaps because the display text has been split to
                                            provide more than one link.
    \value HyperlinkSelectedLinkChanged     The link for the selected hypertext link has changed.
    \value HyperlinkStartIndexChanged       The start position of the display text for a hypertext
                                            link has changed.
    \value HypertextChanged                 The display text for a hypertext link has changed.
    \value HypertextLinkActivated           A hypertext link has been activated, perhaps by being
                                            clicked or via a key press.
    \value HypertextLinkSelected            A hypertext link has been selected.
    \value HypertextNLinksChanged
    \value LocationChanged                  An object's location on the screen has changed.
    \value MenuCommand                      A menu item is triggered.
    \value MenuEnd                          A menu has been closed (Qt uses PopupMenuEnd for all
                                            menus).
    \value MenuStart                        A menu has been opened on the menubar (Qt uses
                                            PopupMenuStart for all menus).
    \value NameChanged                      The QAccessible::Name property of an object has changed.
    \value ObjectAttributeChanged
    \value ObjectCreated                    A new object is created.
    \value ObjectDestroyed                  An object is deleted.
    \value ObjectHide                       An object is hidden; for example, with QWidget::hide().
                                            Any children the object that is hidden has do not send
                                            this event. It is not sent when an object is hidden as
                                            it is being obcured by others.
    \value ObjectReorder                    A layout or item view  has added, removed, or moved an
                                            object (Qt does not use this event).
    \value ObjectShow                       An object is displayed; for example, with
                                            QWidget::show().
    \value PageChanged
    \value ParentChanged                    An object's parent object changed.
    \value PopupMenuEnd                     A pop-up menu has closed.
    \value PopupMenuStart                   A pop-up menu has opened.
    \value ScrollingEnd                     A scrollbar scroll operation has ended (the mouse has
                                            released the slider handle).
    \value ScrollingStart                   A scrollbar scroll operation is about to start; this may
                                            be caused by a mouse press on the slider handle, for
                                            example.
    \value SectionChanged
    \value SelectionAdd                     An item has been added to the selection in an item view.
    \value SelectionRemove                  An item has been removed from an item view selection.
    \value Selection                        The selection has changed in a menu or item view.
    \value SelectionWithin                  Several changes to a selection has occurred in an item
                                            view.
    \value SoundPlayed                      A sound has been played by an object
    \omitvalue StateChanged                 \omit The QAccessible::State of an object has changed.
                                            This value is used internally for the QAccessibleStateChangeEvent. \endomit
    \value TableCaptionChanged              A table caption has been changed.
    \value TableColumnDescriptionChanged    The description of a table column, typically found in
                                            the column's header, has been changed.
    \value TableColumnHeaderChanged         A table column header has been changed.
    \omitvalue TableModelChanged            \omit The model providing data for a table has been changed. \endomit
    \value TableRowDescriptionChanged       The description of a table row, typically found in the
                                            row's header, has been changed.
    \value TableRowHeaderChanged            A table row header has been changed.
    \value TableSummaryChanged              The summary of a table has been changed.
    \omitvalue TextAttributeChanged
    \omitvalue TextCaretMoved               \omit The caret has moved in an editable widget.
                                            The caret represents the cursor position in an editable
                                            widget with the input focus. \endomit
    \value TextColumnChanged                A text column has been changed.
    \omitvalue TextInserted                 \omit Text has been inserted into an editable widget. \endomit
    \omitvalue TextRemoved                  \omit Text has been removed from an editable widget. \endomit
    \omitvalue TextSelectionChanged         \omit The selected text has changed in an editable widget. \endomit
    \omitvalue TextUpdated                  \omit The text has been update in an editable widget. \endomit
    \omitvalue ValueChanged                 \omit The QAccessible::Value of an object has changed. \endomit
    \value VisibleDataChanged

    The values for this enum are defined to be the same as those defined in the
    \l{AccessibleEventID.idl File Reference}{IAccessible2} and
    \l{Microsoft Active Accessibility Event Constants}{MSAA} specifications.
*/

/*!
    \enum QAccessible::Role

    This enum defines the role of an accessible object. The roles are:

    \value AlertMessage     An object that is used to alert the user.
    \value Animation        An object that displays an animation.
    \value Application      The application's main window.
    \value Assistant        An object that provids interactive help.
    \value Border           An object that represents a border.
    \value ButtonDropDown   A button that drops down a list of items.
    \value ButtonDropGrid   A button that drops down a grid.
    \value ButtonMenu       A button that drops down a menu.
    \value Canvas           An object that displays graphics that the user can interact with.
    \value Caret            An object that represents the system caret (text cursor).
    \value Cell             A cell in a table.
    \value Chart            An object that displays a graphical representation of data.
    \value CheckBox         An object that represents an option that can be checked or unchecked. Some options provide a "mixed" state, e.g. neither checked nor unchecked.
    \value Client           The client area in a window.
    \value Clock            A clock displaying time.
    \value ColorChooser     A dialog that lets the user choose a color.
    \value Column           A column of cells, usually within a table.
    \value ColumnHeader     A header for a column of data.
    \value ComboBox         A list of choices that the user can select from.
    \value ComplementaryContent A part of the document or web page that is complementary to the main content, usually a landmark (see WAI-ARIA).
    \value Cursor           An object that represents the mouse cursor.
    \value Desktop          The object represents the desktop or workspace.
    \value Dial             An object that represents a dial or knob.
    \value Dialog           A dialog box.
    \value Document         A document, for example in an office application.
    \value EditableText     Editable text such as a line or text edit.
    \value Equation         An object that represents a mathematical equation.
    \value Footer           A footer in a page (usually in documents).
    \value Form             A web form containing controls.
    \value Graphic          A graphic or picture, e.g. an icon.
    \value Grip             A grip that the user can drag to change the size of widgets.
    \value Grouping         An object that represents a logical grouping of other objects.
    \value Heading          A heading in a document.
    \value HelpBalloon      An object that displays help in a separate, short lived window.
    \value HotkeyField      A hotkey field that allows the user to enter a key sequence.
    \value Indicator        An indicator that represents a current value or item.
    \value LayeredPane      An object that can contain layered children, e.g. in a stack.
    \value Link             A link to something else.
    \value List             A list of items, from which the user can select one or more items.
    \value ListItem         An item in a list of items.
    \value MenuBar          A menu bar from which menus are opened by the user.
    \value MenuItem         An item in a menu or menu bar.
    \value NoRole           The object has no role. This usually indicates an invalid object.
    \value Note             A section whose content is parenthetic or ancillary to the main content of the resource.
    \value Notification     An object that represents a notification (e.g. in the system tray). This role only has an effect on Linux.
    \value PageTab          A page tab that the user can select to switch to a different page in a dialog.
    \value PageTabList      A list of page tabs.
    \value Paragraph        A paragraph of text (usually found in documents).
    \value Pane             A generic container.
    \value PopupMenu        A menu which lists options that the user can select to perform an action.
    \value ProgressBar      The object displays the progress of an operation in progress.
    \value PropertyPage     A property page where the user can change options and settings.
    \value Button           A button.
    \value RadioButton      An object that represents an option that is mutually exclusive with other options.
    \value Row              A row of cells, usually within a table.
    \value RowHeader        A header for a row of data.
    \value ScrollBar        A scroll bar, which allows the user to scroll the visible area.
    \value Section          A section (in a document).
    \value Separator        A separator that divides space into logical areas.
    \value Slider           A slider that allows the user to select a value within a given range.
    \value Sound            An object that represents a sound.
    \value SpinBox          A spin box widget that allows the user to enter a value within a given range.
    \value Splitter         A splitter distributing available space between its child widgets.
    \value StaticText       Static text, such as labels for other widgets.
    \value StatusBar        A status bar.
    \value Table            A table representing data in a grid of rows and columns.
    \value Terminal         A terminal or command line interface.
    \value TitleBar         The title bar caption of a window.
    \value ToolBar          A tool bar, which groups widgets that the user accesses frequently.
    \value ToolTip          A tool tip which provides information about other objects.
    \value Tree             A list of items in a tree structure.
    \value TreeItem         An item in a tree structure.
    \value UserRole         The first value to be used for user defined roles.
    \value WebDocument      HTML document, usually in a browser.
    \value Whitespace       Blank space between other objects.
    \value Window           A top level window.
*/

/*!
    \enum QAccessible::RelationFlag

    This enum type defines bit flags that can be combined to indicate
    the relationship between two accessible objects.

    \value Label            The first object is the label of the second object.
    \value Labelled         The first object is labelled by the second object.
    \value Controller       The first object controls the second object.
    \value Controlled       The first object is controlled by the second object.
    \value AllRelations     Used as a mask to specify that we are interesting in information
                            about all relations

    Implementations of relations() return a combination of these flags.
    Some values are mutually exclusive.
*/

/*!
    \enum QAccessible::Text

    This enum specifies string information that an accessible object
    returns.

    \value Name         The name of the object. This can be used both
                        as an identifier or a short description by
                        accessible clients.
    \value Description  A short text describing the object.
    \value Value        The value of the object.
    \value Help         A longer text giving information about how to use the object.
    \value Accelerator  The keyboard shortcut that executes the object's default action.
    \value UserText     The first value to be used for user defined text.
    \omitvalue DebugDescription
*/

/*! \enum QAccessible::TextBoundaryType
    This enum describes different types of text boundaries. It follows the IAccessible2 API and is used in the \l QAccessibleTextInterface.

    \value CharBoundary         Use individual characters as boundary.
    \value WordBoundary         Use words as boundaries.
    \value SentenceBoundary     Use sentences as boundary.
    \value ParagraphBoundary    Use paragraphs as boundary.
    \value LineBoundary         Use newlines as boundary.
    \value NoBoundary           No boundary (use the whole text).

    \sa QAccessibleTextInterface
*/


/*!
    \enum QAccessible::InterfaceType

    \l QAccessibleInterface supports several sub interfaces.
    In order to provide more information about some objects, their accessible
    representation should implement one or more of these interfaces.

    \note When subclassing one of these interfaces, \l QAccessibleInterface::interface_cast() needs to be implemented.

    \value TextInterface            For text that supports selections or is more than one line. Simple labels do not need to implement this interface.
    \omitvalue EditableTextInterface    \omit For text that can be edited by the user. \endomit
    \value ValueInterface           For objects that are used to manipulate a value, for example slider or scroll bar.
    \value ActionInterface          For interactive objects that allow the user to trigger an action. Basically everything that allows for example mouse interaction.
    \omitvalue ImageInterface       \omit For objects that represent an image. This interface is generally less important. \endomit
    \value TableInterface           For lists, tables and trees.
    \value TableCellInterface       For cells in a TableInterface object.

    \sa QAccessibleInterface::interface_cast(), QAccessibleTextInterface, QAccessibleValueInterface, QAccessibleActionInterface, QAccessibleTableInterface, QAccessibleTableCellInterface
*/

#ifndef QT_NO_ACCESSIBILITY

/*!
    Destroys the QAccessibleInterface.
*/
QAccessibleInterface::~QAccessibleInterface()
{
}

/*!
    \typedef QAccessible::Id

    Synonym for unsigned, used by the QAccessibleInterface cache.
*/


/* accessible widgets plugin discovery stuff */
Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
    (QAccessibleFactoryInterface_iid, QLatin1String("/accessible")))
typedef QHash<QString, QAccessiblePlugin*> QAccessiblePluginsHash;
Q_GLOBAL_STATIC(QAccessiblePluginsHash, qAccessiblePlugins)

// FIXME turn this into one global static struct
Q_GLOBAL_STATIC(QList<QAccessible::InterfaceFactory>, qAccessibleFactories)
Q_GLOBAL_STATIC(QList<QAccessible::ActivationObserver *>, qAccessibleActivationObservers)

QAccessible::UpdateHandler QAccessible::updateHandler = nullptr;
QAccessible::RootObjectHandler QAccessible::rootObjectHandler = nullptr;

static bool cleanupAdded = false;

static QPlatformAccessibility *platformAccessibility()
{
    QPlatformIntegration *pfIntegration = QGuiApplicationPrivate::platformIntegration();
    return pfIntegration ? pfIntegration->accessibility() : nullptr;
}

/*!
    \fn QAccessible::QAccessible()
    \internal

    This class is purely a collection of enums and static functions,
    it is not supposed to be instantiated.
*/


/*!
    \internal
*/
void QAccessible::cleanup()
{
    if (QPlatformAccessibility *pfAccessibility = platformAccessibility())
        pfAccessibility->cleanup();
}

static void qAccessibleCleanup()
{
    qAccessibleActivationObservers()->clear();
    qAccessibleFactories()->clear();
}

/*!
    \typedef QAccessible::InterfaceFactory

    This is a typedef for a pointer to a function with the following
    signature:

    \snippet code/src_gui_accessible_qaccessible.cpp 1

    The function receives a QString and a QObject pointer, where the
    QString is the key identifying the interface. The QObject is used
    to pass on to the QAccessibleInterface so that it can hold a reference
    to it.

    If the key and the QObject does not have a corresponding
    QAccessibleInterface, \nullptr will be returned.

    Installed factories are called by queryAccessibilityInterface() until
    one provides an interface.
*/

/*!
    \typedef QAccessible::UpdateHandler

    \internal

    A function pointer type. Use a function with this prototype to install
    your own update function.

    The function is called by updateAccessibility().
*/

/*!
    \typedef QAccessible::RootObjectHandler

    \internal

    A function pointer type. Use a function with this prototype to install
    your own root object handler.

    The function is called by setRootObject().
*/


/*!
    Installs the InterfaceFactory \a factory. The last factory added
    is the first one used by queryAccessibleInterface().
*/
void QAccessible::installFactory(InterfaceFactory factory)
{
    if (!factory)
        return;

    if (!cleanupAdded) {
        qAddPostRoutine(qAccessibleCleanup);
        cleanupAdded = true;
    }
    if (qAccessibleFactories()->contains(factory))
        return;
    qAccessibleFactories()->append(factory);
}

/*!
    Removes \a factory from the list of installed InterfaceFactories.
*/
void QAccessible::removeFactory(InterfaceFactory factory)
{
    qAccessibleFactories()->removeAll(factory);
}

/*!
    \internal

    Installs the given \a handler as the function to be used by
    updateAccessibility(), and returns the previously installed
    handler.
*/
QAccessible::UpdateHandler QAccessible::installUpdateHandler(UpdateHandler handler)
{
    UpdateHandler old = updateHandler;
    updateHandler = handler;
    return old;
}

/*!
    \internal

    Installs the given \a handler as the function to be used by setRootObject(),
    and returns the previously installed handler.
*/
QAccessible::RootObjectHandler QAccessible::installRootObjectHandler(RootObjectHandler handler)
{
    RootObjectHandler old = rootObjectHandler;
    rootObjectHandler = handler;
    return old;
}

/*!
    \class QAccessible::ActivationObserver
    \internal

    Interface to listen to activation or deactivation of the accessibility framework.
    \sa installActivationObserver()
*/

QAccessible::ActivationObserver::~ActivationObserver()
{
    // must be empty until ### Qt 6
}

/*!
    \internal

    Install \a observer to get notified of activation or deactivation (global accessibility has been enabled or disabled).
*/
void QAccessible::installActivationObserver(QAccessible::ActivationObserver *observer)
{
    if (!observer)
        return;

    if (!cleanupAdded) {
        qAddPostRoutine(qAccessibleCleanup);
        cleanupAdded = true;
    }
    if (qAccessibleActivationObservers()->contains(observer))
        return;
    qAccessibleActivationObservers()->append(observer);
}

/*!
    \internal

    Remove an \a observer to no longer get notified of state changes.
    \sa installActivationObserver()
*/
void QAccessible::removeActivationObserver(ActivationObserver *observer)
{
    qAccessibleActivationObservers()->removeAll(observer);
}

/*!
    If a QAccessibleInterface implementation exists for the given \a object,
    this function returns a pointer to the implementation; otherwise it
    returns \nullptr.

    The function calls all installed factory functions (from most
    recently installed to least recently installed) until one is found
    that provides an interface for the class of \a object. If no
    factory can provide an accessibility implementation for the class
    the function loads installed accessibility plugins, and tests if
    any of the plugins can provide the implementation.

    If no implementation for the object's class is available, the
    function tries to find an implementation for the object's parent
    class, using the above strategy.

    All interfaces are managed by an internal cache and should not be deleted.
*/
QAccessibleInterface *QAccessible::queryAccessibleInterface(QObject *object)
{
    if (!object)
        return nullptr;

    if (Id id = QAccessibleCache::instance()->objectToId.value(object))
        return QAccessibleCache::instance()->interfaceForId(id);

    // Create a QAccessibleInterface for the object class. Start by the most
    // derived class and walk up the class hierarchy.
    const QMetaObject *mo = object->metaObject();
    while (mo) {
        const QString cn = QLatin1String(mo->className());

        // Check if the class has a InterfaceFactory installed.
        for (int i = qAccessibleFactories()->count(); i > 0; --i) {
            InterfaceFactory factory = qAccessibleFactories()->at(i - 1);
            if (QAccessibleInterface *iface = factory(cn, object)) {
                QAccessibleCache::instance()->insert(object, iface);
                Q_ASSERT(QAccessibleCache::instance()->objectToId.contains(object));
                return iface;
            }
        }
        // Find a QAccessiblePlugin (factory) for the class name. If there's
        // no entry in the cache try to create it using the plugin loader.
        if (!qAccessiblePlugins()->contains(cn)) {
            QAccessiblePlugin *factory = nullptr; // 0 means "no plugin found". This is cached as well.
            const int index = loader()->indexOf(cn);
            if (index != -1)
                factory = qobject_cast<QAccessiblePlugin *>(loader()->instance(index));
            qAccessiblePlugins()->insert(cn, factory);
        }

        // At this point the cache should contain a valid factory pointer or 0:
        Q_ASSERT(qAccessiblePlugins()->contains(cn));
        QAccessiblePlugin *factory = qAccessiblePlugins()->value(cn);
        if (factory) {
            QAccessibleInterface *result = factory->create(cn, object);
            if (result) {   // Need this condition because of QDesktopScreenWidget
                QAccessibleCache::instance()->insert(object, result);
                Q_ASSERT(QAccessibleCache::instance()->objectToId.contains(object));
            }
            return result;
        }
        mo = mo->superClass();
    }

    if (object == qApp) {
        QAccessibleInterface *appInterface = new QAccessibleApplication;
        QAccessibleCache::instance()->insert(object, appInterface);
        Q_ASSERT(QAccessibleCache::instance()->objectToId.contains(qApp));
        return appInterface;
    }

    return nullptr;
}

/*!
    \brief Call this function to ensure that manually created interfaces
    are properly memory managed.

    Must only be called exactly once per interface \a iface.
    This is implicitly called when calling queryAccessibleInterface,
    calling this function is only required when QAccessibleInterfaces
    are instantiated with the "new" operator. This is not recommended,
    whenever possible use the default functions and let \l queryAccessibleInterface()
    take care of this.

    When it is necessary to reimplement the QAccessibleInterface::child() function
    and returning the child after constructing it, this function needs to be called.
 */
QAccessible::Id QAccessible::registerAccessibleInterface(QAccessibleInterface *iface)
{
    Q_ASSERT(iface);
    return QAccessibleCache::instance()->insert(iface->object(), iface);
}

/*!
    Removes the interface belonging to this \a id from the cache and
    deletes it. The id becomes invalid an may be re-used by the
    cache.
*/
void QAccessible::deleteAccessibleInterface(Id id)
{
    QAccessibleCache::instance()->deleteInterface(id);
}

/*!
    Returns the unique ID for the QAccessibleInterface \a iface.
*/
QAccessible::Id QAccessible::uniqueId(QAccessibleInterface *iface)
{
    Id id = QAccessibleCache::instance()->idForInterface(iface);
    if (!id)
        id = registerAccessibleInterface(iface);
    return id;
}

/*!
    Returns the QAccessibleInterface belonging to the \a id.

    Returns \nullptr if the id is invalid.
*/
QAccessibleInterface *QAccessible::accessibleInterface(Id id)
{
    return QAccessibleCache::instance()->interfaceForId(id);
}


/*!
    Returns \c true if the platform requested accessibility information.

    This function will return false until a tool such as a screen reader
    accessed the accessibility framework. It is still possible to use
    \l QAccessible::queryAccessibleInterface() even if accessibility is not
    active. But there will be no notifications sent to the platform.

    It is recommended to use this function to prevent expensive notifications
    via updateAccessibility() when they are not needed.
*/
bool QAccessible::isActive()
{
    if (QPlatformAccessibility *pfAccessibility = platformAccessibility())
        return pfAccessibility->isActive();
    return false;
}

/*!
    \internal
*/
void QAccessible::setActive(bool active)
{
    for (int i = 0; i < qAccessibleActivationObservers()->count() ;++i)
        qAccessibleActivationObservers()->at(i)->accessibilityActiveChanged(active);
}


/*!
  Sets the root object of the accessible objects of this application
  to \a object.  All other accessible objects are reachable using object
  navigation from the root object.

  Normally, it isn't necessary to call this function, because Qt sets
  the QApplication object as the root object immediately before the
  event loop is entered in QApplication::exec().

  Use QAccessible::installRootObjectHandler() to redirect the function
  call to a customized handler function.

  \sa queryAccessibleInterface()
*/
void QAccessible::setRootObject(QObject *object)
{
    if (rootObjectHandler) {
        rootObjectHandler(object);
        return;
    }

    if (QPlatformAccessibility *pfAccessibility = platformAccessibility())
        pfAccessibility->setRootObject(object);
}

/*!
  Notifies about a change that might be relevant for accessibility clients.

  \a event provides details about the change. These include the source
  of the change and the nature of the change.  The \a event should
  contain enough information give meaningful notifications.

  For example, the type \c ValueChange indicates that the position of
  a slider has been changed.

  Call this function whenever the state of your accessible object or
  one of its sub-elements has been changed either programmatically
  (e.g. by calling QLabel::setText()) or by user interaction.

  If there are no accessibility tools listening to this event, the
  performance penalty for calling this function is small, but if
  determining the parameters of the call is expensive you can test
  QAccessible::isActive() to avoid unnecessary computation.
*/
void QAccessible::updateAccessibility(QAccessibleEvent *event)
{
    // NOTE: Querying for the accessibleInterface below will result in
    // resolving and caching the interface, which in some cases will
    // cache the wrong information as updateAccessibility is called
    // during construction of widgets. If you see cases where the
    // cache seems wrong, this call is "to blame", but the code that
    // caches dynamic data should be updated to handle change events.
    QAccessibleInterface *iface = event->accessibleInterface();
    if (isActive() && iface) {
        if (event->type() == QAccessible::TableModelChanged) {
            if (iface->tableInterface())
                iface->tableInterface()->modelChange(static_cast<QAccessibleTableModelChangeEvent*>(event));
        }

        if (updateHandler) {
            updateHandler(event);
            return;
        }
    }

    if (QPlatformAccessibility *pfAccessibility = platformAccessibility())
        pfAccessibility->notifyAccessibilityUpdate(event);
}

#if QT_DEPRECATED_SINCE(5, 0)
/*!
    \obsolete
    \fn void QAccessible::updateAccessibility(QObject *object, int child, Event reason);

    \brief Use QAccessible::updateAccessibility(QAccessibleEvent*) instead.
*/
#endif

/*!
    \internal
    \brief getBoundaries is a helper function to find the accessible text boundaries for QTextCursor based documents.
    \param documentCursor a valid cursor bound to the document (not null). It needs to ba at the position to look for the boundary
    \param boundaryType the type of boundary to find
    \return the boundaries as pair
*/
QPair< int, int > QAccessible::qAccessibleTextBoundaryHelper(const QTextCursor &offsetCursor, TextBoundaryType boundaryType)
{
    Q_ASSERT(!offsetCursor.isNull());

    QTextCursor endCursor = offsetCursor;
    endCursor.movePosition(QTextCursor::End);
    int characterCount = endCursor.position();

    QPair<int, int> result;
    QTextCursor cursor = offsetCursor;
    switch (boundaryType) {
    case CharBoundary:
        result.first = cursor.position();
        cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);
        result.second = cursor.position();
        break;
    case WordBoundary:
        cursor.movePosition(QTextCursor::StartOfWord, QTextCursor::MoveAnchor);
        result.first = cursor.position();
        cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
        result.second = cursor.position();
        break;
    case SentenceBoundary: {
        // QCursor does not provide functionality to move to next sentence.
        // We therefore find the current block, then go through the block using
        // QTextBoundaryFinder and find the sentence the \offset represents
        cursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::MoveAnchor);
        result.first = cursor.position();
        cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
        result.second = cursor.position();
        QString blockText = cursor.selectedText();
        const int offsetWithinBlockText = offsetCursor.position() - result.first;
        QTextBoundaryFinder sentenceFinder(QTextBoundaryFinder::Sentence, blockText);
        sentenceFinder.setPosition(offsetWithinBlockText);
        int prevBoundary = offsetWithinBlockText;
        int nextBoundary = offsetWithinBlockText;
        if (!(sentenceFinder.boundaryReasons() & QTextBoundaryFinder::StartOfItem))
            prevBoundary = sentenceFinder.toPreviousBoundary();
        nextBoundary = sentenceFinder.toNextBoundary();
        if (nextBoundary != -1)
            result.second = result.first + nextBoundary;
        if (prevBoundary != -1)
            result.first += prevBoundary;
        break; }
    case LineBoundary:
        cursor.movePosition(QTextCursor::StartOfLine, QTextCursor::MoveAnchor);
        result.first = cursor.position();
        cursor.movePosition(QTextCursor::EndOfLine, QTextCursor::KeepAnchor);
        result.second = cursor.position();
        break;
    case ParagraphBoundary:
        cursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::MoveAnchor);
        result.first = cursor.position();
        cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
        result.second = cursor.position();
        break;
    case NoBoundary:
        result.first = 0;
        result.second = characterCount;
        break;
    }
    return result;
}

/*!
    \class QAccessibleInterface
    \brief The QAccessibleInterface class defines an interface that exposes information
    about accessible objects.

    \ingroup accessibility
    \inmodule QtGui

    This class is part of \l {Accessibility for QWidget Applications}.

    Accessibility tools (also called AT Clients), such as screen readers
    or braille displays, require high-level information about
    accessible objects in an application. Accessible objects provide
    specialized input and output methods, making it possible for users
    to use accessibility tools with enabled applications (AT Servers).

    Every element that the user needs to interact with or react to is
    an accessible object, and should provide this information. These
    are mainly visual objects, such as widgets and widget elements, but
    can also be content, such as sounds.

    The AT client uses three basic concepts to acquire information
    about any accessible object in an application:
    \list
    \li \e Properties The client can read information about
    accessible objects. In some cases the client can also modify these
    properties; such as text in a line edit.
    \li \e Actions The client can invoke actions like pressing a button
    or .
    \li \e{Relationships and Navigation} The client can traverse from one
    accessible object to another, using the relationships between objects.
    \endlist

    The QAccessibleInterface defines the API for these three concepts.

    \section1 Relationships and Navigation

    The functions childCount() and indexOfChild() return the number of
    children of an accessible object and the index a child object has
    in its parent. The childAt() function returns a child QAccessibleInterface
    that is found at a position. The child does not have to be a direct
    child. This allows bypassing intermediate layers when the parent already knows the
    top-most child. childAt() is used for hit testing (finding the object
    under the mouse).

    The relations() function provides information about the relations an
    object has to other objects, and parent() and child() allows
    traversing from one object to another object.

    \section1 Properties

    The central property of an accessible objects is what role() it
    has. Different objects can have the same role, e.g. both the "Add
    line" element in a scroll bar and the \c OK button in a dialog have
    the same role, "button". The role implies what kind of
    interaction the user can perform with the user interface element.

    An object's state() property is a combination of different state
    flags and can describe both how the object's state differs from a
    "normal" state, e.g. it might be unavailable, and also how it
    behaves, e.g. it might be selectable.

    The text() property provides textual information about the object.
    An object usually has a name, but can provide extended information
    such as a description, help text, or information about any
    keyboard accelerators it provides. Some objects allow changing the
    text() property through the setText() function, but this
    information is in most cases read-only.

    The rect() property provides information about the geometry of an
    accessible object. This information is usually only available for
    visual objects.

    \section1 Interfaces

    To enable the user to interact with an accessible object the
    object must implement QAccessibleActionInterface in addition to
    QAccessibleInterface.
    Objects that support selections can define actions to change the selection.

    There are several other interfaces that should be implemented as required.
    QAccessibleTextInterface should be used for bigger texts edits such as document views.
    This interface should not be implemented for labels/single line edits.

    For sliders, scrollbars and other numerical value selectors QAccessibleValueInterface
    should be implemented.

    Lists, tables and trees should implement QAccessibleTableInterface.

    \sa QAccessible, QAccessibleActionInterface, QAccessibleTextInterface, QAccessibleValueInterface, QAccessibleTableInterface
*/

/*!
    \fn bool QAccessibleInterface::isValid() const

    Returns \c true if all the data necessary to use this interface
    implementation is valid (e.g. all pointers are non-null);
    otherwise returns \c false.

    \sa object()
*/

/*!
    \fn QObject *QAccessibleInterface::object() const

    Returns a pointer to the QObject this interface implementation provides
    information for.

    \sa isValid()
*/

/*!
    \fn int QAccessibleInterface::childCount() const

    Returns the number of children that belong to this object. A child
    can provide accessibility information on its own (e.g. a child
    widget), or be a sub-element of this accessible object.

    All objects provide this information.

    \sa indexOfChild()
*/

/*!
    \fn int QAccessibleInterface::indexOfChild(const QAccessibleInterface *child) const

    Returns the 0-based index of the object \a child in this object's
    children list, or -1 if \a child is not a child of this object.

    All objects provide this information about their children.

    \sa childCount()
*/

/*!
    Returns the meaningful relations to other widgets. Usually this will not return parent/child
    relations, unless they are handled in a specific way such as in tree views.
    It will typically return the labelled-by and label relations.

    It is possible to filter the relations by using \a match.
    It should never return itself.

    \sa parent(), child()
*/
QVector<QPair<QAccessibleInterface*, QAccessible::Relation> >
QAccessibleInterface::relations(QAccessible::Relation /*match = QAccessible::AllRelations*/) const
{
    return QVector<QPair<QAccessibleInterface*, QAccessible::Relation> >();
}

/*!
    Returns the object that has the keyboard focus.

    The object returned can be any descendant, including itself.
*/
QAccessibleInterface *QAccessibleInterface::focusChild() const
{
    return nullptr;
}

/*!
    \fn QAccessibleInterface *QAccessibleInterface::childAt(int x, int y) const

    Returns the QAccessibleInterface of a child that contains the screen coordinates (\a x, \a y).
    If there are no children at this position this function returns \nullptr.
    The returned accessible must be a child, but not necessarily a direct child.

    This function is only relyable for visible objects (invisible
    object might not be laid out correctly).

    All visual objects provide this information.

    A default implementation is provided for objects inheriting QAccessibleObject. This will iterate
    over all children. If the widget manages its children (e.g. a table) it will be more efficient
    to write a specialized implementation.

    \sa rect()
*/

/*!
    \fn QAccessibleInterface* QAccessibleInterface::parent() const

    Returns the QAccessibleInterface of the parent in the accessible object hierarchy.

    Returns \nullptr if no parent exists (e.g. for the top level application object).

    \sa child()
*/

/*!
    \fn QAccessibleInterface* QAccessibleInterface::child(int index) const

    Returns the accessible child with index \a index.
    0-based index. The number of children of an object can be checked with childCount.

    Returns \nullptr when asking for an invalid child (e.g. when the child became invalid in the meantime).

    \sa childCount(), parent()
*/

/*!
    \fn QString QAccessibleInterface::text(QAccessible::Text t) const

    Returns the value of the text property \a t of the object.

    The \l QAccessible::Name is a string used by clients to identify, find, or
    announce an accessible object for the user. All objects must have
    a name that is unique within their container. The name can be
    used differently by clients, so the name should both give a
    short description of the object and be unique.

    An accessible object's \l QAccessible::Description provides textual information
    about an object's visual appearance. The description is primarily
    used to provide greater context for vision-impaired users, but is
    also used for context searching or other applications. Not all
    objects have a description. An "OK" button would not need a
    description, but a tool button that shows a picture of a smiley
    would.

    The \l QAccessible::Value of an accessible object represents visual information
    contained by the object, e.g. the text in a line edit. Usually,
    the value can be modified by the user. Not all objects have a
    value, e.g. static text labels don't, and some objects have a
    state that already is the value, e.g. toggle buttons.

    The \l QAccessible::Help text provides information about the function and
    usage of an accessible object. Not all objects provide this
    information.

    The \l QAccessible::Accelerator is a keyboard shortcut that activates the
    object's default action. A keyboard shortcut is the underlined
    character in the text of a menu, menu item or widget, and is
    either the character itself, or a combination of this character
    and a modifier key like Alt, Ctrl or Shift. Command controls like
    tool buttons also have shortcut keys and usually display them in
    their tooltip.

    All objects provide a string for \l QAccessible::Name.

    \sa role(), state()
*/

/*!
    \fn void QAccessibleInterface::setText(QAccessible::Text t, const QString &text)

    Sets the text property \a t of the object to \a text.

    Note that the text properties of most objects are read-only
    so calling this function might have no effect.

    \sa text()
*/

/*!
    \fn QRect QAccessibleInterface::rect() const

    Returns the geometry of the object. The geometry is in screen coordinates.

    This function is only reliable for visible objects (invisible
    objects might not be laid out correctly).

    All visual objects provide this information.

    \sa childAt()
*/

/*!
    \fn QAccessible::Role QAccessibleInterface::role() const

    Returns the role of the object.
    The role of an object is usually static.

    All accessible objects have a role.

    \sa text(), state()
*/

/*!
    \fn QAccessible::State QAccessibleInterface::state() const

    Returns the current state of the object.
    The returned value is a combination of the flags in
    the QAccessible::StateFlag enumeration.

    All accessible objects have a state.

    \sa text(), role()
*/

/*!
    Returns the accessible's foreground color if applicable or an invalid QColor.

    \sa backgroundColor()
*/
QColor QAccessibleInterface::foregroundColor() const
{
    return QColor();
}

/*!
    Returns the accessible's background color if applicable or an invalid QColor.

    \sa foregroundColor()
*/
QColor QAccessibleInterface::backgroundColor() const
{
    return QColor();
}

/*!
    \fn QAccessibleTextInterface *QAccessibleInterface::textInterface()
*/

/*!
    \fn QAccessibleTextInterface *QAccessibleInterface::editableTextInterface()
    \internal
*/

/*!
    \fn QAccessibleValueInterface *QAccessibleInterface::valueInterface()
*/

/*!
    \fn QAccessibleTableInterface *QAccessibleInterface::tableInterface()
*/

/*!
    \fn QAccessibleTableCellInterface *QAccessibleInterface::tableCellInterface()
*/

/*!
    \fn QAccessibleActionInterface *QAccessibleInterface::actionInterface()
*/

/*!
    \fn QAccessibleImageInterface *QAccessibleInterface::imageInterface()
    \internal
*/

/*!
    \class QAccessibleEvent
    \ingroup accessibility
    \inmodule QtGui

    \brief The QAccessibleEvent class is the base class for accessibility notifications.

    This class is used with \l QAccessible::updateAccessibility().

    The event type is one of the values of \l QAccessible::Event.
    There are a number of subclasses that should be used to provide more details about the
    event.

    For example to notify about a focus change when re-implementing QWidget::setFocus,
    the event could be used as follows:
    \snippet code/src_gui_accessible_qaccessible.cpp 2

    To enable in process screen readers, all events must be sent after the change has happened.
*/

/*! \fn QAccessibleEvent::QAccessibleEvent(QObject *object, QAccessible::Event type)

    Constructs a QAccessibleEvent to notify that \a object has changed.
    The event \a type describes what changed.
*/

/*! \fn QAccessibleEvent::QAccessibleEvent(QAccessibleInterface *interface, QAccessible::Event type)

    Constructs a QAccessibleEvent to notify that \a interface has changed.
    The event \a type describes what changed.
    Use this function if you already have a QAccessibleInterface or no QObject, otherwise consider
    the overload taking a \l QObject parameter as it might be cheaper.
*/

/*!
  Destroys the event.
*/
QAccessibleEvent::~QAccessibleEvent()
{
    // must be empty until ### Qt 6
}

/*! \fn QAccessible::Event QAccessibleEvent::type() const
  Returns the event type.
*/

/*! \fn QObject* QAccessibleEvent::object() const
  Returns the event object.
*/

/*! \fn void QAccessibleEvent::setChild(int child)
  Sets the child index to \a child.
*/

/*! \fn int QAccessibleEvent::child() const
  Returns the child index.
*/

/*!
    \internal
    Returns the uniqueId of the QAccessibleInterface represented by this event.

    In case the object() function returns \nullptr, this is the only way to access the
    interface.
*/
QAccessible::Id QAccessibleEvent::uniqueId() const
{
    if (!m_object)
        return m_uniqueId;
    QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(m_object);
    if (!iface)
        return 0;
    if (m_child != -1) {
        iface = iface->child(m_child);
        if (Q_UNLIKELY(!iface)) {
            qCWarning(lcAccessibilityCore) << "Invalid child in QAccessibleEvent:" << m_object << "child:" << m_child;
            return 0;
        }
    }
    return QAccessible::uniqueId(iface);
}

/*!
    \class QAccessibleValueChangeEvent
    \ingroup accessibility
    \inmodule QtGui

    \brief The QAccessibleValueChangeEvent describes a change in value for an accessible object.

    It contains the new value.

    This class is used with \l QAccessible::updateAccessibility().
*/

/*! \fn QAccessibleValueChangeEvent::QAccessibleValueChangeEvent(QObject *object, const QVariant &value)

    Constructs a new QAccessibleValueChangeEvent for \a object.
    The event contains the new \a value.
*/
/*! \fn QAccessibleValueChangeEvent::QAccessibleValueChangeEvent(QAccessibleInterface *iface, const QVariant &val)

    Constructs a new QAccessibleValueChangeEvent for \a iface.
    The event contains the new value \a val.
*/

/*! \fn void QAccessibleValueChangeEvent::setValue(const QVariant & value)

    Sets the new \a value for this event.
*/
/*!
    \fn QVariant QAccessibleValueChangeEvent::value() const

    Returns the new value of the accessible object of this event.
*/
/*!
    \internal
*/
QAccessibleValueChangeEvent::~QAccessibleValueChangeEvent()
{
    // must be empty until ### Qt 6
}

/*!
    \class QAccessibleStateChangeEvent
    \ingroup accessibility
    \inmodule QtGui

    \brief The QAccessibleStateChangeEvent notfies the accessibility framework
    that the state of an object has changed.

    This class is used with \l QAccessible::updateAccessibility().

    \sa QAccessibleInterface::state()
*/
/*! \fn QAccessibleStateChangeEvent::QAccessibleStateChangeEvent(QObject *object, QAccessible::State state)

    Constructs a new QAccessibleStateChangeEvent for \a object.
    The difference to the object's previous state is in \a state.
*/
/*!
    \fn QAccessibleStateChangeEvent::QAccessibleStateChangeEvent(QAccessibleInterface *iface, QAccessible::State state)

    Constructs a new QAccessibleStateChangeEvent.
    \a iface is the interface associated with the event
    \a state is the state of the accessible object.
*/
/*!
    \fn QAccessible::State QAccessibleStateChangeEvent::changedStates() const
    \brief Returns the states that have been changed.

    Keep in mind that the returned states are the ones that have changed.
    To find out about the state of an object, use QAccessibleInterface::state().

    For example, if an object used to have the focus but loses it,
    the object's state will have focused set to \c false. This event on the
    other hand tells about the change and has focused set to \c true since
    the focus state is changed from \c true to \c false.
*/
/*!
    \internal
*/
QAccessibleStateChangeEvent::~QAccessibleStateChangeEvent()
{
    // must be empty until ### Qt 6
}

/*!
    \class QAccessibleTableModelChangeEvent
    \ingroup accessibility
    \inmodule QtGui

    \brief The QAccessibleTableModelChangeEvent signifies a change in a table, list, or tree where cells
    are added or removed.
    If the change affected a number of rows, firstColumn and lastColumn will return -1.
    Likewise for columns, the row functions may return -1.

    This class is used with \l QAccessible::updateAccessibility().
*/

/*! \enum QAccessibleTableModelChangeEvent::ModelChangeType
    This enum describes the different types of changes in the table model.
    \value ModelReset      The model has been reset, all previous knowledge about the model is now invalid.
    \value DataChanged     No cells have been added or removed, but the data of the specified cell range is invalid.
    \value RowsInserted    New rows have been inserted.
    \value ColumnsInserted New columns have been inserted.
    \value RowsRemoved     Rows have been removed.
    \value ColumnsRemoved  Columns have been removed.
*/
/*! \fn QAccessibleTableModelChangeEvent::QAccessibleTableModelChangeEvent(QObject *object, ModelChangeType changeType)

    Constructs a new QAccessibleTableModelChangeEvent for \a object of with \a changeType.
*/
/*! \fn int QAccessibleTableModelChangeEvent::firstColumn() const

    Returns the first changed column.
*/
/*! \fn int QAccessibleTableModelChangeEvent::firstRow() const

    Returns the first changed row.
*/
/*! \fn int QAccessibleTableModelChangeEvent::lastColumn() const

    Returns the last changed column.
*/
/*! \fn int QAccessibleTableModelChangeEvent::lastRow() const

    Returns the last changed row.
*/
/*! \fn QAccessibleTableModelChangeEvent::ModelChangeType QAccessibleTableModelChangeEvent::modelChangeType() const

    Returns the type of change.
*/
/*! \fn void QAccessibleTableModelChangeEvent::setFirstColumn(int column)

    Sets the first changed \a column.
*/
/*! \fn void QAccessibleTableModelChangeEvent::setFirstRow(int row)

    Sets the first changed \a row.
*/
/*! \fn void QAccessibleTableModelChangeEvent::setLastColumn(int column)

    Sets the last changed \a column.
*/
/*! \fn void QAccessibleTableModelChangeEvent::setLastRow(int row)

    Sets the last changed \a row.
*/
/*! \fn void QAccessibleTableModelChangeEvent::setModelChangeType(ModelChangeType changeType)

    Sets the type of change to \a changeType.
*/
/*!
    \fn QAccessibleTableModelChangeEvent::QAccessibleTableModelChangeEvent(QAccessibleInterface *iface, ModelChangeType changeType)

    Constructs a new QAccessibleTableModelChangeEvent for interface \a iface with a model
    change type \a changeType.
*/
/*!
    \internal
*/
QAccessibleTableModelChangeEvent::~QAccessibleTableModelChangeEvent()
{
    // must be empty until ### Qt 6
}
/*!
    \class QAccessibleTextCursorEvent
    \ingroup accessibility
    \inmodule QtGui

    \brief The QAccessibleTextCursorEvent class notifies of cursor movements.

    This class is used with \l QAccessible::updateAccessibility().
*/
/*! \fn QAccessibleTextCursorEvent::QAccessibleTextCursorEvent(QObject *object, int cursorPos)

    Create a new QAccessibleTextCursorEvent for \a object.
    The \a cursorPos is the new cursor position.
*/
/*! \fn int QAccessibleTextCursorEvent::cursorPosition() const

    Returns the cursor position.
*/
/*! \fn void QAccessibleTextCursorEvent::setCursorPosition(int position)

    Sets the cursor \a position for this event.
*/
/*!
    \internal
*/
QAccessibleTextCursorEvent::~QAccessibleTextCursorEvent()
{
    // must be empty until ### Qt 6
}


/*!
    \fn QAccessibleTextCursorEvent::QAccessibleTextCursorEvent(QAccessibleInterface *iface, int cursorPos)

    Create a new QAccessibleTextCursorEvent for \a iface,
    The \a cursorPos is the new cursor position.
*/

/*!
    \class QAccessibleTextInsertEvent
    \ingroup accessibility
    \inmodule QtGui

    \brief The QAccessibleTextInsertEvent class notifies of text being inserted.

    This class is used with \l QAccessible::updateAccessibility().
*/
/*! \fn QAccessibleTextInsertEvent::QAccessibleTextInsertEvent(QObject *object, int position, const QString &text)

    Constructs a new QAccessibleTextInsertEvent event for \a object.
    The \a text has been inserted at \a position.
    By default, it is assumed that the cursor has moved to the end
    of the selection. If that is not the case, one needs to manually
    set it with \l QAccessibleTextCursorEvent::setCursorPosition() for this event.
*/
/*! \fn int QAccessibleTextInsertEvent::changePosition() const

    Returns the position where the text was inserted.
*/
/*! \fn QString QAccessibleTextInsertEvent::textInserted() const

    Returns the text that has been inserted.
*/
/*!
    \internal
*/
QAccessibleTextInsertEvent::~QAccessibleTextInsertEvent()
{
    // must be empty until ### Qt 6
}


/*!
    \class QAccessibleTextRemoveEvent
    \ingroup accessibility
    \inmodule QtGui

    \brief The QAccessibleTextRemoveEvent class notifies of text being deleted.

    This class is used with \l QAccessible::updateAccessibility().
*/
/*! \fn QAccessibleTextRemoveEvent::QAccessibleTextRemoveEvent(QObject *object, int position, const QString &text)

    Constructs a new QAccessibleTextRemoveEvent event for \a object.
    The \a text has been removed at \a position.
    By default it is assumed that the cursor has moved to \a position.
    If that is not the case, one needs to manually
    set it with \l QAccessibleTextCursorEvent::setCursorPosition() for this event.
*/
/*! \fn QAccessibleTextRemoveEvent::QAccessibleTextRemoveEvent(QAccessibleInterface *iface, int position, const QString &text)

    Constructs a new QAccessibleTextRemoveEvent event for \a iface.
    The \a text has been removed at \a position.
    By default it is assumed that the cursor has moved to \a position.
    If that is not the case, one needs to manually
    set it with \l QAccessibleTextCursorEvent::setCursorPosition() for this event.
*/

/*! \fn int QAccessibleTextRemoveEvent::changePosition() const

    Returns the position where the text was removed.
*/
/*! \fn QString QAccessibleTextRemoveEvent::textRemoved() const

    Returns the text that has been removed.
*/
/*!
    \internal
*/
QAccessibleTextRemoveEvent::~QAccessibleTextRemoveEvent()
{
    // must be empty until ### Qt 6
}

/*!
   \fn QAccessibleTextSelectionEvent::QAccessibleTextSelectionEvent(QAccessibleInterface *iface, int start, int end)

   Constructs a new QAccessibleTextSelectionEvent for \a iface. The new selection this
   event notifies about is from position \a start to \a end.
*/

/*!
     \fn QAccessibleTextInsertEvent::QAccessibleTextInsertEvent(QAccessibleInterface *iface, int position, const QString &text)

     Constructs a new QAccessibleTextInsertEvent event for \a iface. The text has been inserted at
     \a position.
*/

/*!
     \fn inline QAccessibleTextUpdateEvent::QAccessibleTextUpdateEvent(QAccessibleInterface *iface, int position, const QString &oldText,
         const QString &text)

     Constructs a new QAccessibleTextUpdateEvent for \a iface. The text change takes place at
     \a position where the \a oldText was removed and \a text inserted instead.

*/



/*!
    \class QAccessibleTextUpdateEvent
    \ingroup accessibility
    \inmodule QtGui

    \brief The QAccessibleTextUpdateEvent class notifies about text changes.
    This is for accessibles that support editable text such as line edits.
    This event occurs for example when a portion of selected text
    gets replaced by pasting a new text or in override mode of editors.

    This class is used with \l QAccessible::updateAccessibility().
*/
/*! \fn QAccessibleTextUpdateEvent::QAccessibleTextUpdateEvent(QObject *object, int position, const QString &oldText, const QString &text)

    Constructs a new QAccessibleTextUpdateEvent for \a object.
    The text change takes place at \a position where the \a oldText was removed and \a text inserted instead.
*/
/*! \fn int QAccessibleTextUpdateEvent::changePosition() const

    Returns where the change took place.
*/
/*! \fn QString QAccessibleTextUpdateEvent::textInserted() const

    Returns the inserted text.
*/
/*! \fn QString QAccessibleTextUpdateEvent::textRemoved() const

    Returns the removed text.
*/
/*!
    \internal
*/
QAccessibleTextUpdateEvent::~QAccessibleTextUpdateEvent()
{
    // must be empty until ### Qt 6
}


/*!
    \class QAccessibleTextSelectionEvent
    \ingroup accessibility
    \inmodule QtGui

    \brief QAccessibleTextSelectionEvent signals a change in the text selection of an object.

    This class is used with \l QAccessible::updateAccessibility().
*/
/*! \fn QAccessibleTextSelectionEvent::QAccessibleTextSelectionEvent(QObject *object, int start, int end)

    Constructs a new QAccessibleTextSelectionEvent for \a object.
    The new selection this event notifies about is from position \a start to \a end.
*/
/*! \fn int QAccessibleTextSelectionEvent::selectionEnd() const

    Returns the position of the last selected character.
*/
/*! \fn int QAccessibleTextSelectionEvent::selectionStart() const

    Returns the position of the first selected character.
*/
/*! \fn void QAccessibleTextSelectionEvent::setSelection(int start, int end)

    Sets the selection for this event from position \a start to \a end.
*/
/*!
    \internal
*/
QAccessibleTextSelectionEvent::~QAccessibleTextSelectionEvent()
{
    // must be empty until ### Qt 6
}



/*!
    Returns the QAccessibleInterface associated with the event.
*/
QAccessibleInterface *QAccessibleEvent::accessibleInterface() const
{
    if (m_object == nullptr)
        return QAccessible::accessibleInterface(m_uniqueId);

    QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(m_object);
    if (!iface || !iface->isValid())
        return nullptr;

    if (m_child >= 0) {
        QAccessibleInterface *child = iface->child(m_child);
        if (child) {
            iface = child;
        } else {
            qCWarning(lcAccessibilityCore) << "Cannot create accessible child interface for object: " << m_object << " index: " << m_child;
        }
    }
    return iface;
}

/*!
    Returns the window associated with the underlying object.
    For instance, QAccessibleWidget reimplements this and returns
    the windowHandle() of the QWidget.

    It is used on some platforms to be able to notify the AT client about
    state changes.
    The backend will traverse up all ancestors until it finds a window.
    (This means that at least one interface among the ancestors should
    return a valid QWindow pointer).

    The default implementation returns \nullptr.
  */
QWindow *QAccessibleInterface::window() const
{
    return nullptr;
}

/*!
    \internal
    Method to allow extending this class without breaking binary compatibility.
    The actual behavior and format of \a data depends on \a id argument
    which must be defined if the class is to be extended with another virtual
    function.
    Currently, this is unused.
*/
void QAccessibleInterface::virtual_hook(int /*id*/, void * /*data*/)
{
}

/*!
    \fn void *QAccessibleInterface::interface_cast(QAccessible::InterfaceType type)

    Returns a specialized accessibility interface \a type from the
    generic QAccessibleInterface.

    This function must be reimplemented when providing more
    information about a widget or object through the specialized
    interfaces. For example a line edit should implement the
    QAccessibleTextInterface.

    \sa QAccessible::InterfaceType, QAccessibleTextInterface,
    QAccessibleValueInterface, QAccessibleActionInterface,
    QAccessibleTableInterface, QAccessibleTableCellInterface
*/

/*! \internal */
const char *qAccessibleRoleString(QAccessible::Role role)
{
    if (role >= QAccessible::UserRole)
         role = QAccessible::UserRole;
    static int roleEnum = QAccessible::staticMetaObject.indexOfEnumerator("Role");
    return QAccessible::staticMetaObject.enumerator(roleEnum).valueToKey(role);
}

/*! \internal */
const char *qAccessibleEventString(QAccessible::Event event)
{
    static int eventEnum = QAccessible::staticMetaObject.indexOfEnumerator("Event");
    return QAccessible::staticMetaObject.enumerator(eventEnum).valueToKey(event);
}

/*! \internal */
bool operator==(const QAccessible::State &first, const QAccessible::State &second)
{
    return memcmp(&first, &second, sizeof(QAccessible::State)) == 0;
}

#ifndef QT_NO_DEBUG_STREAM
/*! \internal */
Q_GUI_EXPORT QDebug operator<<(QDebug d, const QAccessibleInterface *iface)
{
    QDebugStateSaver saver(d);
    if (!iface) {
        d << "QAccessibleInterface(null)";
        return d;
    }
    d.nospace();
    d << "QAccessibleInterface(" << Qt::hex << (const void *) iface << Qt::dec;
    if (iface->isValid()) {
        d << " name=" << iface->text(QAccessible::Name) << ' ';
        d << "role=" << qAccessibleRoleString(iface->role()) << ' ';
        if (iface->childCount())
            d << "childc=" << iface->childCount() << ' ';
        if (iface->object()) {
            d << "obj=" << iface->object();
        }
        QStringList stateStrings;
        QAccessible::State st = iface->state();
        if (st.focusable)
            stateStrings << QLatin1String("focusable");
        if (st.focused)
            stateStrings << QLatin1String("focused");
        if (st.selected)
            stateStrings << QLatin1String("selected");
        if (st.invisible)
            stateStrings << QLatin1String("invisible");

        if (!stateStrings.isEmpty())
            d << stateStrings.join(QLatin1Char('|'));

        if (!st.invisible)
            d << "rect=" << iface->rect();

    } else {
        d << " invalid";
    }
    d << ')';
    return d;
}

/*! \internal */
QDebug operator<<(QDebug d, const QAccessibleEvent &ev)
{
    QDebugStateSaver saver(d);
    d.nospace() << "QAccessibleEvent(";
    if (ev.object()) {
        d.nospace() << "object=" << Qt::hex << ev.object() << Qt::dec;
        d.nospace() << "child=" << ev.child();
    } else {
        d.nospace() << "no object, uniqueId=" << ev.uniqueId();
    }
    d << " event=" << qAccessibleEventString(ev.type());
    if (ev.type() == QAccessible::StateChanged) {
        QAccessible::State changed = static_cast<const QAccessibleStateChangeEvent*>(&ev)->changedStates();
        d << "State changed:";
        if (changed.disabled) d << "disabled";
        if (changed.selected) d << "selected";
        if (changed.focusable) d << "focusable";
        if (changed.focused) d << "focused";
        if (changed.pressed) d << "pressed";
        if (changed.checkable) d << "checkable";
        if (changed.checked) d << "checked";
        if (changed.checkStateMixed) d << "checkStateMixed";
        if (changed.readOnly) d << "readOnly";
        if (changed.hotTracked) d << "hotTracked";
        if (changed.defaultButton) d << "defaultButton";
        if (changed.expanded) d << "expanded";
        if (changed.collapsed) d << "collapsed";
        if (changed.busy) d << "busy";
        if (changed.expandable) d << "expandable";
        if (changed.marqueed) d << "marqueed";
        if (changed.animated) d << "animated";
        if (changed.invisible) d << "invisible";
        if (changed.offscreen) d << "offscreen";
        if (changed.sizeable) d << "sizeable";
        if (changed.movable) d << "movable";
        if (changed.selfVoicing) d << "selfVoicing";
        if (changed.selectable) d << "selectable";
        if (changed.linked) d << "linked";
        if (changed.traversed) d << "traversed";
        if (changed.multiSelectable) d << "multiSelectable";
        if (changed.extSelectable) d << "extSelectable";
        if (changed.passwordEdit) d << "passwordEdit"; // used to be Protected
        if (changed.hasPopup) d << "hasPopup";
        if (changed.modal) d << "modal";

        // IA2 - we chose to not add some IA2 states for now
        // Below the ones that seem helpful
        if (changed.active) d << "active";
        if (changed.invalid) d << "invalid"; // = defunct
        if (changed.editable) d << "editable";
        if (changed.multiLine) d << "multiLine";
        if (changed.selectableText) d << "selectableText";
        if (changed.supportsAutoCompletion) d << "supportsAutoCompletion";

    }
    d << ')';
    return d;
}
#endif // QT_NO_DEBUGSTREAM

/*!
    \class QAccessibleTextInterface
    \inmodule QtGui

    \ingroup accessibility

    \brief The QAccessibleTextInterface class implements support for text handling.

    This interface corresponds to the IAccessibleText interface.
    It should be implemented for widgets that display more text than a plain label.
    Labels should be represented by only \l QAccessibleInterface
    and return their text as name (\l QAccessibleInterface::text() with \l QAccessible::Name as type).
    The QAccessibleTextInterface is typically for text that a screen reader
    might want to read line by line, and for widgets that support text selection and input.
    This interface is, for example, implemented for QLineEdit.

    \l{IAccessible2 Specification}
*/

/*!

    Destroys the QAccessibleTextInterface.
*/
QAccessibleTextInterface::~QAccessibleTextInterface()
{
    // must be empty until ### Qt 6
}

/*!
    \fn void QAccessibleTextInterface::addSelection(int startOffset, int endOffset)

    Select the text from \a startOffset to \a endOffset.
    The \a startOffset is the first character that will be selected.
    The \a endOffset is the first character that will not be selected.

    When the object supports multiple selections (e.g. in a word processor),
    this adds a new selection, otherwise it replaces the previous selection.

    The selection will be \a endOffset - \a startOffset characters long.
*/

/*!
    \fn QString QAccessibleTextInterface::attributes(int offset, int *startOffset, int *endOffset) const

    Returns the text attributes at the position \a offset.
    In addition the range of the attributes is returned in \a startOffset and \a endOffset.
*/

/*!
    \fn int QAccessibleTextInterface::cursorPosition() const

    Returns the current cursor position.
*/

/*!
    \fn QRect QAccessibleTextInterface::characterRect(int offset) const

    Returns the position and size of the character at position \a offset in screen coordinates.
*/

/*!
    \fn int QAccessibleTextInterface::selectionCount() const

    Returns the number of selections in this text.
*/

/*!
    \fn int QAccessibleTextInterface::offsetAtPoint(const QPoint &point) const

    Returns the offset of the character at the \a point in screen coordinates.
*/

/*!
    \fn void QAccessibleTextInterface::selection(int selectionIndex, int *startOffset, int *endOffset) const

    Returns a selection. The size of the selection is returned in \a startOffset and \a endOffset.
    If there is no selection both \a startOffset and \a endOffset are \nullptr.

    The accessibility APIs support multiple selections. For most widgets though, only one selection
    is supported with \a selectionIndex equal to 0.
*/

/*!
    \fn QString QAccessibleTextInterface::text(int startOffset, int endOffset) const

    Returns the text from \a startOffset to \a endOffset.
    The \a startOffset is the first character that will be returned.
    The \a endOffset is the first character that will not be returned.
*/

/*!
    \internal
    Helper for finding line breaks in textBeforeOffset/textAtOffset/textAfterOffset.
    \a beforeAtAfter is the line we look for. -1 for before, 0 for at and 1 for after.
*/
static QString textLineBoundary(int beforeAtAfter, const QString &text, int offset, int *startOffset, int *endOffset)
{
    Q_ASSERT(beforeAtAfter >= -1 && beforeAtAfter <= 1);
    Q_ASSERT(*startOffset == -1 && *endOffset == -1);
    int length = text.length();
    Q_ASSERT(offset >= 0 && offset <= length);

    // move offset into the right range (if asking for line before or after
    if (beforeAtAfter == 1) {
        offset = text.indexOf(QChar::LineFeed, qMin(offset, length - 1));
        if (offset < 0)
            return QString(); // after the last line comes nothing
        ++offset; // move after the newline
    } else if (beforeAtAfter == -1) {
        offset = text.lastIndexOf(QChar::LineFeed, qMax(offset - 1, 0));
        if (offset < 0)
            return QString(); // before first line comes nothing
    }

    if (offset > 0)
        *startOffset = text.lastIndexOf(QChar::LineFeed, offset - 1);
    ++*startOffset; // move to the char after the newline (0 if lastIndexOf returned -1)

    *endOffset = text.indexOf(QChar::LineFeed, qMin(offset, length - 1)) + 1; // include newline char
    if (*endOffset <= 0 || *endOffset > length)
        *endOffset = length; // if the text doesn't end with a newline it ends at length

    return text.mid(*startOffset, *endOffset - *startOffset);
}

/*!
    Returns the text item of type \a boundaryType that is close to offset \a offset
    and sets \a startOffset and \a endOffset values to the start and end positions
    of that item; returns an empty string if there is no such an item.
    Sets \a startOffset and \a endOffset values to -1 on error.

    This default implementation is provided for small text edits. A word processor or
    text editor should provide their own efficient implementations. This function makes no
    distinction between paragraphs and lines.

    \note this function can not take the cursor position into account. By convention
    an \a offset of -2 means that this function should use the cursor position as offset.
    Thus an offset of -2 must be converted to the cursor position before calling this
    function.
    An offset of -1 is used for the text length and custom implementations of this function
    have to return the result as if the length was passed in as offset.
*/
QString QAccessibleTextInterface::textBeforeOffset(int offset, QAccessible::TextBoundaryType boundaryType,
                                                   int *startOffset, int *endOffset) const
{
    const QString txt = text(0, characterCount());

    if (offset == -1)
        offset = txt.length();

    *startOffset = *endOffset = -1;
    if (txt.isEmpty() || offset <= 0 || offset > txt.length())
        return QString();

    // type initialized just to silence a compiler warning [-Werror=maybe-uninitialized]
    QTextBoundaryFinder::BoundaryType type = QTextBoundaryFinder::Grapheme;
    switch (boundaryType) {
    case QAccessible::CharBoundary:
        type = QTextBoundaryFinder::Grapheme;
        break;
    case QAccessible::WordBoundary:
        type = QTextBoundaryFinder::Word;
        break;
    case QAccessible::SentenceBoundary:
        type = QTextBoundaryFinder::Sentence;
        break;
    case QAccessible::LineBoundary:
    case QAccessible::ParagraphBoundary:
        // Lines can not use QTextBoundaryFinder since Line there means any potential line-break.
        return textLineBoundary(-1, txt, offset, startOffset, endOffset);
    case QAccessible::NoBoundary:
        // return empty, this function currently only supports single lines, so there can be no line before
        return QString();
    default:
        Q_UNREACHABLE();
    }

    // keep behavior in sync with QTextCursor::movePosition()!

    QTextBoundaryFinder boundary(type, txt);
    boundary.setPosition(offset);

    do {
        if ((boundary.boundaryReasons() & (QTextBoundaryFinder::StartOfItem | QTextBoundaryFinder::EndOfItem)))
            break;
    } while (boundary.toPreviousBoundary() > 0);
    Q_ASSERT(boundary.position() >= 0);
    *endOffset = boundary.position();

    while (boundary.toPreviousBoundary() > 0) {
        if ((boundary.boundaryReasons() & (QTextBoundaryFinder::StartOfItem | QTextBoundaryFinder::EndOfItem)))
            break;
    }
    Q_ASSERT(boundary.position() >= 0);
    *startOffset = boundary.position();

    return txt.mid(*startOffset, *endOffset - *startOffset);
}

/*!
    Returns the text item of type \a boundaryType that is right after offset \a offset
    and sets \a startOffset and \a endOffset values to the start and end positions
    of that item; returns an empty string if there is no such an item.
    Sets \a startOffset and \a endOffset values to -1 on error.

    This default implementation is provided for small text edits. A word processor or
    text editor should provide their own efficient implementations. This function makes no
    distinction between paragraphs and lines.

    \note this function can not take the cursor position into account. By convention
    an \a offset of -2 means that this function should use the cursor position as offset.
    Thus an offset of -2 must be converted to the cursor position before calling this
    function.
    An offset of -1 is used for the text length and custom implementations of this function
    have to return the result as if the length was passed in as offset.
*/
QString QAccessibleTextInterface::textAfterOffset(int offset, QAccessible::TextBoundaryType boundaryType,
                                                  int *startOffset, int *endOffset) const
{
    const QString txt = text(0, characterCount());

    if (offset == -1)
        offset = txt.length();

    *startOffset = *endOffset = -1;
    if (txt.isEmpty() || offset < 0 || offset >= txt.length())
        return QString();

    // type initialized just to silence a compiler warning [-Werror=maybe-uninitialized]
    QTextBoundaryFinder::BoundaryType type = QTextBoundaryFinder::Grapheme;
    switch (boundaryType) {
    case QAccessible::CharBoundary:
        type = QTextBoundaryFinder::Grapheme;
        break;
    case QAccessible::WordBoundary:
        type = QTextBoundaryFinder::Word;
        break;
    case QAccessible::SentenceBoundary:
        type = QTextBoundaryFinder::Sentence;
        break;
    case QAccessible::LineBoundary:
    case QAccessible::ParagraphBoundary:
        // Lines can not use QTextBoundaryFinder since Line there means any potential line-break.
        return textLineBoundary(1, txt, offset, startOffset, endOffset);
    case QAccessible::NoBoundary:
        // return empty, this function currently only supports single lines, so there can be no line after
        return QString();
    default:
        Q_UNREACHABLE();
    }

    // keep behavior in sync with QTextCursor::movePosition()!

    QTextBoundaryFinder boundary(type, txt);
    boundary.setPosition(offset);

    while (true) {
        int toNext = boundary.toNextBoundary();
        if ((boundary.boundaryReasons() & (QTextBoundaryFinder::StartOfItem | QTextBoundaryFinder::EndOfItem)))
            break;
        if (toNext < 0 || toNext >= txt.length())
            break; // not found, the boundary might not exist
    }
    Q_ASSERT(boundary.position() <= txt.length());
    *startOffset = boundary.position();

    while (true) {
        int toNext = boundary.toNextBoundary();
        if ((boundary.boundaryReasons() & (QTextBoundaryFinder::StartOfItem | QTextBoundaryFinder::EndOfItem)))
            break;
        if (toNext < 0 || toNext >= txt.length())
            break; // not found, the boundary might not exist
    }
    Q_ASSERT(boundary.position() <= txt.length());
    *endOffset = boundary.position();

    if ((*startOffset == -1) || (*endOffset == -1) || (*startOffset == *endOffset)) {
        *endOffset = -1;
        *startOffset = -1;
    }

    return txt.mid(*startOffset, *endOffset - *startOffset);
}

/*!
    Returns the text item of type \a boundaryType at offset \a offset
    and sets \a startOffset and \a endOffset values to the start and end positions
    of that item; returns an empty string if there is no such an item.
    Sets \a startOffset and \a endOffset values to -1 on error.

    This default implementation is provided for small text edits. A word processor or
    text editor should provide their own efficient implementations. This function makes no
    distinction between paragraphs and lines.

    \note this function can not take the cursor position into account. By convention
    an \a offset of -2 means that this function should use the cursor position as offset.
    Thus an offset of -2 must be converted to the cursor position before calling this
    function.
    An offset of -1 is used for the text length and custom implementations of this function
    have to return the result as if the length was passed in as offset.
*/
QString QAccessibleTextInterface::textAtOffset(int offset, QAccessible::TextBoundaryType boundaryType,
                                               int *startOffset, int *endOffset) const
{
    const QString txt = text(0, characterCount());

    if (offset == -1)
        offset = txt.length();

    *startOffset = *endOffset = -1;
    if (txt.isEmpty() || offset < 0 || offset > txt.length())
        return QString();

    if (offset == txt.length() && boundaryType == QAccessible::CharBoundary)
        return QString();

    // type initialized just to silence a compiler warning [-Werror=maybe-uninitialized]
    QTextBoundaryFinder::BoundaryType type = QTextBoundaryFinder::Grapheme;
    switch (boundaryType) {
    case QAccessible::CharBoundary:
        type = QTextBoundaryFinder::Grapheme;
        break;
    case QAccessible::WordBoundary:
        type = QTextBoundaryFinder::Word;
        break;
    case QAccessible::SentenceBoundary:
        type = QTextBoundaryFinder::Sentence;
        break;
    case QAccessible::LineBoundary:
    case QAccessible::ParagraphBoundary:
        // Lines can not use QTextBoundaryFinder since Line there means any potential line-break.
        return textLineBoundary(0, txt, offset, startOffset, endOffset);
    case QAccessible::NoBoundary:
        *startOffset = 0;
        *endOffset = txt.length();
        return txt;
    default:
        Q_UNREACHABLE();
    }

    // keep behavior in sync with QTextCursor::movePosition()!

    QTextBoundaryFinder boundary(type, txt);
    boundary.setPosition(offset);

    do {
        if ((boundary.boundaryReasons() & (QTextBoundaryFinder::StartOfItem | QTextBoundaryFinder::EndOfItem)))
            break;
    } while (boundary.toPreviousBoundary() > 0);
    Q_ASSERT(boundary.position() >= 0);
    *startOffset = boundary.position();

    while (boundary.toNextBoundary() < txt.length()) {
        if ((boundary.boundaryReasons() & (QTextBoundaryFinder::StartOfItem | QTextBoundaryFinder::EndOfItem)))
            break;
    }
    Q_ASSERT(boundary.position() <= txt.length());
    *endOffset = boundary.position();

    return txt.mid(*startOffset, *endOffset - *startOffset);
}

/*!
    \fn void QAccessibleTextInterface::removeSelection(int selectionIndex)

    Clears the selection with index \a selectionIndex.
*/

/*!
    \fn void QAccessibleTextInterface::setCursorPosition(int position)

    Moves the cursor to \a position.
*/

/*!
    \fn void QAccessibleTextInterface::setSelection(int selectionIndex, int startOffset, int endOffset)

    Set the selection \a selectionIndex to the range from \a startOffset to \a endOffset.

    \sa addSelection(), removeSelection()
*/

/*!
    \fn int QAccessibleTextInterface::characterCount() const

    Returns the length of the text (total size including spaces).
*/

/*!
    \fn void QAccessibleTextInterface::scrollToSubstring(int startIndex, int endIndex)

    Ensures that the text between \a startIndex and \a endIndex is visible.
*/

/*!
    \class QAccessibleEditableTextInterface
    \ingroup accessibility
    \inmodule QtGui

    \brief The QAccessibleEditableTextInterface class implements support for objects with editable text.

    When implementing this interface you will almost certainly also want to implement \l QAccessibleTextInterface.

    \sa QAccessibleInterface

    \l{IAccessible2 Specification}
*/

/*!

    Destroys the QAccessibleEditableTextInterface.
*/
QAccessibleEditableTextInterface::~QAccessibleEditableTextInterface()
{
    // must be empty until ### Qt 6
}

/*!
    \fn void QAccessibleEditableTextInterface::deleteText(int startOffset, int endOffset)

    Deletes the text from \a startOffset to \a endOffset.
*/

/*!
    \fn void QAccessibleEditableTextInterface::insertText(int offset, const QString &text)

    Inserts \a text at position \a offset.
*/

/*!
    \fn void QAccessibleEditableTextInterface::replaceText(int startOffset, int endOffset, const QString &text)

    Removes the text from \a startOffset to \a endOffset and instead inserts \a text.
*/

/*!
    \class QAccessibleValueInterface
    \inmodule QtGui
    \ingroup accessibility

    \brief The QAccessibleValueInterface class implements support for objects that manipulate a value.

    This interface should be implemented by accessible objects that represent a value.
    Examples are spinner, slider, dial and scroll bar.

    Instead of forcing the user to deal with the individual parts of the widgets, this interface
    gives an easier approach to the kind of widget it represents.

    Usually this interface is implemented by classes that also implement \l QAccessibleInterface.

    \l{IAccessible2 Specification}
*/

/*!
    Destroys the QAccessibleValueInterface.

*/
QAccessibleValueInterface::~QAccessibleValueInterface()
{
    // must be empty until ### Qt 6
}

/*!
    \fn QVariant QAccessibleValueInterface::currentValue() const

    Returns the current value of the widget. This is usually a double or int.
    \sa setCurrentValue()
*/

/*!
    \fn void QAccessibleValueInterface::setCurrentValue(const QVariant &value)

    Sets the \a value. If the desired \a value is out of the range of permissible values,
    this call will be ignored.

    \sa currentValue(), minimumValue(), maximumValue()
*/

/*!
    \fn QVariant QAccessibleValueInterface::maximumValue() const

    Returns the maximum value this object accepts.
    \sa minimumValue(), currentValue()
*/

/*!
    \fn QVariant QAccessibleValueInterface::minimumValue() const

    Returns the minimum value this object accepts.
    \sa maximumValue(), currentValue()
*/

/*!
    \fn QVariant QAccessibleValueInterface::minimumStepSize() const

    Returns the minimum step size for the accessible.
    This is the smalles increment that makes sense when changing the value.
    When programatically changing the value it should always be a multiple
    of the minimum step size.

    Some tools use this value even when the setCurrentValue does not
    perform any action. Progress bars for example are read-only but
    should return their range divided by 100.
*/

/*!
    \class QAccessibleImageInterface
    \inmodule QtGui
    \ingroup accessibility
    \internal
    \preliminary

    \brief The QAccessibleImageInterface class implements support for
    the IAccessibleImage interface.

    \l{IAccessible2 Specification}
*/

/*!
    Destroys the QAccessibleImageInterface.
*/
QAccessibleImageInterface::~QAccessibleImageInterface()
{
    // must be empty until ### Qt 6
}

/*!
    \class QAccessibleTableCellInterface
    \inmodule QtGui
    \ingroup accessibility

    \brief The QAccessibleTableCellInterface class implements support for
    the IAccessibleTable2 Cell interface.

    \l{IAccessible2 Specification}
*/

/*!

    Destroys the QAccessibleTableCellInterface.
*/
QAccessibleTableCellInterface::~QAccessibleTableCellInterface()
{
    // must be empty until ### Qt 6
}

/*!
    \fn virtual int QAccessibleTableCellInterface::columnExtent() const

    Returns the number of columns occupied by this cell accessible.
*/

/*!
    \fn virtual QList<QAccessibleInterface*> QAccessibleTableCellInterface::columnHeaderCells() const

    Returns the column headers as an array of cell accessibles.
*/

/*!
    \fn virtual int QAccessibleTableCellInterface::columnIndex() const

    Translates this cell accessible into the corresponding column index.
*/

/*!
    \fn virtual int QAccessibleTableCellInterface::rowExtent() const

    Returns the number of rows occupied by this cell accessible.
*/

/*!
    \fn virtual QList<QAccessibleInterface*> QAccessibleTableCellInterface::rowHeaderCells() const

    Returns the row headers as an array of cell accessibles.
*/

/*!
    \fn virtual int QAccessibleTableCellInterface::rowIndex() const

    Translates this cell accessible into the corresponding row index.
*/

/*!
    \fn virtual bool QAccessibleTableCellInterface::isSelected() const

    Returns a boolean value indicating whether this cell is selected.
*/

/*!
    \fn virtual QAccessibleInterface *QAccessibleTableCellInterface::table() const

    Returns the QAccessibleInterface of the table containing this cell.
*/


/*!
    \class QAccessibleTableInterface
    \ingroup accessibility

    \brief The QAccessibleTableInterface class implements support for
    the IAccessibleTable2 interface.

    \l{IAccessible2 Specification}
*/

/*!

    Destroys the QAccessibleTableInterface.
*/
QAccessibleTableInterface::~QAccessibleTableInterface()
{
    // must be empty until ### Qt 6
}

/*!
    \fn virtual QAccessibleInterface *QAccessibleTableInterface::cellAt(int row, int column) const

    Returns the cell at the specified \a row and \a column in the table.
*/

/*!
    \fn virtual QAccessibleInterface *QAccessibleTableInterface::caption() const

    Returns the caption for the table.
*/

/*!
    \fn virtual QString QAccessibleTableInterface::columnDescription(int column) const

    Returns the description text of the specified \a column in the table.
*/

/*!
    \fn virtual int QAccessibleTableInterface::columnCount() const

    Returns the total number of columns in table.
*/

/*!
    \fn virtual int QAccessibleTableInterface::rowCount() const

    Returns the total number of rows in table.
*/

/*!
    \fn virtual int QAccessibleTableInterface::selectedCellCount() const

    Returns the total number of selected cells.
*/

/*!
    \fn virtual int QAccessibleTableInterface::selectedColumnCount() const

    Returns the total number of selected columns.
*/

/*!
    \fn virtual int QAccessibleTableInterface::selectedRowCount() const

    Returns the total number of selected rows.
*/

/*!
    \fn virtual QString QAccessibleTableInterface::rowDescription(int row) const

    Returns the description text of the specified \a row in the table.
*/

/*!
    \fn virtual QList<int> QAccessibleTableInterface::selectedCells() const

    Returns the list of selected cell (by their index as \l QAccessibleInterface::child() accepts).
*/

/*!
    \fn virtual QList<int> QAccessibleTableInterface::selectedColumns() const

    Returns the list of currently selected columns.
*/

/*!
    \fn virtual QList<int> QAccessibleTableInterface::selectedRows() const

    Returns the list of currently selected columns.
*/

/*!
    \fn virtual QAccessibleInterface *QAccessibleTableInterface::summary() const

    Returns a QAccessibleInterface that represents a summary of the table.
    This function may return 0 if no such interface exists.
*/

/*!
    \fn virtual bool QAccessibleTableInterface::isColumnSelected(int column) const

    Returns a boolean value indicating whether the specified \a column is completely selected.
*/

/*!
    \fn virtual bool QAccessibleTableInterface::isRowSelected(int row) const

    Returns a boolean value indicating whether the specified \a row is completely selected.
*/

/*!
    \fn virtual bool QAccessibleTableInterface::selectRow(int row)

    Selects \a row. This function might unselect all previously selected rows.
    Returns \c true if the selection was successful.
*/

/*!
    \fn virtual bool QAccessibleTableInterface::selectColumn(int column)

    Selects \a column. This function might unselect all previously selected columns.
    Returns \c true if the selection was successful.
*/

/*!
    \fn virtual bool QAccessibleTableInterface::unselectRow(int row)

    Unselects \a row, leaving other selected rows selected (if any).
    Returns \c true if the selection was successful.
*/

/*!
    \fn virtual bool QAccessibleTableInterface::unselectColumn(int column)

    Unselects \a column, leaving other selected columns selected (if any).
    Returns \c true if the selection was successful.
*/

/*!
    \fn virtual void QAccessibleTableInterface::modelChange(QAccessibleTableModelChangeEvent *event)

    Informs about a change in the model's layout.
    The \a event contains the details.
    \sa QAccessibleTableModelChangeEvent
*/


/*!
    \class QAccessibleActionInterface
    \ingroup accessibility

    \brief The QAccessibleActionInterface class implements support for
    invocable actions in the interface.

    Accessible objects should implement the action interface if they support user interaction.
    Usually this interface is implemented by classes that also implement \l QAccessibleInterface.

    The supported actions should use the predefined actions offered in this class unless they do not
    fit a predefined action. In that case a custom action can be added.

    When subclassing QAccessibleActionInterface you need to provide a list of actionNames which
    is the primary means to discover the available actions. Action names are never localized.
    In order to present actions to the user there are two functions that need to return localized versions
    of the name and give a description of the action. For the predefined action names use
    \l QAccessibleActionInterface::localizedActionName() and \l QAccessibleActionInterface::localizedActionDescription()
    to return their localized counterparts.

    In general you should use one of the predefined action names, unless describing an action that does not fit these:
    \table
    \header \li Action name         \li Description
    \row    \li \l toggleAction()   \li toggles the item (checkbox, radio button, switch, ...)
    \row    \li \l decreaseAction() \li decrease the value of the accessible (e.g. spinbox)
    \row    \li \l increaseAction() \li increase the value of the accessible (e.g. spinbox)
    \row    \li \l pressAction()    \li press or click or activate the accessible (should correspont to clicking the object with the mouse)
    \row    \li \l setFocusAction() \li set the focus to this accessible
    \row    \li \l showMenuAction() \li show a context menu, corresponds to right-clicks
    \endtable

    In order to invoke the action, \l doAction() is called with an action name.

    Most widgets will simply implement \l pressAction(). This is what happens when the widget is activated by
    being clicked, space pressed or similar.

    \l{IAccessible2 Specification}
*/

/*!

    Destroys the QAccessibleActionInterface.
*/
QAccessibleActionInterface::~QAccessibleActionInterface()
{
    // must be empty until ### Qt 6
}

/*!
    \fn QStringList QAccessibleActionInterface::actionNames() const

    Returns the list of actions supported by this accessible object.
    The actions returned should be in preferred order,
    i.e. the action that the user most likely wants to trigger should be returned first,
    while the least likely action should be returned last.

    The list does only contain actions that can be invoked.
    It won't return disabled actions, or actions associated with disabled UI controls.

    The list can be empty.

    Note that this list is not localized. For a localized representation re-implement \l localizedActionName()
    and \l localizedActionDescription()

    \sa doAction(), localizedActionName(), localizedActionDescription()
*/

/*!
    \fn QString QAccessibleActionInterface::localizedActionName(const QString &actionName) const

    Returns a localized action name of \a actionName.

    For custom actions this function has to be re-implemented.
    When using one of the default names, you can call this function in QAccessibleActionInterface
    to get the localized string.

    \sa actionNames(), localizedActionDescription()
*/

/*!
    \fn QString QAccessibleActionInterface::localizedActionDescription(const QString &actionName) const

    Returns a localized action description of the action \a actionName.

    When using one of the default names, you can call this function in QAccessibleActionInterface
    to get the localized string.

    \sa actionNames(), localizedActionName()
*/

/*!
    \fn void QAccessibleActionInterface::doAction(const QString &actionName)

    Invokes the action specified by \a actionName.
    Note that \a actionName is the non-localized name as returned by \l actionNames()
    This function is usually implemented by calling the same functions
    that other user interaction, such as clicking the object, would trigger.

    \sa actionNames()
*/

/*!
    \fn QStringList QAccessibleActionInterface::keyBindingsForAction(const QString &actionName) const

    Returns a list of the keyboard shortcuts available for invoking the action named \a actionName.

    This is important to let users learn alternative ways of using the application by emphasizing the keyboard.

    \sa actionNames()
*/


struct QAccessibleActionStrings
{
    QAccessibleActionStrings() :
        pressAction(QStringLiteral(QT_TRANSLATE_NOOP("QAccessibleActionInterface", "Press"))),
        increaseAction(QStringLiteral(QT_TRANSLATE_NOOP("QAccessibleActionInterface", "Increase"))),
        decreaseAction(QStringLiteral(QT_TRANSLATE_NOOP("QAccessibleActionInterface", "Decrease"))),
        showMenuAction(QStringLiteral(QT_TRANSLATE_NOOP("QAccessibleActionInterface", "ShowMenu"))),
        setFocusAction(QStringLiteral(QT_TRANSLATE_NOOP("QAccessibleActionInterface", "SetFocus"))),
        toggleAction(QStringLiteral(QT_TRANSLATE_NOOP("QAccessibleActionInterface", "Toggle"))),
        scrollLeftAction(QStringLiteral(QT_TRANSLATE_NOOP("QAccessibleActionInterface", "Scroll Left"))),
        scrollRightAction(QStringLiteral(QT_TRANSLATE_NOOP("QAccessibleActionInterface", "Scroll Right"))),
        scrollUpAction(QStringLiteral(QT_TRANSLATE_NOOP("QAccessibleActionInterface", "Scroll Up"))),
        scrollDownAction(QStringLiteral(QT_TRANSLATE_NOOP("QAccessibleActionInterface", "Scroll Down"))),
        previousPageAction(QStringLiteral(QT_TRANSLATE_NOOP("QAccessibleActionInterface", "Previous Page"))),
        nextPageAction(QStringLiteral(QT_TRANSLATE_NOOP("QAccessibleActionInterface", "Next Page")))
    {}

    const QString pressAction;
    const QString increaseAction;
    const QString decreaseAction;
    const QString showMenuAction;
    const QString setFocusAction;
    const QString toggleAction;
    const QString scrollLeftAction;
    const QString scrollRightAction;
    const QString scrollUpAction;
    const QString scrollDownAction;
    const QString previousPageAction;
    const QString nextPageAction;

    QString localizedDescription(const QString &actionName)
    {
        if (actionName == pressAction)
            return QAccessibleActionInterface::tr("Triggers the action");
        else if (actionName == increaseAction)
            return QAccessibleActionInterface::tr("Increase the value");
        else if (actionName == decreaseAction)
            return QAccessibleActionInterface::tr("Decrease the value");
        else if (actionName == showMenuAction)
            return QAccessibleActionInterface::tr("Shows the menu");
        else if (actionName == setFocusAction)
            return QAccessibleActionInterface::tr("Sets the focus");
        else if (actionName == toggleAction)
            return QAccessibleActionInterface::tr("Toggles the state");
        else if (actionName == scrollLeftAction)
            return QAccessibleActionInterface::tr("Scrolls to the left");
        else if (actionName == scrollRightAction)
            return QAccessibleActionInterface::tr("Scrolls to the right");
        else if (actionName == scrollUpAction)
            return QAccessibleActionInterface::tr("Scrolls up");
        else if (actionName == scrollDownAction)
            return QAccessibleActionInterface::tr("Scrolls down");
        else if (actionName == previousPageAction)
            return QAccessibleActionInterface::tr("Goes back a page");
        else if (actionName == nextPageAction)
            return QAccessibleActionInterface::tr("Goes to the next page");


        return QString();
    }
};

Q_GLOBAL_STATIC(QAccessibleActionStrings, accessibleActionStrings)

QString QAccessibleActionInterface::localizedActionName(const QString &actionName) const
{
    return QAccessibleActionInterface::tr(qPrintable(actionName));
}

QString QAccessibleActionInterface::localizedActionDescription(const QString &actionName) const
{
    return accessibleActionStrings()->localizedDescription(actionName);
}

/*!
    Returns the name of the press default action.
    \sa actionNames(), localizedActionName()
  */
const QString &QAccessibleActionInterface::pressAction()
{
    return accessibleActionStrings()->pressAction;
}

/*!
    Returns the name of the increase default action.
    \sa actionNames(), localizedActionName()
  */
const QString &QAccessibleActionInterface::increaseAction()
{
    return accessibleActionStrings()->increaseAction;
}

/*!
    Returns the name of the decrease default action.
    \sa actionNames(), localizedActionName()
  */
const QString &QAccessibleActionInterface::decreaseAction()
{
    return accessibleActionStrings()->decreaseAction;
}

/*!
    Returns the name of the show menu default action.
    \sa actionNames(), localizedActionName()
  */
const QString &QAccessibleActionInterface::showMenuAction()
{
    return accessibleActionStrings()->showMenuAction;
}

/*!
    Returns the name of the set focus default action.
    \sa actionNames(), localizedActionName()
  */
const QString &QAccessibleActionInterface::setFocusAction()
{
    return accessibleActionStrings()->setFocusAction;
}

/*!
    Returns the name of the toggle default action.
    \sa actionNames(), localizedActionName()
  */
const QString &QAccessibleActionInterface::toggleAction()
{
    return accessibleActionStrings()->toggleAction;
}

/*!
    Returns the name of the scroll left default action.
    \sa actionNames(), localizedActionName()
  */
QString QAccessibleActionInterface::scrollLeftAction()
{
    return accessibleActionStrings()->scrollLeftAction;
}

/*!
    Returns the name of the scroll right default action.
    \sa actionNames(), localizedActionName()
  */
QString QAccessibleActionInterface::scrollRightAction()
{
    return accessibleActionStrings()->scrollRightAction;
}

/*!
    Returns the name of the scroll up default action.
    \sa actionNames(), localizedActionName()
  */
QString QAccessibleActionInterface::scrollUpAction()
{
    return accessibleActionStrings()->scrollUpAction;
}

/*!
    Returns the name of the scroll down default action.
    \sa actionNames(), localizedActionName()
  */
QString QAccessibleActionInterface::scrollDownAction()
{
    return accessibleActionStrings()->scrollDownAction;
}

/*!
    Returns the name of the previous page default action.
    \sa actionNames(), localizedActionName()
  */
QString QAccessibleActionInterface::previousPageAction()
{
    return accessibleActionStrings()->previousPageAction;
}

/*!
    Returns the name of the next page default action.
    \sa actionNames(), localizedActionName()
  */
QString QAccessibleActionInterface::nextPageAction()
{
    return accessibleActionStrings()->nextPageAction;
}

/*! \internal */
QString qAccessibleLocalizedActionDescription(const QString &actionName)
{
    return accessibleActionStrings()->localizedDescription(actionName);
}

#endif // QT_NO_ACCESSIBILITY

QT_END_NAMESPACE

