/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qaccessiblewidgets.h"
#include "qabstracttextdocumentlayout.h"
#include "qapplication.h"
#include "qclipboard.h"
#include "qtextedit.h"
#include "private/qtextedit_p.h"
#include "qtextdocument.h"
#include "qtextobject.h"
#include "qscrollbar.h"
#include "qdebug.h"
#include <QApplication>
#include <QStackedWidget>
#include <QToolBox>
#include <QMdiArea>
#include <QMdiSubWindow>
#include <QWorkspace>
#include <QDialogButtonBox>
#include <limits.h>
#include <QRubberBand>
#include <QTextBrowser>
#include <QCalendarWidget>
#include <QAbstractItemView>
#include <QDockWidget>
#include <QMainWindow>
#include <QAbstractButton>
#include <private/qdockwidget_p.h>
#include <QtGui/QFocusFrame>

#ifndef QT_NO_ACCESSIBILITY

QT_BEGIN_NAMESPACE

using namespace QAccessible2;

QList<QWidget*> childWidgets(const QWidget *widget, bool includeTopLevel)
{
    if (widget == 0)
        return QList<QWidget*>();
    QList<QObject*> list = widget->children();
    QList<QWidget*> widgets;
    for (int i = 0; i < list.size(); ++i) {
        QWidget *w = qobject_cast<QWidget *>(list.at(i));
        if (!w)
            continue;
        QString objectName = w->objectName();
        if ((includeTopLevel || !w->isWindow()) 
              && !qobject_cast<QFocusFrame*>(w)
              && !qobject_cast<QMenu*>(w)
              && objectName != QLatin1String("qt_rubberband")
              && objectName != QLatin1String("qt_qmainwindow_extended_splitter")) {
            widgets.append(w);
        }
    }
    return widgets;
}

static inline int distance(QWidget *source, QWidget *target,
                           QAccessible::RelationFlag relation)
{
    if (!source || !target)
        return -1;

    int returnValue = -1;
    switch (relation) {
    case QAccessible::Up:
        if (target->y() <= source->y())
            returnValue = source->y() - target->y();
        break;
    case QAccessible::Down:
        if (target->y() >= source->y() + source->height())
            returnValue = target->y() - (source->y() + source->height());
        break;
    case QAccessible::Right:
        if (target->x() >= source->x() + source->width())
            returnValue = target->x() - (source->x() + source->width());
        break;
    case QAccessible::Left:
        if (target->x() <= source->x())
            returnValue = source->x() - target->x();
        break;
    default:
        break;
    }
    return returnValue;
}

static inline QWidget *mdiAreaNavigate(QWidget *area,
                                       QAccessible::RelationFlag relation, int entry)
{
#if defined(QT_NO_MDIAREA) && defined(QT_NO_WORKSPACE)
    Q_UNUSED(area);
#endif
#ifndef QT_NO_MDIAREA
    const QMdiArea *mdiArea = qobject_cast<QMdiArea *>(area);
#endif
#ifndef QT_NO_WORKSPACE
    const QWorkspace *workspace = qobject_cast<QWorkspace *>(area);
#endif
    if (true
#ifndef QT_NO_MDIAREA
        && !mdiArea
#endif
#ifndef QT_NO_WORKSPACE
    && !workspace
#endif
    )
        return 0;

    QWidgetList windows;
#ifndef QT_NO_MDIAREA
    if (mdiArea) {
        foreach (QMdiSubWindow *window, mdiArea->subWindowList())
            windows.append(window);
    } else
#endif
    {
#ifndef QT_NO_WORKSPACE
        foreach (QWidget *window, workspace->windowList())
            windows.append(window->parentWidget());
#endif
    }

    if (windows.isEmpty() || entry < 1 || entry > windows.count())
        return 0;

    QWidget *source = windows.at(entry - 1);
    QMap<int, QWidget *> candidates;
    foreach (QWidget *window, windows) {
        if (source == window)
            continue;
        int candidateDistance = distance(source, window, relation);
        if (candidateDistance >= 0)
            candidates.insert(candidateDistance, window);
    }

    int minimumDistance = INT_MAX;
    QWidget *target = 0;
    foreach (QWidget *candidate, candidates) {
        switch (relation) {
        case QAccessible::Up:
        case QAccessible::Down:
            if (qAbs(candidate->x() - source->x()) < minimumDistance) {
                target = candidate;
                minimumDistance = qAbs(candidate->x() - source->x());
            }
            break;
        case QAccessible::Left:
        case QAccessible::Right:
            if (qAbs(candidate->y() - source->y()) < minimumDistance) {
                target = candidate;
                minimumDistance = qAbs(candidate->y() - source->y());
            }
            break;
        default:
            break;
        }
        if (minimumDistance == 0)
            break;
    }

#ifndef QT_NO_WORKSPACE
    if (workspace) {
        foreach (QWidget *widget, workspace->windowList()) {
            if (widget->parentWidget() == target)
                target = widget;
        }
    }
#endif
    return target;
}

#ifndef QT_NO_TEXTEDIT

/*!
  \class QAccessibleTextEdit
  \brief The QAccessibleTextEdit class implements the QAccessibleInterface for richtext editors.
  \internal
*/

static QTextBlock qTextBlockAt(const QTextDocument *doc, int pos)
{
    Q_ASSERT(pos >= 0);

    QTextBlock block = doc->begin();
    int i = 0;
    while (block.isValid() && i < pos) {
        block = block.next();
        ++i;
    }
    return block;
}

static int qTextBlockPosition(QTextBlock block)
{
    int child = 0;
    while (block.isValid()) {
        block = block.previous();
        ++child;
    }

    return child;
}

/*!
  \fn QAccessibleTextEdit::QAccessibleTextEdit(QWidget* widget)

  Constructs a QAccessibleTextEdit object for a \a widget.
*/
QAccessibleTextEdit::QAccessibleTextEdit(QWidget *o)
: QAccessibleWidgetEx(o, EditableText)
{
    Q_ASSERT(widget()->inherits("QTextEdit"));
    childOffset = QAccessibleWidgetEx::childCount();
}

/*! Returns the text edit. */
QTextEdit *QAccessibleTextEdit::textEdit() const
{
    return static_cast<QTextEdit *>(widget());
}

QRect QAccessibleTextEdit::rect(int child) const
{
    if (child <= childOffset)
        return QAccessibleWidgetEx::rect(child);

     QTextEdit *edit = textEdit();
     QTextBlock block = qTextBlockAt(edit->document(), child - childOffset - 1);
     if (!block.isValid())
         return QRect();

     QRect rect = edit->document()->documentLayout()->blockBoundingRect(block).toRect();
     rect.translate(-edit->horizontalScrollBar()->value(), -edit->verticalScrollBar()->value());

     rect = edit->viewport()->rect().intersect(rect);
     if (rect.isEmpty())
         return QRect();

     return rect.translated(edit->viewport()->mapToGlobal(QPoint(0, 0)));
}

int QAccessibleTextEdit::childAt(int x, int y) const
{
    QTextEdit *edit = textEdit();
    if (!edit->isVisible())
        return -1;

    QPoint point = edit->viewport()->mapFromGlobal(QPoint(x, y));
    QTextBlock block = edit->cursorForPosition(point).block();
    if (block.isValid())
        return qTextBlockPosition(block) + childOffset;

    return QAccessibleWidgetEx::childAt(x, y);
}

/*! \reimp */
QString QAccessibleTextEdit::text(Text t, int child) const
{
    if (t == Value) {
        if (child > childOffset)
            return qTextBlockAt(textEdit()->document(), child - childOffset - 1).text();
        if (!child)
            return textEdit()->toPlainText();
    }

    return QAccessibleWidgetEx::text(t, child);
}

/*! \reimp */
void QAccessibleTextEdit::setText(Text t, int child, const QString &text)
{
    if (t != Value || (child > 0 && child <= childOffset)) {
        QAccessibleWidgetEx::setText(t, child, text);
        return;
    }
    if (textEdit()->isReadOnly())
        return;

    if (!child) {
        textEdit()->setText(text);
        return;
    }
    QTextBlock block = qTextBlockAt(textEdit()->document(), child - childOffset - 1);
    if (!block.isValid())
        return;

    QTextCursor cursor(block);
    cursor.select(QTextCursor::BlockUnderCursor);
    cursor.insertText(text);
}

/*! \reimp */
QAccessible::Role QAccessibleTextEdit::role(int child) const
{
    if (child > childOffset)
        return EditableText;
    return QAccessibleWidgetEx::role(child);
}

QVariant QAccessibleTextEdit::invokeMethodEx(QAccessible::Method method, int child,
                                                     const QVariantList &params)
{
    if (child)
        return QVariant();

    switch (method) {
    case ListSupportedMethods: {
        QSet<QAccessible::Method> set;
        set << ListSupportedMethods << SetCursorPosition << GetCursorPosition;
        return qVariantFromValue(set | qvariant_cast<QSet<QAccessible::Method> >(
                    QAccessibleWidgetEx::invokeMethodEx(method, child, params)));
    }
    case SetCursorPosition:
        setCursorPosition(params.value(0).toInt());
        return true;
    case GetCursorPosition:
        return textEdit()->textCursor().position();
    default:
        return QAccessibleWidgetEx::invokeMethodEx(method, child, params);
    }
}

int QAccessibleTextEdit::childCount() const
{
    return childOffset + textEdit()->document()->blockCount();
}
#endif // QT_NO_TEXTEDIT

#ifndef QT_NO_STACKEDWIDGET
// ======================= QAccessibleStackedWidget ======================
QAccessibleStackedWidget::QAccessibleStackedWidget(QWidget *widget)
    : QAccessibleWidgetEx(widget, LayeredPane)
{
    Q_ASSERT(qobject_cast<QStackedWidget *>(widget));
}

QVariant QAccessibleStackedWidget::invokeMethodEx(QAccessible::Method, int, const QVariantList &)
{
    return QVariant();
}


int QAccessibleStackedWidget::childAt(int x, int y) const
{
    if (!stackedWidget()->isVisible())
        return -1;
    QWidget *currentWidget = stackedWidget()->currentWidget();
    if (!currentWidget)
        return -1;
    QPoint position = currentWidget->mapFromGlobal(QPoint(x, y));
    if (currentWidget->rect().contains(position))
        return 1;
    return -1;
}

int QAccessibleStackedWidget::childCount() const
{
    return stackedWidget()->count();
}

int QAccessibleStackedWidget::indexOfChild(const QAccessibleInterface *child) const
{
    if (!child || (stackedWidget()->currentWidget() != child->object()))
        return -1;
    return 1;
}

int QAccessibleStackedWidget::navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const
{
    *target = 0;

    QObject *targetObject = 0;
    switch (relation) {
    case Child:
        if (entry != 1)
            return -1;
        targetObject = stackedWidget()->currentWidget();
        break;
    default:
        return QAccessibleWidgetEx::navigate(relation, entry, target);
    }
    *target = QAccessible::queryAccessibleInterface(targetObject);
    return *target ? 0 : -1;
}

QStackedWidget *QAccessibleStackedWidget::stackedWidget() const
{
    return static_cast<QStackedWidget *>(object());
}
#endif // QT_NO_STACKEDWIDGET

#ifndef QT_NO_TOOLBOX
// ======================= QAccessibleToolBox ======================
QAccessibleToolBox::QAccessibleToolBox(QWidget *widget)
    : QAccessibleWidgetEx(widget, LayeredPane)
{
    Q_ASSERT(qobject_cast<QToolBox *>(widget));
}

QString QAccessibleToolBox::text(Text textType, int child) const
{
    if (textType != Value || child <= 0 || child > toolBox()->count())
        return QAccessibleWidgetEx::text(textType, child);
    return toolBox()->itemText(child - 1);
}

void QAccessibleToolBox::setText(Text textType, int child, const QString &text)
{
    if (textType != Value || child <= 0 || child > toolBox()->count()) {
        QAccessibleWidgetEx::setText(textType, child, text);
        return;
    }
    toolBox()->setItemText(child - 1, text);
}

QAccessible::State QAccessibleToolBox::state(int child) const
{
    QWidget *childWidget = toolBox()->widget(child - 1);
    if (!childWidget)
        return QAccessibleWidgetEx::state(child);
    QAccessible::State childState = QAccessible::Normal;
    if (toolBox()->currentWidget() == childWidget)
        childState |= QAccessible::Expanded;
    else
        childState |= QAccessible::Collapsed;
    return childState;
}

QVariant QAccessibleToolBox::invokeMethodEx(QAccessible::Method, int, const QVariantList &)
{
    return QVariant();
}

int QAccessibleToolBox::childCount() const
{
    return toolBox()->count();
}

int QAccessibleToolBox::indexOfChild(const QAccessibleInterface *child) const
{
    if (!child)
        return -1;
    QWidget *childWidget = qobject_cast<QWidget *>(child->object());
    if (!childWidget)
        return -1;
    int index = toolBox()->indexOf(childWidget);
    if (index != -1)
        ++index;
    return index;
}

int QAccessibleToolBox::navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const
{
    *target = 0;
    if (entry <= 0 || entry > toolBox()->count())
        return QAccessibleWidgetEx::navigate(relation, entry, target);
    int index = -1;
    if (relation == QAccessible::Up)
        index = entry - 2;
    else if (relation == QAccessible::Down)
        index = entry;
    *target = QAccessible::queryAccessibleInterface(toolBox()->widget(index));
    return *target ? 0: -1;
}

QToolBox * QAccessibleToolBox::toolBox() const
{
    return static_cast<QToolBox *>(object());
}
#endif // QT_NO_TOOLBOX

// ======================= QAccessibleMdiArea ======================
#ifndef QT_NO_MDIAREA
QAccessibleMdiArea::QAccessibleMdiArea(QWidget *widget)
    : QAccessibleWidgetEx(widget, LayeredPane)
{
    Q_ASSERT(qobject_cast<QMdiArea *>(widget));
}

QAccessible::State QAccessibleMdiArea::state(int child) const
{
    if (child < 0)
        return QAccessibleWidgetEx::state(child);
    if (child == 0)
        return QAccessible::Normal;
    QList<QMdiSubWindow *> subWindows = mdiArea()->subWindowList();
    if (subWindows.isEmpty() || child > subWindows.count())
        return QAccessibleWidgetEx::state(child);
    if (subWindows.at(child - 1) == mdiArea()->activeSubWindow())
        return QAccessible::Focused;
    return QAccessible::Normal;
}

QVariant QAccessibleMdiArea::invokeMethodEx(QAccessible::Method, int, const QVariantList &)
{
    return QVariant();
}

int QAccessibleMdiArea::childCount() const
{
    return mdiArea()->subWindowList().count();
}

int QAccessibleMdiArea::indexOfChild(const QAccessibleInterface *child) const
{
    if (!child || !child->object() || mdiArea()->subWindowList().isEmpty())
        return -1;
    if (QMdiSubWindow *window = qobject_cast<QMdiSubWindow *>(child->object())) {
        int index = mdiArea()->subWindowList().indexOf(window);
        if (index != -1)
            return ++index;
    }
    return -1;
}

int QAccessibleMdiArea::navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const
{
    *target = 0;
    QWidget *targetObject = 0;
    QList<QMdiSubWindow *> subWindows = mdiArea()->subWindowList();
    switch (relation) {
    case Child:
        if (entry < 1 || subWindows.isEmpty() || entry > subWindows.count())
            return -1;
        targetObject = subWindows.at(entry - 1);
        break;
    case Up:
    case Down:
    case Left:
    case Right:
        targetObject = mdiAreaNavigate(mdiArea(), relation, entry);
        break;
    default:
        return QAccessibleWidgetEx::navigate(relation, entry, target);
    }
    *target = QAccessible::queryAccessibleInterface(targetObject);
    return *target ? 0: -1;
}

QMdiArea *QAccessibleMdiArea::mdiArea() const
{
    return static_cast<QMdiArea *>(object());
}

// ======================= QAccessibleMdiSubWindow ======================
QAccessibleMdiSubWindow::QAccessibleMdiSubWindow(QWidget *widget)
    : QAccessibleWidgetEx(widget, QAccessible::Window)
{
    Q_ASSERT(qobject_cast<QMdiSubWindow *>(widget));
}

QString QAccessibleMdiSubWindow::text(Text textType, int child) const
{
    if (textType == QAccessible::Name && (child == 0 || child == 1)) {
        QString title = mdiSubWindow()->windowTitle();
        title.replace(QLatin1String("[*]"), QLatin1String(""));
        return title;
    }
    return QAccessibleWidgetEx::text(textType, child);
}

void QAccessibleMdiSubWindow::setText(Text textType, int child, const QString &text)
{
    if (textType == QAccessible::Name && (child == 0 || child == 1))
        mdiSubWindow()->setWindowTitle(text);
    else
        QAccessibleWidgetEx::setText(textType, child, text);
}

QAccessible::State QAccessibleMdiSubWindow::state(int child) const
{
    if (child != 0 || !mdiSubWindow()->parent())
        return QAccessibleWidgetEx::state(child);
    QAccessible::State state = QAccessible::Normal | QAccessible::Focusable;
    if (!mdiSubWindow()->isMaximized())
        state |= (QAccessible::Movable | QAccessible::Sizeable);
    if (mdiSubWindow()->isAncestorOf(QApplication::focusWidget())
            || QApplication::focusWidget() == mdiSubWindow())
        state |= QAccessible::Focused;
    if (!mdiSubWindow()->isVisible())
        state |= QAccessible::Invisible;
    if (!mdiSubWindow()->parentWidget()->contentsRect().contains(mdiSubWindow()->geometry()))
        state |= QAccessible::Offscreen;
    if (!mdiSubWindow()->isEnabled())
        state |= QAccessible::Unavailable;
    return state;
}

QVariant QAccessibleMdiSubWindow::invokeMethodEx(QAccessible::Method, int, const QVariantList &)
{
    return QVariant();
}

int QAccessibleMdiSubWindow::childCount() const
{
    if (mdiSubWindow()->widget())
        return 1;
    return 0;
}

int QAccessibleMdiSubWindow::indexOfChild(const QAccessibleInterface *child) const
{
    if (child && child->object() && child->object() == mdiSubWindow()->widget())
        return 1;
    return -1;
}

int QAccessibleMdiSubWindow::navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const
{
    *target = 0;

    if (!mdiSubWindow()->parent())
        return QAccessibleWidgetEx::navigate(relation, entry, target);

    QWidget *targetObject = 0;
    QMdiSubWindow *source = mdiSubWindow();
    switch (relation) {
    case Child:
        if (entry != 1 || !source->widget())
            return -1;
        targetObject = source->widget();
        break;
    case Up:
    case Down:
    case Left:
    case Right: {
        if (entry != 0)
            break;
        QWidget *parent = source->parentWidget();
        while (parent && !parent->inherits("QMdiArea"))
            parent = parent->parentWidget();
        QMdiArea *mdiArea = qobject_cast<QMdiArea *>(parent);
        if (!mdiArea)
            break;
        int index = mdiArea->subWindowList().indexOf(source);
        if (index == -1)
            break;
        if (QWidget *dest = mdiAreaNavigate(mdiArea, relation, index + 1)) {
            *target = QAccessible::queryAccessibleInterface(dest);
            return *target ? 0 : -1;
        }
        break;
    }
    default:
        return QAccessibleWidgetEx::navigate(relation, entry, target);
    }
    *target = QAccessible::queryAccessibleInterface(targetObject);
    return *target ? 0: -1;
}

QRect QAccessibleMdiSubWindow::rect(int child) const
{
    if (mdiSubWindow()->isHidden())
        return QRect();
    if (!mdiSubWindow()->parent())
        return QAccessibleWidgetEx::rect(child);
    const QPoint pos = mdiSubWindow()->mapToGlobal(QPoint(0, 0));
    if (child == 0)
        return QRect(pos, mdiSubWindow()->size());
    if (child == 1 && mdiSubWindow()->widget()) {
        if (mdiSubWindow()->widget()->isHidden())
            return QRect();
        const QRect contentsRect = mdiSubWindow()->contentsRect();
        return QRect(pos.x() + contentsRect.x(), pos.y() + contentsRect.y(),
                     contentsRect.width(), contentsRect.height());
    }
    return QRect();
}

int QAccessibleMdiSubWindow::childAt(int x, int y) const
{
    if (!mdiSubWindow()->isVisible())
        return -1;
    if (!mdiSubWindow()->parent())
        return QAccessibleWidgetEx::childAt(x, y);
    const QRect globalGeometry = rect(0);
    if (!globalGeometry.isValid())
        return -1;
    const QRect globalChildGeometry = rect(1);
    if (globalChildGeometry.isValid() && globalChildGeometry.contains(QPoint(x, y)))
        return 1;
    if (globalGeometry.contains(QPoint(x, y)))
        return 0;
    return -1;
}

QMdiSubWindow *QAccessibleMdiSubWindow::mdiSubWindow() const
{
    return static_cast<QMdiSubWindow *>(object());
}
#endif // QT_NO_MDIAREA

// ======================= QAccessibleWorkspace ======================
#ifndef QT_NO_WORKSPACE
QAccessibleWorkspace::QAccessibleWorkspace(QWidget *widget)
    : QAccessibleWidgetEx(widget, LayeredPane)
{
    Q_ASSERT(qobject_cast<QWorkspace *>(widget));
}

QAccessible::State QAccessibleWorkspace::state(int child) const
{
    if (child < 0)
        return QAccessibleWidgetEx::state(child);
    if (child == 0)
        return QAccessible::Normal;
    QWidgetList subWindows = workspace()->windowList();
    if (subWindows.isEmpty() || child > subWindows.count())
        return QAccessibleWidgetEx::state(child);
    if (subWindows.at(child - 1) == workspace()->activeWindow())
        return QAccessible::Focused;
    return QAccessible::Normal;
}

QVariant QAccessibleWorkspace::invokeMethodEx(QAccessible::Method, int, const QVariantList &)
{
    return QVariant();
}

int QAccessibleWorkspace::childCount() const
{
    return workspace()->windowList().count();
}

int QAccessibleWorkspace::indexOfChild(const QAccessibleInterface *child) const
{
    if (!child || !child->object() || workspace()->windowList().isEmpty())
        return -1;
    if (QWidget *window = qobject_cast<QWidget *>(child->object())) {
        int index = workspace()->windowList().indexOf(window);
        if (index != -1)
            return ++index;
    }
    return -1;
}

int QAccessibleWorkspace::navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const
{
    *target = 0;
    QWidget *targetObject = 0;
    QWidgetList subWindows = workspace()->windowList();
    switch (relation) {
    case Child:
        if (entry < 1 || subWindows.isEmpty() || entry > subWindows.count())
            return -1;
        targetObject = subWindows.at(entry - 1);
        break;
    case Up:
    case Down:
    case Left:
    case Right:
        targetObject = mdiAreaNavigate(workspace(), relation, entry);
        break;
    default:
        return QAccessibleWidgetEx::navigate(relation, entry, target);
    }
    *target = QAccessible::queryAccessibleInterface(targetObject);
    return *target ? 0: -1;
}

QWorkspace *QAccessibleWorkspace::workspace() const
{
    return static_cast<QWorkspace *>(object());
}
#endif

#ifndef QT_NO_DIALOGBUTTONBOX
// ======================= QAccessibleDialogButtonBox ======================
QAccessibleDialogButtonBox::QAccessibleDialogButtonBox(QWidget *widget)
    : QAccessibleWidgetEx(widget, Grouping)
{
    Q_ASSERT(qobject_cast<QDialogButtonBox*>(widget));
}

QVariant QAccessibleDialogButtonBox::invokeMethodEx(QAccessible::Method, int, const QVariantList &)
{
    return QVariant();
}
#endif // QT_NO_DIALOGBUTTONBOX

#ifndef QT_NO_TEXTBROWSER
QAccessibleTextBrowser::QAccessibleTextBrowser(QWidget *widget)
    : QAccessibleTextEdit(widget)
{
    Q_ASSERT(qobject_cast<QTextBrowser *>(widget));
}

QAccessible::Role QAccessibleTextBrowser::role(int child) const
{
    if (child != 0)
        return QAccessibleTextEdit::role(child);
    return QAccessible::StaticText;
}
#endif // QT_NO_TEXTBROWSER

#ifndef QT_NO_CALENDARWIDGET
// ===================== QAccessibleCalendarWidget ========================
QAccessibleCalendarWidget::QAccessibleCalendarWidget(QWidget *widget)
    : QAccessibleWidgetEx(widget, Table)
{
    Q_ASSERT(qobject_cast<QCalendarWidget *>(widget));
}

QVariant QAccessibleCalendarWidget::invokeMethodEx(QAccessible::Method, int, const QVariantList &)
{
    return QVariant();
}

int QAccessibleCalendarWidget::childCount() const
{
   return calendarWidget()->isNavigationBarVisible() ? 2 : 1;
}

int QAccessibleCalendarWidget::indexOfChild(const QAccessibleInterface *child) const
{
    if (!child || !child->object() || childCount() <= 0)
        return -1;
    if (qobject_cast<QAbstractItemView *>(child->object()))
        return childCount();
    return 1;
}

int QAccessibleCalendarWidget::navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const
{
    *target = 0;
    if (entry <= 0 || entry > childCount())
        return QAccessibleWidgetEx::navigate(relation, entry, target);
    QWidget *targetWidget = 0;
    switch (relation) {
    case Child:
        if (childCount() == 1) {
            targetWidget = calendarView();
        } else {
            if (entry == 1)
                targetWidget = navigationBar();
            else
                targetWidget = calendarView();
        }
        break;
    case Up:
        if (entry == 2)
            targetWidget = navigationBar();
        break;
    case Down:
        if (entry == 1 && childCount() == 2)
            targetWidget = calendarView();
        break;
    default:
        return QAccessibleWidgetEx::navigate(relation, entry, target);
    }
    *target = queryAccessibleInterface(targetWidget);
    return *target ? 0: -1;
}

QRect QAccessibleCalendarWidget::rect(int child) const
{
    if (!calendarWidget()->isVisible() || child > childCount())
        return QRect();
    if (child == 0)
        return QAccessibleWidgetEx::rect(child);
    QWidget *childWidget = 0;
    if (childCount() == 2)
        childWidget = child == 1 ? navigationBar() : calendarView();
    else
        childWidget = calendarView();
    return QRect(childWidget->mapToGlobal(QPoint(0, 0)), childWidget->size());
}

int QAccessibleCalendarWidget::childAt(int x, int y) const
{
    const QPoint globalTargetPos = QPoint(x, y);
    if (!rect(0).contains(globalTargetPos))
        return -1;
    if (rect(1).contains(globalTargetPos))
        return 1;
    if (rect(2).contains(globalTargetPos))
        return 2;
    return 0;
}

QCalendarWidget *QAccessibleCalendarWidget::calendarWidget() const
{
    return static_cast<QCalendarWidget *>(object());
}

QAbstractItemView *QAccessibleCalendarWidget::calendarView() const
{
    foreach (QObject *child, calendarWidget()->children()) {
        if (child->objectName() == QLatin1String("qt_calendar_calendarview"))
            return static_cast<QAbstractItemView *>(child);
    }
    return 0;
}

QWidget *QAccessibleCalendarWidget::navigationBar() const
{
    foreach (QObject *child, calendarWidget()->children()) {
        if (child->objectName() == QLatin1String("qt_calendar_navigationbar"))
            return static_cast<QWidget *>(child);
    }
    return 0;
}
#endif // QT_NO_CALENDARWIDGET

#ifndef QT_NO_DOCKWIDGET
QAccessibleDockWidget::QAccessibleDockWidget(QWidget *widget)
    : QAccessibleWidgetEx(widget, Window)
{

}

int QAccessibleDockWidget::navigate(RelationFlag relation, int entry, QAccessibleInterface **iface) const
{
    if (relation == Child) {
        if (entry == 1) {
            *iface = new QAccessibleTitleBar(dockWidget());
            return 0;
        } else if (entry == 2) {
            if (dockWidget()->widget())
                *iface = QAccessible::queryAccessibleInterface(dockWidget()->widget());
            return 0;
        }
        *iface = 0;
        return -1;
    }
    return QAccessibleWidgetEx::navigate(relation, entry, iface);
}

int QAccessibleDockWidget::childAt(int x, int y) const
{
    for (int i = childCount(); i >= 0; --i) {
        if (rect(i).contains(x,y))
            return i;
    }
    return -1;
}

int QAccessibleDockWidget::childCount() const
{
    return dockWidget()->widget() ? 2 : 1;
}

int QAccessibleDockWidget::indexOfChild(const QAccessibleInterface *child) const
{
    if (child) {
        if (child->role(0) == TitleBar) {
            return 1;
        } else {
            return 2;   //###
        }
    }
    return -1;
}

QAccessible::Role QAccessibleDockWidget::role(int child) const
{
    switch (child) {
        case 0:
            return Window;
        case 1:
            return TitleBar;
        case 2:
            //###
            break;
        default:
            break;
    }
    return NoRole;
}

QAccessible::State QAccessibleDockWidget::state(int child) const
{
    //### mark tabified widgets as invisible
    return QAccessibleWidgetEx::state(child);
}

QRect QAccessibleDockWidget::rect (int child ) const
{
    QRect rect;
    bool mapToGlobal = true;
    if (child == 0) {
        if (dockWidget()->isFloating()) {
            rect = dockWidget()->frameGeometry();
            mapToGlobal = false;
        } else {
            rect = dockWidget()->rect();
        }
    }else if (child == 1) {
        QDockWidgetLayout *layout = qobject_cast<QDockWidgetLayout*>(dockWidget()->layout());
        rect = layout->titleArea();
    }else if (child == 2) {
        if (dockWidget()->widget())
            rect = dockWidget()->widget()->geometry();
    }
    if (rect.isNull())
        return rect;

    if (mapToGlobal)
        rect.moveTopLeft(dockWidget()->mapToGlobal(rect.topLeft()));

    return rect;
}

QVariant QAccessibleDockWidget::invokeMethodEx(QAccessible::Method, int, const QVariantList &)
{
    return QVariant();
}

QDockWidget *QAccessibleDockWidget::dockWidget() const
{
    return static_cast<QDockWidget *>(object());
}

////
//      QAccessibleTitleBar
////
QAccessibleTitleBar::QAccessibleTitleBar(QDockWidget *widget)
    : m_dockWidget(widget)
{

}

int QAccessibleTitleBar::navigate(RelationFlag relation, int entry, QAccessibleInterface **iface) const
{
    if (entry == 0 || relation == Self) {
        *iface = new QAccessibleTitleBar(dockWidget());
        return 0;
    }
    switch (relation) {
    case Child:
    case FocusChild:
        if (entry >= 1) {
            QDockWidgetLayout *layout = dockWidgetLayout();
            int index = 1;
            int role;
            for (role = QDockWidgetLayout::CloseButton; role <= QDockWidgetLayout::FloatButton; ++role) {
                QWidget *w = layout->widgetForRole((QDockWidgetLayout::Role)role);
                if (!w->isVisible())
                    continue;
                if (index == entry)
                    break;
                ++index;
            }
            *iface = 0;
            return role > QDockWidgetLayout::FloatButton ? -1 : index;
        }
        break;
    case Ancestor:
        {
        QAccessibleDockWidget *target = new QAccessibleDockWidget(dockWidget());
        int index;
        if (entry == 1) {
            *iface = target;
            return 0;
        }
        index = target->navigate(Ancestor, entry - 1, iface);
        delete target;
        return index;

        break;}
    case Sibling:
        return navigate(Child, entry, iface);
        break;
    default:
        break;
    }
    *iface = 0;
    return -1;
}

QAccessible::Relation QAccessibleTitleBar::relationTo(int /*child*/,  const QAccessibleInterface * /*other*/, int /*otherChild*/) const
{
    return Unrelated;   //###
}

int QAccessibleTitleBar::indexOfChild(const QAccessibleInterface * /*child*/) const
{
    return -1;
}

int QAccessibleTitleBar::childCount() const
{
    QDockWidgetLayout *layout = dockWidgetLayout();
    int count = 0;
    for (int role = QDockWidgetLayout::CloseButton; role <= QDockWidgetLayout::FloatButton; ++role) {
        QWidget *w = layout->widgetForRole((QDockWidgetLayout::Role)role);
        if (w && w->isVisible())
            ++count;
    }
    return count;
}

QString QAccessibleTitleBar::text(Text t, int child) const
{
    if (!child) {
        if (t == Value) {
            return dockWidget()->windowTitle();
        }
    }
    return QString();
}

QAccessible::State QAccessibleTitleBar::state(int child) const
{
    QAccessible::State state = Normal;
    if (child) {
        QDockWidgetLayout *layout = dockWidgetLayout();
        QAbstractButton *b = static_cast<QAbstractButton *>(layout->widgetForRole((QDockWidgetLayout::Role)child));
        if (b) {
            if (b->isDown())
                state |= Pressed;
        }
    } else {
        QDockWidget *w = dockWidget();
        if (w->testAttribute(Qt::WA_WState_Visible) == false)
            state |= Invisible;
        if (w->focusPolicy() != Qt::NoFocus && w->isActiveWindow())
            state |= Focusable;
        if (w->hasFocus())
            state |= Focused;
        if (!w->isEnabled())
            state |= Unavailable;
    }

    return state;
}

QRect QAccessibleTitleBar::rect (int child ) const
{
    bool mapToGlobal = true;
    QRect rect;
    if (child == 0) {
        if (dockWidget()->isFloating()) {
            rect = dockWidget()->frameGeometry();
            QPoint globalPos = dockWidget()->mapToGlobal( dockWidget()->widget()->rect().topLeft() );
            globalPos.ry()--;
            rect.setBottom(globalPos.y());
            mapToGlobal = false;
        } else {
            QDockWidgetLayout *layout = qobject_cast<QDockWidgetLayout*>(dockWidget()->layout());
            rect = layout->titleArea();
        }
    }else if (child >= 1 && child <= childCount()) {
        QDockWidgetLayout *layout = dockWidgetLayout();
        int index = 1;
        for (int role = QDockWidgetLayout::CloseButton; role <= QDockWidgetLayout::FloatButton; ++role) {
            QWidget *w = layout->widgetForRole((QDockWidgetLayout::Role)role);
            if (!w || !w->isVisible())
                continue;
            if (index == child) {
                rect = w->geometry();
                break;
            }
            ++index;
        }
    }
    if (rect.isNull())
        return rect;

    if (mapToGlobal)
        rect.moveTopLeft(dockWidget()->mapToGlobal(rect.topLeft()));
    return rect;
}

int QAccessibleTitleBar::childAt(int x, int y) const
{
    for (int i = childCount(); i >= 0; --i) {
        if (rect(i).contains(x,y))
            return i;
    }
    return -1;
}

QObject *QAccessibleTitleBar::object() const
{
    return 0;
}

QDockWidgetLayout *QAccessibleTitleBar::dockWidgetLayout() const
{
    return qobject_cast<QDockWidgetLayout*>(dockWidget()->layout());
}

QDockWidget *QAccessibleTitleBar::dockWidget() const
{
    return m_dockWidget;
}

QString QAccessibleTitleBar::actionText(int action, Text t, int child) const
{
    QString str;
    if (child >= 1 && child <= childCount()) {
        if (t == Name) {
            switch (action) {
            case Press:
            case DefaultAction:
                if (child == QDockWidgetLayout::CloseButton) {
                    str = QDockWidget::tr("Close");
                } else if (child == QDockWidgetLayout::FloatButton) {
                    str = dockWidget()->isFloating() ? QDockWidget::tr("Dock")
                                                     : QDockWidget::tr("Float");
                }
                break;
            default:
                break;
            }
        }
    }
    return str;
}

bool QAccessibleTitleBar::doAction(int action, int child, const QVariantList& /*params*/)
{
    if (!child || !dockWidget()->isEnabled())
        return false;

    switch (action) {
    case DefaultAction:
    case Press: {
        QDockWidgetLayout *layout = dockWidgetLayout();
        QAbstractButton *btn = static_cast<QAbstractButton *>(layout->widgetForRole((QDockWidgetLayout::Role)child));
        if (btn)
            btn->animateClick();
        return true;
        break;}
    default:
        break;
    }

    return false;
}

int QAccessibleTitleBar::userActionCount (int /*child*/) const
{
    return 0;
}

QAccessible::Role QAccessibleTitleBar::role(int child) const
{
    switch (child) {
        case 0:
            return TitleBar;
            break;
        default:
            if (child >= 1 && child <= childCount())
                return PushButton;
            break;
    }

    return NoRole;
}

void QAccessibleTitleBar::setText(Text /*t*/, int /*child*/, const QString &/*text*/)
{

}

bool QAccessibleTitleBar::isValid() const
{
    return dockWidget();
}

#endif // QT_NO_DOCKWIDGET

#ifndef QT_NO_TEXTEDIT
void QAccessibleTextEdit::addSelection(int startOffset, int endOffset)
{
    setSelection(0, startOffset, endOffset);
}

QString QAccessibleTextEdit::attributes(int offset, int *startOffset, int *endOffset)
{
    // TODO - wait for a definition of attributes
    Q_UNUSED(offset);
    Q_UNUSED(startOffset);
    Q_UNUSED(endOffset);
    return QString();
}

int QAccessibleTextEdit::cursorPosition()
{
    return textEdit()->textCursor().position();
}

QRect QAccessibleTextEdit::characterRect(int offset, CoordinateType coordType)
{
    QTextEdit *edit = textEdit();
    QTextCursor cursor(edit->document());
    cursor.setPosition(offset);

    if (cursor.position() != offset)
        return QRect();

    QRect r = edit->cursorRect(cursor);
    if (cursor.movePosition(QTextCursor::NextCharacter)) {
        r.setWidth(edit->cursorRect(cursor).y() - r.y());
    } else {
        // we don't know the width of the character - maybe because we're at document end
        // in that case, IAccessible2 tells us to return the width of a default character
        int averageCharWidth = QFontMetrics(cursor.charFormat().font()).averageCharWidth();
        if (edit->layoutDirection() == Qt::RightToLeft)
            averageCharWidth *= -1;
        r.setWidth(averageCharWidth);
    }

    switch (coordType) {
    case RelativeToScreen:
        r.moveTo(edit->viewport()->mapToGlobal(r.topLeft()));
        break;
    case RelativeToParent:
        break;
    }

    return r;
}

int QAccessibleTextEdit::selectionCount()
{
    return textEdit()->textCursor().hasSelection() ? 1 : 0;
}

int QAccessibleTextEdit::offsetAtPoint(const QPoint &point, CoordinateType coordType)
{
    QTextEdit *edit = textEdit();

    QPoint p = point;
    if (coordType == RelativeToScreen)
        p = edit->viewport()->mapFromGlobal(p);
    // convert to document coordinates
    p += QPoint(edit->horizontalScrollBar()->value(), edit->verticalScrollBar()->value());

    return edit->document()->documentLayout()->hitTest(p, Qt::ExactHit);
}

void QAccessibleTextEdit::selection(int selectionIndex, int *startOffset, int *endOffset)
{
    *startOffset = *endOffset = 0;
    QTextCursor cursor = textEdit()->textCursor();

    if (selectionIndex != 0 || !cursor.hasSelection())
        return;

    *startOffset = cursor.selectionStart();
    *endOffset = cursor.selectionEnd();
}

QString QAccessibleTextEdit::text(int startOffset, int endOffset)
{
    QTextCursor cursor(textEdit()->document());

    cursor.setPosition(startOffset, QTextCursor::MoveAnchor);
    cursor.setPosition(endOffset, QTextCursor::KeepAnchor);

    return cursor.selectedText();
}

QString QAccessibleTextEdit::textBeforeOffset (int offset, BoundaryType boundaryType,
        int *startOffset, int *endOffset)
{
    // TODO - what exactly is before?
    Q_UNUSED(offset);
    Q_UNUSED(boundaryType);
    Q_UNUSED(startOffset);
    Q_UNUSED(endOffset);
    return QString();
}

QString QAccessibleTextEdit::textAfterOffset(int offset, BoundaryType boundaryType,
        int *startOffset, int *endOffset)
{
    // TODO - what exactly is after?
    Q_UNUSED(offset);
    Q_UNUSED(boundaryType);
    Q_UNUSED(startOffset);
    Q_UNUSED(endOffset);
    return QString();
}

QString QAccessibleTextEdit::textAtOffset(int offset, BoundaryType boundaryType,
                                          int *startOffset, int *endOffset)
{
    Q_ASSERT(startOffset);
    Q_ASSERT(endOffset);

    *startOffset = *endOffset = -1;
    QTextEdit *edit = textEdit();

    QTextCursor cursor(edit->document());
    if (offset >= characterCount())
        return QString();

    switch (boundaryType) {
    case CharBoundary:
        cursor.setPosition(offset);
        *startOffset = cursor.position();
        cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);
        *endOffset = cursor.position();
        break;
    case WordBoundary:
        cursor.movePosition(QTextCursor::StartOfWord, QTextCursor::MoveAnchor);
        *startOffset = cursor.position();
        cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
        *endOffset = cursor.position();
        break;
    case SentenceBoundary:
        // TODO - what's a sentence?
        return QString();
    case LineBoundary:
        cursor.movePosition(QTextCursor::StartOfLine, QTextCursor::MoveAnchor);
        *startOffset = cursor.position();
        cursor.movePosition(QTextCursor::EndOfLine, QTextCursor::KeepAnchor);
        *endOffset = cursor.position();
        break;
    case ParagraphBoundary:
        cursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::MoveAnchor);
        *startOffset = cursor.position();
        cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
        *endOffset = cursor.position();
        break;
    case NoBoundary: {
        *startOffset = 0;
        const QString txt = edit->toPlainText();
        *endOffset = txt.count();
        return txt; }
    default:
        qDebug("AccessibleTextAdaptor::textAtOffset: Unknown boundary type %d", boundaryType);
        return QString();
    }

    return cursor.selectedText();
}

void QAccessibleTextEdit::removeSelection(int selectionIndex)
{
    if (selectionIndex != 0)
        return;

    QTextCursor cursor = textEdit()->textCursor();
    cursor.clearSelection();
    textEdit()->setTextCursor(cursor);
}

void QAccessibleTextEdit::setCursorPosition(int position)
{
    QTextCursor cursor = textEdit()->textCursor();
    cursor.setPosition(position);
    textEdit()->setTextCursor(cursor);
}

void QAccessibleTextEdit::setSelection(int selectionIndex, int startOffset, int endOffset)
{
    if (selectionIndex != 0)
        return;

    QTextCursor cursor = textEdit()->textCursor();
    cursor.setPosition(startOffset, QTextCursor::MoveAnchor);
    cursor.setPosition(endOffset, QTextCursor::KeepAnchor);
    textEdit()->setTextCursor(cursor);
}

int QAccessibleTextEdit::characterCount()
{
    return textEdit()->toPlainText().count();
}

void QAccessibleTextEdit::scrollToSubstring(int startIndex, int endIndex)
{
    QTextEdit *edit = textEdit();

    QTextCursor cursor(edit->document());
    cursor.setPosition(startIndex);
    QRect r = edit->cursorRect(cursor);

    cursor.setPosition(endIndex);
    r.setBottomRight(edit->cursorRect(cursor).bottomRight());

    r.moveTo(r.x() + edit->horizontalScrollBar()->value(),
             r.y() + edit->verticalScrollBar()->value());

    // E V I L, but ensureVisible is not public
    if (!QMetaObject::invokeMethod(edit, "_q_ensureVisible", Q_ARG(QRectF, r)))
        qWarning("AccessibleTextEdit::scrollToSubstring failed!");
}

static QTextCursor cursorForRange(QTextEdit *textEdit, int startOffset, int endOffset)
{
    QTextCursor cursor(textEdit->document());
    cursor.setPosition(startOffset, QTextCursor::MoveAnchor);
    cursor.setPosition(endOffset, QTextCursor::KeepAnchor);

    return cursor;
}

void QAccessibleTextEdit::copyText(int startOffset, int endOffset)
{
    QTextCursor cursor = cursorForRange(textEdit(), startOffset, endOffset);

    if (!cursor.hasSelection())
        return;

//     QApplication::clipboard()->setMimeData(new QTextEditMimeData(cursor.selection()));
}

void QAccessibleTextEdit::deleteText(int startOffset, int endOffset)
{
    QTextCursor cursor = cursorForRange(textEdit(), startOffset, endOffset);

    cursor.removeSelectedText();
}

void QAccessibleTextEdit::insertText(int offset, const QString &text)
{
    QTextCursor cursor(textEdit()->document());
    cursor.setPosition(offset);

    cursor.insertText(text);
}

void QAccessibleTextEdit::cutText(int startOffset, int endOffset)
{
    QTextCursor cursor = cursorForRange(textEdit(), startOffset, endOffset);

    if (!cursor.hasSelection())
        return;

//     QApplication::clipboard()->setMimeData(new QTextEditMimeData(cursor.selection()));
    cursor.removeSelectedText();
}

void QAccessibleTextEdit::pasteText(int offset)
{
    QTextEdit *edit = textEdit();

    QTextCursor oldCursor = edit->textCursor();
    QTextCursor newCursor = oldCursor;
    newCursor.setPosition(offset);

    edit->setTextCursor(newCursor);
#ifndef QT_NO_CLIPBOARD
    edit->paste();
#endif
    edit->setTextCursor(oldCursor);
}

void QAccessibleTextEdit::replaceText(int startOffset, int endOffset, const QString &text)
{
    QTextCursor cursor = cursorForRange(textEdit(), startOffset, endOffset);

    cursor.removeSelectedText();
    cursor.insertText(text);
}

void QAccessibleTextEdit::setAttributes(int startOffset, int endOffset, const QString &attributes)
{
    // TODO
    Q_UNUSED(startOffset);
    Q_UNUSED(endOffset);
    Q_UNUSED(attributes);
}

#endif // QT_NO_TEXTEDIT

#ifndef QT_NO_MAINWINDOW
QAccessibleMainWindow::QAccessibleMainWindow(QWidget *widget)
    : QAccessibleWidgetEx(widget, Application) { }

QVariant QAccessibleMainWindow::invokeMethodEx(QAccessible::Method /*method*/, int /*child*/, const QVariantList & /*params*/)
{
    return QVariant();
}

int QAccessibleMainWindow::childCount() const
{
    QList<QWidget*> kids = childWidgets(mainWindow(), true);
    return kids.count();
}

int QAccessibleMainWindow::indexOfChild(const QAccessibleInterface *iface) const
{
    QList<QWidget*> kids = childWidgets(mainWindow(), true);
    int childIndex = kids.indexOf(static_cast<QWidget*>(iface->object()));
    return childIndex == -1 ? -1 : ++childIndex;
}

int QAccessibleMainWindow::navigate(RelationFlag relation, int entry, QAccessibleInterface **iface) const
{
    if (relation == Child && entry >= 1) {
        QList<QWidget*> kids = childWidgets(mainWindow(), true);
        if (entry <= kids.count()) {
            *iface = QAccessible::queryAccessibleInterface(kids.at(entry - 1));
            return *iface ? 0 : -1;
        }
    }
    return QAccessibleWidgetEx::navigate(relation, entry, iface);
}

int QAccessibleMainWindow::childAt(int x, int y) const
{
    QWidget *w = widget();
    if (!w->isVisible())
        return -1;
    QPoint gp = w->mapToGlobal(QPoint(0, 0));
    if (!QRect(gp.x(), gp.y(), w->width(), w->height()).contains(x, y))
        return -1;

    QWidgetList kids = childWidgets(mainWindow(), true);
    QPoint rp = mainWindow()->mapFromGlobal(QPoint(x, y));
    for (int i = 0; i < kids.size(); ++i) {
        QWidget *child = kids.at(i);
        if (!child->isWindow() && !child->isHidden() && child->geometry().contains(rp)) {
            return i + 1;
        }
    }
    return 0;
}

QMainWindow *QAccessibleMainWindow::mainWindow() const
{
    return qobject_cast<QMainWindow *>(object());
}

#endif //QT_NO_MAINWINDOW

QT_END_NAMESPACE

#endif // QT_NO_ACCESSIBILITY
