Skip to content

Instantly share code, notes, and snippets.

@ahf
Created May 4, 2011 16:42
Show Gist options
  • Save ahf/955539 to your computer and use it in GitHub Desktop.
Save ahf/955539 to your computer and use it in GitHub Desktop.
From 7cb8b0ce15a7a26fe0fa394d7d7a38ef098d7a88 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Alexander=20F=C3=A6r=C3=B8y?= <alexander.faeroy@nokia.com>
Date: Wed, 4 May 2011 16:49:03 +0200
Subject: [PATCH 1/2] Add Support for Save to Gallery.
We ask the UI Process for a result filename for the image that is to
be saved to the disk. If the resulting result filename is an empty
string, we wont save it to the disk. This allows us to reject the image
based on being too large, having a bogus filename or bogus MIME type.
This commit also adds a new method for the QWKPage type, namely the
QWKPage::setRequestImageSaveFunction(), which allows you to set the
handler function for this image save request.
It wasn't possible to use Qt style signals, since they may be
asynchronous.
r=Kimmo
---
WebCore/page/ContextMenuClient.h | 2 +
WebCore/page/ContextMenuController.cpp | 3 +
WebCore/platform/ContextMenu.cpp | 3 +
WebCore/platform/ContextMenuItem.h | 1 +
WebCore/platform/LocalizationStrategy.h | 1 +
WebCore/platform/LocalizedStrings.cpp | 5 ++
WebCore/platform/LocalizedStrings.h | 1 +
WebKit2/UIProcess/API/C/WKPage.h | 2 +
WebKit2/UIProcess/API/qt/ClientImpl.cpp | 18 ++++++++
WebKit2/UIProcess/API/qt/ClientImpl.h | 1 +
WebKit2/UIProcess/API/qt/qwkpage.cpp | 14 ++++++-
WebKit2/UIProcess/API/qt/qwkpage.h | 4 ++
WebKit2/UIProcess/API/qt/qwkpage_p.h | 1 +
WebKit2/UIProcess/WebPageProxy.cpp | 5 ++
WebKit2/UIProcess/WebPageProxy.h | 3 +
WebKit2/UIProcess/WebPageProxy.messages.in | 3 +
WebKit2/UIProcess/WebUIClient.cpp | 12 +++++
WebKit2/UIProcess/WebUIClient.h | 2 +
WebKit2/UIProcess/qt/WebContextMenuProxyQt.cpp | 2 +
.../WebCoreSupport/WebContextMenuClient.cpp | 44 ++++++++++++++++++++
.../WebCoreSupport/WebContextMenuClient.h | 1 +
.../WebCoreSupport/WebPlatformStrategies.cpp | 5 ++
.../WebCoreSupport/WebPlatformStrategies.h | 1 +
23 files changed, 133 insertions(+), 1 deletions(-)
diff --git a/WebCore/page/ContextMenuClient.h b/WebCore/page/ContextMenuClient.h
index e23b329..ebe92f1 100644
--- a/WebCore/page/ContextMenuClient.h
+++ b/WebCore/page/ContextMenuClient.h
@@ -34,6 +34,7 @@ namespace WebCore {
class ContextMenuItem;
class Frame;
class HitTestResult;
+ class Image;
class KURL;
class ContextMenuClient {
@@ -52,6 +53,7 @@ namespace WebCore {
virtual void stopSpeaking() = 0;
virtual void shareLink(const String& title, const KURL& url) = 0;
virtual void shareImage(const KURL& url, const String& altText) = 0;
+ virtual void saveImageToGallery(const KURL& url, Image *image) = 0;
#if PLATFORM(MAC)
virtual void searchWithSpotlight() = 0;
diff --git a/WebCore/page/ContextMenuController.cpp b/WebCore/page/ContextMenuController.cpp
index 7ad664a..1cbd589 100644
--- a/WebCore/page/ContextMenuController.cpp
+++ b/WebCore/page/ContextMenuController.cpp
@@ -178,6 +178,9 @@ void ContextMenuController::contextMenuItemSelected(ContextMenuItem* item)
case ContextMenuItemTagShareImage:
m_client->shareImage(result.absoluteImageURL(), result.altDisplayString());
break;
+ case ContextMenuItemTagSaveImageToGallery:
+ m_client->saveImageToGallery(result.absoluteImageURL(), result.image());
+ break;
case ContextMenuItemTagDownloadLinkToDisk:
// FIXME: Some day we should be able to do this from within WebCore.
m_client->downloadURL(result.absoluteLinkURL());
diff --git a/WebCore/platform/ContextMenu.cpp b/WebCore/platform/ContextMenu.cpp
index 1c0224e..bbcf34f 100644
--- a/WebCore/platform/ContextMenu.cpp
+++ b/WebCore/platform/ContextMenu.cpp
@@ -327,6 +327,8 @@ void ContextMenu::populate()
contextMenuItemTagShareLink());
ContextMenuItem ShareImageItem(ActionType, ContextMenuItemTagShareImage,
contextMenuItemTagShareLink());
+ ContextMenuItem SaveImageToGalleryItem(ActionType, ContextMenuItemTagSaveImageToGallery,
+ contextMenuItemTagSaveImageToGallery());
#if PLATFORM(GTK)
ContextMenuItem DeleteItem(ActionType, ContextMenuItemTagDelete, contextMenuItemTagDelete());
#endif
@@ -368,6 +370,7 @@ void ContextMenu::populate()
if (!imageURL.protocolIsData()) {
appendItem(OpenImageInNewWindowItem);
appendItem(DownloadImageItem);
+ appendItem(SaveImageToGalleryItem);
if (!imageURL.isLocalFile() && imageURL.pass().isEmpty())
appendItem(ShareImageItem);
diff --git a/WebCore/platform/ContextMenuItem.h b/WebCore/platform/ContextMenuItem.h
index afab28a..5287285 100644
--- a/WebCore/platform/ContextMenuItem.h
+++ b/WebCore/platform/ContextMenuItem.h
@@ -68,6 +68,7 @@ namespace WebCore {
ContextMenuItemTagOpenFrameInNewWindow,
ContextMenuItemTagShareLink,
ContextMenuItemTagShareImage,
+ ContextMenuItemTagSaveImageToGallery,
ContextMenuItemTagCopy,
ContextMenuItemTagGoBack,
ContextMenuItemTagGoForward,
diff --git a/WebCore/platform/LocalizationStrategy.h b/WebCore/platform/LocalizationStrategy.h
index cc17b5d..fc60814 100644
--- a/WebCore/platform/LocalizationStrategy.h
+++ b/WebCore/platform/LocalizationStrategy.h
@@ -52,6 +52,7 @@ public:
virtual String contextMenuItemTagOpenLinkInNewWindow() = 0;
virtual String contextMenuItemTagShareLink() = 0;
virtual String contextMenuItemTagShareImage() = 0;
+ virtual String contextMenuItemTagSaveImageToGallery() = 0;
virtual String contextMenuItemTagDownloadLinkToDisk() = 0;
virtual String contextMenuItemTagCopyLinkToClipboard() = 0;
virtual String contextMenuItemTagOpenImageInNewWindow() = 0;
diff --git a/WebCore/platform/LocalizedStrings.cpp b/WebCore/platform/LocalizedStrings.cpp
index 89f8f2c..88066ea 100644
--- a/WebCore/platform/LocalizedStrings.cpp
+++ b/WebCore/platform/LocalizedStrings.cpp
@@ -89,6 +89,11 @@ String contextMenuItemTagShareImage()
return platformStrategies()->localizationStrategy()->contextMenuItemTagShareImage();
}
+String contextMenuItemTagSaveImageToGallery()
+{
+ return platformStrategies()->localizationStrategy()->contextMenuItemTagSaveImageToGallery();
+}
+
String contextMenuItemTagDownloadLinkToDisk()
{
return platformStrategies()->localizationStrategy()->contextMenuItemTagDownloadLinkToDisk();
diff --git a/WebCore/platform/LocalizedStrings.h b/WebCore/platform/LocalizedStrings.h
index 2868173..a7ba686 100644
--- a/WebCore/platform/LocalizedStrings.h
+++ b/WebCore/platform/LocalizedStrings.h
@@ -48,6 +48,7 @@ namespace WebCore {
String contextMenuItemTagOpenLinkInNewWindow();
String contextMenuItemTagShareLink();
String contextMenuItemTagShareImage();
+ String contextMenuItemTagSaveImageToGallery();
String contextMenuItemTagDownloadLinkToDisk();
String contextMenuItemTagCopyLinkToClipboard();
String contextMenuItemTagOpenImageInNewWindow();
diff --git a/WebKit2/UIProcess/API/C/WKPage.h b/WebKit2/UIProcess/API/C/WKPage.h
index e1080de..01ca46d 100644
--- a/WebKit2/UIProcess/API/C/WKPage.h
+++ b/WebKit2/UIProcess/API/C/WKPage.h
@@ -160,6 +160,7 @@ typedef void (*WKPageDidScrollCallback)(WKPageRef page, const void *clientInfo);
typedef void (*WKPageAuthenticationRequiredCallback)(WKPageRef page, WKStringRef host, WKStringRef realm, WKStringRef oldUsername, WKStringRef* username, WKStringRef* password, const void *clientInfo);
typedef void (*WKPageDecidePolicyForGeolocationPermissionRequestCallback)(WKPageRef page, WKFrameRef frame, WKSecurityOriginRef origin, WKGeolocationPermissionRequestRef permissionRequest, const void* clientInfo);
typedef unsigned long long (*WKPageExceededDatabaseQuotaCallback)(WKPageRef page, WKFrameRef frame, WKSecurityOriginRef origin, WKStringRef databaseName, WKStringRef displayName, unsigned long long currentQuota, unsigned long long currentUsage, unsigned long long expectedUsage, const void *clientInfo);
+typedef void (*WKPageRequestImageSaveCallback)(WKPageRef page, WKStringRef originalFileName, WKStringRef mimeType, int imageSize, WKStringRef *resultFileName, const void *clientInfo);
struct WKPageUIClient {
int version;
@@ -189,6 +190,7 @@ struct WKPageUIClient {
WKPageDecidePolicyForGeolocationPermissionRequestCallback decidePolicyForGeolocationPermissionRequest;
WKPageAuthenticationRequiredCallback authenticationRequired;
WKPageExceededDatabaseQuotaCallback exceededDatabaseQuota;
+ WKPageRequestImageSaveCallback requestImageSave;
};
typedef struct WKPageUIClient WKPageUIClient;
diff --git a/WebKit2/UIProcess/API/qt/ClientImpl.cpp b/WebKit2/UIProcess/API/qt/ClientImpl.cpp
index b3e7bda..641b60b 100644
--- a/WebKit2/UIProcess/API/qt/ClientImpl.cpp
+++ b/WebKit2/UIProcess/API/qt/ClientImpl.cpp
@@ -325,6 +325,24 @@ void qt_wk_authenticationRequired(WKPageRef page, WKStringRef host, WKStringRef
*password = WKStringCreateWithQString(qPassword);
}
+void qt_wk_requestImageSave(WKPageRef page, WKStringRef originalFileName, WKStringRef mimeType, int imageSize, WKStringRef* resultFileName, const void *clientInfo)
+{
+ QWKPage* wkPage = toQWKPage(clientInfo);
+ QWKPagePrivate* d = QWKPagePrivate::get(wkPage);
+ QWKPage::RequestImageSaveFn requestImageSaveFn = d->requestImageSaveFn;
+
+ if (!requestImageSaveFn)
+ return;
+
+ const QString qOriginalFileName = WKStringCopyQString(originalFileName);
+ const QString qMIMEType = WKStringCopyQString(mimeType);
+ QString qResultFileName;
+
+ requestImageSaveFn(wkPage, qOriginalFileName, qMIMEType, imageSize, &qResultFileName);
+
+ *resultFileName = WKStringCreateWithQString(qResultFileName);
+}
+
unsigned long long qt_wk_exceededDatabaseQuota(WKPageRef page, WKFrameRef frame, WKSecurityOriginRef origin, WKStringRef databaseName, WKStringRef displayName, unsigned long long currentQuota, unsigned long long currentUsage, unsigned long long expectedUsage, const void *clientInfo)
{
QWKPage* wkPage = toQWKPage(clientInfo);
diff --git a/WebKit2/UIProcess/API/qt/ClientImpl.h b/WebKit2/UIProcess/API/qt/ClientImpl.h
index 16ac8a8..8ba97c7 100644
--- a/WebKit2/UIProcess/API/qt/ClientImpl.h
+++ b/WebKit2/UIProcess/API/qt/ClientImpl.h
@@ -56,6 +56,7 @@ bool qt_wk_runBeforeUnloadConfirmPanel(WKPageRef page, WKStringRef message, WKFr
void qt_wk_decidePolicyForGeolocationPermissionRequest(WKPageRef page, WKFrameRef frame, WKSecurityOriginRef origin, WKGeolocationPermissionRequestRef permissionRequest, const void* clientInfo);
void qt_wk_authenticationRequired(WKPageRef page, WKStringRef host, WKStringRef realm, WKStringRef oldUsername, WKStringRef* username, WKStringRef* password, const void* clientInfo);
+void qt_wk_requestImageSave(WKPageRef page, WKStringRef originalFilename, WKStringRef mimeType, int imageSize, WKStringRef* resultFilename, const void* clientInfo);
unsigned long long qt_wk_exceededDatabaseQuota(WKPageRef page, WKFrameRef frame, WKSecurityOriginRef origin, WKStringRef databaseName, WKStringRef displayName, unsigned long long currentQuota, unsigned long long currentUsage, unsigned long long expectedUsage, const void *clientInfo);
diff --git a/WebKit2/UIProcess/API/qt/qwkpage.cpp b/WebKit2/UIProcess/API/qt/qwkpage.cpp
index 809c85f..4168ad8 100644
--- a/WebKit2/UIProcess/API/qt/qwkpage.cpp
+++ b/WebKit2/UIProcess/API/qt/qwkpage.cpp
@@ -72,6 +72,8 @@ static WebCore::ContextMenuAction contextMenuActionForWebAction(QWKPage::WebActi
return WebCore::ContextMenuItemTagShareLink;
case QWKPage::ShareImage:
return WebCore::ContextMenuItemTagShareImage;
+ case QWKPage::SaveImageToGallery:
+ return WebCore::ContextMenuItemTagSaveImageToGallery;
case QWKPage::CopyLinkToClipboard:
return WebCore::ContextMenuItemTagCopyLinkToClipboard;
case QWKPage::OpenImageInNewWindow:
@@ -108,6 +110,7 @@ QWKPagePrivate::QWKPagePrivate(QWKPage* qq, QWKContext* c)
, runJavaScriptConfirmBeforeUnloadFn(0)
, authenticationRequiredFn(0)
, databaseQuotaExceededFn(0)
+ , requestImageSaveFn(0)
#if CPU(ARM)
// The way touch is implemented on the device can mess the order
// of touch event. We have to filter all mouse events.
@@ -896,7 +899,8 @@ QWKPage::QWKPage(QWKContext* context)
0, /* pageDidScroll */
qt_wk_decidePolicyForGeolocationPermissionRequest,
qt_wk_authenticationRequired,
- qt_wk_exceededDatabaseQuota
+ qt_wk_exceededDatabaseQuota,
+ qt_wk_requestImageSave
};
WKPageSetPageUIClient(pageRef(), &uiClient);
@@ -1101,6 +1105,11 @@ void QWKPage::setAuthenticationRequiredFunction(AuthenticationRequiredFn functio
d->authenticationRequiredFn = function;
}
+void QWKPage::setRequestImageSaveFunction(RequestImageSaveFn function)
+{
+ d->requestImageSaveFn = function;
+}
+
void QWKPage::setDatabaseQuotaExceededFunction(DatabaseQuotaExceededFn function)
{
d->databaseQuotaExceededFn = function;
@@ -1273,6 +1282,9 @@ QAction* QWKPage::action(WebAction action) const
case ShareImage:
text = contextMenuItemTagShareImage();
break;
+ case SaveImageToGallery:
+ text = contextMenuItemTagSaveImageToGallery();
+ break;
case CopyLinkToClipboard:
text = contextMenuItemTagCopyLinkToClipboard();
break;
diff --git a/WebKit2/UIProcess/API/qt/qwkpage.h b/WebKit2/UIProcess/API/qt/qwkpage.h
index 106042c..8b9f0a2 100644
--- a/WebKit2/UIProcess/API/qt/qwkpage.h
+++ b/WebKit2/UIProcess/API/qt/qwkpage.h
@@ -51,6 +51,8 @@ public:
ShareLink,
ShareImage,
+ SaveImageToGallery,
+
Back,
Forward,
Stop,
@@ -151,6 +153,7 @@ public:
typedef QString (*RunJavaScriptPromptFn)(QWKPage*, const QString& message, const QString& defaultValue);
typedef bool (*RunJavaScriptConfirmBeforeUnloadFn)(QWKPage*, const QString& message);
typedef void (*AuthenticationRequiredFn)(QWKPage*, const QString& host, const QString& realm, const QString& oldUsername, QString* username, QString* password);
+ typedef void (*RequestImageSaveFn)(QWKPage*, const QString& originalFilename, const QString& mimeType, int imageSize, QString* resultFileName);
typedef unsigned long long (*DatabaseQuotaExceededFn)(QWKPage*, const QWKSecurityOrigin& origin, const QString& databaseName, const QString& displayName, unsigned long long currentQuota, unsigned long long currentUsage, unsigned long long expectedUsage);
@@ -163,6 +166,7 @@ public:
void setRunJavaScriptConfirmBeforeUnloadFunction(RunJavaScriptConfirmBeforeUnloadFn function);
void setAuthenticationRequiredFunction(AuthenticationRequiredFn function);
void setDatabaseQuotaExceededFunction(DatabaseQuotaExceededFn function);
+ void setRequestImageSaveFunction(RequestImageSaveFn function);
void setCustomUserAgent(const QString&);
QString customUserAgent() const;
diff --git a/WebKit2/UIProcess/API/qt/qwkpage_p.h b/WebKit2/UIProcess/API/qt/qwkpage_p.h
index e8744f4..c9331da 100644
--- a/WebKit2/UIProcess/API/qt/qwkpage_p.h
+++ b/WebKit2/UIProcess/API/qt/qwkpage_p.h
@@ -147,6 +147,7 @@ public:
QWKPage::RunJavaScriptConfirmBeforeUnloadFn runJavaScriptConfirmBeforeUnloadFn;
QWKPage::AuthenticationRequiredFn authenticationRequiredFn;
QWKPage::DatabaseQuotaExceededFn databaseQuotaExceededFn;
+ QWKPage::RequestImageSaveFn requestImageSaveFn;
bool filterMouseEvents;
QHash<int, QPointF> trackedTouchPointPositions;
diff --git a/WebKit2/UIProcess/WebPageProxy.cpp b/WebKit2/UIProcess/WebPageProxy.cpp
index 773fb4d..5d84f42 100644
--- a/WebKit2/UIProcess/WebPageProxy.cpp
+++ b/WebKit2/UIProcess/WebPageProxy.cpp
@@ -1736,6 +1736,11 @@ void WebPageProxy::shareImage(const String& url, const String& altText)
m_pageClient->shareImage(KURL(KURL(), url), altText);
}
+void WebPageProxy::requestImageSave(const String& originalFileName, const String& mimeType, int imageSize, String& resultFileName)
+{
+ m_uiClient.requestImageSave(this, originalFileName, mimeType, imageSize, resultFileName);
+}
+
void WebPageProxy::contextMenuItemSelected(const WebContextMenuItemData& item)
{
if (!isValid())
diff --git a/WebKit2/UIProcess/WebPageProxy.h b/WebKit2/UIProcess/WebPageProxy.h
index ac61bbc..bf85916 100644
--- a/WebKit2/UIProcess/WebPageProxy.h
+++ b/WebKit2/UIProcess/WebPageProxy.h
@@ -433,6 +433,9 @@ private:
void shareLink(const String& title, const String& url);
void shareImage(const String& url, const String& altText);
+ // Save Image
+ void requestImageSave(const String& originalFileName, const String& mimeType, int imageSize, String& resultFileName);
+
void takeFocus(bool direction);
void setToolTip(const String&);
void setCursor(const WebCore::Cursor&);
diff --git a/WebKit2/UIProcess/WebPageProxy.messages.in b/WebKit2/UIProcess/WebPageProxy.messages.in
index 658b48c..008e06b 100644
--- a/WebKit2/UIProcess/WebPageProxy.messages.in
+++ b/WebKit2/UIProcess/WebPageProxy.messages.in
@@ -154,6 +154,9 @@ messages -> WebPageProxy {
ShareLink(WTF::String title, WTF::String url)
ShareImage(WTF::String url, WTF::String altText)
+ # Save Image
+ RequestImageSave(WTF::String originalFileName, WTF::String mimeType, int imageSize) -> (WTF::String resultFileName)
+
# Authentication required.
AuthenticationRequired(WTF::String host, WTF::String realm, WTF::String oldUsername) -> (WTF::String username, WTF::String password)
diff --git a/WebKit2/UIProcess/WebUIClient.cpp b/WebKit2/UIProcess/WebUIClient.cpp
index 4e0a6f9..b2be17e 100644
--- a/WebKit2/UIProcess/WebUIClient.cpp
+++ b/WebKit2/UIProcess/WebUIClient.cpp
@@ -250,6 +250,18 @@ void WebUIClient::authenticationRequired(WebPageProxy* page, const String& host,
password = toWTFString(passwordRef);
}
+void WebUIClient::requestImageSave(WebPageProxy* page, const String& originalFileName, const String& mimeType, int imageSize, String& resultFileName)
+{
+ if (!m_client.requestImageSave)
+ return;
+
+ WKStringRef resultFileNameRef = 0;
+ m_client.requestImageSave(toAPI(page), toAPI(originalFileName.impl()), toAPI(mimeType.impl()),
+ imageSize, &resultFileNameRef, m_client.clientInfo);
+
+ resultFileName = toWTFString(resultFileNameRef);
+}
+
bool WebUIClient::decidePolicyForGeolocationPermissionRequest(WebPageProxy* page, WebFrameProxy* frame, WebSecurityOrigin* origin, GeolocationPermissionRequestProxy* permissionRequest)
{
if (!m_client.decidePolicyForGeolocationPermissionRequest)
diff --git a/WebKit2/UIProcess/WebUIClient.h b/WebKit2/UIProcess/WebUIClient.h
index b3af889..56635c0 100644
--- a/WebKit2/UIProcess/WebUIClient.h
+++ b/WebKit2/UIProcess/WebUIClient.h
@@ -85,6 +85,8 @@ public:
void authenticationRequired(WebPageProxy*, const String& host, const String& realm, const String& oldUsername, String& username, String& password);
+ void requestImageSave(WebPageProxy*, const String& originalFileName, const String& mimeType, int imageSize, String& resultFileName);
+
unsigned long long exceededDatabaseQuota(WebPageProxy*, WebFrameProxy*, WebSecurityOrigin*, const String& databaseName, const String& databaseDisplayName, unsigned long long currentQuota, unsigned long long currentUsage, unsigned long long expectedUsage);
};
diff --git a/WebKit2/UIProcess/qt/WebContextMenuProxyQt.cpp b/WebKit2/UIProcess/qt/WebContextMenuProxyQt.cpp
index 4868d87..f67ac3f 100644
--- a/WebKit2/UIProcess/qt/WebContextMenuProxyQt.cpp
+++ b/WebKit2/UIProcess/qt/WebContextMenuProxyQt.cpp
@@ -46,6 +46,8 @@ static QWKPage::WebAction webActionForContextMenuAction(WebCore::ContextMenuActi
return QWKPage::ShareLink;
case WebCore::ContextMenuItemTagShareImage:
return QWKPage::ShareImage;
+ case WebCore::ContextMenuItemTagSaveImageToGallery:
+ return QWKPage::SaveImageToGallery;
case WebCore::ContextMenuItemTagCopyLinkToClipboard:
return QWKPage::CopyLinkToClipboard;
case WebCore::ContextMenuItemTagOpenImageInNewWindow:
diff --git a/WebKit2/WebProcess/WebCoreSupport/WebContextMenuClient.cpp b/WebKit2/WebProcess/WebCoreSupport/WebContextMenuClient.cpp
index 440f07b..dd2c574 100644
--- a/WebKit2/WebProcess/WebCoreSupport/WebContextMenuClient.cpp
+++ b/WebKit2/WebProcess/WebCoreSupport/WebContextMenuClient.cpp
@@ -28,7 +28,15 @@
#include "WebContextMenuItemData.h"
#include "WebPage.h"
#include "WebPageProxyMessages.h"
+#include "WebProcess.h"
#include <WebCore/ContextMenu.h>
+#include <WebCore/Image.h>
+#include <WebCore/MIMETypeRegistry.h>
+#include <WebCore/SharedBuffer.h>
+
+#if PLATFORM(QT)
+#include <QFile>
+#endif
#define DISABLE_NOT_IMPLEMENTED_WARNINGS 1
#include "NotImplemented.h"
@@ -101,4 +109,40 @@ void WebContextMenuClient::shareImage(const KURL& url, const String& altText)
m_page->send(Messages::WebPageProxy::ShareImage(url, altText));
}
+void WebContextMenuClient::saveImageToGallery(const KURL& url, Image* image)
+{
+ if (!image)
+ return;
+
+ String mimeType = MIMETypeRegistry::getMIMETypeForExtension(image->filenameExtension());
+ String fileName = url.lastPathComponent();
+ String extension = image->filenameExtension();
+ String resultFileName;
+
+ /* If the image lacks an extension, we'll add one based on its MIME-type. */
+ if (fileName.reverseFind(".") == notFound) {
+ fileName.append(".");
+ fileName.append(extension);
+ }
+
+ if (!WebProcess::shared().connection()->sendSync(
+ Messages::WebPageProxy::RequestImageSave(fileName, mimeType, image->data()->size()),
+ Messages::WebPageProxy::RequestImageSave::Reply(resultFileName), m_page->pageID())) {
+ return;
+ }
+
+ // If the result filename is empty, don't save the image.
+ if (!resultFileName.isEmpty()) {
+#if PLATFORM(QT)
+ QFile file(resultFileName);
+
+ if (file.exists() || !file.open(QFile::WriteOnly))
+ return;
+
+ if (file.write(image->data()->data(), image->data()->size()) == -1)
+ return;
+#endif
+ }
+}
+
} // namespace WebKit
diff --git a/WebKit2/WebProcess/WebCoreSupport/WebContextMenuClient.h b/WebKit2/WebProcess/WebCoreSupport/WebContextMenuClient.h
index b8db7e5..aecfa1e 100644
--- a/WebKit2/WebProcess/WebCoreSupport/WebContextMenuClient.h
+++ b/WebKit2/WebProcess/WebCoreSupport/WebContextMenuClient.h
@@ -53,6 +53,7 @@ private:
virtual void stopSpeaking();
virtual void shareLink(const String& title, const WebCore::KURL& url);
virtual void shareImage(const WebCore::KURL& url, const String& altText);
+ virtual void saveImageToGallery(const WebCore::KURL& url, WebCore::Image* image);
#if PLATFORM(MAC)
virtual void searchWithSpotlight();
diff --git a/WebKit2/WebProcess/WebCoreSupport/WebPlatformStrategies.cpp b/WebKit2/WebProcess/WebCoreSupport/WebPlatformStrategies.cpp
index 37d8aed..c06b3cd 100644
--- a/WebKit2/WebProcess/WebCoreSupport/WebPlatformStrategies.cpp
+++ b/WebKit2/WebProcess/WebCoreSupport/WebPlatformStrategies.cpp
@@ -192,6 +192,11 @@ String WebPlatformStrategies::contextMenuItemTagShareImage()
return UI_STRING("Share Image", "Share Image context menu item");
}
+String WebPlatformStrategies::contextMenuItemTagSaveImageToGallery()
+{
+ return UI_STRING("Save Image", "Save Image context menu item");
+}
+
String WebPlatformStrategies::contextMenuItemTagDownloadLinkToDisk()
{
return UI_STRING("Download Linked File", "Download Linked File context menu item");
diff --git a/WebKit2/WebProcess/WebCoreSupport/WebPlatformStrategies.h b/WebKit2/WebProcess/WebCoreSupport/WebPlatformStrategies.h
index 0b44c16..52696be 100644
--- a/WebKit2/WebProcess/WebCoreSupport/WebPlatformStrategies.h
+++ b/WebKit2/WebProcess/WebCoreSupport/WebPlatformStrategies.h
@@ -65,6 +65,7 @@ private:
virtual String contextMenuItemTagOpenLinkInNewWindow();
virtual String contextMenuItemTagShareLink();
virtual String contextMenuItemTagShareImage();
+ virtual String contextMenuItemTagSaveImageToGallery();
virtual String contextMenuItemTagDownloadLinkToDisk();
virtual String contextMenuItemTagCopyLinkToClipboard();
virtual String contextMenuItemTagOpenImageInNewWindow();
--
1.7.0.4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment