summaryrefslogtreecommitdiffstats
path: root/src/core/download_manager_delegate_qt.cpp
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 /src/core/download_manager_delegate_qt.cpp
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>
Diffstat (limited to 'src/core/download_manager_delegate_qt.cpp')
-rw-r--r--src/core/download_manager_delegate_qt.cpp216
1 files changed, 71 insertions, 145 deletions
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);
+}