Changeset View
Changeset View
Standalone View
Standalone View
webenginepart/src/webenginepartdownloadmanager.cpp
Context not available. | |||||
26 | #include <QWebEngineView> | 26 | #include <QWebEngineView> | ||
---|---|---|---|---|---|
27 | #include <QWebEngineProfile> | 27 | #include <QWebEngineProfile> | ||
28 | #include <QDebug> | 28 | #include <QDebug> | ||
29 | #include <QFileDialog> | ||||
30 | #include <QDir> | ||||
31 | #include <QStandardPaths> | ||||
32 | #include <QMessageBox> | ||||
33 | #include <QWebEngineCookieStore> | ||||
34 | #include <QDBusInterface> | ||||
35 | | ||||
36 | #include <KParts/BrowserOpenOrSaveQuestion> | ||||
37 | #include <KIO/CopyJob> | ||||
38 | #include <KJobWidgets> | ||||
39 | #include <KJobUiDelegate> | ||||
40 | #include <KIO/SimpleJob> | ||||
41 | #include <KParts/BrowserRun> | ||||
42 | #include <KLocalizedString> | ||||
29 | 43 | | |||
30 | WebEnginePartDownloadManager::WebEnginePartDownloadManager() | 44 | WebEnginePartDownloadManager::WebEnginePartDownloadManager() | ||
31 | : QObject() | 45 | : QObject(), m_lastRequestPage(Q_NULLPTR) | ||
32 | { | 46 | { | ||
33 | connect(QWebEngineProfile::defaultProfile(), &QWebEngineProfile::downloadRequested, this, &WebEnginePartDownloadManager::performDownload); | 47 | connect(QWebEngineProfile::defaultProfile(), &QWebEngineProfile::downloadRequested, this, &WebEnginePartDownloadManager::performDownload); | ||
48 | connect(QWebEngineProfile::defaultProfile()->cookieStore(), &QWebEngineCookieStore::cookieAdded, this, &WebEnginePartDownloadManager::addCookie); | ||||
34 | } | 49 | } | ||
35 | 50 | | |||
36 | WebEnginePartDownloadManager::~WebEnginePartDownloadManager() | 51 | WebEnginePartDownloadManager::~WebEnginePartDownloadManager() | ||
Context not available. | |||||
62 | 77 | | |||
63 | void WebEnginePartDownloadManager::performDownload(QWebEngineDownloadItem* it) | 78 | void WebEnginePartDownloadManager::performDownload(QWebEngineDownloadItem* it) | ||
64 | { | 79 | { | ||
80 | bool forceDownload = false; | ||||
81 | bool savingPage = false; | ||||
82 | #if QT_VERSION >= QT_VERSION_CHECK(5, 8, 0) | ||||
83 | savingPage = it->type() == QWebEngineDownloadItem::SavePage; | ||||
84 | forceDownload = it->type() != QWebEngineDownloadItem::UserRequested; | ||||
85 | #elif QT_VERSION >= QT_VERSION_CHECK(5, 7, 0) | ||||
86 | savingPage = it->savePageFormat() != QWebEngineDownloadItem::UnknownSaveFormat; | ||||
87 | #endif | ||||
88 | if(savingPage){ | ||||
89 | savePage(it); | ||||
90 | return; | ||||
91 | } | ||||
65 | WebEnginePage *page = m_requests.take(it->url()); | 92 | WebEnginePage *page = m_requests.take(it->url()); | ||
66 | bool forceNew = false; | 93 | bool newTabOrWindow = false; | ||
67 | if (!page && !m_pages.isEmpty()) { | 94 | if(!page && !m_pages.isEmpty()){ | ||
68 | qDebug() << "downloading" << it->url() << "in new window or tab"; | | |||
69 | page = m_pages.first(); | 95 | page = m_pages.first(); | ||
70 | forceNew = true; | 96 | newTabOrWindow = true; | ||
71 | } else if (!page) { | | |||
72 | qDebug() << "Couldn't find a part wanting to download" << it->url(); | | |||
73 | return; | | |||
74 | } | 97 | } | ||
75 | page->download(it->url(), forceNew); | 98 | if(page){ | ||
99 | if(forceDownload || page->forceDownloadWithThis()) saveOrOpen(it, page); | ||||
100 | else page->download(it, newTabOrWindow); | ||||
101 | } | ||||
102 | else performDownloadWithoutKIO(it); | ||||
103 | } | ||||
104 | | ||||
105 | bool WebEnginePartDownloadManager::saveOrOpen(QWebEngineDownloadItem* it, WebEnginePage* page) | ||||
106 | { | ||||
107 | QString mimeType = it->mimeType(); | ||||
108 | // Convert executable text files to plain text... | ||||
109 | if (KParts::BrowserRun::isTextExecutable(mimeType)) { | ||||
110 | mimeType = QLatin1String("text/plain"); | ||||
111 | } | ||||
112 | KParts::BrowserOpenOrSaveQuestion dlg(page->view(), it->url(), mimeType); | ||||
113 | dlg.setFeatures(KParts::BrowserOpenOrSaveQuestion::ServiceSelection); | ||||
114 | KParts::BrowserOpenOrSaveQuestion::Result res = dlg.askOpenOrSave(); | ||||
115 | KService::Ptr offer = dlg.selectedService(); | ||||
116 | switch(res){ | ||||
117 | case KParts::BrowserOpenOrSaveQuestion::Save: | ||||
118 | downloadAndSave(it, page); | ||||
119 | break; | ||||
120 | case KParts::BrowserOpenOrSaveQuestion::Open: | ||||
121 | downloadAndOpen(it, page, offer); | ||||
122 | break; | ||||
123 | default: | ||||
124 | return false; | ||||
125 | } | ||||
126 | it->cancel(); | ||||
127 | return true; | ||||
76 | } | 128 | } | ||
77 | 129 | | |||
78 | void WebEnginePartDownloadManager::recordNavigationRequest(WebEnginePage *page, const QUrl& url) | 130 | void WebEnginePartDownloadManager::recordNavigationRequest(WebEnginePage *page, const QUrl& url) | ||
79 | { | 131 | { | ||
80 | qDebug() << url; | | |||
81 | m_requests.insert(url, page); | 132 | m_requests.insert(url, page); | ||
133 | m_lastRequestPage = page; | ||||
134 | connect(m_lastRequestPage, &QWebEnginePage::loadFinished,this, &WebEnginePartDownloadManager::clearLastRequestPage); | ||||
135 | connect(m_lastRequestPage, &QWebEnginePage::destroyed, this, &WebEnginePartDownloadManager::clearLastRequestPage); | ||||
82 | } | 136 | } | ||
83 | 137 | | |||
84 | WebEnginePage* WebEnginePartDownloadManager::pageForDownload(QWebEngineDownloadItem* it) | 138 | WebEnginePage* WebEnginePartDownloadManager::pageForDownload(QWebEngineDownloadItem* it) | ||
Context not available. | |||||
89 | } | 143 | } | ||
90 | return page; | 144 | return page; | ||
91 | } | 145 | } | ||
146 | | ||||
147 | bool WebEnginePartDownloadManager::downloadAndSave(QWebEngineDownloadItem* it, WebEnginePage* page) | ||||
148 | { | ||||
149 | QString fileName = QDir(QStandardPaths::writableLocation(QStandardPaths::DownloadLocation)).filePath(it->path()); | ||||
150 | QUrl destUrl = QUrl::fromLocalFile(QFileDialog::getSaveFileName(page->view(), "Choose download destination", fileName)); | ||||
151 | if (!destUrl.isValid()) return true; | ||||
152 | QMap <QString,QString> metaData; | ||||
153 | metaData[QLatin1String("MaxCacheSize")] = QLatin1String("0"); | ||||
154 | metaData[QLatin1String("cache")] = QLatin1String("cache"); | ||||
155 | KParts::BrowserRun::saveUrlUsingKIO(it->url(), destUrl, page->view(), metaData); | ||||
156 | return true; | ||||
157 | } | ||||
158 | | ||||
159 | bool WebEnginePartDownloadManager::downloadAndOpen(QWebEngineDownloadItem* it, WebEnginePage* page, KService::Ptr offer) | ||||
160 | { | ||||
161 | if (KParts::BrowserRun::allowExecution(it->mimeType(), it->url())) { | ||||
162 | QList<QUrl> list {it->url()}; | ||||
163 | bool success = false; | ||||
164 | if (offer) { | ||||
165 | success = KRun::runService(*offer, list, page->view(), false, it->path()); | ||||
166 | } else { | ||||
167 | success = KRun::displayOpenWithDialog(list, page->view(), false, it->path()); | ||||
168 | if (!success) return false; | ||||
169 | } | ||||
170 | // For non KIO apps and cancelled Open With dialog, remove slave on hold. | ||||
171 | if (!success || (offer && !offer->categories().contains(QLatin1String("KDE")))) { | ||||
172 | KIO::SimpleJob::removeOnHold(); // Remove any slave-on-hold... | ||||
173 | } | ||||
174 | return true; | ||||
175 | } | ||||
176 | else return false; | ||||
177 | } | ||||
178 | | ||||
179 | //TODO: write a more fatureful function (have the user choose the path and format, for instance) | ||||
180 | void WebEnginePartDownloadManager::savePage(QWebEngineDownloadItem* it) | ||||
181 | { | ||||
182 | it->accept(); | ||||
183 | } | ||||
184 | | ||||
185 | //TODO: display message when download finished | ||||
186 | bool WebEnginePartDownloadManager::performDownloadWithoutKIO(QWebEngineDownloadItem* it) | ||||
187 | { | ||||
188 | qWarning() << "Downloading" << it->url() << "without using KIO"; | ||||
189 | QString path = QFileDialog::getSaveFileName(Q_NULLPTR, i18n("Download file"), it->path()); | ||||
190 | if(!path.isEmpty()) it->setPath(path); | ||||
191 | connect(it, &QWebEngineDownloadItem::finished, this, &WebEnginePartDownloadManager::downloadFinished); | ||||
192 | it->accept(); | ||||
193 | return true; | ||||
194 | } | ||||
195 | | ||||
196 | void WebEnginePartDownloadManager::addCookie(const QNetworkCookie& cookie) | ||||
197 | { | ||||
198 | if(!m_lastRequestPage) return; | ||||
199 | QDBusInterface interface("org.kde.kcookiejar5", "/modules/kcookiejar", "org.kde.KCookieServer"); | ||||
200 | if(!interface.isValid()){ | ||||
201 | qDebug() << "Invalid DBUS interface"; | ||||
202 | return; | ||||
203 | } | ||||
204 | QByteArray header("Set-Cookie: "); | ||||
205 | header += cookie.toRawForm(); | ||||
206 | QString url = m_lastRequestPage->url().toString(); | ||||
207 | qlonglong winId = m_lastRequestPage->view()->window()->winId(); | ||||
208 | interface.call(QDBus::NoBlock, "addCookies", url, header, winId); | ||||
209 | if(interface.lastError().isValid()) qDebug() << interface.lastError(); | ||||
210 | } | ||||
211 | | ||||
212 | void WebEnginePartDownloadManager::clearLastRequestPage() | ||||
213 | { | ||||
214 | if(m_lastRequestPage){ | ||||
215 | disconnect(m_lastRequestPage, &QWebEnginePage::loadFinished, this, &WebEnginePartDownloadManager::clearLastRequestPage); | ||||
216 | disconnect(m_lastRequestPage, &QWebEnginePage::destroyed, this, &WebEnginePartDownloadManager::clearLastRequestPage); | ||||
217 | m_lastRequestPage = Q_NULLPTR; | ||||
218 | } | ||||
219 | } | ||||
220 | | ||||
221 | void WebEnginePartDownloadManager::downloadFinished() | ||||
222 | { | ||||
223 | QMessageBox::information(Q_NULLPTR, "", i18n("Download finshed")); | ||||
224 | } | ||||
225 | | ||||
Context not available. |