/****************************************************************************
**
** 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 QtGui module 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 "qaccessible.h"

#ifndef QT_NO_ACCESSIBILITY
#include "qaccessible_mac_p.h"
#include "qhash.h"
#include "qset.h"
#include "qpointer.h"
#include "qapplication.h"
#include "qmainwindow.h"
#include "qtextdocument.h"
#include "qdebug.h"
#include "qabstractslider.h"
#include "qsplitter.h"
#include "qtabwidget.h"
#include "qlistview.h"
#include "qtableview.h"
#include "qdockwidget.h"

#include <private/qt_mac_p.h>
#include <private/qwidget_p.h>
#include <CoreFoundation/CoreFoundation.h>

QT_BEGIN_NAMESPACE

/*
    Set up platform defines. There is a one-to-one correspondence between the
    Carbon and Cocoa roles and attributes, but the prefix and type changes.
*/
#ifdef QT_MAC_USE_COCOA
typedef NSString * const QAXRoleType;
#define QAXApplicationRole NSAccessibilityApplicationRole
#define QAXButtonRole NSAccessibilityButtonRole
#define QAXCancelAction NSAccessibilityCancelAction
#define QAXCheckBoxRole NSAccessibilityCheckBoxRole
#define QAXChildrenAttribute NSAccessibilityChildrenAttribute
#define QAXCloseButtonAttribute NSAccessibilityCloseButtonAttribute
#define QAXCloseButtonAttribute NSAccessibilityCloseButtonAttribute
#define QAXColumnRole NSAccessibilityColumnRole
#define QAXConfirmAction NSAccessibilityConfirmAction
#define QAXContentsAttribute NSAccessibilityContentsAttribute
#define QAXDecrementAction NSAccessibilityDecrementAction
#define QAXDecrementArrowSubrole NSAccessibilityDecrementArrowSubrole
#define QAXDecrementPageSubrole NSAccessibilityDecrementPageSubrole
#define QAXDescriptionAttribute NSAccessibilityDescriptionAttribute
#define QAXEnabledAttribute NSAccessibilityEnabledAttribute
#define QAXExpandedAttribute NSAccessibilityExpandedAttribute
#define QAXFocusedAttribute NSAccessibilityFocusedAttribute
#define QAXFocusedUIElementChangedNotification NSAccessibilityFocusedUIElementChangedNotification
#define QAXFocusedWindowChangedNotification NSAccessibilityFocusedWindowChangedNotification
#define QAXGroupRole NSAccessibilityGroupRole
#define QAXGrowAreaAttribute NSAccessibilityGrowAreaAttribute
#define QAXGrowAreaRole NSAccessibilityGrowAreaRole
#define QAXHelpAttribute NSAccessibilityHelpAttribute
#define QAXHorizontalOrientationValue NSAccessibilityHorizontalOrientationValue
#define QAXHorizontalScrollBarAttribute NSAccessibilityHorizontalScrollBarAttribute
#define QAXIncrementAction NSAccessibilityIncrementAction
#define QAXIncrementArrowSubrole NSAccessibilityIncrementArrowSubrole
#define QAXIncrementPageSubrole NSAccessibilityIncrementPageSubrole
#define QAXIncrementorRole NSAccessibilityIncrementorRole
#define QAXLinkedUIElementsAttribute NSAccessibilityLinkedUIElementsAttribute
#define QAXListRole NSAccessibilityListRole
#define QAXMainAttribute NSAccessibilityMainAttribute
#define QAXMaxValueAttribute NSAccessibilityMaxValueAttribute
#define QAXMenuBarRole NSAccessibilityMenuBarRole
#define QAXMenuButtonRole NSAccessibilityMenuButtonRole
#define QAXMenuClosedNotification NSAccessibilityMenuClosedNotification
#define QAXMenuItemRole NSAccessibilityMenuItemRole
#define QAXMenuOpenedNotification NSAccessibilityMenuOpenedNotification
#define QAXMenuRole NSAccessibilityMenuRole
#define QAXMinValueAttribute NSAccessibilityMinValueAttribute
#define QAXMinimizeButtonAttribute NSAccessibilityMinimizeButtonAttribute
#define QAXMinimizedAttribute NSAccessibilityMinimizedAttribute
#define QAXNextContentsAttribute NSAccessibilityNextContentsAttribute
#define QAXOrientationAttribute NSAccessibilityOrientationAttribute
#define QAXParentAttribute NSAccessibilityParentAttribute
#define QAXPickAction NSAccessibilityPickAction
#define QAXPopUpButtonRole NSAccessibilityPopUpButtonRole
#define QAXPositionAttribute NSAccessibilityPositionAttribute
#define QAXPressAction NSAccessibilityPressAction
#define QAXPreviousContentsAttribute NSAccessibilityPreviousContentsAttribute
#define QAXProgressIndicatorRole NSAccessibilityProgressIndicatorRole
#define QAXRadioButtonRole NSAccessibilityRadioButtonRole
#define QAXRoleAttribute NSAccessibilityRoleAttribute
#define QAXRoleDescriptionAttribute NSAccessibilityRoleDescriptionAttribute
#define QAXRowRole NSAccessibilityRowRole
#define QAXRowsAttribute NSAccessibilityRowsAttribute
#define QAXScrollAreaRole NSAccessibilityScrollAreaRole
#define QAXScrollBarRole NSAccessibilityScrollBarRole
#define QAXSelectedAttribute NSAccessibilitySelectedAttribute
#define QAXSelectedChildrenAttribute NSAccessibilitySelectedChildrenAttribute
#define QAXSelectedRowsAttribute NSAccessibilitySelectedRowsAttribute
#define QAXSizeAttribute NSAccessibilitySizeAttribute
#define QAXSliderRole NSAccessibilitySliderRole
#define QAXSplitGroupRole NSAccessibilitySplitGroupRole
#define QAXSplitterRole NSAccessibilitySplitterRole
#define QAXSplittersAttribute NSAccessibilitySplittersAttribute
#define QAXStaticTextRole NSAccessibilityStaticTextRole
#define QAXSubroleAttribute NSAccessibilitySubroleAttribute
#define QAXSubroleAttribute NSAccessibilitySubroleAttribute
#define QAXTabGroupRole NSAccessibilityTabGroupRole
#define QAXTableRole NSAccessibilityTableRole
#define QAXTabsAttribute NSAccessibilityTabsAttribute
#define QAXTextFieldRole NSAccessibilityTextFieldRole
#define QAXTitleAttribute NSAccessibilityTitleAttribute
#define QAXTitleUIElementAttribute NSAccessibilityTitleUIElementAttribute
#define QAXToolbarButtonAttribute NSAccessibilityToolbarButtonAttribute
#define QAXToolbarRole NSAccessibilityToolbarRole
#define QAXTopLevelUIElementAttribute NSAccessibilityTopLevelUIElementAttribute
#define QAXUnknownRole NSAccessibilityUnknownRole
#define QAXValueAttribute NSAccessibilityValueAttribute
#define QAXValueChangedNotification NSAccessibilityValueChangedNotification
#define QAXValueIndicatorRole NSAccessibilityValueIndicatorRole
#define QAXVerticalOrientationValue NSAccessibilityVerticalOrientationValue
#define QAXVerticalScrollBarAttribute NSAccessibilityVerticalScrollBarAttribute
#define QAXVisibleRowsAttribute NSAccessibilityVisibleRowsAttribute
#define QAXWindowAttribute NSAccessibilityWindowAttribute
#define QAXWindowCreatedNotification NSAccessibilityWindowCreatedNotification
#define QAXWindowMovedNotification NSAccessibilityWindowMovedNotification
#define QAXWindowRole NSAccessibilityWindowRole
#define QAXZoomButtonAttribute NSAccessibilityZoomButtonAttribute
#else
typedef CFStringRef const QAXRoleType;
#define QAXApplicationRole kAXApplicationRole
#define QAXButtonRole kAXButtonRole
#define QAXCancelAction kAXCancelAction
#define QAXCheckBoxRole kAXCheckBoxRole
#define QAXChildrenAttribute kAXChildrenAttribute
#define QAXCloseButtonAttribute kAXCloseButtonAttribute
#define QAXColumnRole kAXColumnRole
#define QAXConfirmAction kAXConfirmAction
#define QAXContentsAttribute kAXContentsAttribute
#define QAXDecrementAction kAXDecrementAction
#define QAXDecrementArrowSubrole kAXDecrementArrowSubrole
#define QAXDecrementPageSubrole kAXDecrementPageSubrole
#define QAXDescriptionAttribute kAXDescriptionAttribute
#define QAXEnabledAttribute kAXEnabledAttribute
#define QAXExpandedAttribute kAXExpandedAttribute
#define QAXFocusedAttribute kAXFocusedAttribute
#define QAXFocusedUIElementChangedNotification kAXFocusedUIElementChangedNotification
#define QAXFocusedWindowChangedNotification kAXFocusedWindowChangedNotification
#define QAXGroupRole kAXGroupRole
#define QAXGrowAreaAttribute kAXGrowAreaAttribute
#define QAXGrowAreaRole kAXGrowAreaRole
#define QAXHelpAttribute kAXHelpAttribute
#define QAXHorizontalOrientationValue kAXHorizontalOrientationValue
#define QAXHorizontalScrollBarAttribute kAXHorizontalScrollBarAttribute
#define QAXIncrementAction kAXIncrementAction
#define QAXIncrementArrowSubrole kAXIncrementArrowSubrole
#define QAXIncrementPageSubrole kAXIncrementPageSubrole
#define QAXIncrementorRole kAXIncrementorRole
#define QAXLinkedUIElementsAttribute kAXLinkedUIElementsAttribute
#define QAXListRole kAXListRole
#define QAXMainAttribute kAXMainAttribute
#define QAXMaxValueAttribute kAXMaxValueAttribute
#define QAXMenuBarRole kAXMenuBarRole
#define QAXMenuButtonRole kAXMenuButtonRole
#define QAXMenuClosedNotification kAXMenuClosedNotification
#define QAXMenuItemRole kAXMenuItemRole
#define QAXMenuOpenedNotification kAXMenuOpenedNotification
#define QAXMenuRole kAXMenuRole
#define QAXMinValueAttribute kAXMinValueAttribute
#define QAXMinimizeButtonAttribute kAXMinimizeButtonAttribute
#define QAXMinimizedAttribute kAXMinimizedAttribute
#define QAXNextContentsAttribute kAXNextContentsAttribute
#define QAXOrientationAttribute kAXOrientationAttribute
#define QAXParentAttribute kAXParentAttribute
#define QAXPickAction kAXPickAction
#define QAXPopUpButtonRole kAXPopUpButtonRole
#define QAXPositionAttribute kAXPositionAttribute
#define QAXPressAction kAXPressAction
#define QAXPreviousContentsAttribute kAXPreviousContentsAttribute
#define QAXProgressIndicatorRole kAXProgressIndicatorRole
#define QAXRadioButtonRole kAXRadioButtonRole
#define QAXRoleAttribute kAXRoleAttribute
#define QAXRoleDescriptionAttribute kAXRoleDescriptionAttribute
#define QAXRowRole kAXRowRole
#define QAXRowsAttribute kAXRowsAttribute
#define QAXScrollAreaRole kAXScrollAreaRole
#define QAXScrollBarRole kAXScrollBarRole
#define QAXSelectedAttribute kAXSelectedAttribute
#define QAXSelectedChildrenAttribute kAXSelectedChildrenAttribute
#define QAXSelectedRowsAttribute kAXSelectedRowsAttribute
#define QAXSizeAttribute kAXSizeAttribute
#define QAXSliderRole kAXSliderRole
#define QAXSplitGroupRole kAXSplitGroupRole
#define QAXSplitterRole kAXSplitterRole
#define QAXSplittersAttribute kAXSplittersAttribute
#define QAXStaticTextRole kAXStaticTextRole
#define QAXSubroleAttribute kAXSubroleAttribute
#define QAXTabGroupRole kAXTabGroupRole
#define QAXTableRole kAXTableRole
#define QAXTabsAttribute kAXTabsAttribute
#define QAXTextFieldRole kAXTextFieldRole
#define QAXTitleAttribute kAXTitleAttribute
#define QAXTitleUIElementAttribute kAXTitleUIElementAttribute
#define QAXToolbarButtonAttribute kAXToolbarButtonAttribute
#define QAXToolbarRole kAXToolbarRole
#define QAXTopLevelUIElementAttribute kAXTopLevelUIElementAttribute
#define QAXUnknownRole kAXUnknownRole
#define QAXValueAttribute kAXValueAttribute
#define QAXValueChangedNotification kAXValueChangedNotification
#define QAXValueIndicatorRole kAXValueIndicatorRole
#define QAXVerticalOrientationValue kAXVerticalOrientationValue
#define QAXVerticalScrollBarAttribute kAXVerticalScrollBarAttribute
#define QAXVisibleRowsAttribute kAXVisibleRowsAttribute
#define QAXWindowAttribute kAXWindowAttribute
#define QAXWindowCreatedNotification kAXWindowCreatedNotification
#define QAXWindowMovedNotification kAXWindowMovedNotification
#define QAXWindowRole kAXWindowRole
#define QAXZoomButtonAttribute kAXZoomButtonAttribute
#endif


/*****************************************************************************
  Externals
 *****************************************************************************/
extern bool qt_mac_is_macsheet(const QWidget *w); //qwidget_mac.cpp
extern bool qt_mac_is_macdrawer(const QWidget *w); //qwidget_mac.cpp

/*****************************************************************************
  QAccessible Bindings
 *****************************************************************************/
//hardcoded bindings between control info and (known) QWidgets
struct QAccessibleTextBinding {
    int qt;
    QAXRoleType mac;
    bool settable;
} text_bindings[][10] = {
    { { QAccessible::MenuItem, QAXMenuItemRole, false },
      { -1, 0, false }
    },
    { { QAccessible::MenuBar, QAXMenuBarRole, false },
      { -1, 0, false }
    },
    { { QAccessible::ScrollBar, QAXScrollBarRole, false },
      { -1, 0, false }
    },
    { { QAccessible::Grip, QAXGrowAreaRole, false },
      { -1, 0, false }
    },
    { { QAccessible::Window, QAXWindowRole, false },
      { -1, 0, false }
    },
    { { QAccessible::Dialog, QAXWindowRole, false },
      { -1, 0, false }
    },
    { { QAccessible::AlertMessage, QAXWindowRole, false },
      { -1, 0, false }
    },
    { { QAccessible::ToolTip, QAXWindowRole, false },
      { -1, 0, false }
    },
    { { QAccessible::HelpBalloon, QAXWindowRole, false },
      { -1, 0, false }
    },
    { { QAccessible::PopupMenu, QAXMenuRole, false },
      { -1, 0, false }
    },
    { { QAccessible::Application, QAXApplicationRole, false },
      { -1, 0, false }
    },
    { { QAccessible::Pane, QAXGroupRole, false },
      { -1, 0, false }
    },
    { { QAccessible::Grouping, QAXGroupRole, false },
      { -1, 0, false }
    },
    { { QAccessible::Separator, QAXSplitterRole, false },
      { -1, 0, false }
    },
    { { QAccessible::ToolBar, QAXToolbarRole, false },
      { -1, 0, false }
    },
    { { QAccessible::PageTab, QAXRadioButtonRole, false },
      { -1, 0, false }
    },
    { { QAccessible::ButtonMenu, QAXMenuButtonRole, false },
      { -1, 0, false }
    },
    { { QAccessible::ButtonDropDown, QAXPopUpButtonRole, false },
      { -1, 0, false }
    },
    { { QAccessible::SpinBox, QAXIncrementorRole, false },
      { -1, 0, false }
    },
    { { QAccessible::Slider, QAXSliderRole, false },
      { -1, 0, false }
    },
    { { QAccessible::ProgressBar, QAXProgressIndicatorRole, false },
      { -1, 0, false }
    },
    { { QAccessible::ComboBox, QAXPopUpButtonRole, false },
      { -1, 0, false }
    },
    { { QAccessible::RadioButton, QAXRadioButtonRole, false },
      { -1, 0, false }
    },
    { { QAccessible::CheckBox, QAXCheckBoxRole, false },
      { -1, 0, false }
    },
    { { QAccessible::StaticText, QAXStaticTextRole, false },
      { QAccessible::Name, QAXValueAttribute, false },
      { -1, 0, false }
    },
    { { QAccessible::Table, QAXTableRole, false },
      { -1, 0, false }
    },
    { { QAccessible::StatusBar, QAXStaticTextRole, false },
      { -1, 0, false }
    },
    { { QAccessible::Column, QAXColumnRole, false },
      { -1, 0, false }
    },
    { { QAccessible::ColumnHeader, QAXColumnRole, false },
      { -1, 0, false }
    },
    { { QAccessible::Row, QAXRowRole, false },
      { -1, 0, false }
    },
    { { QAccessible::RowHeader, QAXRowRole, false },
      { -1, 0, false }
    },
    { { QAccessible::Cell, QAXTextFieldRole, false },
      { -1, 0, false }
    },
    { { QAccessible::PushButton, QAXButtonRole, false },
      { -1, 0, false }
    },
    { { QAccessible::EditableText, QAXTextFieldRole, true },
      { -1, 0, false }
    },
    { { QAccessible::Link, QAXTextFieldRole, false },
      { -1, 0, false }
    },
    { { QAccessible::Indicator, QAXValueIndicatorRole, false },
      { -1, 0, false }
    },
    { { QAccessible::Splitter, QAXSplitGroupRole, false },
      { -1, 0, false }
    },
    { { QAccessible::List, QAXListRole, false },
      { -1, 0, false }
    },
    { { QAccessible::ListItem, QAXStaticTextRole, false },
      { -1, 0, false }
    },
    { { QAccessible::Cell, QAXStaticTextRole, false },
      { -1, 0, false }
    },
    { { -1, 0, false } }
};

class QAInterface;
static CFStringRef macRole(const QAInterface &interface);

QDebug operator<<(QDebug debug, const QAInterface &interface)
{
    if (interface.isValid() == false)
        debug << "invalid interface";
    else 
        debug << interface.object() << "id" << interface.id() << "role" << hex << interface.role();
    return debug;
}

// The root of the Qt accessible hiearchy.
static QObject *rootObject = 0;


bool QAInterface::operator==(const QAInterface &other) const
{
    if (isValid() == false || other.isValid() == false)
        return (isValid() && other.isValid());
    
    // walk up the parent chain, comparing child indexes, until we reach
    // an interface that has a QObject.
    QAInterface currentThis = *this;
    QAInterface currentOther = other;
    
    while (currentThis.object() == 0) {
        if (currentOther.object() != 0)
            return false;

        // fail if the child indexes in the two hirearchies don't match.
        if (currentThis.parent().indexOfChild(currentThis) !=
            currentOther.parent().indexOfChild(currentOther))
            return false;

        currentThis = currentThis.parent();
        currentOther = currentOther.parent();
    }
    
    return (currentThis.object() == currentOther.object() && currentThis.id() == currentOther.id());
}

bool QAInterface::operator!=(const QAInterface &other) const
{
    return !operator==(other);
}

uint qHash(const QAInterface &item)
{
    if (item.isValid())
        return qHash(item.object()) + qHash(item.id());
    else
        return qHash(item.cachedObject()) + qHash(item.id());
}

QAInterface QAInterface::navigate(RelationFlag relation, int entry) const
{
        if (!checkValid())
            return QAInterface();

    // On a QAccessibleInterface that handles its own children we can short-circut
    // the navigation if this QAInterface refers to one of the children:
    if (child != 0) {
        // The Ancestor interface will always be the same QAccessibleInterface with
        // a child value of 0.
        if (relation == QAccessible::Ancestor)
            return QAInterface(*this, 0);

        // The child hiearchy is only one level deep, so navigating to a child
        // of a child is not possible.
        if (relation == QAccessible::Child) {
            return QAInterface();
        }
    }
    QAccessibleInterface *child_iface = 0;

    const int status = base.interface->navigate(relation, entry, &child_iface);

    if (status == -1)
        return QAInterface(); // not found;

    // Check if target is a child of this interface.
    if (!child_iface) {
        return QAInterface(*this, status);
    } else {
        // Target is child_iface or a child of that (status decides).
        return QAInterface(child_iface, status);
    }
}

QAElement::QAElement()
:elementRef(0)
{}

QAElement::QAElement(AXUIElementRef elementRef)
:elementRef(elementRef)
{
    if (elementRef != 0) {
        CFRetain(elementRef);
        CFRetain(object());
    }
}

QAElement::QAElement(const QAElement &element)
:elementRef(element.elementRef)
{
    if (elementRef != 0) {
        CFRetain(elementRef);
        CFRetain(object());
    }
}

QAElement::QAElement(HIObjectRef object, int child)
{
#ifndef QT_MAC_USE_COCOA
    if (object == 0) {
        elementRef = 0; // Create invalid QAElement.
    } else {
        elementRef = AXUIElementCreateWithHIObjectAndIdentifier(object, child);
        CFRetain(object);
    }
#else
    Q_UNUSED(object);
    Q_UNUSED(child);
#endif
}

QAElement::~QAElement()
{
    if (elementRef != 0) {
        CFRelease(object());
        CFRelease(elementRef);
    }
}

void QAElement::operator=(const QAElement &other)
{
    if (*this == other)
        return;

    if (elementRef != 0) {
        CFRelease(object());
        CFRelease(elementRef);
    }

    elementRef = other.elementRef;

    if (elementRef != 0) {
        CFRetain(elementRef);
        CFRetain(object());
    }
}

bool QAElement::operator==(const QAElement &other) const
{
    if (elementRef == 0 || other.elementRef == 0)
        return (elementRef == other.elementRef);

    return CFEqual(elementRef, other.elementRef);
}

uint qHash(QAElement element)
{
    return qHash(element.object()) + qHash(element.id());
}

#ifndef QT_MAC_USE_COCOA
static QInterfaceFactory *createFactory(const QAInterface &interface);
#endif
Q_GLOBAL_STATIC(QAccessibleHierarchyManager, accessibleHierarchyManager);

/*
    Reomves all accessibility info accosiated with the sender object.
*/
void QAccessibleHierarchyManager::objectDestroyed(QObject *object)
{
    HIObjectRef hiObject = qobjectHiobjectHash.value(object);
    delete qobjectElementHash.value(object);
    qobjectElementHash.remove(object);
    hiobjectInterfaceHash.remove(hiObject);
}

/*
    Removes all stored items.
*/
void QAccessibleHierarchyManager::reset()
{
    qDeleteAll(qobjectElementHash);
    qobjectElementHash.clear();
    hiobjectInterfaceHash.clear();
    qobjectHiobjectHash.clear();
}

QAccessibleHierarchyManager *QAccessibleHierarchyManager::instance()
{
    return accessibleHierarchyManager();
}

#ifndef QT_MAC_USE_COCOA
static bool isItemView(const QAInterface &interface)
{
    QObject *object = interface.object();
    return (interface.role() == QAccessible::List || interface.role() == QAccessible::Table
            || (object && qobject_cast<QAbstractItemView *>(interface.object()))
            || (object && object->objectName() == QLatin1String("qt_scrollarea_viewport")
                && qobject_cast<QAbstractItemView *>(object->parent())));
}
#endif

static bool isTabWidget(const QAInterface &interface)
{
    if (QObject *object = interface.object())
        return (object->inherits("QTabWidget") && interface.id() == 0);
    return false;
}

static bool isStandaloneTabBar(const QAInterface &interface)
{
    QObject *object = interface.object();
    if (interface.role() == QAccessible::PageTabList && object)
        return (qobject_cast<QTabWidget *>(object->parent()) == 0);

    return false;
}

static bool isEmbeddedTabBar(const QAInterface &interface)
{
    QObject *object = interface.object();
    if (interface.role() == QAccessible::PageTabList && object)
        return (qobject_cast<QTabWidget *>(object->parent()));

    return false;
}

/*
    Decides if a QAInterface is interesting from an accessibility users point of view.
*/
bool isItInteresting(const QAInterface &interface)
{
    // Mac accessibility does not have an attribute that corresponds to the Invisible/Offscreen
    // state, so we disable the interface here.
    const QAccessible::State state = interface.state();
    if (state & QAccessible::Invisible ||
        state & QAccessible::Offscreen )
        return false;

    const QAccessible::Role role = interface.role();

    if (QObject * const object = interface.object()) {
        const QString className = QLatin1String(object->metaObject()->className());

        // VoiceOver focusing on tool tips can be confusing. The contents of the
        // tool tip is avalible through the description attribute anyway, so
        // we disable accessibility for tool tips.
        if (className == QLatin1String("QTipLabel"))
            return false;

        // Hide TabBars that has a QTabWidget parent (the tab widget handles the accessibility)
        if (isEmbeddedTabBar(interface))
            return false;

         // Hide docked dockwidgets. ### causes infinitie loop in the apple accessibility code.
     /*    if (QDockWidget *dockWidget = qobject_cast<QDockWidget *>(object)) {
            if (dockWidget->isFloating() == false)
                return false;        
         }
    */
    }

    // Client is a generic role returned by plain QWidgets or other
    // widgets that does not have separate QAccessible interface, such
    // as the TabWidget. Return false unless macRole gives the interface
    // a special role.
    if (role == QAccessible::Client && macRole(interface) == CFStringRef(QAXUnknownRole))
        return false;

    // Some roles are not interesting:
    if (role == QAccessible::Border ||    // QFrame
        role == QAccessible::Application || // We use the system-provided application element.
        role == QAccessible::MenuItem)      // The system also provides the menu items.
        return false;

    // It is probably better to access the toolbar buttons directly than having
    // to navigate through the toolbar.
    if (role == QAccessible::ToolBar)
        return false;

    return true;
}

QAElement QAccessibleHierarchyManager::registerInterface(QObject *object, int child)
{
#ifndef QT_MAC_USE_COCOA
    return registerInterface(QAInterface(QAccessible::queryAccessibleInterface(object), child));
#else
    Q_UNUSED(object);
    Q_UNUSED(child);
    return QAElement();
#endif
}

/*
    Creates a QAXUIelement that corresponds to the given QAInterface.
*/
QAElement QAccessibleHierarchyManager::registerInterface(const QAInterface &interface)
{
#ifndef QT_MAC_USE_COCOA
    if (interface.isValid() == false)
        return QAElement();
    QAInterface objectInterface = interface.objectInterface();

    QObject * qobject = objectInterface.object();
    HIObjectRef hiobject = objectInterface.hiObject();
    if (qobject == 0 || hiobject == 0)
        return QAElement();

    if (qobjectElementHash.contains(qobject) == false) {
        registerInterface(qobject, hiobject, createFactory(interface));
        HIObjectSetAccessibilityIgnored(hiobject, !isItInteresting(interface));
    }

    return QAElement(hiobject, interface.id());
#else
    Q_UNUSED(interface);
    return QAElement();
#endif
}

#ifndef QT_MAC_USE_COCOA
#include "qaccessible_mac_carbon.cpp"
#endif

void QAccessibleHierarchyManager::registerInterface(QObject * qobject, HIObjectRef hiobject, QInterfaceFactory *interfaceFactory)
{
#ifndef QT_MAC_USE_COCOA
    if (qobjectElementHash.contains(qobject) == false) {
        qobjectElementHash.insert(qobject, interfaceFactory);
        qobjectHiobjectHash.insert(qobject, hiobject);
        connect(qobject, SIGNAL(destroyed(QObject *)), SLOT(objectDestroyed(QObject *)));
    }

    if (hiobjectInterfaceHash.contains(hiobject) == false) {
        hiobjectInterfaceHash.insert(hiobject, interfaceFactory);
        installAcessibilityEventHandler(hiobject);
    }
#else
    Q_UNUSED(qobject);
    Q_UNUSED(hiobject);
    Q_UNUSED(interfaceFactory);
#endif
}

void QAccessibleHierarchyManager::registerChildren(const QAInterface &interface)
{
    QObject * const object = interface.object();
    if (object == 0)
        return;

    QInterfaceFactory *interfaceFactory = qobjectElementHash.value(object);
    
    if (interfaceFactory == 0)
        return;

    interfaceFactory->registerChildren();
}

QAInterface QAccessibleHierarchyManager::lookup(const AXUIElementRef &element)
{
     if (element == 0)
        return QAInterface();
#ifndef QT_MAC_USE_COCOA
    HIObjectRef hiObject = AXUIElementGetHIObject(element);

    QInterfaceFactory *factory = hiobjectInterfaceHash.value(hiObject);
    if (factory == 0) {
        return QAInterface();
    }

    UInt64 id;
    AXUIElementGetIdentifier(element, &id);
    return factory->interface(id);
#else
    return QAInterface();
#endif;
}

QAInterface QAccessibleHierarchyManager::lookup(const QAElement &element)
{
    return lookup(element.element());
}

QAElement QAccessibleHierarchyManager::lookup(const QAInterface &interface)
{
    if (interface.isValid() == false)
        return QAElement();

    QInterfaceFactory *factory = qobjectElementHash.value(interface.objectInterface().object());
    if (factory == 0)
        return QAElement();

    return factory->element(interface);
}

QAElement QAccessibleHierarchyManager::lookup(QObject * const object, int id)
{
    QInterfaceFactory *factory = qobjectElementHash.value(object);
    if (factory == 0)
        return QAElement();

    return factory->element(id);
}

/*
    Standard interface mapping, return the stored interface
    or HIObjectRef, and there is an one-to-one mapping between
    the identifier and child.
*/
class QStandardInterfaceFactory : public QInterfaceFactory
{
public:
    QStandardInterfaceFactory(const QAInterface &interface)
    : m_interface(interface), object(interface.hiObject())
    {
        CFRetain(object);
    }
    
    ~QStandardInterfaceFactory()
    {
         CFRelease(object);
    }

    
    QAInterface interface(UInt64 identifier)
    {
        const int child = identifier;
        return QAInterface(m_interface, child);
    }

    QAElement element(int id)
    {
        return QAElement(object, id);
    }

    QAElement element(const QAInterface &interface)
    {
        if (interface.object() == 0)
            return QAElement();
        return QAElement(object, interface.id());
    }

    void registerChildren()
    {
        const int childCount = m_interface.childCount();
        for (int i = 1; i <= childCount; ++i) {
            accessibleHierarchyManager()->registerInterface(m_interface.navigate(QAccessible::Child, i));
        }
    }

private:
    QAInterface m_interface;
    HIObjectRef object;
};

/*
    Interface mapping where that creates one HIObject for each interface child.
*/
class QMultipleHIObjectFactory : public QInterfaceFactory
{
public:
    QMultipleHIObjectFactory(const QAInterface &interface)
    : m_interface(interface)
    {  }
    
    ~QMultipleHIObjectFactory()
    {
        foreach (HIObjectRef object, objects) {
            CFRelease(object);
        }
    }

    QAInterface interface(UInt64 identifier)
    {
        const int child = identifier;
        return QAInterface(m_interface, child);
    }

    QAElement element(int child)
    {
        if (child == 0)
            return QAElement(m_interface.hiObject(), 0);
        
        if (child > objects.count())
            return QAElement();

        return QAElement(objects.at(child - 1), child);
    }

    void registerChildren()
    {
#ifndef QT_MAC_USE_COCOA
        const int childCount = m_interface.childCount();
        for (int i = 1; i <= childCount; ++i) {
            HIObjectRef hiobject;
            HIObjectCreate(kObjectQtAccessibility, 0, &hiobject);
            objects.append(hiobject);
              accessibleHierarchyManager()->registerInterface(m_interface.object(), hiobject, this);
            HIObjectSetAccessibilityIgnored(hiobject, !isItInteresting(m_interface.navigate(QAccessible::Child, i)));
        }
#endif
    }

private:
    QAInterface m_interface;
    QList<HIObjectRef> objects;
};

class QItemViewInterfaceFactory : public QInterfaceFactory
{
public:
    QItemViewInterfaceFactory(const QAInterface &interface)
    : m_interface(interface), object(interface.hiObject())
    {
        CFRetain(object);
        columnCount = 0;
        if (QTableView * tableView = qobject_cast<QTableView *>(interface.parent().object())) {
            if (tableView->model())
                columnCount = tableView->model()->columnCount();
            if (tableView->verticalHeader())
                ++columnCount;
        }
    }
    
    ~QItemViewInterfaceFactory()
    {
        CFRelease(object);
    }

    QAInterface interface(UInt64 identifier)
    {
        if (identifier == 0)
            return m_interface;

        if (m_interface.role() == QAccessible::List)
            return m_interface.childAt(identifier);
        
        if (m_interface.role() == QAccessible::Table) {
            const int index = identifier;
            if (index == 0)
                return m_interface; // return the item view interface.
           
            const int rowIndex = (index - 1) / (columnCount + 1);
            const int cellIndex = (index - 1)  % (columnCount + 1);
/*
            qDebug() << "index" << index;
            qDebug() << "rowIndex" << rowIndex;
            qDebug() << "cellIndex" << cellIndex;
*/
            const QAInterface rowInterface = m_interface.childAt(rowIndex + 1);

            if ((cellIndex) == 0) // Is it a row?
                return rowInterface;
            else {
                return rowInterface.childAt(cellIndex);
            }
        }

        return QAInterface();
    }

    QAElement element(int id)
    {
        if (id != 0) {
            return QAElement();
        }
        return QAElement(object, 0);
    }

    QAElement element(const QAInterface &interface)
    {
        if (interface.object() && interface.object() == m_interface.object()) {
            return QAElement(object, 0);
        } else if (m_interface.role() == QAccessible::List) {
            if (interface.parent().object() && interface.parent().object() == m_interface.object())
                return QAElement(object, m_interface.indexOfChild(interface));
        } else if (m_interface.role() == QAccessible::Table) {
            QAInterface currentInterface = interface;
            int index = 0;

            while (currentInterface.isValid() && currentInterface.object() == 0) {
                const QAInterface parentInterface = currentInterface.parent();
/*
                qDebug() << "current index" << index;
                qDebug() << "current interface" << interface;

                qDebug() << "parent interface" << parentInterface;
                qDebug() << "grandparent interface" << parentInterface.parent();
                qDebug() << "childCount" << interface.childCount();
                qDebug() << "index of child" << parentInterface.indexOfChild(currentInterface);
*/
                index += ((parentInterface.indexOfChild(currentInterface) - 1) * (currentInterface.childCount() + 1)) + 1;
                currentInterface = parentInterface;
//                qDebug() << "new current interface" << currentInterface;
            }
            if (currentInterface.object() == m_interface.object())
                return QAElement(object, index);


        }
        return QAElement();
    }

    void registerChildren()
    {
        // Item view child interfraces don't have their own qobjects, so there is nothing to register here.
    }

private:
    QAInterface m_interface;
    HIObjectRef object;
    int columnCount; // for table views;
};

#ifndef QT_MAC_USE_COCOA
static bool managesChildren(const QAInterface &interface)
{
    return (interface.childCount() > 0 && interface.childAt(1).id() > 0);
}

static QInterfaceFactory *createFactory(const QAInterface &interface)
{
    if (isItemView(interface)) {
        return new QItemViewInterfaceFactory(interface);
    }  if (managesChildren(interface)) {
        return new QMultipleHIObjectFactory(interface);
    }

    return new QStandardInterfaceFactory(interface);
}
#endif

QList<QAElement> lookup(const QList<QAInterface> &interfaces)
{
    QList<QAElement> elements;
    foreach (const QAInterface &interface, interfaces)
        if (interface.isValid()) {
            const QAElement element = accessibleHierarchyManager()->lookup(interface);
            if (element.isValid())
                elements.append(element);
        }
    return elements;
}

// Debug output helpers:
/*
static QString nameForEventKind(UInt32 kind)
{
    switch(kind) {
        case kEventAccessibleGetChildAtPoint:       return QString("GetChildAtPoint");      break;
        case kEventAccessibleGetAllAttributeNames:  return QString("GetAllAttributeNames"); break;
        case kEventAccessibleGetNamedAttribute:     return QString("GetNamedAttribute");    break;
        case kEventAccessibleSetNamedAttribute:     return QString("SetNamedAttribute");    break;
        case kEventAccessibleGetAllActionNames:     return QString("GetAllActionNames");    break;
        case kEventAccessibleGetFocusedChild:       return QString("GetFocusedChild");      break;
        default:
            return QString("Unknown accessibility event type: %1").arg(kind);
        break;
    };
}
*/
#ifndef QT_MAC_USE_COCOA
static bool qt_mac_append_cf_uniq(CFMutableArrayRef array, CFTypeRef value)
{
    if (value == 0)
        return false; 

    CFRange range;
    range.location = 0;
    range.length = CFArrayGetCount(array);
    if(!CFArrayContainsValue(array, range, value)) {
        CFArrayAppendValue(array, value);
        return true;
    }
    return false;
}

static OSStatus setAttributeValue(EventRef event, const QList<QAElement> &elements)
{
    CFMutableArrayRef array = CFArrayCreateMutable(0, 0, &kCFTypeArrayCallBacks);
    foreach (const QAElement &element, elements) {
        if (element.isValid())
            CFArrayAppendValue(array, element.element());
    }

    const OSStatus err = SetEventParameter(event, kEventParamAccessibleAttributeValue, 
                                           typeCFTypeRef, sizeof(array), &array);
    CFRelease(array);
    return err;
}
#endif //QT_MAC_USE_COCOA

/*
    Gets the AccessibleObject parameter from an event.
*/
static inline AXUIElementRef getAccessibleObjectParameter(EventRef event)
{
    AXUIElementRef element;
    GetEventParameter(event, kEventParamAccessibleObject, typeCFTypeRef, 0,
                        sizeof(element), 0, &element);
    return element;
}

/*
    The application event handler makes sure that all top-level qt windows are registered
    before any accessibility events are handeled.
*/
#ifndef QT_MAC_USE_COCOA
static OSStatus applicationEventHandler(EventHandlerCallRef next_ref, EventRef event, void *)
{
    QAInterface rootInterface(QAccessible::queryAccessibleInterface(rootObject ? rootObject : qApp), 0);
    accessibleHierarchyManager()->registerChildren(rootInterface);

    return CallNextEventHandler(next_ref, event);
}

/*
    Returns the value for element by combining the QAccessibility::Checked and
    QAccessibility::Mixed flags into an int value that the Mac accessibilty
    system understands. This works for check boxes, radio buttons, and the like.
    The return values are:
    0: unchecked
    1: checked
    2: undecided
*/
static int buttonValue(QAInterface element)
{
    const QAccessible::State state = element.state();
    if (state & QAccessible::Mixed)
        return 2;
    else if(state & QAccessible::Checked)
        return 1;
    else
        return 0;
}

static QString getValue(const QAInterface &interface)
{
    const QAccessible::Role role = interface.role();
    if (role == QAccessible::RadioButton || role == QAccessible::CheckBox)
        return QString::number(buttonValue(interface));
    else
        return interface.text(QAccessible::Value);
}
#endif //QT_MAC_USE_COCOA

/*
    Translates a QAccessible::Role into a mac accessibility role.
*/
static CFStringRef macRole(const QAInterface &interface)
{
    const QAccessible::Role qtRole = interface.role();

//    qDebug() << "role for" << interface.object() << "interface role" << hex << qtRole;

    // Qt accessibility:  QAccessible::Splitter contains QAccessible::Grip.
    // Mac accessibility: AXSplitGroup contains AXSplitter.
    if (qtRole == QAccessible::Grip) {
        const QAInterface parent = interface.parent();
        if (parent.isValid() && parent.role() == QAccessible::Splitter)
            return CFStringRef(QAXSplitterRole);
    }

    // Tab widgets and standalone tab bars get the kAXTabGroupRole. Accessibility
    // for tab bars emebedded in a tab widget is handled by the tab widget.
    if (isTabWidget(interface) || isStandaloneTabBar(interface))
        return kAXTabGroupRole;

    if (QObject *object = interface.object()) {
        // ### The interface for an abstract scroll area returns the generic "Client"
        // role, so we have to to an extra detect on the QObject here.
        if (object->inherits("QAbstractScrollArea") && interface.id() == 0)
            return CFStringRef(QAXScrollAreaRole);

        if (object->inherits("QDockWidget"))
            return CFStringRef(QAXUnknownRole);
    }

    int i = 0;
    int testRole = text_bindings[i][0].qt;
    while (testRole != -1) {
        if (testRole == qtRole)
            return CFStringRef(text_bindings[i][0].mac);
        ++i;
        testRole = text_bindings[i][0].qt;
    }

//    qDebug() << "got unknown role!" << interface << interface.parent();

    return CFStringRef(QAXUnknownRole);
}

/*
    Translates a QAccessible::Role and an attribute name into a QAccessible::Text, taking into
    account execptions listed in text_bindings.
*/
#ifndef QT_MAC_USE_COCOA
static int textForRoleAndAttribute(QAccessible::Role role, CFStringRef attribute)
{
     // Search for exception, return it if found.
    int testRole = text_bindings[0][0].qt;
    int i = 0;
    while (testRole != -1) {
        if (testRole == role) {
            int j = 1;
            int qtRole = text_bindings[i][j].qt;
            CFStringRef testAttribute = CFStringRef(text_bindings[i][j].mac);
            while (qtRole != -1) {
                if (CFStringCompare(attribute, testAttribute, 0) == kCFCompareEqualTo) {
                    return (QAccessible::Text)qtRole;
                }
                ++j;
                testAttribute = CFStringRef(text_bindings[i][j].mac); /// ### custom compare
                qtRole = text_bindings[i][j].qt; /// ### custom compare
            }
            break;
        }
        ++i;
        testRole = text_bindings[i][0].qt;
    }

    // Return default mappping
    if (CFStringCompare(attribute, CFStringRef(QAXTitleAttribute), 0) == kCFCompareEqualTo)
        return QAccessible::Name;
    else if (CFStringCompare(attribute, CFStringRef(QAXValueAttribute), 0) == kCFCompareEqualTo)
        return QAccessible::Value;
    else if (CFStringCompare(attribute, CFStringRef(QAXHelpAttribute), 0) == kCFCompareEqualTo)
        return QAccessible::Help;
    else if (CFStringCompare(attribute, CFStringRef(QAXDescriptionAttribute), 0) == kCFCompareEqualTo)
        return QAccessible::Description;
    else
        return -1;
}

/*
    Returns the subrole string constant for the interface if it has one,
    else returns an empty string.
*/
static QCFString subrole(const QAInterface &interface)
{
    const QAInterface parent = interface.parent();
    if (parent.isValid() == false)
        return QCFString();

    if (parent.role() == QAccessible::ScrollBar) {
        QCFString subrole;
        switch(interface.id()) {
            case 1: subrole = CFStringRef(QAXDecrementArrowSubrole); break;
            case 2: subrole = CFStringRef(QAXDecrementPageSubrole); break;
            case 4: subrole = CFStringRef(QAXIncrementPageSubrole); break;
            case 5: subrole = CFStringRef(QAXIncrementArrowSubrole); break;
            default:
            break;
        }
        return subrole;
    }
    return QCFString();
}

// Gets the scroll bar orientation by asking the QAbstractSlider object directly.
static Qt::Orientation scrollBarOrientation(const QAInterface &scrollBar)
{
    QObject *const object = scrollBar.object();
    if (QAbstractSlider * const sliderObject = qobject_cast<QAbstractSlider * const>(object))
        return sliderObject->orientation();

    return Qt::Vertical; // D'oh! The interface wasn't a scroll bar.
}

static QAInterface scrollAreaGetScrollBarInterface(const QAInterface &scrollArea, Qt::Orientation orientation)
{
    if (macRole(scrollArea) != CFStringRef(CFStringRef(QAXScrollAreaRole)))
        return QAInterface();

    // Child 1 is the contents widget, 2 and 3 are the scroll bar containers wich contains possible scroll bars.
    for (int i = 2; i <= 3; ++i) {
        QAInterface scrollBarContainer = scrollArea.childAt(i);
        for (int i = 1; i <= scrollBarContainer.childCount(); ++i) {
            QAInterface scrollBar = scrollBarContainer.childAt(i);
            if (scrollBar.isValid() &&
                scrollBar.role() == QAccessible::ScrollBar &&
                scrollBarOrientation(scrollBar) == orientation)
                return scrollBar;
        }
    }

    return QAInterface();
}

static bool scrollAreaHasScrollBar(const QAInterface &scrollArea, Qt::Orientation orientation)
{
    return scrollAreaGetScrollBarInterface(scrollArea, orientation).isValid();
}

static QAElement scrollAreaGetScrollBar(const QAInterface &scrollArea, Qt::Orientation orientation)
{
    return accessibleHierarchyManager()->lookup(scrollAreaGetScrollBarInterface(scrollArea, orientation));
}

static QAElement scrollAreaGetContents(const QAInterface &scrollArea)
{
    // Child 1 is the contents widget,
    return accessibleHierarchyManager()->lookup(scrollArea.navigate(QAccessible::Child, 1));
}

static QAElement tabWidgetGetContents(const QAInterface &interface)
{
    // A kAXTabGroup has a kAXContents attribute, which consists of the
    // ui elements for the current tab page. Get the current tab page
    // from the QStackedWidget, where the current visible page can
    // be found at index 1.
    QAInterface stackedWidget = interface.childAt(1);
    accessibleHierarchyManager()->registerChildren(stackedWidget);
    QAInterface tabPageInterface = stackedWidget.childAt(1);
    return accessibleHierarchyManager()->lookup(tabPageInterface);
}

static QList<QAElement> tabBarGetTabs(const QAInterface &interface)
{
    // Get the tabs by searching for children with the "PageTab" role.
    // This filters out the left/right navigation buttons.
    accessibleHierarchyManager()->registerChildren(interface);
    QList<QAElement> tabs;
    const int numChildren = interface.childCount();
    for (int i = 1; i < numChildren + 1; ++i) {
        QAInterface child = interface.navigate(QAccessible::Child, i);
        if (child.isValid() && child.role() == QAccessible::PageTab) {
            tabs.append(accessibleHierarchyManager()->lookup(child));
        }
    }
    return tabs;
}

static QList<QAElement> tabWidgetGetTabs(const QAInterface &interface)
{
    // Each QTabWidget has two children, a QStackedWidget and a QTabBar.
    // Get the tabs from the QTabBar.
    return tabBarGetTabs(interface.childAt(2));
}

static QList<QAElement> tabWidgetGetChildren(const QAInterface &interface)
{
    // The children for a kAXTabGroup should consist of the tabs and the
    // contents of the current open tab page.
    QList<QAElement> children = tabWidgetGetTabs(interface);
    children += tabWidgetGetContents(interface);
    return children;
}
#endif //QT_MAC_USE_COCOA

/*
    Returns the label (buddy) interface for interface, or 0 if it has none.
*/
/*
static QAInterface findLabel(const QAInterface &interface)
{
    return interface.navigate(QAccessible::Label, 1);
}
*/
/*
    Returns a list of interfaces this interface labels, or an empty list if it doesn't label any.
*/
/*
static QList<QAInterface> findLabelled(const QAInterface &interface)
{
    QList<QAInterface> interfaceList;

    int count = 1;
    const QAInterface labelled = interface.navigate(QAccessible::Labelled, count);
    while (labelled.isValid()) {
        interfaceList.append(labelled);
        ++count;
    }
    return interfaceList;
}
*/
/*
    Tests if the given QAInterface has data for a mac attribute.
*/
#ifndef QT_MAC_USE_COCOA
static bool supportsAttribute(CFStringRef attribute, const QAInterface &interface)
{
    const int text = textForRoleAndAttribute(interface.role(), attribute);

    // Special case: Static texts don't have a title.
    if (interface.role() == QAccessible::StaticText && attribute == CFStringRef(QAXTitleAttribute))
        return false;

    // Return true if we the attribute matched a QAccessible::Role and we get text for that role from the interface.
    if (text != -1) {
        if (text == QAccessible::Value) // Special case for Value, see getValue()
            return !getValue(interface).isEmpty();
        else
            return !interface.text((QAccessible::Text)text).isEmpty();
    }

    if (CFStringCompare(attribute, CFStringRef(QAXChildrenAttribute),  0) == kCFCompareEqualTo) {
        if (interface.childCount() > 0)
            return true;
    }

    if (CFStringCompare(attribute, CFStringRef(QAXSubroleAttribute),  0) == kCFCompareEqualTo) {
        return (subrole(interface) != QCFString());
    }

    return false;
}

static void appendIfSupported(CFMutableArrayRef array, CFStringRef attribute, const QAInterface &interface)
{
    if (supportsAttribute(attribute, interface))
        qt_mac_append_cf_uniq(array, attribute);
}

/*
    Returns the names of the attributes the give QAInterface supports.
*/
static OSStatus getAllAttributeNames(EventRef event, const QAInterface &interface, EventHandlerCallRef next_ref)
{
    // Call system event handler.
    OSStatus err = CallNextEventHandler(next_ref, event);
    if(err != noErr && err != eventNotHandledErr)
        return err;
    CFMutableArrayRef attrs = 0;
    GetEventParameter(event, kEventParamAccessibleAttributeNames, typeCFMutableArrayRef, 0,
                      sizeof(attrs), 0, &attrs);

    if (!attrs)
        return eventNotHandledErr;

    // Append attribute names that are always supported.
    qt_mac_append_cf_uniq(attrs, CFStringRef(QAXPositionAttribute));
    qt_mac_append_cf_uniq(attrs, CFStringRef(QAXSizeAttribute));
    qt_mac_append_cf_uniq(attrs, CFStringRef(QAXRoleAttribute));
    qt_mac_append_cf_uniq(attrs, CFStringRef(QAXEnabledAttribute));
    qt_mac_append_cf_uniq(attrs, CFStringRef(QAXWindowAttribute));
    qt_mac_append_cf_uniq(attrs, CFStringRef(QAXTopLevelUIElementAttribute));

    // Append these names if the QInterafceItem returns any data for them.
    appendIfSupported(attrs, CFStringRef(QAXTitleAttribute), interface);
    appendIfSupported(attrs, CFStringRef(QAXValueAttribute), interface);
    appendIfSupported(attrs, CFStringRef(QAXDescriptionAttribute), interface);
    appendIfSupported(attrs, CFStringRef(QAXLinkedUIElementsAttribute), interface);
    appendIfSupported(attrs, CFStringRef(QAXHelpAttribute), interface);
    appendIfSupported(attrs, CFStringRef(QAXTitleUIElementAttribute), interface);
    appendIfSupported(attrs, CFStringRef(QAXChildrenAttribute), interface);
    appendIfSupported(attrs, CFStringRef(QAXSubroleAttribute), interface);

    // Append attribute names based on the interaface role.
    switch (interface.role())  {
        case QAccessible::Window:
            qt_mac_append_cf_uniq(attrs, CFStringRef(QAXMainAttribute));
            qt_mac_append_cf_uniq(attrs, CFStringRef(QAXMinimizedAttribute));
            qt_mac_append_cf_uniq(attrs, CFStringRef(QAXCloseButtonAttribute));
            qt_mac_append_cf_uniq(attrs, CFStringRef(QAXZoomButtonAttribute));
            qt_mac_append_cf_uniq(attrs, CFStringRef(QAXMinimizeButtonAttribute));
            qt_mac_append_cf_uniq(attrs, CFStringRef(QAXToolbarButtonAttribute));
            qt_mac_append_cf_uniq(attrs, CFStringRef(QAXGrowAreaAttribute));
        break;
        case QAccessible::RadioButton:
        case QAccessible::CheckBox:
            qt_mac_append_cf_uniq(attrs, CFStringRef(QAXMinValueAttribute));
            qt_mac_append_cf_uniq(attrs, CFStringRef(QAXMaxValueAttribute));
        break;
        case QAccessible::ScrollBar:
            qt_mac_append_cf_uniq(attrs, CFStringRef(QAXOrientationAttribute));
        break;
        case QAccessible::Splitter:
            qt_mac_append_cf_uniq(attrs, CFStringRef(QAXSplittersAttribute));
        break;
        case QAccessible::Table:
            qt_mac_append_cf_uniq(attrs, CFStringRef(QAXRowsAttribute));
            qt_mac_append_cf_uniq(attrs, CFStringRef(QAXVisibleRowsAttribute));
            qt_mac_append_cf_uniq(attrs, CFStringRef(QAXSelectedRowsAttribute));
        break;
        default:
        break;
    }

    // Append attribute names based on the mac accessibility role.
    const QCFString mac_role = macRole(interface);
    if (mac_role == CFStringRef(QAXSplitterRole)) {
        qt_mac_append_cf_uniq(attrs, CFStringRef(QAXPreviousContentsAttribute));
        qt_mac_append_cf_uniq(attrs, CFStringRef(QAXNextContentsAttribute));
        qt_mac_append_cf_uniq(attrs, CFStringRef(QAXOrientationAttribute));
    } else if (mac_role == CFStringRef(QAXScrollAreaRole)) {
        if (scrollAreaHasScrollBar(interface, Qt::Horizontal))
            qt_mac_append_cf_uniq(attrs, CFStringRef(QAXHorizontalScrollBarAttribute));
        if (scrollAreaHasScrollBar(interface, Qt::Vertical))
            qt_mac_append_cf_uniq(attrs, CFStringRef(QAXVerticalScrollBarAttribute));
        qt_mac_append_cf_uniq(attrs, CFStringRef(QAXContentsAttribute));
    } else if (mac_role == CFStringRef(QAXTabGroupRole)) {
        qt_mac_append_cf_uniq(attrs, CFStringRef(QAXTabsAttribute));
        // Only tab widgets can have the contents attribute, there is no way of getting
        // the contents from a QTabBar.
        if (isTabWidget(interface)) 
            qt_mac_append_cf_uniq(attrs, CFStringRef(QAXContentsAttribute));
    }

    return noErr;
}

static void handleStringAttribute(EventRef event, QAccessible::Text text, const QAInterface &interface)
{
    QString str = interface.text(text);
    if (str.isEmpty())
        return;

    // Remove any html markup from the text string, or VoiceOver will read the html tags.
    static QTextDocument document;
    document.setHtml(str);
    str = document.toPlainText();

    CFStringRef cfstr = QCFString::toCFStringRef(str);
    SetEventParameter(event, kEventParamAccessibleAttributeValue, typeCFStringRef, sizeof(cfstr), &cfstr);
}

/*
    Handles the parent attribute for a interface.
    There are basically three cases here:
    1. interface is a HIView and has only HIView children.
    2. interface is a HIView but has children that is not a HIView
    3. interface is not a HIView.
*/
static OSStatus handleChildrenAttribute(EventHandlerCallRef next_ref, EventRef event, QAInterface &interface)
{
   // Add the children for this interface to the global QAccessibelHierachyManager.
    accessibleHierarchyManager()->registerChildren(interface);

    if (isTabWidget(interface)) {
        QList<QAElement> children = tabWidgetGetChildren(interface);
        const int childCount = children.count();

        CFMutableArrayRef array = 0;
        array = CFArrayCreateMutable(0, 0, &kCFTypeArrayCallBacks);
        for (int i = 0; i < childCount; ++i)  {
            qt_mac_append_cf_uniq(array, children.at(i).element());
        }

        OSStatus err;
        err = SetEventParameter(event, kEventParamAccessibleAttributeValue, typeCFArrayRef, sizeof(array), &array);
        if (err != noErr)
            qWarning("Qt:Internal error (%s:%d)", __FILE__, __LINE__);

        return noErr;
    }

    const QList<QAElement> children = lookup(interface.children());
    const int childCount = children.count();

    OSStatus err = eventNotHandledErr;
    if (interface.isHIView())
        err = CallNextEventHandler(next_ref, event);

    CFMutableArrayRef array = 0;
    int arraySize = 0;
    if (err == noErr) {
        CFTypeRef obj = 0;
        err = GetEventParameter(event, kEventParamAccessibleAttributeValue, typeCFTypeRef, NULL , sizeof(obj), NULL, &obj);
        if (err == noErr && obj != 0) {
            array = (CFMutableArrayRef)obj;
            arraySize = CFArrayGetCount(array);
        }
    }

    if (array) {
        CFArrayRemoveAllValues(array);
        for (int i = 0; i < childCount; ++i)  {
            qt_mac_append_cf_uniq(array, children.at(i).element());
        }
    } else {
        array = CFArrayCreateMutable(0, 0, &kCFTypeArrayCallBacks);
        for (int i = 0; i < childCount; ++i)  {
            qt_mac_append_cf_uniq(array, children.at(i).element());
        }

        err = SetEventParameter(event, kEventParamAccessibleAttributeValue, typeCFArrayRef, sizeof(array), &array);
        if (err != noErr)
            qWarning("Qt:Internal error (%s:%d)", __FILE__, __LINE__);
    }

    return noErr;
}

/*

*/
static OSStatus handleParentAttribute(EventHandlerCallRef next_ref, EventRef event, const QAInterface &interface)
{
    OSStatus err = eventNotHandledErr;
    if (interface.isHIView()) {
         err = CallNextEventHandler(next_ref, event);
    }
    if (err == noErr)
        return err;

    const QAInterface parentInterface  = interface.navigate(QAccessible::Ancestor, 1);
    const QAElement parentElement = accessibleHierarchyManager()->lookup(parentInterface);

    if (parentElement.isValid() == false)
        return eventNotHandledErr;

    AXUIElementRef elementRef = parentElement.element();
    SetEventParameter(event, kEventParamAccessibleAttributeValue, typeCFTypeRef, sizeof(elementRef), &elementRef);
    return noErr;
}
#endif

struct IsWindowTest
{
    static inline bool test(const QAInterface &interface)
    {
        return (interface.role() == QAccessible::Window);
    }
};

struct IsWindowAndNotDrawerOrSheetTest
{
    static inline bool test(const QAInterface &interface)
    {
        QWidget * const widget = qobject_cast<QWidget*>(interface.object());
        return (interface.role() == QAccessible::Window &&
                widget && widget->isWindow() &&
                !qt_mac_is_macdrawer(widget) &&
                !qt_mac_is_macsheet(widget));
    }
};

/*
    Navigates up the iterfaces ancestor hierachy until a QAccessibleInterface that
    passes the Test is found. If we reach a interface that is a HIView we stop the
    search and call AXUIElementCopyAttributeValue.
*/
template <typename TestType>
OSStatus navigateAncestors(EventHandlerCallRef next_ref, EventRef event, const QAInterface &interface, CFStringRef attribute)
{
    if (interface.isHIView())
        return CallNextEventHandler(next_ref, event);

    QAInterface current = interface;
    QAElement element;
    while (current.isValid()) {
        if (TestType::test(interface)) {
            element = accessibleHierarchyManager()->lookup(current);
            break;
        }

        // If we reach an InterfaceItem that is a HiView we can hand of the search to
        // the system event handler. This is the common case.
        if (current.isHIView()) {
            CFTypeRef value = 0;
            const QAElement currentElement = accessibleHierarchyManager()->lookup(current);
            AXError err = AXUIElementCopyAttributeValue(currentElement.element(), attribute, &value);
            AXUIElementRef newElement = (AXUIElementRef)value;

            if (err == noErr)
                element = QAElement(newElement);

            if (newElement != 0)
                CFRelease(newElement);
            break;
        }

        QAInterface next = current.parent();
        if (next.isValid() == false)
            break;
        if (next == current)
            break;
        current = next;
    }

    if (element.isValid() == false)
        return eventNotHandledErr;


    AXUIElementRef elementRef = element.element();
    SetEventParameter(event, kEventParamAccessibleAttributeValue, typeCFTypeRef,
                                      sizeof(elementRef), &elementRef);
    return noErr;
}

/*
    Returns the top-level window for an interface, which is the closest ancestor interface that
    has the Window role, but is not a sheet or a drawer.
*/
#ifndef QT_MAC_USE_COCOA
static OSStatus handleWindowAttribute(EventHandlerCallRef next_ref, EventRef event, const QAInterface &interface)
{
    return navigateAncestors<IsWindowAndNotDrawerOrSheetTest>(next_ref, event, interface, CFStringRef(QAXWindowAttribute));
}

/*
    Returns the top-level window for an interface, which is the closest ancestor interface that
    has the Window role. (Can also be a sheet or a drawer)
*/
static OSStatus handleTopLevelUIElementAttribute(EventHandlerCallRef next_ref, EventRef event, const QAInterface &interface)
{
    return navigateAncestors<IsWindowTest>(next_ref, event, interface, CFStringRef(QAXTopLevelUIElementAttribute));
}

/*
    Returns the tab buttons for an interface.
*/
static OSStatus handleTabsAttribute(EventHandlerCallRef next_ref, EventRef event, QAInterface &interface)
{
    Q_UNUSED(next_ref);
    if (isTabWidget(interface))
        return setAttributeValue(event, tabWidgetGetTabs(interface));
    else
        return setAttributeValue(event, tabBarGetTabs(interface));
}

static OSStatus handlePositionAttribute(EventHandlerCallRef, EventRef event, const QAInterface &interface)
{
    QPoint qpoint(interface.rect().topLeft());
    HIPoint point;
    point.x = qpoint.x();
    point.y = qpoint.y();
    SetEventParameter(event, kEventParamAccessibleAttributeValue, typeHIPoint, sizeof(point), &point);
    return noErr;
}

static OSStatus handleSizeAttribute(EventHandlerCallRef, EventRef event, const QAInterface &interface)
{
    QSize qSize(interface.rect().size());
    HISize size;
    size.width = qSize.width();
    size.height = qSize.height();
    SetEventParameter(event, kEventParamAccessibleAttributeValue, typeHISize, sizeof(size), &size);
    return noErr;
}

static OSStatus handleSubroleAttribute(EventHandlerCallRef, EventRef event, const QAInterface &interface)
{
    const QCFString role = subrole(interface);
    CFStringRef rolestr = (CFStringRef)role;
    SetEventParameter(event, kEventParamAccessibleAttributeValue, typeCFTypeRef, sizeof(rolestr), &rolestr);
    return noErr;
}

static OSStatus handleOrientationAttribute(EventHandlerCallRef next_ref, EventRef event, const QAInterface &interface)
{
    QObject *const object = interface.object();
    Qt::Orientation orientation;
    if (interface.role() == QAccessible::ScrollBar) {
        orientation  = scrollBarOrientation(interface);
    } else if (QSplitterHandle * const splitter = qobject_cast<QSplitterHandle * const>(object)) {
        // Qt reports the layout orientation, but we want the splitter handle orientation.
        orientation = (splitter->orientation() == Qt::Horizontal) ? Qt::Vertical : Qt::Horizontal;
    } else {
        return CallNextEventHandler(next_ref, event);
    }
    const CFStringRef orientationString = (orientation == Qt::Vertical)
        ? CFStringRef(QAXVerticalOrientationValue) : CFStringRef(QAXHorizontalOrientationValue);
    SetEventParameter(event, kEventParamAccessibleAttributeValue, typeCFStringRef, sizeof(orientationString), &orientationString);
    return noErr;
}

/*
    Figures out the next or previous contents for a splitter.
*/
static OSStatus handleSplitterContentsAttribute(EventHandlerCallRef next_ref, EventRef event, const QAInterface &interface, QCFString nextOrPrev)
{
    if (interface.isValid() == false || interface.role() != QAccessible::Grip)
        return eventNotHandledErr;

    const QAInterface parent = interface.parent();
    if (parent.isValid() == false)
        return CallNextEventHandler(next_ref, event);

    if (parent.role() != QAccessible::Splitter)
        return CallNextEventHandler(next_ref, event);

    const QSplitter * const splitter = qobject_cast<const QSplitter * const>(parent.object());
    if (splitter == 0)
        return CallNextEventHandler(next_ref, event);

    QWidget * const splitterHandle = qobject_cast<QWidget * const>(interface.object());
    const int splitterHandleIndex = splitter->indexOf(splitterHandle);
    const int widgetIndex = (nextOrPrev == QCFString(CFStringRef(QAXPreviousContentsAttribute))) ? splitterHandleIndex - 1 : splitterHandleIndex;
    const QAElement contentsElement = accessibleHierarchyManager()->lookup(splitter->widget(widgetIndex), 0);
    return setAttributeValue(event, QList<QAElement>() << contentsElement);
}

/*
    Creates a list of all splitter handles the splitter contains.
*/
static OSStatus handleSplittersAttribute(EventHandlerCallRef next_ref, EventRef event, QAInterface &interface)
{
    const QSplitter * const splitter = qobject_cast<const QSplitter * const>(interface.object());
    if (splitter == 0)
        return CallNextEventHandler(next_ref, event);

    accessibleHierarchyManager()->registerChildren(interface);

    QList<QAElement> handles;
    const int visibleSplitterCount = splitter->count() -1; // skip first handle, it's always invisible.
    for (int i = 0; i < visibleSplitterCount; ++i)
        handles.append(accessibleHierarchyManager()->lookup(splitter->handle(i + 1), 0));

    return setAttributeValue(event, handles);
}

// This handler gets the scroll bars for a scroll area
static OSStatus handleScrollBarAttribute(EventHandlerCallRef next_ref, EventRef event, QAInterface &scrollArea, Qt::Orientation orientation)
{
    QAElement scrollBar = scrollAreaGetScrollBar(scrollArea, orientation);
    if (scrollBar.isValid() == false)
        return CallNextEventHandler(next_ref, event);

    AXUIElementRef elementRef = scrollBar.element();
    SetEventParameter(event, kEventParamAccessibleAttributeValue, typeCFTypeRef, sizeof(elementRef), &elementRef);
    return noErr;
}

// This handler gets the contents for a scroll area or tab widget.
static OSStatus handleContentsAttribute(EventHandlerCallRef next_ref, EventRef event, QAInterface &interface)
{
    const QCFString mac_role = macRole(interface);

    QAElement contents;

    if (mac_role == kAXTabGroupRole) {
        contents = tabWidgetGetContents(interface);
    } else {
        contents = scrollAreaGetContents(interface);
        if (contents.isValid() == false)
            return CallNextEventHandler(next_ref, event);
    }

    return setAttributeValue(event, QList<QAElement>() << contents);
}

static OSStatus handleRowsAttribute(EventHandlerCallRef, EventRef event, QAInterface &tableView)
{
    QList<QAElement> rows = lookup(tableView.children());

    // kill the first row which is the horizontal header.
    rows.removeAt(0);

    return setAttributeValue(event, rows);
}

static OSStatus handleVisibleRowsAttribute(EventHandlerCallRef, EventRef event, QAInterface &tableView)
{
    QList<QAElement> visibleRows;

    QList<QAInterface> rows = tableView.children();
    // kill the first row which is the horizontal header.
    rows.removeAt(0);

    foreach (const QAInterface &interface, rows)
        if ((interface.state() & QAccessible::Invisible) == false)
            visibleRows.append(accessibleHierarchyManager()->lookup(interface));

    return setAttributeValue(event, visibleRows);
}

static OSStatus handleSelectedRowsAttribute(EventHandlerCallRef, EventRef event, QAInterface &tableView)
{
    QList<QAElement> selectedRows;
    foreach (const QAInterface &interface, tableView.children())
        if ((interface.state() & QAccessible::Selected))
            selectedRows.append(accessibleHierarchyManager()->lookup(interface));

    return setAttributeValue(event, selectedRows);
}

static OSStatus getNamedAttribute(EventHandlerCallRef next_ref, EventRef event, QAInterface &interface)
{
    CFStringRef var;
    GetEventParameter(event, kEventParamAccessibleAttributeName, typeCFStringRef, 0,
                              sizeof(var), 0, &var);

    if (CFStringCompare(var, CFStringRef(QAXChildrenAttribute), 0) == kCFCompareEqualTo) {
        return handleChildrenAttribute(next_ref, event, interface);
    } else if(CFStringCompare(var, CFStringRef(QAXTopLevelUIElementAttribute), 0) == kCFCompareEqualTo) {
        return handleTopLevelUIElementAttribute(next_ref, event, interface);
    } else if(CFStringCompare(var, CFStringRef(QAXWindowAttribute), 0) == kCFCompareEqualTo) {
        return handleWindowAttribute(next_ref, event, interface);
    } else if(CFStringCompare(var, CFStringRef(QAXParentAttribute), 0) == kCFCompareEqualTo) {
        return handleParentAttribute(next_ref, event, interface);
    } else if (CFStringCompare(var, CFStringRef(QAXPositionAttribute), 0) == kCFCompareEqualTo) {
        return handlePositionAttribute(next_ref, event, interface);
    } else if (CFStringCompare(var, CFStringRef(QAXSizeAttribute), 0) == kCFCompareEqualTo) {
        return handleSizeAttribute(next_ref, event, interface);
    } else  if (CFStringCompare(var, CFStringRef(QAXRoleAttribute), 0) == kCFCompareEqualTo) {
        CFStringRef role = macRole(interface);
// ###
//        QWidget * const widget = qobject_cast<QWidget *>(interface.object());
//        if (role == CFStringRef(QAXUnknownRole) && widget && widget->isWindow())
//            role = CFStringRef(QAXWindowRole);

        SetEventParameter(event, kEventParamAccessibleAttributeValue, typeCFStringRef,
                          sizeof(role), &role);

    } else if (CFStringCompare(var, CFStringRef(QAXEnabledAttribute), 0) == kCFCompareEqualTo) {
        Boolean val =  !((interface.state() & QAccessible::Unavailable))
                     && !((interface.state() & QAccessible::Invisible));
        SetEventParameter(event, kEventParamAccessibleAttributeValue, typeBoolean,
                          sizeof(val), &val);
    } else if (CFStringCompare(var, CFStringRef(QAXExpandedAttribute), 0) == kCFCompareEqualTo) {
        Boolean val = (interface.state() & QAccessible::Expanded);
        SetEventParameter(event, kEventParamAccessibleAttributeValue, typeBoolean,
                          sizeof(val), &val);
    } else if (CFStringCompare(var, CFStringRef(QAXSelectedAttribute), 0) == kCFCompareEqualTo) {
        Boolean val = (interface.state() & QAccessible::Selection);
        SetEventParameter(event, kEventParamAccessibleAttributeValue, typeBoolean,
                          sizeof(val), &val);
    } else if (CFStringCompare(var, CFStringRef(QAXFocusedAttribute), 0) == kCFCompareEqualTo) {
        Boolean val = (interface.state() & QAccessible::Focus);
        SetEventParameter(event, kEventParamAccessibleAttributeValue, typeBoolean,
                          sizeof(val), &val);
    } else if (CFStringCompare(var, CFStringRef(QAXSelectedChildrenAttribute), 0) == kCFCompareEqualTo) {
        const int cc = interface.childCount();
        QList<QAElement> selected;
        for (int i = 1; i <= cc; ++i) {
            const QAInterface child_iface = interface.navigate(QAccessible::Child, i);
            if (child_iface.isValid() && child_iface.state() & QAccessible::Selected)
                selected.append(accessibleHierarchyManager()->lookup(child_iface));
        }

        return setAttributeValue(event, selected);

      } else if (CFStringCompare(var, CFStringRef(QAXCloseButtonAttribute), 0) == kCFCompareEqualTo) {
        if(interface.object() && interface.object()->isWidgetType()) {
            Boolean val = true; //do we want to add a WState for this?
            SetEventParameter(event, kEventParamAccessibleAttributeValue, typeBoolean,
                              sizeof(val), &val);
        }
    } else if (CFStringCompare(var, CFStringRef(QAXZoomButtonAttribute), 0) == kCFCompareEqualTo) {
        if(interface.object() && interface.object()->isWidgetType()) {
            QWidget *widget = (QWidget*)interface.object();
            Boolean val = (widget->windowFlags() & Qt::WindowMaximizeButtonHint);
            SetEventParameter(event, kEventParamAccessibleAttributeValue, typeBoolean,
                              sizeof(val), &val);
        }
    } else if (CFStringCompare(var, CFStringRef(QAXMinimizeButtonAttribute), 0) == kCFCompareEqualTo) {
        if(interface.object() && interface.object()->isWidgetType()) {
            QWidget *widget = (QWidget*)interface.object();
            Boolean val = (widget->windowFlags() & Qt::WindowMinimizeButtonHint);
            SetEventParameter(event, kEventParamAccessibleAttributeValue, typeBoolean,
                              sizeof(val), &val);
        }
    } else if (CFStringCompare(var, CFStringRef(QAXToolbarButtonAttribute), 0) == kCFCompareEqualTo) {
        if(interface.object() && interface.object()->isWidgetType()) {
            QWidget *widget = (QWidget*)interface.object();
            Boolean val = qobject_cast<QMainWindow *>(widget) != 0;
            SetEventParameter(event, kEventParamAccessibleAttributeValue, typeBoolean,
                              sizeof(val), &val);
        }
    } else if (CFStringCompare(var, CFStringRef(QAXGrowAreaAttribute), 0) == kCFCompareEqualTo) {
        if(interface.object() && interface.object()->isWidgetType()) {
            Boolean val = true; //do we want to add a WState for this?
            SetEventParameter(event, kEventParamAccessibleAttributeValue, typeBoolean,
                              sizeof(val), &val);
        }
    } else if (CFStringCompare(var, CFStringRef(QAXMinimizedAttribute), 0) == kCFCompareEqualTo) {
        if (interface.object() && interface.object()->isWidgetType()) {
            QWidget *widget = (QWidget*)interface.object();
            Boolean val = (widget->windowState() & Qt::WindowMinimized);
            SetEventParameter(event, kEventParamAccessibleAttributeValue, typeBoolean,
                              sizeof(val), &val);
        }
    } else if (CFStringCompare(var, CFStringRef(QAXSubroleAttribute), 0) == kCFCompareEqualTo) {
        return handleSubroleAttribute(next_ref, event, interface);
    } else if (CFStringCompare(var, CFStringRef(QAXRoleDescriptionAttribute), 0) == kCFCompareEqualTo) {
#if !defined(QT_MAC_USE_COCOA)
        if (HICopyAccessibilityRoleDescription) {
            const CFStringRef roleDescription = HICopyAccessibilityRoleDescription(macRole(interface), 0);
            SetEventParameter(event, kEventParamAccessibleAttributeValue, typeCFStringRef,
                          sizeof(roleDescription), &roleDescription);
        } else
#endif
        {
            // Just use Qt::Description on 10.3
            handleStringAttribute(event, QAccessible::Description, interface);
        }
    } else if (CFStringCompare(var, CFStringRef(QAXTitleAttribute), 0) == kCFCompareEqualTo) {
        const QAccessible::Role role = interface.role();
        const QAccessible::Text text = (QAccessible::Text)textForRoleAndAttribute(role, var);
        handleStringAttribute(event, text, interface);
    } else if (CFStringCompare(var, CFStringRef(QAXValueAttribute), 0) == kCFCompareEqualTo) {
        const QAccessible::Role role = interface.role();
        const QAccessible::Text text = (QAccessible::Text)textForRoleAndAttribute(role, var);
        if (role == QAccessible::CheckBox || role == QAccessible::RadioButton) {
            int value = buttonValue(interface);
            SetEventParameter(event, kEventParamAccessibleAttributeValue, typeUInt32, sizeof(value), &value);
        } else {
            handleStringAttribute(event, text, interface);
        }
    } else if (CFStringCompare(var, CFStringRef(QAXDescriptionAttribute), 0) == kCFCompareEqualTo) {
        const QAccessible::Role role = interface.role();
        const QAccessible::Text text = (QAccessible::Text)textForRoleAndAttribute(role, var);
        handleStringAttribute(event, text, interface);
    } else if (CFStringCompare(var, CFStringRef(QAXLinkedUIElementsAttribute), 0) == kCFCompareEqualTo) {
        return CallNextEventHandler(next_ref, event);
    } else if (CFStringCompare(var, CFStringRef(QAXHelpAttribute), 0) == kCFCompareEqualTo) {
        const QAccessible::Role role = interface.role();
        const QAccessible::Text text = (QAccessible::Text)textForRoleAndAttribute(role, var);
        handleStringAttribute(event, text, interface);
    } else if (CFStringCompare(var, kAXTitleUIElementAttribute, 0) == kCFCompareEqualTo) {
        return CallNextEventHandler(next_ref, event);
    } else if (CFStringCompare(var, CFStringRef(QAXTabsAttribute), 0) == kCFCompareEqualTo) {
        return handleTabsAttribute(next_ref, event, interface);
    } else if (CFStringCompare(var, CFStringRef(QAXMinValueAttribute), 0) == kCFCompareEqualTo) {
        // tabs we first go to the tab bar which is child #2.
        QAInterface tabBarInterface = interface.childAt(2);
        return handleTabsAttribute(next_ref, event, tabBarInterface);
    } else if (CFStringCompare(var, CFStringRef(QAXMinValueAttribute), 0) == kCFCompareEqualTo) {
        if (interface.role() == QAccessible::RadioButton || interface.role() == QAccessible::CheckBox) {
            uint value = 0;
            SetEventParameter(event, kEventParamAccessibleAttributeValue, typeUInt32, sizeof(value), &value);
        } else {
            return CallNextEventHandler(next_ref, event);
        }
    } else if (CFStringCompare(var, CFStringRef(QAXMaxValueAttribute), 0) == kCFCompareEqualTo) {
        if (interface.role() == QAccessible::RadioButton || interface.role() == QAccessible::CheckBox) {
            uint value = 2;
            SetEventParameter(event, kEventParamAccessibleAttributeValue, typeUInt32, sizeof(value), &value);
        } else {
            return CallNextEventHandler(next_ref, event);
        }
    } else if (CFStringCompare(var, CFStringRef(QAXOrientationAttribute), 0) == kCFCompareEqualTo) {
        return handleOrientationAttribute(next_ref, event, interface);
    } else if (CFStringCompare(var, CFStringRef(QAXPreviousContentsAttribute), 0) == kCFCompareEqualTo) {
        return handleSplitterContentsAttribute(next_ref, event, interface, CFStringRef(QAXPreviousContentsAttribute));
    } else if (CFStringCompare(var, CFStringRef(QAXNextContentsAttribute), 0) == kCFCompareEqualTo) {
        return handleSplitterContentsAttribute(next_ref, event, interface, CFStringRef(QAXNextContentsAttribute));
    } else if (CFStringCompare(var, CFStringRef(QAXSplittersAttribute), 0) == kCFCompareEqualTo) {
        return handleSplittersAttribute(next_ref, event, interface);
    } else if (CFStringCompare(var, CFStringRef(QAXHorizontalScrollBarAttribute), 0) == kCFCompareEqualTo) {
        return handleScrollBarAttribute(next_ref, event, interface, Qt::Horizontal);
    } else if (CFStringCompare(var, CFStringRef(QAXVerticalScrollBarAttribute), 0) == kCFCompareEqualTo) {
        return handleScrollBarAttribute(next_ref, event, interface, Qt::Vertical);
    } else if (CFStringCompare(var, CFStringRef(QAXContentsAttribute), 0) == kCFCompareEqualTo) {
        return handleContentsAttribute(next_ref, event, interface);
    } else if (CFStringCompare(var, CFStringRef(QAXRowsAttribute), 0) == kCFCompareEqualTo) {
        return handleRowsAttribute(next_ref, event, interface);
    } else if (CFStringCompare(var, CFStringRef(QAXVisibleRowsAttribute), 0) == kCFCompareEqualTo) {
        return handleVisibleRowsAttribute(next_ref, event, interface);
    } else if (CFStringCompare(var, CFStringRef(QAXSelectedRowsAttribute), 0) == kCFCompareEqualTo) {
        return handleSelectedRowsAttribute(next_ref, event, interface);
    } else {
        return CallNextEventHandler(next_ref, event);
    }
    return noErr;
}

static OSStatus isNamedAttributeSettable(EventRef event, const QAInterface &interface)
{
    CFStringRef var;
    GetEventParameter(event, kEventParamAccessibleAttributeName, typeCFStringRef, 0,
                      sizeof(var), 0, &var);
    Boolean settable = false;
    if (CFStringCompare(var, CFStringRef(QAXFocusedAttribute), 0) == kCFCompareEqualTo) {
        settable = true;
    } else {
        for (int r = 0; text_bindings[r][0].qt != -1; r++) {
            if(interface.role() == (QAccessible::Role)text_bindings[r][0].qt) {
                for (int a = 1; text_bindings[r][a].qt != -1; a++) {
                    if (CFStringCompare(var, CFStringRef(text_bindings[r][a].mac), 0) == kCFCompareEqualTo) {
                        settable = text_bindings[r][a].settable;
                        break;
                    }
                }
            }
        }
    }
    SetEventParameter(event, kEventParamAccessibleAttributeSettable, typeBoolean,
                      sizeof(settable), &settable);
    return noErr;
}

static OSStatus getChildAtPoint(EventHandlerCallRef next_ref, EventRef event, QAInterface &interface)
{
    Q_UNUSED(next_ref);
    if (interface.isValid() == false)
        return eventNotHandledErr;

    // Add the children for this interface to the global QAccessibelHierachyManager.
    accessibleHierarchyManager()->registerChildren(interface);

    Point where;
    GetEventParameter(event, kEventParamMouseLocation, typeQDPoint, 0, sizeof(where), 0, &where);
    const QAInterface childInterface = interface.childAt(where.h, where.v);

    if (childInterface.isValid() == false || childInterface == interface)
        return eventNotHandledErr;

    const QAElement element = accessibleHierarchyManager()->lookup(childInterface);
    if (element.isValid() == false)
        return eventNotHandledErr;

    AXUIElementRef elementRef = element.element();
    CFRetain(elementRef);
    SetEventParameter(event, kEventParamAccessibleChild, typeCFTypeRef,
                                  sizeof(elementRef), &elementRef);

    return noErr;
}

/*
    Returns a list of actions the given interface supports.
    Currently implemented by getting the interface role and deciding based on that.
*/
static QList<QAccessible::Action> supportedPredefinedActions(const QAInterface &interface)
{
    QList<QAccessible::Action> actions;
    switch (interface.role()) {
        default:
            // Most things can be pressed.
            actions.append(QAccessible::Press);
        break;
    }

    return actions;
}

/*
    Translates a predefined QAccessible::Action to a Mac action constant.
    Returns an empty string if the Qt Action has no mac equivalent.
*/
static QCFString translateAction(const QAccessible::Action action)
{
    switch (action) {
        case QAccessible::Press:
            return CFStringRef(QAXPressAction);
        break;
        case QAccessible::Increase:
            return CFStringRef(QAXIncrementAction);
        break;
        case QAccessible::Decrease:
            return CFStringRef(QAXDecrementAction);
        break;
        case QAccessible::Accept:
            return CFStringRef(QAXConfirmAction);
        break;
        case QAccessible::Select:
            return CFStringRef(QAXPickAction);
        break;
        case QAccessible::Cancel:
            return CFStringRef(QAXCancelAction);
        break;
        default:
            return QCFString();
        break;
    }
}

/*
    Translates between a Mac action constant and a QAccessible::Action.
    Returns QAccessible::Default action if there is no Qt predefined equivalent.
*/
static QAccessible::Action translateAction(const CFStringRef actionName)
{
    if(CFStringCompare(actionName, CFStringRef(QAXPressAction), 0) == kCFCompareEqualTo) {
        return QAccessible::Press;
    } else if(CFStringCompare(actionName, CFStringRef(QAXIncrementAction), 0) == kCFCompareEqualTo) {
        return QAccessible::Increase;
    } else if(CFStringCompare(actionName, CFStringRef(QAXDecrementAction), 0) == kCFCompareEqualTo) {
        return QAccessible::Decrease;
    } else if(CFStringCompare(actionName, CFStringRef(QAXConfirmAction), 0) == kCFCompareEqualTo) {
        return QAccessible::Accept;
    } else if(CFStringCompare(actionName, CFStringRef(QAXPickAction), 0) == kCFCompareEqualTo) {
        return QAccessible::Select;
    } else if(CFStringCompare(actionName, CFStringRef(QAXCancelAction), 0) == kCFCompareEqualTo) {
        return QAccessible::Cancel;
    } else {
        return QAccessible::DefaultAction;
    }
}
#endif // QT_MAC_USE_COCOA

/*
    Copies the translated names all supported actions for an interface into the kEventParamAccessibleActionNames
    event parameter.
*/
#ifndef QT_MAC_USE_COCOA
static OSStatus getAllActionNames(EventHandlerCallRef next_ref, EventRef event, const QAInterface &interface)
{
    Q_UNUSED(next_ref);

    CFMutableArrayRef actions = 0;
    GetEventParameter(event, kEventParamAccessibleActionNames, typeCFMutableArrayRef, 0,
                      sizeof(actions), 0, &actions);

    // Add supported predefined actions.
    const QList<QAccessible::Action> predefinedActions = supportedPredefinedActions(interface);
    for (int i = 0; i < predefinedActions.count(); ++i) {
        const QCFString action = translateAction(predefinedActions.at(i));
        if (action != QCFString())
            qt_mac_append_cf_uniq(actions, action);
    }

    // Add user actions
    const int actionCount = interface.userActionCount();
    for (int i = 0; i < actionCount; ++i) {
        const QString actionName = interface.actionText(i, QAccessible::Name);
        qt_mac_append_cf_uniq(actions, QCFString::toCFStringRef(actionName));
    }

    return noErr;
}
#endif

/*
    Handles the perforNamedAction event.
*/
#ifndef QT_MAC_USE_COCOA
static OSStatus performNamedAction(EventHandlerCallRef next_ref, EventRef event, const QAInterface& interface)
{
    Q_UNUSED(next_ref);

    CFStringRef act;
    GetEventParameter(event, kEventParamAccessibleActionName, typeCFStringRef, 0,
                      sizeof(act), 0, &act);

    const QAccessible::Action action = translateAction(act);

    // Perform built-in action
    if (action != QAccessible::DefaultAction) {
        interface.doAction(action, QVariantList());
        return noErr;
    }

    // Search for user-defined actions and perform it if found.
    const int actCount = interface.userActionCount();
    const QString qAct = QCFString::toQString(act);
    for(int i = 0; i < actCount; i++) {
        if(interface.actionText(i, QAccessible::Name) == qAct) {
            interface.doAction(i, QVariantList());
            break;
        }
    }
    return noErr;
}

static OSStatus setNamedAttribute(EventHandlerCallRef next_ref, EventRef event, const QAInterface &interface)
{
    Q_UNUSED(next_ref);
    Q_UNUSED(event);

    CFStringRef var;
    GetEventParameter(event, kEventParamAccessibleAttributeName, typeCFStringRef, 0,
                      sizeof(var), 0, &var);
    if(CFStringCompare(var, CFStringRef(QAXFocusedAttribute), 0) == kCFCompareEqualTo) {
        CFTypeRef val;
        if(GetEventParameter(event, kEventParamAccessibleAttributeValue, typeCFTypeRef, 0,
                             sizeof(val), 0, &val) == noErr) {
            if(CFGetTypeID(val) == CFBooleanGetTypeID() &&
               CFEqual(static_cast<CFBooleanRef>(val), kCFBooleanTrue)) {
                interface.doAction(QAccessible::SetFocus);
            }
        }
    } else {
        bool found = false;
        for(int r = 0; text_bindings[r][0].qt != -1; r++) {
            if(interface.role() == (QAccessible::Role)text_bindings[r][0].qt) {
                for(int a = 1; text_bindings[r][a].qt != -1; a++) {
                    if(CFStringCompare(var, CFStringRef(text_bindings[r][a].mac), 0) == kCFCompareEqualTo) {
                        if(!text_bindings[r][a].settable) {
                        } else {
                            CFTypeRef val;
                            if(GetEventParameter(event, kEventParamAccessibleAttributeValue, typeCFTypeRef, 0,
                                                 sizeof(val), 0, &val) == noErr) {
                                if(CFGetTypeID(val) == CFStringGetTypeID())
                                    interface.setText((QAccessible::Text)text_bindings[r][a].qt,
                                                   QCFString::toQString(static_cast<CFStringRef>(val)));

                            }
                        }
                        found = true;
                        break;
                    }
                }
                break;
            }
        }
    }
    return noErr;
}

/*
    This is the main accessibility event handler.
*/
static OSStatus accessibilityEventHandler(EventHandlerCallRef next_ref, EventRef event, void *data)
{
    Q_UNUSED(data)

    // Return if this event is not a AccessibleGetNamedAttribute event.
    const UInt32 eclass = GetEventClass(event);
    if (eclass != kEventClassAccessibility)
        return eventNotHandledErr;

    // Get the AXUIElementRef and QAInterface pointer
    AXUIElementRef element = 0;
    GetEventParameter(event, kEventParamAccessibleObject, typeCFTypeRef, 0, sizeof(element), 0, &element);
    QAInterface interface = accessibleHierarchyManager()->lookup(element);
    if (interface.isValid() == false)
        return eventNotHandledErr;

    const UInt32 ekind = GetEventKind(event);
    OSStatus status = noErr;
    switch (ekind) {
        case kEventAccessibleGetAllAttributeNames:
             status = getAllAttributeNames(event, interface, next_ref);
        break;
        case kEventAccessibleGetNamedAttribute:
             status = getNamedAttribute(next_ref, event, interface);
        break;
        case kEventAccessibleIsNamedAttributeSettable:
             status = isNamedAttributeSettable(event, interface);
        break;
        case kEventAccessibleGetChildAtPoint:
            status = getChildAtPoint(next_ref, event, interface);
        break;
        case kEventAccessibleGetAllActionNames:
            status = getAllActionNames(next_ref, event, interface);
        break;
        case kEventAccessibleGetFocusedChild:
            status = CallNextEventHandler(next_ref, event);
        break;
        case kEventAccessibleSetNamedAttribute:
            status = setNamedAttribute(next_ref, event, interface);
        break;
        case kEventAccessiblePerformNamedAction:
            status = performNamedAction(next_ref, event, interface);
        break;
        default:
            status = CallNextEventHandler(next_ref, event);
        break;
    };
    return status;
}
#endif

void QAccessible::initialize()
{
#ifndef QT_MAC_USE_COCOA
    registerQtAccessibilityHIObjectSubclass();
    installApplicationEventhandler();
#endif
}

// Sets thre root object for the application
void QAccessible::setRootObject(QObject *object)
{
    // Call installed root object handler if we have one
    if (rootObjectHandler) {
        rootObjectHandler(object);
        return;
    }

    rootObject = object;
}

void QAccessible::cleanup()
{
    accessibleHierarchyManager()->reset();
#ifndef QT_MAC_USE_COCOA
    removeEventhandler(applicationEventHandlerUPP);
    removeEventhandler(objectCreateEventHandlerUPP);
    removeEventhandler(accessibilityEventHandlerUPP);
#endif
}

void QAccessible::updateAccessibility(QObject *object, int child, Event reason)
{
    // Call installed update handler if we have one.
    if (updateHandler) {
        updateHandler(object, child, reason);
        return;
    }

#ifndef QT_MAC_USE_COCOA
    // Return if the mac accessibility is not enabled.
    if(!AXAPIEnabled())
        return;

     // Work around crash, disable accessiblity for focus frames.
     if (qstrcmp(object->metaObject()->className(), "QFocusFrame") == 0)
        return;

//    qDebug() << "updateAccessibility" << object << child << hex << reason;

    if (reason == ObjectShow) {
        QAInterface interface = QAInterface(QAccessible::queryAccessibleInterface(object), child);
        accessibleHierarchyManager()->registerInterface(interface);
    }

    const QAElement element = accessibleHierarchyManager()->lookup(object, child);
    if (element.isValid() == false)
        return;


    CFStringRef notification = 0;
    if(object && object->isWidgetType() && reason == ObjectCreated) {
        notification = CFStringRef(QAXWindowCreatedNotification);
    } else if(reason == ValueChanged) {
        notification = CFStringRef(QAXValueChangedNotification);
    } else if(reason == MenuStart) {
        notification = CFStringRef(QAXMenuOpenedNotification);
    } else if(reason == MenuEnd) {
        notification = CFStringRef(QAXMenuClosedNotification);
    } else if(reason == LocationChanged) {
        notification = CFStringRef(QAXWindowMovedNotification);
    } else if(reason == ObjectShow || reason == ObjectHide ) {
        // When a widget is deleted we get a ObjectHide before the destroyed(QObject *)
        // signal is emitted (which makes sense). However, at this point we are in the
        // middle of the QWidget destructor which means that we have to be careful when
        // using the widget pointer. Since we can't control what the accessibilty interfaces
        // does when navigate() is called below we ignore the hide update in this case.
        // (the widget will be deleted soon anyway.)
        extern QWidgetPrivate * qt_widget_private(QWidget *);
        if (QWidget *widget = qobject_cast<QWidget*>(object)) {
            if (qt_widget_private(widget)->data.in_destructor)
                return;

            // Check widget parent as well, special case for preventing crash
            // when the viewport() of an abstract scroll area is hidden when
            // the QWidget destructor hides all its children.
            QWidget *parentWidget = widget->parentWidget();
            if (parentWidget && qt_widget_private(parentWidget)->data.in_destructor)
                return;
        }

        // There is no equivalent Mac notification for ObjectShow/Hide, so we call HIObjectSetAccessibilityIgnored
        // and isItIntersting which will mark the HIObject accociated with the element as ignored if the
        // QAccessible::Invisible state bit is set.
        QAInterface interface = accessibleHierarchyManager()->lookup(element);
        if (interface.isValid()) {
            HIObjectSetAccessibilityIgnored(element.object(), !isItInteresting(interface));
        }

        // If the interface manages its own children, also check if we should ignore those.
        if (isItemView(interface) == false && managesChildren(interface)) {
            for (int i = 1; i <= interface.childCount(); ++i) {
                QAInterface childInterface = interface.navigate(QAccessible::Child, i);
                if (childInterface.isValid() && childInterface.isHIView() == false) {
                    const QAElement element = accessibleHierarchyManager()->lookup(childInterface);
                    if (element.isValid()) {
                        HIObjectSetAccessibilityIgnored(element.object(), !isItInteresting(childInterface));
                    }
                }
            }
        }

    } else if(reason == Focus) {
        if(object && object->isWidgetType()) {
            QWidget *w = static_cast<QWidget*>(object);
            if(w->isWindow())
                notification = CFStringRef(QAXFocusedWindowChangedNotification);
            else
                notification = CFStringRef(QAXFocusedUIElementChangedNotification);
        }
    }

    if (!notification)
        return;

    AXNotificationHIObjectNotify(notification, element.object(), element.id());
#endif
}

QT_END_NAMESPACE

#endif // QT_NO_ACCESSIBILITY
