Windows: simplify registration of QWindowsMime implementations
Register the QWindowsMime implementation instance in the QWindowsMime constructor, and remove it again in the destructor. Provide a convenience static method to register a mime type. This makes it a lot easier to use the type, without having to use native interfaces. Since this requires adding a qwindowsmime.cpp file, move the (so far internal) documentation there. Task-number: QTBUG-93632 Change-Id: I3b5e45be6255bd11a576127304c4aec9d7364e69 Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
This commit is contained in:
parent
68f097923f
commit
fe1075332c
@ -413,7 +413,7 @@ qt_internal_extend_target(Gui CONDITION WIN32
|
|||||||
image/qpixmap_win.cpp
|
image/qpixmap_win.cpp
|
||||||
kernel/qwindowdefs_win.h
|
kernel/qwindowdefs_win.h
|
||||||
platform/windows/qwindowsguieventdispatcher.cpp platform/windows/qwindowsguieventdispatcher_p.h
|
platform/windows/qwindowsguieventdispatcher.cpp platform/windows/qwindowsguieventdispatcher_p.h
|
||||||
platform/windows/qwindowsmime_p.h
|
platform/windows/qwindowsmime_p.h platform/windows/qwindowsmime.cpp
|
||||||
platform/windows/qwindowsnativeinterface.cpp
|
platform/windows/qwindowsnativeinterface.cpp
|
||||||
rhi/cs_tdr_p.h
|
rhi/cs_tdr_p.h
|
||||||
rhi/qrhid3d11.cpp rhi/qrhid3d11_p.h
|
rhi/qrhid3d11.cpp rhi/qrhid3d11_p.h
|
||||||
|
153
src/gui/platform/windows/qwindowsmime.cpp
Normal file
153
src/gui/platform/windows/qwindowsmime.cpp
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
// Copyright (C) 2022 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||||
|
|
||||||
|
#include "qwindowsmime_p.h"
|
||||||
|
|
||||||
|
#include <QtGui/private/qguiapplication_p.h>
|
||||||
|
#include <QtGui/qpa/qplatformintegration.h>
|
||||||
|
|
||||||
|
using namespace QNativeInterface::Private;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\class QWindowsMime
|
||||||
|
\brief The QWindowsMime class maps open-standard MIME to Window Clipboard formats.
|
||||||
|
\internal
|
||||||
|
|
||||||
|
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 QWindowsMime 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().
|
||||||
|
|
||||||
|
\sa QWindowsMimeRegistry
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn bool QWindowsMime::canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const
|
||||||
|
\internal
|
||||||
|
|
||||||
|
Returns \c 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 QWindowsMime::canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const
|
||||||
|
\internal
|
||||||
|
|
||||||
|
Returns \c 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 QWindowsMime::mimeForFormat(const FORMATETC &formatetc) const
|
||||||
|
\internal
|
||||||
|
|
||||||
|
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 QList<FORMATETC> QWindowsMime::formatsForMime(const QString &mimeType, const QMimeData *mimeData) const
|
||||||
|
\internal
|
||||||
|
|
||||||
|
Returns a QList 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 QWindowsMime::convertToMime(const QString &mimeType, IDataObject *pDataObj,
|
||||||
|
QMetaType preferredType) const
|
||||||
|
\internal
|
||||||
|
|
||||||
|
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 QWindowsMime::convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const
|
||||||
|
\internal
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Constructs a QWindowsMime instance.
|
||||||
|
|
||||||
|
The instance is automatically registered, and will be called to convert data during
|
||||||
|
clipboard or drag'n'drop operations.
|
||||||
|
*/
|
||||||
|
QWindowsMime::QWindowsMime()
|
||||||
|
{
|
||||||
|
auto nativeWindowsApp = dynamic_cast<QWindowsApplication *>(QGuiApplicationPrivate::platformIntegration());
|
||||||
|
Q_ASSERT(nativeWindowsApp);
|
||||||
|
nativeWindowsApp->registerMime(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Constructs a QWindowsMime instance.
|
||||||
|
|
||||||
|
The instance is automatically unregistered.
|
||||||
|
*/
|
||||||
|
QWindowsMime::~QWindowsMime()
|
||||||
|
{
|
||||||
|
auto nativeWindowsApp = dynamic_cast<QWindowsApplication *>(QGuiApplicationPrivate::platformIntegration());
|
||||||
|
Q_ASSERT(nativeWindowsApp);
|
||||||
|
nativeWindowsApp->unregisterMime(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Registers the MIME type \a mime, and returns an ID number
|
||||||
|
identifying the format on Windows.
|
||||||
|
|
||||||
|
A mime type \c {application/x-qt-windows-mime;value="WindowsType"} will be
|
||||||
|
registered as the clipboard format for \c WindowsType.
|
||||||
|
*/
|
||||||
|
int QWindowsMime::registerMimeType(const QString &mimeType)
|
||||||
|
{
|
||||||
|
auto nativeWindowsApp = dynamic_cast<QWindowsApplication *>(QGuiApplicationPrivate::platformIntegration());
|
||||||
|
Q_ASSERT(nativeWindowsApp);
|
||||||
|
return nativeWindowsApp->registerMimeType(mimeType);
|
||||||
|
}
|
@ -30,7 +30,10 @@ namespace QNativeInterface::Private {
|
|||||||
class Q_GUI_EXPORT QWindowsMime
|
class Q_GUI_EXPORT QWindowsMime
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~QWindowsMime() = default;
|
QWindowsMime();
|
||||||
|
virtual ~QWindowsMime();
|
||||||
|
|
||||||
|
static int registerMimeType(const QString &mimeType);
|
||||||
|
|
||||||
// for converting from Qt
|
// for converting from Qt
|
||||||
virtual bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const = 0;
|
virtual bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const = 0;
|
||||||
|
@ -333,105 +333,6 @@ QDebug operator<<(QDebug d, IDataObject *dataObj)
|
|||||||
}
|
}
|
||||||
#endif // !QT_NO_DEBUG_STREAM
|
#endif // !QT_NO_DEBUG_STREAM
|
||||||
|
|
||||||
/*!
|
|
||||||
\class QWindowsMime
|
|
||||||
\brief The QWindowsMime class maps open-standard MIME to Window Clipboard formats.
|
|
||||||
\internal
|
|
||||||
|
|
||||||
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 QWindowsMime 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().
|
|
||||||
|
|
||||||
\sa QWindowsMimeRegistry
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
\fn bool QWindowsMime::canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const
|
|
||||||
|
|
||||||
Returns \c 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 QWindowsMime::canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const
|
|
||||||
|
|
||||||
Returns \c 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 QWindowsMime::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 QList<FORMATETC> QWindowsMime::formatsForMime(const QString &mimeType, const QMimeData *mimeData) const
|
|
||||||
|
|
||||||
Returns a QList 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 QWindowsMime::convertToMime(const QString &mimeType, IDataObject *pDataObj,
|
|
||||||
QMetaType 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 QWindowsMime::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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
class QWindowsMimeText : public QNativeInterface::Private::QWindowsMime
|
class QWindowsMimeText : public QNativeInterface::Private::QWindowsMime
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -605,8 +506,8 @@ private:
|
|||||||
|
|
||||||
QWindowsMimeURI::QWindowsMimeURI()
|
QWindowsMimeURI::QWindowsMimeURI()
|
||||||
{
|
{
|
||||||
CF_INETURL_W = QWindowsMimeRegistry::registerMimeType(QStringLiteral("UniformResourceLocatorW"));
|
CF_INETURL_W = registerMimeType(QStringLiteral("UniformResourceLocatorW"));
|
||||||
CF_INETURL = QWindowsMimeRegistry::registerMimeType(QStringLiteral("UniformResourceLocator"));
|
CF_INETURL = registerMimeType(QStringLiteral("UniformResourceLocator"));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QWindowsMimeURI::canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const
|
bool QWindowsMimeURI::canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const
|
||||||
@ -775,7 +676,7 @@ private:
|
|||||||
|
|
||||||
QWindowsMimeHtml::QWindowsMimeHtml()
|
QWindowsMimeHtml::QWindowsMimeHtml()
|
||||||
{
|
{
|
||||||
CF_HTML = QWindowsMimeRegistry::registerMimeType(QStringLiteral("HTML Format"));
|
CF_HTML = registerMimeType(QStringLiteral("HTML Format"));
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<FORMATETC> QWindowsMimeHtml::formatsForMime(const QString &mimeType, const QMimeData *mimeData) const
|
QList<FORMATETC> QWindowsMimeHtml::formatsForMime(const QString &mimeType, const QMimeData *mimeData) const
|
||||||
@ -1075,8 +976,8 @@ private:
|
|||||||
QBuiltInMimes::QBuiltInMimes()
|
QBuiltInMimes::QBuiltInMimes()
|
||||||
: QWindowsMime()
|
: QWindowsMime()
|
||||||
{
|
{
|
||||||
outFormats.insert(QWindowsMimeRegistry::registerMimeType(QStringLiteral("application/x-color")), QStringLiteral("application/x-color"));
|
outFormats.insert(registerMimeType(QStringLiteral("application/x-color")), QStringLiteral("application/x-color"));
|
||||||
inFormats.insert(QWindowsMimeRegistry::registerMimeType(QStringLiteral("application/x-color")), QStringLiteral("application/x-color"));
|
inFormats.insert(registerMimeType(QStringLiteral("application/x-color")), QStringLiteral("application/x-color"));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QBuiltInMimes::canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const
|
bool QBuiltInMimes::canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const
|
||||||
@ -1257,7 +1158,7 @@ QList<FORMATETC> QLastResortMimes::formatsForMime(const QString &mimeType, const
|
|||||||
auto mit = std::find(formats.begin(), formats.end(), mimeType);
|
auto mit = std::find(formats.begin(), formats.end(), mimeType);
|
||||||
// register any other available formats
|
// register any other available formats
|
||||||
if (mit == formats.end() && !excludeList.contains(mimeType, Qt::CaseInsensitive))
|
if (mit == formats.end() && !excludeList.contains(mimeType, Qt::CaseInsensitive))
|
||||||
mit = formats.insert(QWindowsMimeRegistry::registerMimeType(mimeType), mimeType);
|
mit = formats.insert(registerMimeType(mimeType), mimeType);
|
||||||
if (mit != formats.end())
|
if (mit != formats.end())
|
||||||
formatetcs += setCf(mit.key());
|
formatetcs += setCf(mit.key());
|
||||||
|
|
||||||
@ -1301,7 +1202,7 @@ bool QLastResortMimes::canConvertToMime(const QString &mimeType, IDataObject *pD
|
|||||||
}
|
}
|
||||||
// if it is not in there then register it and see if we can get it
|
// if it is not in there then register it and see if we can get it
|
||||||
const auto mit = std::find(formats.cbegin(), formats.cend(), mimeType);
|
const auto mit = std::find(formats.cbegin(), formats.cend(), mimeType);
|
||||||
const int cf = mit != formats.cend() ? mit.key() : QWindowsMimeRegistry::registerMimeType(mimeType);
|
const int cf = mit != formats.cend() ? mit.key() : registerMimeType(mimeType);
|
||||||
return canGetData(cf, pDataObj);
|
return canGetData(cf, pDataObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1318,7 +1219,7 @@ QVariant QLastResortMimes::convertToMime(const QString &mimeType, IDataObject *p
|
|||||||
data = getData(int(cf), pDataObj, lindex);
|
data = getData(int(cf), pDataObj, lindex);
|
||||||
} else {
|
} else {
|
||||||
const auto mit = std::find(formats.cbegin(), formats.cend(), mimeType);
|
const auto mit = std::find(formats.cbegin(), formats.cend(), mimeType);
|
||||||
const int cf = mit != formats.cend() ? mit.key() : QWindowsMimeRegistry::registerMimeType(mimeType);
|
const int cf = mit != formats.cend() ? mit.key() : registerMimeType(mimeType);
|
||||||
data = getData(cf, pDataObj);
|
data = getData(cf, pDataObj);
|
||||||
}
|
}
|
||||||
if (!data.isEmpty())
|
if (!data.isEmpty())
|
||||||
@ -1445,15 +1346,18 @@ QList<FORMATETC> QWindowsMimeRegistry::allFormatsForMime(const QMimeData *mimeDa
|
|||||||
|
|
||||||
void QWindowsMimeRegistry::ensureInitialized() const
|
void QWindowsMimeRegistry::ensureInitialized() const
|
||||||
{
|
{
|
||||||
if (m_mimes.isEmpty()) {
|
if (m_internalMimeCount == 0) {
|
||||||
m_mimes
|
m_internalMimeCount = -1; // prevent reentrancy when types register themselves
|
||||||
#ifndef QT_NO_IMAGEFORMAT_BMP
|
#ifndef QT_NO_IMAGEFORMAT_BMP
|
||||||
<< new QWindowsMimeImage
|
(void)new QWindowsMimeImage;
|
||||||
#endif //QT_NO_IMAGEFORMAT_BMP
|
#endif //QT_NO_IMAGEFORMAT_BMP
|
||||||
<< new QLastResortMimes
|
(void)new QLastResortMimes;
|
||||||
<< new QWindowsMimeText << new QWindowsMimeURI
|
(void)new QWindowsMimeText;
|
||||||
<< new QWindowsMimeHtml << new QBuiltInMimes;
|
(void)new QWindowsMimeURI;
|
||||||
|
(void)new QWindowsMimeHtml;
|
||||||
|
(void)new QBuiltInMimes;
|
||||||
m_internalMimeCount = m_mimes.size();
|
m_internalMimeCount = m_mimes.size();
|
||||||
|
Q_ASSERT(m_internalMimeCount > 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user