summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/kernel/qeventdispatcher_winrt.cpp22
-rw-r--r--src/corelib/kernel/qeventdispatcher_winrt_p.h1
-rw-r--r--src/plugins/platforms/winrt/qwinrtcanvas.cpp146
-rw-r--r--src/plugins/platforms/winrt/qwinrtcanvas.h75
-rw-r--r--src/plugins/platforms/winrt/qwinrtintegration.cpp17
-rw-r--r--src/plugins/platforms/winrt/qwinrtintegration.h3
-rw-r--r--src/plugins/platforms/winrt/qwinrtscreen.cpp22
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiaaccessibility.cpp106
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiaaccessibility.h64
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiabaseprovider.cpp76
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiabaseprovider.h72
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiacontrolmetadata.cpp182
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiacontrolmetadata.h117
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiaemptypropertyvalue.h108
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiagriditemprovider.cpp160
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiagriditemprovider.h78
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiagridprovider.cpp135
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiagridprovider.h76
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiainvokeprovider.cpp88
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiainvokeprovider.h74
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiamainprovider.cpp779
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiamainprovider.h124
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiametadatacache.cpp112
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiametadatacache.h76
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiapeervector.cpp149
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiapeervector.h80
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiaprovidercache.cpp99
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiaprovidercache.h77
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiarangevalueprovider.cpp167
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiarangevalueprovider.h80
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionitemprovider.cpp214
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionitemprovider.h78
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionprovider.cpp158
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionprovider.h76
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiatableitemprovider.cpp141
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiatableitemprovider.h75
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiatableprovider.cpp167
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiatableprovider.h76
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiatextprovider.cpp232
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiatextprovider.h83
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiatextrangeprovider.cpp497
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiatextrangeprovider.h95
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiatoggleprovider.cpp104
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiatoggleprovider.h75
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiautils.cpp182
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiautils.h83
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiavalueprovider.cpp136
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiavalueprovider.h77
-rw-r--r--src/plugins/platforms/winrt/uiautomation/uiautomation.pri45
-rw-r--r--src/plugins/platforms/winrt/winrt.pro4
50 files changed, 5953 insertions, 10 deletions
diff --git a/src/corelib/kernel/qeventdispatcher_winrt.cpp b/src/corelib/kernel/qeventdispatcher_winrt.cpp
index 33753ed507..600c6c38fd 100644
--- a/src/corelib/kernel/qeventdispatcher_winrt.cpp
+++ b/src/corelib/kernel/qeventdispatcher_winrt.cpp
@@ -43,6 +43,8 @@
#include <QtCore/QThread>
#include <QtCore/QHash>
#include <QtCore/QMutex>
+#include <QtCore/QSemaphore>
+#include <QtCore/QSharedPointer>
#include <QtCore/qfunctions_winrt.h>
#include <private/qabstracteventdispatcher_p.h>
#include <private/qcoreapplication_p.h>
@@ -293,6 +295,26 @@ HRESULT QEventDispatcherWinRT::runOnXamlThread(const std::function<HRESULT ()> &
return QWinRTFunctions::await(op);
}
+HRESULT QEventDispatcherWinRT::runOnMainThread(const std::function<HRESULT()> &delegate, int timeout)
+{
+ if (QThread::currentThread() == QCoreApplication::instance()->thread())
+ return delegate();
+
+ auto semaphore = QSharedPointer<QSemaphore>(new QSemaphore);
+ auto ptrSemaphore = new QSharedPointer<QSemaphore>(semaphore);
+ auto result = QSharedPointer<HRESULT>(new HRESULT);
+ auto ptrResult = new QSharedPointer<HRESULT>(result);
+
+ QMetaObject::invokeMethod(QCoreApplication::instance(), [delegate, ptrSemaphore, ptrResult]() {
+ **ptrResult = delegate();
+ delete ptrResult;
+ (*ptrSemaphore)->release();
+ delete ptrSemaphore;
+ }, nullptr);
+
+ return semaphore->tryAcquire(1, timeout) ? *result : E_FAIL;
+}
+
bool QEventDispatcherWinRT::processEvents(QEventLoop::ProcessEventsFlags flags)
{
Q_D(QEventDispatcherWinRT);
diff --git a/src/corelib/kernel/qeventdispatcher_winrt_p.h b/src/corelib/kernel/qeventdispatcher_winrt_p.h
index f69bb9cf3f..8b998a7958 100644
--- a/src/corelib/kernel/qeventdispatcher_winrt_p.h
+++ b/src/corelib/kernel/qeventdispatcher_winrt_p.h
@@ -75,6 +75,7 @@ public:
~QEventDispatcherWinRT();
static HRESULT runOnXamlThread(const std::function<HRESULT()> &delegate, bool waitForRun = true);
+ static HRESULT runOnMainThread(const std::function<HRESULT()> &delegate, int timeout = 100);
bool processEvents(QEventLoop::ProcessEventsFlags flags);
bool hasPendingEvents();
diff --git a/src/plugins/platforms/winrt/qwinrtcanvas.cpp b/src/plugins/platforms/winrt/qwinrtcanvas.cpp
new file mode 100644
index 0000000000..ad77d811e6
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtcanvas.cpp
@@ -0,0 +1,146 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwinrtcanvas.h"
+#include "uiautomation/qwinrtuiaaccessibility.h"
+#include "uiautomation/qwinrtuiamainprovider.h"
+#include "uiautomation/qwinrtuiametadatacache.h"
+#include "uiautomation/qwinrtuiautils.h"
+
+#include <QtCore/QLoggingCategory>
+#include <QtCore/qfunctions_winrt.h>
+
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::System;
+using namespace ABI::Windows::UI;
+using namespace ABI::Windows::UI::Core;
+using namespace ABI::Windows::UI::Xaml;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::Foundation::Collections;
+
+QT_BEGIN_NAMESPACE
+
+QWinRTCanvas::QWinRTCanvas(const std::function<QWindow*()> &delegateWindow)
+{
+ ComPtr<Xaml::Controls::ICanvasFactory> factory;
+ HRESULT hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_Xaml_Controls_Canvas).Get(), IID_PPV_ARGS(&factory));
+ Q_ASSERT_SUCCEEDED(hr);
+
+ hr = factory->CreateInstance(this, &m_base, &m_core);
+ Q_ASSERT_SUCCEEDED(hr);
+
+ delegate = delegateWindow;
+}
+
+QWinRTCanvas::~QWinRTCanvas()
+{
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTCanvas::QueryInterface(REFIID iid, LPVOID *iface)
+{
+ if (!iface)
+ return E_POINTER;
+ *iface = nullptr;
+
+ if (iid == IID_IUnknown) {
+ *iface = static_cast<Xaml::IUIElementOverrides *>(this);
+ AddRef();
+ return S_OK;
+ } else if (iid == Xaml::IID_IUIElementOverrides) {
+ *iface = static_cast<Xaml::IUIElementOverrides *>(this);
+ AddRef();
+ return S_OK;
+ } else {
+ return m_base.CopyTo(iid, iface);
+ }
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTCanvas::GetIids(ULONG *iidCount, IID **iids)
+{
+ *iidCount = 0;
+ *iids = nullptr;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTCanvas::GetRuntimeClassName(HSTRING *className)
+{
+ const wchar_t *name = L"QWinRTCanvas";
+ return ::WindowsCreateString(name, static_cast<UINT32>(::wcslen(name)), className);
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTCanvas::GetTrustLevel(TrustLevel *trustLevel)
+{
+ *trustLevel = TrustLevel::BaseTrust;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTCanvas::OnCreateAutomationPeer(Xaml::Automation::Peers::IAutomationPeer **returnValue)
+{
+ if (!returnValue)
+ return E_INVALIDARG;
+ *returnValue = nullptr;
+
+ if (delegate) {
+ if (QWindow *window = delegate()) {
+ QWinRTUiaAccessibility::activate();
+ if (QAccessibleInterface *accessible = window->accessibleRoot()) {
+ QAccessible::Id accid = QWinRTUiAutomation::idForAccessible(accessible);
+ QWinRTUiaMetadataCache::instance()->load(accid);
+ if (ComPtr<QWinRTUiaMainProvider> provider = QWinRTUiaMainProvider::providerForAccessibleId(accid))
+ return provider.CopyTo(returnValue);
+ }
+ }
+ }
+ return m_base->OnCreateAutomationPeer(returnValue);
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTCanvas::OnDisconnectVisualChildren()
+{
+ return m_base->OnDisconnectVisualChildren();
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTCanvas::FindSubElementsForTouchTargeting(Point point, Rect boundingRect, IIterable<IIterable<ABI::Windows::Foundation::Point>*> **returnValue)
+{
+ return m_base->FindSubElementsForTouchTargeting(point, boundingRect, returnValue);
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/plugins/platforms/winrt/qwinrtcanvas.h b/src/plugins/platforms/winrt/qwinrtcanvas.h
new file mode 100644
index 0000000000..68c15c7602
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtcanvas.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTCANVAS_H
+#define QWINRTCANVAS_H
+
+#include <QtCore/qglobal.h>
+#include <QtGui/QWindow>
+
+#include <wrl.h>
+#include <windows.ui.xaml.h>
+#include <functional>
+
+QT_BEGIN_NAMESPACE
+
+class QWinRTCanvas:
+ public Microsoft::WRL::RuntimeClass<ABI::Windows::UI::Xaml::IUIElementOverrides>
+{
+public:
+ QWinRTCanvas(const std::function<QWindow*()> &delegateWindow);
+ virtual ~QWinRTCanvas();
+
+ HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, LPVOID *iface) override;
+ HRESULT STDMETHODCALLTYPE GetIids(ULONG *iidCount, IID **iids) override;
+ HRESULT STDMETHODCALLTYPE GetRuntimeClassName(HSTRING *className) override;
+ HRESULT STDMETHODCALLTYPE GetTrustLevel(TrustLevel *trustLevel) override;
+ HRESULT STDMETHODCALLTYPE OnCreateAutomationPeer(ABI::Windows::UI::Xaml::Automation::Peers::IAutomationPeer **returnValue) override;
+ HRESULT STDMETHODCALLTYPE OnDisconnectVisualChildren() override;
+ HRESULT STDMETHODCALLTYPE FindSubElementsForTouchTargeting(ABI::Windows::Foundation::Point point, ABI::Windows::Foundation::Rect boundingRect, ABI::Windows::Foundation::Collections::IIterable<ABI::Windows::Foundation::Collections::IIterable<ABI::Windows::Foundation::Point>*> **returnValue) override;
+
+private:
+ Microsoft::WRL::ComPtr<ABI::Windows::UI::Xaml::IUIElementOverrides> m_base;
+ Microsoft::WRL::ComPtr<ABI::Windows::UI::Xaml::Controls::ICanvas> m_core;
+ std::function<QWindow*()> delegate;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINRTCANVAS_H
diff --git a/src/plugins/platforms/winrt/qwinrtintegration.cpp b/src/plugins/platforms/winrt/qwinrtintegration.cpp
index 7a30c8d98b..eae043f3a7 100644
--- a/src/plugins/platforms/winrt/qwinrtintegration.cpp
+++ b/src/plugins/platforms/winrt/qwinrtintegration.cpp
@@ -50,6 +50,9 @@
#ifndef QT_NO_DRAGANDDROP
#include "qwinrtdrag.h"
#endif
+#if QT_CONFIG(accessibility)
+# include "uiautomation/qwinrtuiaaccessibility.h"
+#endif
#include <QtGui/QOffscreenSurface>
#include <QtGui/QOpenGLContext>
@@ -119,6 +122,9 @@ public:
QPlatformClipboard *clipboard;
QWinRTScreen *mainScreen;
QScopedPointer<QWinRTInputContext> inputContext;
+#if QT_CONFIG(accessibility)
+ QWinRTUiaAccessibility *accessibility;
+#endif
ComPtr<ICoreApplication> application;
QHash<CoreApplicationCallbackRemover, EventRegistrationToken> applicationTokens;
@@ -198,6 +204,9 @@ QWinRTIntegration::QWinRTIntegration() : d_ptr(new QWinRTIntegrationPrivate)
screenAdded(d->mainScreen);
d->platformServices = new QWinRTServices;
d->clipboard = new QWinRTClipboard;
+#if QT_CONFIG(accessibility)
+ d->accessibility = new QWinRTUiaAccessibility;
+#endif
}
QWinRTIntegration::~QWinRTIntegration()
@@ -315,6 +324,14 @@ QPlatformDrag *QWinRTIntegration::drag() const
}
#endif // QT_NO_DRAGANDDROP
+#if QT_CONFIG(accessibility)
+QPlatformAccessibility *QWinRTIntegration::accessibility() const
+{
+ Q_D(const QWinRTIntegration);
+ return d->accessibility;
+}
+#endif // QT_CONFIG(accessibility)
+
Qt::KeyboardModifiers QWinRTIntegration::queryKeyboardModifiers() const
{
Q_D(const QWinRTIntegration);
diff --git a/src/plugins/platforms/winrt/qwinrtintegration.h b/src/plugins/platforms/winrt/qwinrtintegration.h
index e22532a266..adc7620727 100644
--- a/src/plugins/platforms/winrt/qwinrtintegration.h
+++ b/src/plugins/platforms/winrt/qwinrtintegration.h
@@ -100,6 +100,9 @@ public:
#ifndef QT_NO_DRAGANDDROP
QPlatformDrag *drag() const override;
#endif
+#if QT_CONFIG(accessibility)
+ QPlatformAccessibility *accessibility() const override;
+#endif
Qt::KeyboardModifiers queryKeyboardModifiers() const override;
diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp
index e37aeb0bc5..a325d6f817 100644
--- a/src/plugins/platforms/winrt/qwinrtscreen.cpp
+++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp
@@ -46,6 +46,7 @@
#include "qwinrtdrag.h"
#endif
#include "qwinrtwindow.h"
+#include "qwinrtcanvas.h"
#include <private/qeventdispatcher_winrt_p.h>
#include <private/qhighdpiscaling_p.h>
@@ -463,7 +464,7 @@ public:
QTouchDevice *touchDevice;
ComPtr<ICoreWindow> coreWindow;
ComPtr<ICorePointerRedirector> redirect;
- ComPtr<Xaml::IDependencyObject> canvas;
+ ComPtr<QWinRTCanvas> canvas;
ComPtr<IApplicationView> view;
ComPtr<IDisplayInformation> displayInformation;
@@ -553,27 +554,25 @@ QWinRTScreen::QWinRTScreen()
hr = applicationViewStatics->GetForCurrentView(&d->view);
RETURN_VOID_IF_FAILED("Could not access currentView");
- // Create a canvas and set it as the window content. Eventually, this should have its own method so multiple "screens" can be added
- ComPtr<Xaml::Controls::ICanvas> canvas;
- hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_UI_Xaml_Controls_Canvas).Get(), &canvas);
- Q_ASSERT_SUCCEEDED(hr);
+ d->canvas = Make<QWinRTCanvas>([this]() { return topWindow(); });
+
ComPtr<Xaml::IFrameworkElement> frameworkElement;
- hr = canvas.As(&frameworkElement);
+ hr = d->canvas.As(&frameworkElement);
Q_ASSERT_SUCCEEDED(hr);
hr = frameworkElement->put_Width(d->logicalRect.width());
Q_ASSERT_SUCCEEDED(hr);
hr = frameworkElement->put_Height(d->logicalRect.height());
Q_ASSERT_SUCCEEDED(hr);
+
ComPtr<Xaml::IUIElement> uiElement;
- hr = canvas.As(&uiElement);
+ hr = d->canvas.As(&uiElement);
Q_ASSERT_SUCCEEDED(hr);
+
#ifndef QT_NO_DRAGANDDROP
QWinRTDrag::instance()->setUiElement(uiElement);
#endif
hr = window->put_Content(uiElement.Get());
Q_ASSERT_SUCCEEDED(hr);
- hr = canvas.As(&d->canvas);
- Q_ASSERT_SUCCEEDED(hr);
d->cursor.reset(new QWinRTCursor);
@@ -723,7 +722,10 @@ ICoreWindow *QWinRTScreen::coreWindow() const
Xaml::IDependencyObject *QWinRTScreen::canvas() const
{
Q_D(const QWinRTScreen);
- return d->canvas.Get();
+ Xaml::IDependencyObject *depCanvas;
+ if (SUCCEEDED(d->canvas.CopyTo(&depCanvas)))
+ return depCanvas;
+ return nullptr;
}
void QWinRTScreen::initialize()
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiaaccessibility.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiaaccessibility.cpp
new file mode 100644
index 0000000000..878fcd0f96
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiaaccessibility.cpp
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiaaccessibility.h"
+#include "qwinrtuiamainprovider.h"
+
+#include <QtGui/QAccessible>
+#include <QtGui/QWindow>
+#include <QtGui/QGuiApplication>
+#include <QtGui/private/qguiapplication_p.h>
+#include <QtCore/qt_windows.h>
+#include <qpa/qplatformintegration.h>
+
+QT_BEGIN_NAMESPACE
+
+QWinRTUiaAccessibility::QWinRTUiaAccessibility()
+{
+}
+
+QWinRTUiaAccessibility::~QWinRTUiaAccessibility()
+{
+}
+
+// Handles UI Automation window messages.
+void QWinRTUiaAccessibility::activate()
+{
+ // Start handling accessibility internally
+ QGuiApplicationPrivate::platformIntegration()->accessibility()->setActive(true);
+}
+
+// Handles accessibility update notifications.
+void QWinRTUiaAccessibility::notifyAccessibilityUpdate(QAccessibleEvent *event)
+{
+ if (!event)
+ return;
+
+ QAccessibleInterface *accessible = event->accessibleInterface();
+ if (!isActive() || !accessible || !accessible->isValid())
+ return;
+
+ switch (event->type()) {
+ case QAccessible::Focus:
+ QWinRTUiaMainProvider::notifyFocusChange(event);
+ break;
+ case QAccessible::StateChanged:
+ QWinRTUiaMainProvider::notifyStateChange(static_cast<QAccessibleStateChangeEvent *>(event));
+ break;
+ case QAccessible::ValueChanged:
+ QWinRTUiaMainProvider::notifyValueChange(static_cast<QAccessibleValueChangeEvent *>(event));
+ break;
+ case QAccessible::TextAttributeChanged:
+ case QAccessible::TextColumnChanged:
+ case QAccessible::TextInserted:
+ case QAccessible::TextRemoved:
+ case QAccessible::TextUpdated:
+ case QAccessible::TextSelectionChanged:
+ case QAccessible::TextCaretMoved:
+ QWinRTUiaMainProvider::notifyTextChange(event);
+ break;
+ default:
+ break;
+ }
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiaaccessibility.h b/src/plugins/platforms/winrt/uiautomation/qwinrtuiaaccessibility.h
new file mode 100644
index 0000000000..b966271e21
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiaaccessibility.h
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTUIAACCESSIBILITY_H
+#define QWINRTUIAACCESSIBILITY_H
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include <qpa/qplatformaccessibility.h>
+
+QT_BEGIN_NAMESPACE
+
+// WinRT platform accessibility implemented over UI Automation.
+class QWinRTUiaAccessibility : public QPlatformAccessibility
+{
+public:
+ explicit QWinRTUiaAccessibility();
+ virtual ~QWinRTUiaAccessibility();
+ static void activate();
+ void notifyAccessibilityUpdate(QAccessibleEvent *event) override;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
+
+#endif // QWINRTUIAACCESSIBILITY_H
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiabaseprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiabaseprovider.cpp
new file mode 100644
index 0000000000..ee53714caa
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiabaseprovider.cpp
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiabaseprovider.h"
+
+#include <QtGui/QAccessible>
+#include <QtGui/QAccessibleInterface>
+#include <QtCore/QLoggingCategory>
+#include <QtCore/QString>
+
+QT_BEGIN_NAMESPACE
+
+QWinRTUiaBaseProvider::QWinRTUiaBaseProvider(QAccessible::Id id) :
+ m_id(id)
+{
+}
+
+QWinRTUiaBaseProvider::~QWinRTUiaBaseProvider()
+{
+}
+
+QAccessibleInterface *QWinRTUiaBaseProvider::accessibleInterface() const
+{
+ QAccessibleInterface *accessible = QAccessible::accessibleInterface(m_id);
+ if (accessible && accessible->isValid())
+ return accessible;
+ return nullptr;
+}
+
+QAccessible::Id QWinRTUiaBaseProvider::id() const
+{
+ return m_id;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiabaseprovider.h b/src/plugins/platforms/winrt/uiautomation/qwinrtuiabaseprovider.h
new file mode 100644
index 0000000000..d8837354dc
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiabaseprovider.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTUIABASEPROVIDER_H
+#define QWINRTUIABASEPROVIDER_H
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include <QtGui/QAccessible>
+#include <QtGui/QAccessibleInterface>
+#include <QtCore/QPointer>
+
+QT_BEGIN_NAMESPACE
+
+// Base class for UI Automation providers.
+class QWinRTUiaBaseProvider : public QObject
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(QWinRTUiaBaseProvider)
+public:
+ explicit QWinRTUiaBaseProvider(QAccessible::Id id);
+ virtual ~QWinRTUiaBaseProvider();
+
+ QAccessibleInterface *accessibleInterface() const;
+ QAccessible::Id id() const;
+
+private:
+ QAccessible::Id m_id;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
+
+#endif // QWINRTUIABASEPROVIDER_H
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiacontrolmetadata.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiacontrolmetadata.cpp
new file mode 100644
index 0000000000..4e406a3545
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiacontrolmetadata.cpp
@@ -0,0 +1,182 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiacontrolmetadata.h"
+#include "qwinrtuiautils.h"
+
+#include <QtCore/QLoggingCategory>
+#include <QtCore/QString>
+
+QT_BEGIN_NAMESPACE
+
+using namespace QWinRTUiAutomation;
+
+QWinRTUiaControlMetadata::QWinRTUiaControlMetadata()
+{
+}
+
+QWinRTUiaControlMetadata::QWinRTUiaControlMetadata(QAccessible::Id id)
+{
+ update(id);
+}
+
+void QWinRTUiaControlMetadata::update(QAccessible::Id id)
+{
+ if (QAccessibleInterface *accessible = accessibleForId(id)) {
+ m_automationId = generateAutomationId(accessible);
+ m_className = generateClassName(accessible);
+ m_controlName = generateControlName(accessible);
+ m_role = generateRole(accessible);
+ m_state = accessible->state();
+ m_accelerator = accessible->text(QAccessible::Accelerator);
+ m_access = accessible->text(QAccessible::Accelerator);
+ m_help = accessible->text(QAccessible::Help);
+ m_description = accessible->text(QAccessible::Description);
+ m_value = accessible->text(QAccessible::Value);
+ m_boundingRect = accessible->rect();
+ updateValueData(accessible);
+ updateTableData(accessible);
+ updateTextData(accessible);
+ }
+}
+
+QString QWinRTUiaControlMetadata::generateControlName(QAccessibleInterface *accessible)
+{
+ const bool clientTopLevel = (accessible->role() == QAccessible::Client)
+ && accessible->parent() && (accessible->parent()->role() == QAccessible::Application);
+
+ QString name = accessible->text(QAccessible::Name);
+ if (name.isEmpty() && clientTopLevel)
+ name = QCoreApplication::applicationName();
+ return name;
+}
+
+QString QWinRTUiaControlMetadata::generateClassName(QAccessibleInterface *accessible)
+{
+ QString name;
+
+ if (QObject *obj = accessible->object())
+ name = QLatin1String(obj->metaObject()->className());
+ return name;
+}
+
+// Generates an ID based on the name of the controls and their parents.
+QString QWinRTUiaControlMetadata::generateAutomationId(QAccessibleInterface *accessible)
+{
+ QString autid;
+ QObject *obj = accessible->object();
+ while (obj) {
+ QString name = obj->objectName();
+ if (name.isEmpty()) {
+ autid = QStringLiteral("");
+ break;
+ }
+ if (!autid.isEmpty())
+ autid.prepend(QLatin1Char('.'));
+ autid.prepend(name);
+ obj = obj->parent();
+ }
+ return autid;
+}
+
+QAccessible::Role QWinRTUiaControlMetadata::generateRole(QAccessibleInterface *accessible)
+{
+ const bool clientTopLevel = (accessible->role() == QAccessible::Client)
+ && accessible->parent() && (accessible->parent()->role() == QAccessible::Application);
+
+ if (clientTopLevel) {
+ // Reports a top-level widget as a window.
+ return QAccessible::Window;
+ } else {
+ return accessible->role();
+ }
+}
+
+void QWinRTUiaControlMetadata::updateValueData(QAccessibleInterface *accessible)
+{
+ if (QAccessibleValueInterface *valueInterface = accessible->valueInterface()) {
+ m_minimumValue = valueInterface->minimumValue().toDouble();
+ m_maximumValue = valueInterface->maximumValue().toDouble();
+ m_currentValue = valueInterface->currentValue().toDouble();
+ m_minimumStepSize = valueInterface->minimumStepSize().toDouble();
+ } else {
+ m_minimumValue = 0.0;
+ m_maximumValue = 0.0;
+ m_currentValue = 0.0;
+ m_minimumStepSize = 0.0;
+ }
+}
+
+void QWinRTUiaControlMetadata::updateTableData(QAccessibleInterface *accessible)
+{
+ if (QAccessibleTableInterface *tableInterface = accessible->tableInterface()) {
+ m_rowIndex = 0;
+ m_columnIndex = 0;
+ m_rowCount = tableInterface->rowCount();
+ m_columnCount = tableInterface->columnCount();
+ } else if (QAccessibleTableCellInterface *tableCellInterface = accessible->tableCellInterface()) {
+ m_rowIndex = tableCellInterface->rowIndex();
+ m_columnIndex = tableCellInterface->columnIndex();
+ m_rowCount = tableCellInterface->rowExtent();
+ m_columnCount = tableCellInterface->columnExtent();
+ } else {
+ m_rowIndex = 0;
+ m_columnIndex = 0;
+ m_rowCount = 0;
+ m_columnCount = 0;
+ }
+}
+
+void QWinRTUiaControlMetadata::updateTextData(QAccessibleInterface *accessible)
+{
+ if (QAccessibleTextInterface *textInterface = accessible->textInterface()) {
+ m_cursorPosition = textInterface->cursorPosition();
+ m_text = textInterface->text(0, textInterface->characterCount());
+ } else {
+ m_cursorPosition = 0;
+ m_text = QStringLiteral("");
+ }
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiacontrolmetadata.h b/src/plugins/platforms/winrt/uiautomation/qwinrtuiacontrolmetadata.h
new file mode 100644
index 0000000000..769f073a1b
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiacontrolmetadata.h
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTUIACONTROLMETADATA_H
+#define QWINRTUIACONTROLMETADATA_H
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include <QString>
+#include <QtGui/QAccessible>
+#include <QtGui/QAccessibleInterface>
+
+QT_BEGIN_NAMESPACE
+
+// Cacheable control metadata
+class QWinRTUiaControlMetadata
+{
+public:
+ QWinRTUiaControlMetadata();
+ QWinRTUiaControlMetadata(QAccessible::Id id);
+ void update(QAccessible::Id id);
+ QString automationId() const { return m_automationId; }
+ QString className() const { return m_className; }
+ QString controlName() const { return m_controlName; }
+ QString accelerator() const { return m_accelerator; }
+ QString access() const { return m_access; }
+ QString help() const { return m_help; }
+ QString description() const { return m_description; }
+ QString value() const { return m_value; }
+ QString text() const { return m_text; }
+ QAccessible::Role role() const { return m_role; }
+ QAccessible::State state() const { return m_state; }
+ QRect boundingRect() const { return m_boundingRect; }
+ double minimumValue() const { return m_minimumValue; }
+ double maximumValue() const { return m_maximumValue; }
+ double currentValue() const { return m_currentValue; }
+ double minimumStepSize() const { return m_minimumStepSize; }
+ int rowIndex() const { return m_rowIndex; }
+ int columnIndex() const { return m_columnIndex; }
+ int rowCount() const { return m_rowCount; }
+ int columnCount() const { return m_columnCount; }
+ int characterCount() const { return m_text.length(); }
+ int cursorPosition() const { return m_cursorPosition; }
+
+private:
+ QString generateControlName(QAccessibleInterface *accessible);
+ QString generateClassName(QAccessibleInterface *accessible);
+ QString generateAutomationId(QAccessibleInterface *accessible);
+ QAccessible::Role generateRole(QAccessibleInterface *accessible);
+ void updateValueData(QAccessibleInterface *accessible);
+ void updateTableData(QAccessibleInterface *accessible);
+ void updateTextData(QAccessibleInterface *accessible);
+ QString m_automationId;
+ QString m_className;
+ QString m_controlName;
+ QString m_accelerator;
+ QString m_access;
+ QString m_help;
+ QString m_description;
+ QString m_value;
+ QString m_text;
+ QAccessible::Role m_role = QAccessible::NoRole;
+ QAccessible::State m_state;
+ QRect m_boundingRect;
+ double m_minimumValue = 0.0;
+ double m_maximumValue = 0.0;
+ double m_currentValue = 0.0;
+ double m_minimumStepSize = 0.0;
+ int m_rowIndex = 0;
+ int m_columnIndex = 0;
+ int m_rowCount = 0;
+ int m_columnCount = 0;
+ int m_cursorPosition = 0;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
+
+#endif // QWINRTUIACONTROLMETADATA_H
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiaemptypropertyvalue.h b/src/plugins/platforms/winrt/uiautomation/qwinrtuiaemptypropertyvalue.h
new file mode 100644
index 0000000000..35e4df75fc
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiaemptypropertyvalue.h
@@ -0,0 +1,108 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTUIAEMPTYPROPERTYVALUE_H
+#define QWINRTUIAEMPTYPROPERTYVALUE_H
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include <wrl.h>
+#include <windows.ui.xaml.h>
+
+QT_BEGIN_NAMESPACE
+
+// Implements an empty property value.
+class QWinRTUiaEmptyPropertyValue :
+ public Microsoft::WRL::RuntimeClass<ABI::Windows::Foundation::IPropertyValue>
+{
+ InspectableClass(L"QWinRTUiaEmptyPropertyValue", BaseTrust);
+public:
+
+ HRESULT STDMETHODCALLTYPE get_Type(ABI::Windows::Foundation::PropertyType *value)
+ {
+ *value = ABI::Windows::Foundation::PropertyType_Empty;
+ return S_OK;
+ }
+
+ HRESULT STDMETHODCALLTYPE get_IsNumericScalar(boolean*) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetUInt8(BYTE*) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetInt16(INT16*) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetUInt16(UINT16*) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetInt32(INT32*) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetUInt32(UINT32*) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetInt64(INT64*) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetUInt64(UINT64*) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetSingle(FLOAT*) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetDouble(DOUBLE*) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetChar16(WCHAR*) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetBoolean(boolean*) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetString(HSTRING*) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetGuid(GUID*) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetDateTime(ABI::Windows::Foundation::DateTime*) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetTimeSpan(ABI::Windows::Foundation::TimeSpan*) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetPoint(ABI::Windows::Foundation::Point*) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetSize(ABI::Windows::Foundation::Size*) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetRect(ABI::Windows::Foundation::Rect*) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetUInt8Array(UINT32*, BYTE**) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetInt16Array(UINT32*, INT16**) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetUInt16Array(UINT32*, UINT16**) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetInt32Array(UINT32*, INT32**) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetUInt32Array(UINT32*, UINT32**) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetInt64Array(UINT32*, INT64**) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetUInt64Array(UINT32*, UINT64**) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetSingleArray(UINT32*, FLOAT**) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetDoubleArray(UINT32*, DOUBLE**) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetChar16Array(UINT32*, WCHAR**) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetBooleanArray(UINT32*, boolean**) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetStringArray(UINT32*, HSTRING**) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetInspectableArray(UINT32*, IInspectable***) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetGuidArray(UINT32*, GUID**) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetDateTimeArray(UINT32*, ABI::Windows::Foundation::DateTime**) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetTimeSpanArray(UINT32*, ABI::Windows::Foundation::TimeSpan**) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetPointArray(UINT32*, ABI::Windows::Foundation::Point**) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetSizeArray(UINT32*, ABI::Windows::Foundation::Size**) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetRectArray(UINT32*, ABI::Windows::Foundation::Rect**) { return E_FAIL; }
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
+
+#endif // QWINRTUIAEMPTYPROPERTYVALUE_H
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiagriditemprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiagriditemprovider.cpp
new file mode 100644
index 0000000000..524000b618
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiagriditemprovider.cpp
@@ -0,0 +1,160 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiagriditemprovider.h"
+#include "qwinrtuiamainprovider.h"
+#include "qwinrtuiametadatacache.h"
+#include "qwinrtuiautils.h"
+
+#include <QtGui/QAccessible>
+#include <QtGui/QAccessibleInterface>
+#include <QtCore/QLoggingCategory>
+#include <QtCore/QString>
+#include <QtCore/private/qeventdispatcher_winrt_p.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace QWinRTUiAutomation;
+using namespace ABI::Windows::UI::Xaml::Automation;
+using namespace ABI::Windows::UI::Xaml::Automation::Provider;
+using namespace ABI::Windows::UI::Xaml::Automation::Peers;
+
+QWinRTUiaGridItemProvider::QWinRTUiaGridItemProvider(QAccessible::Id id) :
+ QWinRTUiaBaseProvider(id)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+}
+
+QWinRTUiaGridItemProvider::~QWinRTUiaGridItemProvider()
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+}
+
+// Returns the column index of the item.
+HRESULT STDMETHODCALLTYPE QWinRTUiaGridItemProvider::get_Column(INT32 *value)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!value)
+ return E_INVALIDARG;
+
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ *value = metadata->columnIndex();
+ return S_OK;
+}
+
+// Returns the number of columns occupied by the item.
+HRESULT STDMETHODCALLTYPE QWinRTUiaGridItemProvider::get_ColumnSpan(INT32 *value)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!value)
+ return E_INVALIDARG;
+
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ *value = metadata->columnCount();
+ return S_OK;
+}
+
+// Returns the provider for the containing table/tree.
+HRESULT STDMETHODCALLTYPE QWinRTUiaGridItemProvider::get_ContainingGrid(IIRawElementProviderSimple **value)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!value)
+ return E_INVALIDARG;
+ *value = nullptr;
+
+ auto accid = id();
+ auto elementId = QSharedPointer<QAccessible::Id>(new QAccessible::Id(0));
+ auto ptrElementId = new QSharedPointer<QAccessible::Id>(elementId);
+
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementId]() {
+ if (QAccessibleInterface *accessible = accessibleForId(accid)) {
+ if (QAccessibleTableCellInterface *tableCellInterface = accessible->tableCellInterface()) {
+ if (QAccessibleInterface *table = tableCellInterface->table()) {
+ **ptrElementId = idForAccessible(table);
+ QWinRTUiaMetadataCache::instance()->load(**ptrElementId);
+ }
+ }
+ }
+ delete ptrElementId;
+ return S_OK;
+ }))) {
+ return E_FAIL;
+ }
+
+ if (!*elementId)
+ return S_OK;
+
+ return QWinRTUiaMainProvider::rawProviderForAccessibleId(*elementId, value);
+}
+
+// Returns the row index of the item.
+HRESULT STDMETHODCALLTYPE QWinRTUiaGridItemProvider::get_Row(INT32 *value)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!value)
+ return E_INVALIDARG;
+
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ *value = metadata->rowIndex();
+ return S_OK;
+}
+
+// Returns the number of rows occupied by the item.
+HRESULT STDMETHODCALLTYPE QWinRTUiaGridItemProvider::get_RowSpan(INT32 *value)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!value)
+ return E_INVALIDARG;
+
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ *value = metadata->rowCount();
+ return S_OK;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiagriditemprovider.h b/src/plugins/platforms/winrt/uiautomation/qwinrtuiagriditemprovider.h
new file mode 100644
index 0000000000..70504fc555
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiagriditemprovider.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTUIAGRIDITEMPROVIDER_H
+#define QWINRTUIAGRIDITEMPROVIDER_H
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiabaseprovider.h"
+
+#include <wrl.h>
+#include <windows.ui.xaml.h>
+
+QT_BEGIN_NAMESPACE
+
+// Implements the Grid Item control pattern provider. Used by items within a table/tree.
+class QWinRTUiaGridItemProvider :
+ public QWinRTUiaBaseProvider,
+ public Microsoft::WRL::RuntimeClass<ABI::Windows::UI::Xaml::Automation::Provider::IGridItemProvider>
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(QWinRTUiaGridItemProvider)
+ InspectableClass(L"QWinRTUiaGridItemProvider", BaseTrust);
+
+public:
+ explicit QWinRTUiaGridItemProvider(QAccessible::Id id);
+ virtual ~QWinRTUiaGridItemProvider();
+
+ // IGridItemProvider
+ HRESULT STDMETHODCALLTYPE get_Column(INT32 *value) override;
+ HRESULT STDMETHODCALLTYPE get_ColumnSpan(INT32 *value) override;
+ HRESULT STDMETHODCALLTYPE get_ContainingGrid(ABI::Windows::UI::Xaml::Automation::Provider::IIRawElementProviderSimple **value) override;
+ HRESULT STDMETHODCALLTYPE get_Row(INT32 *value) override;
+ HRESULT STDMETHODCALLTYPE get_RowSpan(INT32 *value) override;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
+
+#endif // QWINRTUIAGRIDITEMPROVIDER_H
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiagridprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiagridprovider.cpp
new file mode 100644
index 0000000000..e469991de2
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiagridprovider.cpp
@@ -0,0 +1,135 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiagridprovider.h"
+#include "qwinrtuiamainprovider.h"
+#include "qwinrtuiametadatacache.h"
+#include "qwinrtuiautils.h"
+
+#include <QtGui/QAccessible>
+#include <QtGui/QAccessibleInterface>
+#include <QtCore/QLoggingCategory>
+#include <QtCore/QString>
+#include <QtCore/private/qeventdispatcher_winrt_p.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace QWinRTUiAutomation;
+using namespace ABI::Windows::UI::Xaml::Automation;
+using namespace ABI::Windows::UI::Xaml::Automation::Provider;
+using namespace ABI::Windows::UI::Xaml::Automation::Peers;
+
+QWinRTUiaGridProvider::QWinRTUiaGridProvider(QAccessible::Id id) :
+ QWinRTUiaBaseProvider(id)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+}
+
+QWinRTUiaGridProvider::~QWinRTUiaGridProvider()
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+}
+
+// Returns the number of columns.
+HRESULT STDMETHODCALLTYPE QWinRTUiaGridProvider::get_ColumnCount(INT32 *value)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!value)
+ return E_INVALIDARG;
+
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ *value = metadata->columnCount();
+ return S_OK;
+}
+
+// Returns the number of rows.
+HRESULT STDMETHODCALLTYPE QWinRTUiaGridProvider::get_RowCount(INT32 *value)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!value)
+ return E_INVALIDARG;
+
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ *value = metadata->rowCount();
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaGridProvider::GetItem(INT32 row, INT32 column, IIRawElementProviderSimple **returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ *returnValue = nullptr;
+
+ auto accid = id();
+ auto elementId = QSharedPointer<QAccessible::Id>(new QAccessible::Id(0));
+ auto ptrElementId = new QSharedPointer<QAccessible::Id>(elementId);
+
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, row, column, ptrElementId]() {
+ if (QAccessibleInterface *accessible = accessibleForId(accid)) {
+ if (QAccessibleTableInterface *tableInterface = accessible->tableInterface()) {
+ if ((row >= 0) && (row < tableInterface->rowCount()) && (column >= 0) && (column < tableInterface->columnCount())) {
+ if (QAccessibleInterface *cell = tableInterface->cellAt(row, column)) {
+ **ptrElementId = idForAccessible(cell);
+ QWinRTUiaMetadataCache::instance()->load(**ptrElementId);
+ }
+ }
+ }
+ }
+ delete ptrElementId;
+ return S_OK;
+ }))) {
+ return E_FAIL;
+ }
+
+ if (!*elementId)
+ return E_FAIL;
+
+ return QWinRTUiaMainProvider::rawProviderForAccessibleId(*elementId, returnValue);
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiagridprovider.h b/src/plugins/platforms/winrt/uiautomation/qwinrtuiagridprovider.h
new file mode 100644
index 0000000000..d6dfaed315
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiagridprovider.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTUIAGRIDPROVIDER_H
+#define QWINRTUIAGRIDPROVIDER_H
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiabaseprovider.h"
+
+#include <wrl.h>
+#include <windows.ui.xaml.h>
+
+QT_BEGIN_NAMESPACE
+
+// Implements the Grid control pattern provider. Used by tables/trees.
+class QWinRTUiaGridProvider :
+ public QWinRTUiaBaseProvider,
+ public Microsoft::WRL::RuntimeClass<ABI::Windows::UI::Xaml::Automation::Provider::IGridProvider>
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(QWinRTUiaGridProvider)
+ InspectableClass(L"QWinRTUiaGridProvider", BaseTrust);
+
+public:
+ explicit QWinRTUiaGridProvider(QAccessible::Id id);
+ virtual ~QWinRTUiaGridProvider();
+
+ // IGridProvider
+ HRESULT STDMETHODCALLTYPE get_ColumnCount(INT32 *value) override;
+ HRESULT STDMETHODCALLTYPE get_RowCount(INT32 *value) override;
+ HRESULT STDMETHODCALLTYPE GetItem(INT32 row, INT32 column, ABI::Windows::UI::Xaml::Automation::Provider::IIRawElementProviderSimple **returnValue) override;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
+
+#endif // QWINRTUIAGRIDPROVIDER_H
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiainvokeprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiainvokeprovider.cpp
new file mode 100644
index 0000000000..e2cf7bc107
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiainvokeprovider.cpp
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiainvokeprovider.h"
+#include "qwinrtuiametadatacache.h"
+#include "qwinrtuiautils.h"
+
+#include <QtGui/QAccessible>
+#include <QtGui/QAccessibleInterface>
+#include <QtCore/QLoggingCategory>
+#include <QtCore/QString>
+#include <QtCore/private/qeventdispatcher_winrt_p.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace QWinRTUiAutomation;
+using namespace ABI::Windows::UI::Xaml::Automation;
+using namespace ABI::Windows::UI::Xaml::Automation::Provider;
+
+QWinRTUiaInvokeProvider::QWinRTUiaInvokeProvider(QAccessible::Id id) :
+ QWinRTUiaBaseProvider(id)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+}
+
+QWinRTUiaInvokeProvider::~QWinRTUiaInvokeProvider()
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaInvokeProvider::Invoke()
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ auto accid = id();
+
+ QEventDispatcherWinRT::runOnMainThread([accid]() {
+ if (QAccessibleInterface *accessible = accessibleForId(accid))
+ if (QAccessibleActionInterface *actionInterface = accessible->actionInterface())
+ actionInterface->doAction(QAccessibleActionInterface::pressAction());
+ QWinRTUiaMetadataCache::instance()->load(accid);
+ return S_OK;
+ }, 0);
+ return S_OK;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiainvokeprovider.h b/src/plugins/platforms/winrt/uiautomation/qwinrtuiainvokeprovider.h
new file mode 100644
index 0000000000..dfe7917a16
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiainvokeprovider.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTUIAINVOKEPROVIDER_H
+#define QWINRTUIAINVOKEPROVIDER_H
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiabaseprovider.h"
+
+#include <wrl.h>
+#include <windows.ui.xaml.h>
+
+QT_BEGIN_NAMESPACE
+
+// Implements the Invoke control pattern provider.
+class QWinRTUiaInvokeProvider :
+ public QWinRTUiaBaseProvider,
+ public Microsoft::WRL::RuntimeClass<ABI::Windows::UI::Xaml::Automation::Provider::IInvokeProvider>
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(QWinRTUiaInvokeProvider)
+ InspectableClass(L"QWinRTUiaInvokeProvider", BaseTrust);
+
+public:
+ explicit QWinRTUiaInvokeProvider(QAccessible::Id id);
+ virtual ~QWinRTUiaInvokeProvider();
+
+ // IInvokeProvider
+ HRESULT STDMETHODCALLTYPE Invoke() override;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
+
+#endif // QWINRTUIAINVOKEPROVIDER_H
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiamainprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiamainprovider.cpp
new file mode 100644
index 0000000000..99efe27c34
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiamainprovider.cpp
@@ -0,0 +1,779 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiamainprovider.h"
+#include "qwinrtuiaprovidercache.h"
+#include "qwinrtuiavalueprovider.h"
+#include "qwinrtuiarangevalueprovider.h"
+#include "qwinrtuiatextprovider.h"
+#include "qwinrtuiatoggleprovider.h"
+#include "qwinrtuiainvokeprovider.h"
+#include "qwinrtuiaselectionprovider.h"
+#include "qwinrtuiaselectionitemprovider.h"
+#include "qwinrtuiatableprovider.h"
+#include "qwinrtuiatableitemprovider.h"
+#include "qwinrtuiagridprovider.h"
+#include "qwinrtuiagriditemprovider.h"
+#include "qwinrtuiapeervector.h"
+#include "qwinrtuiametadatacache.h"
+#include "qwinrtuiaemptypropertyvalue.h"
+#include "qwinrtuiautils.h"
+
+#include <QCoreApplication>
+#include <QSemaphore>
+#include <QtCore/QLoggingCategory>
+#include <QtCore/qfunctions_winrt.h>
+#include <QtCore/private/qeventdispatcher_winrt_p.h>
+
+using namespace QWinRTUiAutomation;
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::System;
+using namespace ABI::Windows::UI;
+using namespace ABI::Windows::UI::Core;
+using namespace ABI::Windows::UI::Xaml;
+using namespace ABI::Windows::UI::Xaml::Automation;
+using namespace ABI::Windows::UI::Xaml::Automation::Provider;
+using namespace ABI::Windows::UI::Xaml::Automation::Peers;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::Foundation::Collections;
+
+QT_BEGIN_NAMESPACE
+
+QWinRTUiaMainProvider::QWinRTUiaMainProvider(QAccessible::Id id)
+ : QWinRTUiaBaseProvider(id)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ ComPtr<IAutomationPeerFactory> factory;
+ HRESULT hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_Xaml_Automation_Peers_AutomationPeer).Get(), IID_PPV_ARGS(&factory));
+ Q_ASSERT_SUCCEEDED(hr);
+
+ hr = factory->CreateInstance(this, &m_base, &m_core);
+ Q_ASSERT_SUCCEEDED(hr);
+}
+
+QWinRTUiaMainProvider::~QWinRTUiaMainProvider()
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::QueryInterface(REFIID iid, LPVOID *iface)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!iface)
+ return E_POINTER;
+ *iface = nullptr;
+
+ if (iid == IID_IUnknown) {
+ *iface = static_cast<IAutomationPeerOverrides *>(this);
+ AddRef();
+ return S_OK;
+ } else if (iid == IID_IAutomationPeerOverrides) {
+ *iface = static_cast<IAutomationPeerOverrides *>(this);
+ AddRef();
+ return S_OK;
+ } else {
+ return m_base.CopyTo(iid, iface);
+ }
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetIids(ULONG *iidCount, IID **iids)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+ *iidCount = 0;
+ *iids = nullptr;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetRuntimeClassName(HSTRING *className)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+ return qHString(QStringLiteral("QWinRTUiaMainProvider"), className);
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetTrustLevel(TrustLevel *trustLevel)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+ *trustLevel = TrustLevel::BaseTrust;
+ return S_OK;
+}
+
+// Returns a cached instance of the provider for a specific accessible interface.
+QWinRTUiaMainProvider *QWinRTUiaMainProvider::providerForAccessibleId(QAccessible::Id id)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ QWinRTUiaProviderCache *providerCache = QWinRTUiaProviderCache::instance();
+ QWinRTUiaMainProvider *provider = qobject_cast<QWinRTUiaMainProvider *>(providerCache->providerForId(id));
+
+ if (provider) {
+ provider->AddRef();
+ } else {
+ ComPtr<QWinRTUiaMainProvider> p = Make<QWinRTUiaMainProvider>(id);
+ provider = p.Get();
+ provider->AddRef();
+ providerCache->insert(id, provider);
+ }
+ return provider;
+}
+
+// Returns an IIRawElementProviderSimple for a specific accessible interface.
+HRESULT QWinRTUiaMainProvider::rawProviderForAccessibleId(QAccessible::Id elementId,
+ IIRawElementProviderSimple **returnValue)
+{
+ if (!returnValue)
+ return E_INVALIDARG;
+ *returnValue = nullptr;
+
+ if (ComPtr<QWinRTUiaMainProvider> provider = providerForAccessibleId(elementId)) {
+ ComPtr<IAutomationPeer> automationPeer;
+ if (SUCCEEDED(provider.As(&automationPeer))) {
+ ComPtr<IAutomationPeerProtected> automationPeerProtected;
+ if (SUCCEEDED(provider.As(&automationPeerProtected))) {
+ return automationPeerProtected->ProviderFromPeer(automationPeer.Get(), returnValue);
+ }
+ }
+ }
+ return E_FAIL;
+}
+
+// Returns an array of IIRawElementProviderSimple instances for a list of accessible interface ids.
+HRESULT QWinRTUiaMainProvider::rawProviderArrayForAccessibleIdList(const QList<QAccessible::Id> &elementIds,
+ UINT32 *returnValueSize,
+ IIRawElementProviderSimple ***returnValue)
+{
+ if (!returnValueSize || !returnValue)
+ return E_INVALIDARG;
+ *returnValueSize = 0;
+ *returnValue = nullptr;
+
+ QList<IIRawElementProviderSimple *> rawProviderList;
+
+ for (auto elementId : qAsConst(elementIds)) {
+ IIRawElementProviderSimple *rawProvider;
+ if (SUCCEEDED(rawProviderForAccessibleId(elementId, &rawProvider)))
+ rawProviderList.append(rawProvider);
+ }
+
+ if (rawProviderList.size() == 0)
+ return S_OK;
+
+ *returnValue = static_cast<IIRawElementProviderSimple **>(CoTaskMemAlloc(rawProviderList.size() * sizeof(IIRawElementProviderSimple *)));
+ if (!*returnValue) {
+ for (auto rawProvider : qAsConst(rawProviderList))
+ rawProvider->Release();
+ return E_OUTOFMEMORY;
+ }
+
+ int index = 0;
+ for (auto rawProvider : qAsConst(rawProviderList))
+ (*returnValue)[index++] = rawProvider;
+ *returnValueSize = rawProviderList.size();
+ return S_OK;
+}
+
+void QWinRTUiaMainProvider::notifyFocusChange(QAccessibleEvent *event)
+{
+ if (QAccessibleInterface *accessible = event->accessibleInterface()) {
+ QAccessible::Id accid = idForAccessible(accessible);
+ QWinRTUiaMetadataCache::instance()->load(accid);
+ QEventDispatcherWinRT::runOnXamlThread([accid]() {
+ if (ComPtr<QWinRTUiaMainProvider> provider = providerForAccessibleId(accid)) {
+ ComPtr<IAutomationPeer> automationPeer;
+ if (SUCCEEDED(provider->QueryInterface(IID_PPV_ARGS(&automationPeer)))) {
+ automationPeer->RaiseAutomationEvent(AutomationEvents_AutomationFocusChanged);
+ }
+ }
+ return S_OK;
+ }, false);
+ }
+}
+
+void QWinRTUiaMainProvider::notifyStateChange(QAccessibleStateChangeEvent *event)
+{
+ if (QAccessibleInterface *accessible = event->accessibleInterface()) {
+ QAccessible::Id accid = idForAccessible(accessible);
+ QWinRTUiaMetadataCache::instance()->load(accid);
+
+ if (event->changedStates().checked || event->changedStates().checkStateMixed) {
+ // Notifies states changes in checkboxes.
+ if (accessible->role() == QAccessible::CheckBox) {
+ QEventDispatcherWinRT::runOnXamlThread([accid]() {
+ if (ComPtr<QWinRTUiaMainProvider> provider = providerForAccessibleId(accid)) {
+ ComPtr<IAutomationPeer> automationPeer;
+ if (SUCCEEDED(provider->QueryInterface(IID_PPV_ARGS(&automationPeer)))) {
+ ComPtr<ITogglePatternIdentifiersStatics> toggleStatics;
+ if (SUCCEEDED(RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_Xaml_Automation_TogglePatternIdentifiers).Get(), IID_PPV_ARGS(&toggleStatics)))) {
+ ComPtr<IAutomationProperty> toggleStateProperty;
+ if (SUCCEEDED(toggleStatics->get_ToggleStateProperty(&toggleStateProperty))) {
+ ComPtr<QWinRTUiaEmptyPropertyValue> emptyValue = Make<QWinRTUiaEmptyPropertyValue>();
+ // by sending an event with an empty value we force ui automation to refresh its state
+ automationPeer->RaisePropertyChangedEvent(toggleStateProperty.Get(), emptyValue.Get(), emptyValue.Get());
+ }
+ }
+ }
+ }
+ return S_OK;
+ }, false);
+ }
+ }
+ if (event->changedStates().active) {
+ if (accessible->role() == QAccessible::Window) {
+ // Notifies window opened/closed.
+ bool active = accessible->state().active;
+ QEventDispatcherWinRT::runOnXamlThread([accid, active]() {
+ if (ComPtr<QWinRTUiaMainProvider> provider = providerForAccessibleId(accid)) {
+ ComPtr<IAutomationPeer> automationPeer;
+ if (SUCCEEDED(provider->QueryInterface(IID_PPV_ARGS(&automationPeer)))) {
+ if (active) {
+ automationPeer->RaiseAutomationEvent(AutomationEvents_WindowOpened);
+ } else {
+ automationPeer->RaiseAutomationEvent(AutomationEvents_WindowClosed);
+ }
+ }
+ }
+ return S_OK;
+ }, false);
+ }
+ }
+ }
+}
+
+void QWinRTUiaMainProvider::notifyValueChange(QAccessibleValueChangeEvent *event)
+{
+ if (QAccessibleInterface *accessible = event->accessibleInterface()) {
+ QAccessible::Id accid = idForAccessible(accessible);
+ QWinRTUiaMetadataCache::instance()->load(accid);
+ if (QAccessibleValueInterface *valueInterface = accessible->valueInterface()) {
+ // Notifies changes in values of controls supporting the value interface.
+ double value = valueInterface->currentValue().toDouble();
+ QEventDispatcherWinRT::runOnXamlThread([accid, value]() {
+ // For some reason RaisePropertyChangedEvent() does not seem to be
+ // forwarding notifications for any property types except empty,
+ // which would do nothing here. ToDo: find a workaround.
+ return S_OK;
+ }, false);
+ }
+ }
+}
+
+// Notifies changes in text content and selection state of text controls.
+void QWinRTUiaMainProvider::notifyTextChange(QAccessibleEvent *event)
+{
+ if (QAccessibleInterface *accessible = event->accessibleInterface()) {
+ QAccessible::Id accid = idForAccessible(accessible);
+ QWinRTUiaMetadataCache::instance()->load(accid);
+ bool readOnly = accessible->state().readOnly;
+ QAccessible::Event eventType = event->type();
+ if (accessible->textInterface()) {
+ QEventDispatcherWinRT::runOnXamlThread([accid, eventType, readOnly]() {
+ if (ComPtr<QWinRTUiaMainProvider> provider = providerForAccessibleId(accid)) {
+ ComPtr<IAutomationPeer> automationPeer;
+ if (SUCCEEDED(provider->QueryInterface(IID_PPV_ARGS(&automationPeer)))) {
+ if (eventType == QAccessible::TextSelectionChanged) {
+ automationPeer->RaiseAutomationEvent(AutomationEvents_TextPatternOnTextSelectionChanged);
+ } else if (eventType == QAccessible::TextCaretMoved) {
+ if (!readOnly) {
+ automationPeer->RaiseAutomationEvent(AutomationEvents_TextPatternOnTextSelectionChanged);
+ }
+ } else {
+ automationPeer->RaiseAutomationEvent(AutomationEvents_TextPatternOnTextChanged);
+ }
+ }
+ }
+ return S_OK;
+ }, false);
+ }
+ }
+}
+
+// Return providers for specific control patterns
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetPatternCore(PatternInterface patternInterface, IInspectable **returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__ << patternInterface;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ *returnValue = nullptr;
+
+ QAccessibleInterface *accessible = accessibleInterface();
+ if (!accessible)
+ return E_FAIL;
+
+ switch (patternInterface) {
+ case PatternInterface_Text:
+ case PatternInterface_Text2: {
+ // All text controls.
+ if (accessible->textInterface()) {
+ ComPtr<QWinRTUiaTextProvider> provider = Make<QWinRTUiaTextProvider>(id());
+ return provider.CopyTo(returnValue);
+ }
+ break;
+ }
+ case PatternInterface_Value: {
+ // All accessible controls return text(QAccessible::Value) (which may be empty).
+ ComPtr<QWinRTUiaValueProvider> provider = Make<QWinRTUiaValueProvider>(id());
+ return provider.CopyTo(returnValue);
+ }
+ case PatternInterface_RangeValue: {
+ // Controls providing a numeric value within a range (e.g., sliders, scroll bars, dials).
+ if (accessible->valueInterface()) {
+ ComPtr<QWinRTUiaRangeValueProvider> provider = Make<QWinRTUiaRangeValueProvider>(id());
+ return provider.CopyTo(returnValue);
+ }
+ break;
+ }
+ case PatternInterface_Toggle: {
+ // Checkbox controls.
+ if (accessible->role() == QAccessible::CheckBox) {
+ ComPtr<QWinRTUiaToggleProvider> provider = Make<QWinRTUiaToggleProvider>(id());
+ return provider.CopyTo(returnValue);
+ }
+ break;
+ }
+ case PatternInterface_Selection: {
+ // Lists of items.
+ if (accessible->role() == QAccessible::List) {
+ ComPtr<QWinRTUiaSelectionProvider> provider = Make<QWinRTUiaSelectionProvider>(id());
+ return provider.CopyTo(returnValue);
+ }
+ break;
+ }
+ case PatternInterface_SelectionItem: {
+ // Items within a list and radio buttons.
+ if ((accessible->role() == QAccessible::RadioButton)
+ || (accessible->role() == QAccessible::ListItem)) {
+ ComPtr<QWinRTUiaSelectionItemProvider> provider = Make<QWinRTUiaSelectionItemProvider>(id());
+ return provider.CopyTo(returnValue);
+ }
+ break;
+ }
+ case PatternInterface_Table: {
+ // Table/tree.
+ if (accessible->tableInterface()
+ && ((accessible->role() == QAccessible::Table) || (accessible->role() == QAccessible::Tree))) {
+ ComPtr<QWinRTUiaTableProvider> provider = Make<QWinRTUiaTableProvider>(id());
+ return provider.CopyTo(returnValue);
+ }
+ break;
+ }
+ case PatternInterface_TableItem: {
+ // Item within a table/tree.
+ if (accessible->tableCellInterface()
+ && ((accessible->role() == QAccessible::Cell) || (accessible->role() == QAccessible::TreeItem))) {
+ ComPtr<QWinRTUiaTableItemProvider> provider = Make<QWinRTUiaTableItemProvider>(id());
+ return provider.CopyTo(returnValue);
+ }
+ break;
+ }
+ case PatternInterface_Grid: {
+ // Table/tree.
+ if (accessible->tableInterface()
+ && ((accessible->role() == QAccessible::Table) || (accessible->role() == QAccessible::Tree))) {
+ ComPtr<QWinRTUiaGridProvider> provider = Make<QWinRTUiaGridProvider>(id());
+ return provider.CopyTo(returnValue);
+ }
+ break;
+ }
+ case PatternInterface_GridItem: {
+ // Item within a table/tree.
+ if (accessible->tableCellInterface()
+ && ((accessible->role() == QAccessible::Cell) || (accessible->role() == QAccessible::TreeItem))) {
+ ComPtr<QWinRTUiaGridItemProvider> provider = Make<QWinRTUiaGridItemProvider>(id());
+ return provider.CopyTo(returnValue);
+ }
+ break;
+ }
+ case PatternInterface_Invoke: {
+ // Things that have an invokable action (e.g., simple buttons).
+ if (accessible->actionInterface()) {
+ ComPtr<QWinRTUiaInvokeProvider> provider = Make<QWinRTUiaInvokeProvider>(id());
+ return provider.CopyTo(returnValue);
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetAcceleratorKeyCore(HSTRING *returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ return qHString(metadata->accelerator(), returnValue);
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetAccessKeyCore(HSTRING *returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ return qHString(metadata->access(), returnValue);
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetAutomationControlTypeCore(AutomationControlType *returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ *returnValue = roleToControlType(metadata->role());
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetAutomationIdCore(HSTRING *returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ return qHString(metadata->automationId(), returnValue);
+}
+
+// Returns the bounding rectangle for the accessible control.
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetBoundingRectangleCore(ABI::Windows::Foundation::Rect *returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+
+ QRect rect = metadata->boundingRect();
+ returnValue->X = rect.x();
+ returnValue->Y = rect.y();
+ returnValue->Width = rect.width();
+ returnValue->Height = rect.height();
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetChildrenCore(IVector<AutomationPeer *> **returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ *returnValue = nullptr;
+
+ auto accid = id();
+ auto children = QSharedPointer<QList<QAccessible::Id>>(new QList<QAccessible::Id>);
+ auto ptrChildren = new QSharedPointer<QList<QAccessible::Id>>(children);
+
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrChildren]() {
+ if (QAccessibleInterface *accessible = accessibleForId(accid)) {
+ int childCount = accessible->childCount();
+ for (int i = 0; i < childCount; ++i) {
+ if (QAccessibleInterface *childAcc = accessible->child(i)) {
+ QAccessible::Id childId = idForAccessible(childAcc);
+ QWinRTUiaMetadataCache::instance()->load(childId);
+ (*ptrChildren)->append(childId);
+ }
+ }
+ }
+ delete ptrChildren;
+ return S_OK;
+ }))) {
+ return E_FAIL;
+ }
+
+ ComPtr<IVector<AutomationPeer *>> peerVector = Make<QWinRTUiaPeerVector>();
+
+ for (auto childId : qAsConst(*children)) {
+ if (ComPtr<QWinRTUiaMainProvider> provider = providerForAccessibleId(childId)) {
+ IAutomationPeer *peer;
+ if (SUCCEEDED(provider.CopyTo(&peer)))
+ peerVector->Append(peer);
+ }
+ }
+ return peerVector.CopyTo(returnValue);
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetClassNameCore(HSTRING *returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ return qHString(metadata->className(), returnValue);
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetClickablePointCore(ABI::Windows::Foundation::Point *returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetHelpTextCore(HSTRING *returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ return qHString(metadata->help(), returnValue);
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetItemStatusCore(HSTRING *returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetItemTypeCore(HSTRING *returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetLabeledByCore(IAutomationPeer **returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetLocalizedControlTypeCore(HSTRING *returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetNameCore(HSTRING *returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ return qHString(metadata->controlName(), returnValue);
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetOrientationCore(AutomationOrientation *returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ *returnValue = AutomationOrientation_None;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::HasKeyboardFocusCore(boolean *returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ *returnValue = (metadata->state().focused != 0);
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::IsContentElementCore(boolean *returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ *returnValue = true;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::IsControlElementCore(boolean *returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ *returnValue = true;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::IsEnabledCore(boolean *returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ *returnValue = (metadata->state().disabled == 0);
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::IsKeyboardFocusableCore(boolean *returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ *returnValue = (metadata->state().focusable != 0);
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::IsOffscreenCore(boolean *returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ *returnValue = false;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::IsPasswordCore(boolean *returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ *returnValue = (metadata->role() == QAccessible::EditableText) && (metadata->state().passwordEdit != 0);
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::IsRequiredForFormCore(boolean *returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ *returnValue = false;
+ return S_OK;
+}
+
+// Sets focus to the control.
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::SetFocusCore()
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ QAccessibleInterface *accessible = accessibleInterface();
+ if (!accessible)
+ return E_FAIL;
+
+ QAccessibleActionInterface *actionInterface = accessible->actionInterface();
+ if (!actionInterface)
+ return E_FAIL;
+
+ QEventDispatcherWinRT::runOnMainThread([actionInterface]() {
+ actionInterface->doAction(QAccessibleActionInterface::setFocusAction());
+ return S_OK;
+ });
+ return S_OK;
+}
+
+// Returns a provider for the UI element present at the specified screen coordinates.
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetPeerFromPointCore(ABI::Windows::Foundation::Point point, IAutomationPeer **returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ *returnValue = nullptr;
+
+ // Scale coordinates from High DPI screens?
+
+ auto accid = id();
+ auto elementId = QSharedPointer<QAccessible::Id>(new QAccessible::Id(0));
+ auto ptrElementId = new QSharedPointer<QAccessible::Id>(elementId);
+
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementId, point]() {
+ // Controls can be embedded within grouping elements. By default returns the innermost control.
+ QAccessibleInterface *target = accessibleForId(accid);
+ while (QAccessibleInterface *tmpacc = target->childAt(point.X, point.Y)) {
+ target = tmpacc;
+ // For accessibility tools it may be better to return the text element instead of its subcomponents.
+ if (target->textInterface()) break;
+ }
+ **ptrElementId = idForAccessible(target);
+ QWinRTUiaMetadataCache::instance()->load(**ptrElementId);
+ delete ptrElementId;
+ return S_OK;
+ }))) {
+ return E_FAIL;
+ }
+
+ if (ComPtr<QWinRTUiaMainProvider> provider = providerForAccessibleId(*elementId))
+ return provider.CopyTo(returnValue);
+ return E_FAIL;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetLiveSettingCore(AutomationLiveSetting *returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ return E_NOTIMPL;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
+
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiamainprovider.h b/src/plugins/platforms/winrt/uiautomation/qwinrtuiamainprovider.h
new file mode 100644
index 0000000000..3ae9d2759e
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiamainprovider.h
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTUIAMAINPROVIDER_H
+#define QWINRTUIAMAINPROVIDER_H
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiabaseprovider.h"
+
+#include <QtCore/qglobal.h>
+#include <QtCore/QPointer>
+#include <QtCore/QSharedPointer>
+#include <QtGui/QAccessible>
+#include <QtGui/QAccessibleInterface>
+
+#include <wrl.h>
+#include <windows.ui.xaml.h>
+
+QT_BEGIN_NAMESPACE
+
+// The main WinRT UI Automation class.
+class QWinRTUiaMainProvider:
+ public QWinRTUiaBaseProvider,
+ public Microsoft::WRL::RuntimeClass<ABI::Windows::UI::Xaml::Automation::Peers::IAutomationPeerOverrides>
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(QWinRTUiaMainProvider)
+
+public:
+ explicit QWinRTUiaMainProvider(QAccessible::Id id);
+ virtual ~QWinRTUiaMainProvider();
+ static QWinRTUiaMainProvider *providerForAccessibleId(QAccessible::Id id);
+ static HRESULT rawProviderForAccessibleId(QAccessible::Id elementId, ABI::Windows::UI::Xaml::Automation::Provider::IIRawElementProviderSimple **returnValue);
+ static HRESULT rawProviderArrayForAccessibleIdList(const QList<QAccessible::Id> &elementIds, UINT32 *returnValueSize, ABI::Windows::UI::Xaml::Automation::Provider::IIRawElementProviderSimple ***returnValue);
+ static void notifyFocusChange(QAccessibleEvent *event);
+ static void notifyStateChange(QAccessibleStateChangeEvent *event);
+ static void notifyValueChange(QAccessibleValueChangeEvent *event);
+ static void notifyTextChange(QAccessibleEvent *event);
+
+ // IUnknown
+ HRESULT STDMETHODCALLTYPE QueryInterface(REFIID id, LPVOID *iface) override;
+
+ // IInspectable
+ HRESULT STDMETHODCALLTYPE GetIids(ULONG *iidCount, IID **iids) override;
+ HRESULT STDMETHODCALLTYPE GetRuntimeClassName(HSTRING *className) override;
+ HRESULT STDMETHODCALLTYPE GetTrustLevel(TrustLevel *trustLevel) override;
+
+ // IAutomationPeerOverrides
+ HRESULT STDMETHODCALLTYPE GetPatternCore(ABI::Windows::UI::Xaml::Automation::Peers::PatternInterface patternInterface, IInspectable **returnValue) override;
+ HRESULT STDMETHODCALLTYPE GetAcceleratorKeyCore(HSTRING *returnValue) override;
+ HRESULT STDMETHODCALLTYPE GetAccessKeyCore(HSTRING *returnValue) override;
+ HRESULT STDMETHODCALLTYPE GetAutomationControlTypeCore(ABI::Windows::UI::Xaml::Automation::Peers::AutomationControlType *returnValue) override;
+ HRESULT STDMETHODCALLTYPE GetAutomationIdCore(HSTRING *returnValue) override;
+ HRESULT STDMETHODCALLTYPE GetBoundingRectangleCore(ABI::Windows::Foundation::Rect *returnValue) override;
+ HRESULT STDMETHODCALLTYPE GetChildrenCore(ABI::Windows::Foundation::Collections::IVector<ABI::Windows::UI::Xaml::Automation::Peers::AutomationPeer*> **returnValue) override;
+ HRESULT STDMETHODCALLTYPE GetClassNameCore(HSTRING *returnValue) override;
+ HRESULT STDMETHODCALLTYPE GetClickablePointCore(ABI::Windows::Foundation::Point *returnValue) override;
+ HRESULT STDMETHODCALLTYPE GetHelpTextCore(HSTRING *returnValue) override;
+ HRESULT STDMETHODCALLTYPE GetItemStatusCore(HSTRING *returnValue) override;
+ HRESULT STDMETHODCALLTYPE GetItemTypeCore(HSTRING *returnValue) override;
+ HRESULT STDMETHODCALLTYPE GetLabeledByCore(ABI::Windows::UI::Xaml::Automation::Peers::IAutomationPeer **returnValue) override;
+ HRESULT STDMETHODCALLTYPE GetLocalizedControlTypeCore(HSTRING *returnValue) override;
+ HRESULT STDMETHODCALLTYPE GetNameCore(HSTRING *returnValue) override;
+ HRESULT STDMETHODCALLTYPE GetOrientationCore(ABI::Windows::UI::Xaml::Automation::Peers::AutomationOrientation *returnValue) override;
+ HRESULT STDMETHODCALLTYPE HasKeyboardFocusCore(boolean *returnValue) override;
+ HRESULT STDMETHODCALLTYPE IsContentElementCore(boolean *returnValue) override;
+ HRESULT STDMETHODCALLTYPE IsControlElementCore(boolean *returnValue) override;
+ HRESULT STDMETHODCALLTYPE IsEnabledCore(boolean *returnValue) override;
+ HRESULT STDMETHODCALLTYPE IsKeyboardFocusableCore(boolean *returnValue) override;
+ HRESULT STDMETHODCALLTYPE IsOffscreenCore(boolean *returnValue) override;
+ HRESULT STDMETHODCALLTYPE IsPasswordCore(boolean *returnValue) override;
+ HRESULT STDMETHODCALLTYPE IsRequiredForFormCore(boolean *returnValue) override;
+ HRESULT STDMETHODCALLTYPE SetFocusCore() override;
+ HRESULT STDMETHODCALLTYPE GetPeerFromPointCore(ABI::Windows::Foundation::Point point, ABI::Windows::UI::Xaml::Automation::Peers::IAutomationPeer **returnValue) override;
+ HRESULT STDMETHODCALLTYPE GetLiveSettingCore(ABI::Windows::UI::Xaml::Automation::Peers::AutomationLiveSetting *returnValue) override;
+
+private:
+ Microsoft::WRL::ComPtr<ABI::Windows::UI::Xaml::Automation::Peers::IAutomationPeerOverrides> m_base;
+ Microsoft::WRL::ComPtr<ABI::Windows::UI::Xaml::Automation::Peers::IAutomationPeer> m_core;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
+
+#endif // QWINRTUIAMAINPROVIDER_H
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiametadatacache.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiametadatacache.cpp
new file mode 100644
index 0000000000..442ff184a8
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiametadatacache.cpp
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiametadatacache.h"
+#include "qwinrtuiautils.h"
+
+#include <QtCore/QLoggingCategory>
+#include <QtCore/private/qeventdispatcher_winrt_p.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace QWinRTUiAutomation;
+
+// Private constructor
+QWinRTUiaMetadataCache::QWinRTUiaMetadataCache()
+{
+}
+
+// shared instance
+QWinRTUiaMetadataCache *QWinRTUiaMetadataCache::instance()
+{
+ static QWinRTUiaMetadataCache metadataCache;
+ return &metadataCache;
+}
+
+// Returns the cached metadata associated with the ID, or an instance with default values.
+QSharedPointer<QWinRTUiaControlMetadata> QWinRTUiaMetadataCache::metadataForId(QAccessible::Id id)
+{
+ QSharedPointer<QWinRTUiaControlMetadata> metadata;
+
+ m_mutex.lock();
+ if (m_metadataTable.contains(id))
+ metadata = m_metadataTable[id];
+ else
+ metadata = QSharedPointer<QWinRTUiaControlMetadata>(new QWinRTUiaControlMetadata);
+ m_mutex.unlock();
+ return metadata;
+}
+
+// Caches metadata from the accessibility framework within the main thread.
+bool QWinRTUiaMetadataCache::load(QAccessible::Id id)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([id]() {
+ QWinRTUiaMetadataCache::instance()->insert(id, QSharedPointer<QWinRTUiaControlMetadata>(new QWinRTUiaControlMetadata(id)));
+ return S_OK;
+ }))) {
+ return false;
+ }
+ return true;
+}
+
+// Inserts metadata in the cache and associates it with an accessibility ID.
+void QWinRTUiaMetadataCache::insert(QAccessible::Id id, const QSharedPointer<QWinRTUiaControlMetadata> &metadata)
+{
+ m_mutex.lock();
+ m_metadataTable[id] = metadata;
+ m_mutex.unlock();
+}
+
+// Removes metadata with a given id from the cache.
+void QWinRTUiaMetadataCache::remove(QAccessible::Id id)
+{
+ m_mutex.lock();
+ m_metadataTable.remove(id);
+ m_mutex.unlock();
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
+
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiametadatacache.h b/src/plugins/platforms/winrt/uiautomation/qwinrtuiametadatacache.h
new file mode 100644
index 0000000000..2d68d1b654
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiametadatacache.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTUIAMETADATACACHE_H
+#define QWINRTUIAMETADATACACHE_H
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiacontrolmetadata.h"
+
+#include <QtCore/QHash>
+#include <QtCore/QMutex>
+#include <QtGui/QAccessible>
+#include <QtGui/QAccessibleInterface>
+
+QT_BEGIN_NAMESPACE
+
+// Singleton used to cache metadata using the accessibility ID as the key.
+class QWinRTUiaMetadataCache : public QObject
+{
+ QWinRTUiaMetadataCache();
+ Q_OBJECT
+public:
+ static QWinRTUiaMetadataCache *instance();
+ QSharedPointer<QWinRTUiaControlMetadata> metadataForId(QAccessible::Id id);
+ void insert(QAccessible::Id id, const QSharedPointer<QWinRTUiaControlMetadata> &metadata);
+ void remove(QAccessible::Id id);
+ bool load(QAccessible::Id id);
+
+private:
+ QHash<QAccessible::Id, QSharedPointer<QWinRTUiaControlMetadata>> m_metadataTable;
+ QMutex m_mutex;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
+
+#endif // QWINRTUIAMETADATACACHE_H
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiapeervector.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiapeervector.cpp
new file mode 100644
index 0000000000..e3d6bcae4b
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiapeervector.cpp
@@ -0,0 +1,149 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiapeervector.h"
+#include "qwinrtuiautils.h"
+
+using namespace ABI::Windows::UI::Xaml::Automation::Peers;
+using namespace ABI::Windows::Foundation::Collections;
+
+QT_BEGIN_NAMESPACE
+
+HRESULT QWinRTUiaPeerVector::GetAt(quint32 index, IAutomationPeer **item)
+{
+ if (index >= quint32(m_impl.size()))
+ return E_FAIL;
+ if ((*item = m_impl.at(index)))
+ (*item)->AddRef();
+ return S_OK;
+}
+
+HRESULT QWinRTUiaPeerVector::get_Size(quint32 *size)
+{
+ *size = m_impl.size();
+ return S_OK;
+}
+
+HRESULT QWinRTUiaPeerVector::GetView(IVectorView<AutomationPeer *> **view)
+{
+ *view = nullptr;
+ return E_NOTIMPL;
+}
+
+HRESULT QWinRTUiaPeerVector::IndexOf(IAutomationPeer *value, quint32 *index, boolean *found)
+{
+ int idx = m_impl.indexOf(value);
+ if (idx > -1) {
+ *index = quint32(idx);
+ *found = true;
+ } else {
+ *found = false;
+ }
+ return S_OK;
+}
+
+HRESULT QWinRTUiaPeerVector::SetAt(quint32 index, IAutomationPeer *item)
+{
+ if (index >= quint32(m_impl.size()))
+ return E_FAIL;
+ if (IAutomationPeer *elem = m_impl.at(index)) {
+ if (elem == item)
+ return S_OK;
+ else
+ elem->Release();
+ }
+ if (item)
+ item->AddRef();
+ m_impl[index] = item;
+ return S_OK;
+}
+
+HRESULT QWinRTUiaPeerVector::InsertAt(quint32 index, IAutomationPeer *item)
+{
+ if (index >= quint32(m_impl.size()))
+ return E_FAIL;
+ if (item)
+ item->AddRef();
+ m_impl.insert(index, item);
+ return S_OK;
+}
+
+HRESULT QWinRTUiaPeerVector::RemoveAt(quint32 index)
+{
+ if (index >= quint32(m_impl.size()))
+ return E_FAIL;
+ if (IAutomationPeer *elem = m_impl.at(index))
+ elem->Release();
+ m_impl.remove(index);
+ return S_OK;
+}
+
+HRESULT QWinRTUiaPeerVector::Append(IAutomationPeer *item)
+{
+ if (item)
+ item->AddRef();
+ m_impl.append(item);
+ return S_OK;
+}
+
+HRESULT QWinRTUiaPeerVector::RemoveAtEnd()
+{
+ if (m_impl.size() == 0)
+ return E_FAIL;
+ if (IAutomationPeer *elem = m_impl.last())
+ elem->Release();
+ m_impl.removeLast();
+ return S_OK;
+}
+
+HRESULT QWinRTUiaPeerVector::Clear()
+{
+ for (auto elem : qAsConst(m_impl))
+ if (elem)
+ elem->Release();
+ m_impl.clear();
+ return S_OK;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiapeervector.h b/src/plugins/platforms/winrt/uiautomation/qwinrtuiapeervector.h
new file mode 100644
index 0000000000..265526de09
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiapeervector.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTUIAPEERVECTOR_H
+#define QWINRTUIAPEERVECTOR_H
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include <QtCore/QString>
+#include <QtCore/qt_windows.h>
+#include <QtGui/QAccessible>
+#include <QtGui/QAccessibleInterface>
+#include <QtGui/QWindow>
+#include <QVector>
+
+#include <wrl.h>
+#include <windows.ui.xaml.h>
+
+QT_BEGIN_NAMESPACE
+
+// Implements IVector<AutomationPeer *>
+class QWinRTUiaPeerVector : public Microsoft::WRL::RuntimeClass<ABI::Windows::Foundation::Collections::IVector<ABI::Windows::UI::Xaml::Automation::Peers::AutomationPeer *>>
+{
+public:
+ HRESULT STDMETHODCALLTYPE GetAt(quint32 index, ABI::Windows::UI::Xaml::Automation::Peers::IAutomationPeer **item) override;
+ HRESULT STDMETHODCALLTYPE get_Size(quint32 *size) override;
+ HRESULT STDMETHODCALLTYPE GetView(ABI::Windows::Foundation::Collections::IVectorView<ABI::Windows::UI::Xaml::Automation::Peers::AutomationPeer *> **view) override;
+ HRESULT STDMETHODCALLTYPE IndexOf(ABI::Windows::UI::Xaml::Automation::Peers::IAutomationPeer *value, quint32 *index, boolean *found) override;
+ HRESULT STDMETHODCALLTYPE SetAt(quint32 index, ABI::Windows::UI::Xaml::Automation::Peers::IAutomationPeer *item) override;
+ HRESULT STDMETHODCALLTYPE InsertAt(quint32 index, ABI::Windows::UI::Xaml::Automation::Peers::IAutomationPeer *item) override;
+ HRESULT STDMETHODCALLTYPE RemoveAt(quint32 index) override;
+ HRESULT STDMETHODCALLTYPE Append(ABI::Windows::UI::Xaml::Automation::Peers::IAutomationPeer *item) override;
+ HRESULT STDMETHODCALLTYPE RemoveAtEnd() override;
+ HRESULT STDMETHODCALLTYPE Clear() override;
+private:
+ QVector<ABI::Windows::UI::Xaml::Automation::Peers::IAutomationPeer *> m_impl;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
+
+#endif // QWINRTUIAPEERVECTOR_H
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiaprovidercache.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiaprovidercache.cpp
new file mode 100644
index 0000000000..06ff094c45
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiaprovidercache.cpp
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiaprovidercache.h"
+
+QT_BEGIN_NAMESPACE
+
+// Private constructor
+QWinRTUiaProviderCache::QWinRTUiaProviderCache()
+{
+}
+
+// shared instance
+QWinRTUiaProviderCache *QWinRTUiaProviderCache::instance()
+{
+ static QWinRTUiaProviderCache providerCache;
+ return &providerCache;
+}
+
+// Returns the provider instance associated with the ID, or nullptr.
+QWinRTUiaBaseProvider *QWinRTUiaProviderCache::providerForId(QAccessible::Id id) const
+{
+ return m_providerTable.value(id);
+}
+
+// Inserts a provider in the cache and associates it with an accessibility ID.
+void QWinRTUiaProviderCache::insert(QAccessible::Id id, QWinRTUiaBaseProvider *provider)
+{
+ remove(id);
+ if (provider) {
+ m_providerTable[id] = provider;
+ m_inverseTable[provider] = id;
+ // Connects the destroyed signal to our slot, to remove deleted objects from the cache.
+ QObject::connect(provider, &QObject::destroyed, this, &QWinRTUiaProviderCache::objectDestroyed);
+ }
+}
+
+// Removes deleted provider objects from the cache.
+void QWinRTUiaProviderCache::objectDestroyed(QObject *obj)
+{
+ // We have to use the inverse table to map the object address back to its ID,
+ // since at this point (called from QObject destructor), it has already been
+ // partially destroyed and we cannot treat it as a provider.
+ auto it = m_inverseTable.find(obj);
+ if (it != m_inverseTable.end()) {
+ m_providerTable.remove(*it);
+ m_inverseTable.remove(obj);
+ }
+}
+
+// Removes a provider with a given id from the cache.
+void QWinRTUiaProviderCache::remove(QAccessible::Id id)
+{
+ m_inverseTable.remove(m_providerTable.value(id));
+ m_providerTable.remove(id);
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiaprovidercache.h b/src/plugins/platforms/winrt/uiautomation/qwinrtuiaprovidercache.h
new file mode 100644
index 0000000000..393ef7d562
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiaprovidercache.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTUIAPROVIDERCACHE_H
+#define QWINRTUIAPROVIDERCACHE_H
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiabaseprovider.h"
+
+#include <QtCore/QHash>
+#include <QtGui/QAccessible>
+#include <QtGui/QAccessibleInterface>
+
+QT_BEGIN_NAMESPACE
+
+// Singleton used to cache provider instances using the accessibility ID as the key.
+class QWinRTUiaProviderCache : public QObject
+{
+ QWinRTUiaProviderCache();
+ Q_OBJECT
+public:
+ static QWinRTUiaProviderCache *instance();
+ QWinRTUiaBaseProvider *providerForId(QAccessible::Id id) const;
+ void insert(QAccessible::Id id, QWinRTUiaBaseProvider *provider);
+ void remove(QAccessible::Id id);
+
+private Q_SLOTS:
+ void objectDestroyed(QObject *obj);
+
+private:
+ QHash<QAccessible::Id, QWinRTUiaBaseProvider *> m_providerTable;
+ QHash<QObject *, QAccessible::Id> m_inverseTable;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
+
+#endif // QWINRTUIAPROVIDERCACHE_H
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiarangevalueprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiarangevalueprovider.cpp
new file mode 100644
index 0000000000..4ac59c890a
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiarangevalueprovider.cpp
@@ -0,0 +1,167 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiarangevalueprovider.h"
+#include "qwinrtuiametadatacache.h"
+#include "qwinrtuiautils.h"
+
+#include <QtGui/QAccessible>
+#include <QtGui/QAccessibleInterface>
+#include <QtCore/QLoggingCategory>
+#include <QtCore/QString>
+#include <QtCore/private/qeventdispatcher_winrt_p.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace QWinRTUiAutomation;
+using namespace ABI::Windows::UI::Xaml::Automation;
+using namespace ABI::Windows::UI::Xaml::Automation::Provider;
+
+QWinRTUiaRangeValueProvider::QWinRTUiaRangeValueProvider(QAccessible::Id id) :
+ QWinRTUiaBaseProvider(id)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+}
+
+QWinRTUiaRangeValueProvider::~QWinRTUiaRangeValueProvider()
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaRangeValueProvider::get_IsReadOnly(boolean *value)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!value)
+ return E_INVALIDARG;
+
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ *value = (metadata->state().readOnly != 0);
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaRangeValueProvider::get_LargeChange(DOUBLE *value)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!value)
+ return E_INVALIDARG;
+
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ *value = metadata->minimumStepSize();
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaRangeValueProvider::get_Maximum(DOUBLE *value)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!value)
+ return E_INVALIDARG;
+
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ *value = metadata->maximumValue();
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaRangeValueProvider::get_Minimum(DOUBLE *value)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!value)
+ return E_INVALIDARG;
+
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ *value = metadata->minimumValue();
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaRangeValueProvider::get_SmallChange(DOUBLE *value)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!value)
+ return E_INVALIDARG;
+
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ *value = metadata->minimumStepSize();
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaRangeValueProvider::get_Value(DOUBLE *value)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!value)
+ return E_INVALIDARG;
+
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ *value = metadata->currentValue();
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaRangeValueProvider::SetValue(DOUBLE value)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ auto accid = id();
+
+ QEventDispatcherWinRT::runOnMainThread([accid, value]() {
+ if (QAccessibleInterface *accessible = accessibleForId(accid)) {
+ if (QAccessibleValueInterface *valueInterface = accessible->valueInterface()) {
+ double minimum = valueInterface->minimumValue().toDouble();
+ double maximum = valueInterface->maximumValue().toDouble();
+ if ((value >= minimum) && (value <= maximum)) {
+ valueInterface->setCurrentValue(QVariant(value));
+ }
+ }
+ }
+ QWinRTUiaMetadataCache::instance()->load(accid);
+ return S_OK;
+ }, 0);
+
+ return S_OK;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiarangevalueprovider.h b/src/plugins/platforms/winrt/uiautomation/qwinrtuiarangevalueprovider.h
new file mode 100644
index 0000000000..4e98959526
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiarangevalueprovider.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTUIARANGEVALUEPROVIDER_H
+#define QWINRTUIARANGEVALUEPROVIDER_H
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiabaseprovider.h"
+
+#include <wrl.h>
+#include <windows.ui.xaml.h>
+
+QT_BEGIN_NAMESPACE
+
+// Implements the Range Value control pattern provider.
+class QWinRTUiaRangeValueProvider :
+ public QWinRTUiaBaseProvider,
+ public Microsoft::WRL::RuntimeClass<ABI::Windows::UI::Xaml::Automation::Provider::IRangeValueProvider>
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(QWinRTUiaRangeValueProvider)
+ InspectableClass(L"QWinRTUiaRangeValueProvider", BaseTrust);
+
+public:
+ explicit QWinRTUiaRangeValueProvider(QAccessible::Id id);
+ virtual ~QWinRTUiaRangeValueProvider();
+
+ // IRangeValueProvider
+ HRESULT STDMETHODCALLTYPE get_IsReadOnly(boolean *value) override;
+ HRESULT STDMETHODCALLTYPE get_LargeChange(DOUBLE *value) override;
+ HRESULT STDMETHODCALLTYPE get_Maximum(DOUBLE *value) override;
+ HRESULT STDMETHODCALLTYPE get_Minimum(DOUBLE *value) override;
+ HRESULT STDMETHODCALLTYPE get_SmallChange(DOUBLE *value) override;
+ HRESULT STDMETHODCALLTYPE get_Value(DOUBLE *value) override;
+ HRESULT STDMETHODCALLTYPE SetValue(DOUBLE value) override;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
+
+#endif // QWINRTUIARANGEVALUEPROVIDER_H
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionitemprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionitemprovider.cpp
new file mode 100644
index 0000000000..9bc88272ba
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionitemprovider.cpp
@@ -0,0 +1,214 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiaselectionitemprovider.h"
+#include "qwinrtuiamainprovider.h"
+#include "qwinrtuiametadatacache.h"
+#include "qwinrtuiautils.h"
+
+#include <QtGui/QAccessible>
+#include <QtGui/QAccessibleInterface>
+#include <QtCore/QLoggingCategory>
+#include <QtCore/QString>
+#include <QtCore/private/qeventdispatcher_winrt_p.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace QWinRTUiAutomation;
+using namespace ABI::Windows::UI::Xaml::Automation;
+using namespace ABI::Windows::UI::Xaml::Automation::Provider;
+using namespace ABI::Windows::UI::Xaml::Automation::Peers;
+
+QWinRTUiaSelectionItemProvider::QWinRTUiaSelectionItemProvider(QAccessible::Id id) :
+ QWinRTUiaBaseProvider(id)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+}
+
+QWinRTUiaSelectionItemProvider::~QWinRTUiaSelectionItemProvider()
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+}
+
+// Returns true if element is currently selected.
+HRESULT STDMETHODCALLTYPE QWinRTUiaSelectionItemProvider::get_IsSelected(boolean *value)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!value)
+ return E_INVALIDARG;
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ if (metadata->role() == QAccessible::RadioButton)
+ *value = metadata->state().checked;
+ else
+ *value = metadata->state().selected;
+ return S_OK;
+}
+
+// Returns the provider for the container element (e.g., the list for the list item).
+HRESULT STDMETHODCALLTYPE QWinRTUiaSelectionItemProvider::get_SelectionContainer(IIRawElementProviderSimple **value)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!value)
+ return E_INVALIDARG;
+ *value = nullptr;
+
+ auto accid = id();
+ auto elementId = QSharedPointer<QAccessible::Id>(new QAccessible::Id(0));
+ auto ptrElementId = new QSharedPointer<QAccessible::Id>(elementId);
+
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementId]() {
+ if (QAccessibleInterface *accessible = accessibleForId(accid)) {
+ // Radio buttons do not require a container.
+ if (accessible->role() == QAccessible::ListItem) {
+ if (QAccessibleInterface *parent = accessible->parent()) {
+ if (parent->role() == QAccessible::List) {
+ **ptrElementId = idForAccessible(parent);
+ }
+ }
+ }
+ }
+ delete ptrElementId;
+ return S_OK;
+ }))) {
+ return E_FAIL;
+ }
+
+ if (!*elementId)
+ return S_OK;
+
+ return QWinRTUiaMainProvider::rawProviderForAccessibleId(*elementId, value);
+}
+
+// Adds the element to the list of selected elements.
+HRESULT STDMETHODCALLTYPE QWinRTUiaSelectionItemProvider::AddToSelection()
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ auto accid = id();
+
+ QEventDispatcherWinRT::runOnMainThread([accid]() {
+ if (QAccessibleInterface *accessible = accessibleForId(accid)) {
+ if (QAccessibleActionInterface *actionInterface = accessible->actionInterface()) {
+ if (accessible->role() == QAccessible::RadioButton) {
+ // For radio buttons we invoke the selection action.
+ actionInterface->doAction(QAccessibleActionInterface::pressAction());
+ } else {
+ // Toggle list item if not already selected.
+ if (!accessible->state().selected) {
+ actionInterface->doAction(QAccessibleActionInterface::toggleAction());
+ }
+ }
+ }
+ }
+ QWinRTUiaMetadataCache::instance()->load(accid);
+ return S_OK;
+ }, 0);
+ return S_OK;
+}
+
+// Removes a list item from selection.
+HRESULT STDMETHODCALLTYPE QWinRTUiaSelectionItemProvider::RemoveFromSelection()
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ auto accid = id();
+
+ QEventDispatcherWinRT::runOnMainThread([accid]() {
+ if (QAccessibleInterface *accessible = accessibleForId(accid)) {
+ if (QAccessibleActionInterface *actionInterface = accessible->actionInterface()) {
+ if (accessible->role() != QAccessible::RadioButton) {
+ if (accessible->state().selected) {
+ actionInterface->doAction(QAccessibleActionInterface::toggleAction());
+ }
+ }
+ }
+ }
+ QWinRTUiaMetadataCache::instance()->load(accid);
+ return S_OK;
+ }, 0);
+ return S_OK;
+}
+
+// Selects the element (deselecting all others).
+HRESULT STDMETHODCALLTYPE QWinRTUiaSelectionItemProvider::Select()
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ auto accid = id();
+
+ QEventDispatcherWinRT::runOnMainThread([accid]() {
+ if (QAccessibleInterface *accessible = accessibleForId(accid)) {
+ if (QAccessibleActionInterface *actionInterface = accessible->actionInterface()) {
+ if (accessible->role() == QAccessible::RadioButton) {
+ // For radio buttons we just invoke the selection action; others are automatically deselected.
+ actionInterface->doAction(QAccessibleActionInterface::pressAction());
+ } else {
+ // Toggle list item if not already selected. It must be done first to support all selection modes.
+ if (!accessible->state().selected) {
+ actionInterface->doAction(QAccessibleActionInterface::toggleAction());
+ }
+ // Toggle selected siblings.
+ if (QAccessibleInterface *parent = accessible->parent()) {
+ for (int i = 0; i < parent->childCount(); ++i) {
+ if (QAccessibleInterface *sibling = parent->child(i)) {
+ if ((sibling != accessible) && (sibling->state().selected)) {
+ if (QAccessibleActionInterface *siblingAction = sibling->actionInterface()) {
+ siblingAction->doAction(QAccessibleActionInterface::toggleAction());
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ QWinRTUiaMetadataCache::instance()->load(accid);
+ return S_OK;
+ }, 0);
+ return S_OK;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionitemprovider.h b/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionitemprovider.h
new file mode 100644
index 0000000000..1b3cce7495
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionitemprovider.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTUIASELECTIONITEMPROVIDER_H
+#define QWINRTUIASELECTIONITEMPROVIDER_H
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiabaseprovider.h"
+
+#include <wrl.h>
+#include <windows.ui.xaml.h>
+
+QT_BEGIN_NAMESPACE
+
+// Implements the Selection Item control pattern provider. Used for List items and radio buttons.
+class QWinRTUiaSelectionItemProvider :
+ public QWinRTUiaBaseProvider,
+ public Microsoft::WRL::RuntimeClass<ABI::Windows::UI::Xaml::Automation::Provider::ISelectionItemProvider>
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(QWinRTUiaSelectionItemProvider)
+ InspectableClass(L"QWinRTUiaSelectionItemProvider", BaseTrust);
+
+public:
+ explicit QWinRTUiaSelectionItemProvider(QAccessible::Id id);
+ virtual ~QWinRTUiaSelectionItemProvider();
+
+ // ISelectionItemProvider
+ HRESULT STDMETHODCALLTYPE get_IsSelected(boolean *value) override;
+ HRESULT STDMETHODCALLTYPE get_SelectionContainer(ABI::Windows::UI::Xaml::Automation::Provider::IIRawElementProviderSimple **value) override;
+ HRESULT STDMETHODCALLTYPE AddToSelection() override;
+ HRESULT STDMETHODCALLTYPE RemoveFromSelection() override;
+ HRESULT STDMETHODCALLTYPE Select() override;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
+
+#endif // QWINRTUIASELECTIONITEMPROVIDER_H
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionprovider.cpp
new file mode 100644
index 0000000000..9e61a8df61
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionprovider.cpp
@@ -0,0 +1,158 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiaselectionprovider.h"
+#include "qwinrtuiametadatacache.h"
+#include "qwinrtuiamainprovider.h"
+#include "qwinrtuiautils.h"
+
+#include <QtGui/QAccessible>
+#include <QtGui/QAccessibleInterface>
+#include <QtCore/QLoggingCategory>
+#include <QtCore/QString>
+#include <QtCore/private/qeventdispatcher_winrt_p.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace QWinRTUiAutomation;
+using namespace ABI::Windows::UI::Xaml::Automation;
+using namespace ABI::Windows::UI::Xaml::Automation::Provider;
+using namespace ABI::Windows::UI::Xaml::Automation::Peers;
+
+QWinRTUiaSelectionProvider::QWinRTUiaSelectionProvider(QAccessible::Id id) :
+ QWinRTUiaBaseProvider(id)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+}
+
+QWinRTUiaSelectionProvider::~QWinRTUiaSelectionProvider()
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaSelectionProvider::get_CanSelectMultiple(boolean *value)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!value)
+ return E_INVALIDARG;
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ *value = (metadata->state().multiSelectable != 0);
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaSelectionProvider::get_IsSelectionRequired(boolean *value)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!value)
+ return E_INVALIDARG;
+ *value = false;
+
+ auto accid = id();
+ auto selectionRequired = QSharedPointer<bool>(new bool(false));
+ auto ptrSelectionRequired = new QSharedPointer<bool>(selectionRequired);
+
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrSelectionRequired]() {
+ // Initially returns false if none are selected. After the first selection, it may be required.
+ bool anySelected = false;
+ if (QAccessibleInterface *accessible = accessibleForId(accid)) {
+ int childCount = accessible->childCount();
+ for (int i = 0; i < childCount; ++i) {
+ if (QAccessibleInterface *childAcc = accessible->child(i)) {
+ if (childAcc->state().selected) {
+ anySelected = true;
+ break;
+ }
+ }
+ }
+ **ptrSelectionRequired = anySelected && !accessible->state().multiSelectable && !accessible->state().extSelectable;
+ }
+ delete ptrSelectionRequired;
+ return S_OK;
+ }))) {
+ return E_FAIL;
+ }
+
+ *value = *selectionRequired;
+ return S_OK;
+}
+
+// Returns an array of providers with the selected items.
+HRESULT STDMETHODCALLTYPE QWinRTUiaSelectionProvider::GetSelection(UINT32 *returnValueSize, IIRawElementProviderSimple ***returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValueSize || !returnValue)
+ return E_INVALIDARG;
+ *returnValueSize = 0;
+ *returnValue = nullptr;
+
+ auto accid = id();
+ auto elementIds = QSharedPointer<QList<QAccessible::Id>>(new QList<QAccessible::Id>);
+ auto ptrElementIds = new QSharedPointer<QList<QAccessible::Id>>(elementIds);
+
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementIds]() {
+ if (QAccessibleInterface *accessible = accessibleForId(accid)) {
+ int childCount = accessible->childCount();
+ for (int i = 0; i < childCount; ++i) {
+ if (QAccessibleInterface *childAcc = accessible->child(i)) {
+ if (childAcc->state().selected) {
+ QAccessible::Id childId = idForAccessible(childAcc);
+ QWinRTUiaMetadataCache::instance()->load(childId);
+ (*ptrElementIds)->append(childId);
+ }
+ }
+ }
+ }
+ delete ptrElementIds;
+ return S_OK;
+ }))) {
+ return E_FAIL;
+ }
+
+ return QWinRTUiaMainProvider::rawProviderArrayForAccessibleIdList(*elementIds, returnValueSize, returnValue);
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionprovider.h b/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionprovider.h
new file mode 100644
index 0000000000..dcd286800f
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionprovider.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTUIASELECTIONPROVIDER_H
+#define QWINRTUIASELECTIONPROVIDER_H
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiabaseprovider.h"
+
+#include <wrl.h>
+#include <windows.ui.xaml.h>
+
+QT_BEGIN_NAMESPACE
+
+// Implements the Selection control pattern provider. Used for Lists.
+class QWinRTUiaSelectionProvider :
+ public QWinRTUiaBaseProvider,
+ public Microsoft::WRL::RuntimeClass<ABI::Windows::UI::Xaml::Automation::Provider::ISelectionProvider>
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(QWinRTUiaSelectionProvider)
+ InspectableClass(L"QWinRTUiaSelectionProvider", BaseTrust);
+
+public:
+ explicit QWinRTUiaSelectionProvider(QAccessible::Id id);
+ virtual ~QWinRTUiaSelectionProvider();
+
+ // ISelectionProvider
+ HRESULT STDMETHODCALLTYPE get_CanSelectMultiple(boolean *value) override;
+ HRESULT STDMETHODCALLTYPE get_IsSelectionRequired(boolean *value) override;
+ HRESULT STDMETHODCALLTYPE GetSelection(UINT32 *returnValueSize, ABI::Windows::UI::Xaml::Automation::Provider::IIRawElementProviderSimple ***returnValue) override;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
+
+#endif // QWINRTUIASELECTIONPROVIDER_H
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableitemprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableitemprovider.cpp
new file mode 100644
index 0000000000..1af74a8b72
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableitemprovider.cpp
@@ -0,0 +1,141 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiatableitemprovider.h"
+#include "qwinrtuiamainprovider.h"
+#include "qwinrtuiametadatacache.h"
+#include "qwinrtuiautils.h"
+
+#include <QtGui/QAccessible>
+#include <QtGui/QAccessibleInterface>
+#include <QtCore/QLoggingCategory>
+#include <QtCore/QString>
+#include <QtCore/private/qeventdispatcher_winrt_p.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace QWinRTUiAutomation;
+using namespace ABI::Windows::UI::Xaml::Automation;
+using namespace ABI::Windows::UI::Xaml::Automation::Provider;
+
+QWinRTUiaTableItemProvider::QWinRTUiaTableItemProvider(QAccessible::Id id) :
+ QWinRTUiaBaseProvider(id)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+}
+
+QWinRTUiaTableItemProvider::~QWinRTUiaTableItemProvider()
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+}
+
+// Returns the providers for the column headers associated with the item.
+HRESULT STDMETHODCALLTYPE QWinRTUiaTableItemProvider::GetColumnHeaderItems(UINT32 *returnValueSize, IIRawElementProviderSimple ***returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValueSize || !returnValue)
+ return E_INVALIDARG;
+ *returnValueSize = 0;
+ *returnValue = nullptr;
+
+ auto accid = id();
+ auto elementIds = QSharedPointer<QList<QAccessible::Id>>(new QList<QAccessible::Id>);
+ auto ptrElementIds = new QSharedPointer<QList<QAccessible::Id>>(elementIds);
+
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementIds]() {
+ if (QAccessibleInterface *accessible = accessibleForId(accid)) {
+ if (QAccessibleTableCellInterface *tableCellInterface = accessible->tableCellInterface()) {
+ QList<QAccessibleInterface *> headers = tableCellInterface->columnHeaderCells();
+ for (auto header : qAsConst(headers)) {
+ QAccessible::Id headerId = idForAccessible(header);
+ QWinRTUiaMetadataCache::instance()->load(headerId);
+ (*ptrElementIds)->append(headerId);
+ }
+ }
+ }
+ delete ptrElementIds;
+ return S_OK;
+ }))) {
+ return E_FAIL;
+ }
+
+ return QWinRTUiaMainProvider::rawProviderArrayForAccessibleIdList(*elementIds, returnValueSize, returnValue);
+}
+
+// Returns the providers for the row headers associated with the item.
+HRESULT STDMETHODCALLTYPE QWinRTUiaTableItemProvider::GetRowHeaderItems(UINT32 *returnValueSize, IIRawElementProviderSimple ***returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValueSize || !returnValue)
+ return E_INVALIDARG;
+ *returnValueSize = 0;
+ *returnValue = nullptr;
+
+ auto accid = id();
+ auto elementIds = QSharedPointer<QList<QAccessible::Id>>(new QList<QAccessible::Id>);
+ auto ptrElementIds = new QSharedPointer<QList<QAccessible::Id>>(elementIds);
+
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementIds]() {
+ if (QAccessibleInterface *accessible = accessibleForId(accid)) {
+ if (QAccessibleTableCellInterface *tableCellInterface = accessible->tableCellInterface()) {
+ QList<QAccessibleInterface *> headers = tableCellInterface->rowHeaderCells();
+ for (auto header : qAsConst(headers)) {
+ QAccessible::Id headerId = idForAccessible(header);
+ QWinRTUiaMetadataCache::instance()->load(headerId);
+ (*ptrElementIds)->append(headerId);
+ }
+ }
+ }
+ delete ptrElementIds;
+ return S_OK;
+ }))) {
+ return E_FAIL;
+ }
+
+ return QWinRTUiaMainProvider::rawProviderArrayForAccessibleIdList(*elementIds, returnValueSize, returnValue);
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableitemprovider.h b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableitemprovider.h
new file mode 100644
index 0000000000..cb759864ae
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableitemprovider.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTUIATABLEITEMPROVIDER_H
+#define QWINRTUIATABLEITEMPROVIDER_H
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiabaseprovider.h"
+
+#include <wrl.h>
+#include <windows.ui.xaml.h>
+
+QT_BEGIN_NAMESPACE
+
+// Implements the Table Item control pattern provider. Used by items within a table/tree.
+class QWinRTUiaTableItemProvider :
+ public QWinRTUiaBaseProvider,
+ public Microsoft::WRL::RuntimeClass<ABI::Windows::UI::Xaml::Automation::Provider::ITableItemProvider>
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(QWinRTUiaTableItemProvider)
+ InspectableClass(L"QWinRTUiaTableItemProvider", BaseTrust);
+
+public:
+ explicit QWinRTUiaTableItemProvider(QAccessible::Id id);
+ virtual ~QWinRTUiaTableItemProvider();
+
+ // ITableItemProvider
+ HRESULT STDMETHODCALLTYPE GetColumnHeaderItems(UINT32 *returnValueSize, ABI::Windows::UI::Xaml::Automation::Provider::IIRawElementProviderSimple ***returnValue) override;
+ HRESULT STDMETHODCALLTYPE GetRowHeaderItems(UINT32 *returnValueSize, ABI::Windows::UI::Xaml::Automation::Provider::IIRawElementProviderSimple ***returnValue) override;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
+
+#endif // QWINRTUIATABLEITEMPROVIDER_H
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableprovider.cpp
new file mode 100644
index 0000000000..e71ade3c1f
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableprovider.cpp
@@ -0,0 +1,167 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiatableprovider.h"
+#include "qwinrtuiamainprovider.h"
+#include "qwinrtuiametadatacache.h"
+#include "qwinrtuiautils.h"
+
+#include <QtGui/QAccessible>
+#include <QtGui/QAccessibleInterface>
+#include <QtCore/QLoggingCategory>
+#include <QtCore/QString>
+#include <QtCore/private/qeventdispatcher_winrt_p.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace QWinRTUiAutomation;
+using namespace ABI::Windows::UI::Xaml::Automation;
+using namespace ABI::Windows::UI::Xaml::Automation::Provider;
+using namespace ABI::Windows::UI::Xaml::Automation::Peers;
+
+QWinRTUiaTableProvider::QWinRTUiaTableProvider(QAccessible::Id id) :
+ QWinRTUiaBaseProvider(id)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+}
+
+QWinRTUiaTableProvider::~QWinRTUiaTableProvider()
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+}
+
+// Returns the primary direction of traversal for the table.
+HRESULT STDMETHODCALLTYPE QWinRTUiaTableProvider::get_RowOrColumnMajor(RowOrColumnMajor *value)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!value)
+ return E_INVALIDARG;
+ *value = RowOrColumnMajor_Indeterminate;
+ return S_OK;
+}
+
+// Gets the providers for all the column headers in the table.
+HRESULT STDMETHODCALLTYPE QWinRTUiaTableProvider::GetColumnHeaders(UINT32 *returnValueSize, IIRawElementProviderSimple ***returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValueSize || !returnValue)
+ return E_INVALIDARG;
+ *returnValueSize = 0;
+ *returnValue = nullptr;
+
+ auto accid = id();
+ auto elementIds = QSharedPointer<QList<QAccessible::Id>>(new QList<QAccessible::Id>);
+ auto ptrElementIds = new QSharedPointer<QList<QAccessible::Id>>(elementIds);
+
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementIds]() {
+ if (QAccessibleInterface *accessible = accessibleForId(accid)) {
+ if (QAccessibleTableInterface *tableInterface = accessible->tableInterface()) {
+ for (int i = 0; i < tableInterface->columnCount(); ++i) {
+ if (QAccessibleInterface *cell = tableInterface->cellAt(0, i)) {
+ QWinRTUiaMetadataCache::instance()->load(idForAccessible(cell));
+ if (QAccessibleTableCellInterface *tableCellInterface = cell->tableCellInterface()) {
+ QList<QAccessibleInterface *> headers = tableCellInterface->columnHeaderCells();
+ for (auto header : qAsConst(headers)) {
+ QAccessible::Id headerId = idForAccessible(header);
+ QWinRTUiaMetadataCache::instance()->load(headerId);
+ (*ptrElementIds)->append(headerId);
+ }
+ }
+ }
+ }
+ }
+ }
+ delete ptrElementIds;
+ return S_OK;
+ }))) {
+ return E_FAIL;
+ }
+
+ return QWinRTUiaMainProvider::rawProviderArrayForAccessibleIdList(*elementIds, returnValueSize, returnValue);
+}
+
+// Gets the providers for all the row headers in the table.
+HRESULT STDMETHODCALLTYPE QWinRTUiaTableProvider::GetRowHeaders(UINT32 *returnValueSize, IIRawElementProviderSimple ***returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValueSize || !returnValue)
+ return E_INVALIDARG;
+ *returnValueSize = 0;
+ *returnValue = nullptr;
+
+ auto accid = id();
+ auto elementIds = QSharedPointer<QList<QAccessible::Id>>(new QList<QAccessible::Id>);
+ auto ptrElementIds = new QSharedPointer<QList<QAccessible::Id>>(elementIds);
+
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementIds]() {
+ if (QAccessibleInterface *accessible = accessibleForId(accid)) {
+ if (QAccessibleTableInterface *tableInterface = accessible->tableInterface()) {
+ for (int i = 0; i < tableInterface->rowCount(); ++i) {
+ if (QAccessibleInterface *cell = tableInterface->cellAt(i, 0)) {
+ QWinRTUiaMetadataCache::instance()->load(idForAccessible(cell));
+ if (QAccessibleTableCellInterface *tableCellInterface = cell->tableCellInterface()) {
+ QList<QAccessibleInterface *> headers = tableCellInterface->rowHeaderCells();
+ for (auto header : qAsConst(headers)) {
+ QAccessible::Id headerId = idForAccessible(header);
+ QWinRTUiaMetadataCache::instance()->load(headerId);
+ (*ptrElementIds)->append(headerId);
+ }
+ }
+ }
+ }
+ }
+ }
+ delete ptrElementIds;
+ return S_OK;
+ }))) {
+ return E_FAIL;
+ }
+
+ return QWinRTUiaMainProvider::rawProviderArrayForAccessibleIdList(*elementIds, returnValueSize, returnValue);
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableprovider.h b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableprovider.h
new file mode 100644
index 0000000000..0cd174e401
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableprovider.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTUIATABLEPROVIDER_H
+#define QWINRTUIATABLEPROVIDER_H
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiabaseprovider.h"
+
+#include <wrl.h>
+#include <windows.ui.xaml.h>
+
+QT_BEGIN_NAMESPACE
+
+// Implements the Table control pattern provider. Used by tables/trees.
+class QWinRTUiaTableProvider :
+ public QWinRTUiaBaseProvider,
+ public Microsoft::WRL::RuntimeClass<ABI::Windows::UI::Xaml::Automation::Provider::ITableProvider>
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(QWinRTUiaTableProvider)
+ InspectableClass(L"QWinRTUiaTableProvider", BaseTrust);
+
+public:
+ explicit QWinRTUiaTableProvider(QAccessible::Id id);
+ virtual ~QWinRTUiaTableProvider();
+
+ // ITableProvider
+ HRESULT STDMETHODCALLTYPE get_RowOrColumnMajor(ABI::Windows::UI::Xaml::Automation::RowOrColumnMajor *value) override;
+ HRESULT STDMETHODCALLTYPE GetColumnHeaders(UINT32 *returnValueSize, ABI::Windows::UI::Xaml::Automation::Provider::IIRawElementProviderSimple ***returnValue) override;
+ HRESULT STDMETHODCALLTYPE GetRowHeaders(UINT32 *returnValueSize, ABI::Windows::UI::Xaml::Automation::Provider::IIRawElementProviderSimple ***returnValue) override;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
+
+#endif // QWINRTUIATABLEPROVIDER_H
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextprovider.cpp
new file mode 100644
index 0000000000..aa120377df
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextprovider.cpp
@@ -0,0 +1,232 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiatextprovider.h"
+#include "qwinrtuiametadatacache.h"
+#include "qwinrtuiatextrangeprovider.h"
+#include "qwinrtuiautils.h"
+
+#include <QtGui/QAccessible>
+#include <QtGui/QAccessibleInterface>
+#include <QtCore/QLoggingCategory>
+#include <QtCore/QString>
+#include <QtCore/private/qeventdispatcher_winrt_p.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace QWinRTUiAutomation;
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::UI::Xaml::Automation;
+using namespace ABI::Windows::UI::Xaml::Automation::Provider;
+
+QWinRTUiaTextProvider::QWinRTUiaTextProvider(QAccessible::Id id) :
+ QWinRTUiaBaseProvider(id)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+}
+
+QWinRTUiaTextProvider::~QWinRTUiaTextProvider()
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+}
+
+// Returns a text range provider for the entire text.
+HRESULT STDMETHODCALLTYPE QWinRTUiaTextProvider::get_DocumentRange(ITextRangeProvider **value)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!value)
+ return E_INVALIDARG;
+
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ ComPtr<QWinRTUiaTextRangeProvider> textRangeProvider = Make<QWinRTUiaTextRangeProvider>(id(), 0, metadata->characterCount());
+ return textRangeProvider.CopyTo(value);
+}
+
+// Currently supporting single selection.
+HRESULT STDMETHODCALLTYPE QWinRTUiaTextProvider::get_SupportedTextSelection(SupportedTextSelection *value)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+ if (!value)
+ return E_INVALIDARG;
+ *value = SupportedTextSelection_Single;
+ return S_OK;
+
+}
+
+// Returns an array of providers for the selected text ranges.
+HRESULT STDMETHODCALLTYPE QWinRTUiaTextProvider::GetSelection(UINT32 *returnValueSize, ITextRangeProvider ***returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValueSize || !returnValue)
+ return E_INVALIDARG;
+ *returnValueSize = 0;
+ *returnValue = nullptr;
+
+ auto accid = id();
+ auto selections = QSharedPointer<QList<QPair<int,int>>>(new QList<QPair<int,int>>);
+ auto ptrSelections = new QSharedPointer<QList<QPair<int,int>>>(selections);
+
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrSelections]() {
+ if (QAccessibleInterface *accessible = accessibleForId(accid)) {
+ if (QAccessibleTextInterface *textInterface = accessible->textInterface()) {
+ for (int i = 0; i < textInterface->selectionCount(); ++i) {
+ QPair<int,int> sel;
+ textInterface->selection(i, &sel.first, &sel.second);
+ (*ptrSelections)->append(sel);
+ }
+ if ((*ptrSelections)->size() == 0) {
+ // If there is no selection, we return an array with a single degenerate (empty) text range at the cursor position.
+ QPair<int,int> sel(textInterface->cursorPosition(), textInterface->cursorPosition());
+ (*ptrSelections)->append(sel);
+ }
+ }
+ }
+ delete ptrSelections;
+ return S_OK;
+ }))) {
+ return E_FAIL;
+ }
+
+ int selCount = selections->size();
+ if (selCount < 1)
+ return E_FAIL;
+
+ ITextRangeProvider **providerArray = static_cast<ITextRangeProvider **>(CoTaskMemAlloc(selCount * sizeof(ITextRangeProvider *)));
+ if (!providerArray)
+ return E_OUTOFMEMORY;
+
+ for (int i = 0; i < selCount; ++i) {
+ ComPtr<QWinRTUiaTextRangeProvider> textRangeProvider = Make<QWinRTUiaTextRangeProvider>(id(), (*selections)[i].first, (*selections)[i].second);
+ textRangeProvider.CopyTo(&providerArray[i]);
+ }
+ *returnValueSize = selCount;
+ *returnValue = providerArray;
+ return S_OK;
+}
+
+// Returns an array of providers for the visible text ranges.
+HRESULT STDMETHODCALLTYPE QWinRTUiaTextProvider::GetVisibleRanges(UINT32 *returnValueSize, ITextRangeProvider ***returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValueSize || !returnValue)
+ return E_INVALIDARG;
+
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+
+ // Considering the entire text as visible.
+ ComPtr<QWinRTUiaTextRangeProvider> textRangeProvider = Make<QWinRTUiaTextRangeProvider>(id(), 0, metadata->characterCount());
+ textRangeProvider.CopyTo(*returnValue);
+ *returnValueSize = 1;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaTextProvider::RangeFromChild(IIRawElementProviderSimple *childElement, ITextRangeProvider **returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+ if (!childElement || !returnValue)
+ return E_INVALIDARG;
+ *returnValue = nullptr;
+ // No children supported.
+ return S_OK;
+}
+
+// Returns a degenerate text range at the specified point.
+HRESULT STDMETHODCALLTYPE QWinRTUiaTextProvider::RangeFromPoint(ABI::Windows::Foundation::Point screenLocation, ITextRangeProvider **returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ *returnValue = nullptr;
+
+ const QPoint pt(screenLocation.X, screenLocation.Y);
+ auto accid = id();
+ auto offset = QSharedPointer<int>(new int);
+ auto ptrOffset = new QSharedPointer<int>(offset);
+
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, pt, ptrOffset]() {
+ if (QAccessibleInterface *accessible = accessibleForId(accid))
+ if (QAccessibleTextInterface *textInterface = accessible->textInterface())
+ **ptrOffset = qBound(0, textInterface->offsetAtPoint(pt), textInterface->characterCount() - 1);
+ delete ptrOffset;
+ return S_OK;
+ }))) {
+ return E_FAIL;
+ }
+
+ ComPtr<QWinRTUiaTextRangeProvider> textRangeProvider = Make<QWinRTUiaTextRangeProvider>(id(), *offset, *offset);
+ textRangeProvider.CopyTo(returnValue);
+ return S_OK;
+}
+
+// Not supporting annotations.
+HRESULT STDMETHODCALLTYPE QWinRTUiaTextProvider::RangeFromAnnotation(IIRawElementProviderSimple *annotationElement, ITextRangeProvider **returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+ if (!annotationElement || !returnValue)
+ return E_INVALIDARG;
+ *returnValue = nullptr;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaTextProvider::GetCaretRange(boolean *isActive, ITextRangeProvider **returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!isActive || !returnValue)
+ return E_INVALIDARG;
+
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ *isActive = metadata->state().focused;
+
+ ComPtr<QWinRTUiaTextRangeProvider> textRangeProvider = Make<QWinRTUiaTextRangeProvider>(id(), metadata->cursorPosition(), metadata->cursorPosition());
+ return textRangeProvider.CopyTo(returnValue);
+}
+
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextprovider.h b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextprovider.h
new file mode 100644
index 0000000000..80d88e4115
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextprovider.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTUIATEXTPROVIDER_H
+#define QWINRTUIATEXTPROVIDER_H
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiabaseprovider.h"
+
+#include <wrl.h>
+#include <windows.ui.xaml.h>
+
+QT_BEGIN_NAMESPACE
+
+// Implements the Text control pattern provider. Used for text controls.
+class QWinRTUiaTextProvider :
+ public QWinRTUiaBaseProvider,
+ public Microsoft::WRL::RuntimeClass<ABI::Windows::UI::Xaml::Automation::Provider::ITextProvider, ABI::Windows::UI::Xaml::Automation::Provider::ITextProvider2>
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(QWinRTUiaTextProvider)
+ InspectableClass(L"QWinRTUiaTextProvider", BaseTrust);
+
+public:
+ explicit QWinRTUiaTextProvider(QAccessible::Id id);
+ virtual ~QWinRTUiaTextProvider();
+
+ // ITextProvider
+ HRESULT STDMETHODCALLTYPE get_DocumentRange(ABI::Windows::UI::Xaml::Automation::Provider::ITextRangeProvider **value) override;
+ HRESULT STDMETHODCALLTYPE get_SupportedTextSelection(ABI::Windows::UI::Xaml::Automation::SupportedTextSelection *value) override;
+ HRESULT STDMETHODCALLTYPE GetSelection(UINT32 *returnValueSize, ABI::Windows::UI::Xaml::Automation::Provider::ITextRangeProvider ***returnValue) override;
+ HRESULT STDMETHODCALLTYPE GetVisibleRanges(UINT32 *returnValueSize, ABI::Windows::UI::Xaml::Automation::Provider::ITextRangeProvider ***returnValue) override;
+ HRESULT STDMETHODCALLTYPE RangeFromChild(ABI::Windows::UI::Xaml::Automation::Provider::IIRawElementProviderSimple *childElement, ABI::Windows::UI::Xaml::Automation::Provider::ITextRangeProvider **returnValue) override;
+ HRESULT STDMETHODCALLTYPE RangeFromPoint(ABI::Windows::Foundation::Point screenLocation, ABI::Windows::UI::Xaml::Automation::Provider::ITextRangeProvider **returnValue) override;
+
+ // ITextProvider2
+ HRESULT STDMETHODCALLTYPE RangeFromAnnotation(ABI::Windows::UI::Xaml::Automation::Provider::IIRawElementProviderSimple *annotationElement, ABI::Windows::UI::Xaml::Automation::Provider::ITextRangeProvider **returnValue) override;
+ HRESULT STDMETHODCALLTYPE GetCaretRange(boolean *isActive, ABI::Windows::UI::Xaml::Automation::Provider::ITextRangeProvider **returnValue) override;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
+
+#endif // QWINRTUIATEXTPROVIDER_H
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextrangeprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextrangeprovider.cpp
new file mode 100644
index 0000000000..fc3778d652
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextrangeprovider.cpp
@@ -0,0 +1,497 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiatextrangeprovider.h"
+#include "qwinrtuiametadatacache.h"
+#include "qwinrtuiamainprovider.h"
+#include "qwinrtuiautils.h"
+
+#include <QtGui/QAccessible>
+#include <QtGui/QAccessibleInterface>
+#include <QtCore/QLoggingCategory>
+#include <QtCore/QString>
+#include <QtCore/private/qeventdispatcher_winrt_p.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace QWinRTUiAutomation;
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::UI::Xaml;
+using namespace ABI::Windows::UI::Xaml::Automation;
+using namespace ABI::Windows::UI::Xaml::Automation::Provider;
+using namespace ABI::Windows::UI::Xaml::Automation::Text;
+
+QWinRTUiaTextRangeProvider::QWinRTUiaTextRangeProvider(QAccessible::Id id, int startOffset, int endOffset) :
+ QWinRTUiaBaseProvider(id),
+ m_startOffset(startOffset),
+ m_endOffset(endOffset)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__ << startOffset << endOffset;
+}
+
+QWinRTUiaTextRangeProvider::~QWinRTUiaTextRangeProvider()
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::Clone(ITextRangeProvider **returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+ if (!returnValue)
+ return E_INVALIDARG;
+
+ ComPtr<QWinRTUiaTextRangeProvider> textRangeProvider = Make<QWinRTUiaTextRangeProvider>(id(), m_startOffset, m_endOffset);
+ textRangeProvider.CopyTo(returnValue);
+ return S_OK;
+}
+
+// Two ranges are considered equal if their start/end points are the same.
+HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::Compare(ITextRangeProvider *textRangeProvider, boolean *returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+ if (!textRangeProvider || !returnValue)
+ return E_INVALIDARG;
+
+ QWinRTUiaTextRangeProvider *targetProvider = static_cast<QWinRTUiaTextRangeProvider *>(textRangeProvider);
+ *returnValue = ((targetProvider->m_startOffset == m_startOffset) && (targetProvider->m_endOffset == m_endOffset));
+ return S_OK;
+}
+
+// Compare different endpoinds between two providers.
+HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::CompareEndpoints(TextPatternRangeEndpoint endpoint, ITextRangeProvider *textRangeProvider, TextPatternRangeEndpoint targetEndpoint, INT32 *returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!textRangeProvider || !returnValue)
+ return E_INVALIDARG;
+
+ QWinRTUiaTextRangeProvider *targetProvider = static_cast<QWinRTUiaTextRangeProvider *>(textRangeProvider);
+
+ int point = (endpoint == TextPatternRangeEndpoint_Start) ? m_startOffset : m_endOffset;
+ int targetPoint = (targetEndpoint == TextPatternRangeEndpoint_Start) ?
+ targetProvider->m_startOffset : targetProvider->m_endOffset;
+ *returnValue = point - targetPoint;
+ return S_OK;
+}
+
+// Expands/normalizes the range for a given text unit.
+HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::ExpandToEnclosingUnit(TextUnit unit)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__ << "unit=" << unit << "this: " << this;
+
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+
+ int len = metadata->characterCount();
+ if (len < 1) {
+ m_startOffset = 0;
+ m_endOffset = 0;
+ } else {
+ if (unit == TextUnit_Character) {
+ m_startOffset = qBound(0, m_startOffset, len - 1);
+ m_endOffset = m_startOffset + 1;
+ } else {
+ QString text = metadata->text();
+ for (int t = m_startOffset; t >= 0; --t) {
+ if (!isTextUnitSeparator(unit, text[t]) && ((t == 0) || isTextUnitSeparator(unit, text[t - 1]))) {
+ m_startOffset = t;
+ break;
+ }
+ }
+ for (int t = m_startOffset; t < len; ++t) {
+ if ((t == len - 1) || (isTextUnitSeparator(unit, text[t]) && ((unit == TextUnit_Word) || !isTextUnitSeparator(unit, text[t + 1])))) {
+ m_endOffset = t + 1;
+ break;
+ }
+ }
+ }
+ }
+ return S_OK;
+}
+
+// Not supported.
+HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::FindAttribute(INT32 /*attributeId*/, IInspectable * /*value*/, boolean /*backward*/, ITextRangeProvider **returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+ if (!returnValue)
+ return E_INVALIDARG;
+ *returnValue = nullptr;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::FindText(HSTRING /*text*/, boolean /*backward*/, boolean /*ignoreCase*/, ITextRangeProvider **returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+ if (!returnValue)
+ return E_INVALIDARG;
+ *returnValue = nullptr;
+ return S_OK;
+}
+
+// Returns the value of a given attribute.
+HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::GetAttributeValue(INT32 attributeId, IInspectable **returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__ << "attributeId=" << attributeId;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ *returnValue = nullptr;
+
+ ComPtr<IPropertyValueStatics> propertyValueStatics;
+ if (FAILED(RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Foundation_PropertyValue).Get(), IID_PPV_ARGS(&propertyValueStatics))))
+ return E_FAIL;
+
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+
+ switch (attributeId) {
+ case AutomationTextAttributesEnum_IsReadOnlyAttribute:
+ return propertyValueStatics->CreateBoolean(metadata->state().readOnly, returnValue);
+ case AutomationTextAttributesEnum_CaretPositionAttribute:
+ if (metadata->cursorPosition() == 0)
+ return propertyValueStatics->CreateInt32(AutomationCaretPosition_BeginningOfLine, returnValue);
+ else if (metadata->cursorPosition() == metadata->characterCount())
+ return propertyValueStatics->CreateInt32(AutomationCaretPosition_EndOfLine, returnValue);
+ else
+ return propertyValueStatics->CreateInt32(AutomationCaretPosition_Unknown, returnValue);
+ default:
+ break;
+ }
+ return E_FAIL;
+}
+
+// Returns an array of bounding rectangles for text lines within the range.
+HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::GetBoundingRectangles(UINT32 *returnValueSize, DOUBLE **returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValueSize || !returnValue)
+ return E_INVALIDARG;
+ *returnValueSize = 0;
+ *returnValue = nullptr;
+
+ auto accid = id();
+ auto startOffset = m_startOffset;
+ auto endOffset = m_endOffset;
+ auto rects = QSharedPointer<QList<QRect>>(new QList<QRect>);
+ auto ptrRects = new QSharedPointer<QList<QRect>>(rects);
+
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, startOffset, endOffset, ptrRects]() {
+ if (QAccessibleInterface *accessible = accessibleForId(accid)) {
+ if (QAccessibleTextInterface *textInterface = accessible->textInterface()) {
+ int len = textInterface->characterCount();
+ if ((startOffset >= 0) && (endOffset <= len) && (startOffset < endOffset)) {
+ int start, end;
+ textInterface->textAtOffset(startOffset, QAccessible::LineBoundary, &start, &end);
+ while ((start >= 0) && (end >= 0)) {
+ int startRange = qMax(start, startOffset);
+ int endRange = qMin(end, endOffset);
+ if (startRange < endRange) {
+ // Calculates a bounding rectangle for the line and adds it to the list.
+ const QRect startRect = textInterface->characterRect(startRange);
+ const QRect endRect = textInterface->characterRect(endRange - 1);
+ const QRect lineRect(qMin(startRect.x(), endRect.x()),
+ qMin(startRect.y(), endRect.y()),
+ qMax(startRect.x() + startRect.width(), endRect.x() + endRect.width()) - qMin(startRect.x(), endRect.x()),
+ qMax(startRect.y() + startRect.height(), endRect.y() + endRect.height()) - qMin(startRect.y(), endRect.y()));
+ (*ptrRects)->append(lineRect);
+ }
+ if (end >= len) break;
+ textInterface->textAfterOffset(end + 1, QAccessible::LineBoundary, &start, &end);
+ }
+ }
+ }
+ }
+ delete ptrRects;
+ return S_OK;
+ }))) {
+ return E_FAIL;
+ }
+
+ DOUBLE *doubleArray = static_cast<DOUBLE *>(CoTaskMemAlloc(4 * rects->size() * sizeof(DOUBLE)));
+ if (!doubleArray)
+ return E_OUTOFMEMORY;
+
+ for (int i = 0; i < rects->size(); ++i) {
+ doubleArray[i*4] = (*rects)[i].left();
+ doubleArray[i*4+1] = (*rects)[i].top();
+ doubleArray[i*4+2] = (*rects)[i].width();
+ doubleArray[i*4+3] = (*rects)[i].height();
+ }
+ *returnValue = doubleArray;
+ *returnValueSize = 4 * rects->size();
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::GetEnclosingElement(IIRawElementProviderSimple **returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+ if (!returnValue)
+ return E_INVALIDARG;
+ return QWinRTUiaMainProvider::rawProviderForAccessibleId(id(), returnValue);
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::GetText(INT32 maxLength, HSTRING *returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+ if (!returnValue)
+ return E_INVALIDARG;
+ *returnValue = nullptr;
+
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+
+ QString rangeText = metadata->text().mid(m_startOffset, m_endOffset - m_startOffset);
+
+ if ((maxLength > -1) && (rangeText.size() > maxLength))
+ rangeText.truncate(maxLength);
+ return qHString(rangeText, returnValue);
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::Move(TextUnit unit, INT32 count, INT32 *returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+ if (!returnValue)
+ return E_INVALIDARG;
+ *returnValue = 0;
+
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+
+ int len = metadata->characterCount();
+ if (len < 1)
+ return S_OK;
+
+ if (unit == TextUnit_Character) {
+ // Moves the start point, ensuring it lies within the bounds.
+ int start = qBound(0, m_startOffset + count, len - 1);
+ // If range was initially empty, leaves it as is; otherwise, normalizes it to one char.
+ m_endOffset = (m_endOffset > m_startOffset) ? start + 1 : start;
+ *returnValue = start - m_startOffset; // Returns the actually moved distance.
+ m_startOffset = start;
+ } else {
+ if (count > 0) {
+ MoveEndpointByUnit(TextPatternRangeEndpoint_End, unit, count, returnValue);
+ MoveEndpointByUnit(TextPatternRangeEndpoint_Start, unit, count, returnValue);
+ } else {
+ MoveEndpointByUnit(TextPatternRangeEndpoint_Start, unit, count, returnValue);
+ MoveEndpointByUnit(TextPatternRangeEndpoint_End, unit, count, returnValue);
+ }
+ }
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::MoveEndpointByUnit(TextPatternRangeEndpoint endpoint, TextUnit unit, INT32 count, INT32 *returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+ if (!returnValue)
+ return E_INVALIDARG;
+ *returnValue = 0;
+
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+
+ int len = metadata->characterCount();
+ if (len < 1)
+ return S_OK;
+
+ if (unit == TextUnit_Character) {
+ if (endpoint == TextPatternRangeEndpoint_Start) {
+ int boundedValue = qBound(0, m_startOffset + count, len - 1);
+ *returnValue = boundedValue - m_startOffset;
+ m_startOffset = boundedValue;
+ m_endOffset = qBound(m_startOffset, m_endOffset, len);
+ } else {
+ int boundedValue = qBound(0, m_endOffset + count, len);
+ *returnValue = boundedValue - m_endOffset;
+ m_endOffset = boundedValue;
+ m_startOffset = qBound(0, m_startOffset, m_endOffset);
+ }
+ } else {
+ QString text = metadata->text();
+ int moved = 0;
+
+ if (endpoint == TextPatternRangeEndpoint_Start) {
+ if (count > 0) {
+ for (int t = m_startOffset; (t < len - 1) && (moved < count); ++t) {
+ if (isTextUnitSeparator(unit, text[t]) && !isTextUnitSeparator(unit, text[t + 1])) {
+ m_startOffset = t + 1;
+ ++moved;
+ }
+ }
+ m_endOffset = qBound(m_startOffset, m_endOffset, len);
+ } else {
+ for (int t = m_startOffset - 1; (t >= 0) && (moved > count); --t) {
+ if (!isTextUnitSeparator(unit, text[t]) && ((t == 0) || isTextUnitSeparator(unit, text[t - 1]))) {
+ m_startOffset = t;
+ --moved;
+ }
+ }
+ }
+ } else {
+ if (count > 0) {
+ for (int t = m_endOffset; (t < len) && (moved < count); ++t) {
+ if ((t == len - 1) || (isTextUnitSeparator(unit, text[t]) && ((unit == TextUnit_Word) || !isTextUnitSeparator(unit, text[t + 1])))) {
+ m_endOffset = t + 1;
+ ++moved;
+ }
+ }
+ } else {
+ int end = 0;
+ for (int t = m_endOffset - 2; (t > 0) && (moved > count); --t) {
+ if (isTextUnitSeparator(unit, text[t]) && ((unit == TextUnit_Word) || !isTextUnitSeparator(unit, text[t + 1]))) {
+ end = t + 1;
+ --moved;
+ }
+ }
+ m_endOffset = end;
+ m_startOffset = qBound(0, m_startOffset, m_endOffset);
+ }
+ }
+ *returnValue = moved;
+ }
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::MoveEndpointByRange(TextPatternRangeEndpoint endpoint, ITextRangeProvider *textRangeProvider, TextPatternRangeEndpoint targetEndpoint)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+ if (!textRangeProvider)
+ return E_INVALIDARG;
+
+ QWinRTUiaTextRangeProvider *targetProvider = static_cast<QWinRTUiaTextRangeProvider *>(textRangeProvider);
+
+ int targetPoint = (targetEndpoint == TextPatternRangeEndpoint_Start) ?
+ targetProvider->m_startOffset : targetProvider->m_endOffset;
+
+ // If the moved endpoint crosses the other endpoint, that one is moved too.
+ if (endpoint == TextPatternRangeEndpoint_Start) {
+ m_startOffset = targetPoint;
+ if (m_endOffset < m_startOffset)
+ m_endOffset = m_startOffset;
+ } else {
+ m_endOffset = targetPoint;
+ if (m_endOffset < m_startOffset)
+ m_startOffset = m_endOffset;
+ }
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::Select()
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ auto accid = id();
+ auto startOffset = m_startOffset;
+ auto endOffset = m_endOffset;
+
+ QEventDispatcherWinRT::runOnMainThread([accid, startOffset, endOffset]() {
+ if (QAccessibleInterface *accessible = accessibleForId(accid))
+ if (QAccessibleTextInterface *textInterface = accessible->textInterface()) {
+ // unselects all and adds a new selection
+ for (int i = textInterface->selectionCount() - 1; i >= 0; --i)
+ textInterface->removeSelection(i);
+ textInterface->addSelection(startOffset, endOffset);
+ }
+ QWinRTUiaMetadataCache::instance()->load(accid);
+ return S_OK;
+ }, 0);
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::AddToSelection()
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+ return Select();
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::RemoveFromSelection()
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ auto accid = id();
+
+ QEventDispatcherWinRT::runOnMainThread([accid]() {
+ if (QAccessibleInterface *accessible = accessibleForId(accid))
+ if (QAccessibleTextInterface *textInterface = accessible->textInterface()) {
+ // unselects all
+ for (int i = textInterface->selectionCount() - 1; i >= 0; --i)
+ textInterface->removeSelection(i);
+ }
+ QWinRTUiaMetadataCache::instance()->load(accid);
+ return S_OK;
+ }, 0);
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::ScrollIntoView(boolean /*alignToTop*/)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ auto accid = id();
+ auto startOffset = m_startOffset;
+ auto endOffset = m_endOffset;
+
+ QEventDispatcherWinRT::runOnMainThread([accid, startOffset, endOffset]() {
+ if (QAccessibleInterface *accessible = accessibleForId(accid))
+ if (QAccessibleTextInterface *textInterface = accessible->textInterface()) {
+ textInterface->scrollToSubstring(startOffset, endOffset);
+ }
+ QWinRTUiaMetadataCache::instance()->load(accid);
+ return S_OK;
+ }, 0);
+ return S_OK;
+}
+
+// Returns an array of children elements embedded within the range.
+HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::GetChildren(UINT32 *returnValueSize, IIRawElementProviderSimple ***returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ // Not supporting any children.
+ returnValueSize = 0;
+ *returnValue = nullptr;
+ return S_OK;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextrangeprovider.h b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextrangeprovider.h
new file mode 100644
index 0000000000..81b5f0d400
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextrangeprovider.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTUIATEXTRANGEPROVIDER_H
+#define QWINRTUIATEXTRANGEPROVIDER_H
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiabaseprovider.h"
+
+#include <wrl.h>
+#include <windows.ui.xaml.h>
+
+QT_BEGIN_NAMESPACE
+
+// Implements the Text Range control pattern provider. Used for text controls.
+class QWinRTUiaTextRangeProvider :
+ public QWinRTUiaBaseProvider,
+ public Microsoft::WRL::RuntimeClass<ABI::Windows::UI::Xaml::Automation::Provider::ITextRangeProvider>
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(QWinRTUiaTextRangeProvider)
+ InspectableClass(L"QWinRTUiaTextRangeProvider", BaseTrust);
+
+public:
+ explicit QWinRTUiaTextRangeProvider(QAccessible::Id id, int startOffset, int endOffset);
+ virtual ~QWinRTUiaTextRangeProvider();
+
+ // ITextRangeProvider
+ HRESULT STDMETHODCALLTYPE Clone(ABI::Windows::UI::Xaml::Automation::Provider::ITextRangeProvider **returnValue) override;
+ HRESULT STDMETHODCALLTYPE Compare(ABI::Windows::UI::Xaml::Automation::Provider::ITextRangeProvider *textRangeProvider, boolean *returnValue) override;
+ HRESULT STDMETHODCALLTYPE CompareEndpoints(ABI::Windows::UI::Xaml::Automation::Text::TextPatternRangeEndpoint endpoint, ABI::Windows::UI::Xaml::Automation::Provider::ITextRangeProvider *textRangeProvider, ABI::Windows::UI::Xaml::Automation::Text::TextPatternRangeEndpoint targetEndpoint, INT32 *returnValue) override;
+ HRESULT STDMETHODCALLTYPE ExpandToEnclosingUnit(ABI::Windows::UI::Xaml::Automation::Text::TextUnit unit) override;
+ HRESULT STDMETHODCALLTYPE FindAttribute(INT32 attributeId, IInspectable *value, boolean backward, ABI::Windows::UI::Xaml::Automation::Provider::ITextRangeProvider **returnValue) override;
+ HRESULT STDMETHODCALLTYPE FindText(HSTRING text, boolean backward, boolean ignoreCase, ABI::Windows::UI::Xaml::Automation::Provider::ITextRangeProvider **returnValue) override;
+ HRESULT STDMETHODCALLTYPE GetAttributeValue(INT32 attributeId, IInspectable **returnValue) override;
+ HRESULT STDMETHODCALLTYPE GetBoundingRectangles(UINT32 *returnValueSize, DOUBLE **returnValue) override;
+ HRESULT STDMETHODCALLTYPE GetEnclosingElement(ABI::Windows::UI::Xaml::Automation::Provider::IIRawElementProviderSimple **returnValue) override;
+ HRESULT STDMETHODCALLTYPE GetText(INT32 maxLength, HSTRING *returnValue) override;
+ HRESULT STDMETHODCALLTYPE Move(ABI::Windows::UI::Xaml::Automation::Text::TextUnit unit, INT32 count, INT32 *returnValue) override;
+ HRESULT STDMETHODCALLTYPE MoveEndpointByUnit(ABI::Windows::UI::Xaml::Automation::Text::TextPatternRangeEndpoint endpoint, ABI::Windows::UI::Xaml::Automation::Text::TextUnit unit, INT32 count, INT32 *returnValue) override;
+ HRESULT STDMETHODCALLTYPE MoveEndpointByRange(ABI::Windows::UI::Xaml::Automation::Text::TextPatternRangeEndpoint endpoint, ABI::Windows::UI::Xaml::Automation::Provider::ITextRangeProvider *textRangeProvider, ABI::Windows::UI::Xaml::Automation::Text::TextPatternRangeEndpoint targetEndpoint) override;
+ HRESULT STDMETHODCALLTYPE Select() override;
+ HRESULT STDMETHODCALLTYPE AddToSelection() override;
+ HRESULT STDMETHODCALLTYPE RemoveFromSelection() override;
+ HRESULT STDMETHODCALLTYPE ScrollIntoView(boolean alignToTop) override;
+ HRESULT STDMETHODCALLTYPE GetChildren(UINT32 *returnValueSize, ABI::Windows::UI::Xaml::Automation::Provider::IIRawElementProviderSimple ***returnValue) override;
+
+private:
+ int m_startOffset;
+ int m_endOffset;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
+
+#endif // QWINRTUIATEXTRANGEPROVIDER_H
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiatoggleprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatoggleprovider.cpp
new file mode 100644
index 0000000000..59f55eb422
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatoggleprovider.cpp
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiatoggleprovider.h"
+#include "qwinrtuiametadatacache.h"
+#include "qwinrtuiautils.h"
+
+#include <QtGui/QAccessible>
+#include <QtGui/QAccessibleInterface>
+#include <QtCore/QLoggingCategory>
+#include <QtCore/QString>
+#include <QtCore/private/qeventdispatcher_winrt_p.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace QWinRTUiAutomation;
+using namespace ABI::Windows::UI::Xaml::Automation;
+using namespace ABI::Windows::UI::Xaml::Automation::Provider;
+
+QWinRTUiaToggleProvider::QWinRTUiaToggleProvider(QAccessible::Id id) :
+ QWinRTUiaBaseProvider(id)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+}
+
+QWinRTUiaToggleProvider::~QWinRTUiaToggleProvider()
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+}
+
+// Gets the current toggle state.
+HRESULT STDMETHODCALLTYPE QWinRTUiaToggleProvider::get_ToggleState(ToggleState *value)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!value)
+ return E_INVALIDARG;
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ if (metadata->state().checked)
+ *value = metadata->state().checkStateMixed ? ToggleState_Indeterminate : ToggleState_On;
+ else
+ *value = ToggleState_Off;
+ return S_OK;
+}
+
+// Toggles the state by invoking the toggle action.
+HRESULT STDMETHODCALLTYPE QWinRTUiaToggleProvider::Toggle()
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ auto accid = id();
+
+ QEventDispatcherWinRT::runOnMainThread([accid]() {
+ if (QAccessibleInterface *accessible = accessibleForId(accid))
+ if (QAccessibleActionInterface *actionInterface = accessible->actionInterface())
+ actionInterface->doAction(QAccessibleActionInterface::toggleAction());
+ QWinRTUiaMetadataCache::instance()->load(accid);
+ return S_OK;
+ }, 0);
+ return S_OK;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiatoggleprovider.h b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatoggleprovider.h
new file mode 100644
index 0000000000..3d1740c0a1
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatoggleprovider.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTUIATOGGLEPROVIDER_H
+#define QWINRTUIATOGGLEPROVIDER_H
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiabaseprovider.h"
+
+#include <wrl.h>
+#include <windows.ui.xaml.h>
+
+QT_BEGIN_NAMESPACE
+
+// Implements the Toggle control pattern provider. Used for checkboxes.
+class QWinRTUiaToggleProvider :
+ public QWinRTUiaBaseProvider,
+ public Microsoft::WRL::RuntimeClass<ABI::Windows::UI::Xaml::Automation::Provider::IToggleProvider>
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(QWinRTUiaToggleProvider)
+ InspectableClass(L"QWinRTUiaToggleProvider", BaseTrust);
+
+public:
+ explicit QWinRTUiaToggleProvider(QAccessible::Id id);
+ virtual ~QWinRTUiaToggleProvider();
+
+ // IToggleProvider
+ HRESULT STDMETHODCALLTYPE get_ToggleState(ABI::Windows::UI::Xaml::Automation::ToggleState *value) override;
+ HRESULT STDMETHODCALLTYPE Toggle() override;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
+
+#endif // QWINRTUIATOGGLEPROVIDER_H
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiautils.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiautils.cpp
new file mode 100644
index 0000000000..98483216c0
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiautils.cpp
@@ -0,0 +1,182 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiautils.h"
+
+using namespace ABI::Windows::UI::Xaml::Automation::Peers;
+using namespace ABI::Windows::UI::Xaml::Automation::Text;
+using namespace ABI::Windows::Foundation::Collections;
+
+QT_BEGIN_NAMESPACE
+
+Q_LOGGING_CATEGORY(lcQpaUiAutomation, "qt.qpa.uiautomation")
+
+namespace QWinRTUiAutomation {
+
+// Returns the window containing the element (usually the top window),
+QWindow *windowForAccessible(const QAccessibleInterface *accessible)
+{
+ QWindow *window = accessible->window();
+ if (!window) {
+ QAccessibleInterface *acc = accessible->parent();
+ while (acc && acc->isValid() && !window) {
+ window = acc->window();
+ QAccessibleInterface *par = acc->parent();
+ acc = par;
+ }
+ }
+ return window;
+}
+
+QAccessibleInterface *accessibleForId(QAccessible::Id id)
+{
+ QAccessibleInterface *accessible = QAccessible::accessibleInterface(id);
+ if (!accessible || !accessible->isValid())
+ return nullptr;
+ return accessible;
+}
+
+QAccessible::Id idForAccessible(QAccessibleInterface *accessible)
+{
+ if (!accessible)
+ return QAccessible::Id(0);
+ return QAccessible::uniqueId(accessible);
+}
+
+// Maps an accessibility role ID to an UI Automation control type ID.
+AutomationControlType roleToControlType(QAccessible::Role role)
+{
+ static const QHash<QAccessible::Role, AutomationControlType> mapping {
+ {QAccessible::TitleBar, AutomationControlType::AutomationControlType_TitleBar},
+ {QAccessible::MenuBar, AutomationControlType::AutomationControlType_MenuBar},
+ {QAccessible::ScrollBar, AutomationControlType::AutomationControlType_ScrollBar},
+ {QAccessible::Grip, AutomationControlType::AutomationControlType_Thumb},
+ {QAccessible::Sound, AutomationControlType::AutomationControlType_Custom},
+ {QAccessible::Cursor, AutomationControlType::AutomationControlType_Custom},
+ {QAccessible::Caret, AutomationControlType::AutomationControlType_Custom},
+ {QAccessible::AlertMessage, AutomationControlType::AutomationControlType_Custom},
+ {QAccessible::Window, AutomationControlType::AutomationControlType_Window},
+ {QAccessible::Client, AutomationControlType::AutomationControlType_Custom},
+ {QAccessible::PopupMenu, AutomationControlType::AutomationControlType_Menu},
+ {QAccessible::MenuItem, AutomationControlType::AutomationControlType_MenuItem},
+ {QAccessible::ToolTip, AutomationControlType::AutomationControlType_ToolTip},
+ {QAccessible::Application, AutomationControlType::AutomationControlType_Custom},
+ {QAccessible::Document, AutomationControlType::AutomationControlType_Document},
+ {QAccessible::Pane, AutomationControlType::AutomationControlType_Pane},
+ {QAccessible::Chart, AutomationControlType::AutomationControlType_Custom},
+ {QAccessible::Dialog, AutomationControlType::AutomationControlType_Window},
+ {QAccessible::Border, AutomationControlType::AutomationControlType_Custom},
+ {QAccessible::Grouping, AutomationControlType::AutomationControlType_Group},
+ {QAccessible::Separator, AutomationControlType::AutomationControlType_Separator},
+ {QAccessible::ToolBar, AutomationControlType::AutomationControlType_ToolBar},
+ {QAccessible::StatusBar, AutomationControlType::AutomationControlType_StatusBar},
+ {QAccessible::Table, AutomationControlType::AutomationControlType_Table},
+ {QAccessible::ColumnHeader, AutomationControlType::AutomationControlType_Header},
+ {QAccessible::RowHeader, AutomationControlType::AutomationControlType_Header},
+ {QAccessible::Column, AutomationControlType::AutomationControlType_HeaderItem},
+ {QAccessible::Row, AutomationControlType::AutomationControlType_HeaderItem},
+ {QAccessible::Cell, AutomationControlType::AutomationControlType_DataItem},
+ {QAccessible::Link, AutomationControlType::AutomationControlType_Hyperlink},
+ {QAccessible::HelpBalloon, AutomationControlType::AutomationControlType_ToolTip},
+ {QAccessible::Assistant, AutomationControlType::AutomationControlType_Custom},
+ {QAccessible::List, AutomationControlType::AutomationControlType_List},
+ {QAccessible::ListItem, AutomationControlType::AutomationControlType_ListItem},
+ {QAccessible::Tree, AutomationControlType::AutomationControlType_Tree},
+ {QAccessible::TreeItem, AutomationControlType::AutomationControlType_TreeItem},
+ {QAccessible::PageTab, AutomationControlType::AutomationControlType_TabItem},
+ {QAccessible::PropertyPage, AutomationControlType::AutomationControlType_Custom},
+ {QAccessible::Indicator, AutomationControlType::AutomationControlType_Custom},
+ {QAccessible::Graphic, AutomationControlType::AutomationControlType_Image},
+ {QAccessible::StaticText, AutomationControlType::AutomationControlType_Edit},
+ {QAccessible::EditableText, AutomationControlType::AutomationControlType_Edit},
+ {QAccessible::Button, AutomationControlType::AutomationControlType_Button},
+ {QAccessible::CheckBox, AutomationControlType::AutomationControlType_CheckBox},
+ {QAccessible::RadioButton, AutomationControlType::AutomationControlType_RadioButton},
+ {QAccessible::ComboBox, AutomationControlType::AutomationControlType_ComboBox},
+ {QAccessible::ProgressBar, AutomationControlType::AutomationControlType_ProgressBar},
+ {QAccessible::Dial, AutomationControlType::AutomationControlType_Custom},
+ {QAccessible::HotkeyField, AutomationControlType::AutomationControlType_Custom},
+ {QAccessible::Slider, AutomationControlType::AutomationControlType_Slider},
+ {QAccessible::SpinBox, AutomationControlType::AutomationControlType_Spinner},
+ {QAccessible::Canvas, AutomationControlType::AutomationControlType_Custom},
+ {QAccessible::Animation, AutomationControlType::AutomationControlType_Custom},
+ {QAccessible::Equation, AutomationControlType::AutomationControlType_Custom},
+ {QAccessible::ButtonDropDown, AutomationControlType::AutomationControlType_Button},
+ {QAccessible::ButtonMenu, AutomationControlType::AutomationControlType_Button},
+ {QAccessible::ButtonDropGrid, AutomationControlType::AutomationControlType_Button},
+ {QAccessible::Whitespace, AutomationControlType::AutomationControlType_Custom},
+ {QAccessible::PageTabList, AutomationControlType::AutomationControlType_Tab},
+ {QAccessible::Clock, AutomationControlType::AutomationControlType_Custom},
+ {QAccessible::Splitter, AutomationControlType::AutomationControlType_Custom},
+ };
+
+ return mapping.value(role, AutomationControlType::AutomationControlType_Custom);
+}
+
+// True if a character can be a separator for a text unit.
+bool isTextUnitSeparator(TextUnit unit, const QChar &ch)
+{
+ return (((unit == TextUnit_Word) || (unit == TextUnit_Format)) && ch.isSpace())
+ || ((unit == TextUnit_Line) && (ch.toLatin1() == '\n'));
+}
+
+HRESULT qHString(const QString &str, HSTRING *returnValue)
+{
+ if (!returnValue)
+ return E_INVALIDARG;
+
+ const wchar_t *wstr = reinterpret_cast<const wchar_t *>(str.utf16());
+ return ::WindowsCreateString(wstr, static_cast<UINT32>(::wcslen(wstr)), returnValue);
+}
+
+QString hStrToQStr(const HSTRING &hStr)
+{
+ quint32 len;
+ const wchar_t *wstr = ::WindowsGetStringRawBuffer(hStr, &len);
+ return QString::fromWCharArray(wstr, len);
+}
+
+} // namespace QWinRTUiAutomation
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiautils.h b/src/plugins/platforms/winrt/uiautomation/qwinrtuiautils.h
new file mode 100644
index 0000000000..9519cb4eb5
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiautils.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTUIAUTILS_H
+#define QWINRTUIAUTILS_H
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include <QtCore/QString>
+#include <QtCore/qt_windows.h>
+#include <QtGui/QAccessible>
+#include <QtGui/QAccessibleInterface>
+#include <QtGui/QWindow>
+#include <QtCore/QLoggingCategory>
+
+#include <wrl.h>
+#include <windows.ui.xaml.h>
+#include <functional>
+
+QT_BEGIN_NAMESPACE
+
+Q_DECLARE_LOGGING_CATEGORY(lcQpaUiAutomation)
+
+namespace QWinRTUiAutomation {
+
+QWindow *windowForAccessible(const QAccessibleInterface *accessible);
+
+QAccessibleInterface *accessibleForId(QAccessible::Id id);
+
+QAccessible::Id idForAccessible(QAccessibleInterface *accessible);
+
+ABI::Windows::UI::Xaml::Automation::Peers::AutomationControlType roleToControlType(QAccessible::Role role);
+
+bool isTextUnitSeparator(ABI::Windows::UI::Xaml::Automation::Text::TextUnit unit, const QChar &ch);
+
+HRESULT qHString(const QString &str, HSTRING *returnValue);
+
+QString hStrToQStr(const HSTRING &hStr);
+
+} // namespace QWinRTUiAutomation
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
+
+#endif // QWINRTUIAUTILS_H
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiavalueprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiavalueprovider.cpp
new file mode 100644
index 0000000000..21389b74d2
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiavalueprovider.cpp
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiavalueprovider.h"
+#include "qwinrtuiametadatacache.h"
+#include "qwinrtuiautils.h"
+
+#include <QtGui/QAccessible>
+#include <QtGui/QAccessibleInterface>
+#include <QtCore/QLoggingCategory>
+#include <QtCore/QString>
+#include <QtCore/private/qeventdispatcher_winrt_p.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace QWinRTUiAutomation;
+using namespace ABI::Windows::UI::Xaml::Automation;
+using namespace ABI::Windows::UI::Xaml::Automation::Provider;
+
+QWinRTUiaValueProvider::QWinRTUiaValueProvider(QAccessible::Id id) :
+ QWinRTUiaBaseProvider(id)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+}
+
+QWinRTUiaValueProvider::~QWinRTUiaValueProvider()
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+}
+
+// True for read-only controls.
+HRESULT STDMETHODCALLTYPE QWinRTUiaValueProvider::get_IsReadOnly(boolean *value)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!value)
+ return E_INVALIDARG;
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ *value = (metadata->state().readOnly != 0);
+ return S_OK;
+}
+
+// Returns the value in text form.
+HRESULT STDMETHODCALLTYPE QWinRTUiaValueProvider::get_Value(HSTRING *value)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!value)
+ return E_INVALIDARG;
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ return qHString(metadata->value(), value);
+}
+
+// Sets the value associated with the control.
+HRESULT STDMETHODCALLTYPE QWinRTUiaValueProvider::SetValue(HSTRING value)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ auto accid = id();
+ auto tmpValue = QSharedPointer<QString>(new QString);
+ auto ptrValue = new QSharedPointer<QString>(tmpValue);
+
+ *tmpValue = hStrToQStr(value);
+
+ QEventDispatcherWinRT::runOnMainThread([accid, ptrValue]() {
+
+ if (QAccessibleInterface *accessible = accessibleForId(accid)) {
+
+ // First sets the value as a text.
+ accessible->setText(QAccessible::Value, **ptrValue);
+
+ // Then, if the control supports the value interface (range value)
+ // and the supplied text can be converted to a number, and that number
+ // lies within the min/max limits, sets it as the control's current (numeric) value.
+ if (QAccessibleValueInterface *valueInterface = accessible->valueInterface()) {
+ bool ok = false;
+ double numval = (*ptrValue)->toDouble(&ok);
+ if (ok) {
+ double minimum = valueInterface->minimumValue().toDouble();
+ double maximum = valueInterface->maximumValue().toDouble();
+ if ((numval >= minimum) && (numval <= maximum)) {
+ valueInterface->setCurrentValue(QVariant(numval));
+ }
+ }
+ }
+ }
+ QWinRTUiaMetadataCache::instance()->load(accid);
+ delete ptrValue;
+ return S_OK;
+ }, 0);
+
+ return S_OK;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiavalueprovider.h b/src/plugins/platforms/winrt/uiautomation/qwinrtuiavalueprovider.h
new file mode 100644
index 0000000000..d9cd5d200d
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiavalueprovider.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTUIAVALUEPROVIDER_H
+#define QWINRTUIAVALUEPROVIDER_H
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiabaseprovider.h"
+
+#include <wrl.h>
+#include <windows.ui.xaml.h>
+
+QT_BEGIN_NAMESPACE
+
+// Implements the Value control pattern provider.
+// Supported for all controls that can return text(QAccessible::Value).
+class QWinRTUiaValueProvider :
+ public QWinRTUiaBaseProvider,
+ public Microsoft::WRL::RuntimeClass<ABI::Windows::UI::Xaml::Automation::Provider::IValueProvider>
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(QWinRTUiaValueProvider)
+ InspectableClass(L"QWinRTUiaValueProvider", BaseTrust);
+
+public:
+ explicit QWinRTUiaValueProvider(QAccessible::Id id);
+ virtual ~QWinRTUiaValueProvider();
+
+ // IValueProvider
+ HRESULT STDMETHODCALLTYPE get_IsReadOnly(boolean *value) override;
+ HRESULT STDMETHODCALLTYPE get_Value(HSTRING *value) override;
+ HRESULT STDMETHODCALLTYPE SetValue(HSTRING value) override;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
+
+#endif // QWINRTUIAVALUEPROVIDER_H
diff --git a/src/plugins/platforms/winrt/uiautomation/uiautomation.pri b/src/plugins/platforms/winrt/uiautomation/uiautomation.pri
new file mode 100644
index 0000000000..ca0dfae53f
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/uiautomation.pri
@@ -0,0 +1,45 @@
+
+SOURCES += \
+ $$PWD/qwinrtuiaaccessibility.cpp \
+ $$PWD/qwinrtuiabaseprovider.cpp \
+ $$PWD/qwinrtuiacontrolmetadata.cpp \
+ $$PWD/qwinrtuiagriditemprovider.cpp \
+ $$PWD/qwinrtuiagridprovider.cpp \
+ $$PWD/qwinrtuiainvokeprovider.cpp \
+ $$PWD/qwinrtuiamainprovider.cpp \
+ $$PWD/qwinrtuiametadatacache.cpp \
+ $$PWD/qwinrtuiapeervector.cpp \
+ $$PWD/qwinrtuiaprovidercache.cpp \
+ $$PWD/qwinrtuiarangevalueprovider.cpp \
+ $$PWD/qwinrtuiaselectionitemprovider.cpp \
+ $$PWD/qwinrtuiaselectionprovider.cpp \
+ $$PWD/qwinrtuiatableitemprovider.cpp \
+ $$PWD/qwinrtuiatableprovider.cpp \
+ $$PWD/qwinrtuiatextprovider.cpp \
+ $$PWD/qwinrtuiatextrangeprovider.cpp \
+ $$PWD/qwinrtuiatoggleprovider.cpp \
+ $$PWD/qwinrtuiautils.cpp \
+ $$PWD/qwinrtuiavalueprovider.cpp
+
+HEADERS += \
+ $$PWD/qwinrtuiaaccessibility.h \
+ $$PWD/qwinrtuiabaseprovider.h \
+ $$PWD/qwinrtuiacontrolmetadata.h \
+ $$PWD/qwinrtuiaemptypropertyvalue.h \
+ $$PWD/qwinrtuiagriditemprovider.h \
+ $$PWD/qwinrtuiagridprovider.h \
+ $$PWD/qwinrtuiainvokeprovider.h \
+ $$PWD/qwinrtuiamainprovider.h \
+ $$PWD/qwinrtuiametadatacache.h \
+ $$PWD/qwinrtuiapeervector.h \
+ $$PWD/qwinrtuiaprovidercache.h \
+ $$PWD/qwinrtuiarangevalueprovider.h \
+ $$PWD/qwinrtuiaselectionitemprovider.h \
+ $$PWD/qwinrtuiaselectionprovider.h \
+ $$PWD/qwinrtuiatableitemprovider.h \
+ $$PWD/qwinrtuiatableprovider.h \
+ $$PWD/qwinrtuiatextprovider.h \
+ $$PWD/qwinrtuiatextrangeprovider.h \
+ $$PWD/qwinrtuiatoggleprovider.h \
+ $$PWD/qwinrtuiautils.h \
+ $$PWD/qwinrtuiavalueprovider.h
diff --git a/src/plugins/platforms/winrt/winrt.pro b/src/plugins/platforms/winrt/winrt.pro
index 042b270cff..167c5b0448 100644
--- a/src/plugins/platforms/winrt/winrt.pro
+++ b/src/plugins/platforms/winrt/winrt.pro
@@ -13,6 +13,7 @@ LIBS += -lws2_32 -ld3d11
SOURCES = \
main.cpp \
qwinrtbackingstore.cpp \
+ qwinrtcanvas.cpp \
qwinrtclipboard.cpp \
qwinrtcursor.cpp \
qwinrtdrag.cpp \
@@ -31,6 +32,7 @@ SOURCES = \
HEADERS = \
qwinrtbackingstore.h \
+ qwinrtcanvas.h \
qwinrtclipboard.h \
qwinrtcursor.h \
qwinrtdrag.h \
@@ -58,6 +60,8 @@ contains(DEFINES, QT_NO_DRAGANDDROP) {
HEADERS -= qwinrtdrag.h
}
+qtConfig(accessibility): include($$PWD/uiautomation/uiautomation.pri)
+
PLUGIN_TYPE = platforms
PLUGIN_CLASS_NAME = QWinRTIntegrationPlugin
!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = -