diff options
author | David Faure <david.faure@kdab.com> | 2014-11-05 16:53:46 +0100 |
---|---|---|
committer | David Faure <david.faure@kdab.com> | 2014-11-13 19:21:06 +0100 |
commit | efbc53858725ec8563bb97423d9bf789c41cf79f (patch) | |
tree | 09d64bc8fcf528c7656c3689f4cb70098a102760 | |
parent | 4c1ea8f72ce806a5059ddec1ec1364f9a92294f0 (diff) |
qwindowsmime.cpp: support dropping multiple mail attachments
Only the data for the first file could be reached with the mimetype
application/x-qt-windows-mime;value="FileContents"
To get the data for the other files, setting the lindex field of
the FORMATETC struct is necessary. Provide support for that by
appending ;index=N to the mimetype string.
The Windows API provides no generic way to find out how many of these
are available (the app has to find out by looking into the FILEGROUPDESCRIPTORW
structure, for this particular use case), so these additional mimetypes
are not listed in QMimeData::formats(). However this patch extends
the documentation to mention the feature.
[ChangeLog][Platform Specific Changes][Windows][QMimeData] Add support
for handling dropping of multiple mail attachments, adding ;index=N to
the mimetype string application/x-qt-windows-mime;value="FileContents"
Task-number: QTBUG-17373
Change-Id: I031e477d2357b4e5135d2dcd3e3cf991025715a5
Reviewed-by: Andy Shaw <andy.shaw@digia.com>
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@theqtcompany.com>
-rw-r--r-- | src/corelib/doc/snippets/code/src_corelib_kernel_qmimedata.cpp | 6 | ||||
-rw-r--r-- | src/corelib/kernel/qmimedata.cpp | 5 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qwindowsmime.cpp | 27 |
3 files changed, 32 insertions, 6 deletions
diff --git a/src/corelib/doc/snippets/code/src_corelib_kernel_qmimedata.cpp b/src/corelib/doc/snippets/code/src_corelib_kernel_qmimedata.cpp index 7f42cd8def..278a00fdfd 100644 --- a/src/corelib/doc/snippets/code/src_corelib_kernel_qmimedata.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_kernel_qmimedata.cpp @@ -106,3 +106,9 @@ if (event->mimeData()->hasColor()) { ... } //! [7] + + +//! [8] +application/x-qt-windows-mime;value="FileContents";index=0 +application/x-qt-windows-mime;value="FileContents";index=1 +//! [8] diff --git a/src/corelib/kernel/qmimedata.cpp b/src/corelib/kernel/qmimedata.cpp index 15fdf57747..45aec88429 100644 --- a/src/corelib/kernel/qmimedata.cpp +++ b/src/corelib/kernel/qmimedata.cpp @@ -286,6 +286,11 @@ QVariant QMimeDataPrivate::retrieveTypedData(const QString &format, QVariant::Ty The \c value declaration of each format describes the way in which the data is encoded. + In some cases (e.g. dropping multiple email attachments), multiple data + values are available. They can be accessed by adding an \c index value: + + \snippet code/src_corelib_kernel_qmimedata.cpp 8 + On Windows, the MIME format does not always map directly to the clipboard formats. Qt provides QWinMime to map clipboard formats to open-standard MIME formats. Similarly, the diff --git a/src/plugins/platforms/windows/qwindowsmime.cpp b/src/plugins/platforms/windows/qwindowsmime.cpp index 2de1477f29..42f4e66d6c 100644 --- a/src/plugins/platforms/windows/qwindowsmime.cpp +++ b/src/plugins/platforms/windows/qwindowsmime.cpp @@ -343,10 +343,11 @@ static bool setData(const QByteArray &data, STGMEDIUM *pmedium) return true; } -static QByteArray getData(int cf, IDataObject *pDataObj) +static QByteArray getData(int cf, IDataObject *pDataObj, int lindex = -1) { QByteArray data; FORMATETC formatetc = setCf(cf); + formatetc.lindex = lindex; STGMEDIUM s; if (pDataObj->GetData(&formatetc, &s) == S_OK) { DWORD * val = (DWORD*)GlobalLock(s.hGlobal); @@ -1339,16 +1340,29 @@ static bool isCustomMimeType(const QString &mimeType) return mimeType.startsWith(QLatin1String(x_qt_windows_mime), Qt::CaseInsensitive); } -static QString customMimeType(const QString &mimeType) +static QString customMimeType(const QString &mimeType, int *lindex = 0) { int len = sizeof(x_qt_windows_mime) - 1; - int n = mimeType.lastIndexOf(QLatin1Char('\"'))-len; - return mimeType.mid(len, n); + int n = mimeType.lastIndexOf(QLatin1Char('\"')) - len; + QString ret = mimeType.mid(len, n); + + const int beginPos = mimeType.indexOf(QLatin1String(";index=")); + if (beginPos > -1) { + const int endPos = mimeType.indexOf(QLatin1Char(';'), beginPos + 1); + const int indexStartPos = beginPos + 7; + if (lindex) + *lindex = mimeType.midRef(indexStartPos, endPos == -1 ? endPos : endPos - indexStartPos).toInt(); + } else { + if (lindex) + *lindex = -1; + } + return ret; } bool QLastResortMimes::canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const { if (isCustomMimeType(mimeType)) { + // MSDN documentation for QueryGetData says only -1 is supported, so ignore lindex here. QString clipFormat = customMimeType(mimeType); int cf = RegisterClipboardFormat(reinterpret_cast<const wchar_t *> (clipFormat.utf16())); return canGetData(cf, pDataObj); @@ -1369,9 +1383,10 @@ QVariant QLastResortMimes::convertToMime(const QString &mimeType, IDataObject *p if (canConvertToMime(mimeType, pDataObj)) { QByteArray data; if (isCustomMimeType(mimeType)) { - QString clipFormat = customMimeType(mimeType); + int lindex; + QString clipFormat = customMimeType(mimeType, &lindex); int cf = RegisterClipboardFormat(reinterpret_cast<const wchar_t *> (clipFormat.utf16())); - data = getData(cf, pDataObj); + data = getData(cf, pDataObj, lindex); } else if (formats.keys(mimeType).isEmpty()) { int cf = QWindowsMime::registerMimeType(mimeType); data = getData(cf, pDataObj); |