diff --git a/webenginepart/src/CMakeLists.txt b/webenginepart/src/CMakeLists.txt --- a/webenginepart/src/CMakeLists.txt +++ b/webenginepart/src/CMakeLists.txt @@ -7,6 +7,7 @@ webenginepage.cpp websslinfo.cpp webhistoryinterface.cpp + webenginepartdownloadmanager.cpp settings/webenginesettings.cpp settings/webengine_filter.cpp ui/searchbar.cpp diff --git a/webenginepart/src/webenginepage.h b/webenginepart/src/webenginepage.h --- a/webenginepart/src/webenginepage.h +++ b/webenginepart/src/webenginepage.h @@ -62,21 +62,17 @@ */ void setSslInfo (const WebSslInfo &other); - /** - * Reimplemented for internal reasons. The API is not affected. - * - * @internal - * @see KWebEnginePage::downloadRequest. - */ - void downloadRequest(QWebEngineDownloadItem* request); + void download(const QUrl &url, bool newWindow = false); Q_SIGNALS: /** * This signal is emitted whenever a user cancels/aborts a load resource * request. */ void loadAborted(const QUrl &url); + void navigationRequested(WebEnginePage* page, const QUrl& url); + protected: /** * Returns the webengine part in use by this object. @@ -125,7 +121,6 @@ QPointer m_part; QScopedPointer m_passwdServerClient; - }; diff --git a/webenginepart/src/webenginepage.cpp b/webenginepart/src/webenginepage.cpp --- a/webenginepart/src/webenginepage.cpp +++ b/webenginepart/src/webenginepage.cpp @@ -26,6 +26,7 @@ #include "websslinfo.h" #include "webengineview.h" #include "settings/webenginesettings.h" +#include "webenginepartdownloadmanager.h" #include #include @@ -88,11 +89,11 @@ this, &WebEnginePage::slotLoadFinished); connect(this, &QWebEnginePage::authenticationRequired, this, &WebEnginePage::slotAuthenticationRequired); - connect(this->profile(), &QWebEngineProfile::downloadRequested, this, &WebEnginePage::downloadRequest); if(!this->profile()->httpUserAgent().contains(QLatin1String("Konqueror"))) { this->profile()->setHttpUserAgent(this->profile()->httpUserAgent() + " Konqueror (WebEnginePart)"); } + WebEnginePartDownloadManager::instance()->addPage(this); } WebEnginePage::~WebEnginePage() @@ -131,10 +132,8 @@ cmd = exeName; } -void WebEnginePage::downloadRequest(QWebEngineDownloadItem* request) +void WebEnginePage::download(const QUrl& url, bool newWindow) { - const QUrl url(request->url()); - // Integration with a download manager... if (!url.isLocalFile()) { QString managerExe; @@ -145,21 +144,9 @@ return; } } - - // Ask the user where to save. We don't have a GUI like Firefox or Chrome to - // notify of something being saved to the Downloads directory. - QPointer dlg(new QFileDialog(view())); - dlg->setAcceptMode(QFileDialog::AcceptSave); - dlg->setWindowTitle(i18n("Save As")); - dlg->setConfirmOverwrite(true); - dlg->selectFile(request->path()); - if (dlg->exec()) { - request->setPath(dlg->selectedFiles().at(0)); - request->accept(); - } else { - request->cancel(); - } - delete dlg; + KParts::BrowserArguments bArgs; + bArgs.setForcesNewWindow(newWindow); + emit part()->browserExtension()->openUrlRequest(url, KParts::OpenUrlArguments(), bArgs); } QWebEnginePage *WebEnginePage::createWindow(WebWindowType type) @@ -271,7 +258,7 @@ // Honor the enabling/disabling of plugins per host. settings()->setAttribute(QWebEngineSettings::PluginsEnabled, WebEngineSettings::self()->isPluginsEnabled(reqUrl.host())); - // Insert the request into the queue... + emit navigationRequested(this, url); return QWebEnginePage::acceptNavigationRequest(url, type, isMainFrame); } @@ -839,8 +826,9 @@ webenginePart->connectWebEnginePageSignals(this); //Set the create new window flag to false... m_createNewWindow = false; - } + } + emit navigationRequested(this, url); return WebEnginePage::acceptNavigationRequest(url, type, isMainFrame); } diff --git a/webenginepart/src/webenginepartdownloadmanager.h b/webenginepart/src/webenginepartdownloadmanager.h new file mode 100644 --- /dev/null +++ b/webenginepart/src/webenginepartdownloadmanager.h @@ -0,0 +1,60 @@ +/* + * This file is part of the KDE project. + * + * Copyright (C) 2017 Stefano Crocco + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + */ + +#ifndef WEBENGINEPARTDOWNLOADMANAGER_H +#define WEBENGINEPARTDOWNLOADMANAGER_H + +#include +#include +#include + +class WebEnginePage; +class QWebEngineDownloadItem; + +class WebEnginePartDownloadManager : public QObject +{ + Q_OBJECT + +public: + + static WebEnginePartDownloadManager* instance(); + + ~WebEnginePartDownloadManager(); + +public Q_SLOTS: + void addPage(WebEnginePage *page); + void removePage(QObject *page); + +private: + + WebEnginePartDownloadManager(); + WebEnginePage* pageForDownload(QWebEngineDownloadItem *it); + +private Q_SLOTS: + + void performDownload(QWebEngineDownloadItem *it); + void recordNavigationRequest(WebEnginePage* page, const QUrl& url); + +private: + QVector m_pages; + QHash m_requests; +}; + +#endif // WEBENGINEPARTDOWNLOADMANAGER_H diff --git a/webenginepart/src/webenginepartdownloadmanager.cpp b/webenginepart/src/webenginepartdownloadmanager.cpp new file mode 100644 --- /dev/null +++ b/webenginepart/src/webenginepartdownloadmanager.cpp @@ -0,0 +1,88 @@ +/* + * This file is part of the KDE project. + * + * Copyright (C) 2017 Stefano Crocco + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + */ + +#include "webenginepartdownloadmanager.h" + +#include "webenginepage.h" + +#include +#include +#include +#include + +WebEnginePartDownloadManager::WebEnginePartDownloadManager(): QObject() +{ + connect(QWebEngineProfile::defaultProfile(), &QWebEngineProfile::downloadRequested, this, &WebEnginePartDownloadManager::performDownload); +} + +WebEnginePartDownloadManager::~WebEnginePartDownloadManager() +{ + m_requests.clear(); +} + +WebEnginePartDownloadManager * WebEnginePartDownloadManager::instance() +{ + static WebEnginePartDownloadManager inst; + return &inst; +} + +void WebEnginePartDownloadManager::addPage(WebEnginePage* page) +{ + if (!m_pages.contains(page)) m_pages.append(page); + connect(page, &WebEnginePage::navigationRequested, this, &WebEnginePartDownloadManager::recordNavigationRequest); + connect(page, &QObject::destroyed, this, &WebEnginePartDownloadManager::removePage); +} + +void WebEnginePartDownloadManager::removePage(QObject* page) +{ + const QUrl url = m_requests.key(static_cast(page)); + m_requests.remove(url); + m_pages.removeOne(static_cast(page)); +} + +void WebEnginePartDownloadManager::performDownload(QWebEngineDownloadItem* it) +{ + WebEnginePage *page = m_requests.take(it->url()); + bool forceNew = false; + if (!page && !m_pages.isEmpty()) { + qDebug() << "downloading" << it->url() << "in new window or tab"; + page = m_pages.first(); + forceNew = true; + } + else if (!page){ + qDebug() << "Couldn't find a part wanting to download" << it->url(); + return; + } + page->download(it->url(), forceNew); +} + +void WebEnginePartDownloadManager::recordNavigationRequest(WebEnginePage *page, const QUrl& url) +{ + qDebug() << "recordNavigatioRequest for" << url; + m_requests.insert(url, page); +} + + +WebEnginePage* WebEnginePartDownloadManager::pageForDownload(QWebEngineDownloadItem* it) +{ + WebEnginePage *page = m_requests.value(it->url()); + if(!page && !m_pages.isEmpty()) page = m_pages.first(); + return page; +}