├── src ├── ui │ ├── ui.pri │ ├── utils │ │ ├── qmldir │ │ ├── ColorUtils.qml │ │ └── UrlUtils.qml │ ├── drawer │ │ ├── DrawerContentItem.qml │ │ ├── content │ │ │ └── downloads │ │ │ │ ├── DrawerDownloadsContent.qml │ │ │ │ └── DownloadItemDelegate.qml │ │ └── Drawer.qml │ ├── tabview │ │ ├── TabBarActionBar.qml │ │ ├── TabIndicator.qml │ │ ├── TabView.qml │ │ ├── TabType.qml │ │ ├── TabActionManager.qml │ │ ├── TabContentView.qml │ │ ├── content │ │ │ ├── AboutContent.qml │ │ │ └── WebContent.qml │ │ ├── TabContent.qml │ │ ├── TabDelegate.qml │ │ ├── TabController.qml │ │ └── TabPage.qml │ ├── expansionbar │ │ ├── ExpansionBarItem.qml │ │ └── ExpansionBar.qml │ ├── qmldir │ ├── ui.qrc │ ├── overlay │ │ ├── BaseOverlay.qml │ │ └── SearchOverlay.qml │ ├── components │ │ ├── ActionBar.qml │ │ ├── ThemeSelection.qml │ │ └── SearchEngineSelection.qml │ ├── toolbar │ │ └── Toolbar.qml │ ├── Main.qml │ ├── omnibox │ │ └── Omnibox.qml │ └── window │ │ └── ShortcutManager.qml ├── main │ └── main.pri ├── 3rdparty │ ├── 3rdparty.pri │ └── regex-weburl │ │ ├── qmldir │ │ ├── README │ │ ├── regex-weburl.qrc │ │ └── regex-weburl.js ├── extensions │ ├── extensions.pri │ ├── default │ │ ├── themes │ │ │ ├── dark.json │ │ │ ├── light.json │ │ │ └── bluegrey.json │ │ ├── search │ │ │ ├── bing.json │ │ │ ├── baidu.json │ │ │ ├── google.json │ │ │ ├── yahoo.json │ │ │ ├── yandex.json │ │ │ ├── peekier.json │ │ │ └── duckduckgo.json │ │ └── meta │ │ │ └── package.json │ └── default.qrc └── core │ ├── settings │ ├── searchconfig.cpp │ ├── startconfig.cpp │ ├── themeconfig.cpp │ ├── searchconfig.h │ ├── startconfig.h │ ├── settings.h │ └── themeconfig.h │ ├── extensions │ ├── extension.cpp │ ├── extensionelement.cpp │ ├── extensionsearchengineparameter.cpp │ ├── extensiontheme.cpp │ ├── extensionsearchengine.cpp │ ├── extensionsmodel.h │ ├── extensionelement.h │ ├── extensionthemesmodel.h │ ├── extensionsearchenginesmodel.h │ ├── extensionsearchengineparameter.h │ ├── extensionsmanager.h │ ├── extensionsearchengine.h │ ├── extensionsmodel.cpp │ ├── extension.h │ ├── extensionparser.h │ ├── extensionsearchenginesmodel.cpp │ ├── extensiontheme.h │ ├── extensionthemesmodel.cpp │ └── extensionsmanager.cpp │ ├── global │ ├── version.h │ └── paths.h │ ├── utils │ ├── secondarythemetimer.cpp │ ├── themeprovider.cpp │ ├── secondarythemetimer.h │ ├── themeprovider.h │ ├── searchprovider.h │ └── searchprovider.cpp │ ├── core.pri │ └── models │ ├── downloadsmodel.h │ ├── webdownload.cpp │ ├── webdownload.h │ ├── downloadsmodel.cpp │ ├── tabsmodel.h │ ├── tab.cpp │ └── tab.h ├── res ├── icon │ ├── 512x512 │ │ └── apps │ │ │ └── io.liri.Browser.png │ └── icon.qrc └── io.liri.Browser.desktop ├── .mailmap ├── .gitignore ├── AUTHORS.md ├── liri-browser.pro ├── .travis.yml └── README.md /src/ui/ui.pri: -------------------------------------------------------------------------------- 1 | RESOURCES += $$PWD/ui.qrc 2 | -------------------------------------------------------------------------------- /src/main/main.pri: -------------------------------------------------------------------------------- 1 | SOURCES += $$PWD/main.cpp 2 | -------------------------------------------------------------------------------- /src/3rdparty/3rdparty.pri: -------------------------------------------------------------------------------- 1 | RESOURCES += $$PWD/regex-weburl/regex-weburl.qrc 2 | -------------------------------------------------------------------------------- /src/extensions/extensions.pri: -------------------------------------------------------------------------------- 1 | RESOURCES += $$PWD/default.qrc 2 | 3 | DISTFILES += 4 | -------------------------------------------------------------------------------- /src/3rdparty/regex-weburl/qmldir: -------------------------------------------------------------------------------- 1 | module 3rdparty.dperini.regexweburl 2 | 3 | RegexWebUrl 1.0 regex-weburl.js 4 | -------------------------------------------------------------------------------- /src/ui/utils/qmldir: -------------------------------------------------------------------------------- 1 | module utils 2 | singleton ColorUtils 1.0 ColorUtils.qml 3 | singleton UrlUtils 1.0 UrlUtils.qml 4 | -------------------------------------------------------------------------------- /res/icon/512x512/apps/io.liri.Browser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/probonopd/browser/patch-1/res/icon/512x512/apps/io.liri.Browser.png -------------------------------------------------------------------------------- /res/icon/icon.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | 512x512/io.liri.Browser.png 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/3rdparty/regex-weburl/README: -------------------------------------------------------------------------------- 1 | Regular Expression for URL validation 2 | Author: Diego Perini 3 | Updated: 2010/12/05 4 | License: MIT 5 | 6 | Source: https://gist.github.com/dperini/729294 7 | -------------------------------------------------------------------------------- /src/3rdparty/regex-weburl/regex-weburl.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | qmldir 4 | regex-weburl.js 5 | 6 | 7 | -------------------------------------------------------------------------------- /res/io.liri.Browser.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Name=Liri Browser 3 | Comment=Material Design Webbrowser 4 | Exec=liri-browser %U 5 | Terminal=false 6 | Type=Application 7 | Categories=Qt;Network;WebBrowser; 8 | Keywords=Web;Browser; 9 | Icon=io.liri.Browser 10 | 11 | -------------------------------------------------------------------------------- /.mailmap: -------------------------------------------------------------------------------- 1 | Tim Süberkrüb 2 | Pier Luigi Fiorini 3 | Ivan Fateev JohnPoison 4 | Ivan Fateev John Poison (Ivan Fateev) 5 | -------------------------------------------------------------------------------- /src/extensions/default/themes/dark.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema": { 3 | "type": "lbx/theme", 4 | "version": "0.1.0" 5 | }, 6 | "meta": { 7 | "name": "default.dark", 8 | "title": "Default Dark", 9 | "summary": "A dark theme", 10 | "description": "Default dark theme for Liri Browser" 11 | }, 12 | "palette": { 13 | "dark": true, 14 | "adapt_website_theme": false, 15 | "accent": "#03A9F4", 16 | "primary": "#2196F3", 17 | "foreground": "white", 18 | "background": "#212121" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/extensions/default/themes/light.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema": { 3 | "type": "lbx/theme", 4 | "version": "0.1.0" 5 | }, 6 | "meta": { 7 | "name": "default.light", 8 | "title": "Default Light", 9 | "summary": "A light theme", 10 | "description": "Default light theme for Liri Browser" 11 | }, 12 | "palette": { 13 | "dark": false, 14 | "adapt_website_theme": true, 15 | "accent": "#E91E63", 16 | "primary": "#7C4DFF", 17 | "foreground": "#212121", 18 | "background": "white" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/extensions/default/themes/bluegrey.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema": { 3 | "type": "lbx/theme", 4 | "version": "0.1.0" 5 | }, 6 | "meta": { 7 | "name": "default.bluegrey", 8 | "title": "Default Blue Grey", 9 | "summary": "A blue grey theme", 10 | "description": "Default blue grey theme for Liri Browser" 11 | }, 12 | "palette": { 13 | "dark": true, 14 | "adapt_website_theme": false, 15 | "accent": "#3F51B5", 16 | "primary": "#2196F3", 17 | "foreground": "white", 18 | "background": "#263238" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # C++ objects and libs 2 | 3 | *.slo 4 | *.lo 5 | *.o 6 | *.a 7 | *.la 8 | *.lai 9 | *.so 10 | *.dll 11 | *.dylib 12 | 13 | # Qt-es 14 | 15 | /.qmake.cache 16 | /.qmake.stash 17 | *.pro.user 18 | *.pro.user.* 19 | *.qbs.user 20 | *.qbs.user.* 21 | *.moc 22 | moc_*.cpp 23 | qrc_*.cpp 24 | ui_*.h 25 | Makefile* 26 | *build-* 27 | 28 | # QtCreator 29 | 30 | *.autosave 31 | 32 | # QtCtreator Qml 33 | *.qmlproject.user 34 | *.qmlproject.user.* 35 | 36 | # QtCtreator CMake 37 | CMakeLists.txt.user 38 | 39 | # Oxide and QtWebEngine 40 | GPUCache/ 41 | QuotaManager 42 | QuotaManager-journal 43 | TransportSecurity 44 | databases/ 45 | 46 | #GitEye 47 | /.project 48 | -------------------------------------------------------------------------------- /src/extensions/default.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | default/meta/package.json 4 | default/themes/bluegrey.json 5 | default/themes/dark.json 6 | default/themes/light.json 7 | default/search/duckduckgo.json 8 | default/search/google.json 9 | default/search/bing.json 10 | default/search/yahoo.json 11 | default/search/baidu.json 12 | default/search/peekier.json 13 | default/search/yandex.json 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/extensions/default/search/bing.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema": { 3 | "type": "lbx/search", 4 | "version": "0.1.0" 5 | }, 6 | "meta": { 7 | "name": "default.bing", 8 | "title": "Bing", 9 | "summary": "Bing search engine", 10 | "description": "Bing Web Search." 11 | }, 12 | "url": { 13 | "base": { 14 | "search": "https://bing.com/search", 15 | "homepage": "https://bing.com/" 16 | }, 17 | "params": [ 18 | { 19 | "type": "get", 20 | "name": "q", 21 | "value": "$(search.query)", 22 | "context": ["search"] 23 | } 24 | ] 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/extensions/default/search/baidu.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema": { 3 | "type": "lbx/search", 4 | "version": "0.1.0" 5 | }, 6 | "meta": { 7 | "name": "default.baidu", 8 | "title": "Baidu", 9 | "summary": "Baidu search engine", 10 | "description": "Baidu Web Search." 11 | }, 12 | "url": { 13 | "base": { 14 | "search": "https://baidu.com/s", 15 | "homepage": "https://baidu.com/" 16 | }, 17 | "params": [ 18 | { 19 | "type": "get", 20 | "name": "wd", 21 | "value": "$(search.query)", 22 | "context": ["search"] 23 | } 24 | ] 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/extensions/default/search/google.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema": { 3 | "type": "lbx/search", 4 | "version": "0.1.0" 5 | }, 6 | "meta": { 7 | "name": "default.google", 8 | "title": "Google", 9 | "summary": "Google search engine", 10 | "description": "Google Web Search." 11 | }, 12 | "url": { 13 | "base": { 14 | "search": "https://google.com/search", 15 | "homepage": "https://google.com/" 16 | }, 17 | "params": [ 18 | { 19 | "type": "get", 20 | "name": "q", 21 | "value": "$(search.query)", 22 | "context": ["search"] 23 | } 24 | ] 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/extensions/default/search/yahoo.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema": { 3 | "type": "lbx/search", 4 | "version": "0.1.0" 5 | }, 6 | "meta": { 7 | "name": "default.yahoo", 8 | "title": "Yahoo", 9 | "summary": "Yahoo search engine", 10 | "description": "Yahoo Web Search." 11 | }, 12 | "url": { 13 | "base": { 14 | "search": "https://search.yahoo.com/search", 15 | "homepage": "https://yahoo.com/" 16 | }, 17 | "params": [ 18 | { 19 | "type": "get", 20 | "name": "q", 21 | "value": "$(search.query)", 22 | "context": ["search"] 23 | } 24 | ] 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/extensions/default/search/yandex.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema": { 3 | "type": "lbx/search", 4 | "version": "0.1.0" 5 | }, 6 | "meta": { 7 | "name": "default.yandex", 8 | "title": "Yandex", 9 | "summary": "Yandex search engine", 10 | "description": "Yandex Web Search." 11 | }, 12 | "url": { 13 | "base": { 14 | "search": "https://yandex.ru/search", 15 | "homepage": "https://yandex.ru/" 16 | }, 17 | "params": [ 18 | { 19 | "type": "get", 20 | "name": "text", 21 | "value": "$(search.query)", 22 | "context": ["search"] 23 | } 24 | ] 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/extensions/default/search/peekier.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema": { 3 | "type": "lbx/search", 4 | "version": "0.1.0" 5 | }, 6 | "meta": { 7 | "name": "default.peekier", 8 | "title": "Peekier", 9 | "summary": "Peekier search engine", 10 | "description": "Peekier Web Search." 11 | }, 12 | "url": { 13 | "base": { 14 | "search": "https://peekier.com", 15 | "homepage": "https://peekier.com" 16 | }, 17 | "params": [ 18 | { 19 | "type": "hashbang", 20 | "name": "hashbang", 21 | "value": "$(search.query)", 22 | "context": ["search"] 23 | } 24 | ] 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /AUTHORS.md: -------------------------------------------------------------------------------- 1 | Liri Browser 2 | ============ 3 | 4 | # Core Developers 5 | 6 | * Tim Süberkrüb 7 | 8 | # Contributors 9 | 10 | This is the list of contributors to this code base. 11 | 12 | Names are sorted by number of commits at the time of this writing. 13 | Commit data has been generated with: 14 | 15 | ```sh 16 | git shortlog -s -e -n 17 | ``` 18 | 19 | Commit counts have been removed, since they change pretty frequently. 20 | 21 | Remember to update this file before any release is made, also make sure 22 | a .mailmap file is maintained if committer names and email addresses 23 | change over time. 24 | 25 | * Tim Süberkrüb 26 | * Ivan Fateev 27 | * Pier Luigi Fiorini 28 | 29 | -------------------------------------------------------------------------------- /src/ui/drawer/DrawerContentItem.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2016 Tim Süberkrüb (https://github.com/tim-sueberkrueb) 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | import QtQuick 2.7 21 | 22 | Item { 23 | property string title 24 | } 25 | -------------------------------------------------------------------------------- /src/ui/tabview/TabBarActionBar.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2016 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | import QtQuick 2.7 25 | import ".." 26 | 27 | ActionBar {} 28 | -------------------------------------------------------------------------------- /src/extensions/default/search/duckduckgo.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema": { 3 | "type": "lbx/search", 4 | "version": "0.1.0" 5 | }, 6 | "meta": { 7 | "name": "default.duckduckgo", 8 | "title": "DuckDuckGo", 9 | "summary": "DuckDuckGo search engine", 10 | "description": "The search engine that doesn't track you." 11 | }, 12 | "url": { 13 | "base": { 14 | "search": "https://duckduckgo.com/", 15 | "homepage": "https://duckduckgo.com/" 16 | }, 17 | "params": [ 18 | { 19 | "type": "get", 20 | "name": "q", 21 | "value": "$(search.query)", 22 | "context": ["search"] 23 | }, 24 | { 25 | "type": "get", 26 | "name": "kae", 27 | "value": "$(theme.background)", 28 | "context": ["search", "homepage"] 29 | } 30 | ] 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/ui/tabview/TabIndicator.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2016 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | import QtQuick 2.7 25 | 26 | Rectangle { 27 | implicitHeight: 2 28 | } 29 | -------------------------------------------------------------------------------- /src/ui/expansionbar/ExpansionBarItem.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2016 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | import QtQuick 2.7 25 | 26 | Item { 27 | signal closed() 28 | } 29 | -------------------------------------------------------------------------------- /src/core/settings/searchconfig.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2016 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | #include "searchconfig.h" 25 | 26 | SearchConfig::SearchConfig(QObject *parent) 27 | : QObject(parent) 28 | { 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/core/settings/startconfig.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2016 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | #include "startconfig.h" 25 | 26 | StartConfig::StartConfig(QObject *parent) 27 | : QObject(parent) 28 | { 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/core/extensions/extension.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2017 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | #include "extension.h" 25 | 26 | #include 27 | 28 | Extension::Extension(QObject *parent) 29 | : QObject(parent) 30 | { 31 | m_valid = true; 32 | } 33 | -------------------------------------------------------------------------------- /src/extensions/default/meta/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema": { 3 | "type": "lbx/meta", 4 | "version": "0.1.0" 5 | }, 6 | "meta": { 7 | "name": "default", 8 | "version": "0.1.0", 9 | "title": "Default Extension", 10 | "author": "Tim Süberkrüb", 11 | "email": "tim.sueberkrueb@web.de", 12 | "summary": "Default extension", 13 | "description": "Provides default themes and elements" 14 | }, 15 | "content": { 16 | "static": { 17 | "themes": [ 18 | "res://themes/light.json", 19 | "res://themes/dark.json", 20 | "res://themes/bluegrey.json" 21 | ], 22 | "search": [ 23 | "res://search/duckduckgo.json", 24 | "res://search/google.json", 25 | "res://search/bing.json", 26 | "res://search/yahoo.json", 27 | "res://search/baidu.json", 28 | "res://search/peekier.json", 29 | "res://search/yandex.json" 30 | ] 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/core/settings/themeconfig.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2017 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | #include "themeconfig.h" 25 | 26 | ThemeConfig::ThemeConfig(QObject *parent) 27 | : QObject(parent) 28 | { 29 | m_secondaryStartTime = QTime(21, 0); 30 | m_secondaryEndTime = QTime(7, 0); 31 | } 32 | -------------------------------------------------------------------------------- /src/core/extensions/extensionelement.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2017 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | #include "extensionelement.h" 25 | 26 | ExtensionElement::ExtensionElement(QObject *parent) 27 | : QObject(parent) 28 | { 29 | m_valid = true; 30 | } 31 | 32 | ExtensionElement *ExtensionElement::clone(QObject *parent) 33 | { 34 | ExtensionElement* element = new ExtensionElement(parent); 35 | element->setValid(valid()); 36 | element->setExtensionName(extensionName()); 37 | element->setName(name()); 38 | return element; 39 | } 40 | -------------------------------------------------------------------------------- /src/core/global/version.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2017 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | #ifndef VERSION_H 25 | #define VERSION_H 26 | 27 | #include 28 | #include 29 | 30 | namespace Version { 31 | const int major = 0; 32 | const int minor = 4; 33 | const int update = 0; 34 | const bool isRelease = false; 35 | const QString fullString = QString("v%1.%2.%3-%4").arg(major).arg(minor).arg(update).arg(isRelease ? "release" : "devel"); 36 | const QVersionNumber version = QVersionNumber(major, minor, update); 37 | } 38 | 39 | #endif // VERSION_H 40 | -------------------------------------------------------------------------------- /src/ui/qmldir: -------------------------------------------------------------------------------- 1 | module ui 2 | 3 | # components 4 | ActionBar 1.0 components/ActionBar.qml 5 | ThemeSelection 1.0 components/ThemeSelection.qml 6 | SearchEngineSelection 1.0 components/SearchEngineSelection.qml 7 | 8 | # tabview 9 | TabView 1.0 tabview/TabView.qml 10 | TabBar 1.0 tabview/TabBar.qml 11 | TabController 1.0 tabview/TabController.qml 12 | TabContentView 1.0 tabview/TabContentView.qml 13 | TabContent 1.0 tabview/TabContent.qml 14 | singleton TabType 1.0 tabview/TabType.qml 15 | 16 | # content 17 | WebContent 1.0 tabview/content/WebContent.qml 18 | SettingsContent 1.0 tabview/content/SettingsContent.qml 19 | ExtensionsContent 1.0 tabview/content/ExtensionsContent.qml 20 | AboutContent 1.0 tabview/content/AboutContent.qml 21 | 22 | # omnibox 23 | Omnibox 1.0 omnibox/Omnibox.qml 24 | 25 | # toolbar 26 | Toolbar 1.0 toolbar/Toolbar.qml 27 | 28 | # expansionbar 29 | ExpansionBar 1.0 expansionbar/ExpansionBar.qml 30 | 31 | # overlays 32 | BaseOverlay 1.0 overlay/BaseOverlay.qml 33 | SearchOverlay 1.0 overlay/SearchOverlay.qml 34 | 35 | # drawer 36 | Drawer 1.0 drawer/Drawer.qml 37 | DrawerContentItem 1.0 drawer/DrawerContentItem.qml 38 | 39 | # drawer content 40 | DrawerDownloadsContent 1.0 drawer/content/downloads/DrawerDownloadsContent.qml 41 | 42 | # window 43 | BrowserWindow 1.0 window/BrowserWindow.qml 44 | 45 | # utils 46 | singleton ColorUtils 1.0 utils/ColorUtils.qml 47 | singleton UrlUtils 1.0 utils/UrlUtils.qml 48 | -------------------------------------------------------------------------------- /src/core/global/paths.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2017 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | #ifndef PATHS_H 25 | #define PATHS_H 26 | 27 | #include 28 | #include 29 | 30 | namespace Paths { 31 | const QString ConfigLocation = QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation) + "/liri-browser/"; 32 | const QString DataLocation = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/liri-browser/"; 33 | const QString SettingsFile = ConfigLocation + "settings.json"; 34 | const QString ExtensionsLocation = DataLocation + "extensions/"; 35 | } 36 | 37 | #endif // PATHS_H 38 | -------------------------------------------------------------------------------- /src/core/extensions/extensionsearchengineparameter.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2017 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | #include "extensionsearchengineparameter.h" 25 | 26 | ExtensionSearchEngineParameter::ExtensionSearchEngineParameter(QObject *parent) 27 | : QObject(parent) 28 | { 29 | 30 | } 31 | 32 | ExtensionSearchEngineParameter *ExtensionSearchEngineParameter::clone(QObject *parent) 33 | { 34 | ExtensionSearchEngineParameter* param = new ExtensionSearchEngineParameter(parent); 35 | param->setType(m_type); 36 | param->setName(m_name); 37 | param->setValue(m_value); 38 | param->setContext(m_context); 39 | return param; 40 | } 41 | -------------------------------------------------------------------------------- /src/ui/tabview/TabView.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2016 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | import QtQuick 2.7 25 | import QtQuick.Layouts 1.1 26 | import core 1.0 27 | 28 | Item { 29 | id: tabView 30 | property TabsModel tabsModel 31 | property TabBar tabBar: tabBar 32 | 33 | ColumnLayout { 34 | anchors.fill: parent 35 | spacing: 0 36 | 37 | TabBar { 38 | id: tabBar 39 | Layout.fillWidth: true 40 | tabsModel: tabView.tabsModel 41 | } 42 | 43 | Rectangle { 44 | color: "green" 45 | Layout.fillHeight: true 46 | Layout.fillWidth: true 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/ui/utils/ColorUtils.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2016 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | pragma Singleton 25 | import QtQuick 2.4 26 | import Fluid.Core 1.0 27 | 28 | QtObject { 29 | function shadeColor(color, percent) { 30 | // from http://stackoverflow.com/questions/5560248/programmatically-lighten-or-darken-a-hex-color-or-rgb-and-blend-colors 31 | color = Utils.asColor(color).toString() 32 | var f=parseInt(color.slice(1),16),t=percent<0?0:255,p=percent<0?percent*-1:percent,R=f>>16,G=f>>8&0x00FF,B=f&0x0000FF; 33 | return "#"+(0x1000000+(Math.round((t-R)*p)+R)*0x10000+(Math.round((t-G)*p)+G)*0x100+(Math.round((t-B)*p)+B)).toString(16).slice(1); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/ui/tabview/TabType.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2017 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | pragma Singleton 25 | import QtQuick 2.7 26 | import "../utils" 27 | 28 | QtObject { 29 | property int unknown: -1 30 | property int webview: 0 31 | property int settings: 1 32 | property int extensions: 2 33 | property int about: 3 34 | 35 | function fromUrl(url) { 36 | if (UrlUtils.isLiriUrl(url)) { 37 | if (url == "liri://settings") 38 | return settings; 39 | else if (url == "liri://extensions") 40 | return extensions; 41 | else if (url == "liri://about") 42 | return about; 43 | } else { 44 | return webview; 45 | } 46 | return unknown; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/core/extensions/extensiontheme.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2017 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | #include "extensiontheme.h" 25 | 26 | ExtensionTheme::ExtensionTheme(QObject *parent) 27 | : ExtensionElement(parent) 28 | { 29 | 30 | } 31 | 32 | ExtensionTheme *ExtensionTheme::clone(QObject *parent) 33 | { 34 | ExtensionTheme* newTheme = new ExtensionTheme(parent); 35 | newTheme->setValid(valid()); 36 | newTheme->setExtensionName(extensionName()); 37 | newTheme->setName(name()); 38 | newTheme->setTitle(title()); 39 | newTheme->setSummary(summary()); 40 | newTheme->setDescription(description()); 41 | newTheme->setDark(dark()); 42 | newTheme->setAdaptWebsiteTheme(adaptWebsiteTheme()); 43 | newTheme->setAccent(accent()); 44 | newTheme->setPrimary(primary()); 45 | newTheme->setForeground(foreground()); 46 | newTheme->setBackground(background()); 47 | return newTheme; 48 | } 49 | -------------------------------------------------------------------------------- /src/core/utils/secondarythemetimer.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2017 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | #include "secondarythemetimer.h" 25 | 26 | SecondaryThemeTimer::SecondaryThemeTimer(QObject *parent) 27 | : QObject(parent) 28 | { 29 | m_timer = new QTimer(this); 30 | m_timer->setInterval(60000); 31 | connect(m_timer, &QTimer::timeout, this, &SecondaryThemeTimer::update); 32 | } 33 | 34 | void SecondaryThemeTimer::start() 35 | { 36 | m_timer->start(); 37 | } 38 | 39 | void SecondaryThemeTimer::stop() 40 | { 41 | m_timer->stop(); 42 | } 43 | 44 | void SecondaryThemeTimer::update() 45 | { 46 | bool isActive = false; 47 | QTime now = QTime::currentTime(); 48 | if (m_endTime > m_startTime) { 49 | isActive = (now > m_startTime && now < m_endTime); 50 | } 51 | else { 52 | isActive = (now > m_startTime || now < m_endTime ); 53 | } 54 | isActiveTimeChanged(m_isActiveTime = isActive); 55 | } 56 | -------------------------------------------------------------------------------- /liri-browser.pro: -------------------------------------------------------------------------------- 1 | load(liri_deployment) 2 | 3 | TEMPLATE = app 4 | TARGET = liri-browser 5 | 6 | CONFIG += c++11 7 | QT += qml quick quickcontrols2 widgets 8 | 9 | unix:!android { 10 | target.path = $$LIRI_INSTALL_BINDIR 11 | 12 | icon.path = $$LIRI_INSTALL_PREFIX/share/icons/hicolor 13 | icon.files += res/icon/512x512 14 | 15 | desktop.path = $$LIRI_INSTALL_PREFIX/share/applications 16 | desktop.files += res/io.liri.Browser.desktop 17 | 18 | # Deprecation warning for PREFIX 19 | prefix = $$(PREFIX) 20 | !isEmpty(prefix) { 21 | warning("Using the PREFIX environment variable to specify the installation prefix is deprecated.") 22 | warning("Use qmake LIRI_INSTALL_PREFIX= instead.") 23 | target.path = $${prefix}/bin 24 | } 25 | 26 | INSTALLS += target icon desktop 27 | } 28 | 29 | # Load QuaZIP library 30 | linux:LIBS += -L/usr/local/lib -lquazip 31 | 32 | # Show useful files in QtCreator 33 | OTHER_FILES += README.md \ 34 | LICENSE* 35 | 36 | # Specify CONFIG+=QTWEBENGINE_ENABLED when running qmake. 37 | # Otherwise, Liri Browser expects the Oxide web engine. 38 | contains(CONFIG, QTWEBENGINE_ENABLED) { 39 | message("Found QTWEBENGINE_ENABLED in CONFIG") 40 | QT += webengine 41 | DEFINES += IS_QTWEBENGINE_ENABLED 42 | message("Using QtWebEngine") 43 | } 44 | 45 | # Enable High DPI scaling if Qt >= 5.6 46 | greaterThan(QT_MAJOR_VERSION, 4) { 47 | greaterThan(QT_MINOR_VERSION, 5) { 48 | DEFINES += ENABLE_HIGH_DPI_SCALING 49 | message("Using high-dpi scaling") 50 | } 51 | } 52 | 53 | # Include sub project include files 54 | include(src/3rdparty/3rdparty.pri) 55 | include(src/core/core.pri) 56 | include(src/main/main.pri) 57 | include(src/ui/ui.pri) 58 | include(src/extensions/extensions.pri) 59 | -------------------------------------------------------------------------------- /src/ui/tabview/TabActionManager.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2016 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | import QtQuick 2.7 25 | import SlimeEngine 0.2 26 | 27 | QtObject { 28 | property QtObject internal: QtObject { 29 | property var uid 30 | property var tabController 31 | } 32 | 33 | signal newWebViewRequested(var request) 34 | signal closeRequested() 35 | 36 | onNewWebViewRequested: { 37 | switch (request.destination) { 38 | case NewViewRequest.NewViewInTab: 39 | case NewViewRequest.NewViewInBackgroundTab: 40 | internal.tabController.openNewViewRequest(request); 41 | break; 42 | case NewViewRequest.NewViewInDialog: 43 | case NewViewRequest.NewViewInWindow: 44 | internal.tabController.newWindowRequested(request); 45 | break; 46 | } 47 | } 48 | 49 | onCloseRequested: { 50 | tabController.removeTab(internal.uid); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/core/extensions/extensionsearchengine.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2017 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | #include "extensionsearchengine.h" 25 | 26 | ExtensionSearchEngine::ExtensionSearchEngine(QObject *parent) 27 | : ExtensionElement(parent) 28 | { 29 | m_parameters = new QList(); 30 | } 31 | 32 | ExtensionSearchEngine *ExtensionSearchEngine::clone(QObject *parent) 33 | { 34 | ExtensionSearchEngine* searchEngine = new ExtensionSearchEngine(parent); 35 | searchEngine->setName(m_name); 36 | searchEngine->setExtensionName(m_extensionName); 37 | searchEngine->setTitle(m_title); 38 | searchEngine->setSummary(m_summary); 39 | searchEngine->setDescription(m_description); 40 | searchEngine->setUrlBaseSearch(m_urlBaseSearch); 41 | searchEngine->setUrlBaseHomepage(m_urlBaseHomepage); 42 | for (int i=0; ilength(); i++) { 43 | searchEngine->parameters()->append(m_parameters->at(i)->clone()); 44 | } 45 | return searchEngine; 46 | } 47 | -------------------------------------------------------------------------------- /src/ui/ui.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | tabview/TabBar.qml 4 | tabview/TabView.qml 5 | tabview/TabDelegate.qml 6 | tabview/TabIndicator.qml 7 | qmldir 8 | utils/ColorUtils.qml 9 | tabview/TabBarActionBar.qml 10 | tabview/TabController.qml 11 | tabview/TabContentView.qml 12 | omnibox/Omnibox.qml 13 | toolbar/Toolbar.qml 14 | utils/UrlUtils.qml 15 | window/BrowserWindow.qml 16 | tabview/TabActionManager.qml 17 | drawer/Drawer.qml 18 | components/ActionBar.qml 19 | Main.qml 20 | drawer/DrawerContentItem.qml 21 | drawer/content/downloads/DownloadItemDelegate.qml 22 | drawer/content/downloads/DrawerDownloadsContent.qml 23 | expansionbar/ExpansionBar.qml 24 | expansionbar/ExpansionBarItem.qml 25 | overlay/SearchOverlay.qml 26 | overlay/BaseOverlay.qml 27 | tabview/TabPage.qml 28 | tabview/TabType.qml 29 | tabview/TabContent.qml 30 | tabview/content/WebContent.qml 31 | tabview/content/SettingsContent.qml 32 | utils/qmldir 33 | window/ShortcutManager.qml 34 | tabview/content/ExtensionsContent.qml 35 | tabview/content/AboutContent.qml 36 | components/ThemeSelection.qml 37 | components/SearchEngineSelection.qml 38 | 39 | 40 | -------------------------------------------------------------------------------- /src/core/core.pri: -------------------------------------------------------------------------------- 1 | HEADERS += \ 2 | $$PWD/models/tabsmodel.h \ 3 | $$PWD/models/tab.h \ 4 | $$PWD/models/downloadsmodel.h \ 5 | $$PWD/models/webdownload.h \ 6 | $$PWD/settings/settings.h \ 7 | $$PWD/settings/startconfig.h \ 8 | $$PWD/settings/searchconfig.h \ 9 | $$PWD/settings/themeconfig.h \ 10 | $$PWD/global/paths.h \ 11 | $$PWD/extensions/extensionsmanager.h \ 12 | $$PWD/extensions/extension.h \ 13 | $$PWD/extensions/extensiontheme.h \ 14 | $$PWD/extensions/extensionsmodel.h \ 15 | $$PWD/extensions/extensionthemesmodel.h \ 16 | $$PWD/global/version.h \ 17 | $$PWD/utils/secondarythemetimer.h \ 18 | $$PWD/utils/themeprovider.h \ 19 | $$PWD/extensions/extensionparser.h \ 20 | $$PWD/extensions/extensionsearchengine.h \ 21 | $$PWD/extensions/extensionsearchengineparameter.h \ 22 | $$PWD/extensions/extensionsearchenginesmodel.h \ 23 | $$PWD/extensions/extensionelement.h \ 24 | $$PWD/utils/searchprovider.h 25 | 26 | SOURCES += \ 27 | $$PWD/models/tabsmodel.cpp \ 28 | $$PWD/models/tab.cpp \ 29 | $$PWD/models/downloadsmodel.cpp \ 30 | $$PWD/models/webdownload.cpp \ 31 | $$PWD/settings/settings.cpp \ 32 | $$PWD/settings/startconfig.cpp \ 33 | $$PWD/settings/searchconfig.cpp \ 34 | $$PWD/settings/themeconfig.cpp \ 35 | $$PWD/extensions/extensionsmanager.cpp \ 36 | $$PWD/extensions/extension.cpp \ 37 | $$PWD/extensions/extensiontheme.cpp \ 38 | $$PWD/extensions/extensionsmodel.cpp \ 39 | $$PWD/extensions/extensionthemesmodel.cpp \ 40 | $$PWD/utils/secondarythemetimer.cpp \ 41 | $$PWD/utils/themeprovider.cpp \ 42 | $$PWD/extensions/extensionparser.cpp \ 43 | $$PWD/extensions/extensionsearchengine.cpp \ 44 | $$PWD/extensions/extensionsearchengineparameter.cpp \ 45 | $$PWD/extensions/extensionsearchenginesmodel.cpp \ 46 | $$PWD/extensions/extensionelement.cpp \ 47 | $$PWD/utils/searchprovider.cpp 48 | -------------------------------------------------------------------------------- /src/core/utils/themeprovider.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2017 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | #include "themeprovider.h" 25 | 26 | #include 27 | 28 | ThemeProvider::ThemeProvider(QObject *parent) 29 | : QObject(parent) 30 | { 31 | m_defaultName = "default.light"; 32 | connect(this, &ThemeProvider::nameChanged, 33 | this, &ThemeProvider::update); 34 | } 35 | 36 | void ThemeProvider::setModel(ExtensionThemesModel *model) 37 | { 38 | modelChanged(m_model = model); 39 | connect(m_model, &ExtensionThemesModel::countChanged, 40 | this, &ThemeProvider::update); 41 | } 42 | 43 | void ThemeProvider::update() 44 | { 45 | // Get theme by name 46 | ExtensionTheme* theme = m_model->get(m_name); 47 | // Fallback to default theme if theme couldn't be found 48 | if (!theme->valid()) { 49 | qWarning() << "Theme" << m_name << "was requested but could not be found."; 50 | qWarning() << "Falling back to default theme" << m_defaultName << "..."; 51 | theme = m_model->get(m_defaultName); 52 | } 53 | currentChanged(m_current = theme); 54 | } 55 | -------------------------------------------------------------------------------- /src/ui/drawer/content/downloads/DrawerDownloadsContent.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2016 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | import QtQuick 2.7 25 | import QtQuick.Layouts 1.1 26 | import QtQuick.Controls 2.0 27 | import Fluid.Controls 1.0 28 | import core 1.0 29 | import "../../.." 30 | 31 | DrawerContentItem { 32 | id: drawerContentItem 33 | title: "Downloads" 34 | 35 | property DownloadsModel downloadsModel 36 | 37 | ListView { 38 | anchors.fill: parent 39 | clip: true 40 | model: downloadsModel 41 | delegate: DownloadItemDelegate { 42 | downloadsModel: drawerContentItem.downloadsModel 43 | } 44 | } 45 | 46 | Label { 47 | id: lblNoDownloads 48 | anchors.top: parent.top 49 | 50 | visible: downloadsModel.count === 0 51 | text: "No downloads for this session" 52 | wrapMode: Text.WordWrap 53 | width: Math.min(noDownloadsMetrics.width, parent.width) 54 | 55 | TextMetrics { 56 | id: noDownloadsMetrics 57 | font: lblNoDownloads.font 58 | text: lblNoDownloads.text 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/core/models/downloadsmodel.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2016 Tim Süberkrüb (https://github.com/tim-sueberkrueb) 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #ifndef DOWNLOADSMODEL_H 21 | #define DOWNLOADSMODEL_H 22 | 23 | #include 24 | #include "webdownload.h" 25 | 26 | class DownloadsModel : public QAbstractListModel 27 | { 28 | Q_OBJECT 29 | Q_PROPERTY(int count READ count NOTIFY countChanged) 30 | public: 31 | explicit DownloadsModel(QObject* parent = nullptr); 32 | 33 | enum DownloadRoles { 34 | Path, 35 | MimeType, 36 | Progress, 37 | Invalid 38 | }; 39 | 40 | int rowCount(const QModelIndex &parent=QModelIndex()) const; 41 | QHash roleNames(); 42 | Q_INVOKABLE QVariant data(const QModelIndex &index, int role) const; 43 | 44 | Q_INVOKABLE int count() const; 45 | Q_INVOKABLE WebDownload* add(); 46 | Q_INVOKABLE WebDownload* get(const int index) const; 47 | Q_INVOKABLE bool remove(WebDownload* download); 48 | Q_INVOKABLE bool remove(const int index); 49 | 50 | private: 51 | WebDownload* m_invalid_download; 52 | QList m_downloads_list; 53 | 54 | signals: 55 | void countChanged(int count); 56 | }; 57 | 58 | #endif // DOWNLOADSMODEL_H 59 | -------------------------------------------------------------------------------- /src/core/models/webdownload.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2017 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | #include "webdownload.h" 25 | 26 | WebDownload::WebDownload(QObject *parent) 27 | : QObject(parent) 28 | { 29 | m_finished = false; 30 | } 31 | 32 | void WebDownload::setPath(QString path) 33 | { 34 | pathChanged(m_path = path); 35 | } 36 | 37 | QString WebDownload::path() const 38 | { 39 | return m_path; 40 | } 41 | 42 | void WebDownload::setMimeType(QString mimeType) 43 | { 44 | mimeTypeChanged(m_mimeType = mimeType); 45 | } 46 | 47 | QString WebDownload::mimeType() const 48 | { 49 | return m_mimeType; 50 | } 51 | 52 | void WebDownload::setProgress(int progress) 53 | { 54 | progressChanged(m_progress = progress); 55 | } 56 | 57 | int WebDownload::progress() const 58 | { 59 | return m_progress; 60 | } 61 | 62 | void WebDownload::setFinished(bool finished) 63 | { 64 | finishedChanged(m_finished = finished); 65 | } 66 | 67 | bool WebDownload::finished() const 68 | { 69 | return m_finished; 70 | } 71 | 72 | void WebDownload::setInvalid(bool invalid) 73 | { 74 | invalidChanged(m_invalid = invalid); 75 | } 76 | 77 | bool WebDownload::invalid() const 78 | { 79 | return m_invalid; 80 | } 81 | -------------------------------------------------------------------------------- /src/ui/drawer/Drawer.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2016 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | import QtQuick 2.7 25 | import QtQuick.Layouts 1.1 26 | import QtQuick.Controls 2.0 27 | import Fluid.Controls 1.0 28 | 29 | Drawer { 30 | property list contentComponents 31 | property int currentContentIndex: -1 32 | 33 | function loadContent(index) { 34 | currentContentIndex = index; 35 | } 36 | 37 | width: 256 38 | // Disabled dragMargin because Drawer shows different content based 39 | // on which menu item is selected. 40 | // The drag-in gesture also conflicts with the browser webview 41 | // scrollbar on some platforms 42 | dragMargin: 0 43 | 44 | ColumnLayout { 45 | anchors { 46 | fill: parent 47 | margins: 2 * Units.smallSpacing 48 | } 49 | 50 | spacing: 2 * Units.smallSpacing 51 | 52 | TitleLabel { 53 | text: contentLoader.item ? contentLoader.item.title : "" 54 | } 55 | 56 | Loader { 57 | id: contentLoader 58 | Layout.fillHeight: true 59 | Layout.fillWidth: true 60 | sourceComponent: currentContentIndex >= 0 ? contentComponents[currentContentIndex] : null 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/core/settings/searchconfig.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2016 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | #ifndef SEARCHCONFIG_H 25 | #define SEARCHCONFIG_H 26 | 27 | #include 28 | #include 29 | 30 | class SearchConfig : public QObject 31 | { 32 | Q_OBJECT 33 | Q_PROPERTY(QString searchEngine READ searchEngine WRITE setSearchEngine NOTIFY searchEngineChanged) 34 | Q_PROPERTY(QUrl customSearchUrl READ customSearchUrl WRITE setCustomSearchUrl NOTIFY customSearchUrlChanged) 35 | Q_ENUMS(SearchEngine) 36 | public: 37 | explicit SearchConfig(QObject *parent = nullptr); 38 | 39 | QString searchEngine() const { return m_searchEngine; } 40 | void setSearchEngine(QString searchEngine) { searchEngineChanged(m_searchEngine = searchEngine); } 41 | 42 | QUrl customSearchUrl() const { return m_customSearchUrl; } 43 | void setCustomSearchUrl(QUrl customSearchUrl) { customSearchUrlChanged(m_customSearchUrl = customSearchUrl); } 44 | 45 | signals: 46 | void searchEngineChanged(QString searchEngine); 47 | void searchUrlChanged(QUrl searchUrl); 48 | void customSearchUrlChanged(QUrl customSearchUrl); 49 | 50 | private: 51 | QString m_searchEngine; 52 | QUrl m_searchUrl; 53 | QUrl m_customSearchUrl; 54 | }; 55 | 56 | #endif // SEARCHCONFIG_H 57 | -------------------------------------------------------------------------------- /src/core/extensions/extensionsmodel.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2017 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | #ifndef EXTENSIONSMODEL_H 25 | #define EXTENSIONSMODEL_H 26 | 27 | #include 28 | 29 | #include "extension.h" 30 | 31 | class ExtensionsModel : public QAbstractListModel 32 | { 33 | Q_OBJECT 34 | Q_PROPERTY(int count READ count NOTIFY countChanged) 35 | public: 36 | explicit ExtensionsModel(QObject *parent = nullptr); 37 | 38 | enum Roles { 39 | Name = Qt::UserRole + 1, 40 | Title, 41 | Description, 42 | Summary, 43 | Author, 44 | Email 45 | }; 46 | 47 | int rowCount(const QModelIndex &parent=QModelIndex()) const; 48 | QHash roleNames() const; 49 | QVariant data(const QModelIndex &index, int role) const; 50 | 51 | Q_INVOKABLE int count() const; 52 | void add(Extension* extension); 53 | void remove(const int index); 54 | void remove(Extension* extension); 55 | Q_INVOKABLE Extension *get(const int index) const; 56 | Q_INVOKABLE Extension *get(const QString name) const; 57 | bool hasName(const QString name) const; 58 | 59 | signals: 60 | void countChanged(int count); 61 | 62 | private: 63 | QList m_extensions; 64 | Extension* m_invalidExtension; 65 | }; 66 | 67 | #endif // EXTENSIONSMODEL_H 68 | -------------------------------------------------------------------------------- /src/ui/overlay/BaseOverlay.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2016 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | import QtQuick 2.7 25 | import QtQuick.Controls.Material 2.0 26 | import Fluid.Controls 1.0 27 | import Fluid.Material 1.0 28 | 29 | Rectangle { 30 | id: baseOverlay 31 | 32 | property bool showing: false 33 | 34 | signal opened() 35 | signal closed() 36 | 37 | function open() { 38 | showing = true; 39 | openAnimation.start(); 40 | } 41 | 42 | function close() { 43 | showing = false; 44 | closeAnimation.start(); 45 | } 46 | 47 | visible: height > 0 48 | 49 | layer.enabled: true 50 | layer.effect: ElevationEffect { elevation: 2 } 51 | 52 | implicitWidth: 300 53 | height: 0 54 | 55 | color: Material.background 56 | 57 | NumberAnimation { 58 | id: openAnimation 59 | target: baseOverlay 60 | property: "height" 61 | from: 0 62 | to: 48 63 | duration: Units.mediumDuration 64 | easing.type: Easing.InOutQuad 65 | onStopped: opened() 66 | } 67 | 68 | NumberAnimation { 69 | id: closeAnimation 70 | target: baseOverlay 71 | property: "height" 72 | from: 48 73 | to: 0 74 | duration: Units.mediumDuration 75 | easing.type: Easing.InOutQuad 76 | onStopped: closed() 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/core/extensions/extensionelement.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2017 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | #ifndef EXTENSIONELEMENT_H 25 | #define EXTENSIONELEMENT_H 26 | 27 | #include 28 | 29 | class ExtensionElement : public QObject 30 | { 31 | Q_OBJECT 32 | Q_PROPERTY(bool valid READ valid WRITE setValid NOTIFY validChanged) 33 | Q_PROPERTY(QString extensionName READ extensionName WRITE setExtensionName NOTIFY extensionNameChanged) 34 | Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) 35 | public: 36 | explicit ExtensionElement(QObject *parent = nullptr); 37 | 38 | virtual ExtensionElement* clone(QObject *parent = nullptr); 39 | 40 | bool valid() const { return m_valid; } 41 | void setValid(bool valid) { validChanged(m_valid = valid); } 42 | 43 | QString extensionName() const { return m_extensionName; } 44 | void setExtensionName(QString extensionName) { extensionNameChanged(m_extensionName = extensionName); } 45 | 46 | QString name() const { return m_name; } 47 | void setName(QString name) { nameChanged(m_name = name); } 48 | 49 | signals: 50 | void validChanged(bool valid); 51 | void extensionNameChanged(QString extensionName); 52 | void nameChanged(QString name); 53 | 54 | protected: 55 | bool m_valid; 56 | QString m_extensionName; 57 | QString m_name; 58 | }; 59 | 60 | #endif // EXTENSIONELEMENT_H 61 | -------------------------------------------------------------------------------- /src/core/utils/secondarythemetimer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2017 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | #ifndef SECONDARYTHEMETIMER_H 25 | #define SECONDARYTHEMETIMER_H 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | class SecondaryThemeTimer : public QObject 32 | { 33 | Q_OBJECT 34 | Q_PROPERTY(QTime startTime READ startTime WRITE setStartTime NOTIFY startTimeChanged) 35 | Q_PROPERTY(QTime endTime READ endTime WRITE setEndTime NOTIFY endTimeChanged) 36 | Q_PROPERTY(bool isActiveTime MEMBER m_isActiveTime NOTIFY isActiveTimeChanged) 37 | public: 38 | explicit SecondaryThemeTimer(QObject *parent = nullptr); 39 | 40 | QTime startTime() const { return m_startTime; } 41 | void setStartTime(QTime startTime) { startTimeChanged(m_startTime = startTime); } 42 | 43 | QTime endTime() const { return m_endTime; } 44 | void setEndTime(QTime endTime) { endTimeChanged(m_endTime = endTime); } 45 | 46 | Q_INVOKABLE void start(); 47 | Q_INVOKABLE void stop(); 48 | 49 | signals: 50 | void startTimeChanged(QTime startTime); 51 | void endTimeChanged(QTime endTime); 52 | void isActiveTimeChanged(bool isActiveTime); 53 | 54 | private: 55 | QTime m_startTime; 56 | QTime m_endTime; 57 | QTimer* m_timer; 58 | bool m_isActiveTime; 59 | 60 | public slots: 61 | Q_INVOKABLE void update(); 62 | 63 | }; 64 | 65 | #endif // SECONDARYTHEMETIMER_H 66 | -------------------------------------------------------------------------------- /src/core/utils/themeprovider.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2017 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | #ifndef THEMEPROVIDER_H 25 | #define THEMEPROVIDER_H 26 | 27 | #include 28 | 29 | #include "../extensions/extensionthemesmodel.h" 30 | #include "../extensions/extensiontheme.h" 31 | 32 | class ThemeProvider : public QObject 33 | { 34 | Q_OBJECT 35 | Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) 36 | Q_PROPERTY(ExtensionTheme* current READ current NOTIFY currentChanged) 37 | public: 38 | explicit ThemeProvider(QObject *parent = 0); 39 | 40 | QString name() const { return m_name; } 41 | void setName(QString name) { nameChanged(m_name = name); } 42 | 43 | QString defaultName() const { return m_defaultName; } 44 | void setDefaultName(QString defaultName) { m_defaultName = defaultName; } 45 | 46 | ExtensionThemesModel* model() { return m_model; } 47 | void setModel(ExtensionThemesModel* model); 48 | 49 | ExtensionTheme* current() { return m_current; } 50 | 51 | signals: 52 | void nameChanged(QString name); 53 | void modelChanged(ExtensionThemesModel* model); 54 | void currentChanged(ExtensionTheme* current); 55 | 56 | private: 57 | QString m_name; 58 | QString m_defaultName; 59 | ExtensionThemesModel* m_model; 60 | ExtensionTheme* m_current; 61 | 62 | private slots: 63 | void update(); 64 | 65 | }; 66 | 67 | #endif // THEMEPROVIDER_H 68 | -------------------------------------------------------------------------------- /src/core/settings/startconfig.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2016 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | #ifndef STARTCONFIG_H 25 | #define STARTCONFIG_H 26 | 27 | #include 28 | #include 29 | 30 | class StartConfig : public QObject 31 | { 32 | Q_OBJECT 33 | Q_PROPERTY(QString searchEngine READ searchEngine WRITE setSearchEngine NOTIFY searchEngineChanged) 34 | Q_PROPERTY(QUrl customUrl READ customUrl WRITE setCustomUrl NOTIFY customUrlChanged) 35 | Q_PROPERTY(bool customEnabled READ customEnabled WRITE setCustomEnabled NOTIFY customEnabledChanged) 36 | public: 37 | explicit StartConfig(QObject *parent = nullptr); 38 | 39 | QString searchEngine() const { return m_searchEngine; } 40 | void setSearchEngine(QString searchEngine) { searchEngineChanged(m_searchEngine = searchEngine); } 41 | 42 | QUrl customUrl() const { return m_customUrl; } 43 | void setCustomUrl(QUrl customUrl) { customUrlChanged(m_customUrl = customUrl); } 44 | 45 | bool customEnabled() const { return m_customEnabled; } 46 | void setCustomEnabled(bool customEnabled) { customEnabledChanged(m_customEnabled = customEnabled); } 47 | 48 | signals: 49 | void searchEngineChanged(QString searchEngine); 50 | void customUrlChanged(QUrl customUrl); 51 | void customEnabledChanged(bool customEnabled); 52 | 53 | private: 54 | QString m_searchEngine; 55 | QUrl m_customUrl; 56 | bool m_customEnabled; 57 | 58 | }; 59 | 60 | #endif // STARTCONFIG_H 61 | -------------------------------------------------------------------------------- /src/core/settings/settings.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2016 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | #ifndef SETTINGS_H 25 | #define SETTINGS_H 26 | 27 | #include 28 | #include 29 | 30 | #include "../global/paths.h" 31 | 32 | #include "startconfig.h" 33 | #include "searchconfig.h" 34 | #include "themeconfig.h" 35 | 36 | class Settings : public QObject 37 | { 38 | Q_OBJECT 39 | Q_PROPERTY(StartConfig* startConfig MEMBER m_startConfig NOTIFY startConfigChanged) 40 | Q_PROPERTY(SearchConfig* searchConfig MEMBER m_searchConfig NOTIFY searchConfigChanged) 41 | Q_PROPERTY(ThemeConfig* themeConfig MEMBER m_themeConfig NOTIFY themeConfigChanged) 42 | Q_PROPERTY(bool dirty READ dirty WRITE setDirty NOTIFY dirtyChanged) 43 | public: 44 | explicit Settings(QObject *parent = nullptr); 45 | 46 | bool dirty() const { return m_dirty; } 47 | void setDirty(bool dirty) { dirtyChanged(m_dirty = dirty); } 48 | 49 | Q_INVOKABLE void load(); 50 | Q_INVOKABLE void save(); 51 | 52 | QByteArray defaultJSON(); 53 | QByteArray json(); 54 | 55 | private: 56 | StartConfig* m_startConfig; 57 | SearchConfig* m_searchConfig; 58 | ThemeConfig* m_themeConfig; 59 | bool m_dirty; 60 | 61 | signals: 62 | void startConfigChanged(StartConfig* startConfig); 63 | void searchConfigChanged(SearchConfig* searchConfig); 64 | void themeConfigChanged(ThemeConfig* themeConfig); 65 | void dirtyChanged(bool dirty); 66 | }; 67 | 68 | #endif // SETTINGS_H 69 | -------------------------------------------------------------------------------- /src/ui/utils/UrlUtils.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2016 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | pragma Singleton 25 | import QtQuick 2.7 26 | import dperini.regexweburl 1.0 27 | 28 | QtObject { 29 | property var webUrlRegex: RegexWebUrl.re_weburl 30 | 31 | function isChromeUrl(url) { 32 | return url.indexOf("chrome://") == 0; 33 | } 34 | 35 | function isViewSourceUrl(url) { 36 | return url.indexOf("view-source:") == 0; 37 | } 38 | 39 | function isWebUrl(url) { 40 | return url.match(webUrlRegex) !== null; 41 | } 42 | 43 | function isLiriUrl(url) { 44 | return url.toString().indexOf("liri://") === 0; 45 | } 46 | 47 | function validUrl(url, searchEngine, currentTheme) { 48 | // Valid web url 49 | var isHttped = (url.indexOf("http://") === 0 || url.indexOf("https://") === 0); 50 | var httpedUrl = isHttped ? url : "http://%1".arg(url); 51 | if (isHttped || isWebUrl(httpedUrl)) { 52 | return httpedUrl; 53 | } 54 | // Liri url 55 | else if (isLiriUrl(url)) { 56 | return url; 57 | } 58 | // Chrome url 59 | else if (isChromeUrl(url)) { 60 | return url; 61 | } 62 | // View source url 63 | else if (isViewSourceUrl(url)) { 64 | return url; 65 | } 66 | // Search term 67 | else { 68 | return Search.searchUrl(url, searchEngine, currentTheme); 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/core/extensions/extensionthemesmodel.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2017 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | #ifndef EXTENSIONTHEMESMODEL_H 25 | #define EXTENSIONTHEMESMODEL_H 26 | 27 | #include 28 | 29 | #include "extensiontheme.h" 30 | 31 | class ExtensionThemesModel : public QAbstractListModel 32 | { 33 | Q_OBJECT 34 | Q_PROPERTY(int count READ count NOTIFY countChanged) 35 | public: 36 | explicit ExtensionThemesModel(QObject *parent = nullptr); 37 | 38 | enum Roles { 39 | Name = Qt::UserRole + 1, 40 | ExtensionName, 41 | Title, 42 | Summary, 43 | Description, 44 | Dark, 45 | Accent, 46 | Primary, 47 | Foreground, 48 | Background 49 | }; 50 | 51 | int rowCount(const QModelIndex &parent=QModelIndex()) const; 52 | QHash roleNames() const; 53 | QVariant data(const QModelIndex &index, int role) const; 54 | 55 | Q_INVOKABLE int count() const; 56 | void add(ExtensionTheme* theme); 57 | void remove(const int index); 58 | void remove(ExtensionTheme* theme); 59 | void removeByExtensionName(const QString extensionName); 60 | Q_INVOKABLE ExtensionTheme* get(const int index) const; 61 | Q_INVOKABLE ExtensionTheme* get(const QString name) const; 62 | 63 | signals: 64 | void countChanged(int count); 65 | 66 | private: 67 | QList m_themes; 68 | ExtensionTheme* m_invalidTheme; 69 | }; 70 | 71 | #endif // EXTENSIONTHEMESMODEL_H 72 | -------------------------------------------------------------------------------- /src/core/extensions/extensionsearchenginesmodel.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2017 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | #ifndef EXTENSIONSEARCHENGINESMODEL_H 25 | #define EXTENSIONSEARCHENGINESMODEL_H 26 | 27 | #include 28 | 29 | #include "extensionsearchengine.h" 30 | 31 | class ExtensionSearchEnginesModel : public QAbstractListModel 32 | { 33 | Q_OBJECT 34 | Q_PROPERTY(int count READ count NOTIFY countChanged) 35 | public: 36 | explicit ExtensionSearchEnginesModel(QObject *parent = nullptr); 37 | 38 | enum Roles { 39 | ExtensionName = Qt::UserRole + 1, 40 | Name, 41 | Title, 42 | Summary, 43 | Description 44 | }; 45 | 46 | int rowCount(const QModelIndex &parent=QModelIndex()) const; 47 | QHash roleNames() const; 48 | QVariant data(const QModelIndex &index, int role) const; 49 | 50 | Q_INVOKABLE int count() const; 51 | void add(ExtensionSearchEngine* searchEngine); 52 | void remove(const int row); 53 | void remove(ExtensionSearchEngine* searchEngine); 54 | void removeByExtensionName(const QString extensionName); 55 | Q_INVOKABLE ExtensionSearchEngine *get(const int row) const; 56 | Q_INVOKABLE ExtensionSearchEngine *get(const QString name) const; 57 | 58 | signals: 59 | void countChanged(int count); 60 | 61 | private: 62 | QList m_searchEngines; 63 | ExtensionSearchEngine* m_invalidSearchEngine; 64 | }; 65 | 66 | #endif // EXTENSIONSEARCHENGINESMODEL_H 67 | -------------------------------------------------------------------------------- /src/core/utils/searchprovider.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2017 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | #ifndef SEARCHPROVIDER_H 25 | #define SEARCHPROVIDER_H 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | #include "../extensions/extensiontheme.h" 32 | #include "../extensions/extensionsearchengine.h" 33 | #include "../extensions/extensionsearchengineparameter.h" 34 | #include "../extensions/extensionsearchenginesmodel.h" 35 | 36 | class SearchProvider : public QObject 37 | { 38 | Q_OBJECT 39 | public: 40 | explicit SearchProvider(QObject *parent = nullptr); 41 | 42 | ExtensionSearchEnginesModel* model() const { return m_model; } 43 | void setModel(ExtensionSearchEnginesModel* model) { modelChanged(m_model = model); } 44 | 45 | Q_INVOKABLE QString searchUrl(QString query, QString engine, ExtensionTheme* theme) const; 46 | Q_INVOKABLE QString homepage(QString engine, ExtensionTheme* theme) const; 47 | QString url(ExtensionSearchEngineParameter::SearchContext context, QString query, QString engine, ExtensionTheme* theme) const; 48 | 49 | signals: 50 | void modelChanged(ExtensionSearchEnginesModel* model); 51 | 52 | private: // methods 53 | QString dynamicValue(QString value, QString query, ExtensionTheme* theme) const; 54 | 55 | private: // members 56 | QString m_defaultSearchEngine; 57 | QString m_engine; 58 | ExtensionSearchEnginesModel* m_model; 59 | QRegularExpression m_reDynamicValue; 60 | }; 61 | 62 | #endif // SEARCHPROVIDER_H 63 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | cache: 2 | directories: 3 | - /var/cache/apt/archives/ 4 | 5 | language: cpp 6 | compiler: gcc 7 | sudo: require 8 | dist: trusty 9 | 10 | before_install: 11 | - sudo add-apt-repository ppa:beineri/opt-qt58-trusty -y 12 | - sudo apt-get update -qq 13 | 14 | install: 15 | - sudo apt-get -y install qt58base qt58declarative qt58quickcontrols2 qt58svg qt58webengine 16 | - source /opt/qt58/bin/qt58-env.sh 17 | 18 | script: 19 | - mkdir -p ./appdir 20 | - wget -O quazip.zip "http://downloads.sourceforge.net/project/quazip/quazip/0.4.4/quazip-0.4.4.zip?r=http%3A%2F%2Fsourceforge.net%2Fprojects%2Fquazip%2F&ts=1328389079&use_mirror=heanet" 21 | - unzip quazip.zip 22 | - cd quazip-0.4.4 23 | - sed -i 's/SHARED/STATIC/g' quazip/CMakeLists.txt 24 | - cmake . 25 | - make 26 | - sudo make install 27 | - git clone -b develop https://github.com/lirios/fluid 28 | - cd fluid 29 | - git submodule update --init 30 | - mkdir build 31 | - cd build 32 | - qmake LIRI_INSTALL_PREFIX=/usr .. 33 | - make -j4 34 | - sudo make install 35 | - sudo make INSTALL_ROOT=../../appdir install ; sudo chown -R $USER ../../appdir ; find ../../appdir/ 36 | - cd ../../ 37 | - git clone https://github.com/tim-sueberkrueb/slime-engine 38 | - cd slime-engine 39 | - qmake PREFIX=/usr 40 | - make -j4 41 | - sudo make install 42 | - sudo make INSTALL_ROOT=../appdir install ; sudo chown -R $USER ../appdir ; find ../appdir/ 43 | - cd ../ 44 | - mkdir build 45 | - cd build 46 | - qmake LIRI_INSTALL_PREFIX=/usr CONFIG+=QTWEBENGINE_ENABLED .. 47 | - make -j4 48 | - sudo make INSTALL_ROOT=../appdir install ; sudo chown -R $USER ../appdir ; find ../appdir/ 49 | - cd ../ 50 | - wget -c "https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage" 51 | - chmod a+x linuxdeployqt*.AppImage 52 | - unset QTDIR; unset QT_PLUGIN_PATH ; unset LD_LIBRARY_PATH 53 | - ./linuxdeployqt*.AppImage ./appdir/usr/share/applications/*.desktop -bundle-non-qt-libs 54 | - ./linuxdeployqt*.AppImage ./appdir/usr/share/applications/*.desktop -appimage 55 | - find ./appdir -executable -type f -exec ldd {} \; | grep " => /usr" | cut -d " " -f 2-3 | sort | uniq 56 | - curl --upload-file ./APPNAME*.AppImage https://transfer.sh/APPNAME-git.$(git rev-parse --short HEAD)-x86_64.AppImage 57 | -------------------------------------------------------------------------------- /src/ui/components/ActionBar.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2016 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | import QtQuick 2.7 25 | import QtQuick.Controls.Material 2.0 26 | import Fluid.Controls 1.0 27 | import ".." 28 | 29 | Item { 30 | id: actionBar 31 | property list actions 32 | property color foregroundColor: Material.foreground 33 | property bool animationsEnabled: true 34 | property int iconSize: Units.iconSizes.smallMedium 35 | 36 | function itemAt(index) { 37 | return actionRepeater.itemAt(index); 38 | } 39 | 40 | implicitHeight: childrenRect.height 41 | implicitWidth: childrenRect.width 42 | 43 | Row { 44 | Repeater { 45 | id: actionRepeater 46 | model: actions 47 | delegate: IconButton { 48 | id: iconButton 49 | visible: model.visible 50 | implicitHeight: 40 51 | implicitWidth: 40 52 | iconSource: model.iconSource 53 | iconSize: actionBar.iconSize 54 | enabled: model.enabled 55 | iconColor: enabled ? foregroundColor : ColorUtils.shadeColor(foregroundColor, 0.5) 56 | onClicked: actions[index].triggered(iconButton) 57 | 58 | Behavior on iconColor { 59 | enabled: animationsEnabled 60 | ColorAnimation { 61 | duration: Units.mediumDuration 62 | } 63 | } 64 | } 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/core/models/webdownload.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2016 Tim Süberkrüb (https://github.com/tim-sueberkrueb) 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #ifndef WEBDOWNLOAD_H 21 | #define WEBDOWNLOAD_H 22 | 23 | #include 24 | 25 | class WebDownload : public QObject 26 | { 27 | Q_OBJECT 28 | Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged) 29 | Q_PROPERTY(QString mimeType READ mimeType WRITE setMimeType NOTIFY mimeTypeChanged) 30 | Q_PROPERTY(int progress READ progress WRITE setProgress NOTIFY progressChanged) 31 | Q_PROPERTY(bool finished READ finished WRITE setFinished NOTIFY finishedChanged) 32 | Q_PROPERTY(bool invalid READ invalid WRITE setInvalid NOTIFY invalidChanged) 33 | public: 34 | explicit WebDownload(QObject *parent = nullptr); 35 | 36 | void setPath(QString path); 37 | QString path() const; 38 | 39 | void setMimeType(QString mimeType); 40 | QString mimeType() const; 41 | 42 | void setProgress(int progress); 43 | int progress() const; 44 | 45 | void setFinished(bool finished); 46 | bool finished() const; 47 | 48 | void setInvalid(bool invalid); 49 | bool invalid() const; 50 | 51 | 52 | signals: 53 | void pathChanged(QString path); 54 | void mimeTypeChanged(QString mimeType); 55 | void progressChanged(int progress); 56 | void finishedChanged(bool finished); 57 | void invalidChanged(bool invalid); 58 | 59 | void cancel(); 60 | 61 | private: 62 | QString m_path; 63 | QString m_mimeType; 64 | int m_progress; 65 | bool m_invalid; 66 | bool m_finished; 67 | 68 | 69 | public slots: 70 | }; 71 | 72 | #endif // WEBDOWNLOAD_H 73 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Liri Browser 2 | ============ 3 | 4 | [![License](https://img.shields.io/badge/license-GPLv3.0-blue.svg)](https://www.gnu.org/licenses/gpl-3.0.html) 5 | [![GitHub release](https://img.shields.io/github/release/lirios/browser.svg)](https://github.com/lirios/browser) 6 | [![Build Status](https://travis-ci.org/lirios/browser.svg?branch=master)](https://travis-ci.org/lirios/browser) 7 | [![GitHub issues](https://img.shields.io/github/issues/lirios/browser.svg)](https://github.com/lirios/browser/issues) 8 | [![Maintained](https://img.shields.io/maintenance/yes/2017.svg)](https://github.com/lirios/browser/commits/develop) 9 | 10 | A cross-platform material design web browser 11 | 12 | ## Dependencies 13 | * Qt >= 5.8.0 with at least the following modules is required: 14 | * [qtbase](http://code.qt.io/cgit/qt/qtbase.git) 15 | * [qtdeclarative](http://code.qt.io/cgit/qt/qtdeclarative.git) 16 | * [qtquickcontrols2](http://code.qt.io/cgit/qt/qtquickcontrols2.git) 17 | 18 | The following modules and their dependencies are required: 19 | * [Fluid](https://github.com/lirios/fluid) from develop branch 20 | * [SlimeEngine](https://github.com/tim-sueberkrueb/slime-engine) 21 | * with either [Oxide](https://launchpad.net/oxide) or [QtWebEngine](http://code.qt.io/cgit/qt/qtwebengine.git/) 22 | * [quazip](http://quazip.sourceforge.net/) 23 | 24 | ## Build 25 | 26 | From the root of the repository, run: 27 | ```sh 28 | mkdir build && cd build 29 | qmake .. 30 | make 31 | ``` 32 | Note: Oxide web engine is expected by default. To build for QtWebEngine, add `CONFIG+=QTWEBENGINE_ENABLED` to your `qmake` line: 33 | ```sh 34 | qmake .. CONFIG+=QTWEBENGINE_ENABLED 35 | ``` 36 | 37 | Use `make distclean` from inside your `build` directory to clean up. 38 | You need to do this before rerunning `qmake` with different options. 39 | 40 | ## Install 41 | 42 | From your build directory, run: 43 | ```sh 44 | sudo make install 45 | ``` 46 | The browser will be installed to `/usr/local` by default. To specify a custom installation prefix, 47 | set the `PREFIX` environment variable when running `qmake`. For example: 48 | ```sh 49 | PREFIX=/opt qmake .. 50 | ``` 51 | 52 | ## Credits 53 | Many thanks to ... 54 | * [Corbin Crutchley](https://github.com/crutchcorn) for creating the application icon 55 | 56 | ## Licensing 57 | Licensed under the terms of the GNU General Public License version 3 or, at your option, any later version. 58 | -------------------------------------------------------------------------------- /src/ui/toolbar/Toolbar.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2016 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | import QtQuick 2.7 25 | import QtQuick.Layouts 1.1 26 | import Fluid.Controls 1.0 27 | import core 1.0 28 | import ".." 29 | 30 | Item { 31 | id: toolbar 32 | property TabController tabController 33 | property TabsModel tabsModel 34 | property string searchEngine 35 | property ExtensionTheme currentTheme 36 | property color selectionColor: Material.accent 37 | property alias omnibox: omnibox 38 | 39 | property list leftActions 40 | property list rightActions 41 | 42 | readonly property ActionBar leftActionBar: leftActionBar 43 | readonly property ActionBar rightActionBar: rightActionBar 44 | 45 | implicitHeight: 56 46 | implicitWidth: 256 47 | 48 | RowLayout { 49 | anchors { 50 | fill: parent 51 | rightMargin: 2 * Units.smallSpacing 52 | } 53 | 54 | Layout.alignment: Qt.AlignLeft | Qt.AlignHCenter 55 | 56 | ActionBar { 57 | id: leftActionBar 58 | actions: leftActions 59 | } 60 | 61 | Omnibox { 62 | id: omnibox 63 | Layout.fillWidth: true 64 | tabsModel: toolbar.tabsModel 65 | tabController: toolbar.tabController 66 | searchEngine: toolbar.searchEngine 67 | currentTheme: toolbar.currentTheme 68 | selectionColor: toolbar.selectionColor 69 | } 70 | 71 | ActionBar { 72 | id: rightActionBar 73 | actions: rightActions 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/core/extensions/extensionsearchengineparameter.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2017 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | #ifndef EXTENSIONSEARCHENGINEPARAMETER_H 25 | #define EXTENSIONSEARCHENGINEPARAMETER_H 26 | 27 | #include 28 | #include 29 | 30 | 31 | class ExtensionSearchEngineParameter : public QObject 32 | { 33 | Q_OBJECT 34 | public: 35 | explicit ExtensionSearchEngineParameter(QObject *parent = nullptr); 36 | 37 | ExtensionSearchEngineParameter* clone(QObject* parent = nullptr); 38 | 39 | enum Type { 40 | Get, 41 | Hashbang 42 | }; 43 | 44 | enum SearchContext { 45 | None = 0x0, 46 | Search = 0x1, 47 | Homepage = 0x2 48 | }; 49 | 50 | Q_DECLARE_FLAGS(ContextFlag, SearchContext) 51 | Q_FLAGS(ContextFlag) 52 | 53 | Type type() const { return m_type; } 54 | void setType(Type type) { typeChanged(m_type = type); } 55 | 56 | QString name() const { return m_name; } 57 | void setName(QString name) { nameChanged(m_name = name); } 58 | 59 | QString value() const { return m_value; } 60 | void setValue(QString value) { valueChanged(m_value = value); } 61 | 62 | ContextFlag context() const { return m_context; } 63 | void setContext(ContextFlag context) { contextChanged(m_context = context); } 64 | 65 | signals: 66 | void typeChanged(Type type); 67 | void nameChanged(QString name); 68 | void valueChanged(QString value); 69 | void contextChanged(ContextFlag context); 70 | 71 | private: 72 | Type m_type; 73 | QString m_name; 74 | QString m_value; 75 | ContextFlag m_context; 76 | }; 77 | 78 | Q_DECLARE_OPERATORS_FOR_FLAGS(ExtensionSearchEngineParameter::ContextFlag) 79 | 80 | #endif // EXTENSIONSEARCHENGINEPARAMETER_H 81 | -------------------------------------------------------------------------------- /src/ui/tabview/TabContentView.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2016 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | import QtQuick 2.7 25 | import core 1.0 26 | 27 | Item { 28 | id: tabContentView 29 | property TabsModel tabsModel 30 | property ListModel pages: ListModel {} 31 | readonly property Item container: contentContainer 32 | 33 | function registerPage(uid, item) { 34 | // Make item invisible for now 35 | item.visible = false; 36 | // Reparent and anchor item 37 | item.parent = contentContainer; 38 | item.anchors.fill = contentContainer; 39 | // Create visibility binding 40 | item.visible = Qt.binding(function(){ return tabsModel.active.uid === uid }); 41 | // Append to pages model 42 | pages.append({ 43 | uid: uid, 44 | item: item 45 | }); 46 | } 47 | 48 | function unregisterPage(uid) { 49 | var page = pageByUID(uid); 50 | if (!page) 51 | return false; 52 | // Make item invisible 53 | page.item.visible = false; 54 | // Destroy item 55 | page.item.destroy(); 56 | // Remove page from model 57 | pages.remove(indexByUID(uid)); 58 | return true; 59 | } 60 | 61 | function pageByUID(uid) { 62 | for (var i=0; i 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | import QtQuick 2.7 25 | import QtQuick.Layouts 1.1 26 | import QtQuick.Controls 2.0 27 | import QtQuick.Controls.Material 2.0 28 | import Fluid.Controls 1.0 29 | import Fluid.Core 1.0 30 | import "../.." 31 | 32 | TabContent { 33 | id: content 34 | 35 | canReload: false 36 | canGoBack: false 37 | canGoForward: false 38 | loading: false 39 | loadProgress: 100 40 | iconUrl: Utils.getSourceForIconName("action/info_outline") 41 | adaptIconColor: true 42 | title: "About Liri Browser" 43 | url: "liri://about" 44 | hasThemeColor: false 45 | 46 | Column { 47 | anchors { 48 | fill: parent 49 | margins: Units.smallSpacing * 2 50 | } 51 | 52 | spacing: Units.smallSpacing 53 | 54 | HeadlineLabel { 55 | text: "Liri Browser" 56 | } 57 | 58 | TitleLabel { 59 | text: ApplicationVersion 60 | } 61 | 62 | BodyLabel { 63 | text: "Liri Browser is a cross-platform material design webbrowser." 64 | wrapMode: Text.WordWrap 65 | width: parent.width 66 | } 67 | 68 | BodyLabel { 69 | text: "Licensed under the terms of the GNU General Public License version 3 or, at your option, any later version." 70 | wrapMode: Text.WordWrap 71 | width: parent.width 72 | } 73 | 74 | SubheadingLabel { 75 | text: "Powered by Qt %1".arg(QtVersion) 76 | } 77 | 78 | SubheadingLabel { 79 | text: "Running on %1".arg(SystemInformation) 80 | wrapMode: Text.WordWrap 81 | width: parent.width 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/ui/drawer/content/downloads/DownloadItemDelegate.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2016 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | import QtQuick 2.7 25 | import QtQuick.Layouts 1.1 26 | import QtQuick.Controls 2.0 27 | import Fluid.Controls 1.0 28 | 29 | 30 | BaseListItem { 31 | property var downloadsModel 32 | property var download: downloadsModel.get(index) 33 | 34 | implicitHeight: 74 35 | 36 | RowLayout { 37 | anchors { 38 | fill: parent 39 | topMargin: Units.smallSpacing 40 | bottomMargin: Units.smallSpacing 41 | } 42 | 43 | spacing: Units.smallSpacing 44 | 45 | Icon { 46 | name: "file/file_download" 47 | } 48 | 49 | ColumnLayout { 50 | Layout.fillWidth: true 51 | Layout.fillHeight: true 52 | spacing: Units.smallSpacing 53 | 54 | Label { 55 | Layout.fillWidth: true 56 | text: download.path 57 | elide: Text.ElideLeft 58 | } 59 | 60 | ProgressBar { 61 | Layout.fillWidth: true 62 | visible: !download.finished 63 | height: download.finished ? 0 : implicitHeight 64 | value: download.progress/100 65 | } 66 | 67 | CaptionLabel { 68 | text: download.finished ? "Finished" : "%1%".arg(download.progress.toString()) 69 | } 70 | } 71 | 72 | IconButton { 73 | iconName: "navigation/cancel" 74 | onClicked: { 75 | // Cancel engine download 76 | download.cancel(); 77 | // Remove from model 78 | downloadsModel.remove(index) 79 | } 80 | } 81 | } 82 | 83 | onClicked: { 84 | // Open download file externally 85 | if (download.finished) 86 | Qt.openUrlExternally("file://" + download.path); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/ui/overlay/SearchOverlay.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2016 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | import QtQuick 2.7 25 | import QtQuick.Layouts 1.1 26 | import QtQuick.Controls 2.0 27 | import Fluid.Controls 1.0 28 | 29 | BaseOverlay { 30 | id: searchOverlay 31 | 32 | property bool searchEnabled: true 33 | 34 | signal searchRequested(string text, bool backwards) 35 | 36 | onOpened: { 37 | searchField.forceActiveFocus(); 38 | } 39 | 40 | implicitWidth: childrenRect.width 41 | 42 | RowLayout { 43 | id: rowLayout 44 | 45 | anchors { 46 | top: parent.top 47 | bottom: parent.bottom 48 | } 49 | 50 | Item { implicitWidth: 16 } // Spacer 51 | 52 | TextField { 53 | id: searchField 54 | selectByMouse: true 55 | enabled: searchEnabled 56 | placeholderText: "Find in page" 57 | onAccepted: { 58 | searchRequested(searchField.text, false); 59 | } 60 | } 61 | 62 | IconButton { 63 | enabled: searchEnabled 64 | implicitHeight: 40 65 | implicitWidth: 40 66 | iconName: "hardware/keyboard_arrow_up" 67 | onClicked: { 68 | searchRequested(searchField.text, true); 69 | } 70 | } 71 | 72 | IconButton { 73 | enabled: searchEnabled 74 | implicitHeight: 40 75 | implicitWidth: 40 76 | iconName: "hardware/keyboard_arrow_down" 77 | onClicked: { 78 | searchRequested(searchField.text, false); 79 | } 80 | } 81 | 82 | IconButton { 83 | implicitHeight: 40 84 | implicitWidth: 40 85 | iconName: "navigation/close" 86 | onClicked: { 87 | searchOverlay.close(); 88 | } 89 | } 90 | 91 | Item { implicitWidth: 8 } // Spacer 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/ui/tabview/TabContent.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2016 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | import QtQuick 2.7 25 | import core 1.0 26 | 27 | Item { 28 | id: content 29 | 30 | property var tab 31 | property var actionManager 32 | 33 | property url iconUrl 34 | property bool adaptIconColor 35 | property url url 36 | property bool canGoBack 37 | property bool canGoForward 38 | property bool canReload 39 | property bool loading 40 | property int loadProgress 41 | property bool hasThemeColor 42 | property color themeColor 43 | property string title 44 | 45 | Binding { 46 | target: content.tab 47 | property: "title" 48 | value: title 49 | } 50 | 51 | Binding { 52 | target: content.tab 53 | property: "iconUrl" 54 | value: iconUrl 55 | } 56 | 57 | Binding { 58 | target: content.tab 59 | property: "adaptIconColor" 60 | value: adaptIconColor 61 | } 62 | 63 | Binding { 64 | target: content.tab 65 | property: "url" 66 | value: url 67 | } 68 | 69 | Binding { 70 | target: content.tab 71 | property: "canGoBack" 72 | value: canGoBack 73 | } 74 | 75 | Binding { 76 | target: content.tab 77 | property: "canGoForward" 78 | value: canGoForward 79 | } 80 | 81 | Binding { 82 | target: content.tab 83 | property: "loading" 84 | value: loading 85 | } 86 | 87 | Binding { 88 | target: content.tab 89 | property: "loadProgress" 90 | value: loadProgress 91 | } 92 | 93 | Binding { 94 | target: content.tab 95 | property: "hasThemeColor" 96 | value: hasThemeColor 97 | } 98 | 99 | Binding { 100 | target: content.tab 101 | property: "themeColor" 102 | value: themeColor 103 | } 104 | 105 | Binding { 106 | target: content.tab 107 | property: "canReload" 108 | value: canReload 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/ui/expansionbar/ExpansionBar.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2016 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | import QtQuick 2.7 25 | import Fluid.Controls 1.0 26 | 27 | Item { 28 | id: expansionBar 29 | 30 | property list contentComponents 31 | property int currentContentIndex: -1 32 | property bool showing: false 33 | 34 | signal opened() 35 | signal closed() 36 | 37 | function loadContent(index) { 38 | currentContentIndex = index; 39 | } 40 | 41 | function open() { 42 | showing = true; 43 | showAnimation.start(); 44 | } 45 | 46 | function close() { 47 | showing = false; 48 | closeAnimation.start(); 49 | } 50 | 51 | clip: true 52 | 53 | Rectangle { 54 | id: contentContainer 55 | anchors { 56 | left: parent.left 57 | right: parent.right 58 | bottom: parent.bottom 59 | } 60 | 61 | height: 48 62 | 63 | Loader { 64 | id: contentLoader 65 | anchors { 66 | fill: parent 67 | leftMargin: 2 * Units.smallSpacing 68 | rightMargin: 2 * Units.smallSpacing 69 | } 70 | sourceComponent: currentContentIndex >= 0 ? contentComponents[currentContentIndex] : null 71 | } 72 | } 73 | 74 | NumberAnimation { 75 | id: showAnimation 76 | target: expansionBar 77 | property: "implicitHeight" 78 | duration: Units.mediumDuration 79 | easing.type: Easing.InOutQuad 80 | to: 56 81 | onStopped: opened() 82 | } 83 | 84 | NumberAnimation { 85 | id: closeAnimation 86 | target: expansionBar 87 | property: "implicitHeight" 88 | duration: Units.mediumDuration 89 | easing.type: Easing.InOutQuad 90 | to: 0 91 | onStopped: closed() 92 | } 93 | 94 | Connections { 95 | enabled: currentContentIndex >= 0 && contentLoader.status === Loader.Ready 96 | target: contentLoader.item 97 | onClosed: { 98 | expansionBar.close(); 99 | currentContentIndex = -1; 100 | } 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/core/extensions/extensionsmanager.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2017 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | #ifndef EXTENSIONSMANAGER_H 25 | #define EXTENSIONSMANAGER_H 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | #include 33 | #include 34 | 35 | #include "../global/paths.h" 36 | #include "extension.h" 37 | #include "extensionparser.h" 38 | #include "extensionsmodel.h" 39 | #include "extensionthemesmodel.h" 40 | #include "extensionsearchenginesmodel.h" 41 | 42 | class ExtensionsManager : public QObject 43 | { 44 | Q_OBJECT 45 | Q_PROPERTY(ExtensionsModel* extensionsModel MEMBER m_extensionsModel NOTIFY extensionsModelChanged) 46 | Q_PROPERTY(ExtensionThemesModel* themesModel MEMBER m_extensionThemesModel NOTIFY extensionThemesModelChanged) 47 | Q_PROPERTY(ExtensionSearchEnginesModel* searchEnginesModel MEMBER m_extensionSearchEnginesModel NOTIFY extensionSearchEnginesModelChanged) 48 | public: 49 | explicit ExtensionsManager(QObject *parent = nullptr); 50 | 51 | void loadBuiltins(); 52 | void startWatching(); 53 | void scan(); 54 | 55 | void addExtension(Extension* extension); 56 | void removeExtension(Extension* extension); 57 | Extension* extensionByName(const QString name); 58 | 59 | void loadFile(const QString filePath); 60 | void unloadFile(const QString filePath); 61 | 62 | ExtensionThemesModel* themesModel() const { return m_extensionThemesModel; } 63 | ExtensionSearchEnginesModel* searchEnginesModel() const { return m_extensionSearchEnginesModel; } 64 | 65 | signals: 66 | void extensionsModelChanged(ExtensionsModel* model); 67 | void extensionThemesModelChanged(ExtensionThemesModel* model); 68 | void extensionSearchEnginesModelChanged(ExtensionSearchEnginesModel* model); 69 | 70 | private: 71 | ExtensionsModel* m_extensionsModel; 72 | ExtensionThemesModel* m_extensionThemesModel; 73 | ExtensionSearchEnginesModel* m_extensionSearchEnginesModel; 74 | QFileSystemWatcher* m_watcher; 75 | 76 | bool m_loaded; 77 | 78 | QList m_files; 79 | QDir m_dir; 80 | 81 | 82 | private slots: 83 | void directoryChanged(const QString path); 84 | void fileAdded(const QString filename); 85 | void fileRemoved(const QString filename); 86 | }; 87 | 88 | #endif // EXTENSIONSMANAGER_H 89 | -------------------------------------------------------------------------------- /src/core/models/downloadsmodel.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2017 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | 25 | #include "downloadsmodel.h" 26 | 27 | DownloadsModel::DownloadsModel(QObject* parent) 28 | : QAbstractListModel(parent) 29 | { 30 | m_invalid_download = new WebDownload(this); 31 | m_invalid_download->setInvalid(true); 32 | } 33 | 34 | int DownloadsModel::rowCount(const QModelIndex &parent) const 35 | { 36 | Q_UNUSED(parent); 37 | return m_downloads_list.length(); 38 | } 39 | 40 | QHash DownloadsModel::roleNames() 41 | { 42 | QHash roles; 43 | roles[Path] = "path"; 44 | roles[MimeType] = "mimeType"; 45 | roles[Progress] = "progress"; 46 | return roles; 47 | } 48 | 49 | QVariant DownloadsModel::data(const QModelIndex &index, int role) const 50 | { 51 | WebDownload* download = get(index.row()); 52 | switch (role) { 53 | case Path: 54 | return QVariant(download->path()); 55 | case MimeType: 56 | return QVariant(download->mimeType()); 57 | case Progress: 58 | return QVariant(download->progress()); 59 | case Invalid: 60 | return QVariant(download->invalid()); 61 | } 62 | return QVariant(); 63 | } 64 | 65 | int DownloadsModel::count() const 66 | { 67 | return m_downloads_list.length(); 68 | } 69 | 70 | WebDownload* DownloadsModel::add() 71 | { 72 | beginInsertRows(QModelIndex(), rowCount(), rowCount()); 73 | WebDownload* download = new WebDownload(this); 74 | m_downloads_list.append(download); 75 | countChanged(count()); 76 | endInsertRows(); 77 | return download; 78 | } 79 | 80 | WebDownload* DownloadsModel::get(const int index) const 81 | { 82 | if (index < 0 || index >= rowCount()) { 83 | return m_invalid_download; 84 | } 85 | return m_downloads_list.at(index); 86 | } 87 | 88 | bool DownloadsModel::remove(WebDownload *download) 89 | { 90 | int index = m_downloads_list.indexOf(download); 91 | if (index == -1) 92 | return false; 93 | beginRemoveRows(QModelIndex(), index, index); 94 | m_downloads_list.removeAt(index); 95 | countChanged(count()); 96 | endRemoveRows(); 97 | return true; 98 | } 99 | 100 | bool DownloadsModel::remove(const int index) 101 | { 102 | return remove(get(index)); 103 | } 104 | -------------------------------------------------------------------------------- /src/core/models/tabsmodel.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2016 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | #ifndef TABSMODEL_H 25 | #define TABSMODEL_H 26 | 27 | #include 28 | #include "tab.h" 29 | 30 | class TabsModel : public QAbstractListModel 31 | { 32 | Q_OBJECT 33 | Q_PROPERTY(int count READ count NOTIFY countChanged) 34 | Q_PROPERTY(bool empty READ empty NOTIFY emptyChanged) 35 | Q_PROPERTY(Tab* active READ active NOTIFY activeChanged) 36 | Q_PROPERTY(int activeRow READ activeRow NOTIFY activeRowChanged) 37 | public: 38 | explicit TabsModel(QObject *parent = nullptr); 39 | 40 | enum TabRoles { 41 | Uid, 42 | Url, 43 | Title, 44 | IconUrl, 45 | CanGoBack, 46 | CanGoForward, 47 | Loading, 48 | LoadProgress, 49 | Valid 50 | }; 51 | 52 | int rowCount(const QModelIndex &parent=QModelIndex()) const; 53 | QHash roleNames() const; 54 | Q_INVOKABLE QVariant data(const QModelIndex &index, int role) const; 55 | 56 | Q_INVOKABLE Tab* get(const int row) const; 57 | Q_INVOKABLE int row(unsigned int uid); 58 | Q_INVOKABLE int row(Tab* tab); 59 | Q_INVOKABLE void add(unsigned int uid); 60 | Q_INVOKABLE void insert(unsigned int uid, int row=-1); 61 | Q_INVOKABLE bool move(int fromRow, int toRow); 62 | Q_INVOKABLE int count() const; 63 | Q_INVOKABLE bool remove(unsigned int uid); 64 | Q_INVOKABLE bool remove(Tab* tab); 65 | Q_INVOKABLE bool empty() const; 66 | 67 | Q_INVOKABLE Tab* byUID(unsigned int uid); 68 | 69 | Q_INVOKABLE bool setActive(unsigned int uid); 70 | Q_INVOKABLE bool setActive(Tab* tab); 71 | Q_INVOKABLE Tab* active() const; 72 | Q_INVOKABLE int activeRow() const; 73 | 74 | Q_INVOKABLE void setInactive(Tab* tab); 75 | Q_INVOKABLE void setInactive(); 76 | 77 | Q_INVOKABLE bool setPreviousTabActive(); 78 | Q_INVOKABLE bool setNextTabActive(); 79 | 80 | signals: 81 | void countChanged(int count); 82 | void emptyChanged(bool empty); 83 | void activeChanged(Tab* tab); 84 | void activeRowChanged(int index); 85 | void beforeTabRemoved(Tab* tab); 86 | 87 | public slots: 88 | 89 | private: // methods 90 | bool activateTabRelativeToCurrent(int offset); 91 | bool setActive(Tab* tab, bool recordToHistory); 92 | 93 | private: // members 94 | QList m_tabsList; 95 | QList m_activeTabHistory; 96 | Tab* m_activeTab; 97 | Tab* m_invalidTab; 98 | }; 99 | 100 | #endif // TABSMODEL_H 101 | -------------------------------------------------------------------------------- /src/core/extensions/extensionsearchengine.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2017 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | #ifndef EXTENSIONSEARCHENGINE_H 25 | #define EXTENSIONSEARCHENGINE_H 26 | 27 | #include 28 | #include 29 | 30 | #include "extensionelement.h" 31 | #include "extensionsearchengineparameter.h" 32 | 33 | class ExtensionSearchEngine : public ExtensionElement 34 | { 35 | Q_OBJECT 36 | Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged) 37 | Q_PROPERTY(QString summary READ summary WRITE setSummary NOTIFY summaryChanged) 38 | Q_PROPERTY(QString description READ description WRITE setDescription NOTIFY descriptionChanged) 39 | Q_PROPERTY(QString urlBaseSearch READ urlBaseSearch WRITE setUrlBaseSearch NOTIFY urlBaseSearchChanged) 40 | Q_PROPERTY(QString urlBaseHomepage READ urlBaseHomepage WRITE setUrlBaseHomepage NOTIFY urlBaseHomepageChanged) 41 | Q_PROPERTY(QList* parameters READ parameters NOTIFY parametersChanged) 42 | public: 43 | explicit ExtensionSearchEngine(QObject *parent = nullptr); 44 | 45 | ExtensionSearchEngine* clone(QObject* parent = nullptr); 46 | 47 | QString title() const { return m_title; } 48 | void setTitle(QString title) { titleChanged(m_title = title); } 49 | 50 | QString summary() const { return m_summary; } 51 | void setSummary(QString summary) { summaryChanged(m_summary = summary); } 52 | 53 | QString description() const { return m_description; } 54 | void setDescription(QString description) { descriptionChanged(m_description = description); } 55 | 56 | QString urlBaseSearch() const { return m_urlBaseSearch; } 57 | void setUrlBaseSearch(QString urlBaseSearch) { urlBaseSearchChanged(m_urlBaseSearch = urlBaseSearch); } 58 | 59 | QString urlBaseHomepage() const { return m_urlBaseHomepage; } 60 | void setUrlBaseHomepage(QString urlBaseHomepage) { urlBaseHomepageChanged(m_urlBaseHomepage = urlBaseHomepage); } 61 | 62 | QList* parameters() const { return m_parameters; } 63 | 64 | signals: 65 | void titleChanged(QString title); 66 | void summaryChanged(QString summary); 67 | void descriptionChanged(QString description); 68 | void urlBaseSearchChanged(QString urlBaseSearchChanged); 69 | void urlBaseHomepageChanged(QString urlBaseHomepage); 70 | void parametersChanged(QList* parameters); 71 | 72 | private: 73 | QString m_title; 74 | QString m_summary; 75 | QString m_description; 76 | QString m_urlBaseSearch; 77 | QString m_urlBaseHomepage; 78 | QList* m_parameters; 79 | }; 80 | 81 | #endif // EXTENSIONSEARCHENGINE_H 82 | -------------------------------------------------------------------------------- /src/ui/tabview/TabDelegate.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2016 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | import QtQuick 2.7 25 | import QtQuick.Layouts 1.1 26 | import QtQuick.Controls 2.0 27 | import QtQuick.Controls.Material 2.0 28 | import QtGraphicalEffects 1.0 29 | import Fluid.Core 1.0 30 | import Fluid.Controls 1.0 31 | import ".." 32 | 33 | Rectangle { 34 | property string title 35 | property url iconSource 36 | property color iconColor: "transparent" 37 | property bool adaptIconColor: false 38 | property bool active: false 39 | property color foregroundColor: Material.foreground 40 | property color backgroundColor: Material.background 41 | 42 | signal closeRequested() 43 | 44 | implicitWidth: 200 45 | 46 | color: backgroundColor 47 | 48 | RowLayout { 49 | anchors { 50 | fill: parent 51 | leftMargin: Units.smallSpacing 52 | } 53 | 54 | spacing: Units.smallSpacing 55 | 56 | Image { 57 | id: icon 58 | Layout.preferredHeight: Units.iconSizes.small 59 | Layout.preferredWidth: Units.iconSizes.small 60 | source: iconSource 61 | clip: true 62 | sourceSize.width: Units.iconSizes.small 63 | sourceSize.height: Units.iconSizes.small 64 | 65 | ColorOverlay { 66 | anchors.fill: icon 67 | visible: iconColor != "transparent" || adaptIconColor 68 | source: icon 69 | color: { 70 | if (adaptIconColor) { 71 | return Utils.lightDark(backgroundColor, "transparent", "white"); 72 | } 73 | else { 74 | return iconColor; 75 | } 76 | } 77 | } 78 | } 79 | 80 | Label { 81 | Layout.fillWidth: true 82 | text: title || "New tab" 83 | color: active ? foregroundColor : ColorUtils.shadeColor(foregroundColor, 0.5) 84 | elide: Text.ElideRight 85 | 86 | Behavior on color { 87 | ColorAnimation { 88 | duration: Units.mediumDuration 89 | easing.type: Easing.InOutQuad 90 | } 91 | } 92 | } 93 | 94 | IconButton { 95 | iconName: "navigation/close" 96 | onClicked: closeRequested() 97 | iconColor: active ? foregroundColor : ColorUtils.shadeColor(foregroundColor, 0.5) 98 | iconSize: 18 99 | implicitHeight: 24 100 | implicitWidth: 24 101 | 102 | Behavior on iconColor { 103 | ColorAnimation { 104 | duration: Units.mediumDuration 105 | easing.type: Easing.InOutQuad 106 | } 107 | } 108 | } 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/ui/tabview/content/WebContent.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2017 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | import QtQuick 2.7 25 | import SlimeEngine 0.2 26 | import "../.." 27 | 28 | TabContent { 29 | id: content 30 | 31 | property var webview: webview 32 | property alias profile: webview.profile 33 | property alias request: webview.request 34 | property int webengine 35 | 36 | canReload: true 37 | canGoBack: webview.canGoBack 38 | canGoForward: webview.canGoForward 39 | loading: webview.loadProgress < 100 40 | loadProgress: webview.loadProgress 41 | iconUrl: webview.icon 42 | adaptIconColor: false 43 | title: webview.title 44 | hasThemeColor: false 45 | 46 | WebView { 47 | id: webview 48 | engine: webengine 49 | anchors.fill: parent 50 | onNewViewRequested: { 51 | actionManager.newWebViewRequested(request); 52 | } 53 | onCloseRequested: { 54 | actionManager.closeRequested(); 55 | } 56 | onLoadStatusChanged: { 57 | if (loadStatus === LoadStatus.LoadSucceeded) { 58 | // Search for theme color 59 | runJavaScript(" 60 | function getThemeColor () { 61 | var metaTags = document.getElementsByTagName('meta'); 62 | for (i=0; i 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | #ifndef THEMECONFIG_H 25 | #define THEMECONFIG_H 26 | 27 | #include 28 | #include 29 | 30 | class ThemeConfig : public QObject 31 | { 32 | Q_OBJECT 33 | Q_PROPERTY(QString primary READ primary WRITE setPrimary NOTIFY primaryChanged) 34 | Q_PROPERTY(QString secondary READ secondary WRITE setSecondary NOTIFY secondaryChanged) 35 | Q_PROPERTY(QString incognito READ incognito WRITE setIncognito NOTIFY incognitoChanged) 36 | Q_PROPERTY(bool secondaryEnabled READ secondaryEnabled WRITE setSecondaryEnabled NOTIFY secondaryEnabledChanged) 37 | Q_PROPERTY(QTime secondaryStartTime READ secondaryStartTime WRITE setSecondaryStartTime NOTIFY secondaryStartTimeChanged) 38 | Q_PROPERTY(QTime secondaryEndTime READ secondaryEndTime WRITE setSecondaryEndTime NOTIFY secondaryEndTimeChanged) 39 | public: 40 | explicit ThemeConfig(QObject *parent = nullptr); 41 | 42 | QString primary() const { return m_primary; } 43 | void setPrimary(QString primary) { primaryChanged(m_primary = primary); } 44 | 45 | QString secondary() const { return m_secondary; } 46 | void setSecondary(QString secondary) { secondaryChanged(m_secondary = secondary); } 47 | 48 | QString incognito() const { return m_incognito; } 49 | void setIncognito(QString incognito) { incognitoChanged(m_incognito = incognito); } 50 | 51 | bool secondaryEnabled() const { return m_secondaryEnabled; } 52 | void setSecondaryEnabled(bool secondaryEnabled) { secondaryEnabledChanged(m_secondaryEnabled = secondaryEnabled); } 53 | 54 | QTime secondaryStartTime() const { return m_secondaryStartTime; } 55 | void setSecondaryStartTime(QTime secondaryStartTime) { secondaryStartTimeChanged(m_secondaryStartTime = secondaryStartTime); } 56 | Q_INVOKABLE void setSecondaryStartTime(QString secondaryStartTime, QString format) { 57 | secondaryStartTimeChanged(m_secondaryStartTime = QTime::fromString(secondaryStartTime, format)); 58 | } 59 | 60 | QTime secondaryEndTime() const { return m_secondaryEndTime; } 61 | void setSecondaryEndTime(QTime secondaryEndTime) { secondaryEndTimeChanged(m_secondaryEndTime = secondaryEndTime); } 62 | Q_INVOKABLE void setSecondaryEndTime(QString secondaryEndTime, QString format) { 63 | secondaryEndTimeChanged(m_secondaryEndTime = QTime::fromString(secondaryEndTime, format)); 64 | } 65 | 66 | signals: 67 | void primaryChanged(QString primary); 68 | void secondaryChanged(QString secondary); 69 | void incognitoChanged(QString incognito); 70 | void secondaryEnabledChanged(bool secondaryEnabled); 71 | void secondaryStartTimeChanged(QTime secondaryStartTime); 72 | void secondaryEndTimeChanged(QTime secondaryEndTime); 73 | 74 | private: 75 | QString m_primary; 76 | QString m_secondary; 77 | QString m_incognito; 78 | bool m_secondaryEnabled; 79 | QTime m_secondaryStartTime; 80 | QTime m_secondaryEndTime; 81 | }; 82 | 83 | #endif // THEMECONFIG_H 84 | -------------------------------------------------------------------------------- /src/core/models/tab.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2016 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | 25 | #include "tab.h" 26 | 27 | Tab::Tab(QObject *parent, bool valid) 28 | : QObject(parent) 29 | { 30 | m_uid = -1; 31 | m_canReload = true; 32 | validChanged(m_valid = valid); 33 | m_iconColor = Qt::transparent; 34 | } 35 | 36 | unsigned int Tab::uid() const 37 | { 38 | return m_uid; 39 | } 40 | 41 | void Tab::setUid(int uid) 42 | { 43 | uidChanged(m_uid = uid); 44 | } 45 | 46 | QUrl Tab::url() const 47 | { 48 | return m_url; 49 | } 50 | 51 | void Tab::setUrl(QUrl url) 52 | { 53 | urlChanged(m_url = url); 54 | } 55 | 56 | QString Tab::title() const 57 | { 58 | return m_title; 59 | } 60 | 61 | void Tab::setTitle(QString title) 62 | { 63 | titleChanged(m_title = title); 64 | } 65 | 66 | QUrl Tab::iconUrl() const 67 | { 68 | return m_iconUrl; 69 | } 70 | 71 | void Tab::setIconUrl(QUrl iconUrl) 72 | { 73 | iconUrlChanged(m_iconUrl = iconUrl); 74 | } 75 | 76 | QColor Tab::iconColor() const 77 | { 78 | return m_iconColor; 79 | } 80 | 81 | void Tab::setIconColor(QColor iconColor) 82 | { 83 | iconColorChanged(m_iconColor = iconColor); 84 | } 85 | 86 | bool Tab::adaptIconColor() const 87 | { 88 | return m_adaptIconColor; 89 | } 90 | 91 | void Tab::setAdaptIconColor(bool adaptIconColor) 92 | { 93 | adaptIconColorChanged(m_adaptIconColor = adaptIconColor); 94 | } 95 | 96 | bool Tab::canGoBack() const 97 | { 98 | return m_canGoBack; 99 | } 100 | 101 | void Tab::setCanGoBack(bool canGoBack) 102 | { 103 | canGoBackChanged(m_canGoBack = canGoBack); 104 | } 105 | 106 | bool Tab::canGoForward() const 107 | { 108 | return m_canGoForward; 109 | } 110 | 111 | void Tab::setCanGoForward(bool canGoForward) 112 | { 113 | canGoForwardChanged(m_canGoForward = canGoForward); 114 | } 115 | 116 | bool Tab::canReload() const 117 | { 118 | return m_canReload; 119 | } 120 | 121 | void Tab::setCanReload(bool canReload) 122 | { 123 | canReloadChanged(m_canReload = canReload); 124 | } 125 | 126 | bool Tab::loading() const 127 | { 128 | return m_loading; 129 | } 130 | 131 | void Tab::setLoading(bool loading) 132 | { 133 | loadingChanged(m_loading = loading); 134 | } 135 | 136 | unsigned int Tab::loadProgress() const 137 | { 138 | return m_loadProgress; 139 | } 140 | 141 | void Tab::setLoadProgress(unsigned int loadProgress) 142 | { 143 | loadProgressChanged(m_loadProgress = loadProgress); 144 | } 145 | 146 | bool Tab::valid() const 147 | { 148 | return m_valid; 149 | } 150 | 151 | bool Tab::hasThemeColor() const 152 | { 153 | return m_hasThemeColor; 154 | } 155 | 156 | void Tab::setHasThemeColor(bool hasThemeColor) 157 | { 158 | hasThemeColorChanged(m_hasThemeColor = hasThemeColor); 159 | } 160 | 161 | QColor Tab::themeColor() const 162 | { 163 | return m_themeColor; 164 | } 165 | 166 | void Tab::setThemeColor(QColor themeColor) 167 | { 168 | themeColorChanged(m_themeColor = themeColor); 169 | } 170 | -------------------------------------------------------------------------------- /src/core/extensions/extensionsmodel.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2017 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | #include "extensionsmodel.h" 25 | 26 | #include 27 | 28 | ExtensionsModel::ExtensionsModel(QObject *parent) 29 | : QAbstractListModel(parent) 30 | { 31 | m_invalidExtension = new Extension(); 32 | m_invalidExtension->setValid(false); 33 | } 34 | 35 | int ExtensionsModel::rowCount(const QModelIndex &parent) const 36 | { 37 | Q_UNUSED(parent); 38 | return m_extensions.length(); 39 | } 40 | 41 | QHash ExtensionsModel::roleNames() const 42 | { 43 | QHash roles; 44 | roles[Name] = "name"; 45 | roles[Title] = "title"; 46 | roles[Description] = "description"; 47 | roles[Summary] = "summary"; 48 | roles[Author] = "author"; 49 | roles[Email] = "email"; 50 | return roles; 51 | } 52 | 53 | QVariant ExtensionsModel::data(const QModelIndex &index, int role) const 54 | { 55 | Extension* extension = get(index.row()); 56 | switch (role) { 57 | case Name: 58 | return QVariant(extension->name()); 59 | case Title: 60 | return QVariant(extension->title()); 61 | case Description: 62 | return QVariant(extension->description()); 63 | case Summary: 64 | return QVariant(extension->summary()); 65 | case Author: 66 | return QVariant(extension->author()); 67 | case Email: 68 | return QVariant(extension->email()); 69 | } 70 | return QVariant(); 71 | } 72 | 73 | int ExtensionsModel::count() const 74 | { 75 | return m_extensions.length(); 76 | } 77 | 78 | void ExtensionsModel::add(Extension *extension) 79 | { 80 | beginInsertRows(QModelIndex(), rowCount(), rowCount()); 81 | m_extensions.append(extension); 82 | countChanged(count()); 83 | endInsertRows(); 84 | } 85 | 86 | void ExtensionsModel::remove(const int row) 87 | { 88 | beginRemoveRows(QModelIndex(), row, row); 89 | Extension* extension = m_extensions.at(row); 90 | m_extensions.removeAt(row); 91 | extension->deleteLater(); 92 | countChanged(count()); 93 | endRemoveRows(); 94 | } 95 | 96 | void ExtensionsModel::remove(Extension *extension) 97 | { 98 | int index = m_extensions.indexOf(extension); 99 | if (index != -1) 100 | remove(index); 101 | } 102 | 103 | Extension *ExtensionsModel::get(const int row) const 104 | { 105 | if (row < 0 || row >= count()) { 106 | return m_invalidExtension; 107 | } 108 | return m_extensions.at(row); 109 | } 110 | 111 | Extension *ExtensionsModel::get(const QString name) const 112 | { 113 | for (Extension* extension : m_extensions) { 114 | if (extension->name() == name) 115 | return extension; 116 | } 117 | return m_invalidExtension; 118 | } 119 | 120 | bool ExtensionsModel::hasName(const QString name) const 121 | { 122 | for (Extension* extension : m_extensions) { 123 | if (extension->name() == name) 124 | return true; 125 | } 126 | return false; 127 | } 128 | -------------------------------------------------------------------------------- /src/core/extensions/extension.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2017 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | #ifndef EXTENSION_H 25 | #define EXTENSION_H 26 | 27 | #include 28 | #include 29 | 30 | #include "extensiontheme.h" 31 | #include "extensionsearchengine.h" 32 | 33 | class Extension : public QObject 34 | { 35 | Q_OBJECT 36 | Q_PROPERTY(bool valid READ valid WRITE setValid NOTIFY validChanged) 37 | Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) 38 | Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged) 39 | Q_PROPERTY(QString description READ description WRITE setDescription NOTIFY descriptionChanged) 40 | Q_PROPERTY(QString summary READ summary WRITE setSummary NOTIFY summaryChanged) 41 | Q_PROPERTY(QString author READ author WRITE setAuthor NOTIFY authorChanged) 42 | Q_PROPERTY(QString email READ email WRITE setEmail NOTIFY emailChanged) 43 | 44 | friend class ExtensionParser; 45 | 46 | public: 47 | explicit Extension(QObject *parent = nullptr); 48 | 49 | bool load(QString filePath); 50 | 51 | bool valid() const { return m_valid; } 52 | void setValid(bool valid) { validChanged(m_valid = valid); } 53 | 54 | QString name() const { return m_name; } 55 | void setName(QString name) { nameChanged(m_name = name); } 56 | 57 | QString version() const { return m_version; } 58 | void setVersion(QString version) { versionChanged(m_version = version); } 59 | 60 | QString title() const { return m_title; } 61 | void setTitle(QString title) { titleChanged(m_title = title); } 62 | 63 | QString author() const { return m_author; } 64 | void setAuthor(QString author) { authorChanged(m_author = author); } 65 | 66 | QString summary() const { return m_summary; } 67 | void setSummary(QString summary) { summaryChanged(m_summary = summary); } 68 | 69 | QString description() const { return m_description; } 70 | void setDescription(QString description) { descriptionChanged(m_description = description); } 71 | 72 | QString email() const { return m_email; } 73 | void setEmail(QString email) { emailChanged(m_email = email); } 74 | 75 | QList themes() const { return m_extensionThemes; } 76 | QList searchEngines() const { return m_extensionSearchEngines; } 77 | 78 | signals: 79 | void validChanged(bool valid); 80 | void nameChanged(QString name); 81 | void versionChanged(QString version); 82 | void titleChanged(QString title); 83 | void authorChanged(QString author); 84 | void descriptionChanged(QString description); 85 | void summaryChanged(QString summary); 86 | void emailChanged(QString email); 87 | 88 | private: 89 | bool m_valid; 90 | 91 | QString m_name; 92 | QString m_version; 93 | QString m_title; 94 | QString m_author; 95 | QString m_description; 96 | QString m_summary; 97 | QString m_email; 98 | 99 | QList m_extensionThemes; 100 | QList m_extensionSearchEngines; 101 | }; 102 | 103 | #endif // EXTENSION_H 104 | -------------------------------------------------------------------------------- /src/core/extensions/extensionparser.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2017 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | #ifndef EXTENSIONPARSER_H 25 | #define EXTENSIONPARSER_H 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | #include 38 | #include 39 | 40 | #include "extension.h" 41 | #include "extensiontheme.h" 42 | #include "extensionsearchengine.h" 43 | 44 | using Type = QJsonValue::Type; 45 | 46 | enum ExtensionType { 47 | LBX, 48 | QRC 49 | }; 50 | 51 | class ExtensionParser : public QObject 52 | { 53 | Q_OBJECT 54 | public: 55 | explicit ExtensionParser(QObject *parent=nullptr); 56 | 57 | bool open(const QUrl url, ExtensionType type=ExtensionType::LBX); 58 | void close(); 59 | 60 | bool load(); 61 | 62 | Extension* extension() const { return m_extension; } 63 | void setExtension(Extension* extension) { extensionChanged(m_extension = extension); } 64 | 65 | QString errorString() const { return m_errorString; } 66 | bool hasError() const { return m_error; } 67 | 68 | signals: 69 | void extensionChanged(Extension* extension); 70 | 71 | private: // enum 72 | enum FieldStatus { 73 | Valid, 74 | NonExistent, 75 | WrongType, 76 | Empty 77 | }; 78 | 79 | private: // exceptions 80 | class FieldError : public QException 81 | { 82 | public: 83 | void raise() const { throw *this; } 84 | FieldError *clone() const { return new FieldError(*this); } 85 | }; 86 | 87 | class ResourceError : public QException 88 | { 89 | public: 90 | void raise() const { throw *this; } 91 | ResourceError *clone() const { return new ResourceError(*this); } 92 | }; 93 | 94 | class ParseError : public QException 95 | { 96 | public: 97 | void raise() const { throw *this; } 98 | ParseError *clone() const { return new ParseError(*this); } 99 | }; 100 | 101 | private: // methods 102 | QByteArray readResource(const QString resourceName); 103 | QString fromResourceName(QString resourceName); 104 | 105 | void loadTheme(const QString resourceName); 106 | void loadSearchEngine(const QString resourceName); 107 | 108 | void parseMeta(const QByteArray jsonData); 109 | void parseTheme(const QByteArray jsonData); 110 | void parseSearchEngine(const QByteArray jsonData); 111 | 112 | FieldStatus fieldStatus(QJsonObject object, QString fieldName, Type fieldType); 113 | void assertField(QJsonObject object, QString fieldName, Type fieldType); 114 | 115 | QString typeName(Type type); 116 | void error(QString errorString); 117 | 118 | private: // members 119 | QuaZip* m_zip; 120 | QuaZipFile* m_zipFile; 121 | 122 | Extension* m_extension; 123 | 124 | ExtensionType m_type; 125 | QUrl m_url; 126 | QString m_filePath; 127 | QString m_pureFileName; 128 | 129 | QString m_errorString; 130 | bool m_error; 131 | }; 132 | 133 | #endif // EXTENSIONPARSER_H 134 | -------------------------------------------------------------------------------- /src/ui/components/ThemeSelection.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2017 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | import QtQuick 2.7 25 | import QtQuick.Layouts 1.1 26 | import QtQuick.Controls 2.0 27 | import QtQuick.Controls.Material 2.0 28 | import Fluid.Controls 1.0 29 | import Fluid.Core 1.0 30 | 31 | Item { 32 | property string title: "Select theme" 33 | property string selectedName: "" 34 | 35 | signal selected(string name) 36 | 37 | implicitHeight: column.childrenRect.height 38 | 39 | Column { 40 | id: column 41 | 42 | width: parent.width 43 | spacing: Units.smallSpacing 44 | 45 | RowLayout { 46 | spacing: Units.largeSpacing 47 | width: parent.width 48 | 49 | SubheadingLabel { 50 | text: title 51 | } 52 | 53 | Item { Layout.fillWidth: true } // Spacer 54 | 55 | TextField { 56 | id: searchField 57 | selectByMouse: true 58 | placeholderText: "Search" 59 | } 60 | } 61 | 62 | Column { 63 | width: parent.width 64 | spacing: Units.smallSpacing 65 | visible: !Extensions.themesModel.get(selectedName).valid 66 | 67 | Label { 68 | width: parent.width 69 | wrapMode: Text.WordWrap 70 | text: "The selected theme %1 could not be found. ".arg('"' + selectedName + '"') 71 | color: Material.color(Material.Red) 72 | } 73 | 74 | Label { 75 | width: parent.width 76 | wrapMode: Text.WordWrap 77 | text: "Either this theme has been removed or there was a problem loading it." 78 | color: Material.color(Material.Red) 79 | } 80 | 81 | Label { 82 | width: parent.width 83 | wrapMode: Text.WordWrap 84 | text: "Select another theme below." 85 | color: Material.color(Material.Red) 86 | } 87 | } 88 | 89 | ListView { 90 | id: listView 91 | 92 | width: parent.width 93 | height: Math.min(256, childrenRect.height) 94 | clip: true 95 | 96 | ScrollBar.vertical: ScrollBar {} 97 | 98 | model: SortFilterProxyModel { 99 | sourceModel: Extensions.themesModel 100 | sortRoleName: "title" 101 | filterRoleName: "title" 102 | filterPattern: "*%1*".arg(searchField.text) 103 | filterPatternSyntax: SortFilterProxyModel.Wildcard 104 | filterCaseSensitivity: Qt.CaseInsensitive 105 | } 106 | 107 | delegate: ListItem { 108 | property bool isSelected: name === selectedName 109 | 110 | highlighted: isSelected 111 | width: listView.width 112 | text: title 113 | subText: summary 114 | iconName: isSelected ? "navigation/check" : "action/search" 115 | onClicked: { 116 | selected(selectedName = name); 117 | } 118 | } 119 | } 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /src/ui/tabview/TabController.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2016 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | import QtQuick 2.7 25 | import SlimeEngine 0.2 26 | import core 1.0 27 | import ".." 28 | 29 | QtObject { 30 | id: tabController 31 | property TabBar tabBar 32 | property TabContentView tabContentView 33 | property TabsModel tabsModel 34 | property WebProfile profile 35 | property int lastUID: 0 36 | property int webengine 37 | 38 | property Component tabPageComponent: Component { TabPage {} } 39 | property Component actionManagerComponent: Component { TabActionManager {} } 40 | 41 | property QtObject internal: QtObject { 42 | property Connections tabBarCloseConnections: Connections { 43 | target: tabBar 44 | onTabCloseRequested: { 45 | removeTab(uid); 46 | } 47 | } 48 | } 49 | 50 | signal newWindowRequested(var request) 51 | 52 | function openUrl(url, background, index) { 53 | addTab( 54 | TabType.fromUrl(url), { 55 | url: url, 56 | background: background 57 | }, 58 | index || -1 59 | ); 60 | } 61 | 62 | function openNewViewRequest(request) { 63 | addTab ( 64 | TabType.webview, { 65 | background: request.destination === NewViewRequest.NewViewInBackgroundTab, 66 | properties: { 67 | profile: profile, 68 | request: request 69 | } 70 | }, 71 | tabsModel.activeRow + 1 // Insert tab next to the current tab 72 | ); 73 | } 74 | 75 | function addTab(type, data, index) { 76 | // Register new unique id 77 | var uid = lastUID++; 78 | var page; 79 | 80 | if (!("properties" in data)) 81 | data["properties"] = {}; 82 | 83 | // Add tab model representation 84 | tabsModel.insert(uid, index || -1); 85 | 86 | // Create page 87 | page = tabPageComponent.createObject(tabContentView.container, { 88 | profile: profile, 89 | tab: tabsModel.byUID(uid), 90 | webengine: webengine 91 | }); 92 | 93 | // Load page 94 | page.load(type, data); 95 | 96 | // Create an action manager for this tab 97 | page.actionManager = actionManagerComponent.createObject(page, {}); 98 | page.actionManager.internal.tabController = tabController; 99 | page.actionManager.internal.uid = uid; 100 | // Register page to content view 101 | tabContentView.registerPage(uid, page); 102 | 103 | // Set the page active if wanted 104 | if (!data.background) { 105 | tabsModel.setActive(uid); 106 | } 107 | } 108 | 109 | function removeTab(uid) { 110 | // Remove model representation 111 | if (!tabsModel.remove(uid)) 112 | return false; 113 | // Unregister page 114 | tabContentView.unregisterPage(uid); 115 | return true; 116 | } 117 | 118 | function tabByUID(uid) { 119 | return tabsModel.byUID(uid); 120 | } 121 | 122 | function pageByUID(uid) { 123 | return tabContentView.pageByUID(uid); 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /src/ui/components/SearchEngineSelection.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2017 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | import QtQuick 2.7 25 | import QtQuick.Layouts 1.1 26 | import QtQuick.Controls 2.0 27 | import QtQuick.Controls.Material 2.0 28 | import Fluid.Controls 1.0 29 | import Fluid.Core 1.0 30 | 31 | Item { 32 | property string title: "Select search engine" 33 | property string selectedName: "" 34 | 35 | signal selected(string name) 36 | 37 | implicitHeight: column.childrenRect.height 38 | 39 | Column { 40 | id: column 41 | 42 | width: parent.width 43 | spacing: Units.smallSpacing 44 | 45 | RowLayout { 46 | spacing: Units.largeSpacing 47 | width: parent.width 48 | 49 | SubheadingLabel { 50 | text: title 51 | } 52 | 53 | Item { Layout.fillWidth: true } // Spacer 54 | 55 | TextField { 56 | id: searchField 57 | selectByMouse: true 58 | placeholderText: "Search" 59 | } 60 | } 61 | 62 | Column { 63 | width: parent.width 64 | spacing: Units.smallSpacing 65 | visible: !Extensions.searchEnginesModel.get(selectedName).valid 66 | 67 | Label { 68 | width: parent.width 69 | wrapMode: Text.WordWrap 70 | text: "The selected search engine %1 could not be found. ".arg('"' + selectedName + '"') 71 | color: Material.color(Material.Red) 72 | } 73 | 74 | Label { 75 | width: parent.width 76 | wrapMode: Text.WordWrap 77 | text: "Either this search engine has been removed or there was a problem loading it." 78 | color: Material.color(Material.Red) 79 | } 80 | 81 | Label { 82 | width: parent.width 83 | wrapMode: Text.WordWrap 84 | text: "Select another search engine below." 85 | color: Material.color(Material.Red) 86 | } 87 | } 88 | 89 | ListView { 90 | id: listView 91 | 92 | width: parent.width 93 | height: Math.min(256, childrenRect.height) 94 | clip: true 95 | 96 | ScrollBar.vertical: ScrollBar {} 97 | 98 | model: SortFilterProxyModel { 99 | sourceModel: Extensions.searchEnginesModel 100 | sortRoleName: "title" 101 | filterRoleName: "title" 102 | filterPattern: "*%1*".arg(searchField.text) 103 | filterPatternSyntax: SortFilterProxyModel.Wildcard 104 | filterCaseSensitivity: Qt.CaseInsensitive 105 | } 106 | 107 | delegate: ListItem { 108 | property bool isSelected: name === selectedName 109 | highlighted: isSelected 110 | width: listView.width 111 | text: title 112 | subText: summary 113 | iconName: isSelected ? "navigation/check" : "image/color_lens" 114 | onClicked: { 115 | selected(selectedName = name); 116 | } 117 | } 118 | } 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /src/core/extensions/extensionsearchenginesmodel.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2017 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | #include "extensionsearchenginesmodel.h" 25 | 26 | ExtensionSearchEnginesModel::ExtensionSearchEnginesModel(QObject *parent) 27 | : QAbstractListModel(parent) 28 | { 29 | m_invalidSearchEngine = new ExtensionSearchEngine(this); 30 | m_invalidSearchEngine->setValid(false); 31 | } 32 | 33 | int ExtensionSearchEnginesModel::rowCount(const QModelIndex &parent) const 34 | { 35 | Q_UNUSED(parent) 36 | return m_searchEngines.length(); 37 | } 38 | 39 | QHash ExtensionSearchEnginesModel::roleNames() const 40 | { 41 | QHash roles; 42 | roles[ExtensionName] = "extensionName"; 43 | roles[Name] = "name"; 44 | roles[Title] = "title"; 45 | roles[Summary] = "summary"; 46 | roles[Description] = "description"; 47 | return roles; 48 | } 49 | 50 | QVariant ExtensionSearchEnginesModel::data(const QModelIndex &index, int role) const 51 | { 52 | ExtensionSearchEngine* searchEngine = get(index.row()); 53 | switch (role) { 54 | case ExtensionName: 55 | return searchEngine->extensionName(); 56 | case Name: 57 | return searchEngine->name(); 58 | case Title: 59 | return searchEngine->title(); 60 | case Summary: 61 | return searchEngine->summary(); 62 | case Description: 63 | return searchEngine->description(); 64 | } 65 | return QVariant(); 66 | } 67 | 68 | int ExtensionSearchEnginesModel::count() const 69 | { 70 | return m_searchEngines.length(); 71 | } 72 | 73 | void ExtensionSearchEnginesModel::add(ExtensionSearchEngine *searchEngine) 74 | { 75 | beginInsertRows(QModelIndex(), rowCount(), rowCount()); 76 | m_searchEngines.append(searchEngine); 77 | countChanged(count()); 78 | endInsertRows(); 79 | } 80 | 81 | void ExtensionSearchEnginesModel::remove(const int row) 82 | { 83 | beginRemoveRows(QModelIndex(), row, row); 84 | ExtensionSearchEngine* searchEngine = m_searchEngines.at(row); 85 | m_searchEngines.removeAt(row); 86 | searchEngine->deleteLater(); 87 | countChanged(count()); 88 | endRemoveRows(); 89 | } 90 | 91 | void ExtensionSearchEnginesModel::remove(ExtensionSearchEngine *searchEngine) 92 | { 93 | int index = m_searchEngines.indexOf(searchEngine); 94 | if (index != -1) 95 | remove(index); 96 | } 97 | 98 | void ExtensionSearchEnginesModel::removeByExtensionName(const QString extensionName) 99 | { 100 | for (ExtensionSearchEngine* searchEngine : m_searchEngines) { 101 | if (searchEngine->extensionName() == extensionName) { 102 | remove(searchEngine); 103 | } 104 | } 105 | } 106 | 107 | ExtensionSearchEngine *ExtensionSearchEnginesModel::get(const int row) const 108 | { 109 | if (row < 0 || row >= count()) { 110 | return m_invalidSearchEngine; 111 | } 112 | return m_searchEngines.at(row); 113 | } 114 | 115 | ExtensionSearchEngine *ExtensionSearchEnginesModel::get(const QString name) const 116 | { 117 | for (ExtensionSearchEngine* searchEngine : m_searchEngines) { 118 | if (searchEngine->name() == name) 119 | return searchEngine; 120 | } 121 | return m_invalidSearchEngine; 122 | } 123 | -------------------------------------------------------------------------------- /src/core/extensions/extensiontheme.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2017 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | #ifndef EXTENSIONTHEME_H 25 | #define EXTENSIONTHEME_H 26 | 27 | #include 28 | #include 29 | 30 | #include "extensionelement.h" 31 | 32 | class ExtensionTheme : public ExtensionElement 33 | { 34 | Q_OBJECT 35 | Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged) 36 | Q_PROPERTY(QString summary READ summary WRITE setSummary NOTIFY summaryChanged) 37 | Q_PROPERTY(QString description READ description WRITE setDescription NOTIFY descriptionChanged) 38 | Q_PROPERTY(bool dark READ dark WRITE setDark NOTIFY darkChanged) 39 | Q_PROPERTY(bool adaptWebsiteTheme READ adaptWebsiteTheme WRITE setAdaptWebsiteTheme NOTIFY adaptWebsiteThemeChanged) 40 | Q_PROPERTY(QColor accent READ accent WRITE setAccent NOTIFY accentChanged) 41 | Q_PROPERTY(QColor primary READ primary WRITE setPrimary NOTIFY primaryChanged) 42 | Q_PROPERTY(QColor foreground READ foreground WRITE setForeground NOTIFY foregroundChanged) 43 | Q_PROPERTY(QColor background READ background WRITE setBackground NOTIFY backgroundChanged) 44 | public: 45 | explicit ExtensionTheme(QObject *parent = nullptr); 46 | 47 | ExtensionTheme* clone(QObject* parent = nullptr); 48 | 49 | QString title() const { return m_title; } 50 | void setTitle(QString title) { titleChanged(m_title = title); } 51 | 52 | QString summary() const { return m_summary; } 53 | void setSummary(QString summary) { summaryChanged(m_summary = summary); } 54 | 55 | QString description() const { return m_description; } 56 | void setDescription(QString description) { descriptionChanged(m_description = description); } 57 | 58 | bool dark() const { return m_dark; } 59 | void setDark(bool dark) { darkChanged(m_dark = dark); } 60 | 61 | bool adaptWebsiteTheme() const { return m_adaptWebsiteTheme; } 62 | void setAdaptWebsiteTheme(bool adaptWebsiteTheme) { adaptWebsiteThemeChanged(m_adaptWebsiteTheme = adaptWebsiteTheme); } 63 | 64 | QColor accent() const { return m_accent; } 65 | void setAccent(QColor accent) { accentChanged(m_accent = accent); } 66 | 67 | QColor primary() const { return m_primary; } 68 | void setPrimary(QColor primary) { primaryChanged(m_primary = primary); } 69 | 70 | QColor foreground() const { return m_foreground; } 71 | void setForeground(QColor foreground) { foregroundChanged(m_foreground = foreground); } 72 | 73 | QColor background() const { return m_background; } 74 | void setBackground(QColor background) { backgroundChanged(m_background = background); } 75 | 76 | signals: 77 | void nameChanged(QString name); 78 | void titleChanged(QString title); 79 | void summaryChanged(QString summary); 80 | void descriptionChanged(QString description); 81 | 82 | void darkChanged(bool dark); 83 | void adaptWebsiteThemeChanged(bool adaptWebsiteTheme); 84 | void accentChanged(QColor accent); 85 | void primaryChanged(QColor primary); 86 | void foregroundChanged(QColor foreground); 87 | void backgroundChanged(QColor background); 88 | 89 | private: 90 | QString m_title; 91 | QString m_summary; 92 | QString m_description; 93 | 94 | bool m_dark; 95 | bool m_adaptWebsiteTheme; 96 | QColor m_accent; 97 | QColor m_primary; 98 | QColor m_foreground; 99 | QColor m_background; 100 | }; 101 | 102 | #endif // EXTENSIONTHEME_H 103 | -------------------------------------------------------------------------------- /src/core/extensions/extensionthemesmodel.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2017 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | #include "extensionthemesmodel.h" 25 | 26 | ExtensionThemesModel::ExtensionThemesModel(QObject *parent) 27 | : QAbstractListModel(parent) 28 | { 29 | m_invalidTheme = new ExtensionTheme(this); 30 | m_invalidTheme->setValid(false); 31 | } 32 | 33 | int ExtensionThemesModel::rowCount(const QModelIndex &parent) const 34 | { 35 | Q_UNUSED(parent); 36 | return m_themes.length(); 37 | } 38 | 39 | QHash ExtensionThemesModel::roleNames() const 40 | { 41 | QHash roles; 42 | roles[Name] = "name"; 43 | roles[ExtensionName] = "extensionName"; 44 | roles[Title] = "title"; 45 | roles[Summary] = "summary"; 46 | roles[Description] = "description"; 47 | roles[Accent] = "accent"; 48 | roles[Primary] = "primary"; 49 | roles[Foreground] = "foreground"; 50 | roles[Background] = "background"; 51 | return roles; 52 | } 53 | 54 | QVariant ExtensionThemesModel::data(const QModelIndex &index, int role) const 55 | { 56 | ExtensionTheme* theme = get(index.row()); 57 | switch (role) { 58 | case Name: 59 | return QVariant(theme->name()); 60 | case ExtensionName: 61 | return QVariant(theme->extensionName()); 62 | case Title: 63 | return QVariant(theme->title()); 64 | case Summary: 65 | return QVariant(theme->summary()); 66 | case Description: 67 | return QVariant(theme->description()); 68 | case Accent: 69 | return QVariant(theme->accent()); 70 | case Primary: 71 | return QVariant(theme->primary()); 72 | case Foreground: 73 | return QVariant(theme->foreground()); 74 | case Background: 75 | return QVariant(theme->background()); 76 | } 77 | return QVariant(); 78 | } 79 | 80 | int ExtensionThemesModel::count() const 81 | { 82 | return m_themes.length(); 83 | } 84 | 85 | void ExtensionThemesModel::add(ExtensionTheme *theme) 86 | { 87 | beginInsertRows(QModelIndex(), rowCount(), rowCount()); 88 | m_themes.append(theme); 89 | countChanged(count()); 90 | endInsertRows(); 91 | } 92 | 93 | void ExtensionThemesModel::remove(const int row) 94 | { 95 | beginRemoveRows(QModelIndex(), row, row); 96 | ExtensionTheme* theme = m_themes.at(row); 97 | m_themes.removeAt(row); 98 | theme->deleteLater(); 99 | countChanged(count()); 100 | endRemoveRows(); 101 | } 102 | 103 | void ExtensionThemesModel::remove(ExtensionTheme* theme) 104 | { 105 | int row = m_themes.indexOf(theme); 106 | if (row != -1) 107 | remove(row); 108 | } 109 | 110 | void ExtensionThemesModel::removeByExtensionName(const QString extensionName) 111 | { 112 | for (ExtensionTheme* theme : m_themes) { 113 | if (theme->extensionName() == extensionName) { 114 | remove(theme); 115 | } 116 | } 117 | } 118 | 119 | ExtensionTheme *ExtensionThemesModel::get(const int row) const 120 | { 121 | if (row < 0 || row >= count()) { 122 | return m_invalidTheme; 123 | } 124 | return m_themes.at(row); 125 | } 126 | 127 | ExtensionTheme *ExtensionThemesModel::get(const QString name) const 128 | { 129 | for (ExtensionTheme* theme : m_themes) { 130 | if (theme->name() == name) 131 | return theme; 132 | } 133 | return m_invalidTheme; 134 | } 135 | -------------------------------------------------------------------------------- /src/ui/tabview/TabPage.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2017 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | import QtQuick 2.7 25 | import ".." 26 | 27 | Item { 28 | id: tabPage 29 | 30 | property var tab 31 | property var actionManager 32 | property var profile 33 | property int webengine 34 | property url previousUrl 35 | property bool loading: false 36 | 37 | property Component settingsContentComponent: Component { 38 | SettingsContent { 39 | tab: tabPage.tab 40 | actionManager: tabPage.actionManager 41 | } 42 | } 43 | 44 | property Component extensionsContentComponent: Component { 45 | ExtensionsContent { 46 | tab: tabPage.tab 47 | actionManager: tabPage.actionManager 48 | } 49 | } 50 | 51 | property Component aboutContentComponent: Component { 52 | AboutContent { 53 | tab: tabPage.tab 54 | actionManager: tabPage.actionManager 55 | } 56 | } 57 | 58 | property Component webContentComponent: Component { 59 | WebContent { 60 | tab: tabPage.tab 61 | actionManager: tabPage.actionManager 62 | } 63 | } 64 | 65 | property var contentItem 66 | property int tabType 67 | 68 | function openUrl(url) { 69 | load(TabType.fromUrl(url), { 70 | url: url, 71 | }); 72 | } 73 | 74 | function load(type, data) { 75 | if (loading) 76 | return false; 77 | loading = true; 78 | 79 | var newContent; 80 | 81 | // Destroy old content if necessary 82 | if (contentItem) 83 | contentItem.destroy(); 84 | 85 | // Finalize properties 86 | if (!("properties" in data)) 87 | data["properties"] = {}; 88 | 89 | data.properties["anchors.fill"] = contentContainer; 90 | data.properties["webengine"] = webengine; 91 | data.properties["profile"] = profile; 92 | data.properties["url"] = data.url; 93 | 94 | // Create content item 95 | switch(type) { 96 | case TabType.webview: 97 | newContent = webContentComponent.createObject( 98 | contentContainer, 99 | data.properties 100 | ); 101 | break; 102 | case TabType.settings: 103 | newContent = settingsContentComponent.createObject( 104 | contentContainer, 105 | data.properties 106 | ); 107 | break; 108 | case TabType.extensions: 109 | newContent = extensionsContentComponent.createObject( 110 | contentContainer, 111 | data.properties 112 | ); 113 | break; 114 | case TabType.about: 115 | newContent = aboutContentComponent.createObject( 116 | contentContainer, 117 | data.properties 118 | ); 119 | break; 120 | } 121 | tabType = type; 122 | contentItem = newContent; 123 | loading = false; 124 | return true; 125 | } 126 | 127 | Connections { 128 | target: tab 129 | onUrlChanged: { 130 | if (url !== previousUrl) { 131 | var newType = TabType.fromUrl(url); 132 | if (newType !== tabType) { 133 | load(newType, {url: url}); 134 | } 135 | previousUrl = url; 136 | } 137 | } 138 | } 139 | 140 | Item { 141 | id: contentContainer 142 | anchors.fill: parent 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /src/3rdparty/regex-weburl/regex-weburl.js: -------------------------------------------------------------------------------- 1 | 2 | // 3 | // Regular Expression for URL validation 4 | // 5 | // Author: Diego Perini 6 | // Updated: 2010/12/05 7 | // License: MIT 8 | // 9 | // Copyright (c) 2010-2013 Diego Perini (http://www.iport.it) 10 | // 11 | // Permission is hereby granted, free of charge, to any person 12 | // obtaining a copy of this software and associated documentation 13 | // files (the "Software"), to deal in the Software without 14 | // restriction, including without limitation the rights to use, 15 | // copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | // copies of the Software, and to permit persons to whom the 17 | // Software is furnished to do so, subject to the following 18 | // conditions: 19 | // 20 | // The above copyright notice and this permission notice shall be 21 | // included in all copies or substantial portions of the Software. 22 | // 23 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 25 | // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 27 | // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 28 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 29 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 30 | // OTHER DEALINGS IN THE SOFTWARE. 31 | // 32 | // the regular expression composed & commented 33 | // could be easily tweaked for RFC compliance, 34 | // it was expressly modified to fit & satisfy 35 | // these test for an URL shortener: 36 | // 37 | // http://mathiasbynens.be/demo/url-regex 38 | // 39 | // Notes on possible differences from a standard/generic validation: 40 | // 41 | // - utf-8 char class take in consideration the full Unicode range 42 | // - TLDs have been made mandatory so single names like "localhost" fails 43 | // - protocols have been restricted to ftp, http and https only as requested 44 | // 45 | // Changes: 46 | // 47 | // - IP address dotted notation validation, range: 1.0.0.0 - 223.255.255.255 48 | // first and last IP address of each class is considered invalid 49 | // (since they are broadcast/network addresses) 50 | // 51 | // - Added exclusion of private, reserved and/or local networks ranges 52 | // 53 | // - Made starting path slash optional (http://example.com?foo=bar) 54 | // 55 | // - Allow a dot (.) at the end of hostnames (http://example.com.) 56 | // 57 | // Compressed one-line versions: 58 | // 59 | // Javascript version 60 | // 61 | // /^(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,}))\.?)(?::\d{2,5})?(?:[/?#]\S*)?$/i 62 | // 63 | // PHP version 64 | // 65 | // _^(?:(?:https?|ftp)://)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\x{00a1}-\x{ffff}0-9]-*)*[a-z\x{00a1}-\x{ffff}0-9]+)(?:\.(?:[a-z\x{00a1}-\x{ffff}0-9]-*)*[a-z\x{00a1}-\x{ffff}0-9]+)*(?:\.(?:[a-z\x{00a1}-\x{ffff}]{2,}))\.?)(?::\d{2,5})?(?:[/?#]\S*)?$_iuS 66 | // 67 | var re_weburl = new RegExp( 68 | "^" + 69 | // protocol identifier 70 | "(?:(?:https?|ftp)://)" + 71 | // user:pass authentication 72 | "(?:\\S+(?::\\S*)?@)?" + 73 | "(?:" + 74 | // IP address exclusion 75 | // private & local networks 76 | "(?!(?:10|127)(?:\\.\\d{1,3}){3})" + 77 | "(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})" + 78 | "(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})" + 79 | // IP address dotted notation octets 80 | // excludes loopback network 0.0.0.0 81 | // excludes reserved space >= 224.0.0.0 82 | // excludes network & broacast addresses 83 | // (first & last IP address of each class) 84 | "(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])" + 85 | "(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}" + 86 | "(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))" + 87 | "|" + 88 | // host name 89 | "(?:(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)" + 90 | // domain name 91 | "(?:\\.(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)*" + 92 | // TLD identifier 93 | "(?:\\.(?:[a-z\\u00a1-\\uffff]{2,}))" + 94 | // TLD may end with dot 95 | "\\.?" + 96 | ")" + 97 | // port number 98 | "(?::\\d{2,5})?" + 99 | // resource path 100 | "(?:[/?#]\\S*)?" + 101 | "$", "i" 102 | ); 103 | -------------------------------------------------------------------------------- /src/core/models/tab.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2016 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | #ifndef TAB_H 25 | #define TAB_H 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | class Tab : public QObject 32 | { 33 | Q_OBJECT 34 | Q_PROPERTY(unsigned int uid READ uid WRITE setUid NOTIFY uidChanged) 35 | Q_PROPERTY(QUrl url READ url WRITE setUrl NOTIFY urlChanged) 36 | Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged) 37 | Q_PROPERTY(QUrl iconUrl READ iconUrl WRITE setIconUrl NOTIFY iconUrlChanged) 38 | Q_PROPERTY(QColor iconColor READ iconColor WRITE setIconColor NOTIFY iconColorChanged) 39 | Q_PROPERTY(bool adaptIconColor READ adaptIconColor WRITE setAdaptIconColor NOTIFY adaptIconColorChanged) 40 | Q_PROPERTY(bool canGoBack READ canGoBack WRITE setCanGoBack NOTIFY canGoBackChanged) 41 | Q_PROPERTY(bool canGoForward READ canGoForward WRITE setCanGoForward NOTIFY canGoForwardChanged) 42 | Q_PROPERTY(bool canReload READ canReload WRITE setCanReload NOTIFY canReloadChanged) 43 | Q_PROPERTY(bool loading READ loading WRITE setLoading NOTIFY loadingChanged) 44 | Q_PROPERTY(unsigned int loadProgress READ loadProgress WRITE setLoadProgress NOTIFY loadProgressChanged) 45 | Q_PROPERTY(bool valid READ valid NOTIFY validChanged) 46 | Q_PROPERTY(bool hasThemeColor READ hasThemeColor WRITE setHasThemeColor NOTIFY hasThemeColorChanged) 47 | Q_PROPERTY(QColor themeColor READ themeColor WRITE setThemeColor NOTIFY themeColorChanged) 48 | public: 49 | explicit Tab(QObject *parent = nullptr, bool valid = true); 50 | 51 | unsigned int uid() const; 52 | void setUid(int uid); 53 | 54 | QUrl url() const; 55 | void setUrl(QUrl url); 56 | 57 | QString title() const; 58 | void setTitle(QString title); 59 | 60 | QUrl iconUrl() const; 61 | void setIconUrl(QUrl iconUrl); 62 | 63 | QColor iconColor() const; 64 | void setIconColor(QColor iconColor); 65 | 66 | bool adaptIconColor() const; 67 | void setAdaptIconColor(bool adaptIconColor); 68 | 69 | bool canGoBack() const; 70 | void setCanGoBack(bool canGoBack); 71 | 72 | bool canGoForward() const; 73 | void setCanGoForward(bool canGoForward); 74 | 75 | bool canReload() const; 76 | void setCanReload(bool canReload); 77 | 78 | bool loading() const; 79 | void setLoading(bool loading); 80 | 81 | unsigned int loadProgress() const; 82 | void setLoadProgress(unsigned int loadProgress); 83 | 84 | bool valid() const; 85 | 86 | bool hasThemeColor() const; 87 | void setHasThemeColor(bool hasThemeColor); 88 | 89 | QColor themeColor() const; 90 | void setThemeColor(QColor themeColor); 91 | 92 | bool invalid() const; 93 | 94 | signals: 95 | void uidChanged(unsigned int uid); 96 | void urlChanged(QUrl url); 97 | void titleChanged(QString title); 98 | void iconUrlChanged(QUrl iconUrl); 99 | void iconColorChanged(QColor iconColor); 100 | void adaptIconColorChanged(bool adaptIconColor); 101 | void canGoBackChanged(bool canGoBack); 102 | void canGoForwardChanged(bool canGoForward); 103 | void canReloadChanged(bool canReload); 104 | void validChanged(bool valid); 105 | void loadingChanged(bool loading); 106 | void loadProgressChanged(unsigned int loadProgress); 107 | void hasThemeColorChanged(bool hasThemeColor); 108 | void themeColorChanged(QColor themeColor); 109 | 110 | void goBack(); 111 | void goForward(); 112 | void reload(); 113 | void stop(); 114 | void findText(QString text, bool backwards, bool caseSensitive); 115 | 116 | public slots: 117 | 118 | private: 119 | unsigned int m_uid; 120 | QUrl m_url; 121 | QString m_title; 122 | QUrl m_iconUrl; 123 | QColor m_iconColor; 124 | bool m_adaptIconColor; 125 | bool m_canGoBack; 126 | bool m_canGoForward; 127 | bool m_canReload; 128 | bool m_loading; 129 | int m_loadProgress; 130 | bool m_hasThemeColor; 131 | QColor m_themeColor; 132 | 133 | bool m_valid; 134 | }; 135 | 136 | #endif // TAB_H 137 | -------------------------------------------------------------------------------- /src/core/utils/searchprovider.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2017 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | #include 25 | 26 | #include "searchprovider.h" 27 | 28 | SearchProvider::SearchProvider(QObject *parent) 29 | : QObject(parent) 30 | { 31 | m_defaultSearchEngine = "default.duckduckgo"; 32 | m_reDynamicValue = QRegularExpression(R"(\$\(\s?([A-Za-z_.]+)\s?\))"); 33 | } 34 | 35 | QString SearchProvider::searchUrl(QString query, QString engine, ExtensionTheme* theme) const 36 | { 37 | return url(ExtensionSearchEngineParameter::Search, query, engine, theme); 38 | } 39 | 40 | QString SearchProvider::homepage(QString engine, ExtensionTheme *theme) const 41 | { 42 | return url(ExtensionSearchEngineParameter::Homepage, "", engine, theme); 43 | } 44 | 45 | QString SearchProvider::url(ExtensionSearchEngineParameter::SearchContext context, QString query, QString engine, ExtensionTheme *theme) const 46 | { 47 | ExtensionSearchEngine* searchEngine = m_model->get(engine); 48 | if (!searchEngine->valid()) { 49 | qWarning() << "Search engine" << engine << "was requested but could not not be found."; 50 | qWarning() << "Falling back to default search engine" << m_defaultSearchEngine << "..."; 51 | searchEngine = m_model->get(m_defaultSearchEngine); 52 | } 53 | QList* params = searchEngine->parameters(); 54 | QString urlString; 55 | if (context == ExtensionSearchEngineParameter::Search) { 56 | urlString = searchEngine->urlBaseSearch(); 57 | } else if (context == ExtensionSearchEngineParameter::Homepage) { 58 | urlString = searchEngine->urlBaseHomepage(); 59 | } 60 | QString getString; 61 | QString hashbangString; 62 | bool firstGet = true; 63 | bool uniqueHashbang = true; 64 | for (int i=0; icount(); i++) { 65 | ExtensionSearchEngineParameter* param = params->at(i); 66 | if (param->context() & context) { 67 | ExtensionSearchEngineParameter::Type type = param->type(); 68 | if (type == ExtensionSearchEngineParameter::Get) { 69 | QString name = param->name(); 70 | QString value = param->value(); 71 | QString paramString; 72 | if (firstGet) 73 | paramString += QString('?') + name + '='; 74 | else 75 | paramString += QString('&') + name + '='; 76 | paramString.append(dynamicValue(value, query, theme)); 77 | firstGet = false; 78 | getString.append(paramString); 79 | } else if (type == ExtensionSearchEngineParameter::Hashbang) { 80 | if (uniqueHashbang) { // Only allow one hashbang per context 81 | QString value = param->value(); 82 | hashbangString = "#!"; 83 | hashbangString.append(dynamicValue(value, query, theme)); 84 | uniqueHashbang = false; 85 | } 86 | } 87 | } 88 | } 89 | urlString.append(getString + hashbangString); 90 | return urlString; 91 | } 92 | 93 | QString SearchProvider::dynamicValue(QString value, QString query, ExtensionTheme* theme) const 94 | { 95 | QRegularExpressionMatchIterator matchIterator = m_reDynamicValue.globalMatch(value); 96 | int offset = 0; 97 | while (matchIterator.hasNext()) { 98 | QRegularExpressionMatch dynamicValueMatch = matchIterator.next(); 99 | if (dynamicValueMatch.hasMatch()) { 100 | QString fieldName = dynamicValueMatch.captured(1); 101 | QString replaceValue; 102 | if (fieldName == "search.query") { 103 | replaceValue = query; 104 | } else if (fieldName == "theme.background") { 105 | replaceValue = theme->background().name().replace("#", "%23"); 106 | } 107 | value.replace(dynamicValueMatch.capturedStart() + offset, dynamicValueMatch.capturedLength(), replaceValue); 108 | offset += (replaceValue.length() - dynamicValueMatch.capturedLength()); 109 | } 110 | } 111 | return value; 112 | } 113 | -------------------------------------------------------------------------------- /src/ui/Main.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2016 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | import QtQuick 2.7 25 | import SlimeEngine 0.2 26 | import core 1.0 27 | import "." 28 | 29 | QtObject { 30 | id: root 31 | 32 | property int webengine 33 | 34 | property WebProfile defaultProfile 35 | property WebProfile incognitoProfile 36 | 37 | property DownloadsModel downloadsModel: DownloadsModel {} 38 | 39 | property Component browserWindowComponent: Component { 40 | BrowserWindow { 41 | profile: root.defaultProfile 42 | downloadsModel: root.downloadsModel 43 | } 44 | } 45 | 46 | property Component downloadWatcherComponent: Component { 47 | Item { 48 | id: downloadWatcher 49 | property var engineDownload 50 | property var downloadModelItem 51 | 52 | Connections { 53 | target: engineDownload 54 | onFinished: { 55 | console.log("Download finished") 56 | downloadWatcher.downloadModelItem.finished = true; 57 | } 58 | onFailed: { 59 | console.log("Download failed"); 60 | } 61 | } 62 | 63 | Connections { 64 | target: downloadModelItem 65 | onCancel: { 66 | engineDownload.cancel(); 67 | } 68 | } 69 | 70 | Binding { 71 | target: downloadModelItem 72 | property: "progress" 73 | value: engineDownload.progress 74 | } 75 | 76 | Binding { 77 | target: downloadModelItem 78 | property: "path" 79 | value: engineDownload.path 80 | } 81 | 82 | Binding { 83 | target: downloadModelItem 84 | property: "mimeType" 85 | value: engineDownload.mimeType 86 | } 87 | } 88 | } 89 | 90 | property Component webProfileComponent: Component { 91 | WebProfile { 92 | engine: webengine 93 | onDownloadRequested: { 94 | // Accept download request, returns SlimeEngine Download item 95 | var engineItem = request.accept(); 96 | // Create model representation 97 | var modelItem = downloadsModel.add(); 98 | // Create download watcher 99 | var watcher = downloadWatcherComponent.createObject(null, { 100 | engineDownload: engineItem, 101 | downloadModelItem: modelItem 102 | }); 103 | } 104 | } 105 | } 106 | 107 | property Binding secondaryStartTimeBinding: Binding { 108 | target: SecondaryThemeTimer 109 | property: "startTime" 110 | value: Settings.themeConfig.secondaryStartTime 111 | } 112 | 113 | property Binding secondaryEndTimeBinding: Binding { 114 | target: SecondaryThemeTimer 115 | property: "endTime" 116 | value: Settings.themeConfig.secondaryEndTime 117 | } 118 | 119 | property Binding currentThemeBinding: Binding { 120 | target: Theme 121 | property: "name" 122 | value: Settings.themeConfig.secondaryEnabled && SecondaryThemeTimer.isActiveTime 123 | ? Settings.themeConfig.secondary 124 | : Settings.themeConfig.primary 125 | } 126 | 127 | property Binding incognitoThemeBinding: Binding { 128 | target: IncognitoTheme 129 | property: "name" 130 | value: Settings.themeConfig.incognito 131 | } 132 | 133 | function openWindowRequest(request) { 134 | var window = newWindow(false, false); 135 | window.openRequest(request); 136 | window.showNormal(); 137 | } 138 | 139 | function newWindow(incognito, openStartUrl) { 140 | var properties = {root: root} 141 | if (incognito) 142 | properties["profile"] = incognitoProfile; 143 | properties["openStartUrl"] = openStartUrl; 144 | var window = browserWindowComponent.createObject(root, properties); 145 | return window; 146 | } 147 | 148 | function newIncognitoWindow() { 149 | return newWindow(true); 150 | } 151 | 152 | function load() { 153 | // Create the default profile after the webengine to use has been decided on the C++ side 154 | defaultProfile = webProfileComponent.createObject(null, {}); 155 | // Create an incognito profile 156 | incognitoProfile = webProfileComponent.createObject(null, {incognito: true}); 157 | // Update dark theme timer 158 | SecondaryThemeTimer.update(); 159 | // Create the first window and show it 160 | newWindow().showNormal(); 161 | } 162 | 163 | Component.onDestruction: { 164 | if (Settings.dirty) { 165 | console.log("Saving settings ..."); 166 | Settings.save(); 167 | } 168 | } 169 | } 170 | -------------------------------------------------------------------------------- /src/ui/omnibox/Omnibox.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2017 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | import QtQuick 2.7 25 | import QtQuick.Layouts 1.1 26 | import QtQuick.Controls 2.0 27 | import QtQuick.Controls.Material 2.0 28 | import Fluid.Controls 1.0 29 | import Fluid.Core 1.0 30 | import Fluid.Material 1.0 31 | import dperini.regexweburl 1.0 32 | import core 1.0 33 | import ".." 34 | 35 | Item { 36 | id: omnibox 37 | property TabController tabController 38 | property TabsModel tabsModel 39 | property string searchEngine 40 | property ExtensionTheme currentTheme 41 | property color selectionColor 42 | property alias editingUrl: showUrlField.editActive 43 | 44 | function focusUrlField() { 45 | showUrlField.forceActiveFocus(); 46 | textField.selectAll(); 47 | } 48 | 49 | implicitHeight: 40 50 | implicitWidth: 256 51 | 52 | 53 | Rectangle { 54 | id: container 55 | anchors.fill: parent 56 | 57 | radius: 2 58 | color: Utils.lightDark(Material.background, "#eeeeee", "white") 59 | 60 | RowLayout { 61 | anchors { 62 | fill: parent 63 | leftMargin: Units.smallSpacing 64 | rightMargin: Units.smallSpacing 65 | } 66 | 67 | TextField { 68 | id: showUrlField 69 | 70 | property bool editActive: false 71 | 72 | Layout.fillHeight: true 73 | Layout.fillWidth: true 74 | 75 | Material.foreground: "#212121" 76 | 77 | bottomPadding: Units.smallSpacing 78 | 79 | background: Item {} 80 | font.pixelSize: 14 81 | readOnly: true 82 | 83 | onActiveFocusChanged: { 84 | if (activeFocus) { 85 | editActive = true; 86 | textField.forceActiveFocus(); 87 | textField.selectAll(); 88 | } 89 | } 90 | 91 | TextField { 92 | id: textField 93 | 94 | anchors.fill: parent 95 | visible: showUrlField.editActive 96 | 97 | selectionColor: omnibox.selectionColor 98 | selectByMouse: true 99 | bottomPadding: Units.smallSpacing 100 | background: Rectangle { color: container.color } 101 | font.pixelSize: 14 102 | 103 | onAccepted: { 104 | var url = UrlUtils.validUrl(text, searchEngine, currentTheme); 105 | if (!tabsModel.active.valid) { 106 | tabController.openUrl(url); 107 | } 108 | else { 109 | var reload = (tabsModel.active.url == url); 110 | tabsModel.active.url = url; 111 | if (reload) 112 | tabsModel.active.reload(); 113 | } 114 | showUrlField.editActive = false; 115 | } 116 | 117 | onActiveFocusChanged: { 118 | if (!activeFocus) { 119 | showUrlField.editActive = false; 120 | } 121 | } 122 | } 123 | } 124 | } 125 | 126 | Rectangle { 127 | visible: tabsModel.active.valid && width < parent.width 128 | anchors { 129 | bottom: parent.bottom 130 | left: parent.left 131 | } 132 | 133 | height: 2 134 | width: parent.width * (tabsModel.active.loadProgress / 100) 135 | color: Material.accent 136 | 137 | Behavior on width { 138 | enabled: tabsModel.active.loading 139 | NumberAnimation { 140 | duration: 200 141 | easing.type: Easing.InOutQuad 142 | } 143 | } 144 | } 145 | 146 | Binding { 147 | when: tabsModel.active.valid 148 | target: showUrlField 149 | property: "text" 150 | value: tabsModel.active.url 151 | } 152 | 153 | Binding { 154 | when: !showUrlField.editActive 155 | target: textField 156 | property: "text" 157 | value: tabsModel.active.url 158 | } 159 | 160 | Binding { 161 | when: tabsModel.empty 162 | target: showUrlField 163 | property: "text" 164 | value: "" 165 | } 166 | 167 | Binding { 168 | when: tabsModel.empty 169 | target: textField 170 | property: "text" 171 | value: "" 172 | } 173 | 174 | Connections { 175 | enabled: tabsModel.active.valid 176 | target: tabsModel 177 | onActiveChanged: { 178 | showUrlField.editActive = false; 179 | } 180 | } 181 | 182 | Behavior on color { 183 | ColorAnimation { duration: 100 } 184 | } 185 | } 186 | } 187 | -------------------------------------------------------------------------------- /src/ui/window/ShortcutManager.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2017 Ivan Fateev 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | import QtQuick 2.7 25 | import core 1.0 26 | import ".." 27 | 28 | Item { 29 | id: shortcutManager 30 | 31 | property var root 32 | property TabsModel tabsModel 33 | property Toolbar toolbar 34 | property TabBar tabBar 35 | property SearchOverlay searchOverlay 36 | 37 | function setActiveTabByIndex(idx) { 38 | if (idx < 0 || idx >= tabsModel.count) { 39 | return; 40 | } 41 | 42 | tabsModel.setActive(tabsModel.get(idx)); 43 | } 44 | 45 | Shortcut { 46 | autoRepeat: false 47 | sequence: StandardKey.Back 48 | onActivated: { 49 | tabsModel.active.goBack(); 50 | } 51 | } 52 | 53 | Shortcut { 54 | autoRepeat: false 55 | sequence: StandardKey.Forward 56 | onActivated: { 57 | tabsModel.active.goForward(); 58 | } 59 | } 60 | 61 | Shortcut { 62 | autoRepeat: false 63 | sequence: StandardKey.Close 64 | onActivated: { 65 | tabBar.tabCloseRequested(tabsModel.active.uid); 66 | } 67 | } 68 | 69 | Shortcut { 70 | autoRepeat: false 71 | sequence: "Ctrl+l" 72 | onActivated: { 73 | toolbar.omnibox.focusUrlField(); 74 | } 75 | } 76 | 77 | Shortcut { 78 | autoRepeat: false 79 | sequence: StandardKey.Refresh 80 | onActivated: { 81 | tabsModel.active.reload(); 82 | } 83 | } 84 | 85 | Shortcut { 86 | autoRepeat: false 87 | sequence: StandardKey.AddTab 88 | onActivated: { 89 | tabBar.newTab(); 90 | } 91 | } 92 | 93 | Shortcut { 94 | autoRepeat: false 95 | // it's a hack since StandardKey.PreviousChild not working for current Qt 5.7 96 | // TODO: for mac it should be forced to Ctrl+Shift+Tab 97 | sequence: Qt.platform.os == "osx" ? "Meta+Shift+Tab" : "Ctrl+Shift+Tab" 98 | onActivated: { 99 | tabsModel.setPreviousTabActive(); 100 | } 101 | } 102 | 103 | Shortcut { 104 | autoRepeat: false 105 | sequence: StandardKey.NextChild 106 | onActivated: { 107 | tabsModel.setNextTabActive(); 108 | } 109 | } 110 | 111 | Shortcut { 112 | autoRepeat: false 113 | sequence: "Alt+1" 114 | onActivated: { 115 | setActiveTabByIndex(0); 116 | } 117 | } 118 | 119 | Shortcut { 120 | autoRepeat: false 121 | sequence: "Alt+2" 122 | onActivated: { 123 | setActiveTabByIndex(1); 124 | } 125 | } 126 | 127 | Shortcut { 128 | autoRepeat: false 129 | sequence: "Alt+3" 130 | onActivated: { 131 | setActiveTabByIndex(2); 132 | } 133 | } 134 | 135 | Shortcut { 136 | autoRepeat: false 137 | sequence: "Alt+4" 138 | onActivated: { 139 | setActiveTabByIndex(3); 140 | } 141 | } 142 | 143 | Shortcut { 144 | autoRepeat: false 145 | sequence: "Alt+5" 146 | onActivated: { 147 | setActiveTabByIndex(4); 148 | } 149 | } 150 | 151 | Shortcut { 152 | autoRepeat: false 153 | sequence: "Alt+6" 154 | onActivated: { 155 | setActiveTabByIndex(5); 156 | } 157 | } 158 | 159 | Shortcut { 160 | autoRepeat: false 161 | sequence: "Alt+7" 162 | onActivated: { 163 | setActiveTabByIndex(6); 164 | } 165 | } 166 | 167 | Shortcut { 168 | autoRepeat: false 169 | sequence: "Alt+8" 170 | onActivated: { 171 | setActiveTabByIndex(7); 172 | } 173 | } 174 | 175 | Shortcut { 176 | autoRepeat: false 177 | sequence: "Alt+9" 178 | onActivated: { 179 | setActiveTabByIndex(8); 180 | } 181 | } 182 | 183 | Shortcut { 184 | autoRepeat: false 185 | sequence: "Alt+0" 186 | onActivated: { 187 | setActiveTabByIndex(tabsModel.count - 1); 188 | } 189 | } 190 | 191 | Shortcut { 192 | autoRepeat: false 193 | sequence: "Esc" 194 | onActivated: { 195 | if (toolbar.omnibox.editingUrl) { 196 | toolbar.forceActiveFocus(); 197 | } else if (tabsModel.active.loading) { 198 | tabsModel.active.stop(); 199 | } else if (searchOverlay.showing) { 200 | searchOverlay.close(); 201 | } 202 | } 203 | } 204 | 205 | Shortcut { 206 | autoRepeat: false 207 | sequence: "Ctrl+f" 208 | onActivated: { 209 | searchOverlay.open(); 210 | } 211 | } 212 | 213 | Shortcut { 214 | autoRepeat: false 215 | sequence: "Ctrl+n" 216 | onActivated: { 217 | var window = root.newWindow(); 218 | window.showNormal(); 219 | } 220 | } 221 | 222 | Shortcut { 223 | autoRepeat: false 224 | sequence: "Ctrl+Shift+n" 225 | onActivated: { 226 | var window = root.newIncognitoWindow(); 227 | window.showNormal(); 228 | } 229 | } 230 | 231 | } 232 | -------------------------------------------------------------------------------- /src/core/extensions/extensionsmanager.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Liri Browser 3 | * 4 | * Copyright (C) 2017 Tim Süberkrüb 5 | * 6 | * $BEGIN_LICENSE:GPL3+$ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | * 21 | * $END_LICENSE$ 22 | */ 23 | 24 | #include "extensionsmanager.h" 25 | 26 | #include 27 | 28 | 29 | ExtensionsManager::ExtensionsManager(QObject *parent) 30 | : QObject(parent) 31 | { 32 | m_dir = QDir(Paths::ExtensionsLocation); 33 | 34 | // Check for paths 35 | if (!QDir(m_dir).exists()) { 36 | qDebug() << "Extensions location doesn't exist."; 37 | qDebug() << "Creating" << Paths::ExtensionsLocation << "..."; 38 | QDir().mkpath(Paths::ExtensionsLocation); 39 | } 40 | 41 | // Create models 42 | m_extensionsModel = new ExtensionsModel(this); 43 | extensionsModelChanged(m_extensionsModel); 44 | m_extensionThemesModel = new ExtensionThemesModel(this); 45 | extensionThemesModelChanged(m_extensionThemesModel); 46 | m_extensionSearchEnginesModel = new ExtensionSearchEnginesModel(this); 47 | extensionSearchEnginesModelChanged(m_extensionSearchEnginesModel); 48 | 49 | // Create watcher 50 | m_watcher = new QFileSystemWatcher(this); 51 | } 52 | 53 | void ExtensionsManager::loadBuiltins() 54 | { 55 | Extension* extension = new Extension(this); 56 | ExtensionParser parser; 57 | parser.setExtension(extension); 58 | if (!parser.open(QUrl("qrc://extensions/default"), ExtensionType::QRC)) 59 | return; 60 | if (!parser.load()) { 61 | extension->deleteLater(); 62 | parser.close(); 63 | return; 64 | } 65 | parser.close(); 66 | parser.deleteLater(); 67 | addExtension(extension); 68 | } 69 | 70 | void ExtensionsManager::startWatching() 71 | { 72 | connect(m_watcher, &QFileSystemWatcher::directoryChanged, 73 | this, &ExtensionsManager::directoryChanged); 74 | m_watcher->addPath(Paths::ExtensionsLocation); 75 | } 76 | 77 | void ExtensionsManager::scan() 78 | { 79 | QStringList nameFilters; 80 | nameFilters << "*.zip"; 81 | nameFilters << "*.lbx"; 82 | QStringList files = m_dir.entryList(nameFilters, QDir::Files); 83 | for (QString filename : files) { 84 | if (!m_files.contains(filename)) { 85 | // New file detected 86 | fileAdded(filename); 87 | } 88 | } 89 | for (QString filename : m_files) { 90 | if (!files.contains(filename)) { 91 | // Removed file detected 92 | fileRemoved(filename); 93 | } 94 | } 95 | } 96 | 97 | void ExtensionsManager::addExtension(Extension *extension) 98 | { 99 | // Add extension themes to theme model 100 | for (ExtensionTheme* theme : extension->themes()) { 101 | m_extensionThemesModel->add(theme->clone(this)); 102 | } 103 | 104 | // Add search engines to search engines model 105 | for (ExtensionSearchEngine* searchEngine : extension->searchEngines()) { 106 | m_extensionSearchEnginesModel->add(searchEngine->clone(this)); 107 | } 108 | 109 | // Add extension to extensions model 110 | m_extensionsModel->add(extension); 111 | } 112 | 113 | void ExtensionsManager::removeExtension(Extension *extension) 114 | { 115 | // Remove themes from theme model 116 | m_extensionThemesModel->removeByExtensionName(extension->name()); 117 | 118 | // Remove from search engines model 119 | m_extensionSearchEnginesModel->removeByExtensionName(extension->name()); 120 | 121 | // Remove from extensions model 122 | m_extensionsModel->remove(extension); 123 | 124 | // Delete object 125 | extension->deleteLater(); 126 | qDebug() << "Extension unloaded."; 127 | } 128 | 129 | Extension *ExtensionsManager::extensionByName(const QString name) 130 | { 131 | return m_extensionsModel->get(name); 132 | } 133 | 134 | void ExtensionsManager::loadFile(const QString filePath) 135 | { 136 | qDebug() << "Loading extension file" << filePath << "..."; 137 | 138 | // Check for duplicate name 139 | QString name = filePath.section("/", -1).section(".", 0, 0); 140 | if (m_extensionsModel->hasName(name)) { 141 | qWarning() << "There is already an extension with name" << name << "registered."; 142 | qWarning() << "Stopped loading extension."; 143 | return; 144 | } 145 | 146 | Extension* extension = new Extension(this); 147 | 148 | ExtensionParser parser; 149 | parser.setExtension(extension); 150 | if(!parser.open(QUrl(filePath), ExtensionType::LBX)) { 151 | return; 152 | } 153 | if (!parser.load()) { 154 | extension->deleteLater(); 155 | parser.close(); 156 | return; 157 | } 158 | parser.close(); 159 | parser.deleteLater(); 160 | addExtension(extension); 161 | } 162 | 163 | void ExtensionsManager::unloadFile(const QString filePath) 164 | { 165 | qDebug() << "Unloading extension file" << filePath << "..."; 166 | QString name = filePath.section("/", -1).section(".", 0, 0); 167 | Extension* extension = m_extensionsModel->get(name); 168 | removeExtension(extension); 169 | } 170 | 171 | void ExtensionsManager::directoryChanged(const QString path) 172 | { 173 | Q_UNUSED(path) 174 | Q_ASSERT(path == Paths::ExtensionsLocation); 175 | scan(); 176 | } 177 | 178 | void ExtensionsManager::fileAdded(const QString filename) 179 | { 180 | qDebug() << "Extension file" << filename << "added."; 181 | m_files.append(filename); 182 | loadFile(Paths::ExtensionsLocation + filename); 183 | } 184 | 185 | void ExtensionsManager::fileRemoved(const QString filename) 186 | { 187 | qDebug() << "Extension file" << filename << "removed."; 188 | m_files.removeAll(filename); 189 | unloadFile(Paths::ExtensionsLocation + filename); 190 | } 191 | --------------------------------------------------------------------------------