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>
This commit is contained in:
parent
4c1ea8f72c
commit
efbc538587
@ -106,3 +106,9 @@ if (event->mimeData()->hasColor()) {
|
|||||||
...
|
...
|
||||||
}
|
}
|
||||||
//! [7]
|
//! [7]
|
||||||
|
|
||||||
|
|
||||||
|
//! [8]
|
||||||
|
application/x-qt-windows-mime;value="FileContents";index=0
|
||||||
|
application/x-qt-windows-mime;value="FileContents";index=1
|
||||||
|
//! [8]
|
||||||
|
@ -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
|
The \c value declaration of each format describes the way in which the
|
||||||
data is encoded.
|
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
|
On Windows, the MIME format does not always map directly to the
|
||||||
clipboard formats. Qt provides QWinMime to map clipboard
|
clipboard formats. Qt provides QWinMime to map clipboard
|
||||||
formats to open-standard MIME formats. Similarly, the
|
formats to open-standard MIME formats. Similarly, the
|
||||||
|
@ -343,10 +343,11 @@ static bool setData(const QByteArray &data, STGMEDIUM *pmedium)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QByteArray getData(int cf, IDataObject *pDataObj)
|
static QByteArray getData(int cf, IDataObject *pDataObj, int lindex = -1)
|
||||||
{
|
{
|
||||||
QByteArray data;
|
QByteArray data;
|
||||||
FORMATETC formatetc = setCf(cf);
|
FORMATETC formatetc = setCf(cf);
|
||||||
|
formatetc.lindex = lindex;
|
||||||
STGMEDIUM s;
|
STGMEDIUM s;
|
||||||
if (pDataObj->GetData(&formatetc, &s) == S_OK) {
|
if (pDataObj->GetData(&formatetc, &s) == S_OK) {
|
||||||
DWORD * val = (DWORD*)GlobalLock(s.hGlobal);
|
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);
|
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 len = sizeof(x_qt_windows_mime) - 1;
|
||||||
int n = mimeType.lastIndexOf(QLatin1Char('\"'))-len;
|
int n = mimeType.lastIndexOf(QLatin1Char('\"')) - len;
|
||||||
return mimeType.mid(len, n);
|
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
|
bool QLastResortMimes::canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const
|
||||||
{
|
{
|
||||||
if (isCustomMimeType(mimeType)) {
|
if (isCustomMimeType(mimeType)) {
|
||||||
|
// MSDN documentation for QueryGetData says only -1 is supported, so ignore lindex here.
|
||||||
QString clipFormat = customMimeType(mimeType);
|
QString clipFormat = customMimeType(mimeType);
|
||||||
int cf = RegisterClipboardFormat(reinterpret_cast<const wchar_t *> (clipFormat.utf16()));
|
int cf = RegisterClipboardFormat(reinterpret_cast<const wchar_t *> (clipFormat.utf16()));
|
||||||
return canGetData(cf, pDataObj);
|
return canGetData(cf, pDataObj);
|
||||||
@ -1369,9 +1383,10 @@ QVariant QLastResortMimes::convertToMime(const QString &mimeType, IDataObject *p
|
|||||||
if (canConvertToMime(mimeType, pDataObj)) {
|
if (canConvertToMime(mimeType, pDataObj)) {
|
||||||
QByteArray data;
|
QByteArray data;
|
||||||
if (isCustomMimeType(mimeType)) {
|
if (isCustomMimeType(mimeType)) {
|
||||||
QString clipFormat = customMimeType(mimeType);
|
int lindex;
|
||||||
|
QString clipFormat = customMimeType(mimeType, &lindex);
|
||||||
int cf = RegisterClipboardFormat(reinterpret_cast<const wchar_t *> (clipFormat.utf16()));
|
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()) {
|
} else if (formats.keys(mimeType).isEmpty()) {
|
||||||
int cf = QWindowsMime::registerMimeType(mimeType);
|
int cf = QWindowsMime::registerMimeType(mimeType);
|
||||||
data = getData(cf, pDataObj);
|
data = getData(cf, pDataObj);
|
||||||
|
Loading…
Reference in New Issue
Block a user