diff options
author | Joerg Bornemann <joerg.bornemann@qt.io> | 2017-08-17 14:59:51 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@qt.io> | 2017-08-18 20:59:02 +0000 |
commit | 99f84ffd2c0c78014a24534a863aa1c755abd51c (patch) | |
tree | 9858801c9ed2c7743e7190b339fc40692baf8fe5 /src/core/web_contents_adapter.cpp | |
parent | 8df8a253b13e866dc23fa6f874d23b7150dc1b05 (diff) |
Handle content::DropData::file_contents
DropData::file_contents and DropData::file_description_filename are
filled by Chromium if the user drags an image from a web page. Write the
file's content into a file with the suggested file name in a temporary
directory, and set the drop action to "move".
This enables users to drag images from the browser to the desktop or a
file browser.
The file is moved by the client to the target location.
The temporary directory is removed when the page is closed.
Note that Chrome doesn't use this temporary directory trick, but employs
techniques like XDS [1] on Linux to transfer the data via the native
clipboard/DnD MIME object. Unfortunately QDrag doesn't support this.
Support could be added, but I consider this solution as good enough.
[1] https://www.freedesktop.org/wiki/Specifications/XDS/
Task-number: QTBUG-60790
Change-Id: I44f2b3170a124e861ed4131c421903d895b70715
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'src/core/web_contents_adapter.cpp')
-rw-r--r-- | src/core/web_contents_adapter.cpp | 36 |
1 files changed, 35 insertions, 1 deletions
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp index 8273b247f..9c78d67a0 100644 --- a/src/core/web_contents_adapter.cpp +++ b/src/core/web_contents_adapter.cpp @@ -93,6 +93,7 @@ #include <QVariant> #include <QtCore/qelapsedtimer.h> #include <QtCore/qmimedata.h> +#include <QtCore/qtemporarydir.h> #include <QtGui/qaccessible.h> #include <QtGui/qdrag.h> #include <QtGui/qpixmap.h> @@ -1206,7 +1207,11 @@ void WebContentsAdapter::startDragging(QObject *dragSource, const content::DropD #endif }); - drag->setMimeData(mimeDataFromDropData(*d->currentDropData)); + QMimeData *mimeData = mimeDataFromDropData(*d->currentDropData); + if (handleDropDataFileContents(dropData, mimeData)) + allowedActions = Qt::MoveAction; + + drag->setMimeData(mimeData); if (!pixmap.isNull()) { drag->setPixmap(pixmap); drag->setHotSpot(offset); @@ -1232,6 +1237,35 @@ void WebContentsAdapter::startDragging(QObject *dragSource, const content::DropD } } +bool WebContentsAdapter::handleDropDataFileContents(const content::DropData &dropData, + QMimeData *mimeData) +{ + if (dropData.file_contents.empty()) + return false; + + Q_D(WebContentsAdapter); + if (!d->dndTmpDir) { + d->dndTmpDir.reset(new QTemporaryDir); + if (!d->dndTmpDir->isValid()) { + d->dndTmpDir.reset(); + return false; + } + } + + const QString &fileName = toQt(dropData.file_description_filename); + const QString &filePath = d->dndTmpDir->filePath(fileName); + QFile file(filePath); + if (!file.open(QIODevice::WriteOnly)) { + qWarning("Cannot write temporary file %s.", qUtf8Printable(filePath)); + return false; + } + file.write(QByteArray::fromStdString(dropData.file_contents)); + + const QUrl &targetUrl = QUrl::fromLocalFile(filePath); + mimeData->setUrls(QList<QUrl>{targetUrl}); + return true; +} + static void fillDropDataFromMimeData(content::DropData *dropData, const QMimeData *mimeData) { Q_ASSERT(dropData->filenames.empty()); |