Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
Network
Konqueror
Commits
cd500298
Commit
cd500298
authored
Jul 25, 2020
by
Stefano Crocco
Browse files
Options
Browse Files
Download
Plain Diff
Add support for BLOB URLs
parents
54c5bc93
1e9659be
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
265 additions
and
7 deletions
+265
-7
src/konqmainwindow.cpp
src/konqmainwindow.cpp
+6
-0
webenginepart/src/CMakeLists.txt
webenginepart/src/CMakeLists.txt
+2
-0
webenginepart/src/webenginepage.cpp
webenginepart/src/webenginepage.cpp
+16
-1
webenginepart/src/webenginepage.h
webenginepart/src/webenginepage.h
+7
-3
webenginepart/src/webenginepartdownloadmanager.cpp
webenginepart/src/webenginepartdownloadmanager.cpp
+193
-2
webenginepart/src/webenginepartdownloadmanager.h
webenginepart/src/webenginepartdownloadmanager.h
+41
-1
No files found.
src/konqmainwindow.cpp
View file @
cd500298
...
...
@@ -697,6 +697,9 @@ void KonqMainWindow::openUrl(KonqView *_view, const QUrl &_url,
KIO
::
ApplicationLauncherJob
*
job
=
new
KIO
::
ApplicationLauncherJob
(
offer
);
job
->
setUrls
({
url
});
job
->
setUiDelegate
(
new
KIO
::
JobUiDelegate
(
KJobUiDelegate
::
AutoHandlingEnabled
,
this
));
if
(
req
.
tempFile
)
{
job
->
setRunFlags
(
KIO
::
ApplicationLauncherJob
::
DeleteTemporaryFiles
);
}
job
->
start
();
}
}
...
...
@@ -1023,6 +1026,9 @@ void KonqMainWindow::openUrlRequestHelper(KonqView *childView, const QUrl &url,
//qCDebug(KONQUEROR_LOG) << "url=" << url;
KonqOpenURLRequest
req
;
req
.
args
=
args
;
if
(
args
.
metaData
().
value
(
"konq-temp-file"
)
==
"1"
)
{
req
.
tempFile
=
true
;
}
req
.
browserArgs
=
browserArgs
;
openUrl
(
childView
,
url
,
args
.
mimeType
(),
req
,
browserArgs
.
trustedSource
);
}
...
...
webenginepart/src/CMakeLists.txt
View file @
cd500298
find_package
(
KF5
${
KF5_MIN_VERSION
}
REQUIRED COMPONENTS Wallet
)
find_package
(
KF5
${
KF5_MIN_VERSION
}
REQUIRED COMPONENTS Notifications
)
add_definitions
(
-DTRANSLATION_DOMAIN=\"webenginepart\"
)
...
...
@@ -56,6 +57,7 @@ target_link_libraries(kwebenginepartlib
Qt5::WebEngineWidgets
KF5::Parts
KF5::Wallet
KF5::Notifications
PRIVATE
Qt5::PrintSupport
KF5::SonnetCore
...
...
webenginepart/src/webenginepage.cpp
View file @
cd500298
...
...
@@ -159,6 +159,16 @@ void WebEnginePage::download(const QUrl& url, bool newWindow)
emit
part
()
->
browserExtension
()
->
openUrlRequest
(
url
,
KParts
::
OpenUrlArguments
(),
bArgs
);
}
void
WebEnginePage
::
requestOpenFileAsTemporary
(
const
QUrl
&
url
,
const
QString
&
mimeType
,
bool
newWindow
)
{
KParts
::
BrowserArguments
bArgs
;
bArgs
.
setForcesNewWindow
(
newWindow
);
KParts
::
OpenUrlArguments
oArgs
;
oArgs
.
setMimeType
(
mimeType
);
oArgs
.
metaData
().
insert
(
"konq-temp-file"
,
"1"
);
emit
part
()
->
browserExtension
()
->
openUrlRequest
(
url
,
oArgs
,
bArgs
);
}
QWebEnginePage
*
WebEnginePage
::
createWindow
(
WebWindowType
type
)
{
//qCDebug(WEBENGINEPART_LOG) << "window type:" << type;
...
...
@@ -744,7 +754,12 @@ void WebEnginePage::changeFullScreenMode(QWebEngineFullScreenRequest req)
}
void
WebEnginePage
::
setStatusBarText
(
const
QString
&
text
)
{
if
(
m_part
)
{
emit
m_part
->
setStatusBarText
(
text
);
}
}
/************************************* Begin NewWindowPage ******************************************/
...
...
webenginepart/src/webenginepage.h
View file @
cd500298
...
...
@@ -66,8 +66,12 @@ public:
void
download
(
const
QUrl
&
url
,
bool
newWindow
=
false
);
void
requestOpenFileAsTemporary
(
const
QUrl
&
url
,
const
QString
&
mimeType
=
""
,
bool
newWindow
=
false
);
void
setStatusBarText
(
const
QString
&
text
);
WebEngineWallet
*
wallet
()
const
{
return
m_wallet
;}
/**
* @brief Tells the page that the part has requested to load the given URL
*
...
...
@@ -112,7 +116,7 @@ protected:
* @internal
*/
bool
acceptNavigationRequest
(
const
QUrl
&
request
,
NavigationType
type
,
bool
isMainFrame
)
override
;
/**
* @brief Override of `QWebEnginePage::certificateError`
*
...
...
@@ -157,7 +161,7 @@ private:
QScopedPointer
<
KPasswdServerClient
>
m_passwdServerClient
;
WebEngineWallet
*
m_wallet
;
/**
* @brief The last URL that the part requested to be loaded
*
...
...
webenginepart/src/webenginepartdownloadmanager.cpp
View file @
cd500298
...
...
@@ -26,9 +26,24 @@
#include <QWebEngineDownloadItem>
#include <QWebEngineView>
#include <QWebEngineProfile>
#include <QFileDialog>
#include <QStandardPaths>
#include <QFileInfo>
#include <QMimeDatabase>
#include <QMimeType>
#include <QTimer>
#include <KLocalizedString>
#include <KNotificationJobUiDelegate>
#include <KParts/BrowserOpenOrSaveQuestion>
#include <KJobTrackerInterface>
#include <KIO/JobTracker>
#include <KIO/OpenUrlJob>
#include <KFileUtils>
#include <KIO/JobUiDelegate>
WebEnginePartDownloadManager
::
WebEnginePartDownloadManager
()
:
QObject
()
:
QObject
()
,
m_tempDownloadDir
(
QDir
(
QDir
::
tempPath
()).
filePath
(
"WebEnginePartDownloadManager"
))
{
connect
(
QWebEngineProfile
::
defaultProfile
(),
&
QWebEngineProfile
::
downloadRequested
,
this
,
&
WebEnginePartDownloadManager
::
performDownload
);
}
...
...
@@ -83,7 +98,101 @@ void WebEnginePartDownloadManager::performDownload(QWebEngineDownloadItem* it)
qCDebug
(
WEBENGINEPART_LOG
)
<<
"Couldn't find a part wanting to download"
<<
it
->
url
();
return
;
}
page
->
download
(
it
->
url
(),
forceNew
);
if
(
it
->
url
().
scheme
()
!=
"blob"
)
{
page
->
download
(
it
->
url
(),
forceNew
);
}
else
{
downloadBlob
(
it
);
}
}
void
WebEnginePartDownloadManager
::
downloadBlob
(
QWebEngineDownloadItem
*
it
)
{
WebEnginePage
*
p
=
qobject_cast
<
WebEnginePage
*>
(
it
->
page
());
QWidget
*
w
=
p
?
p
->
view
()
:
nullptr
;
KParts
::
BrowserOpenOrSaveQuestion
askDlg
(
w
,
it
->
url
(),
it
->
mimeType
());
KParts
::
BrowserOpenOrSaveQuestion
::
Result
ans
=
askDlg
.
askEmbedOrSave
(
KParts
::
BrowserOpenOrSaveQuestion
::
AttachmentDisposition
);
switch
(
ans
)
{
case
KParts
::
BrowserOpenOrSaveQuestion
::
Cancel
:
it
->
cancel
();
return
;
case
KParts
::
BrowserOpenOrSaveQuestion
::
Save
:
saveBlob
(
it
);
break
;
case
KParts
::
BrowserOpenOrSaveQuestion
::
Embed
:
case
KParts
::
BrowserOpenOrSaveQuestion
::
Open
:
openBlob
(
it
,
p
);
break
;
}
}
void
WebEnginePartDownloadManager
::
saveBlob
(
QWebEngineDownloadItem
*
it
)
{
QWidget
*
w
=
it
->
page
()
?
it
->
page
()
->
view
()
:
nullptr
;
QString
downloadDir
=
QStandardPaths
::
writableLocation
(
QStandardPaths
::
DownloadLocation
);
QMimeDatabase
db
;
QMimeType
type
=
db
.
mimeTypeForName
(
it
->
mimeType
());
QFileDialog
dlg
(
w
,
QString
(),
downloadDir
);
dlg
.
setAcceptMode
(
QFileDialog
::
AcceptSave
);
dlg
.
setMimeTypeFilters
(
QStringList
{
type
.
name
(),
"application/octet-stream"
});
dlg
.
setSupportedSchemes
(
QStringList
{
"file"
});
QDialog
::
DialogCode
exitCode
=
static_cast
<
QDialog
::
DialogCode
>
(
dlg
.
exec
());
if
(
exitCode
==
QDialog
::
Rejected
)
{
it
->
cancel
();
return
;
}
QString
file
=
dlg
.
selectedFiles
().
at
(
0
);
QFileInfo
info
(
file
);
it
->
setDownloadFileName
(
info
.
fileName
());
it
->
setDownloadDirectory
(
info
.
path
());
it
->
accept
();
it
->
pause
();
WebEngineBlobDownloadJob
*
j
=
new
WebEngineBlobDownloadJob
(
it
,
this
);
KJobTrackerInterface
*
t
=
KIO
::
getJobTracker
();
if
(
t
)
{
t
->
registerJob
(
j
);
}
j
->
start
();
}
void
WebEnginePartDownloadManager
::
openBlob
(
QWebEngineDownloadItem
*
it
,
WebEnginePage
*
page
)
{
QMimeDatabase
db
;
QMimeType
type
=
db
.
mimeTypeForName
(
it
->
mimeType
());
QString
fileName
=
generateBlobTempFileName
(
it
->
suggestedFileName
(),
type
.
preferredSuffix
());
it
->
setDownloadDirectory
(
m_tempDownloadDir
.
path
());
it
->
setDownloadFileName
(
fileName
);
connect
(
it
,
&
QWebEngineDownloadItem
::
finished
,
this
,
[
this
,
it
,
page
](){
blobDownloadedToFile
(
it
,
page
);});
it
->
accept
();
}
QString
WebEnginePartDownloadManager
::
generateBlobTempFileName
(
const
QString
&
suggestedName
,
const
QString
&
ext
)
const
{
QString
baseName
(
suggestedName
);
if
(
baseName
.
isEmpty
())
{
baseName
=
QString
::
number
(
QTime
::
currentTime
().
msecsSinceStartOfDay
());
}
if
(
QFileInfo
(
baseName
).
completeSuffix
().
isEmpty
()
&&
!
ext
.
isEmpty
())
{
baseName
.
append
(
"."
+
ext
);
}
QString
completeName
=
QDir
(
m_tempDownloadDir
.
path
()).
filePath
(
baseName
);
if
(
QFileInfo
::
exists
(
completeName
))
{
completeName
=
KFileUtils
::
suggestName
(
QUrl
::
fromLocalFile
(
m_tempDownloadDir
.
path
()),
baseName
);
}
return
completeName
;
}
void
WebEnginePartDownloadManager
::
blobDownloadedToFile
(
QWebEngineDownloadItem
*
it
,
WebEnginePage
*
page
)
{
QString
file
=
QDir
(
it
->
downloadDirectory
()).
filePath
(
it
->
downloadFileName
());
if
(
page
)
{
page
->
requestOpenFileAsTemporary
(
QUrl
::
fromLocalFile
(
file
),
it
->
mimeType
());
}
else
{
KIO
::
OpenUrlJob
*
j
=
new
KIO
::
OpenUrlJob
(
QUrl
::
fromLocalFile
(
file
),
it
->
mimeType
(),
this
);
QWidget
*
w
=
page
->
view
();
j
->
setUiDelegate
(
new
KIO
::
JobUiDelegate
(
KJobUiDelegate
::
AutoHandlingEnabled
,
w
?
w
->
window
()
:
nullptr
));
j
->
start
();
}
}
#ifndef DOWNLOADITEM_KNOWS_PAGE
...
...
@@ -103,3 +212,85 @@ WebEnginePage* WebEnginePartDownloadManager::pageForDownload(QWebEngineDownloadI
return
page
;
}
#endif
WebEngineBlobDownloadJob
::
WebEngineBlobDownloadJob
(
QWebEngineDownloadItem
*
it
,
QObject
*
parent
)
:
KJob
(
parent
),
m_downloadItem
(
it
)
{
setCapabilities
(
KJob
::
Killable
|
KJob
::
Suspendable
);
setTotalAmount
(
KJob
::
Bytes
,
m_downloadItem
->
totalBytes
());
connect
(
m_downloadItem
,
&
QWebEngineDownloadItem
::
downloadProgress
,
this
,
&
WebEngineBlobDownloadJob
::
downloadProgressed
);
connect
(
m_downloadItem
,
&
QWebEngineDownloadItem
::
finished
,
this
,
&
WebEngineBlobDownloadJob
::
downloadFinished
);
connect
(
m_downloadItem
,
&
QWebEngineDownloadItem
::
stateChanged
,
this
,
&
WebEngineBlobDownloadJob
::
stateChanged
);
}
void
WebEngineBlobDownloadJob
::
start
()
{
QTimer
::
singleShot
(
0
,
this
,
&
WebEngineBlobDownloadJob
::
startDownloading
);
}
bool
WebEngineBlobDownloadJob
::
doKill
()
{
delete
m_downloadItem
;
m_downloadItem
=
nullptr
;
return
true
;
}
bool
WebEngineBlobDownloadJob
::
doResume
()
{
if
(
m_downloadItem
)
{
m_downloadItem
->
resume
();
}
return
true
;
}
bool
WebEngineBlobDownloadJob
::
doSuspend
()
{
if
(
m_downloadItem
)
{
m_downloadItem
->
pause
();
}
return
true
;
}
void
WebEngineBlobDownloadJob
::
downloadProgressed
(
quint64
received
,
quint64
total
)
{
setPercent
(
received
*
100.0
/
total
);
}
void
WebEngineBlobDownloadJob
::
stateChanged
(
QWebEngineDownloadItem
::
DownloadState
state
)
{
if
(
state
!=
QWebEngineDownloadItem
::
DownloadInterrupted
)
{
return
;
}
setError
(
m_downloadItem
->
interruptReason
()
+
UserDefinedError
);
setErrorText
(
m_downloadItem
->
interruptReasonString
());
}
QString
WebEngineBlobDownloadJob
::
errorString
()
const
{
return
i18n
(
"An error occurred while saving the file: %1"
,
errorText
());
}
void
WebEngineBlobDownloadJob
::
startDownloading
()
{
if
(
m_downloadItem
)
{
m_startTime
=
QDateTime
::
currentDateTime
();
emit
description
(
this
,
i18nc
(
"Notification about downloading a file"
,
"Downloading"
),
QPair
<
QString
,
QString
>
(
i18nc
(
"Source of a file being downloaded"
,
"Source"
),
m_downloadItem
->
url
().
toString
()),
QPair
<
QString
,
QString
>
(
i18nc
(
"Destination of a file download"
,
"Destination"
),
m_downloadItem
->
downloadFileName
()));
m_downloadItem
->
resume
();
}
}
void
WebEngineBlobDownloadJob
::
downloadFinished
()
{
emitResult
();
QDateTime
now
=
QDateTime
::
currentDateTime
();
if
(
m_startTime
.
msecsTo
(
now
)
<
500
)
{
if
(
m_downloadItem
&&
m_downloadItem
->
page
())
{
WebEnginePage
*
page
=
qobject_cast
<
WebEnginePage
*>
(
m_downloadItem
->
page
());
QString
filePath
=
QDir
(
m_downloadItem
->
downloadDirectory
()).
filePath
(
m_downloadItem
->
downloadFileName
());
emit
page
->
setStatusBarText
(
i18nc
(
"Finished saving BLOB URL"
,
"Finished saving %1 as %2"
,
m_downloadItem
->
url
().
toString
(),
filePath
));
}
}
delete
m_downloadItem
;
m_downloadItem
=
nullptr
;
}
webenginepart/src/webenginepartdownloadmanager.h
View file @
cd500298
...
...
@@ -24,9 +24,14 @@
#include <QObject>
#include <QHash>
#include <QVector>
#include <QWebEngineDownloadItem>
#include <QTemporaryDir>
#include <QDateTime>
#include <KJob>
class
WebEnginePage
;
class
Q
WebEngineDownloadItem
;
class
Q
File
;
class
WebEnginePartDownloadManager
:
public
QObject
{
...
...
@@ -39,6 +44,8 @@ public:
private:
WebEnginePartDownloadManager
();
void
downloadBlob
(
QWebEngineDownloadItem
*
it
);
QString
generateBlobTempFileName
(
QString
const
&
suggestedName
,
const
QString
&
ext
)
const
;
public
Q_SLOTS
:
void
addPage
(
WebEnginePage
*
page
);
...
...
@@ -46,6 +53,9 @@ public Q_SLOTS:
private
Q_SLOTS
:
void
performDownload
(
QWebEngineDownloadItem
*
it
);
void
saveBlob
(
QWebEngineDownloadItem
*
it
);
void
openBlob
(
QWebEngineDownloadItem
*
it
,
WebEnginePage
*
page
);
void
blobDownloadedToFile
(
QWebEngineDownloadItem
*
it
,
WebEnginePage
*
page
);
#ifndef DOWNLOADITEM_KNOWS_PAGE
private:
...
...
@@ -60,6 +70,36 @@ private:
#ifndef DOWNLOADITEM_KNOWS_PAGE
QHash
<
QUrl
,
WebEnginePage
*>
m_requests
;
#endif
QTemporaryDir
m_tempDownloadDir
;
};
class
WebEngineBlobDownloadJob
:
public
KJob
{
Q_OBJECT
public:
WebEngineBlobDownloadJob
(
QWebEngineDownloadItem
*
it
,
QObject
*
parent
=
nullptr
);
~
WebEngineBlobDownloadJob
(){}
void
start
()
override
;
QString
errorString
()
const
override
;
protected:
bool
doKill
()
override
;
bool
doResume
()
override
;
bool
doSuspend
()
override
;
private
slots
:
void
downloadProgressed
(
quint64
received
,
quint64
total
);
void
stateChanged
(
QWebEngineDownloadItem
::
DownloadState
state
);
void
startDownloading
();
void
downloadFinished
();
private:
QWebEngineDownloadItem
*
m_downloadItem
;
QDateTime
m_startTime
;
};
#endif // WEBENGINEPARTDOWNLOADMANAGER_H
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment