diff options
author | Friedemann Kleint <Friedemann.Kleint@digia.com> | 2014-06-13 14:14:12 +0200 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@digia.com> | 2014-06-16 16:13:07 +0200 |
commit | b7e905eaa8769c7a4e21c43f20fb995bcd19d0ba (patch) | |
tree | 45cdc50ff29ba77eee9d599a1557e24896d95860 | |
parent | f2a0dbe9128d5fd6caa8711b8b7495eba570ba63 (diff) |
Add QWinMime.
Add class QWinMime (equivalent to WindowsMime in Qt 4).
[ChangeLog][QWinMime] Added abstract class QWinMime (equivalent
to WindowsMime in Qt 4) for registering custom mime type
conversions.
Task-number: QTBUG-39559
Change-Id: Ie8ff4db6cd0ce64f65b83232dc91d771238663d1
Reviewed-by: Joerg Bornemann <joerg.bornemann@digia.com>
-rw-r--r-- | src/winextras/qwinmime.cpp | 190 | ||||
-rw-r--r-- | src/winextras/qwinmime.h | 78 | ||||
-rw-r--r-- | src/winextras/winextras.pro | 8 | ||||
-rw-r--r-- | tests/auto/auto.pro | 3 | ||||
-rw-r--r-- | tests/auto/qwinmime/qwinmime.pro | 4 | ||||
-rw-r--r-- | tests/auto/qwinmime/tst_qwinmime.cpp | 150 |
6 files changed, 430 insertions, 3 deletions
diff --git a/src/winextras/qwinmime.cpp b/src/winextras/qwinmime.cpp new file mode 100644 index 0000000..73d109a --- /dev/null +++ b/src/winextras/qwinmime.cpp @@ -0,0 +1,190 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtWinExtras module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwinmime.h" + +#include <QtGui/QGuiApplication> +#include <QtCore/QMetaObject> +#include <QtCore/QDebug> + +#include <qpa/qplatformnativeinterface.h> + +QT_BEGIN_NAMESPACE + +/*! + \class QWinMime + \inmodule QtWinExtras + \brief The QWinMime class maps open-standard MIME to Window Clipboard formats. + + Qt's drag-and-drop and clipboard facilities use the MIME standard. + On X11, this maps trivially to the Xdnd protocol, but on Windows + although some applications use MIME types to describe clipboard + formats, others use arbitrary non-standardized naming conventions, + or unnamed built-in formats of Windows. + + By instantiating subclasses of QWinMime that provide conversions + between Windows Clipboard and MIME formats, you can convert + proprietary clipboard formats to MIME formats. + + Qt has predefined support for the following Windows Clipboard formats: + + \table + \header \li Windows Format \li Equivalent MIME type + \row \li \c CF_UNICODETEXT \li \c text/plain + \row \li \c CF_TEXT \li \c text/plain + \row \li \c CF_DIB \li \c{image/xyz}, where \c xyz is + a \l{QImageWriter::supportedImageFormats()}{Qt image format} + \row \li \c CF_HDROP \li \c text/uri-list + \row \li \c CF_INETURL \li \c text/uri-list + \row \li \c CF_HTML \li \c text/html + \endtable + + An example use of this class would be to map the Windows Metafile + clipboard format (\c CF_METAFILEPICT) to and from the MIME type + \c{image/x-wmf}. This conversion might simply be adding or removing + a header, or even just passing on the data. See \l{Drag and Drop} + for more information on choosing and definition MIME types. + + You can check if a MIME type is convertible using canConvertFromMime() and + can perform conversions with convertToMime() and convertFromMime(). + + \since 5.4 +*/ + +/*! + Constructs a new conversion object, adding it to the globally accessed + list of available converters. +*/ +QWinMime::QWinMime() +{ + if (!QMetaObject::invokeMethod(QGuiApplication::platformNativeInterface(), + "registerWindowsMime", Q_ARG(void *, this))) { + qWarning() << Q_FUNC_INFO << "Unable to register mime type."; + } +} + +/*! + Destroys a conversion object, removing it from the global + list of available converters. +*/ +QWinMime::~QWinMime() +{ + if (!QMetaObject::invokeMethod(QGuiApplication::platformNativeInterface(), + "unregisterWindowsMime", Q_ARG(void *, this))) { + qWarning() << Q_FUNC_INFO << "Unable to unregister mime type."; + } +} + +/*! + Registers the MIME type \a mime, and returns an ID number + identifying the format on Windows. +*/ +int QWinMime::registerMimeType(const QString &mime) +{ + int result = 0; + if (!QMetaObject::invokeMethod(QGuiApplication::platformNativeInterface(), + "registerMimeType", + Q_RETURN_ARG(int, result), + Q_ARG(QString, mime))) { + qWarning() << Q_FUNC_INFO << "Unable to register mime type " << mime; + } + return result; +} + +/*! + \fn bool QWinMime::canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const + + Returns true if the converter can convert from the \a mimeData to + the format specified in \a formatetc. + + All subclasses must reimplement this pure virtual function. +*/ + +/*! + \fn bool QWinMime::canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const + + Returns true if the converter can convert to the \a mimeType from + the available formats in \a pDataObj. + + All subclasses must reimplement this pure virtual function. +*/ + +/*! + \fn QString QWinMime::mimeForFormat(const FORMATETC &formatetc) const + + Returns the mime type that will be created form the format specified + in \a formatetc, or an empty string if this converter does not support + \a formatetc. + + All subclasses must reimplement this pure virtual function. +*/ + +/*! + \fn QVector<FORMATETC> QWinMime::formatsForMime(const QString &mimeType, const QMimeData *mimeData) const + + Returns a QVector of FORMATETC structures representing the different windows clipboard + formats that can be provided for the \a mimeType from the \a mimeData. + + All subclasses must reimplement this pure virtual function. +*/ + +/*! + \fn QVariant QWinMime::convertToMime(const QString &mimeType, IDataObject *pDataObj, + QVariant::Type preferredType) const + + Returns a QVariant containing the converted data for \a mimeType from \a pDataObj. + If possible the QVariant should be of the \a preferredType to avoid needless conversions. + + All subclasses must reimplement this pure virtual function. +*/ + +/*! + \fn bool QWinMime::convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const + + Convert the \a mimeData to the format specified in \a formatetc. + The converted data should then be placed in \a pmedium structure. + + Return true if the conversion was successful. + + All subclasses must reimplement this pure virtual function. +*/ + +QT_END_NAMESPACE diff --git a/src/winextras/qwinmime.h b/src/winextras/qwinmime.h new file mode 100644 index 0000000..633ad4d --- /dev/null +++ b/src/winextras/qwinmime.h @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtWinExtras module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWINMIME_H +#define QWINMIME_H + +#include <QtWinExtras/qwinextrasglobal.h> + +#include <QtCore/qt_windows.h> +#include <QtCore/QVector> +#include <QtCore/QList> +#include <QtCore/QVariant> + +QT_BEGIN_NAMESPACE + +class QMimeData; + +class Q_WINEXTRAS_EXPORT QWinMime // Keep in sync with QWindowsMime in the Windows platform plugin. +{ + Q_DISABLE_COPY(QWinMime) +public: + QWinMime(); + virtual ~QWinMime(); + + // for converting from Qt + virtual bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const = 0; + virtual bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const = 0; + virtual QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const = 0; + + // for converting to Qt + virtual bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const = 0; + virtual QVariant convertToMime(const QString &mimeType, IDataObject *pDataObj, QVariant::Type preferredType) const = 0; + virtual QString mimeForFormat(const FORMATETC &formatetc) const = 0; + + static int registerMimeType(const QString &mime); +}; + +QT_END_NAMESPACE + +#endif // QWINMIME_H diff --git a/src/winextras/winextras.pro b/src/winextras/winextras.pro index 4537f94..7f6bba4 100644 --- a/src/winextras/winextras.pro +++ b/src/winextras/winextras.pro @@ -2,6 +2,8 @@ TARGET = QtWinExtras load(qt_module) +QT += gui-private core-private + SOURCES += \ qwinfunctions.cpp \ qwinfunctions_p.cpp \ @@ -14,7 +16,8 @@ SOURCES += \ qwineventfilter.cpp \ qwinthumbnailtoolbar.cpp \ qwinthumbnailtoolbutton.cpp \ - qwinevent.cpp + qwinevent.cpp \ + qwinmime.cpp HEADERS += \ qwinfunctions.h \ @@ -37,7 +40,8 @@ HEADERS += \ qwinthumbnailtoolbutton.h \ qwinthumbnailtoolbutton_p.h \ qwinevent.h \ - windowsguidsdefs_p.h + windowsguidsdefs_p.h \ + qwinmime.h QMAKE_DOCS = $$PWD/doc/qtwinextras.qdocconf diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index 12456c8..1e5d1ba 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -6,4 +6,5 @@ SUBDIRS += \ qpixmap \ qwintaskbarbutton \ qwintaskbarprogress \ - qwinjumplist + qwinjumplist \ + qwinmime diff --git a/tests/auto/qwinmime/qwinmime.pro b/tests/auto/qwinmime/qwinmime.pro new file mode 100644 index 0000000..9a1563a --- /dev/null +++ b/tests/auto/qwinmime/qwinmime.pro @@ -0,0 +1,4 @@ +CONFIG += testcase +TARGET = tst_qwinmime +QT += testlib winextras widgets +SOURCES += tst_qwinmime.cpp diff --git a/tests/auto/qwinmime/tst_qwinmime.cpp b/tests/auto/qwinmime/tst_qwinmime.cpp new file mode 100644 index 0000000..a91a972 --- /dev/null +++ b/tests/auto/qwinmime/tst_qwinmime.cpp @@ -0,0 +1,150 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the test suite 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> +#include <QWinMime> +#include <QtTest/QtTest> +#include <QtGui/QClipboard> +#include <QtGui/QPixmap> +#include <QtCore/QVariant> + +class TestMime : public QWinMime +{ +public: + TestMime(bool verbose = false) : formatsForMimeCalled(false), m_verbose(verbose) {} + + bool canConvertFromMime(const FORMATETC &, const QMimeData *mimeData) const Q_DECL_OVERRIDE + { + if (m_verbose) + qDebug() << Q_FUNC_INFO << mimeData->formats(); + return false; + } + + bool convertFromMime(const FORMATETC &, const QMimeData *, STGMEDIUM *) const Q_DECL_OVERRIDE + { + if (m_verbose) + qDebug() << Q_FUNC_INFO; + return false; + } + + QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const Q_DECL_OVERRIDE + { + formatsForMimeCalled = true; + if (m_verbose) + qDebug() << Q_FUNC_INFO << mimeType << mimeData->formats(); + return QVector<FORMATETC>(); + } + + bool canConvertToMime(const QString &mimeType, IDataObject *) const Q_DECL_OVERRIDE + { + if (m_verbose) + qDebug() << Q_FUNC_INFO << mimeType; + return false; + } + + QVariant convertToMime(const QString &mimeType, IDataObject *, QVariant::Type preferredType) const Q_DECL_OVERRIDE + { + if (m_verbose) + qDebug() << Q_FUNC_INFO << mimeType << preferredType; + return QVariant(); + } + + QString mimeForFormat(const FORMATETC &) const Q_DECL_OVERRIDE + { + if (m_verbose) + qDebug() << Q_FUNC_INFO; + return QString(); + } + + mutable bool formatsForMimeCalled; + +private: + const bool m_verbose; +}; + +class tst_QWinMime : public QObject +{ + Q_OBJECT + +private slots: + void testRegisterType(); + void testWinMime_data(); + void testWinMime(); +}; + +void tst_QWinMime::testRegisterType() +{ + const int type = QWinMime::registerMimeType("foo/bar"); + QVERIFY2(type >= 0, QByteArray::number(type)); +} + +void tst_QWinMime::testWinMime_data() +{ + QTest::addColumn<QVariant>("data"); + QTest::newRow("string") << QVariant(QStringLiteral("bla")); + QPixmap pm(10, 10); + pm.fill(Qt::black); + QTest::newRow("pixmap") << QVariant(pm); +} + +void tst_QWinMime::testWinMime() +{ + QFETCH(QVariant, data); + // Basic smoke test for crashes, copy some text into clipboard and check whether + // the test implementation is called. + TestMime testMime; + QClipboard *clipboard = QApplication::clipboard(); + switch (data.type()) { + case QMetaType::QString: + clipboard->setText(data.toString()); + break; + case QMetaType::QPixmap: + clipboard->setPixmap(data.value<QPixmap>()); + break; + default: + break; + } + QTRY_VERIFY(testMime.formatsForMimeCalled); +} + +QTEST_MAIN(tst_QWinMime) + +#include "tst_qwinmime.moc" |