Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
plasma-angelfish
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
Operations
Operations
Incidents
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Rinigus Saar
plasma-angelfish
Commits
de240d92
Commit
de240d92
authored
Mar 26, 2020
by
Marco Martin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
base on desktop file for app name/icon
open external links in external browser
parent
6092d883
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
317 additions
and
10 deletions
+317
-10
CMakeLists.txt
CMakeLists.txt
+1
-1
src/CMakeLists.txt
src/CMakeLists.txt
+11
-1
src/contents/webapp-ui/WebAppView.qml
src/contents/webapp-ui/WebAppView.qml
+270
-0
src/contents/webapp-ui/webapp.qml
src/contents/webapp-ui/webapp.qml
+2
-1
src/urlutils.cpp
src/urlutils.cpp
+5
-0
src/urlutils.h
src/urlutils.h
+1
-0
src/webapp-resources.qrc
src/webapp-resources.qrc
+1
-0
src/webappmain.cpp
src/webappmain.cpp
+26
-7
No files found.
CMakeLists.txt
View file @
de240d92
...
...
@@ -30,7 +30,7 @@ include(KDECompilerSettings NO_POLICY_SCOPE)
################# Find dependencies #################
find_package
(
Qt5
${
QT_MIN_VERSION
}
REQUIRED NO_MODULE COMPONENTS Core Quick Test Gui Svg QuickControls2 Sql
)
find_package
(
KF5
${
KF5_MIN_VERSION
}
REQUIRED COMPONENTS Kirigami2 Purpose I18n
)
find_package
(
KF5
${
KF5_MIN_VERSION
}
REQUIRED COMPONENTS Kirigami2 Purpose I18n
Config CoreAddons
)
# Necessary to support QtWebEngine installed in a different prefix than the rest of Qt (e.g flatpak)
find_package
(
Qt5WebEngine REQUIRED
)
...
...
src/CMakeLists.txt
View file @
de240d92
...
...
@@ -32,6 +32,16 @@ set(angelfish_webapp_SRCS
qt5_add_resources
(
WEBAPP_RESOURCES webapp-resources.qrc
)
add_executable
(
angelfish-webapp
${
angelfish_webapp_SRCS
}
${
RESOURCES
}
${
WEBAPP_RESOURCES
}
)
target_link_libraries
(
angelfish-webapp Qt5::Core Qt5::Qml Qt5::Quick Qt5::Sql Qt5::Svg Qt5::WebEngine KF5::I18n
)
target_link_libraries
(
angelfish-webapp
Qt5::Core
Qt5::Qml
Qt5::Quick
Qt5::Sql
Qt5::Svg
Qt5::WebEngine
KF5::I18n
KF5::CoreAddons
KF5::ConfigCore
KF5::ConfigGui
)
install
(
TARGETS angelfish-webapp
${
KF5_INSTALL_TARGETS_DEFAULT_ARGS
}
)
src/contents/webapp-ui/WebAppView.qml
0 → 100644
View file @
de240d92
/***************************************************************************
* *
* Copyright 2014-2015 Sebastian Kügler <sebas@kde.org> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program 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 General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
* *
***************************************************************************/
import
QtQuick
2.3
import
QtQuick
.
Controls
2.4
as
Controls
import
QtQuick
.
Window
2.1
import
QtQuick
.
Layouts
1.3
import
QtWebEngine
1.7
import
org
.
kde
.
kirigami
2.4
as
Kirigami
import
org
.
kde
.
mobile
.
angelfish
1.0
WebEngineView
{
id
:
webEngineView
property
string
errorCode
:
""
property
string
errorString
:
""
property
bool
privateMode
:
false
property
alias
userAgent
:
userAgent
// loadingActive property is set to true when loading is started
// and turned to false only after succesful or failed loading. It
// is possible to set it to false by calling stopLoading method.
//
// The property was introduced as it triggers visibility of the webEngineView
// in the other parts of the code. When using loading that is linked
// to visibility, stop/start loading was observed in some conditions. It looked as if
// there is an internal optimization of webengine in the case of parallel
// loading of several pages that could use visibility as one of the decision
// making parameters.
property
bool
loadingActive
:
false
property
bool
reloadOnVisible
:
true
// URL that was requested and should be used
// as a base for user interaction. It reflects
// last request (successful or failed)
property
url
requestedUrl
:
url
UserAgentGenerator
{
id
:
userAgent
onUserAgentChanged
:
webEngineView
.
reload
()
}
profile
{
offTheRecord
:
privateMode
httpUserAgent
:
userAgent
.
userAgent
onDownloadRequested
:
{
// if we don't accept the request right away, it will be deleted
download
.
accept
()
// therefore just stop the download again as quickly as possible,
// and ask the user for confirmation
download
.
pause
()
questionLoader
.
setSource
(
"
DownloadQuestion.qml
"
)
questionLoader
.
item
.
download
=
download
questionLoader
.
item
.
visible
=
true
}
onDownloadFinished
:
{
if
(
download
.
state
===
WebEngineDownloadItem
.
DownloadCompleted
)
{
showPassiveNotification
(
i18n
(
"
Download finished
"
))
}
else
if
(
download
.
state
===
WebEngineDownloadItem
.
DownloadInterrupted
)
{
showPassiveNotification
(
i18n
(
"
Download failed
"
))
console
.
log
(
"
Download interrupt reason:
"
+
download
.
interruptReason
)
}
else
if
(
download
.
state
===
WebEngineDownloadItem
.
DownloadCancelled
)
{
console
.
log
(
"
Download cancelled by the user
"
)
}
}
}
settings
{
autoLoadImages
:
webBrowser
.
settings
.
webAutoLoadImages
javascriptEnabled
:
webBrowser
.
settings
.
webJavascriptEnabled
// Disable builtin error pages in favor of our own
errorPageEnabled
:
false
// Load larger touch icons
touchIconsEnabled
:
true
// Disable scrollbars on mobile
showScrollBars
:
!
Kirigami
.
Settings
.
isMobile
}
// Custom context menu
Controls.Menu
{
property
ContextMenuRequest
request
id
:
contextMenu
Controls.MenuItem
{
enabled
:
contextMenu
.
request
!=
null
&&
(
contextMenu
.
request
.
editFlags
&
ContextMenuRequest
.
CanCopy
)
!=
0
text
:
i18n
(
"
Copy
"
)
onTriggered
:
webEngineView
.
triggerWebAction
(
WebEngineView
.
Copy
)
}
Controls.MenuItem
{
enabled
:
contextMenu
.
request
!=
null
&&
(
contextMenu
.
request
.
editFlags
&
ContextMenuRequest
.
CanCut
)
!=
0
text
:
i18n
(
"
Cut
"
)
onTriggered
:
webEngineView
.
triggerWebAction
(
WebEngineView
.
Cut
)
}
Controls.MenuItem
{
enabled
:
contextMenu
.
request
!=
null
&&
(
contextMenu
.
request
.
editFlags
&
ContextMenuRequest
.
CanPaste
)
!=
0
text
:
i18n
(
"
Paste
"
)
onTriggered
:
webEngineView
.
triggerWebAction
(
WebEngineView
.
Paste
)
}
Controls.MenuItem
{
enabled
:
contextMenu
.
request
!=
null
&&
contextMenu
.
request
.
selectedText
text
:
contextMenu
.
request
&&
contextMenu
.
request
.
selectedText
?
i18n
(
"
Search online for '%1'
"
,
contextMenu
.
request
.
selectedText
)
:
i18n
(
"
Search online
"
)
onTriggered
:
Qt
.
openUrlExternally
(
UrlUtils
.
urlFromUserInput
(
BrowserManager
.
searchBaseUrl
+
contextMenu
.
request
.
selectedText
));
}
Controls.MenuItem
{
enabled
:
contextMenu
.
request
!==
null
&&
contextMenu
.
request
.
linkUrl
!==
""
text
:
i18n
(
"
Copy Url
"
)
onTriggered
:
webEngineView
.
triggerWebAction
(
WebEngineView
.
CopyLinkToClipboard
)
}
Controls.MenuItem
{
text
:
i18n
(
"
Download
"
)
onTriggered
:
webEngineView
.
triggerWebAction
(
WebEngineView
.
DownloadLinkToDisk
)
}
}
focus
:
true
onLoadingChanged
:
{
//print("Loading: " + loading);
print
(
"
url:
"
+
loadRequest
.
url
)
//print(" icon: " + webEngineView.icon)
//print(" title: " + webEngineView.title)
/* Handle
* - WebEngineView::LoadStartedStatus,
* - WebEngineView::LoadStoppedStatus,
* - WebEngineView::LoadSucceededStatus and
* - WebEngineView::LoadFailedStatus
*/
var
ec
=
""
;
var
es
=
""
;
if
(
loadRequest
.
status
===
WebEngineView
.
LoadStartedStatus
)
{
loadingActive
=
true
;
}
if
(
loadRequest
.
status
===
WebEngineView
.
LoadSucceededStatus
)
{
if
(
!
privateMode
)
{
var
request
=
new
Object
;
// FIXME
request
.
url
=
currentWebView
.
url
;
request
.
title
=
currentWebView
.
title
;
request
.
icon
=
currentWebView
.
icon
;
BrowserManager
.
addToHistory
(
request
);
BrowserManager
.
updateLastVisited
(
currentWebView
.
url
);
}
loadingActive
=
false
;
}
if
(
loadRequest
.
status
===
WebEngineView
.
LoadFailedStatus
)
{
print
(
"
Load failed:
"
+
loadRequest
.
errorCode
+
"
"
+
loadRequest
.
errorString
);
print
(
"
Load failed url:
"
+
loadRequest
.
url
+
"
"
+
url
);
ec
=
loadRequest
.
errorCode
;
es
=
loadRequest
.
errorString
;
loadingActive
=
false
;
// update requested URL only after its clear that it fails.
// Otherwise, its updated as a part of url property update.
if
(
requestedUrl
!==
loadRequest
.
url
)
requestedUrl
=
loadRequest
.
url
;
}
errorCode
=
ec
;
errorString
=
es
;
}
Component.onCompleted
:
{
print
(
"
WebView completed.
"
);
var
settings
=
webEngineView
.
settings
;
print
(
"
Settings:
"
+
settings
);
}
onIconChanged
:
{
if
(
icon
&&
!
privateMode
)
BrowserManager
.
updateIcon
(
url
,
icon
)
}
onNewViewRequested
:
{
if
(
UrlUtils
.
urlHost
(
request
.
requestedUrl
)
===
UrlUtils
.
urlHost
(
BrowserManager
.
initialUrl
))
{
url
=
request
.
requestedUrl
;
}
else
{
Qt
.
openUrlExternally
(
request
.
requestedUrl
);
}
}
onUrlChanged
:
{
if
(
requestedUrl
!==
url
)
{
requestedUrl
=
url
;
}
}
onFullScreenRequested
:
{
request
.
accept
()
if
(
webBrowser
.
visibility
!==
Window
.
FullScreen
)
webBrowser
.
showFullScreen
()
else
webBrowser
.
showNormal
()
}
onContextMenuRequested
:
{
request
.
accepted
=
true
// Make sure QtWebEngine doesn't show its own context menu.
contextMenu
.
request
=
request
contextMenu
.
x
=
request
.
x
contextMenu
.
y
=
request
.
y
contextMenu
.
open
()
}
onAuthenticationDialogRequested
:
{
request
.
accepted
=
true
sheetLoader
.
setSource
(
"
AuthSheet.qml
"
)
sheetLoader
.
item
.
request
=
request
sheetLoader
.
item
.
open
()
}
onFeaturePermissionRequested
:
{
questionLoader
.
setSource
(
"
PermissionQuestion.qml
"
)
questionLoader
.
item
.
permission
=
feature
questionLoader
.
item
.
origin
=
securityOrigin
questionLoader
.
item
.
visible
=
true
}
onJavaScriptDialogRequested
:
{
request
.
accepted
=
true
sheetLoader
.
setSource
(
"
JavaScriptDialogSheet.qml
"
)
sheetLoader
.
item
.
request
=
request
sheetLoader
.
item
.
open
()
}
onVisibleChanged
:
{
// set user agent to the current displayed tab
// this ensures that we follow mobile preference
// of the current webview. also update the current
// snapshot image with short delay to be sure that
// all kirigami pages have moved into place
if
(
visible
)
{
profile
.
httpUserAgent
=
Qt
.
binding
(
function
()
{
return
userAgent
.
userAgent
;
});
if
(
reloadOnVisible
)
{
reloadOnVisible
=
false
;
reload
();
}
}
}
function
stopLoading
()
{
loadingActive
=
false
;
stop
();
}
}
src/contents/webapp-ui/webapp.qml
View file @
de240d92
...
...
@@ -73,7 +73,8 @@ Kirigami.ApplicationWindow {
// tabs will work correctly
property
bool
initialized
:
false
WebView
{
//FIXME: WebView assumes a multi tab ui, will probably need own implementation
WebAppView
{
id
:
webView
anchors.fill
:
parent
url
:
BrowserManager
.
initialUrl
...
...
src/urlutils.cpp
View file @
de240d92
...
...
@@ -72,3 +72,8 @@ QString UrlUtils::urlPath(const QString &url)
{
return
QUrl
::
fromUserInput
(
url
).
path
();
}
QString
UrlUtils
::
urlHost
(
const
QString
&
url
)
{
return
QUrl
::
fromUserInput
(
url
).
host
();
}
src/urlutils.h
View file @
de240d92
...
...
@@ -41,6 +41,7 @@ public:
Q_INVOKABLE
static
QString
urlScheme
(
const
QString
&
url
);
Q_INVOKABLE
static
QString
urlHostPort
(
const
QString
&
url
);
Q_INVOKABLE
static
QString
urlPath
(
const
QString
&
url
);
Q_INVOKABLE
static
QString
urlHost
(
const
QString
&
url
);
};
#endif // URLUTILS_H
src/webapp-resources.qrc
View file @
de240d92
<RCC>
<qresource prefix="/">
<file alias="webapp.qml">contents/webapp-ui/webapp.qml</file>
<file alias="WebAppView.qml">contents/webapp-ui/WebAppView.qml</file>
</qresource>
</RCC>
src/webappmain.cpp
View file @
de240d92
...
...
@@ -25,6 +25,8 @@
#include <KLocalizedContext>
#include <KLocalizedString>
#include <KDesktopFile>
#include <KAboutData>
#include "bookmarkshistorymodel.h"
#include "browsermanager.h"
...
...
@@ -45,9 +47,9 @@ Q_DECL_EXPORT int main(int argc, char *argv[])
#endif
QApplication
app
(
argc
,
argv
);
QCoreApplication
::
setOrganizationName
(
"KDE"
);
QCoreApplication
::
setOrganizationDomain
(
"mobile.kde.org"
);
QCoreApplication
::
setApplicationName
(
"angelfish"
);
//
QCoreApplication::setOrganizationName("KDE");
//
QCoreApplication::setOrganizationDomain("mobile.kde.org");
//
QCoreApplication::setApplicationName("angelfish");
#if QT_VERSION <= QT_VERSION_CHECK(5, 14, 0)
QtWebEngine
::
initialize
();
...
...
@@ -65,10 +67,27 @@ Q_DECL_EXPORT int main(int argc, char *argv[])
engine
.
addImageProvider
(
IconImageProvider
::
providerId
(),
new
IconImageProvider
(
&
engine
));
// initial url command line parameter
QString
initialUrl
;
if
(
!
parser
.
positionalArguments
().
isEmpty
())
initialUrl
=
QUrl
::
fromUserInput
(
parser
.
positionalArguments
().
first
()).
toString
();
if
(
parser
.
positionalArguments
().
isEmpty
())
{
return
0
;
}
const
QString
fileName
=
parser
.
positionalArguments
().
first
();
KDesktopFile
desktopFile
(
fileName
);
if
(
desktopFile
.
readUrl
().
isEmpty
())
{
return
0
;
}
const
QString
initialUrl
=
QUrl
::
fromUserInput
(
desktopFile
.
readUrl
()).
toString
();
const
QString
appName
=
desktopFile
.
readName
().
toLower
().
replace
(
QLatin1Char
(
' '
),
QLatin1Char
(
'-'
))
+
QLatin1String
(
"-angelfish-webapp"
);
KAboutData
aboutData
(
appName
.
toLower
(),
desktopFile
.
readName
(),
QStringLiteral
(
"0.1"
),
i18n
(
"Angelfish Web App runtime"
),
KAboutLicense
::
GPL
,
i18n
(
"Copyright 2020 Angelfish developers"
));
QApplication
::
setWindowIcon
(
QIcon
::
fromTheme
(
desktopFile
.
readIcon
()));
aboutData
.
addAuthor
(
i18n
(
"Marco Martin"
),
QString
(),
"mart@kde.org"
);
KAboutData
::
setApplicationData
(
aboutData
);
// Exported types
qmlRegisterType
<
BookmarksHistoryModel
>
(
"org.kde.mobile.angelfish"
,
1
,
0
,
"BookmarksHistoryModel"
);
...
...
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