summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndras Becsi <andras.becsi@theqtcompany.com>2014-12-11 19:57:58 +0100
committerAndras Becsi <andras.becsi@theqtcompany.com>2015-01-12 16:34:58 +0100
commite6a74159cebdbfec575f40469c216c90ee8651c1 (patch)
tree331f7a51b9d0c77568bb2744fbd8155733424374
parent4557ccd9785f53abc11460211c84db3e564b364f (diff)
Add QML download API
This patch exposes downloadStarted and downloadFinished signals on the WebEngineProfile to notify about downloads. The WebEngineDownloadItem exposes a subset of Chromium's content::DownloadItem functionality. For now we expose minimal requirements to be able to control downloads in QML but this can be extended in the future. This patch also adds a DownloadView to quicktestbrowser to demonstrate the usage of the new API. [ChangeLog][QtWebEngineQML] Add QtQuick download API Change-Id: I8d8f0daf02c4e0151000427fc2a4b37d28b9db52 Reviewed-by: Jocelyn Turcotte <jocelyn.turcotte@digia.com>
-rw-r--r--src/core/browser_context_adapter.cpp22
-rw-r--r--src/core/browser_context_adapter.h10
-rw-r--r--src/core/browser_context_adapter_client.h63
-rw-r--r--src/core/browser_context_qt.cpp4
-rw-r--r--src/core/browser_context_qt.h4
-rw-r--r--src/core/core_gyp_generator.pro1
-rw-r--r--src/core/download_manager_delegate_qt.cpp216
-rw-r--r--src/core/download_manager_delegate_qt.h46
-rw-r--r--src/webengine/api/qquickwebenginedownloaditem.cpp134
-rw-r--r--src/webengine/api/qquickwebenginedownloaditem_p.h91
-rw-r--r--src/webengine/api/qquickwebenginedownloaditem_p_p.h67
-rw-r--r--src/webengine/api/qquickwebengineprofile.cpp83
-rw-r--r--src/webengine/api/qquickwebengineprofile_p.h4
-rw-r--r--src/webengine/api/qquickwebengineprofile_p_p.h20
-rw-r--r--src/webengine/api/qquickwebenginesingleton_p.h1
-rw-r--r--src/webengine/plugin/experimental/plugin.cpp5
-rw-r--r--src/webengine/webengine.pro3
-rw-r--r--tests/quicktestbrowser/DownloadView.qml165
-rw-r--r--tests/quicktestbrowser/quicktestbrowser.pro1
-rw-r--r--tests/quicktestbrowser/quickwindow.qml27
-rw-r--r--tests/quicktestbrowser/resources.qrc1
21 files changed, 783 insertions, 185 deletions
diff --git a/src/core/browser_context_adapter.cpp b/src/core/browser_context_adapter.cpp
index 637003f96..95ddc4d87 100644
--- a/src/core/browser_context_adapter.cpp
+++ b/src/core/browser_context_adapter.cpp
@@ -36,8 +36,10 @@
#include "browser_context_adapter.h"
+#include "content/public/browser/browser_thread.h"
#include "browser_context_qt.h"
#include "content_client_qt.h"
+#include "download_manager_delegate_qt.h"
#include "web_engine_context.h"
#include "web_engine_visited_links_manager.h"
#include "url_request_context_getter_qt.h"
@@ -67,6 +69,7 @@ BrowserContextAdapter::BrowserContextAdapter(bool offTheRecord)
, m_httpCacheType(DiskHttpCache)
, m_persistentCookiesPolicy(AllowPersistentCookies)
, m_visitedLinksPolicy(TrackVisitedLinksOnDisk)
+ , m_client(0)
, m_httpCacheMaxSize(0)
{
}
@@ -84,6 +87,8 @@ BrowserContextAdapter::BrowserContextAdapter(const QString &storageName)
BrowserContextAdapter::~BrowserContextAdapter()
{
+ if (m_downloadManagerDelegate)
+ content::BrowserThread::DeleteSoon(content::BrowserThread::UI, FROM_HERE, m_downloadManagerDelegate.take());
}
void BrowserContextAdapter::setStorageName(const QString &storageName)
@@ -118,6 +123,23 @@ WebEngineVisitedLinksManager *BrowserContextAdapter::visitedLinksManager()
return m_visitedLinksManager.data();
}
+DownloadManagerDelegateQt *BrowserContextAdapter::downloadManagerDelegate()
+{
+ if (!m_downloadManagerDelegate)
+ m_downloadManagerDelegate.reset(new DownloadManagerDelegateQt(this));
+ return m_downloadManagerDelegate.data();
+}
+
+void BrowserContextAdapter::setClient(BrowserContextAdapterClient *adapterClient)
+{
+ m_client = adapterClient;
+}
+
+void BrowserContextAdapter::cancelDownload(quint32 downloadId)
+{
+ downloadManagerDelegate()->cancelDownload(downloadId);
+}
+
BrowserContextAdapter* BrowserContextAdapter::defaultContext()
{
return WebEngineContext::current()->defaultBrowserContext();
diff --git a/src/core/browser_context_adapter.h b/src/core/browser_context_adapter.h
index 8f03f2094..1c12c465d 100644
--- a/src/core/browser_context_adapter.h
+++ b/src/core/browser_context_adapter.h
@@ -43,7 +43,9 @@
#include <QSharedData>
#include <QString>
+class BrowserContextAdapterClient;
class BrowserContextQt;
+class DownloadManagerDelegateQt;
class WebEngineVisitedLinksManager;
class QWEBENGINE_EXPORT BrowserContextAdapter : public QSharedData
@@ -57,6 +59,12 @@ public:
static BrowserContextAdapter* offTheRecordContext();
WebEngineVisitedLinksManager *visitedLinksManager();
+ DownloadManagerDelegateQt *downloadManagerDelegate();
+
+ BrowserContextAdapterClient* client() { return m_client; }
+
+ void setClient(BrowserContextAdapterClient *adapterClient);
+ void cancelDownload(quint32 downloadId);
BrowserContextQt *browserContext();
@@ -116,12 +124,14 @@ private:
bool m_offTheRecord;
QScopedPointer<BrowserContextQt> m_browserContext;
QScopedPointer<WebEngineVisitedLinksManager> m_visitedLinksManager;
+ QScopedPointer<DownloadManagerDelegateQt> m_downloadManagerDelegate;
QString m_dataPath;
QString m_cachePath;
QString m_httpUserAgent;
HttpCacheType m_httpCacheType;
PersistentCookiesPolicy m_persistentCookiesPolicy;
VisitedLinksPolicy m_visitedLinksPolicy;
+ BrowserContextAdapterClient *m_client;
int m_httpCacheMaxSize;
Q_DISABLE_COPY(BrowserContextAdapter)
diff --git a/src/core/browser_context_adapter_client.h b/src/core/browser_context_adapter_client.h
new file mode 100644
index 000000000..2b6b4f434
--- /dev/null
+++ b/src/core/browser_context_adapter_client.h
@@ -0,0 +1,63 @@
+ /****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef BROWSER_CONTEXT_ADAPTER_CLIENT_H
+#define BROWSER_CONTEXT_ADAPTER_CLIENT_H
+
+#include "qtwebenginecoreglobal.h"
+#include <QString>
+
+class QWEBENGINE_EXPORT BrowserContextAdapterClient
+{
+public:
+ // Keep in sync with content::DownloadItem::DownloadState
+ enum DownloadState {
+ // Download is actively progressing.
+ DownloadInProgress = 0,
+ // Download is completely finished.
+ DownloadCompleted,
+ // Download has been cancelled.
+ DownloadCancelled,
+ // This state indicates that the download has been interrupted.
+ DownloadInterrupted
+ };
+ virtual ~BrowserContextAdapterClient() { }
+
+ virtual void downloadRequested(quint32 downloadId, QString &downloadPath, bool &cancelled) = 0;
+ virtual void downloadUpdated(quint32 downloadId, int downloadState, int percentComplete) = 0;
+};
+
+#endif // BROWSER_CONTEXT_ADAPTER_CLIENT_H
diff --git a/src/core/browser_context_qt.cpp b/src/core/browser_context_qt.cpp
index 9337b6b6b..4661f59fc 100644
--- a/src/core/browser_context_qt.cpp
+++ b/src/core/browser_context_qt.cpp
@@ -37,12 +37,12 @@
#include "browser_context_qt.h"
#include "browser_context_adapter.h"
+#include "download_manager_delegate_qt.h"
#include "type_conversion.h"
#include "qtwebenginecoreglobal.h"
#include "resource_context_qt.h"
#include "url_request_context_getter_qt.h"
-#include "base/files/scoped_temp_dir.h"
#include "base/time/time.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/storage_partition.h"
@@ -108,7 +108,7 @@ content::ResourceContext *BrowserContextQt::GetResourceContext()
content::DownloadManagerDelegate *BrowserContextQt::GetDownloadManagerDelegate()
{
- return downloadManagerDelegate.get();
+ return m_adapter->downloadManagerDelegate();
}
content::BrowserPluginGuestManager *BrowserContextQt::GetGuestManager()
diff --git a/src/core/browser_context_qt.h b/src/core/browser_context_qt.h
index c11a234ab..8ab6024ae 100644
--- a/src/core/browser_context_qt.h
+++ b/src/core/browser_context_qt.h
@@ -41,7 +41,8 @@
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/resource_context.h"
#include "net/url_request/url_request_context.h"
-#include "download_manager_delegate_qt.h"
+
+#include <QtCore/qcompilerdetection.h> // Needed for Q_DECL_OVERRIDE
class BrowserContextAdapter;
class URLRequestContextGetterQt;
@@ -72,7 +73,6 @@ public:
private:
scoped_ptr<content::ResourceContext> resourceContext;
scoped_refptr<URLRequestContextGetterQt> url_request_getter_;
- scoped_ptr<DownloadManagerDelegateQt> downloadManagerDelegate;
BrowserContextAdapter *m_adapter;
friend class BrowserContextAdapter;
diff --git a/src/core/core_gyp_generator.pro b/src/core/core_gyp_generator.pro
index 4514475ec..90a665e84 100644
--- a/src/core/core_gyp_generator.pro
+++ b/src/core/core_gyp_generator.pro
@@ -86,6 +86,7 @@ HEADERS = \
browser_accessibility_manager_qt.h \
browser_accessibility_qt.h \
browser_context_adapter.h \
+ browser_context_adapter_client.h \
browser_context_qt.h \
certificate_error_controller_p.h \
certificate_error_controller.h \
diff --git a/src/core/download_manager_delegate_qt.cpp b/src/core/download_manager_delegate_qt.cpp
index 3df03ffa3..3f6ec7bcc 100644
--- a/src/core/download_manager_delegate_qt.cpp
+++ b/src/core/download_manager_delegate_qt.cpp
@@ -36,6 +36,7 @@
#include "download_manager_delegate_qt.h"
+#include "content/public/browser/download_manager.h"
#include "content/public/browser/download_item.h"
#include "content/public/browser/save_page_type.h"
#include "content/public/browser/web_contents.h"
@@ -46,115 +47,21 @@
#include <QMap>
#include <QStandardPaths>
+#include "browser_context_adapter.h"
+#include "browser_context_adapter_client.h"
+#include "browser_context_qt.h"
#include "type_conversion.h"
#include "qtwebenginecoreglobal.h"
-// Helper class to track currently ongoing downloads to prevent file name
-// clashes / overwriting of files.
-class DownloadTargetHelper : public content::DownloadItem::Observer {
-public:
- DownloadTargetHelper()
- : m_defaultDownloadDirectory(QStandardPaths::writableLocation(QStandardPaths::DownloadLocation))
- {
-
- }
- virtual ~DownloadTargetHelper() {}
-
- bool determineDownloadTarget(content::DownloadItem *item, const content::DownloadTargetCallback &callback);
-
- virtual void OnDownloadUpdated(content::DownloadItem *download) Q_DECL_OVERRIDE;
- virtual void OnDownloadDestroyed(content::DownloadItem *download) Q_DECL_OVERRIDE;
-private:
- bool isPathAvailable(const QString& path);
-
- QDir m_defaultDownloadDirectory;
- QMap<content::DownloadItem*, QString> m_ongoingDownloads;
-};
-
-bool DownloadTargetHelper::isPathAvailable(const QString& path)
-{
- return !m_ongoingDownloads.values().contains(path) && !QFile::exists(path);
-}
-
-bool DownloadTargetHelper::determineDownloadTarget(content::DownloadItem *item, const content::DownloadTargetCallback &callback)
-{
- std::string suggestedFilename = item->GetSuggestedFilename();
-
- if (suggestedFilename.empty())
- suggestedFilename = item->GetTargetFilePath().AsUTF8Unsafe();
-
- if (suggestedFilename.empty())
- suggestedFilename = item->GetURL().ExtractFileName();
-
- if (suggestedFilename.empty())
- suggestedFilename = "qwe_download";
-
- if (!m_defaultDownloadDirectory.exists() && !m_defaultDownloadDirectory.mkpath(m_defaultDownloadDirectory.absolutePath()))
- return false;
-
- QString suggestedFilePath = m_defaultDownloadDirectory.absoluteFilePath(QString::fromStdString(suggestedFilename));
- if (!isPathAvailable(suggestedFilePath)) {
- int i = 1;
- for (; i < 99; i++) {
- QFileInfo tmpFile(suggestedFilePath);
- QString tmpFilePath = QString("%1%2%3(%4).%5").arg(tmpFile.absolutePath()).arg(QDir::separator()).arg(tmpFile.baseName()).arg(i).arg(tmpFile.completeSuffix());
- if (isPathAvailable(tmpFilePath)) {
- suggestedFilePath = tmpFilePath;
- break;
- }
- }
- if (i >= 99) {
- callback.Run(base::FilePath(), content::DownloadItem::TARGET_DISPOSITION_PROMPT, content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT, base::FilePath());
- return false;
- }
- }
-
- m_ongoingDownloads.insert(item, suggestedFilePath);
- item->AddObserver(this);
-
- base::FilePath filePathForCallback(toFilePathString(suggestedFilePath));
- callback.Run(filePathForCallback, content::DownloadItem::TARGET_DISPOSITION_OVERWRITE,
- content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT, filePathForCallback.AddExtension(toFilePathString("download")));
- return true;
-}
-
-void DownloadTargetHelper::OnDownloadUpdated(content::DownloadItem *download)
+DownloadManagerDelegateQt::DownloadManagerDelegateQt(BrowserContextAdapter *contextAdapter)
+ : m_currentId(0)
+ , m_contextAdapter(contextAdapter)
{
- switch (download->GetState()) {
- case content::DownloadItem::COMPLETE:
- case content::DownloadItem::CANCELLED:
- case content::DownloadItem::INTERRUPTED:
- download->RemoveObserver(this);
- m_ongoingDownloads.remove(download);
- break;
- case content::DownloadItem::IN_PROGRESS:
- default:
- break;
- }
-}
-
-void DownloadTargetHelper::OnDownloadDestroyed(content::DownloadItem *download)
-{
- download->RemoveObserver(this);
- m_ongoingDownloads.remove(download);
-}
-
-DownloadManagerDelegateQt::DownloadManagerDelegateQt()
- : m_targetHelper(new DownloadTargetHelper())
- , m_currentId(0)
-{
-
+ Q_ASSERT(m_contextAdapter);
}
DownloadManagerDelegateQt::~DownloadManagerDelegateQt()
{
- delete m_targetHelper;
-}
-
-
-void DownloadManagerDelegateQt::Shutdown()
-{
- QT_NOT_YET_IMPLEMENTED
}
void DownloadManagerDelegateQt::GetNextId(const content::DownloadIdCallback& callback)
@@ -162,24 +69,17 @@ void DownloadManagerDelegateQt::GetNextId(const content::DownloadIdCallback& cal
callback.Run(++m_currentId);
}
-bool DownloadManagerDelegateQt::ShouldOpenFileBasedOnExtension(const base::FilePath& path)
-{
- QT_NOT_YET_IMPLEMENTED
- return false;
-}
-
-bool DownloadManagerDelegateQt::ShouldCompleteDownload(content::DownloadItem* item,
- const base::Closure& complete_callback)
+void DownloadManagerDelegateQt::cancelDownload(const content::DownloadTargetCallback& callback)
{
- QT_NOT_YET_IMPLEMENTED
- return true;
+ callback.Run(base::FilePath(), content::DownloadItem::TARGET_DISPOSITION_PROMPT, content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT, base::FilePath());
}
-bool DownloadManagerDelegateQt::ShouldOpenDownload(content::DownloadItem* item,
- const content::DownloadOpenDelayedCallback& callback)
+void DownloadManagerDelegateQt::cancelDownload(quint32 downloadId)
{
- QT_NOT_YET_IMPLEMENTED
- return false;
+ content::DownloadManager* dlm = content::BrowserContext::GetDownloadManager(m_contextAdapter->browserContext());
+ content::DownloadItem *download = dlm->GetDownload(downloadId);
+ if (download)
+ download->Cancel(/* user_cancel */ true);
}
bool DownloadManagerDelegateQt::DetermineDownloadTarget(content::DownloadItem* item,
@@ -194,41 +94,55 @@ bool DownloadManagerDelegateQt::DetermineDownloadTarget(content::DownloadItem* i
return true;
}
- // Let the target helper determine the download target path.
- return m_targetHelper->determineDownloadTarget(item, callback);
-}
+ std::string suggestedFilename = item->GetSuggestedFilename();
-bool DownloadManagerDelegateQt::GenerateFileHash()
-{
- QT_NOT_YET_IMPLEMENTED
- return false;
-}
+ if (suggestedFilename.empty())
+ suggestedFilename = item->GetTargetFilePath().AsUTF8Unsafe();
-void DownloadManagerDelegateQt::ChooseSavePath(
- content::WebContents* web_contents,
- const base::FilePath& suggested_path,
- const base::FilePath::StringType& default_extension,
- bool can_save_as_complete,
- const content::SavePackagePathPickedCallback& callback)
-{
- QT_NOT_YET_IMPLEMENTED
-}
+ if (suggestedFilename.empty())
+ suggestedFilename = item->GetURL().ExtractFileName();
-void DownloadManagerDelegateQt::OpenDownload(content::DownloadItem* download)
-{
- QT_NOT_YET_IMPLEMENTED
-}
+ if (suggestedFilename.empty())
+ suggestedFilename = "qwe_download";
-void DownloadManagerDelegateQt::ShowDownloadInShell(content::DownloadItem* download)
-{
- QT_NOT_YET_IMPLEMENTED
-}
+ QDir defaultDownloadDirectory = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation);
-void DownloadManagerDelegateQt::CheckForFileExistence(
- content::DownloadItem* download,
- const content::CheckForFileExistenceCallback& callback)
-{
- QT_NOT_YET_IMPLEMENTED
+ QFileInfo suggestedFile(defaultDownloadDirectory.absoluteFilePath(QString::fromStdString(suggestedFilename)));
+ QString suggestedFilePath = suggestedFile.absoluteFilePath();
+ QString tmpFileBase = QString("%1%2%3").arg(suggestedFile.absolutePath()).arg(QDir::separator()).arg(suggestedFile.baseName());
+
+ for (int i = 1; QFileInfo::exists(suggestedFilePath); ++i) {
+ suggestedFilePath = QString("%1(%2).%3").arg(tmpFileBase).arg(i).arg(suggestedFile.completeSuffix());
+ if (i >= 99) {
+ suggestedFilePath = suggestedFile.absoluteFilePath();
+ break;
+ }
+ }
+
+ item->AddObserver(this);
+ quint32 downloadId = item->GetId();
+ if (m_contextAdapter->client()) {
+ bool cancelled = false;
+ m_contextAdapter->client()->downloadRequested(downloadId, suggestedFilePath, cancelled);
+ suggestedFile.setFile(suggestedFilePath);
+
+ if (!cancelled && !suggestedFile.absoluteDir().mkpath(suggestedFile.absolutePath())) {
+ qWarning("Creating download path failed, download cancelled: %s", suggestedFile.absolutePath().toUtf8().data());
+ cancelled = true;
+ }
+
+ if (cancelled) {
+ cancelDownload(callback);
+ return true;
+ }
+
+ base::FilePath filePathForCallback(toFilePathString(suggestedFile.absoluteFilePath()));
+ callback.Run(filePathForCallback, content::DownloadItem::TARGET_DISPOSITION_OVERWRITE,
+ content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT, filePathForCallback.AddExtension(toFilePathString("download")));
+ } else
+ cancelDownload(callback);
+
+ return true;
}
void DownloadManagerDelegateQt::GetSaveDir(content::BrowserContext* browser_context,
@@ -242,4 +156,16 @@ void DownloadManagerDelegateQt::GetSaveDir(content::BrowserContext* browser_cont
*skip_dir_check = true;
}
+void DownloadManagerDelegateQt::OnDownloadUpdated(content::DownloadItem *download)
+{
+ const quint32 downloadId = download->GetId();
+
+ if (m_contextAdapter->client())
+ m_contextAdapter->client()->downloadUpdated(downloadId, download->GetState(), download->PercentComplete());
+}
+void DownloadManagerDelegateQt::OnDownloadDestroyed(content::DownloadItem *download)
+{
+ download->RemoveObserver(this);
+ download->Cancel(/* user_cancel */ false);
+}
diff --git a/src/core/download_manager_delegate_qt.h b/src/core/download_manager_delegate_qt.h
index 4c838363f..007f2e580 100644
--- a/src/core/download_manager_delegate_qt.h
+++ b/src/core/download_manager_delegate_qt.h
@@ -39,7 +39,7 @@
#include "content/public/browser/download_manager_delegate.h"
-#include <qglobal.h>
+#include <QtCore/qcompilerdetection.h> // Needed for Q_DECL_OVERRIDE
namespace base {
class FilePath;
@@ -51,46 +51,38 @@ class DownloadItem;
class WebContents;
}
-class DownloadTargetHelper;
-
-class DownloadManagerDelegateQt : public content::DownloadManagerDelegate
+class BrowserContextAdapter;
+class DownloadManagerDelegateInstance;
+class DownloadManagerDelegateQt
+ : public content::DownloadManagerDelegate
+ , public content::DownloadItem::Observer
{
public:
- DownloadManagerDelegateQt();
- virtual ~DownloadManagerDelegateQt();
-
- void Shutdown() Q_DECL_OVERRIDE;
+ DownloadManagerDelegateQt(BrowserContextAdapter *contextAdapter);
+ ~DownloadManagerDelegateQt();
void GetNextId(const content::DownloadIdCallback& callback) Q_DECL_OVERRIDE;
- bool ShouldOpenFileBasedOnExtension(const base::FilePath& path) Q_DECL_OVERRIDE;
- bool ShouldCompleteDownload(content::DownloadItem* item,
- const base::Closure& complete_callback) Q_DECL_OVERRIDE;
-
- bool ShouldOpenDownload(content::DownloadItem* item,
- const content::DownloadOpenDelayedCallback& callback) Q_DECL_OVERRIDE;
bool DetermineDownloadTarget(content::DownloadItem* item,
const content::DownloadTargetCallback& callback) Q_DECL_OVERRIDE;
- bool GenerateFileHash() Q_DECL_OVERRIDE;
- void ChooseSavePath(content::WebContents* web_contents,
- const base::FilePath& suggested_path,
- const base::FilePath::StringType& default_extension,
- bool can_save_as_complete,
- const content::SavePackagePathPickedCallback& callback) Q_DECL_OVERRIDE;
-
- void OpenDownload(content::DownloadItem* download) Q_DECL_OVERRIDE;
- void ShowDownloadInShell(content::DownloadItem* download) Q_DECL_OVERRIDE;
- void CheckForFileExistence(content::DownloadItem* download,
- const content::CheckForFileExistenceCallback& callback) Q_DECL_OVERRIDE;
-
void GetSaveDir(content::BrowserContext* browser_context,
base::FilePath* website_save_dir,
base::FilePath* download_save_dir,
bool* skip_dir_check) Q_DECL_OVERRIDE;
+ void cancelDownload(quint32 downloadId);
+
+ // Inherited from content::DownloadItem::Observer
+ void OnDownloadUpdated(content::DownloadItem *download) Q_DECL_OVERRIDE;
+ void OnDownloadDestroyed(content::DownloadItem *download) Q_DECL_OVERRIDE;
+
private:
- DownloadTargetHelper* m_targetHelper;
+ void cancelDownload(const content::DownloadTargetCallback& callback);
+ BrowserContextAdapter *m_contextAdapter;
+
uint64 m_currentId;
+
+ friend class DownloadManagerDelegateInstance;
DISALLOW_COPY_AND_ASSIGN(DownloadManagerDelegateQt);
};
diff --git a/src/webengine/api/qquickwebenginedownloaditem.cpp b/src/webengine/api/qquickwebenginedownloaditem.cpp
new file mode 100644
index 000000000..729cb0d3f
--- /dev/null
+++ b/src/webengine/api/qquickwebenginedownloaditem.cpp
@@ -0,0 +1,134 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickwebenginedownloaditem_p.h"
+#include "qquickwebenginedownloaditem_p_p.h"
+
+QT_BEGIN_NAMESPACE
+
+QQuickWebEngineDownloadItemPrivate::QQuickWebEngineDownloadItemPrivate(QQuickWebEngineProfilePrivate *p)
+ : profile(p)
+ , downloadStarted(false)
+ , downloadId(-1)
+ , downloadState(QQuickWebEngineDownloadItem::DownloadCancelled)
+ , downloadProgress(0)
+{
+}
+
+QQuickWebEngineDownloadItemPrivate::~QQuickWebEngineDownloadItemPrivate()
+{
+ Q_Q(QQuickWebEngineDownloadItem);
+ q->cancel();
+}
+
+void QQuickWebEngineDownloadItemPrivate::update(QQuickWebEngineDownloadItem::DownloadState state, int progress)
+{
+ Q_Q(QQuickWebEngineDownloadItem);
+ if (state != downloadState) {
+ downloadState = state;
+ Q_EMIT q->stateChanged();
+ }
+ if (progress != downloadProgress) {
+ downloadProgress = progress;
+ Q_EMIT q->progressChanged();
+ }
+}
+
+void QQuickWebEngineDownloadItem::cancel()
+{
+ Q_D(QQuickWebEngineDownloadItem);
+
+ if (d->downloadState == QQuickWebEngineDownloadItem::DownloadCompleted
+ || d->downloadState == QQuickWebEngineDownloadItem::DownloadCancelled)
+ return;
+
+ d->update(QQuickWebEngineDownloadItem::DownloadCancelled, d->downloadProgress);
+
+ // We directly cancel the download if the user cancels before
+ // it even started, so no need to notify the profile here.
+ if (d->downloadStarted)
+ d->profile->cancelDownload(d->downloadId);
+}
+
+quint32 QQuickWebEngineDownloadItem::id()
+{
+ Q_D(QQuickWebEngineDownloadItem);
+ return d->downloadId;
+}
+
+QQuickWebEngineDownloadItem::DownloadState QQuickWebEngineDownloadItem::state()
+{
+ Q_D(QQuickWebEngineDownloadItem);
+ return d->downloadState;
+}
+
+int QQuickWebEngineDownloadItem::progress()
+{
+ Q_D(QQuickWebEngineDownloadItem);
+ return d->downloadProgress;
+}
+
+QString QQuickWebEngineDownloadItem::path()
+{
+ Q_D(QQuickWebEngineDownloadItem);
+ return d->downloadPath;
+}
+
+void QQuickWebEngineDownloadItem::setPath(QString path)
+{
+ Q_D(QQuickWebEngineDownloadItem);
+ if (d->downloadStarted) {
+ qWarning("Setting the download path is not allowed after the download has been started.");
+ return;
+ }
+ if (d->downloadPath != path) {
+ d->downloadPath = path;
+ Q_EMIT pathChanged();
+ }
+}
+
+QQuickWebEngineDownloadItem::QQuickWebEngineDownloadItem(QQuickWebEngineDownloadItemPrivate *p, QObject *parent)
+ : QObject(parent)
+ , d_ptr(p)
+{
+ p->q_ptr = this;
+}
+
+QQuickWebEngineDownloadItem::~QQuickWebEngineDownloadItem()
+{
+}
+
+QT_END_NAMESPACE
diff --git a/src/webengine/api/qquickwebenginedownloaditem_p.h b/src/webengine/api/qquickwebenginedownloaditem_p.h
new file mode 100644
index 000000000..8ea9f0850
--- /dev/null
+++ b/src/webengine/api/qquickwebenginedownloaditem_p.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKWEBENGINEDOWNLOADITEM_P_H
+#define QQUICKWEBENGINEDOWNLOADITEM_P_H
+
+#include <qtwebengineglobal_p.h>
+#include <QObject>
+#include <QScopedPointer>
+#include <QString>
+
+QT_BEGIN_NAMESPACE
+
+class QQuickWebEngineDownloadItemPrivate;
+class QQuickWebEngineProfilePrivate;
+
+class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineDownloadItem: public QObject {
+ Q_OBJECT
+public:
+ ~QQuickWebEngineDownloadItem();
+ enum DownloadState {
+ DownloadInProgress,
+ DownloadCompleted,
+ DownloadCancelled,
+ DownloadInterrupted
+ };
+ Q_ENUMS(DownloadState)
+
+ Q_PROPERTY(quint32 id READ id() CONSTANT FINAL)
+ Q_PROPERTY(DownloadState state READ state NOTIFY stateChanged)
+ Q_PROPERTY(int progress READ progress NOTIFY progressChanged)
+ Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged)
+
+ Q_INVOKABLE void cancel();
+
+ quint32 id();
+ DownloadState state();
+ int progress();
+ QString path();
+ void setPath(QString path);
+
+Q_SIGNALS:
+ void stateChanged();
+ void progressChanged();
+ void pathChanged();
+
+private:
+ QQuickWebEngineDownloadItem(QQuickWebEngineDownloadItemPrivate*, QObject *parent = 0);
+ Q_DISABLE_COPY(QQuickWebEngineDownloadItem)
+ Q_DECLARE_PRIVATE(QQuickWebEngineDownloadItem)
+ friend class QQuickWebEngineProfilePrivate;
+
+ QScopedPointer<QQuickWebEngineDownloadItemPrivate> d_ptr;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKWEBENGINEDOWNLOADITEM_P_H
diff --git a/src/webengine/api/qquickwebenginedownloaditem_p_p.h b/src/webengine/api/qquickwebenginedownloaditem_p_p.h
new file mode 100644
index 000000000..6b724b4c9
--- /dev/null
+++ b/src/webengine/api/qquickwebenginedownloaditem_p_p.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKWEBENGINEDOWNLOADITEM_P_P_H
+#define QQUICKWEBENGINEDOWNLOADITEM_P_P_H
+
+#include "qquickwebenginedownloaditem_p.h"
+#include "qquickwebengineprofile_p_p.h"
+#include <private/qtwebengineglobal_p.h>
+#include <QString>
+
+QT_BEGIN_NAMESPACE
+
+class QQuickWebEngineDownloadItemPrivate {
+ QQuickWebEngineDownloadItem *q_ptr;
+ QQuickWebEngineProfilePrivate* profile;
+ friend class QQuickWebEngineProfilePrivate;
+public:
+ Q_DECLARE_PUBLIC(QQuickWebEngineDownloadItem)
+ QQuickWebEngineDownloadItemPrivate(QQuickWebEngineProfilePrivate *p);
+ ~QQuickWebEngineDownloadItemPrivate();
+
+ bool downloadStarted;
+ quint32 downloadId;
+ QQuickWebEngineDownloadItem::DownloadState downloadState;
+ int downloadProgress;
+ QString downloadPath;
+
+ void update(QQuickWebEngineDownloadItem::DownloadState state, int progress);
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKWEBENGINEDOWNLOADITEM_P_P_H
diff --git a/src/webengine/api/qquickwebengineprofile.cpp b/src/webengine/api/qquickwebengineprofile.cpp
index 64d9805d6..9eecae073 100644
--- a/src/webengine/api/qquickwebengineprofile.cpp
+++ b/src/webengine/api/qquickwebengineprofile.cpp
@@ -36,31 +36,114 @@
#include "qquickwebengineprofile_p.h"
+#include "qquickwebenginedownloaditem_p.h"
+#include "qquickwebenginedownloaditem_p_p.h"
#include "qquickwebengineprofile_p_p.h"
+#include <QQmlEngine>
#include "browser_context_adapter.h"
QT_BEGIN_NAMESPACE
+static inline QQuickWebEngineDownloadItem::DownloadState toDownloadState(int state) {
+ switch (state) {
+ case BrowserContextAdapterClient::DownloadInProgress:
+ return QQuickWebEngineDownloadItem::DownloadInProgress;
+ case BrowserContextAdapterClient::DownloadCompleted:
+ return QQuickWebEngineDownloadItem::DownloadCompleted;
+ case BrowserContextAdapterClient::DownloadCancelled:
+ return QQuickWebEngineDownloadItem::DownloadCancelled;
+ case BrowserContextAdapterClient::DownloadInterrupted:
+ return QQuickWebEngineDownloadItem::DownloadInterrupted;
+ default:
+ Q_UNREACHABLE();
+ return QQuickWebEngineDownloadItem::DownloadCancelled;
+ }
+}
+
QQuickWebEngineProfilePrivate::QQuickWebEngineProfilePrivate(BrowserContextAdapter* browserContext, bool ownsContext)
: m_browserContext(browserContext)
{
if (ownsContext)
m_browserContextRef = browserContext;
+
+ m_browserContext->setClient(this);
}
QQuickWebEngineProfilePrivate::~QQuickWebEngineProfilePrivate()
{
+ m_browserContext->setClient(0);
+
+ Q_FOREACH (QQuickWebEngineDownloadItem* download, m_ongoingDownloads) {
+ if (download)
+ download->cancel();
+ }
+
+ m_ongoingDownloads.clear();
+}
+
+void QQuickWebEngineProfilePrivate::cancelDownload(quint32 downloadId)
+{
+ m_browserContext->cancelDownload(downloadId);
+}
+
+void QQuickWebEngineProfilePrivate::downloadDestroyed(quint32 downloadId)
+{
+ m_ongoingDownloads.remove(downloadId);
+}
+
+void QQuickWebEngineProfilePrivate::downloadRequested(quint32 downloadId, QString &downloadPath, bool &cancelled)
+{
+ Q_Q(QQuickWebEngineProfile);
+
+ Q_ASSERT(!m_ongoingDownloads.contains(downloadId));
+ QQuickWebEngineDownloadItemPrivate *itemPrivate = new QQuickWebEngineDownloadItemPrivate(this);
+ itemPrivate->downloadId = downloadId;
+ itemPrivate->downloadState = QQuickWebEngineDownloadItem::DownloadInProgress;
+ itemPrivate->downloadPath = downloadPath;
+
+ QQuickWebEngineDownloadItem *download = new QQuickWebEngineDownloadItem(itemPrivate, q);
+
+ m_ongoingDownloads.insert(downloadId, download);
+
+ QQmlEngine::setObjectOwnership(download, QQmlEngine::JavaScriptOwnership);
+ Q_EMIT q->downloadStarted(download);
+ download->d_func()->downloadStarted = true;
+
+ downloadPath = download->path();
+ cancelled = download->state() == QQuickWebEngineDownloadItem::DownloadCancelled;
+}
+
+void QQuickWebEngineProfilePrivate::downloadUpdated(quint32 downloadId, int downloadState, int percentComplete)
+{
+ Q_Q(QQuickWebEngineProfile);
+
+ Q_ASSERT(m_ongoingDownloads.contains(downloadId));
+ QQuickWebEngineDownloadItem* download = m_ongoingDownloads.value(downloadId).data();
+
+ if (!download) {
+ cancelDownload(downloadId);
+ return;
+ }
+
+ download->d_func()->update(toDownloadState(downloadState), percentComplete);
+
+ if (downloadState != BrowserContextAdapterClient::DownloadInProgress) {
+ Q_EMIT q->downloadFinished(download);
+ m_ongoingDownloads.remove(downloadId);
+ }
}
QQuickWebEngineProfile::QQuickWebEngineProfile()
: d_ptr(new QQuickWebEngineProfilePrivate(new BrowserContextAdapter(false), true))
{
+ d_ptr->q_ptr = this;
}
QQuickWebEngineProfile::QQuickWebEngineProfile(QQuickWebEngineProfilePrivate *privatePtr)
: d_ptr(privatePtr)
{
+ d_ptr->q_ptr = this;
}
QQuickWebEngineProfile::~QQuickWebEngineProfile()
diff --git a/src/webengine/api/qquickwebengineprofile_p.h b/src/webengine/api/qquickwebengineprofile_p.h
index 936573e8f..b8d7c8652 100644
--- a/src/webengine/api/qquickwebengineprofile_p.h
+++ b/src/webengine/api/qquickwebengineprofile_p.h
@@ -45,6 +45,7 @@
QT_BEGIN_NAMESPACE
+class QQuickWebEngineDownloadItem;
class QQuickWebEngineProfilePrivate;
class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineProfile : public QObject {
@@ -110,6 +111,9 @@ signals:
void persistentCookiesPolicyChanged();
void httpCacheMaxSizeChanged();
+ void downloadStarted(QQuickWebEngineDownloadItem *download);
+ void downloadFinished(QQuickWebEngineDownloadItem *download);
+
private:
Q_DECLARE_PRIVATE(QQuickWebEngineProfile);
QQuickWebEngineProfile(QQuickWebEngineProfilePrivate *);
diff --git a/src/webengine/api/qquickwebengineprofile_p_p.h b/src/webengine/api/qquickwebengineprofile_p_p.h
index d71dcfda9..18ccfc467 100644
--- a/src/webengine/api/qquickwebengineprofile_p_p.h
+++ b/src/webengine/api/qquickwebengineprofile_p_p.h
@@ -39,21 +39,37 @@
class BrowserContextAdapter;
+#include "browser_context_adapter_client.h"
+#include "qquickwebengineprofile_p.h"
+
#include <QExplicitlySharedDataPointer>
+#include <QMap>
+#include <QPointer>
QT_BEGIN_NAMESPACE
-
-class QQuickWebEngineProfilePrivate {
+class QQuickWebEngineDownloadItem;
+class QQuickWebEngineProfilePrivate
+ : public BrowserContextAdapterClient
+{
public:
+ Q_DECLARE_PUBLIC(QQuickWebEngineProfile)
QQuickWebEngineProfilePrivate(BrowserContextAdapter* browserContext, bool ownsContext);
~QQuickWebEngineProfilePrivate();
BrowserContextAdapter *browserContext() const { return m_browserContext; }
+ void cancelDownload(quint32 downloadId);
+ void downloadDestroyed(quint32 downloadId);
+
+ void downloadRequested(quint32 downloadId, QString &downloadPath, bool &cancelled) Q_DECL_OVERRIDE;
+ void downloadUpdated(quint32 downloadId, int downloadState, int percentComplete) Q_DECL_OVERRIDE;
+
private:
friend class QQuickWebEngineViewPrivate;
+ QQuickWebEngineProfile *q_ptr;
BrowserContextAdapter *m_browserContext;
QExplicitlySharedDataPointer<BrowserContextAdapter> m_browserContextRef;
+ QMap<quint32, QPointer<QQuickWebEngineDownloadItem> > m_ongoingDownloads;
};
QT_END_NAMESPACE
diff --git a/src/webengine/api/qquickwebenginesingleton_p.h b/src/webengine/api/qquickwebenginesingleton_p.h
index 3bc1a9700..f983d0ffb 100644
--- a/src/webengine/api/qquickwebenginesingleton_p.h
+++ b/src/webengine/api/qquickwebenginesingleton_p.h
@@ -43,7 +43,6 @@
QT_BEGIN_NAMESPACE
class QQuickWebEngineProfile;
class QQuickWebEngineSettings;
-
class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineSingleton : public QObject {
Q_OBJECT
Q_PROPERTY(QQuickWebEngineSettings* settings READ settings CONSTANT FINAL)
diff --git a/src/webengine/plugin/experimental/plugin.cpp b/src/webengine/plugin/experimental/plugin.cpp
index 883ebc598..f522478ab 100644
--- a/src/webengine/plugin/experimental/plugin.cpp
+++ b/src/webengine/plugin/experimental/plugin.cpp
@@ -36,6 +36,7 @@
#include <QtQml/qqmlextensionplugin.h>
+#include "qquickwebenginedownloaditem_p.h"
#include "qquickwebenginehistory_p.h"
#include "qquickwebenginesettings_p.h"
#include "qquickwebenginesingleton_p.h"
@@ -80,7 +81,9 @@ public:
QObject::tr("Cannot create a separate instance of NavigationHistory"));
qmlRegisterUncreatableType<QQuickWebEngineSettings>(uri, 1, 0, "WebEngineSettings",
QObject::tr("Cannot create a separate instance of WebEngineSettings"));
- qmlRegisterSingletonType<QQuickWebEngineSingleton>(uri, 1, 0, "WebEngine", webEngineSingletonProvider);
+ qmlRegisterUncreatableType<QQuickWebEngineDownloadItem>(uri, 1, 1, "WebEngineDownloadItem",
+ QObject::tr("Cannot create a separate instance of WebEngineDownloadItem"));
+ qmlRegisterSingletonType<QQuickWebEngineSingleton>(uri, 1, 1, "WebEngine", webEngineSingletonProvider);
}
};
diff --git a/src/webengine/webengine.pro b/src/webengine/webengine.pro
index 11ec95c05..6d17fd2eb 100644
--- a/src/webengine/webengine.pro
+++ b/src/webengine/webengine.pro
@@ -13,6 +13,7 @@ QMAKE_DOCS = $$PWD/doc/qtwebengine.qdocconf
INCLUDEPATH += $$PWD api ../core
SOURCES = \
+ api/qquickwebenginedownloaditem.cpp \
api/qquickwebenginehistory.cpp \
api/qquickwebengineloadrequest.cpp \
api/qquickwebenginenavigationrequest.cpp \
@@ -29,6 +30,8 @@ SOURCES = \
HEADERS = \
api/qtwebengineglobal.h \
api/qtwebengineglobal_p.h \
+ api/qquickwebenginedownloaditem_p.h \
+ api/qquickwebenginedownloaditem_p_p.h \
api/qquickwebenginehistory_p.h \
api/qquickwebengineloadrequest_p.h \
api/qquickwebenginenavigationrequest_p.h \
diff --git a/tests/quicktestbrowser/DownloadView.qml b/tests/quicktestbrowser/DownloadView.qml
new file mode 100644
index 000000000..da24c0142
--- /dev/null
+++ b/tests/quicktestbrowser/DownloadView.qml
@@ -0,0 +1,165 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.1
+import QtQuick.Controls 1.0
+import QtQuick.Controls.Styles 1.0
+import QtWebEngine 1.0
+import QtWebEngine.experimental 1.1
+import QtQuick.Layouts 1.0
+
+Rectangle {
+ id: downloadView
+ color: "lightgray"
+
+ ListModel {
+ id: downloadModel
+ property var downloads: []
+ }
+
+ function append(download) {
+ downloadModel.append(download)
+ downloadModel.downloads.push(download)
+ }
+
+ Component {
+ id: downloadItemDelegate
+
+ Rectangle {
+ width: listView.width
+ height: childrenRect.height
+ anchors.margins: 10
+ radius: 3
+ color: "transparent"
+ border.color: "black"
+ Rectangle {
+ id: progressBar
+
+ property int progress: downloadModel.downloads[index] ? downloadModel.downloads[index].progress : 0
+
+ radius: 3
+ color: width == listView.width ? "green" : "#2b74c7"
+ width: listView.width / 100 * progress
+ height: cancelButton.height
+
+ Behavior on width {
+ SmoothedAnimation { duration: 100 }
+ }
+ }
+ Rectangle {
+ anchors {
+ left: parent.left
+ right: parent.right
+ leftMargin: 20
+ }
+ Label {
+ id: label
+ text: path
+ anchors {
+ verticalCenter: cancelButton.verticalCenter
+ left: parent.left
+ right: cancelButton.left
+ }
+ }
+ Button {
+ id: cancelButton
+ anchors.right: parent.right
+ iconSource: "icons/process-stop.png"
+ onClicked: {
+ var download = downloadModel.downloads[index]
+
+ download.cancel()
+
+ downloadModel.downloads = downloadModel.downloads.filter(function (el) {
+ return el.id !== download.id;
+ });
+ downloadModel.remove(index)
+ }
+ }
+ }
+ }
+
+ }
+ ListView {
+ id: listView
+ anchors {
+ topMargin: 10
+ top: parent.top
+ bottom: parent.bottom
+ horizontalCenter: parent.horizontalCenter
+ }
+ width: parent.width - 20
+ spacing: 5
+
+ model: downloadModel
+ delegate: downloadItemDelegate
+
+ Text {
+ visible: !listView.count
+ horizontalAlignment: Text.AlignHCenter
+ height: 30
+ anchors {
+ top: parent.top
+ left: parent.left
+ right: parent.right
+ }
+ font.pixelSize: 20
+ text: "No active downloads."
+ }
+
+ Rectangle {
+ color: "gray"
+ anchors {
+ bottom: parent.bottom
+ left: parent.left
+ right: parent.right
+ }
+ height: 30
+ Button {
+ id: okButton
+ text: "OK"
+ anchors.centerIn: parent
+ onClicked: {
+ downloadView.visible = false
+ }
+ }
+ }
+ }
+}
diff --git a/tests/quicktestbrowser/quicktestbrowser.pro b/tests/quicktestbrowser/quicktestbrowser.pro
index ac8fe74b3..1da197590 100644
--- a/tests/quicktestbrowser/quicktestbrowser.pro
+++ b/tests/quicktestbrowser/quicktestbrowser.pro
@@ -10,6 +10,7 @@ SOURCES = quickwindow.cpp \
OTHER_FILES += ButtonWithMenu.qml \
ContextMenuExtras.qml \
+ DownloadView.qml \
FeaturePermissionBar.qml \
quickwindow.qml
diff --git a/tests/quicktestbrowser/quickwindow.qml b/tests/quicktestbrowser/quickwindow.qml
index 7bc9dd289..92bd048d4 100644
--- a/tests/quicktestbrowser/quickwindow.qml
+++ b/tests/quicktestbrowser/quickwindow.qml
@@ -40,7 +40,7 @@
import QtQuick 2.1
import QtWebEngine 1.1
-import QtWebEngine.experimental 1.0
+import QtWebEngine.experimental 1.1
import QtQuick.Controls 1.0
import QtQuick.Controls.Styles 1.0
@@ -74,14 +74,18 @@ ApplicationWindow {
}
WebEngineProfile {
- id: testProfile;
- storageName: "Test";
+ id: testProfile
+ storageName: "Test"
httpCacheType: httpDiskCacheEnabled.checked ? WebEngineProfile.DiskHttpCache : WebEngineProfile.MemoryHttpCache;
+ onDownloadStarted: {
+ downloadView.visible = true
+ downloadView.append(download)
+ }
}
WebEngineProfile {
- id: otrProfile;
- offTheRecord: true;
+ id: otrProfile
+ offTheRecord: true
}
// Make sure the Qt.WindowFullscreenButtonHint is set on Mac.
@@ -92,6 +96,12 @@ ApplicationWindow {
StyleItem { id: styleItem }
property bool platformIsMac: styleItem.style == "mac"
+ Action {
+ shortcut: "Ctrl+D"
+ onTriggered: {
+ downloadView.visible = !downloadView.visible
+ }
+ }
Action {
id: focus
@@ -435,6 +445,13 @@ ApplicationWindow {
}
}
}
+
+ DownloadView {
+ id: downloadView
+ visible: false
+ anchors.fill: parent
+ }
+
ZoomController {
id: zoomController
y: parent.mapFromItem(currentWebView, 0 , 0).y - 4
diff --git a/tests/quicktestbrowser/resources.qrc b/tests/quicktestbrowser/resources.qrc
index 4880b3d65..3c9fd5dd7 100644
--- a/tests/quicktestbrowser/resources.qrc
+++ b/tests/quicktestbrowser/resources.qrc
@@ -4,6 +4,7 @@
<file>ContextMenuExtras.qml</file>
<file>FeaturePermissionBar.qml</file>
<file>ButtonWithMenu.qml</file>
+ <file>DownloadView.qml</file>
<file>ZoomController.qml</file>
</qresource>
<qresource prefix="icons">