summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms
diff options
context:
space:
mode:
authorMaurice Kalinowski <maurice.kalinowski@theqtcompany.com>2016-02-15 16:01:21 +0100
committerMaurice Kalinowski <maurice.kalinowski@theqtcompany.com>2016-02-17 04:51:46 +0000
commite7a06c984364a3ffb86b32921aa60672f7b71600 (patch)
tree2d45ac0674f6bb7a9669cc6a7c21ccfefb707655 /src/plugins/platforms
parentad16703fa818b6d2a867b862bbbe51d9517d9fb9 (diff)
winrt: Fix clipboard
Native implementation was missing and so far it only used the Qt internal fallback mode. Unfortunately this does not apply to Windows Phone 8.1. Task-number: QTBUG-49766 Change-Id: I8cbbb0c843d077d7df1396d673fedeab2799b5a6 Reviewed-by: Oliver Wolff <oliver.wolff@theqtcompany.com>
Diffstat (limited to 'src/plugins/platforms')
-rw-r--r--src/plugins/platforms/winrt/qwinrtclipboard.cpp185
-rw-r--r--src/plugins/platforms/winrt/qwinrtclipboard.h78
-rw-r--r--src/plugins/platforms/winrt/qwinrtintegration.cpp9
-rw-r--r--src/plugins/platforms/winrt/qwinrtintegration.h1
-rw-r--r--src/plugins/platforms/winrt/winrt.pro2
5 files changed, 275 insertions, 0 deletions
diff --git a/src/plugins/platforms/winrt/qwinrtclipboard.cpp b/src/plugins/platforms/winrt/qwinrtclipboard.cpp
new file mode 100644
index 0000000000..4e71490902
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtclipboard.cpp
@@ -0,0 +1,185 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwinrtclipboard.h"
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/qfunctions_winrt.h>
+#include <QtCore/private/qeventdispatcher_winrt_p.h>
+
+#include <Windows.ApplicationModel.datatransfer.h>
+
+#include <functional>
+
+using namespace ABI::Windows::ApplicationModel::DataTransfer;
+using namespace ABI::Windows::Foundation;
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+
+typedef IEventHandler<IInspectable *> ContentChangedHandler;
+
+#define RETURN_NULLPTR_IF_FAILED(msg) RETURN_IF_FAILED(msg, return nullptr)
+
+QT_BEGIN_NAMESPACE
+
+QWinRTClipboard::QWinRTClipboard()
+{
+#ifndef Q_OS_WINPHONE
+ QEventDispatcherWinRT::runOnXamlThread([this]() {
+ HRESULT hr;
+ hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_ApplicationModel_DataTransfer_Clipboard).Get(),
+ &m_nativeClipBoard);
+ Q_ASSERT_SUCCEEDED(hr);
+
+ EventRegistrationToken tok;
+ hr = m_nativeClipBoard->add_ContentChanged(Callback<ContentChangedHandler>(this, &QWinRTClipboard::onContentChanged).Get(), &tok);
+ Q_ASSERT_SUCCEEDED(hr);
+
+ return hr;
+ });
+#endif // !Q_OS_WINPHONE
+}
+
+QMimeData *QWinRTClipboard::mimeData(QClipboard::Mode mode)
+{
+ if (!supportsMode(mode))
+ return nullptr;
+
+#ifndef Q_OS_WINPHONE
+ ComPtr<IDataPackageView> view;
+ HRESULT hr;
+ hr = m_nativeClipBoard->GetContent(&view);
+ RETURN_NULLPTR_IF_FAILED("Could not get clipboard content.");
+
+ ComPtr<IAsyncOperation<HSTRING>> op;
+ HString result;
+ // This throws a security exception (WinRT originate error / 0x40080201.
+ // Unfortunately there seems to be no way to avoid this, neither
+ // running on the XAML thread, nor some other way. Stack Overflow
+ // confirms this problem since Windows (Phone) 8.0.
+ hr = view->GetTextAsync(&op);
+ RETURN_NULLPTR_IF_FAILED("Could not get clipboard text.");
+
+ hr = QWinRTFunctions::await(op, result.GetAddressOf());
+ RETURN_NULLPTR_IF_FAILED("Could not get clipboard text content");
+
+ quint32 size;
+ const wchar_t *textStr = result.GetRawBuffer(&size);
+ QString text = QString::fromWCharArray(textStr, size);
+ text.replace(QStringLiteral("\r\n"), QStringLiteral("\n"));
+ m_mimeData.setText(text);
+
+ return &m_mimeData;
+#else // Q_OS_WINPHONE
+ return QPlatformClipboard::mimeData(mode);
+#endif // Q_OS_WINPHONE
+}
+
+// Inspired by QWindowsMimeText::convertFromMime
+inline QString convertToWindowsLineEnding(const QString &text)
+{
+ const QChar *u = text.unicode();
+ QString res;
+ const int s = text.length();
+ int maxsize = s + s / 40 + 3;
+ res.resize(maxsize);
+ int ri = 0;
+ bool cr = false;
+ for (int i = 0; i < s; ++i) {
+ if (*u == QLatin1Char('\r'))
+ cr = true;
+ else {
+ if (*u == QLatin1Char('\n') && !cr)
+ res[ri++] = QLatin1Char('\r');
+ cr = false;
+ }
+ res[ri++] = *u;
+ if (ri+3 >= maxsize) {
+ maxsize += maxsize / 4;
+ res.resize(maxsize);
+ }
+ ++u;
+ }
+ res.truncate(ri);
+ return res;
+}
+
+void QWinRTClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode)
+{
+ if (!supportsMode(mode))
+ return;
+
+#ifndef Q_OS_WINPHONE
+ const QString text = data->text();
+ HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([this, text]() {
+ HRESULT hr;
+ ComPtr<IDataPackage> package;
+ hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_ApplicationModel_DataTransfer_DataPackage).Get(),
+ &package);
+
+ const QString nativeString = convertToWindowsLineEnding(text);
+ HStringReference textRef(reinterpret_cast<LPCWSTR>(nativeString.utf16()), nativeString.length());
+
+ hr = package->SetText(textRef.Get());
+ RETURN_HR_IF_FAILED("Could not set text to clipboard data package.");
+
+ hr = m_nativeClipBoard->SetContent(package.Get());
+ RETURN_HR_IF_FAILED("Could not set clipboard content.");
+ return S_OK;
+ });
+ RETURN_VOID_IF_FAILED("Could not set clipboard text.");
+ emitChanged(mode);
+#else // Q_OS_WINPHONE
+ QPlatformClipboard::setMimeData(data, mode);
+#endif // Q_OS_WINPHONE
+}
+
+bool QWinRTClipboard::supportsMode(QClipboard::Mode mode) const
+{
+#ifndef Q_OS_WINPHONE
+ return mode == QClipboard::Clipboard;
+#else
+ return QPlatformClipboard::supportsMode(mode);
+#endif
+}
+
+HRESULT QWinRTClipboard::onContentChanged(IInspectable *, IInspectable *)
+{
+ emitChanged(QClipboard::Clipboard);
+ return S_OK;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtclipboard.h b/src/plugins/platforms/winrt/qwinrtclipboard.h
new file mode 100644
index 0000000000..1fb10bdfc0
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtclipboard.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTPLATFORMCLIPBOARD_H
+#define QWINRTPLATFORMCLIPBOARD_H
+
+#include <qpa/qplatformclipboard.h>
+#include <QMimeData>
+
+#include <wrl.h>
+
+#ifndef Q_OS_WINPHONE
+namespace ABI {
+ namespace Windows {
+ namespace ApplicationModel {
+ namespace DataTransfer {
+ struct IClipboardStatics;
+ }
+ }
+ }
+}
+#endif // !Q_OS_WINPHONE
+
+QT_BEGIN_NAMESPACE
+
+class QWinRTClipboard: public QPlatformClipboard
+{
+public:
+ QWinRTClipboard();
+
+ QMimeData *mimeData(QClipboard::Mode mode = QClipboard::Clipboard) Q_DECL_OVERRIDE;
+ void setMimeData(QMimeData *data, QClipboard::Mode mode = QClipboard::Clipboard) Q_DECL_OVERRIDE;
+ bool supportsMode(QClipboard::Mode mode) const Q_DECL_OVERRIDE;
+
+ HRESULT onContentChanged(IInspectable *, IInspectable *);
+private:
+#ifndef Q_OS_WINPHONE
+ Microsoft::WRL::ComPtr<ABI::Windows::ApplicationModel::DataTransfer::IClipboardStatics> m_nativeClipBoard;
+#endif
+ QMimeData m_mimeData;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINRTPLATFORMCLIPBOARD_H
diff --git a/src/plugins/platforms/winrt/qwinrtintegration.cpp b/src/plugins/platforms/winrt/qwinrtintegration.cpp
index 9dac667ce5..30c0e81e21 100644
--- a/src/plugins/platforms/winrt/qwinrtintegration.cpp
+++ b/src/plugins/platforms/winrt/qwinrtintegration.cpp
@@ -44,6 +44,7 @@
#include "qwinrteglcontext.h"
#include "qwinrtfontdatabase.h"
#include "qwinrttheme.h"
+#include "qwinrtclipboard.h"
#include <QtGui/QOffscreenSurface>
#include <QtGui/QOpenGLContext>
@@ -111,6 +112,7 @@ class QWinRTIntegrationPrivate
public:
QPlatformFontDatabase *fontDatabase;
QPlatformServices *platformServices;
+ QPlatformClipboard *clipboard;
QWinRTScreen *mainScreen;
QScopedPointer<QWinRTInputContext> inputContext;
@@ -195,6 +197,7 @@ QWinRTIntegration::QWinRTIntegration() : d_ptr(new QWinRTIntegrationPrivate)
screenAdded(d->mainScreen);
d->platformServices = new QWinRTServices;
+ d->clipboard = new QWinRTClipboard;
}
QWinRTIntegration::~QWinRTIntegration()
@@ -300,6 +303,12 @@ QPlatformServices *QWinRTIntegration::services() const
return d->platformServices;
}
+QPlatformClipboard *QWinRTIntegration::clipboard() const
+{
+ Q_D(const QWinRTIntegration);
+ return d->clipboard;
+}
+
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 9bf5d27973..1ed286ab2e 100644
--- a/src/plugins/platforms/winrt/qwinrtintegration.h
+++ b/src/plugins/platforms/winrt/qwinrtintegration.h
@@ -93,6 +93,7 @@ public:
QPlatformFontDatabase *fontDatabase() const Q_DECL_OVERRIDE;
QPlatformInputContext *inputContext() const Q_DECL_OVERRIDE;
QPlatformServices *services() const Q_DECL_OVERRIDE;
+ QPlatformClipboard *clipboard() const Q_DECL_OVERRIDE;
Qt::KeyboardModifiers queryKeyboardModifiers() const Q_DECL_OVERRIDE;
QStringList themeNames() const Q_DECL_OVERRIDE;
diff --git a/src/plugins/platforms/winrt/winrt.pro b/src/plugins/platforms/winrt/winrt.pro
index be6aad02d1..991ec1789b 100644
--- a/src/plugins/platforms/winrt/winrt.pro
+++ b/src/plugins/platforms/winrt/winrt.pro
@@ -16,6 +16,7 @@ INCLUDEPATH += $$QT_SOURCE_TREE/src/3rdparty/freetype/include
SOURCES = \
main.cpp \
qwinrtbackingstore.cpp \
+ qwinrtclipboard.cpp \
qwinrtcursor.cpp \
qwinrteglcontext.cpp \
qwinrteventdispatcher.cpp \
@@ -33,6 +34,7 @@ SOURCES = \
HEADERS = \
qwinrtbackingstore.h \
+ qwinrtclipboard.h \
qwinrtcursor.h \
qwinrteglcontext.h \
qwinrteventdispatcher.h \