summaryrefslogtreecommitdiffstats
path: root/lib/download_manager_delegate_qt.cpp
diff options
context:
space:
mode:
authorMichael BrĂ¼ning <michael.bruning@digia.com>2013-08-08 16:57:40 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-09-03 15:24:34 +0200
commit558999daa168af4d28495b0231165cf995a7653c (patch)
treef7acbbe84dc95d1f5a7084b466c66dc131988e35 /lib/download_manager_delegate_qt.cpp
parentc3f53cadb902f711a90b744c5b186208cf08826b (diff)
Add implementation to enable downloads.
This implementation will download files to the standard download directory and assign unique file names should there be a file with the same name existing or being downloaded. It should be replaced with some more sophisticated code that also takes into account settings and user choice possibly. For now, it is only added to make downloads work at all. Known issue: We do not get notified about completed downloads even though we are observing the DownloadItem objects. Change-Id: I2b52246635d3fd1358edc6b648d470ff821bc9f1 Reviewed-by: Zeno Albisser <zeno.albisser@digia.com>
Diffstat (limited to 'lib/download_manager_delegate_qt.cpp')
-rw-r--r--lib/download_manager_delegate_qt.cpp129
1 files changed, 125 insertions, 4 deletions
diff --git a/lib/download_manager_delegate_qt.cpp b/lib/download_manager_delegate_qt.cpp
index 4cece01a3..478f26471 100644
--- a/lib/download_manager_delegate_qt.cpp
+++ b/lib/download_manager_delegate_qt.cpp
@@ -46,10 +46,116 @@
#include "content/public/browser/web_contents.h"
#include "shared/shared_globals.h"
-DownloadManagerDelegateQt::DownloadManagerDelegateQt() : m_currentId(0)
+#include <QDir>
+#include <QFile>
+#include <QFileInfo>
+#include <QMap>
+#include <QStandardPaths>
+
+// 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);
+ virtual void OnDownloadDestroyed(content::DownloadItem *download);
+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 filenameToUse = QString::fromStdString(suggestedFilename);
+ QString suggestedFilePath = m_defaultDownloadDirectory.absoluteFilePath(filenameToUse);
+
+ 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(suggestedFilePath.toStdString());
+ callback.Run(filePathForCallback, content::DownloadItem::TARGET_DISPOSITION_OVERWRITE,
+ content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT, filePathForCallback.AddExtension("download"));
+ return true;
+}
+
+void DownloadTargetHelper::OnDownloadUpdated(content::DownloadItem *download)
+{
+ 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)
+{
+
+}
+
+DownloadManagerDelegateQt::~DownloadManagerDelegateQt()
+{
+ delete m_targetHelper;
+}
+
+
void DownloadManagerDelegateQt::Shutdown()
{
QT_NOT_YET_IMPLEMENTED
@@ -83,8 +189,20 @@ bool DownloadManagerDelegateQt::ShouldOpenDownload(content::DownloadItem* item,
bool DownloadManagerDelegateQt::DetermineDownloadTarget(content::DownloadItem* item,
const content::DownloadTargetCallback& callback)
{
- QT_NOT_YET_IMPLEMENTED
- return true;
+ base::FilePath downloadFilePath(QStandardPaths::writableLocation(QStandardPaths::DownloadLocation).toStdString());
+
+
+ // Keep the forced file path if set, also as the temporary file, so the check for existence
+ // will already return that the file exists. Forced file paths seem to be only used for
+ // store downloads and other special downloads, so they might never end up here anyway.
+ if (!item->GetForcedFilePath().empty()) {
+ callback.Run(item->GetForcedFilePath(), content::DownloadItem::TARGET_DISPOSITION_PROMPT,
+ content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, item->GetForcedFilePath());
+ return true;
+ }
+
+ // Let the target helper determine the download target path.
+ return m_targetHelper->determineDownloadTarget(item, callback);;
}
bool DownloadManagerDelegateQt::GenerateFileHash()
@@ -125,6 +243,9 @@ void DownloadManagerDelegateQt::GetSaveDir(content::BrowserContext* browser_cont
base::FilePath* download_save_dir,
bool* skip_dir_check)
{
- QT_NOT_YET_IMPLEMENTED
+ *website_save_dir = base::FilePath(QStandardPaths::writableLocation(QStandardPaths::DownloadLocation).toStdString());
+ *download_save_dir = base::FilePath(QStandardPaths::writableLocation(QStandardPaths::DownloadLocation).toStdString());
+ *skip_dir_check = true;
}
+