diff options
Diffstat (limited to 'src')
29 files changed, 743 insertions, 199 deletions
diff --git a/src/core/browser_context_adapter.cpp b/src/core/browser_context_adapter.cpp index 133dd688a..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" @@ -54,9 +56,9 @@ namespace { inline QString buildLocationFromStandardPath(const QString &standardPath, const QString &name) { QString location = standardPath; if (location.isEmpty()) - location = QDir::homePath() % QDir::separator() % QChar::fromLatin1('.') % QCoreApplication::applicationName(); + location = QDir::homePath() % QLatin1String("/.") % QCoreApplication::applicationName(); - location.append(QDir::separator() % QLatin1String("QtWebEngine") % QDir::separator() % name); + location.append(QLatin1String("/QtWebEngine/") % name); return location; } } @@ -66,6 +68,8 @@ BrowserContextAdapter::BrowserContextAdapter(bool offTheRecord) , m_browserContext(new BrowserContextQt(this)) , m_httpCacheType(DiskHttpCache) , m_persistentCookiesPolicy(AllowPersistentCookies) + , m_visitedLinksPolicy(TrackVisitedLinksOnDisk) + , m_client(0) , m_httpCacheMaxSize(0) { } @@ -76,12 +80,15 @@ BrowserContextAdapter::BrowserContextAdapter(const QString &storageName) , m_browserContext(new BrowserContextQt(this)) , m_httpCacheType(DiskHttpCache) , m_persistentCookiesPolicy(AllowPersistentCookies) + , m_visitedLinksPolicy(TrackVisitedLinksOnDisk) , m_httpCacheMaxSize(0) { } BrowserContextAdapter::~BrowserContextAdapter() { + if (m_downloadManagerDelegate) + content::BrowserThread::DeleteSoon(content::BrowserThread::UI, FROM_HERE, m_downloadManagerDelegate.take()); } void BrowserContextAdapter::setStorageName(const QString &storageName) @@ -91,6 +98,7 @@ void BrowserContextAdapter::setStorageName(const QString &storageName) m_name = storageName; if (m_browserContext->url_request_getter_) m_browserContext->url_request_getter_->updateStorageSettings(); + m_visitedLinksManager.reset(); } void BrowserContextAdapter::setOffTheRecord(bool offTheRecord) @@ -100,6 +108,7 @@ void BrowserContextAdapter::setOffTheRecord(bool offTheRecord) m_offTheRecord = offTheRecord; if (m_browserContext->url_request_getter_) m_browserContext->url_request_getter_->updateStorageSettings(); + m_visitedLinksManager.reset(); } BrowserContextQt *BrowserContextAdapter::browserContext() @@ -114,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(); @@ -142,6 +168,7 @@ void BrowserContextAdapter::setDataPath(const QString &path) m_dataPath = path; if (m_browserContext->url_request_getter_) m_browserContext->url_request_getter_->updateStorageSettings(); + m_visitedLinksManager.reset(); } QString BrowserContextAdapter::cachePath() const @@ -170,7 +197,7 @@ QString BrowserContextAdapter::cookiesPath() const return QString(); QString basePath = dataPath(); if (!basePath.isEmpty()) - return basePath % QDir::separator() % QLatin1String("Coookies"); + return basePath % QLatin1String("/Coookies"); return QString(); } @@ -180,7 +207,7 @@ QString BrowserContextAdapter::httpCachePath() const return QString(); QString basePath = cachePath(); if (!basePath.isEmpty()) - return basePath % QDir::separator() % QLatin1String("Cache"); + return basePath % QLatin1String("/Cache"); return QString(); } @@ -234,6 +261,46 @@ void BrowserContextAdapter::setPersistentCookiesPolicy(BrowserContextAdapter::Pe m_browserContext->url_request_getter_->updateCookieStore(); } +BrowserContextAdapter::VisitedLinksPolicy BrowserContextAdapter::visitedLinksPolicy() const +{ + if (isOffTheRecord() || m_visitedLinksPolicy == DoNotTrackVisitedLinks) + return DoNotTrackVisitedLinks; + if (dataPath().isEmpty()) + return TrackVisitedLinksInMemory; + return m_visitedLinksPolicy; +} + +bool BrowserContextAdapter::trackVisitedLinks() const +{ + switch (visitedLinksPolicy()) { + case DoNotTrackVisitedLinks: + return false; + default: + break; + } + return true; +} + +bool BrowserContextAdapter::persistVisitedLinks() const +{ + switch (visitedLinksPolicy()) { + case DoNotTrackVisitedLinks: + case TrackVisitedLinksInMemory: + return false; + default: + break; + } + return true; +} + +void BrowserContextAdapter::setVisitedLinksPolicy(BrowserContextAdapter::VisitedLinksPolicy visitedLinksPolicy) +{ + if (m_visitedLinksPolicy == visitedLinksPolicy) + return; + m_visitedLinksPolicy = visitedLinksPolicy; + m_visitedLinksManager.reset(); +} + int BrowserContextAdapter::httpCacheMaxSize() const { return m_httpCacheMaxSize; diff --git a/src/core/browser_context_adapter.h b/src/core/browser_context_adapter.h index dabd8a11e..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(); @@ -90,25 +98,40 @@ public: ForcePersistentCookies }; + enum VisitedLinksPolicy { + DoNotTrackVisitedLinks = 0, + TrackVisitedLinksInMemory, + TrackVisitedLinksOnDisk, + }; + HttpCacheType httpCacheType() const; void setHttpCacheType(BrowserContextAdapter::HttpCacheType); PersistentCookiesPolicy persistentCookiesPolicy() const; void setPersistentCookiesPolicy(BrowserContextAdapter::PersistentCookiesPolicy); + VisitedLinksPolicy visitedLinksPolicy() const; + void setVisitedLinksPolicy(BrowserContextAdapter::VisitedLinksPolicy); + int httpCacheMaxSize() const; void setHttpCacheMaxSize(int maxSize); + bool trackVisitedLinks() const; + bool persistVisitedLinks() const; + private: QString m_name; 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 e2cc8851b..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" @@ -61,12 +61,12 @@ BrowserContextQt::~BrowserContextQt() base::FilePath BrowserContextQt::GetPath() const { - return base::FilePath(toFilePathString(m_adapter->dataPath())); + return toFilePath(m_adapter->dataPath()); } base::FilePath BrowserContextQt::GetCachePath() const { - return base::FilePath(toFilePathString(m_adapter->cachePath())); + return toFilePath(m_adapter->cachePath()); } bool BrowserContextQt::IsOffTheRecord() const @@ -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/content_browser_client_qt.cpp b/src/core/content_browser_client_qt.cpp index a327270a5..6dfaa64c7 100644 --- a/src/core/content_browser_client_qt.cpp +++ b/src/core/content_browser_client_qt.cpp @@ -70,6 +70,7 @@ #include "access_token_store_qt.h" #include <QGuiApplication> +#include <QLocale> #include <QOpenGLContext> #include <qpa/qplatformnativeinterface.h> @@ -405,6 +406,11 @@ void ContentBrowserClientQt::RequestGeolocationPermission(content::WebContents * contentsDelegate->requestGeolocationPermission(requestingFrameOrigin, resultCallback, cancelCallback); } +blink::WebNotificationPresenter::Permission ContentBrowserClientQt::CheckDesktopNotificationPermission(const GURL&, content::ResourceContext *, int ) +{ + return blink::WebNotificationPresenter::PermissionDenied; +} + content::LocationProvider *ContentBrowserClientQt::OverrideSystemLocationProvider() { #ifdef QT_USE_POSITIONING @@ -413,3 +419,8 @@ content::LocationProvider *ContentBrowserClientQt::OverrideSystemLocationProvide return 0; // Leave it up to Chromium to figure something out. #endif } + +std::string ContentBrowserClientQt::GetApplicationLocale() +{ + return QLocale().name().toStdString(); +} diff --git a/src/core/content_browser_client_qt.h b/src/core/content_browser_client_qt.h index 84b0734da..d5b49e835 100644 --- a/src/core/content_browser_client_qt.h +++ b/src/core/content_browser_client_qt.h @@ -52,6 +52,7 @@ class BrowserContext; class BrowserMainParts; class RenderProcessHost; class RenderViewHostDelegateView; +class ResourceContext; class WebContentsViewPort; class WebContents; struct MainFunctionParams; @@ -99,6 +100,10 @@ public: virtual net::URLRequestContextGetter *CreateRequestContext(content::BrowserContext *browser_context, content::ProtocolHandlerMap *protocol_handlers, content::URLRequestInterceptorScopedVector request_interceptorss) Q_DECL_OVERRIDE; + virtual blink::WebNotificationPresenter::Permission CheckDesktopNotificationPermission(const GURL& source_origin, content::ResourceContext* context, int render_process_id) Q_DECL_OVERRIDE; + + virtual std::string GetApplicationLocale() Q_DECL_OVERRIDE; + void enableInspector(bool enable, content::BrowserContext *browser_context); private: diff --git a/src/core/content_main_delegate_qt.cpp b/src/core/content_main_delegate_qt.cpp index e41888976..44dc0b8bd 100644 --- a/src/core/content_main_delegate_qt.cpp +++ b/src/core/content_main_delegate_qt.cpp @@ -52,6 +52,8 @@ #include "renderer/content_renderer_client_qt.h" #include "web_engine_library_info.h" +#include <QLocale> + static base::StringPiece PlatformResourceProvider(int key) { if (key == IDR_DIR_HEADER_HTML) { base::StringPiece html_data = ui::ResourceBundle::GetSharedInstance().GetRawDataResource(IDR_DIR_HEADER_HTML); @@ -63,7 +65,7 @@ static base::StringPiece PlatformResourceProvider(int key) { void ContentMainDelegateQt::PreSandboxStartup() { net::NetModule::SetResourceProvider(PlatformResourceProvider); - ui::ResourceBundle::InitSharedInstanceWithLocale(l10n_util::GetApplicationLocale(std::string("en-US")), 0); + ui::ResourceBundle::InitSharedInstanceWithLocale(QLocale().name().toStdString(), 0); // Suppress info, warning and error messages per default. int logLevel = logging::LOG_FATAL; 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/core/type_conversion.h b/src/core/type_conversion.h index f88e5dd21..781023b7c 100644 --- a/src/core/type_conversion.h +++ b/src/core/type_conversion.h @@ -39,6 +39,7 @@ #include <QColor> #include <QDateTime> +#include <QDir> #include <QMatrix4x4> #include <QRect> #include <QString> @@ -142,7 +143,7 @@ inline base::Time toTime(const QDateTime &dateTime) { inline base::FilePath::StringType toFilePathString(const QString &str) { #if defined(OS_WIN) - return str.toStdWString(); + return QDir::toNativeSeparators(str).toStdWString(); #else return str.toStdString(); #endif diff --git a/src/core/url_request_context_getter_qt.cpp b/src/core/url_request_context_getter_qt.cpp index 0d72845b5..5d32ef470 100644 --- a/src/core/url_request_context_getter_qt.cpp +++ b/src/core/url_request_context_getter_qt.cpp @@ -177,7 +177,7 @@ void URLRequestContextGetterQt::generateCookieStore() case BrowserContextAdapter::AllowPersistentCookies: cookieStore = content::CreateCookieStore(content::CookieStoreConfig( - base::FilePath(toFilePathString(m_browserContext->cookiesPath())), + toFilePath(m_browserContext->cookiesPath()), content::CookieStoreConfig::PERSISTANT_SESSION_COOKIES, NULL, NULL) ); @@ -185,7 +185,7 @@ void URLRequestContextGetterQt::generateCookieStore() case BrowserContextAdapter::ForcePersistentCookies: cookieStore = content::CreateCookieStore(content::CookieStoreConfig( - base::FilePath(toFilePathString(m_browserContext->cookiesPath())), + toFilePath(m_browserContext->cookiesPath()), content::CookieStoreConfig::RESTORED_SESSION_COOKIES, NULL, NULL) ); @@ -240,7 +240,7 @@ void URLRequestContextGetterQt::generateHttpCache() new net::HttpCache::DefaultBackend( net::DISK_CACHE, net::CACHE_BACKEND_DEFAULT, - base::FilePath(toFilePathString(m_browserContext->httpCachePath())), + toFilePath(m_browserContext->httpCachePath()), m_browserContext->httpCacheMaxSize(), BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE) ); diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp index a2d548fc7..9d53dc48d 100644 --- a/src/core/web_contents_delegate_qt.cpp +++ b/src/core/web_contents_delegate_qt.cpp @@ -269,12 +269,12 @@ void WebContentsDelegateQt::UpdateTargetURL(content::WebContents *source, int32 void WebContentsDelegateQt::DidNavigateAnyFrame(const content::LoadCommittedDetails &, const content::FrameNavigateParams ¶ms) { - if (!params.should_update_history || m_viewClient->browserContextAdapter()->isOffTheRecord()) + // VisistedLinksMaster asserts !IsOffTheRecord(). + if (!params.should_update_history || !m_viewClient->browserContextAdapter()->trackVisitedLinks()) return; m_viewClient->browserContextAdapter()->visitedLinksManager()->addUrl(params.url); } - void WebContentsDelegateQt::overrideWebPreferences(content::WebContents *, WebPreferences *webPreferences) { m_viewClient->webEngineSettings()->overrideWebPreferences(webPreferences); diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp index 60a5d0810..d48c23815 100644 --- a/src/core/web_engine_context.cpp +++ b/src/core/web_engine_context.cpp @@ -91,6 +91,15 @@ void destroyContext() sContext = 0; } +bool usingANGLE() +{ +#if defined(Q_OS_WIN) + return QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES; +#else + return false; +#endif +} + bool usingSoftwareDynamicGL() { #if defined(Q_OS_WIN) @@ -221,7 +230,7 @@ WebEngineContext::WebEngineContext() GLContextHelper::initialize(); - if (usingSoftwareDynamicGL() || usingQtQuick2DRenderer()) { + if (usingANGLE() || usingSoftwareDynamicGL() || usingQtQuick2DRenderer()) { parsedCommandLine->AppendSwitch(switches::kDisableGpu); } else { const char *glType; diff --git a/src/core/web_engine_library_info.cpp b/src/core/web_engine_library_info.cpp index beae9dd75..09e2af495 100644 --- a/src/core/web_engine_library_info.cpp +++ b/src/core/web_engine_library_info.cpp @@ -78,7 +78,7 @@ QString location(QLibraryInfo::LibraryLocation path) switch (path) { case QLibraryInfo::TranslationsPath: if (!webEnginePath.isEmpty()) - return webEnginePath % QDir::separator() % QLatin1String("translations"); + return webEnginePath % QLatin1String("/translations"); break; case QLibraryInfo::DataPath: if (!webEnginePath.isEmpty()) @@ -138,7 +138,7 @@ QString subProcessPath() % QStringLiteral("/Helpers/" QTWEBENGINEPROCESS_NAME ".app/Contents/MacOS/" QTWEBENGINEPROCESS_NAME)); #else static QString processPath (location(QLibraryInfo::LibraryExecutablesPath) - % QDir::separator() % processBinary); + % QLatin1Char('/') % processBinary); #endif if (!initialized) { // Allow overriding at runtime for the time being. @@ -147,7 +147,7 @@ QString subProcessPath() processPath = QString::fromLatin1(fromEnv); if (!QFileInfo(processPath).exists()) { qWarning("QtWebEngineProcess not found at location %s. Trying fallback path...", qPrintable(processPath)); - processPath = QCoreApplication::applicationDirPath() % QDir::separator() % processBinary; + processPath = QCoreApplication::applicationDirPath() % QLatin1Char('/') % processBinary; } if (!QFileInfo(processPath).exists()) qFatal("QtWebEngineProcess not found at location %s. Try setting the QTWEBENGINEPROCESS_PATH environment variable.", qPrintable(processPath)); @@ -162,7 +162,7 @@ QString pluginsPath() #if defined(OS_MACOSX) && defined(QT_MAC_FRAMEWORK_BUILD) return getPath(frameworkBundle()) % QLatin1String("/Libraries"); #else - return location(QLibraryInfo::PluginsPath) % QDir::separator() % QLatin1String("qtwebengine"); + return location(QLibraryInfo::PluginsPath) % QLatin1String("/qtwebengine"); #endif } @@ -176,7 +176,7 @@ QString localesPath() } QString fallbackDir() { - static QString directory = QDir::homePath() % QDir::separator() % QChar::fromLatin1('.') % QCoreApplication::applicationName(); + static QString directory = QDir::homePath() % QLatin1String("/.") % QCoreApplication::applicationName(); return directory; } diff --git a/src/core/web_engine_visited_links_manager.cpp b/src/core/web_engine_visited_links_manager.cpp index a2f6dbf9f..c5ed54f3e 100644 --- a/src/core/web_engine_visited_links_manager.cpp +++ b/src/core/web_engine_visited_links_manager.cpp @@ -81,12 +81,17 @@ void WebEngineVisitedLinksManager::deleteVisitedLinkDataForUrls(const QList<QUrl m_visitedLinkMaster->DeleteURLs(&iterator); } +bool WebEngineVisitedLinksManager::containsUrl(const QUrl &url) const +{ + return m_visitedLinkMaster->IsVisited(toGurl(url)); +} + WebEngineVisitedLinksManager::WebEngineVisitedLinksManager(BrowserContextAdapter *adapter) : m_delegate(new VisitedLinkDelegateQt) { Q_ASSERT(adapter && adapter->browserContext()); BrowserContextQt *browserContext = adapter->browserContext(); - m_visitedLinkMaster.reset(new visitedlink::VisitedLinkMaster(browserContext, m_delegate.data(), /* persist to disk = */true)); + m_visitedLinkMaster.reset(new visitedlink::VisitedLinkMaster(browserContext, m_delegate.data(), adapter->persistVisitedLinks())); m_visitedLinkMaster->Init(); } diff --git a/src/core/web_engine_visited_links_manager.h b/src/core/web_engine_visited_links_manager.h index 5b0286c51..dc2a4bff2 100644 --- a/src/core/web_engine_visited_links_manager.h +++ b/src/core/web_engine_visited_links_manager.h @@ -63,6 +63,8 @@ public: void deleteAllVisitedLinkData(); void deleteVisitedLinkDataForUrls(const QList<QUrl> &); + bool containsUrl(const QUrl &) const; + private: void addUrl(const GURL &); friend class WebContentsDelegateQt; 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..93f0cb7f0 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,6 +81,8 @@ 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")); + qmlRegisterUncreatableType<QQuickWebEngineDownloadItem>(uri, 1, 0, "WebEngineDownloadItem", + QObject::tr("Cannot create a separate instance of WebEngineDownloadItem")); qmlRegisterSingletonType<QQuickWebEngineSingleton>(uri, 1, 0, "WebEngine", webEngineSingletonProvider); } }; diff --git a/src/webengine/webengine.pro b/src/webengine/webengine.pro index 303370365..15514e457 100644 --- a/src/webengine/webengine.pro +++ b/src/webengine/webengine.pro @@ -11,6 +11,7 @@ QMAKE_DOCS = $$PWD/doc/qtwebengine.qdocconf INCLUDEPATH += $$PWD api ../core SOURCES = \ + api/qquickwebenginedownloaditem.cpp \ api/qquickwebenginehistory.cpp \ api/qquickwebengineloadrequest.cpp \ api/qquickwebenginenavigationrequest.cpp \ @@ -27,6 +28,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/src/webenginewidgets/api/qwebengineprofile.cpp b/src/webenginewidgets/api/qwebengineprofile.cpp index 1487f06ce..9929ee657 100644 --- a/src/webenginewidgets/api/qwebengineprofile.cpp +++ b/src/webenginewidgets/api/qwebengineprofile.cpp @@ -40,6 +40,7 @@ #include "qwebengineprofile_p.h" #include "browser_context_adapter.h" +#include "web_engine_visited_links_manager.h" QT_BEGIN_NAMESPACE @@ -305,6 +306,37 @@ void QWebEngineProfile::setHttpCacheMaximumSize(int maxSize) } /*! + Clears all links from the visited links database. + + \sa clearVisitedLinks() +*/ +void QWebEngineProfile::clearAllVisitedLinks() +{ + Q_D(QWebEngineProfile); + d->browserContext()->visitedLinksManager()->deleteAllVisitedLinkData(); +} + +/*! + Clears the links in \a urls from the visited links database. + + \sa clearAllVisitedLinks() +*/ +void QWebEngineProfile::clearVisitedLinks(const QList<QUrl> &urls) +{ + Q_D(QWebEngineProfile); + d->browserContext()->visitedLinksManager()->deleteVisitedLinkDataForUrls(urls); +} + +/*! + Returns true if \a url is considered a visited link by this profile. +*/ +bool QWebEngineProfile::visitedLinksContainsUrl(const QUrl &url) const +{ + Q_D(const QWebEngineProfile); + return d->browserContext()->visitedLinksManager()->containsUrl(url); +} + +/*! Returns the default profile. The default profile uses the storage name "Default". diff --git a/src/webenginewidgets/api/qwebengineprofile.h b/src/webenginewidgets/api/qwebengineprofile.h index d21eed372..0536d711f 100644 --- a/src/webenginewidgets/api/qwebengineprofile.h +++ b/src/webenginewidgets/api/qwebengineprofile.h @@ -46,6 +46,7 @@ QT_BEGIN_NAMESPACE class QObject; +class QUrl; class QWebEnginePage; class QWebEnginePagePrivate; class QWebEngineProfilePrivate; @@ -89,6 +90,10 @@ public: int httpCacheMaximumSize() const; void setHttpCacheMaximumSize(int maxSize); + void clearAllVisitedLinks(); + void clearVisitedLinks(const QList<QUrl> &urls); + bool visitedLinksContainsUrl(const QUrl &url) const; + static QWebEngineProfile *defaultProfile(); private: |