diff --git a/.gitignore b/.gitignore index cd0b5931..1c959ee7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,43 +1,43 @@ build DEBIAN *.deb *.pro.user* *.autosave *~ *.a *.qm *.o !qt_*.qm headers*.tar.gz license_template Makefile* -bin/qupzilla -bin/QupZilla.dmg -mac/images/qupzilla-dmg-icon.iconset +bin/falkon +bin/Falkon.dmg +mac/images/falkon-dmg-icon.iconset lib*.so* bin/core -qupzilla.sh +falkon.sh git_revision *.exe *.dll *.lib *.exp *.zip Thumbs.db *.pdb *.ilk *.kdev4 *.swp *_manifest.* *.embed.manifest bin/autotests .clang_complete -bin/qupzilla.app +bin/falkon.app .DS_Store *.dylib hunspell callgrind.out.* tests/autotests/autotests .ycm_extra_conf.py* *.stash bin/profiles diff --git a/AUTHORS b/AUTHORS deleted file mode 100644 index f67ec1a6..00000000 --- a/AUTHORS +++ /dev/null @@ -1,61 +0,0 @@ -Main developer and project maintainer: - -David Rosca - -Contributors: - -Mladen Pejaković (webview context menu improvements, speed dial background) -Alexander Samilov (tab previews) -Seyyed Razi Alavizadeh (fixed UI for RTL languages) -Franz Fellner (new restore session ui) -Bryan M Dunsmore (opening background tabs, closing window when closing last tab) -Mariusz Fik (fixed tab order in preferences dialog) -Daniele Cocca (close tabs with middle click, initial work on speed dial) -Giuseppe Calà (fixed loading of bookmarklets) -Adrien Vigneron (new QupZilla logo) -Elio Qoshi (new QupZilla logo) - -Translators: - -Jonathan Hooverman (German) -Heimen Stoffels (Dutch) -Peter Vacula (Slovak) -Federico Fabiani (Italian) -Francesco Marinucci (Italian) -Jorge Sevilla (Spanish) -Michał Szymanowski (Polish) -Mariusz Fik (Polish) -Jérôme Giry (French) -Nicolas Ourceau (French) -Vasilis Tsivikis (Greek) -Rustam Salakhutdinov (Russian) -Oleg Brezhnev (Russian) -Sérgio Marques (Portuguese) -Alexandre Carvalho (Brazilian Portuguese) -Mladen Pejaković (Serbian) -Unink-Lio (Chinese) -Yu Hai (Chinese) -Wu Cheng-Hong (Traditional Chinese) -Widya Walesa (Indonesian) -Beqa Arabuli (Georgian) -Daiki Noda (Japanese) -Ștefan Comănescu (Romanian) -Gábor Oberle (Hungarian) -Piccoro McKay Lenz (Venezuelan Spanish) -Stanislav Kuznietsov (Ukrainian) -Seyyed Razi Alavizadeh (Persian) -Guillem Prats (Catalan) -Clara Villalba (Catalan) -Xabier Aramendi (Basque) -Muhammad Fawwaz Orabi (Arabic) -Lasso Kante (N'ko) -Kizito Birabwa (Luganda) -Juan Carlos Sánchez (Mexican Spanish) -Ferhat AYDIN (Turkish) - -Special thanks: - -Jonathan Hooverman (english language correction) -Peter Vacula (for a big support in the beginnings) -Sergio Cipolla (modifications to old QupZilla icon) -Radomir Orkac (qupzilla.com domain) diff --git a/BUILDING.md b/BUILDING.md index aa10cde2..879a15cd 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -1,163 +1,163 @@ General ---------------------------------------------------------------------------------- If you can, you should use precompiled packages for your distribution. But if you cannot use them, or they are not available, please read this information before compiling. After your binary is successfully compiled, you need to copy bin/ folder from git to specific directory by your system you compiled for. On Linux, you can easily do it by running make install. If you are unsure where is the right place, you can check it directly from - QupZilla by clicking from Help Menu on Configuration Information, then in + Falkon by clicking from Help Menu on Configuration Information, then in Path section. - You may want to build QupZilla with debugging symbols (for generating + You may want to build Falkon with debugging symbols (for generating backtrace of crash) as easily as adding one line to src/defines.pri: CONFIG += debug - QupZilla requires Qt (>= 5.8) and QtWebEngine (at least version included in Qt 5.8) + Falkon requires Qt (>= 5.8) and QtWebEngine (at least version included in Qt 5.8) Microsoft Windows ---------------------------------------------------------------------------------- You need Microsoft Visual C++ Compiler, Qt Libraries 5.8 or higher and openssl - libraries. in order to build QupZilla. + libraries. in order to build Falkon. Linux / Unix ---------------------------------------------------------------------------------- You need to have Qt 5 (>= 5.8) with QtWebEngine. Next compulsory requirement is OpenSSL (libcrypto). xcb libraries are also required unless you specify NO_X11 build option. To build KWallet plugin, you need: - KF5 KWallet - set KDE_INTEGRATION build flag To build Gnome-Keyring plugin, you need - libgnome-keyring-dev installed - set GNOME_INTEGRATION build flag For debug build, gdb is required by qmake. MAC OS X ---------------------------------------------------------------------------------- You need to have Xcode from the Apple App Store installed in Applications, [Command Line Tools for the same Xcode version](https://developer.apple.com/) may be included depending on the version, [Homebrew](http://brew.sh/), and `$ brew install openssl` for openssl. Next compulsory requirement is Qt 5 (>= 5.8) with QtWebEngine. After successful compilation, you need to build the application bundle. You will do it with following command: $ make bundle FreeBSD ---------------------------------------------------------------------------------- - You may need to set few sysctls to get QupZilla running with raster graphics system. + You may need to set few sysctls to get Falkon running with raster graphics system. For more informations, please see FAQ. Available Defines ---------------------------------------------------------------------------------- You can set define directly in file (src/defines.pri) or set environment variable by $ export NAME="value" General: - PORTABLE_BUILD QupZilla won't write any data outside of path of execution. + PORTABLE_BUILD Falkon won't write any data outside of path of execution. It will also disable plugins by default. (disabled by default) example: $ export PORTABLE_BUILD="true" NONBLOCK_JS_DIALOGS Enable non-blocking JavaScript dialogs from alert() prompt() and confirm() functions. They are shown inside page and are not blocking application window. However, due to synchronous API, there is a possible crash when closing browser windows with opened dialogs. If you can take this risk and/or make sure you aren't closing browser with opened dialogs, you may enable this option. These dialogs are much more beautiful than normal QDialogs. (disabled by default) example: $ export NONBLOCK_JS_DIALOGS="true" Windows specific defines: W7API Enable Windows 7 API support Requires linking against libraries from Microsoft Visual C++ Compiler 2010 (enabled by default) Linux / Unix specific defines: NO_X11 Disable all X11 calls. Enable this when building for Wayland-only. All X11 calls are guarded by runtime X11 platform check even without this option. example: $ export NO_X11="true" KDE_INTEGRATION Enable KDE integration. Currently it enables building of KWallet Password plugin, which provides support for storing passwords in KWallet. example: $ export KDE_INTEGRATION="true" GNOME_INTEGRATION Enable Gnome integration. Currently it enables building of Gnome-Keyring Password plugin, which provides support for storing passwords in Gnome-Keyring. example: $ export GNOME_INTEGRATION="true" - USE_LIBPATH By default, /usr/lib/ is used for libQupZilla and /usr/lib/qupzilla + USE_LIBPATH By default, /usr/lib/ is used for libFalkon and /usr/lib/falkon for plugins. You can change it by setting this define. example: $ export USE_LIBPATH="/usr/lib64" - NO_SYSTEM_DATAPATH By default, QupZilla is using /usr/share/qupzilla/ path + NO_SYSTEM_DATAPATH By default, Falkon is using /usr/share/falkon/ path for storing themes and translations. - By setting this define, QupZilla will use path of execution. + By setting this define, Falkon will use path of execution. (disabled by default) example: $ export NO_SYSTEM_DATAPATH="true" - QUPZILLA_PREFIX You can define different prefix. - QupZilla binary will then be moved to PREFIX/bin/, use - PREFIX/share/qupzilla/ as datadir, PREFIX/share/applications for + FALKON_PREFIX You can define different prefix. + Falkon binary will then be moved to PREFIX/bin/, use + PREFIX/share/falkon/ as datadir, PREFIX/share/applications for desktop launcher and PREFIX/share/pixmaps for icon. (default prefix is "/usr") example: - $ export QUPZILLA_PREFIX="/usr" + $ export FALKON_PREFIX="/usr" SHARE_FOLDER You can define the path of the share folder, i.e. /usr/share - QupZilla will then use SHARE_FOLDER/qupzilla as datadir, + Falkon will then use SHARE_FOLDER/falkon as datadir, SHARE_FOLDER/applications for desktop launcher and SHARE_FOLDER/pixmaps for the icon. By default it is not defined and files will be installed as described above. (default share folder is "/usr/share") example: $ export SHARE_FOLDER="/usr/share" DISABLE_DBUS Build without QtDBus module. Native desktop notifications will be disabled. example: $ export DISABLE_DBUS="true" diff --git a/COPYRIGHT b/COPYRIGHT index c94b9ba9..b44a1a70 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -1,124 +1,124 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ ------------------------------------------------------------------------ AdBlock, LineEdit class and SqueezeLabel class: ------------------------------------------------------------------------ * Copyright (c) 2008 - 2009, Benjamin C. Meyer * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the Benjamin Meyer nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. ----------------------------------------------------------------------------- QtSingleApplication class: ----------------------------------------------------------------------------- ** ** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of a Qt Solutions component. ** ** Commercial Usage ** Licensees holding valid Qt Commercial licenses may use this file in ** accordance with the Qt Solutions Commercial License Agreement provided ** with the Software or, alternatively, in accordance with the terms ** contained in a written agreement between you and Nokia. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain ** additional rights. These rights are described in the Nokia Qt LGPL ** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this ** package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3.0 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU General Public License version 3.0 requirements will be ** met: http://www.gnu.org/copyleft/gpl.html. ** ** Please note Third Party Software included with Qt Solutions may impose ** additional restrictions and it is the user's responsibility to ensure ** that they have met the licensing requirements of the GPL, LGPL, or Qt ** Solutions Commercial license and the relevant license of the Third ** Party Software they are using. ** ** If you are unsure which license is appropriate for your use, please ** contact Nokia at qt-info@nokia.com. ** ----------------------------------------------------------------------------- OpenSearchReader + OpenSearchEngine class: ----------------------------------------------------------------------------- /* * Copyright 2009 Jakub Wieczorek * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA */ ----------------------------------------------------------------------------- In application are used also some icons from Breeze icon set. More info at https://cgit.kde.org/breeze-icons.git ----------------------------------------------------------------------------- Speed Dial uses some icons from Faenza icon set, which are licensed under the GNU/GPL license. More info at http://tiheum.deviantart.com/art/Faenza-Icons-173323228 ----------------------------------------------------------------------------- diff --git a/FAQ b/FAQ deleted file mode 100644 index c5f20c75..00000000 --- a/FAQ +++ /dev/null @@ -1,3 +0,0 @@ -Frequently Asked Questions - -https://github.com/QupZilla/qupzilla/wiki/FAQ diff --git a/README.md b/README.md index edc9ef0b..7ee105c2 100644 --- a/README.md +++ b/README.md @@ -1,76 +1,2 @@ -QupZilla Web Browser ----------------------------------------------------------------------------------------- - -[![Travis-ci](https://travis-ci.org/QupZilla/qupzilla.svg?branch=master)](https://travis-ci.org/QupZilla/qupzilla) -[![AppVeyor](https://ci.appveyor.com/api/projects/status/github/qupzilla/qupzilla?svg=true)](https://ci.appveyor.com/project/srazi/qupzilla-utoeb) -Homepage: https://www.qupzilla.com -Blog: http://blog.qupzilla.com -IRC: `#qupzilla` at `irc.freenode.net` -Translations: https://www.transifex.com/projects/p/qupzilla - -![QupZilla icon](https://github.com/QupZilla/qupzilla/blob/master/src/lib/data/icons/other/about.png?raw=true) - -QupZilla is a new and very fast QtWebEngine browser. It aims to be a lightweight web browser -available through all major platforms. This project has been originally started only -for educational purposes. But from its start, QupZilla has grown into a feature-rich browser. - -QupZilla has all standard functions you expect from a web browser. It includes bookmarks, -history (both also in sidebar) and tabs. Above that, it has by default enabled blocking ads -with a built-in AdBlock plugin. - -History ----------------------------------------------------------------------------------------- - -The very first version of QupZilla has been released in December 2010 and it was written -in Python with PyQt4 bindings. After a few versions, QupZilla has been completely rewritten -in C++ with the Qt Framework. First public release was 1.0.0-b4. - -Until version 2.0, QupZilla was using QtWebKit. QtWebKit is now deprecated and new versions -are using QtWebEngine. - -Compiling ----------------------------------------------------------------------------------------- - -Before you start compiling, make sure that you have installed the Qt (>= 5.8) development libraries -and you have read the [BUILDING.md](https://github.com/QupZilla/qupzilla/blob/master/BUILDING.md) information. - -**Linux** - - * OpenSSL (libcrypto) is required - * xcb libraries when building without NO_X11 - -**Windows** - * OpenSSL (libeay32) is required - -Then you can start compiling by running this commands: - - $ qmake - $ make - -After a successful compilation the executable binary can be found in the bin/ directory. -On Fedora and possibly other Linux distributions you need to replace `qmake` with `qmake-qt5`. - -On Linux/Unix: To install QupZilla, run this command: (it may be necessary to run it as root) - - $ make install - -On Mac OS X: To deploy QupZilla in dmg image, run this command: - - $ make bundle - -Current version ----------------------------------------------------------------------------------------- - -The current stable version of QupZilla is 2.1.2. You can download precompiled packages -and the sources from the download section at [homepage](https://www.qupzilla.com/download). -However, if you want the latest revision, just take the latest code snapshot either by -downloading a tarball or running: - - $ git clone https://github.com/QupZilla/qupzilla.git - -FAQ and Changelog ----------------------------------------------------------------------------------------- - -If you are experiencing some sort of problem, please read the FAQ before you open an issue. - -[FAQ](https://github.com/QupZilla/qupzilla/wiki/FAQ) | [Changelog](https://github.com/QupZilla/qupzilla/blob/master/CHANGELOG) | [Bug Reports](https://github.com/QupZilla/qupzilla/wiki/Bug-Reports) +Falkon Web Browser +------------------------ diff --git a/bin/themes/chrome/theme.info b/bin/themes/chrome/theme.info index 36b026c4..4d31e06b 100644 --- a/bin/themes/chrome/theme.info +++ b/bin/themes/chrome/theme.info @@ -1,4 +1,4 @@ Name: Chrome Author: David Rosca Short Description: Chrome like theme -Long Description: Chrome like theme for QupZilla based on Firefox Chromifox theme +Long Description: Chrome like theme for Falkon based on Firefox Chromifox theme diff --git a/bin/themes/mac/theme.info b/bin/themes/mac/theme.info index e6b786ad..d18afe64 100644 --- a/bin/themes/mac/theme.info +++ b/bin/themes/mac/theme.info @@ -1,4 +1,4 @@ Name: Mac Author: David Rosca Short Description: Mac like theme -Long Description: Mac like theme for QupZilla based on Firefox Mac OS X theme +Long Description: Mac like theme for Falkon based on Firefox Mac OS X theme diff --git a/bin/themes/windows/theme.info b/bin/themes/windows/theme.info index 63bcb646..9461fd6a 100644 --- a/bin/themes/windows/theme.info +++ b/bin/themes/windows/theme.info @@ -1,4 +1,4 @@ Name: Windows Author: David Rosca Short Description: Windows default theme -Long Description: Windows default theme for QupZilla based on Firefox Strata Aero theme. This theme supports transparent background on Windows 7 +Long Description: Windows default theme for Falkon based on Firefox Strata Aero theme. This theme supports transparent background on Windows 7 diff --git a/QupZilla.pro b/falkon.pro similarity index 83% rename from QupZilla.pro rename to falkon.pro index 72b8eb7f..fc6ab748 100644 --- a/QupZilla.pro +++ b/falkon.pro @@ -1,37 +1,37 @@ #------------------------------------------------- # -# QupZilla - QtWebKit browser +# Falkon - Qt web browser # # Project created by QtCreator 2010-12-18T14:53:41 # #------------------------------------------------- lessThan(QT_VERSION, 5.8) { - error("QupZilla requires at least Qt 5.8!") + error("Falkon requires at least Qt 5.8!") } lessThan(QT.webengine.VERSION, 5.8) { - error("QupZilla requires at least QtWebEngine 5.8!") + error("Falkon requires at least QtWebEngine 5.8!") } # Create plugins directory first on Mac / Linux mac|unix: system(test -d bin/plugins || mkdir bin/plugins) TEMPLATE = subdirs src_lib.subdir = src/lib src_lib.target = sub-src-lib src_main.subdir = src/main src_main.depends = sub-src-lib src_plugins.subdir = src/plugins src_plugins.depends = sub-src-lib SUBDIRS += src_lib src_main src_plugins mac: { macdeploysh.target = bundle macdeploysh.commands = mac/macdeploy.sh $$[QT_INSTALL_BINS]/macdeployqt QMAKE_EXTRA_TARGETS += macdeploysh } diff --git a/flatpak/org.qupzilla.QupZilla.json b/flatpak/org.kde.Falkon.json similarity index 77% rename from flatpak/org.qupzilla.QupZilla.json rename to flatpak/org.kde.Falkon.json index 62989710..d7e7fedd 100644 --- a/flatpak/org.qupzilla.QupZilla.json +++ b/flatpak/org.kde.Falkon.json @@ -1,42 +1,42 @@ { - "id": "org.qupzilla.QupZilla", + "id": "org.kde.Falkon", "runtime": "org.kde.Platform", "runtime-version": "master", "sdk": "org.kde.Sdk", - "rename-icon": "qupzilla", + "rename-icon": "falkon", "tags": ["nightly"], "desktop-file-name-suffix": " (Nightly)", - "command": "qupzilla", + "command": "falkon", "finish-args": [ "--share=ipc", "--share=network", "--socket=x11", "--socket=wayland", "--socket=pulseaudio", "--device=dri", "--filesystem=host", "--system-talk-name=org.freedesktop.GeoClue2" ], "modules": [ { - "name": "qupzilla", + "name": "falkon", "build-options": { "env": { - "QUPZILLA_PREFIX": "/app" + "FALKON_PREFIX": "/app" } }, "sources": [ { "type": "git", - "url": "https://github.com/QupZilla/qupzilla.git" + "url": "git://anongit.kde.org/falkon.git" }, { "type": "script", "commands": [ "qmake" ], "dest-filename": "configure" } ] } ] } diff --git a/linux/appdata/or.qupzilla.QupZilla.appdata.xml b/linux/appdata/or.qupzilla.QupZilla.appdata.xml deleted file mode 100644 index 90346c74..00000000 --- a/linux/appdata/or.qupzilla.QupZilla.appdata.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - org.qupzilla.QupZilla.desktop - CC0-1.0 - GPL-3.0+ - QupZilla - Web Browser - -

- QupZilla is a new and very fast QtWebKit browser. It aims to be a lightweight web browser available through all major platforms. This project has been originally started only for educational purposes. But from its start, QupZilla has grown into a feature-rich browser. -

-

- QupZilla has all standard functions you expect from a web browser. It includes bookmarks, history (both also in sidebar) and tabs. Above that, you can manage RSS feeds with an included RSS reader, block ads with a built-in AdBlock plugin, block Flash content with Click2Flash and edit the local CA Certificates database with an SSL manager. -

-

- QupZilla's main aim is to be a very fast and very stable QtWebKit browser available to everyone. There are already a lot of QtWebKit browsers available, but they are either bound to the KDE environment, not actively developed or very unstable and miss important features. QupZilla, a multi-platform, modern and actively developed browser, is here to fill this gap by providing a very stable browsing experience. -

-
- - https://www.qupzilla.com/screens/gnome.png - https://www.qupzilla.com/screens/kde_window.png - https://www.qupzilla.com/screens/dial_gnome.png - https://www.qupzilla.com/screens/kde_speeddial.png - https://www.qupzilla.com/screens/preferences_gnome.png - https://www.qupzilla.com/screens/kde_preferences.png - - https://www.qupzilla.com/ - nowrep_at_gmail.com -
diff --git a/linux/appdata/org.kde.Falkon.appdata.xml b/linux/appdata/org.kde.Falkon.appdata.xml new file mode 100644 index 00000000..796f9f32 --- /dev/null +++ b/linux/appdata/org.kde.Falkon.appdata.xml @@ -0,0 +1,29 @@ + + + org.kde.Falkon.desktop + CC0-1.0 + GPL-3.0+ + Falkon + Web Browser + +

+ Falkon is a new and very fast QtWebKit browser. It aims to be a lightweight web browser available through all major platforms. This project has been originally started only for educational purposes. But from its start, Falkon has grown into a feature-rich browser. +

+

+ Falkon has all standard functions you expect from a web browser. It includes bookmarks, history (both also in sidebar) and tabs. Above that, you can manage RSS feeds with an included RSS reader, block ads with a built-in AdBlock plugin, block Flash content with Click2Flash and edit the local CA Certificates database with an SSL manager. +

+

+ Falkon's main aim is to be a very fast and very stable QtWebKit browser available to everyone. There are already a lot of QtWebKit browsers available, but they are either bound to the KDE environment, not actively developed or very unstable and miss important features. Falkon, a multi-platform, modern and actively developed browser, is here to fill this gap by providing a very stable browsing experience. +

+
+ + https://www.qupzilla.com/screens/gnome.png + https://www.qupzilla.com/screens/kde_window.png + https://www.qupzilla.com/screens/dial_gnome.png + https://www.qupzilla.com/screens/kde_speeddial.png + https://www.qupzilla.com/screens/preferences_gnome.png + https://www.qupzilla.com/screens/kde_preferences.png + + https://www.qupzilla.com/ + nowrep_at_gmail.com +
diff --git a/linux/applications/org.qupzilla.QupZilla.desktop b/linux/applications/org.kde.Falkon.desktop similarity index 80% rename from linux/applications/org.qupzilla.QupZilla.desktop rename to linux/applications/org.kde.Falkon.desktop index 99cef0cb..5869e329 100644 --- a/linux/applications/org.qupzilla.QupZilla.desktop +++ b/linux/applications/org.kde.Falkon.desktop @@ -1,23 +1,23 @@ [Desktop Entry] -Name=QupZilla +Name=Falkon Type=Application Icon=qupzilla Categories=Network;WebBrowser; Comment=A fast and secure web browser GenericName=Web Browser -Exec=qupzilla %u +Exec=falkon %u MimeType=text/html;application/xhtml+xml;x-scheme-handler/http;x-scheme-handler/https;x-scheme-handler/ftp;application/x-mimearchive; Terminal=false Actions=NewTab;NewWindow;PrivateBrowsing; [Desktop Action NewTab] Name=Open new tab -Exec=qupzilla --new-tab +Exec=falkon --new-tab [Desktop Action NewWindow] Name=Open new window -Exec=qupzilla --new-window +Exec=falkon --new-window [Desktop Action PrivateBrowsing] Name=Start private browsing -Exec=qupzilla --private-browsing +Exec=falkon --private-browsing diff --git a/linux/completion/README.md b/linux/completion/README.md index 5dd03ad4..d645691a 100644 --- a/linux/completion/README.md +++ b/linux/completion/README.md @@ -1,12 +1,12 @@ **Shell completion files** -* *qupzilla* - bash completion file -* *_qupzilla* - zsh completion file +* *falkon* - bash completion file +* *_falkon* - zsh completion file Bash completion file will be automatically installed with make install into `/usr/share/bash-completion/completions` To install zsh completion file, either manually copy it to proper directory (one directory from $fpath), or run this command: - cp _qupzilla "`echo $fpath | cut -d' ' -f1`/_qupzilla" + cp _falkon "`echo $fpath | cut -d' ' -f1`/_falkon" diff --git a/linux/completion/_qupzilla b/linux/completion/_falkon similarity index 82% rename from linux/completion/_qupzilla rename to linux/completion/_falkon index e1d023b7..1076b1af 100644 --- a/linux/completion/_qupzilla +++ b/linux/completion/_falkon @@ -1,27 +1,27 @@ -#compdef qupzilla +#compdef falkon # -# Zsh completion for QupZilla +# Zsh completion for Falkon # opts=( '(-)'{-h,--help}'[print usage help]' - '(-)'{-a,--authors}'[print QupZilla authors]' - '(-)'{-v,--version}'[print QupZilla version]' + '(-)'{-a,--authors}'[print Falkon authors]' + '(-)'{-v,--version}'[print Falkon version]' '(-)'{-p,--profile=}'[start with specified profile]' '(-)'{-e,--no-extensions}'[start without extensions]' '(-)'{-o,--portable}'[start in portable mode]' '(-)'{-t,--new-tab}'[open new tab]' '(-)'{-w,--new-window}'[open new window]' '(-)'{-i,--private-browsing}'[start private browsing]' '(-)'{-d,--download-manager}'[show download manager]' '(-)'{-f,--fullscreen}'[toggle fullscreen]' '(-)'{-r,--no-remote}'[open new browser instance]' '(-)'{-c,--current-tab=}'[open URL in current tab]' '(-)'{-u,--open-window=}'[open URL in new window]' '*:files:_files' ) _x_arguments -C $opts return 0 diff --git a/linux/completion/qupzilla b/linux/completion/falkon similarity index 87% rename from linux/completion/qupzilla rename to linux/completion/falkon index 2d2f9577..27ea1450 100644 --- a/linux/completion/qupzilla +++ b/linux/completion/falkon @@ -1,22 +1,22 @@ # -# Bash completion for QupZilla +# Bash completion for Falkon # -_qupzilla() +_falkon() { local cur prev opts COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" opts="-h --help -a --authors -v --version -p --profile= -e --no-extensions -o --portable -t --new-tab -w --new-window -i --private-browsing -d --download-manager -f --fullscreen -r --no-remote -c --current-tab= -u --open-window=" if [[ ${cur} == -* ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) else _filedir fi } -complete -F _qupzilla qupzilla +complete -F _falkon falkon diff --git a/src/defines.pri b/src/defines.pri index 5a05ca23..6af45dfc 100644 --- a/src/defines.pri +++ b/src/defines.pri @@ -1,108 +1,108 @@ DESTDIR = $$PWD/../bin QZ_DESTDIR = $$DESTDIR OBJECTS_DIR = $$PWD/../build MOC_DIR = $$PWD/../build RCC_DIR = $$PWD/../build UI_DIR = $$PWD/../build # workaround for #849: see https://bugreports.qt-project.org/browse/QTBUG-23196 mocinclude.CONFIG *= fix_target QZ_VERSION = 2.1.99 unix: VERSION = $$QZ_VERSION -DEFINES *= QUPZILLA_VERSION=\\\"""$$QZ_VERSION"\\\"" +DEFINES *= FALKON_VERSION=\\\"""$$QZ_VERSION"\\\"" d_no_system_datapath = $$(NO_SYSTEM_DATAPATH) d_kde_integration = $$(KDE_INTEGRATION) d_gnome_integration = $$(GNOME_INTEGRATION) d_nox11 = $$(NO_X11) d_portable = $$(PORTABLE_BUILD) d_nonblock_dialogs = $$(NONBLOCK_JS_DIALOGS) d_use_lib_path = $$(USE_LIBPATH) d_disable_dbus = $$(DISABLE_DBUS) d_disable_updates_check = $$(DISABLE_UPDATES_CHECK) d_debug_build = $$(DEBUG_BUILD) -d_prefix = $$(QUPZILLA_PREFIX) +d_prefix = $$(FALKON_PREFIX) d_share = $$(SHARE_FOLDER) equals(d_no_system_datapath, "true") { DEFINES *= NO_SYSTEM_DATAPATH } equals(d_kde_integration, "true") { DEFINES *= KDE_INTEGRATION } equals(d_gnome_integration, "true") { DEFINES *= GNOME_INTEGRATION } equals(d_nox11, "true") { DEFINES *= NO_X11 } equals(d_portable, "true") { DEFINES *= PORTABLE_BUILD } equals(d_nonblock_dialogs, "true") { DEFINES *= NONBLOCK_JS_DIALOGS } equals(d_disable_dbus, "true") { DEFINES *= DISABLE_DBUS } equals(d_disable_updates_check, "true") { DEFINES *= DISABLE_UPDATES_CHECK } equals(d_debug_build, "true") { CONFIG += debug } DEFINES *= QT_NO_URL_CAST_FROM_STRING DEFINES *= QT_USE_QSTRINGBUILDER -CONFIG(debug, debug|release): DEFINES *= QUPZILLA_DEBUG_BUILD +CONFIG(debug, debug|release): DEFINES *= FALKON_DEBUG_BUILD win32-msvc* { DEFINES *= W7API LIBS += User32.lib Ole32.lib Shell32.lib ShlWapi.lib Gdi32.lib ComCtl32.lib } # QtDBus not available on Mac mac: DEFINES *= DISABLE_DBUS haiku-* { DEFINES *= DISABLE_DBUS DEFINES *= NO_SYSTEM_DATAPATH DEFINES *= NO_X11 } !mac:unix { binary_folder = /usr/bin library_folder = /usr/lib arch_lib_path = /usr/lib/$${QT_ARCH}-linux-gnu exists($$arch_lib_path): library_folder = $$arch_lib_path # Define a reasonable default for share_folder share_folder = /usr/share !equals(d_prefix, "") { binary_folder = "$$d_prefix"/bin library_folder = "$$d_prefix"/lib share_folder = "$$d_prefix"/share } !equals(d_share, "") { share_folder = "$$d_share" } - data_folder = $$share_folder/qupzilla + data_folder = $$share_folder/falkon launcher_folder = $$share_folder/applications icon_folder = $$share_folder/pixmaps hicolor_folder = $$share_folder/icons/hicolor !equals(d_use_lib_path, ""):library_folder = $$d_use_lib_path DEFINES *= USE_LIBPATH=\\\"""$$library_folder"\\\"" DEFINES *= USE_DATADIR=\\\"""$$data_folder"\\\"" # Define QZ_WS_X11 even with Qt5 (but only when building for X11) !contains(DEFINES, NO_X11) DEFINES *= QZ_WS_X11 } unix: { # Git revision rev = $$system(cd ../ && sh $$PWD/../scripts/getrevision.sh) !equals(rev, ""): DEFINES *= GIT_REVISION=\\\"""$$rev"\\\"" } isEmpty(QMAKE_LRELEASE) { win32|os2:QMAKE_LRELEASE = $$[QT_INSTALL_BINS]\\lrelease.exe else:QMAKE_LRELEASE = $$[QT_INSTALL_BINS]/lrelease # Try to use lrelease from PATH unix:!exists($$QMAKE_LRELEASE) { QMAKE_LRELEASE = lrelease } } isEmpty(QMAKE_LFLAGS_RPATH) { QMAKE_LFLAGS_RPATH = -Wl,-rpath, } diff --git a/src/install.pri b/src/install.pri index f8360de9..b52d2ad3 100644 --- a/src/install.pri +++ b/src/install.pri @@ -1,57 +1,57 @@ include(defines.pri) mac { QMAKE_INFO_PLIST = $$PWD/main/Info.plist ICON = $$PWD/lib/data/icons/exeicons/qupzilla.icns bundle_target.files += $$QZ_DESTDIR/locale bundle_target.files += $$QZ_DESTDIR/themes bundle_target.files += $$QZ_DESTDIR/plugins bundle_target.path = Contents/Resources QMAKE_BUNDLE_DATA += bundle_target } !mac:unix { target.path = $$binary_folder target1.files += $$QZ_DESTDIR/locale target1.files += $$QZ_DESTDIR/themes target1.path = $$data_folder - target2.files = $$PWD/../linux/applications/org.qupzilla.QupZilla.desktop + target2.files = $$PWD/../linux/applications/org.kde.Falkon.desktop target2.path = $$launcher_folder target3.files = $$PWD/../linux/pixmaps/qupzilla.png target3.path = $$icon_folder ico16.files = $$PWD/../linux/hicolor/16x16/apps/qupzilla.png ico16.path = $$hicolor_folder/16x16/apps ico32.files = $$PWD/../linux/hicolor/32x32/apps/qupzilla.png ico32.path = $$hicolor_folder/32x32/apps ico48.files = $$PWD/../linux/hicolor/48x48/apps/qupzilla.png ico48.path = $$hicolor_folder/48x48/apps ico64.files = $$PWD/../linux/hicolor/64x64/apps/qupzilla.png ico64.path = $$hicolor_folder/64x64/apps ico128.files = $$PWD/../linux/hicolor/128x128/apps/qupzilla.png ico128.path = $$hicolor_folder/128x128/apps ico256.files = $$PWD/../linux/hicolor/256x256/apps/qupzilla.png ico256.path = $$hicolor_folder/256x256/apps - bashcompletion.files = $$PWD/../linux/completion/qupzilla + bashcompletion.files = $$PWD/../linux/completion/falkon bashcompletion.path = $$share_folder/bash-completion/completions - appdata.files = $$PWD/../linux/appdata/org.qupzilla.QupZilla.appdata.xml + appdata.files = $$PWD/../linux/appdata/org.kde.Falkon.appdata.xml appdata.path = $$share_folder/appdata INSTALLS += target target1 target2 target3 INSTALLS += ico16 ico32 ico48 ico64 ico128 ico256 INSTALLS += bashcompletion INSTALLS += appdata } diff --git a/src/lib/3rdparty/fancytabwidget.cpp b/src/lib/3rdparty/fancytabwidget.cpp index 7fe7469b..e916ea22 100644 --- a/src/lib/3rdparty/fancytabwidget.cpp +++ b/src/lib/3rdparty/fancytabwidget.cpp @@ -1,747 +1,747 @@ /************************************************************************** ** ** This file is part of Qt Creator ** ** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). ** ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** Commercial Usage ** ** Licensees holding valid Qt Commercial licenses may use this file in ** accordance with the Qt Commercial License Agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and Nokia. ** ** GNU Lesser General Public License Usage ** ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** If you are unsure which license is appropriate for your use, please ** contact the sales department at http://qt.nokia.com/contact. ** **************************************************************************/ #include "fancytabwidget.h" #include "stylehelper.h" #include #include #include #include #include #include #include #include #include #include #include #include #include //#include using namespace Core; using namespace Internal; const int FancyTabBar::m_rounding = 22; const int FancyTabBar::m_textPadding = 4; void FancyTabProxyStyle::drawControl( ControlElement element, const QStyleOption* option, QPainter* p, const QWidget* widget) const { const QStyleOptionTab* v_opt = qstyleoption_cast(option); if (element != CE_TabBarTab || !v_opt) { QProxyStyle::drawControl(element, option, p, widget); return; } const QRect rect = v_opt->rect; const bool selected = v_opt->state & State_Selected; const bool vertical_tabs = v_opt->shape == QTabBar::RoundedWest; const QString text = v_opt->text; if (selected) { //background p->save(); QLinearGradient grad(rect.topLeft(), rect.topRight()); grad.setColorAt(0, QColor(255, 255, 255, 140)); grad.setColorAt(1, QColor(255, 255, 255, 210)); p->fillRect(rect.adjusted(0, 0, 0, -1), grad); p->restore(); //shadows p->setPen(QColor(0, 0, 0, 110)); p->drawLine(rect.topLeft() + QPoint(1, -1), rect.topRight() - QPoint(0, 1)); p->drawLine(rect.bottomLeft(), rect.bottomRight()); p->setPen(QColor(0, 0, 0, 40)); p->drawLine(rect.topLeft(), rect.bottomLeft()); //highlights p->setPen(QColor(255, 255, 255, 50)); p->drawLine(rect.topLeft() + QPoint(0, -2), rect.topRight() - QPoint(0, 2)); p->drawLine(rect.bottomLeft() + QPoint(0, 1), rect.bottomRight() + QPoint(0, 1)); p->setPen(QColor(255, 255, 255, 40)); p->drawLine(rect.topLeft() + QPoint(0, 0), rect.topRight()); p->drawLine(rect.topRight() + QPoint(0, 1), rect.bottomRight() - QPoint(0, 1)); p->drawLine(rect.bottomLeft() + QPoint(0, -1), rect.bottomRight() - QPoint(0, 1)); } QTransform m; if (vertical_tabs) { m = QTransform::fromTranslate(rect.left(), rect.bottom()); m.rotate(-90); } else { m = QTransform::fromTranslate(rect.left(), rect.top()); } const QRect draw_rect(QPoint(0, 0), m.mapRect(rect).size()); p->save(); p->setTransform(m); QRect icon_rect(QPoint(8, 0), v_opt->iconSize); QRect text_rect(icon_rect.topRight() + QPoint(4, 0), draw_rect.size()); text_rect.setRight(draw_rect.width()); icon_rect.translate(0, (draw_rect.height() - icon_rect.height()) / 2); QFont boldFont(p->font()); boldFont.setPointSizeF(Utils::StyleHelper::sidebarFontSize()); boldFont.setBold(true); p->setFont(boldFont); p->setPen(selected ? QColor(255, 255, 255, 160) : QColor(0, 0, 0, 110)); int textFlags = Qt::AlignHCenter | Qt::AlignVCenter; p->drawText(text_rect, textFlags, text); p->setPen(selected ? QColor(60, 60, 60) : Utils::StyleHelper::panelTextColor()); if (widget) { const QString fader_key = "tab_" + text + "_fader"; const QString animation_key = "tab_" + text + "_animation"; const QString tab_hover = widget->property("tab_hover").toString(); int fader = widget->property(fader_key.toUtf8().constData()).toInt(); QPropertyAnimation* animation = widget->property(animation_key.toUtf8().constData()).value(); if (!animation) { QWidget* mut_widget = const_cast(widget); fader = 0; mut_widget->setProperty(fader_key.toUtf8().constData(), fader); animation = new QPropertyAnimation(mut_widget, fader_key.toUtf8(), mut_widget); connect(animation, SIGNAL(valueChanged(QVariant)), mut_widget, SLOT(update())); mut_widget->setProperty(animation_key.toUtf8().constData(), QVariant::fromValue(animation)); } if (text == tab_hover) { if (animation->state() != QAbstractAnimation::Running && fader != 40) { animation->stop(); animation->setDuration(80); animation->setEndValue(40); animation->start(); } } else { if (animation->state() != QAbstractAnimation::Running && fader != 0) { animation->stop(); animation->setDuration(160); animation->setEndValue(0); animation->start(); } } if (!selected) { p->save(); p->fillRect(draw_rect, QColor(255, 255, 255, fader)); p->setPen(QPen(QColor(255, 255, 255, fader), 1.0)); p->drawLine(draw_rect.topLeft(), vertical_tabs ? draw_rect.bottomLeft() : draw_rect.topRight()); p->drawLine(draw_rect.bottomRight(), vertical_tabs ? draw_rect.topRight() : draw_rect.bottomLeft()); p->restore(); } } Utils::StyleHelper::drawIconWithShadow(v_opt->icon, icon_rect, p, selected ? QIcon::Selected : QIcon::Normal); p->drawText(text_rect.translated(0, -1), textFlags, text); p->restore(); } void FancyTabProxyStyle::polish(QWidget* widget) { if (QString(widget->metaObject()->className()) == QLatin1String("QTabBar")) { widget->setMouseTracking(true); widget->installEventFilter(this); } QProxyStyle::polish(widget); } void FancyTabProxyStyle::polish(QApplication* app) { QProxyStyle::polish(app); } void FancyTabProxyStyle::polish(QPalette &palette) { QProxyStyle::polish(palette); } bool FancyTabProxyStyle::eventFilter(QObject* o, QEvent* e) { QTabBar* bar = qobject_cast(o); if (bar && (e->type() == QEvent::MouseMove || e->type() == QEvent::Leave)) { QMouseEvent* event = static_cast(e); const QString old_hovered_tab = bar->property("tab_hover").toString(); const QString hovered_tab = e->type() == QEvent::Leave ? QString() : bar->tabText(bar->tabAt(event->pos())); bar->setProperty("tab_hover", hovered_tab); if (old_hovered_tab != hovered_tab) { bar->update(); } } return false; } FancyTab::FancyTab(QWidget* tabbar) : QWidget(tabbar), tabbar(tabbar), m_fader(0) { animator.setPropertyName("fader"); animator.setTargetObject(this); setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum); } void FancyTab::fadeIn() { animator.stop(); animator.setDuration(80); animator.setEndValue(40); animator.start(); } void FancyTab::fadeOut() { animator.stop(); animator.setDuration(160); animator.setEndValue(0); animator.start(); } void FancyTab::setFader(float value) { m_fader = value; tabbar->update(); } FancyTabBar::FancyTabBar(QWidget* parent) : QWidget(parent) , m_currentIndex(-1) { setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding); //setStyle(new QWindowsStyle); setMinimumWidth(qMax(2 * m_rounding, 40)); setAttribute(Qt::WA_Hover, true); setFocusPolicy(Qt::NoFocus); setMouseTracking(true); // Needed for hover events m_triggerTimer.setSingleShot(true); QVBoxLayout* layout = new QVBoxLayout; layout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Fixed, QSizePolicy::Expanding)); layout->setSpacing(0); layout->setContentsMargins(0, 0, 0, 0); setLayout(layout); // We use a zerotimer to keep the sidebar responsive connect(&m_triggerTimer, SIGNAL(timeout()), this, SLOT(emitCurrentIndex())); } FancyTabBar::~FancyTabBar() { delete style(); } QSize FancyTab::sizeHint() const { QFont boldFont(font()); boldFont.setPointSizeF(Utils::StyleHelper::sidebarFontSize()); boldFont.setBold(true); QFontMetrics fm(boldFont); int spacing = 8; int width = 60 + spacing + 2; int iconHeight = 32; QSize ret(width, iconHeight + spacing + fm.height()); return ret; } QSize FancyTabBar::tabSizeHint(bool minimum) const { QFont boldFont(font()); boldFont.setPointSizeF(Utils::StyleHelper::sidebarFontSize()); boldFont.setBold(true); QFontMetrics fm(boldFont); int spacing = 8; int width = 60 + spacing + 2; int iconHeight = minimum ? 0 : 32; return QSize(width, iconHeight + spacing + fm.height()); } void FancyTabBar::paintEvent(QPaintEvent* event) { Q_UNUSED(event) QPainter p(this); for (int i = 0; i < count(); ++i) if (i != currentIndex()) { paintTab(&p, i); } // paint active tab last, since it overlaps the neighbors if (currentIndex() != -1) { paintTab(&p, currentIndex()); } } void FancyTab::enterEvent(QEvent*) { fadeIn(); } void FancyTab::leaveEvent(QEvent*) { fadeOut(); } QSize FancyTabBar::sizeHint() const { QSize sh = tabSizeHint(); return QSize(sh.width(), sh.height() * m_tabs.count()); } QSize FancyTabBar::minimumSizeHint() const { QSize sh = tabSizeHint(true); return QSize(sh.width(), sh.height() * m_tabs.count()); } QRect FancyTabBar::tabRect(int index) const { return m_tabs[index]->geometry(); } QString FancyTabBar::tabToolTip(int index) const { return m_tabs[index]->toolTip(); } void FancyTabBar::setTabToolTip(int index, const QString &toolTip) { m_tabs[index]->setToolTip(toolTip); } // This keeps the sidebar responsive since // we get a repaint before loading the // mode itself void FancyTabBar::emitCurrentIndex() { emit currentChanged(m_currentIndex); } void FancyTabBar::mousePressEvent(QMouseEvent* e) { e->accept(); for (int index = 0; index < m_tabs.count(); ++index) { if (tabRect(index).contains(e->pos())) { m_currentIndex = index; update(); m_triggerTimer.start(0); break; } } } void FancyTabBar::addTab(const QIcon &icon, const QString &label) { FancyTab* tab = new FancyTab(this); tab->icon = icon; tab->text = label; m_tabs.append(tab); qobject_cast(layout())->insertWidget(layout()->count() - 1, tab); } void FancyTabBar::addSpacer(int size) { qobject_cast(layout())->insertSpacerItem(layout()->count() - 1, new QSpacerItem(0, size, QSizePolicy::Fixed, QSizePolicy::Maximum)); } void FancyTabBar::paintTab(QPainter* painter, int tabIndex) const { if (!validIndex(tabIndex)) { qWarning("invalid index"); return; } painter->save(); QRect rect = tabRect(tabIndex); bool selected = (tabIndex == m_currentIndex); if (selected) { //background painter->save(); QLinearGradient grad(rect.topLeft(), rect.topRight()); grad.setColorAt(0, QColor(255, 255, 255, 140)); grad.setColorAt(1, QColor(255, 255, 255, 210)); painter->fillRect(rect.adjusted(0, 0, 0, -1), grad); painter->restore(); //shadows painter->setPen(QColor(0, 0, 0, 110)); painter->drawLine(rect.topLeft() + QPoint(1, -1), rect.topRight() - QPoint(0, 1)); painter->drawLine(rect.bottomLeft(), rect.bottomRight()); painter->setPen(QColor(0, 0, 0, 40)); painter->drawLine(rect.topLeft(), rect.bottomLeft()); //highlights painter->setPen(QColor(255, 255, 255, 50)); painter->drawLine(rect.topLeft() + QPoint(0, -2), rect.topRight() - QPoint(0, 2)); painter->drawLine(rect.bottomLeft() + QPoint(0, 1), rect.bottomRight() + QPoint(0, 1)); painter->setPen(QColor(255, 255, 255, 40)); painter->drawLine(rect.topLeft() + QPoint(0, 0), rect.topRight()); painter->drawLine(rect.topRight() + QPoint(0, 1), rect.bottomRight() - QPoint(0, 1)); painter->drawLine(rect.bottomLeft() + QPoint(0, -1), rect.bottomRight() - QPoint(0, 1)); } QString tabText(painter->fontMetrics().elidedText(this->tabText(tabIndex), Qt::ElideMiddle, width())); QRect tabTextRect(tabRect(tabIndex)); QRect tabIconRect(tabTextRect); tabIconRect.adjust(+4, +4, -4, -4); tabTextRect.translate(0, -2); QFont boldFont(painter->font()); boldFont.setPointSizeF(Utils::StyleHelper::sidebarFontSize()); boldFont.setBold(true); painter->setFont(boldFont); painter->setPen(selected ? QColor(255, 255, 255, 160) : QColor(0, 0, 0, 110)); int textFlags = Qt::AlignCenter | Qt::AlignBottom; painter->drawText(tabTextRect, textFlags, tabText); painter->setPen(selected ? QColor(60, 60, 60) : Utils::StyleHelper::panelTextColor()); #ifndef Q_OS_MACOS if (!selected) { painter->save(); int fader = int(m_tabs[tabIndex]->fader()); QLinearGradient grad(rect.topLeft(), rect.topRight()); grad.setColorAt(0, Qt::transparent); grad.setColorAt(0.5, QColor(255, 255, 255, fader)); grad.setColorAt(1, Qt::transparent); // painter->fillRect(rect, grad); // painter->setPen(QPen(grad, 1.0)); painter->fillRect(rect, QColor(255, 255, 255, fader)); painter->setPen(QPen(QColor(255, 255, 255, fader), 1.0)); painter->drawLine(rect.topLeft(), rect.topRight()); painter->drawLine(rect.bottomLeft(), rect.bottomRight()); painter->restore(); } #endif const int textHeight = painter->fontMetrics().height(); tabIconRect.adjust(0, 4, 0, -textHeight); Utils::StyleHelper::drawIconWithShadow(tabIcon(tabIndex), tabIconRect, painter, selected ? QIcon::Selected : QIcon::Normal); painter->translate(0, -1); painter->drawText(tabTextRect, textFlags, tabText); painter->restore(); } void FancyTabBar::setCurrentIndex(int index) { m_currentIndex = index; update(); emit currentChanged(m_currentIndex); } ////// // FancyColorButton ////// -class QUPZILLA_EXPORT FancyColorButton : public QWidget +class FALKON_EXPORT FancyColorButton : public QWidget { public: FancyColorButton(QWidget* parent) : m_parent(parent) { setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred); } void mousePressEvent(QMouseEvent* ev) { if (ev->modifiers() & Qt::ShiftModifier) { Utils::StyleHelper::setBaseColor(QColorDialog::getColor(Utils::StyleHelper::requestedBaseColor(), m_parent)); } } private: QWidget* m_parent; }; ////// // FancyTabWidget ////// FancyTabWidget::FancyTabWidget(QWidget* parent) : QWidget(parent), mode_(Mode_None), tab_bar_(NULL), stack_(new QStackedLayout), side_widget_(new QWidget), side_layout_(new QVBoxLayout), top_layout_(new QVBoxLayout), use_background_(false), menu_(NULL), proxy_style_(new FancyTabProxyStyle) { side_layout_->setSpacing(0); side_layout_->setMargin(0); side_layout_->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Fixed, QSizePolicy::Expanding)); side_widget_->setLayout(side_layout_); side_widget_->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding); top_layout_->setMargin(0); top_layout_->setSpacing(0); top_layout_->addLayout(stack_); QHBoxLayout* main_layout = new QHBoxLayout; main_layout->setMargin(0); main_layout->setSpacing(1); main_layout->addWidget(side_widget_); main_layout->addLayout(top_layout_); setLayout(main_layout); } void FancyTabWidget::AddTab(QWidget* tab, const QIcon &icon, const QString &label) { stack_->addWidget(tab); items_ << Item(icon, label); } void FancyTabWidget::AddSpacer(int size) { items_ << Item(size); } void FancyTabWidget::SetBackgroundPixmap(const QPixmap &pixmap) { background_pixmap_ = pixmap; update(); } void FancyTabWidget::paintEvent(QPaintEvent*) { if (!use_background_) { return; } QPainter painter(this); QRect rect = side_widget_->rect().adjusted(0, 0, 1, 0); rect = style()->visualRect(layoutDirection(), geometry(), rect); Utils::StyleHelper::verticalGradient(&painter, rect, rect); if (!background_pixmap_.isNull()) { QRect pixmap_rect(background_pixmap_.rect()); pixmap_rect.moveTo(rect.topLeft()); while (pixmap_rect.top() < rect.bottom()) { QRect source_rect(pixmap_rect.intersected(rect)); source_rect.moveTo(0, 0); painter.drawPixmap(pixmap_rect.topLeft(), background_pixmap_, source_rect); pixmap_rect.moveTop(pixmap_rect.bottom() - 10); } } painter.setPen(Utils::StyleHelper::borderColor()); painter.drawLine(rect.topRight(), rect.bottomRight()); QColor light = Utils::StyleHelper::sidebarHighlight(); painter.setPen(light); painter.drawLine(rect.bottomLeft(), rect.bottomRight()); } int FancyTabWidget::current_index() const { return stack_->currentIndex(); } void FancyTabWidget::SetCurrentIndex(int index) { if (FancyTabBar* bar = qobject_cast(tab_bar_)) { bar->setCurrentIndex(index); } else if (QTabBar* bar = qobject_cast(tab_bar_)) { bar->setCurrentIndex(index); } else { stack_->setCurrentIndex(index); } } void FancyTabWidget::ShowWidget(int index) { stack_->setCurrentIndex(index); emit CurrentChanged(index); } void FancyTabWidget::AddBottomWidget(QWidget* widget) { top_layout_->addWidget(widget); } void FancyTabWidget::SetMode(Mode mode) { // Remove previous tab bar delete tab_bar_; tab_bar_ = NULL; use_background_ = false; // Create new tab bar switch (mode) { case Mode_None: default: qDebug() << "Unknown fancy tab mode" << mode; // fallthrough case Mode_LargeSidebar: { FancyTabBar* bar = new FancyTabBar(this); side_layout_->insertWidget(0, bar); tab_bar_ = bar; foreach (const Item &item, items_) { if (item.type_ == Item::Type_Spacer) { bar->addSpacer(item.spacer_size_); } else { bar->addTab(item.tab_icon_, item.tab_label_); } } bar->setCurrentIndex(stack_->currentIndex()); connect(bar, SIGNAL(currentChanged(int)), SLOT(ShowWidget(int))); use_background_ = true; break; } case Mode_Tabs: MakeTabBar(QTabBar::RoundedNorth, true, false, false); break; case Mode_IconOnlyTabs: MakeTabBar(QTabBar::RoundedNorth, false, true, false); break; case Mode_SmallSidebar: MakeTabBar(QTabBar::RoundedWest, true, true, true); use_background_ = true; break; case Mode_PlainSidebar: MakeTabBar(QTabBar::RoundedWest, true, true, false); break; } tab_bar_->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); mode_ = mode; emit ModeChanged(mode); update(); } void FancyTabWidget::contextMenuEvent(QContextMenuEvent* e) { Q_UNUSED(e) // if (!menu_) { // menu_ = new QMenu(this); // QSignalMapper* mapper = new QSignalMapper(this); // QActionGroup* group = new QActionGroup(this); // AddMenuItem(mapper, group, tr("Large sidebar"), Mode_LargeSidebar); // AddMenuItem(mapper, group, tr("Small sidebar"), Mode_SmallSidebar); // AddMenuItem(mapper, group, tr("Plain sidebar"), Mode_PlainSidebar); // AddMenuItem(mapper, group, tr("Tabs on top"), Mode_Tabs); // AddMenuItem(mapper, group, tr("Icons on top"), Mode_IconOnlyTabs); // menu_->addActions(group->actions()); // connect(mapper, SIGNAL(mapped(int)), SLOT(SetMode(int))); // } // menu_->popup(e->globalPos()); } void FancyTabWidget::AddMenuItem(QSignalMapper* mapper, QActionGroup* group, const QString &text, Mode mode) { QAction* action = group->addAction(text); action->setCheckable(true); mapper->setMapping(action, mode); connect(action, SIGNAL(triggered()), mapper, SLOT(map())); if (mode == mode_) { action->setChecked(true); } } void FancyTabWidget::MakeTabBar(QTabBar::Shape shape, bool text, bool icons, bool fancy) { QTabBar* bar = new QTabBar(this); bar->setShape(shape); bar->setDocumentMode(true); bar->setUsesScrollButtons(true); if (shape == QTabBar::RoundedWest) { bar->setIconSize(QSize(22, 22)); } if (fancy) { bar->setStyle(proxy_style_); } if (shape == QTabBar::RoundedNorth) { top_layout_->insertWidget(0, bar); } else { side_layout_->insertWidget(0, bar); } foreach (const Item &item, items_) { if (item.type_ != Item::Type_Tab) { continue; } QString label = item.tab_label_; if (shape == QTabBar::RoundedWest) { label = QFontMetrics(font()).elidedText(label, Qt::ElideMiddle, 100); } int tab_id = -1; if (icons && text) { tab_id = bar->addTab(item.tab_icon_, label); } else if (icons) { tab_id = bar->addTab(item.tab_icon_, QString()); } else if (text) { tab_id = bar->addTab(label); } bar->setTabToolTip(tab_id, item.tab_label_); } bar->setCurrentIndex(stack_->currentIndex()); connect(bar, SIGNAL(currentChanged(int)), SLOT(ShowWidget(int))); tab_bar_ = bar; } diff --git a/src/lib/3rdparty/fancytabwidget.h b/src/lib/3rdparty/fancytabwidget.h index 13f853d3..68e8ffbf 100644 --- a/src/lib/3rdparty/fancytabwidget.h +++ b/src/lib/3rdparty/fancytabwidget.h @@ -1,238 +1,238 @@ /************************************************************************** ** ** This file is part of Qt Creator ** ** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). ** ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** Commercial Usage ** ** Licensees holding valid Qt Commercial licenses may use this file in ** accordance with the Qt Commercial License Agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and Nokia. ** ** GNU Lesser General Public License Usage ** ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** If you are unsure which license is appropriate for your use, please ** contact the sales department at http://qt.nokia.com/contact. ** **************************************************************************/ #ifndef FANCYTABWIDGET_H #define FANCYTABWIDGET_H #include "qzcommon.h" #include #include #include #include #include #include class QActionGroup; class QMenu; class QPainter; class QSignalMapper; class QStackedLayout; class QStatusBar; class QVBoxLayout; namespace Core { namespace Internal { -class QUPZILLA_EXPORT FancyTabProxyStyle : public QProxyStyle +class FALKON_EXPORT FancyTabProxyStyle : public QProxyStyle { Q_OBJECT public: void drawControl(ControlElement element, const QStyleOption* option, QPainter* painter, const QWidget* widget) const; void polish(QWidget* widget); void polish(QApplication* app); void polish(QPalette &palette); protected: bool eventFilter(QObject* o, QEvent* e); }; -class QUPZILLA_EXPORT FancyTab : public QWidget +class FALKON_EXPORT FancyTab : public QWidget { Q_OBJECT Q_PROPERTY(float fader READ fader WRITE setFader) public: FancyTab(QWidget* tabbar); float fader() { return m_fader; } void setFader(float value); QSize sizeHint() const; void fadeIn(); void fadeOut(); QIcon icon; QString text; protected: void enterEvent(QEvent*); void leaveEvent(QEvent*); private: QPropertyAnimation animator; QWidget* tabbar; float m_fader; }; -class QUPZILLA_EXPORT FancyTabBar : public QWidget +class FALKON_EXPORT FancyTabBar : public QWidget { Q_OBJECT public: FancyTabBar(QWidget* parent = 0); ~FancyTabBar(); void paintEvent(QPaintEvent* event); void paintTab(QPainter* painter, int tabIndex) const; void mousePressEvent(QMouseEvent*); bool validIndex(int index) const { return index >= 0 && index < m_tabs.count(); } QSize sizeHint() const; QSize minimumSizeHint() const; void addTab(const QIcon &icon, const QString &label); void addSpacer(int size = 40); void removeTab(int index) { FancyTab* tab = m_tabs.takeAt(index); delete tab; } void setCurrentIndex(int index); int currentIndex() const { return m_currentIndex; } void setTabToolTip(int index, const QString &toolTip); QString tabToolTip(int index) const; QIcon tabIcon(int index) const {return m_tabs.at(index)->icon; } QString tabText(int index) const { return m_tabs.at(index)->text; } int count() const {return m_tabs.count(); } QRect tabRect(int index) const; signals: void currentChanged(int); public slots: void emitCurrentIndex(); private: static const int m_rounding; static const int m_textPadding; int m_currentIndex; QList m_tabs; QTimer m_triggerTimer; QSize tabSizeHint(bool minimum = false) const; }; -class QUPZILLA_EXPORT FancyTabWidget : public QWidget +class FALKON_EXPORT FancyTabWidget : public QWidget { Q_OBJECT Q_PROPERTY(QPixmap bgPixmap READ bgPixmap WRITE SetBackgroundPixmap) public: FancyTabWidget(QWidget* parent = 0); // Values are persisted - only add to the end enum Mode { Mode_None = 0, Mode_LargeSidebar = 1, Mode_SmallSidebar = 2, Mode_Tabs = 3, Mode_IconOnlyTabs = 4, Mode_PlainSidebar = 5, }; struct Item { Item(const QIcon &icon, const QString &label) : type_(Type_Tab), tab_label_(label), tab_icon_(icon), spacer_size_(0) {} Item(int size) : type_(Type_Spacer), spacer_size_(size) {} enum Type { Type_Tab, Type_Spacer, }; Type type_; QString tab_label_; QIcon tab_icon_; int spacer_size_; }; void AddTab(QWidget* tab, const QIcon &icon, const QString &label); void AddSpacer(int size = 40); void SetBackgroundPixmap(const QPixmap &pixmap); void AddBottomWidget(QWidget* widget); int current_index() const; Mode mode() const { return mode_; } QPixmap bgPixmap() { return background_pixmap_; } public slots: void SetCurrentIndex(int index); void SetMode(Mode mode); void SetMode(int mode) { SetMode(Mode(mode)); } signals: void CurrentChanged(int index); void ModeChanged(FancyTabWidget::Mode mode); protected: void paintEvent(QPaintEvent* event); void contextMenuEvent(QContextMenuEvent* e); private slots: void ShowWidget(int index); private: void MakeTabBar(QTabBar::Shape shape, bool text, bool icons, bool fancy); void AddMenuItem(QSignalMapper* mapper, QActionGroup* group, const QString &text, Mode mode); Mode mode_; QList items_; QWidget* tab_bar_; QStackedLayout* stack_; QPixmap background_pixmap_; QWidget* side_widget_; QVBoxLayout* side_layout_; QVBoxLayout* top_layout_; bool use_background_; QMenu* menu_; FancyTabProxyStyle* proxy_style_; }; } // namespace Internal } // namespace Core using Core::Internal::FancyTab; using Core::Internal::FancyTabBar; using Core::Internal::FancyTabWidget; #endif // FANCYTABWIDGET_H diff --git a/src/lib/3rdparty/lineedit.h b/src/lib/3rdparty/lineedit.h index a7564728..f84fd450 100644 --- a/src/lib/3rdparty/lineedit.h +++ b/src/lib/3rdparty/lineedit.h @@ -1,162 +1,162 @@ #ifndef LINEEDIT_H #define LINEEDIT_H /** * Copyright (c) 2008 - 2009, Benjamin C. Meyer * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the Benjamin Meyer nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include #include #include "qzcommon.h" class QHBoxLayout; /* LineEdit is a subclass of QLineEdit that provides an easy and simple way to add widgets on the left or right hand side of the text. The layout of the widgets on either side are handled by a QHBoxLayout. You can set the spacing around the widgets with setWidgetSpacing(). As widgets are added to the class they are inserted from the outside into the center of the widget. */ class SideWidget; -class QUPZILLA_EXPORT LineEdit : public QLineEdit +class FALKON_EXPORT LineEdit : public QLineEdit { Q_OBJECT Q_PROPERTY(QSize fixedsize READ size WRITE setFixedSize) Q_PROPERTY(int leftMargin READ leftMargin WRITE setLeftMargin) Q_PROPERTY(int fixedwidth READ width WRITE setFixedWidth) Q_PROPERTY(int fixedheight READ height WRITE setFixedHeight) Q_PROPERTY(int minHeight READ minHeight WRITE setMinHeight) public: typedef QList TextFormat; enum WidgetPosition { LeftSide, RightSide }; enum EditAction { Undo = 0, Redo = 1, Cut = 2, Copy = 3, Paste = 4, PasteAndGo = 5, Delete = 6, ClearAll = 7, SelectAll = 8 }; LineEdit(QWidget* parent = 0); void addWidget(QWidget* widget, WidgetPosition position); void removeWidget(QWidget* widget); void setWidgetSpacing(int spacing); int widgetSpacing() const; int leftMargin() const; void setTextFormat(const TextFormat &format); void clearTextFormat(); int minHeight() const; void setMinHeight(int height); QSize sizeHint() const; QAction* editAction(EditAction action) const; public slots: void setLeftMargin(int margin); void updateTextMargins(); protected: void focusInEvent(QFocusEvent* event); void mousePressEvent(QMouseEvent* event); void mouseReleaseEvent(QMouseEvent* event); void mouseDoubleClickEvent(QMouseEvent* event); void resizeEvent(QResizeEvent *event) override; bool event(QEvent* event); QMenu* createContextMenu(); private slots: void updateActions(); void updatePasteActions(); void slotDelete(); private: void init(); SideWidget* m_leftWidget; SideWidget* m_rightWidget; QHBoxLayout* m_leftLayout; QHBoxLayout* m_rightLayout; QHBoxLayout* mainLayout; QAction* m_editActions[9]; int m_minHeight; int m_leftMargin; bool m_ignoreMousePress; }; -class QUPZILLA_EXPORT SideWidget : public QWidget +class FALKON_EXPORT SideWidget : public QWidget { Q_OBJECT signals: void sizeHintChanged(); public: SideWidget(QWidget* parent = 0); protected: bool event(QEvent* event); }; #endif // LINEEDIT_H diff --git a/src/lib/3rdparty/processinfo.cpp b/src/lib/3rdparty/processinfo.cpp index 2d550195..e42c4992 100644 --- a/src/lib/3rdparty/processinfo.cpp +++ b/src/lib/3rdparty/processinfo.cpp @@ -1,119 +1,119 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "processinfo.h" #if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) #include #include #include #include #include #include #include #include #endif ProcessInfo::ProcessInfo(const QString &name) : m_name(name) { } bool ProcessInfo::isRunning() const { #if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) pid_t pid = GetPIDbyName(qPrintable(m_name)); // -1 = process not found // -2 = /proc fs access error return (pid != -1 && pid != -2); #else return false; #endif } #if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) bool ProcessInfo::IsNumeric(const char* ccharptr_CharacterList) const { for (; *ccharptr_CharacterList; ccharptr_CharacterList++) { if (*ccharptr_CharacterList < '0' || *ccharptr_CharacterList > '9') { return false; } } return true; } pid_t ProcessInfo::GetPIDbyName(const char* cchrptr_ProcessName) const { char chrarry_CommandLinePath[260] ; char chrarry_NameOfProcess[300] ; char* chrptr_StringToCompare = NULL ; pid_t pid_ProcessIdentifier = (pid_t) - 1 ; struct dirent* de_DirEntity = NULL ; DIR* dir_proc = NULL ; dir_proc = opendir("/proc/") ; if (dir_proc == NULL) { perror("Couldn't open the /proc/ directory") ; return (pid_t) - 2 ; } // Loop while not NULL while ((de_DirEntity = readdir(dir_proc))) { #ifndef __HAIKU__ if (de_DirEntity->d_type == DT_DIR) { if (IsNumeric(de_DirEntity->d_name)) { strcpy(chrarry_CommandLinePath, "/proc/") ; strcat(chrarry_CommandLinePath, de_DirEntity->d_name) ; strcat(chrarry_CommandLinePath, "/cmdline") ; FILE* fd_CmdLineFile = fopen(chrarry_CommandLinePath, "rt") ; // open the file for reading text if (fd_CmdLineFile) { int r = fscanf(fd_CmdLineFile, "%20s", chrarry_NameOfProcess) ; // read from /proc//cmdline fclose(fd_CmdLineFile); // close the file prior to exiting the routine if (r < 1) { continue; } if (strrchr(chrarry_NameOfProcess, '/')) { chrptr_StringToCompare = strrchr(chrarry_NameOfProcess, '/') + 1 ; } else { chrptr_StringToCompare = chrarry_NameOfProcess ; } //printf("Process name: %s\n", chrarry_NameOfProcess); //printf("Pure Process name: %s\n", chrptr_StringToCompare ); if (!strcmp(chrptr_StringToCompare, cchrptr_ProcessName)) { pid_ProcessIdentifier = (pid_t) atoi(de_DirEntity->d_name) ; closedir(dir_proc) ; return pid_ProcessIdentifier ; } } } } #endif } closedir(dir_proc) ; return pid_ProcessIdentifier ; } #endif diff --git a/src/lib/3rdparty/processinfo.h b/src/lib/3rdparty/processinfo.h index f9218b53..13026f2a 100644 --- a/src/lib/3rdparty/processinfo.h +++ b/src/lib/3rdparty/processinfo.h @@ -1,52 +1,52 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef PROCESSINFO_H #define PROCESSINFO_H #include #if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) #include #endif #include #include "qzcommon.h" /* * Code used from http://ubuntuforums.org/showpost.php?p=6593782&postcount=5 * written by user WitchCraft */ -class QUPZILLA_EXPORT ProcessInfo +class FALKON_EXPORT ProcessInfo { public: explicit ProcessInfo(const QString &name); bool isRunning() const; private: #if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) bool IsNumeric(const char* ccharptr_CharacterList) const; pid_t GetPIDbyName(const char* cchrptr_ProcessName) const; #endif QString m_name; }; #endif // PROCESSINFO_H diff --git a/src/lib/3rdparty/squeezelabelv1.h b/src/lib/3rdparty/squeezelabelv1.h index 60352963..4c1bd445 100644 --- a/src/lib/3rdparty/squeezelabelv1.h +++ b/src/lib/3rdparty/squeezelabelv1.h @@ -1,54 +1,54 @@ /** * Copyright (c) 2009, Benjamin C. Meyer * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the Benjamin Meyer nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef SQUEEZELABELV1_H #define SQUEEZELABELV1_H #include "qzcommon.h" #include /* A label that will squeeze the set text to fit within the size of the widget. The text will be elided in the middle. */ -class QUPZILLA_EXPORT SqueezeLabelV1 : public QLabel +class FALKON_EXPORT SqueezeLabelV1 : public QLabel { Q_OBJECT public: SqueezeLabelV1(QWidget* parent = 0); protected: void paintEvent(QPaintEvent* event); private: QString m_SqueezedTextCache; }; #endif // SQUEEZELABELV1_H diff --git a/src/lib/3rdparty/squeezelabelv2.h b/src/lib/3rdparty/squeezelabelv2.h index 7fe1c1d9..ce5cbe32 100644 --- a/src/lib/3rdparty/squeezelabelv2.h +++ b/src/lib/3rdparty/squeezelabelv2.h @@ -1,52 +1,52 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef SQUEEZELABELV2_H #define SQUEEZELABELV2_H #include "qzcommon.h" #include -class QUPZILLA_EXPORT SqueezeLabelV2 : public QLabel +class FALKON_EXPORT SqueezeLabelV2 : public QLabel { Q_OBJECT public: SqueezeLabelV2(QWidget* parent = 0); SqueezeLabelV2(const QString &string); QString originalText(); void setText(const QString &txt); private slots: void copy(); protected: void contextMenuEvent(QContextMenuEvent* event); void keyPressEvent(QKeyEvent* event); void resizeEvent(QResizeEvent* event); void mousePressEvent(QMouseEvent* event); void mouseMoveEvent(QMouseEvent* event); private: QString m_originalText; QPoint m_dragStart; }; #endif // SQUEEZELABELV2_H diff --git a/src/lib/adblock/adblockaddsubscriptiondialog.cpp b/src/lib/adblock/adblockaddsubscriptiondialog.cpp index 7571eb7e..db89ce10 100644 --- a/src/lib/adblock/adblockaddsubscriptiondialog.cpp +++ b/src/lib/adblock/adblockaddsubscriptiondialog.cpp @@ -1,91 +1,91 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "adblockaddsubscriptiondialog.h" #include "ui_adblockaddsubscriptiondialog.h" AdBlockAddSubscriptionDialog::AdBlockAddSubscriptionDialog(QWidget* parent) : QDialog(parent) , ui(new Ui::AdBlockAddSubscriptionDialog) { ui->setupUi(this); m_knownSubscriptions << Subscription("EasyList (English)", ADBLOCK_EASYLIST_URL) << Subscription("BSI Lista Polska (Polish)", "http://www.bsi.info.pl/filtrABP.txt") << Subscription("Czech List (Czech)", "http://adblock.dajbych.net/adblock.txt") << Subscription("dutchblock (Dutch)", "http://groenewoudt.net/dutchblock/list.txt") << Subscription("Filtros Nauscopicos (Spanish)", "http://abp.mozilla-hispano.org/nauscopio/filtros.txt") << Subscription("IsraelList (Hebrew)", "http://secure.fanboy.co.nz/israelilist/IsraelList.txt") << Subscription("NLBlock (Dutch)", "http://www.verzijlbergh.com/adblock/nlblock.txt") << Subscription("Peter Lowe's list (English)", "http://pgl.yoyo.org/adservers/serverlist.php?hostformat=adblockplus&mimetype=plaintext") << Subscription("PLgeneral (Polish)", "http://www.niecko.pl/adblock/adblock.txt") << Subscription("Schacks Adblock Plus liste (Danish)", "http://adblock.schack.dk/block.txt") << Subscription("Xfiles (Italian)", "http://mozilla.gfsolone.com/filtri.txt") << Subscription("EasyPrivacy (English)", "http://easylist-downloads.adblockplus.org/easyprivacy.txt") << Subscription("RU Adlist (Russian)", "https://easylist-downloads.adblockplus.org/advblock.txt") << Subscription("ABPindo (Indonesian)", "https://raw.githubusercontent.com/heradhis/indonesianadblockrules/master/subscriptions/abpindo.txt") << Subscription("Easylist China (Chinese)", "https://easylist-downloads.adblockplus.org/easylistchina.txt") << Subscription("Anti-Adblock Killer", "https://raw.githubusercontent.com/reek/anti-adblock-killer/master/anti-adblock-killer-filters.txt") << Subscription(tr("Other..."), QString()); foreach (const Subscription &subscription, m_knownSubscriptions) { ui->comboBox->addItem(subscription.title); } connect(ui->comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(indexChanged(int))); indexChanged(0); } QString AdBlockAddSubscriptionDialog::title() const { return ui->title->text(); } QString AdBlockAddSubscriptionDialog::url() const { return ui->url->text(); } void AdBlockAddSubscriptionDialog::indexChanged(int index) { const Subscription subscription = m_knownSubscriptions.at(index); // "Other..." entry if (subscription.url.isEmpty()) { ui->title->clear(); ui->url->clear(); } else { int pos = subscription.title.indexOf(QLatin1Char('(')); QString title = subscription.title; if (pos > 0) { title = title.left(pos).trimmed(); } ui->title->setText(title); ui->title->setCursorPosition(0); ui->url->setText(subscription.url); ui->url->setCursorPosition(0); } } AdBlockAddSubscriptionDialog::~AdBlockAddSubscriptionDialog() { delete ui; } diff --git a/src/lib/adblock/adblockaddsubscriptiondialog.h b/src/lib/adblock/adblockaddsubscriptiondialog.h index f8125d67..7fbea826 100644 --- a/src/lib/adblock/adblockaddsubscriptiondialog.h +++ b/src/lib/adblock/adblockaddsubscriptiondialog.h @@ -1,63 +1,63 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef ADBLOCKADDSUBSCRIPTIONDIALOG_H #define ADBLOCKADDSUBSCRIPTIONDIALOG_H #include #include #include "qzcommon.h" namespace Ui { class AdBlockAddSubscriptionDialog; } -class QUPZILLA_EXPORT AdBlockAddSubscriptionDialog : public QDialog +class FALKON_EXPORT AdBlockAddSubscriptionDialog : public QDialog { Q_OBJECT public: explicit AdBlockAddSubscriptionDialog(QWidget* parent = 0); ~AdBlockAddSubscriptionDialog(); QString title() const; QString url() const; private slots: void indexChanged(int index); private: Ui::AdBlockAddSubscriptionDialog* ui; struct Subscription { QString title; QString url; Subscription() {} Subscription(const QString &t, const QString &u) { title = t; url = u; } }; QVector m_knownSubscriptions; }; #endif // ADBLOCKADDSUBSCRIPTIONDIALOG_H diff --git a/src/lib/adblock/adblockdialog.cpp b/src/lib/adblock/adblockdialog.cpp index c05bda16..bb94154e 100644 --- a/src/lib/adblock/adblockdialog.cpp +++ b/src/lib/adblock/adblockdialog.cpp @@ -1,185 +1,185 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "adblockdialog.h" #include "adblockmanager.h" #include "adblocksubscription.h" #include "adblocktreewidget.h" #include "adblockaddsubscriptiondialog.h" #include "mainapplication.h" #include "qztools.h" #include #include #include #include AdBlockDialog::AdBlockDialog(QWidget* parent) : QWidget(parent) , m_manager(AdBlockManager::instance()) , m_currentTreeWidget(0) , m_currentSubscription(0) , m_loaded(false) { setAttribute(Qt::WA_DeleteOnClose); setupUi(this); QzTools::centerWidgetOnScreen(this); #ifdef Q_OS_MACOS tabWidget->setDocumentMode(false); #endif adblockCheckBox->setChecked(m_manager->isEnabled()); QMenu* menu = new QMenu(buttonOptions); m_actionAddRule = menu->addAction(tr("Add Rule"), this, SLOT(addRule())); m_actionRemoveRule = menu->addAction(tr("Remove Rule"), this, SLOT(removeRule())); menu->addSeparator(); m_actionAddSubscription = menu->addAction(tr("Add Subscription"), this, SLOT(addSubscription())); m_actionRemoveSubscription = menu->addAction(tr("Remove Subscription"), this, SLOT(removeSubscription())); menu->addAction(tr("Update Subscriptions"), m_manager, SLOT(updateAllSubscriptions())); menu->addSeparator(); menu->addAction(tr("Learn about writing rules..."), this, SLOT(learnAboutRules())); buttonOptions->setMenu(menu); connect(menu, SIGNAL(aboutToShow()), this, SLOT(aboutToShowMenu())); connect(adblockCheckBox, SIGNAL(toggled(bool)), this, SLOT(enableAdBlock(bool))); connect(search, SIGNAL(textChanged(QString)), this, SLOT(filterString(QString))); connect(tabWidget, SIGNAL(currentChanged(int)), this, SLOT(currentChanged(int))); connect(buttonBox, SIGNAL(accepted()), this, SLOT(close())); load(); buttonBox->setFocus(); } void AdBlockDialog::showRule(const AdBlockRule* rule) const { AdBlockSubscription* subscription = rule->subscription(); if (!subscription) { return; } for (int i = 0; i < tabWidget->count(); ++i) { AdBlockTreeWidget* treeWidget = qobject_cast(tabWidget->widget(i)); if (subscription == treeWidget->subscription()) { treeWidget->showRule(rule); tabWidget->setCurrentIndex(i); break; } } } void AdBlockDialog::addRule() { m_currentTreeWidget->addRule(); } void AdBlockDialog::removeRule() { m_currentTreeWidget->removeRule(); } void AdBlockDialog::addSubscription() { AdBlockAddSubscriptionDialog dialog(this); if (dialog.exec() != QDialog::Accepted) { return; } QString title = dialog.title(); QString url = dialog.url(); if (AdBlockSubscription* subscription = m_manager->addSubscription(title, url)) { AdBlockTreeWidget* tree = new AdBlockTreeWidget(subscription, tabWidget); int index = tabWidget->insertTab(tabWidget->count() - 1, tree, subscription->title()); tabWidget->setCurrentIndex(index); } } void AdBlockDialog::removeSubscription() { if (m_manager->removeSubscription(m_currentSubscription)) { delete m_currentTreeWidget; } } void AdBlockDialog::currentChanged(int index) { if (index != -1) { m_currentTreeWidget = qobject_cast(tabWidget->widget(index)); m_currentSubscription = m_currentTreeWidget->subscription(); } } void AdBlockDialog::filterString(const QString &string) { if (m_currentTreeWidget && adblockCheckBox->isChecked()) { m_currentTreeWidget->filterString(string); } } void AdBlockDialog::enableAdBlock(bool state) { m_manager->setEnabled(state); if (state) { load(); } } void AdBlockDialog::aboutToShowMenu() { bool subscriptionEditable = m_currentSubscription && m_currentSubscription->canEditRules(); bool subscriptionRemovable = m_currentSubscription && m_currentSubscription->canBeRemoved(); m_actionAddRule->setEnabled(subscriptionEditable); m_actionRemoveRule->setEnabled(subscriptionEditable); m_actionRemoveSubscription->setEnabled(subscriptionRemovable); } void AdBlockDialog::learnAboutRules() { mApp->addNewTab(QUrl("http://adblockplus.org/en/filters")); } void AdBlockDialog::loadSubscriptions() { for (int i = 0; i < tabWidget->count(); ++i) { AdBlockTreeWidget* treeWidget = qobject_cast(tabWidget->widget(i)); treeWidget->refresh(); } } void AdBlockDialog::load() { if (m_loaded || !adblockCheckBox->isChecked()) { return; } foreach (AdBlockSubscription* subscription, m_manager->subscriptions()) { AdBlockTreeWidget* tree = new AdBlockTreeWidget(subscription, tabWidget); tabWidget->addTab(tree, subscription->title()); } m_loaded = true; QTimer::singleShot(50, this, SLOT(loadSubscriptions())); } diff --git a/src/lib/adblock/adblockdialog.h b/src/lib/adblock/adblockdialog.h index ce1725de..886ebb75 100644 --- a/src/lib/adblock/adblockdialog.h +++ b/src/lib/adblock/adblockdialog.h @@ -1,71 +1,71 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef ADBLOCKDIALOG_H #define ADBLOCKDIALOG_H #include #include "qzcommon.h" #include "ui_adblockdialog.h" class AdBlockSubscription; class AdBlockTreeWidget; class AdBlockManager; class AdBlockRule; -class QUPZILLA_EXPORT AdBlockDialog : public QWidget, public Ui_AdBlockDialog +class FALKON_EXPORT AdBlockDialog : public QWidget, public Ui_AdBlockDialog { Q_OBJECT public: explicit AdBlockDialog(QWidget* parent = 0); void showRule(const AdBlockRule* rule) const; private slots: void addRule(); void removeRule(); void addSubscription(); void removeSubscription(); void currentChanged(int index); void filterString(const QString &string); void enableAdBlock(bool state); void aboutToShowMenu(); void learnAboutRules(); void loadSubscriptions(); void load(); private: AdBlockManager* m_manager; AdBlockTreeWidget* m_currentTreeWidget; AdBlockSubscription* m_currentSubscription; QAction* m_actionAddRule; QAction* m_actionRemoveRule; QAction* m_actionAddSubscription; QAction* m_actionRemoveSubscription; bool m_loaded; }; #endif // ADBLOCKDIALOG_H diff --git a/src/lib/adblock/adblockicon.cpp b/src/lib/adblock/adblockicon.cpp index 26be3268..56c1c220 100644 --- a/src/lib/adblock/adblockicon.cpp +++ b/src/lib/adblock/adblockicon.cpp @@ -1,217 +1,217 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "adblockicon.h" #include "adblockrule.h" #include "adblockmanager.h" #include "adblocksubscription.h" #include "mainapplication.h" #include "browserwindow.h" #include "webpage.h" #include "tabbedwebview.h" #include "tabwidget.h" #include "desktopnotificationsfactory.h" #include "qztools.h" #include #include AdBlockIcon::AdBlockIcon(BrowserWindow* window, QWidget* parent) : ClickableLabel(parent) , m_window(window) , m_menuAction(0) , m_flashTimer(0) , m_timerTicks(0) , m_enabled(false) { setCursor(Qt::PointingHandCursor); setToolTip(tr("AdBlock lets you block unwanted content on web pages")); setFixedSize(16, 16); connect(this, SIGNAL(clicked(QPoint)), this, SLOT(showMenu(QPoint))); connect(AdBlockManager::instance(), SIGNAL(enabledChanged(bool)), this, SLOT(setEnabled(bool))); } AdBlockIcon::~AdBlockIcon() { for (int i = 0; i < m_blockedPopups.count(); ++i) delete m_blockedPopups.at(i).first; } void AdBlockIcon::popupBlocked(const QString &ruleString, const QUrl &url) { int index = ruleString.lastIndexOf(QLatin1String(" (")); const QString subscriptionName = ruleString.left(index); const QString filter = ruleString.mid(index + 2, ruleString.size() - index - 3); AdBlockSubscription* subscription = AdBlockManager::instance()->subscriptionByName(subscriptionName); if (filter.isEmpty() || !subscription) { return; } QPair pair; pair.first = new AdBlockRule(filter, subscription); pair.second = url; m_blockedPopups.append(pair); mApp->desktopNotifications()->showNotification(QPixmap(":html/adblock_big.png"), tr("Blocked popup window"), tr("AdBlock blocked unwanted popup window.")); if (!m_flashTimer) { m_flashTimer = new QTimer(this); } if (m_flashTimer->isActive()) { stopAnimation(); } m_flashTimer->setInterval(500); m_flashTimer->start(); connect(m_flashTimer, SIGNAL(timeout()), this, SLOT(animateIcon())); } QAction* AdBlockIcon::menuAction() { if (!m_menuAction) { m_menuAction = new QAction(tr("AdBlock"), this); m_menuAction->setMenu(new QMenu); connect(m_menuAction->menu(), SIGNAL(aboutToShow()), this, SLOT(createMenu())); } m_menuAction->setIcon(QIcon(m_enabled ? ":icons/other/adblock.png" : ":icons/other/adblock-disabled.png")); return m_menuAction; } void AdBlockIcon::createMenu(QMenu* menu) { if (!menu) { menu = qobject_cast(sender()); if (!menu) { return; } } menu->clear(); AdBlockManager* manager = AdBlockManager::instance(); AdBlockCustomList* customList = manager->customList(); WebPage* page = m_window->weView()->page(); const QUrl pageUrl = page->url(); menu->addAction(tr("Show AdBlock &Settings"), manager, SLOT(showDialog())); menu->addSeparator(); if (!pageUrl.host().isEmpty() && m_enabled && manager->canRunOnScheme(pageUrl.scheme())) { const QString host = page->url().host().contains(QLatin1String("www.")) ? pageUrl.host().mid(4) : pageUrl.host(); const QString hostFilter = QString("@@||%1^$document").arg(host); const QString pageFilter = QString("@@|%1|$document").arg(pageUrl.toString()); QAction* act = menu->addAction(tr("Disable on %1").arg(host)); act->setCheckable(true); act->setChecked(customList->containsFilter(hostFilter)); act->setData(hostFilter); connect(act, SIGNAL(triggered()), this, SLOT(toggleCustomFilter())); act = menu->addAction(tr("Disable only on this page")); act->setCheckable(true); act->setChecked(customList->containsFilter(pageFilter)); act->setData(pageFilter); connect(act, SIGNAL(triggered()), this, SLOT(toggleCustomFilter())); menu->addSeparator(); } if (!m_blockedPopups.isEmpty()) { menu->addAction(tr("Blocked Popup Windows"))->setEnabled(false); for (int i = 0; i < m_blockedPopups.count(); i++) { const QPair &pair = m_blockedPopups.at(i); QString address = pair.second.toString().right(55); QString actionText = tr("%1 with (%2)").arg(address, pair.first->filter()).replace(QLatin1Char('&'), QLatin1String("&&")); QAction* action = menu->addAction(actionText, manager, SLOT(showRule())); action->setData(QVariant::fromValue((void*)pair.first)); } } } void AdBlockIcon::showMenu(const QPoint &pos) { QMenu menu; createMenu(&menu); menu.exec(pos); } void AdBlockIcon::toggleCustomFilter() { QAction* action = qobject_cast(sender()); if (!action) { return; } const QString filter = action->data().toString(); AdBlockManager* manager = AdBlockManager::instance(); AdBlockCustomList* customList = manager->customList(); if (customList->containsFilter(filter)) { customList->removeFilter(filter); } else { AdBlockRule* rule = new AdBlockRule(filter, customList); customList->addRule(rule); } } void AdBlockIcon::animateIcon() { ++m_timerTicks; if (m_timerTicks > 10) { stopAnimation(); return; } if (pixmap()->isNull()) { setPixmap(QIcon(QSL(":icons/other/adblock.png")).pixmap(16)); } else { setPixmap(QPixmap()); } } void AdBlockIcon::stopAnimation() { m_timerTicks = 0; m_flashTimer->stop(); disconnect(m_flashTimer, SIGNAL(timeout()), this, SLOT(animateIcon())); setEnabled(m_enabled); } void AdBlockIcon::setEnabled(bool enabled) { if (enabled) { setPixmap(QIcon(QSL(":icons/other/adblock.png")).pixmap(16)); } else { setPixmap(QIcon(QSL(":icons/other/adblock-disabled.png")).pixmap(16)); } m_enabled = enabled; } diff --git a/src/lib/adblock/adblockicon.h b/src/lib/adblock/adblockicon.h index 2b1897c2..455e2a5a 100644 --- a/src/lib/adblock/adblockicon.h +++ b/src/lib/adblock/adblockicon.h @@ -1,62 +1,62 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef ADBLOCKICON_H #define ADBLOCKICON_H #include "qzcommon.h" #include "clickablelabel.h" #include "adblockrule.h" class QMenu; class QUrl; class BrowserWindow; -class QUPZILLA_EXPORT AdBlockIcon : public ClickableLabel +class FALKON_EXPORT AdBlockIcon : public ClickableLabel { Q_OBJECT public: explicit AdBlockIcon(BrowserWindow* window, QWidget* parent = 0); ~AdBlockIcon(); void popupBlocked(const QString &ruleString, const QUrl &url); QAction* menuAction(); public slots: void setEnabled(bool enabled); void createMenu(QMenu* menu = 0); private slots: void showMenu(const QPoint &pos); void toggleCustomFilter(); void animateIcon(); void stopAnimation(); private: BrowserWindow* m_window; QAction* m_menuAction; QVector > m_blockedPopups; QTimer* m_flashTimer; int m_timerTicks; bool m_enabled; }; #endif // ADBLOCKICON_H diff --git a/src/lib/adblock/adblockmanager.cpp b/src/lib/adblock/adblockmanager.cpp index df3a9e57..5530dc9e 100644 --- a/src/lib/adblock/adblockmanager.cpp +++ b/src/lib/adblock/adblockmanager.cpp @@ -1,449 +1,449 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "adblockmanager.h" #include "adblockdialog.h" #include "adblockmatcher.h" #include "adblocksubscription.h" #include "adblockurlinterceptor.h" #include "datapaths.h" #include "mainapplication.h" #include "webpage.h" #include "qztools.h" #include "browserwindow.h" #include "settings.h" #include "networkmanager.h" #include #include #include #include #include #include #include #include //#define ADBLOCK_DEBUG #ifdef ADBLOCK_DEBUG #include #endif Q_GLOBAL_STATIC(AdBlockManager, qz_adblock_manager) AdBlockManager::AdBlockManager(QObject* parent) : QObject(parent) , m_loaded(false) , m_enabled(true) , m_matcher(new AdBlockMatcher(this)) , m_interceptor(new AdBlockUrlInterceptor(this)) { load(); } AdBlockManager::~AdBlockManager() { qDeleteAll(m_subscriptions); } AdBlockManager* AdBlockManager::instance() { return qz_adblock_manager(); } void AdBlockManager::setEnabled(bool enabled) { if (m_enabled == enabled) { return; } m_enabled = enabled; emit enabledChanged(enabled); Settings settings; settings.beginGroup("AdBlock"); settings.setValue("enabled", m_enabled); settings.endGroup(); load(); mApp->reloadUserStyleSheet(); QMutexLocker locker(&m_mutex); if (m_enabled) { m_matcher->update(); } else { m_matcher->clear(); } } QList AdBlockManager::subscriptions() const { return m_subscriptions; } bool AdBlockManager::block(QWebEngineUrlRequestInfo &request) { QMutexLocker locker(&m_mutex); if (!isEnabled()) { return false; } #ifdef ADBLOCK_DEBUG QElapsedTimer timer; timer.start(); #endif const QString urlString = request.requestUrl().toEncoded().toLower(); const QString urlDomain = request.requestUrl().host().toLower(); const QString urlScheme = request.requestUrl().scheme().toLower(); if (!canRunOnScheme(urlScheme) || !canBeBlocked(request.firstPartyUrl())) { return false; } bool res = false; const AdBlockRule* blockedRule = m_matcher->match(request, urlDomain, urlString); if (blockedRule) { res = true; if (request.resourceType() == QWebEngineUrlRequestInfo::ResourceTypeMainFrame) { - QUrl url(QSL("qupzilla:adblock")); + QUrl url(QSL("falkon:adblock")); QUrlQuery query; query.addQueryItem(QSL("rule"), blockedRule->filter()); query.addQueryItem(QSL("subscription"), blockedRule->subscription()->title()); url.setQuery(query); request.redirect(url); } else { request.block(true); } #ifdef ADBLOCK_DEBUG qDebug() << "BLOCKED: " << timer.elapsed() << blockedRule->filter() << request.requestUrl(); #endif } #ifdef ADBLOCK_DEBUG qDebug() << timer.elapsed() << request.requestUrl(); #endif return res; } QStringList AdBlockManager::disabledRules() const { return m_disabledRules; } void AdBlockManager::addDisabledRule(const QString &filter) { m_disabledRules.append(filter); } void AdBlockManager::removeDisabledRule(const QString &filter) { m_disabledRules.removeOne(filter); } bool AdBlockManager::addSubscriptionFromUrl(const QUrl &url) { const QList > queryItems = QUrlQuery(url).queryItems(QUrl::FullyDecoded); QString subscriptionTitle; QString subscriptionUrl; for (int i = 0; i < queryItems.count(); ++i) { QPair pair = queryItems.at(i); if (pair.first == QL1S("location")) subscriptionUrl = pair.second; else if (pair.first == QL1S("title")) subscriptionTitle = pair.second; } if (subscriptionTitle.isEmpty() || subscriptionUrl.isEmpty()) return false; const QString message = AdBlockManager::tr("Do you want to add %1 subscription?").arg(subscriptionTitle); QMessageBox::StandardButton result = QMessageBox::question(0, AdBlockManager::tr("AdBlock Subscription"), message, QMessageBox::Yes | QMessageBox::No); if (result == QMessageBox::Yes) { AdBlockManager::instance()->addSubscription(subscriptionTitle, subscriptionUrl); AdBlockManager::instance()->showDialog(); } return true; } AdBlockSubscription* AdBlockManager::addSubscription(const QString &title, const QString &url) { if (title.isEmpty() || url.isEmpty()) { return 0; } QString fileName = QzTools::filterCharsFromFilename(title.toLower()) + ".txt"; QString filePath = QzTools::ensureUniqueFilename(DataPaths::currentProfilePath() + "/adblock/" + fileName); QByteArray data = QString("Title: %1\nUrl: %2\n[Adblock Plus 1.1.1]").arg(title, url).toLatin1(); QSaveFile file(filePath); if (!file.open(QFile::WriteOnly)) { qWarning() << "AdBlockManager: Cannot write to file" << filePath; return 0; } file.write(data); file.commit(); AdBlockSubscription* subscription = new AdBlockSubscription(title, this); subscription->setUrl(QUrl(url)); subscription->setFilePath(filePath); subscription->loadSubscription(m_disabledRules); m_subscriptions.insert(m_subscriptions.count() - 1, subscription); connect(subscription, SIGNAL(subscriptionUpdated()), mApp, SLOT(reloadUserStyleSheet())); connect(subscription, SIGNAL(subscriptionChanged()), this, SLOT(updateMatcher())); return subscription; } bool AdBlockManager::removeSubscription(AdBlockSubscription* subscription) { QMutexLocker locker(&m_mutex); if (!m_subscriptions.contains(subscription) || !subscription->canBeRemoved()) { return false; } QFile(subscription->filePath()).remove(); m_subscriptions.removeOne(subscription); m_matcher->update(); delete subscription; return true; } AdBlockCustomList* AdBlockManager::customList() const { foreach (AdBlockSubscription* subscription, m_subscriptions) { AdBlockCustomList* list = qobject_cast(subscription); if (list) { return list; } } return 0; } void AdBlockManager::load() { QMutexLocker locker(&m_mutex); if (m_loaded) { return; } #ifdef ADBLOCK_DEBUG QElapsedTimer timer; timer.start(); #endif Settings settings; settings.beginGroup("AdBlock"); m_enabled = settings.value("enabled", m_enabled).toBool(); m_disabledRules = settings.value("disabledRules", QStringList()).toStringList(); QDateTime lastUpdate = settings.value("lastUpdate", QDateTime()).toDateTime(); settings.endGroup(); if (!m_enabled) { return; } QDir adblockDir(DataPaths::currentProfilePath() + "/adblock"); // Create if neccessary if (!adblockDir.exists()) { QDir(DataPaths::currentProfilePath()).mkdir("adblock"); } foreach (const QString &fileName, adblockDir.entryList(QStringList("*.txt"), QDir::Files)) { if (fileName == QLatin1String("customlist.txt")) { continue; } const QString absolutePath = adblockDir.absoluteFilePath(fileName); QFile file(absolutePath); if (!file.open(QFile::ReadOnly)) { continue; } QTextStream textStream(&file); textStream.setCodec("UTF-8"); QString title = textStream.readLine(1024).remove(QLatin1String("Title: ")); QUrl url = QUrl(textStream.readLine(1024).remove(QLatin1String("Url: "))); if (title.isEmpty() || !url.isValid()) { qWarning() << "AdBlockManager: Invalid subscription file" << absolutePath; continue; } AdBlockSubscription* subscription = new AdBlockSubscription(title, this); subscription->setUrl(url); subscription->setFilePath(absolutePath); m_subscriptions.append(subscription); } // Prepend EasyList if subscriptions are empty if (m_subscriptions.isEmpty()) { AdBlockSubscription* easyList = new AdBlockSubscription(tr("EasyList"), this); easyList->setUrl(QUrl(ADBLOCK_EASYLIST_URL)); easyList->setFilePath(DataPaths::currentProfilePath() + QLatin1String("/adblock/easylist.txt")); m_subscriptions.prepend(easyList); } // Append CustomList AdBlockCustomList* customList = new AdBlockCustomList(this); m_subscriptions.append(customList); // Load all subscriptions foreach (AdBlockSubscription* subscription, m_subscriptions) { subscription->loadSubscription(m_disabledRules); connect(subscription, SIGNAL(subscriptionUpdated()), mApp, SLOT(reloadUserStyleSheet())); connect(subscription, SIGNAL(subscriptionChanged()), this, SLOT(updateMatcher())); } if (lastUpdate.addDays(5) < QDateTime::currentDateTime()) { QTimer::singleShot(1000 * 60, this, SLOT(updateAllSubscriptions())); } #ifdef ADBLOCK_DEBUG qDebug() << "AdBlock loaded in" << timer.elapsed(); #endif m_matcher->update(); m_loaded = true; mApp->networkManager()->installUrlInterceptor(m_interceptor); } void AdBlockManager::updateMatcher() { QMutexLocker locker(&m_mutex); m_matcher->update(); } void AdBlockManager::updateAllSubscriptions() { foreach (AdBlockSubscription* subscription, m_subscriptions) { subscription->updateSubscription(); } Settings settings; settings.beginGroup("AdBlock"); settings.setValue("lastUpdate", QDateTime::currentDateTime()); settings.endGroup(); } void AdBlockManager::save() { if (!m_loaded) { return; } foreach (AdBlockSubscription* subscription, m_subscriptions) { subscription->saveSubscription(); } Settings settings; settings.beginGroup("AdBlock"); settings.setValue("enabled", m_enabled); settings.setValue("disabledRules", m_disabledRules); settings.endGroup(); } bool AdBlockManager::isEnabled() const { return m_enabled; } bool AdBlockManager::canRunOnScheme(const QString &scheme) const { return !(scheme == QLatin1String("file") || scheme == QLatin1String("qrc") - || scheme == QLatin1String("qupzilla") || scheme == QLatin1String("data") + || scheme == QLatin1String("falkon") || scheme == QLatin1String("data") || scheme == QLatin1String("abp")); } bool AdBlockManager::canBeBlocked(const QUrl &url) const { return !m_matcher->adBlockDisabledForUrl(url); } QString AdBlockManager::elementHidingRules(const QUrl &url) const { if (!isEnabled() || !canRunOnScheme(url.scheme()) || !canBeBlocked(url)) return QString(); return m_matcher->elementHidingRules(); } QString AdBlockManager::elementHidingRulesForDomain(const QUrl &url) const { if (!isEnabled() || !canRunOnScheme(url.scheme()) || !canBeBlocked(url)) return QString(); return m_matcher->elementHidingRulesForDomain(url.host()); } AdBlockSubscription* AdBlockManager::subscriptionByName(const QString &name) const { foreach (AdBlockSubscription* subscription, m_subscriptions) { if (subscription->title() == name) { return subscription; } } return 0; } AdBlockDialog* AdBlockManager::showDialog() { if (!m_adBlockDialog) { m_adBlockDialog = new AdBlockDialog; } m_adBlockDialog.data()->show(); m_adBlockDialog.data()->raise(); m_adBlockDialog.data()->activateWindow(); return m_adBlockDialog.data(); } void AdBlockManager::showRule() { if (QAction* action = qobject_cast(sender())) { const AdBlockRule* rule = static_cast(action->data().value()); if (rule) { showDialog()->showRule(rule); } } } diff --git a/src/lib/adblock/adblockmanager.h b/src/lib/adblock/adblockmanager.h index bd2e83be..81fc1eab 100644 --- a/src/lib/adblock/adblockmanager.h +++ b/src/lib/adblock/adblockmanager.h @@ -1,101 +1,101 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef ADBLOCKMANAGER_H #define ADBLOCKMANAGER_H #include #include #include #include #include "qzcommon.h" class QUrl; class QWebEngineUrlRequestInfo; class AdBlockRule; class AdBlockDialog; class AdBlockMatcher; class AdBlockCustomList; class AdBlockSubscription; class AdBlockUrlInterceptor; -class QUPZILLA_EXPORT AdBlockManager : public QObject +class FALKON_EXPORT AdBlockManager : public QObject { Q_OBJECT public: AdBlockManager(QObject* parent = 0); ~AdBlockManager(); void load(); void save(); bool isEnabled() const; bool canRunOnScheme(const QString &scheme) const; QString elementHidingRules(const QUrl &url) const; QString elementHidingRulesForDomain(const QUrl &url) const; AdBlockSubscription* subscriptionByName(const QString &name) const; QList subscriptions() const; bool block(QWebEngineUrlRequestInfo &request); QStringList disabledRules() const; void addDisabledRule(const QString &filter); void removeDisabledRule(const QString &filter); bool addSubscriptionFromUrl(const QUrl &url); AdBlockSubscription* addSubscription(const QString &title, const QString &url); bool removeSubscription(AdBlockSubscription* subscription); AdBlockCustomList* customList() const; static AdBlockManager* instance(); signals: void enabledChanged(bool enabled); public slots: void setEnabled(bool enabled); void showRule(); void updateMatcher(); void updateAllSubscriptions(); AdBlockDialog* showDialog(); private: inline bool canBeBlocked(const QUrl &url) const; bool m_loaded; bool m_enabled; QList m_subscriptions; AdBlockMatcher* m_matcher; QStringList m_disabledRules; AdBlockUrlInterceptor *m_interceptor; QPointer m_adBlockDialog; QMutex m_mutex; }; #endif // ADBLOCKMANAGER_H diff --git a/src/lib/adblock/adblockmatcher.cpp b/src/lib/adblock/adblockmatcher.cpp index 98581d90..90927538 100644 --- a/src/lib/adblock/adblockmatcher.cpp +++ b/src/lib/adblock/adblockmatcher.cpp @@ -1,219 +1,219 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2014-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "adblockmatcher.h" #include "adblockmanager.h" #include "adblockrule.h" #include "adblocksubscription.h" AdBlockMatcher::AdBlockMatcher(AdBlockManager* manager) : QObject(manager) , m_manager(manager) { } AdBlockMatcher::~AdBlockMatcher() { clear(); } const AdBlockRule* AdBlockMatcher::match(const QWebEngineUrlRequestInfo &request, const QString &urlDomain, const QString &urlString) const { // Exception rules if (m_networkExceptionTree.find(request, urlDomain, urlString)) return 0; int count = m_networkExceptionRules.count(); for (int i = 0; i < count; ++i) { const AdBlockRule* rule = m_networkExceptionRules.at(i); if (rule->networkMatch(request, urlDomain, urlString)) return 0; } // Block rules if (const AdBlockRule* rule = m_networkBlockTree.find(request, urlDomain, urlString)) return rule; count = m_networkBlockRules.count(); for (int i = 0; i < count; ++i) { const AdBlockRule* rule = m_networkBlockRules.at(i); if (rule->networkMatch(request, urlDomain, urlString)) return rule; } return 0; } bool AdBlockMatcher::adBlockDisabledForUrl(const QUrl &url) const { int count = m_documentRules.count(); for (int i = 0; i < count; ++i) if (m_documentRules.at(i)->urlMatch(url)) return true; return false; } bool AdBlockMatcher::elemHideDisabledForUrl(const QUrl &url) const { if (adBlockDisabledForUrl(url)) return true; int count = m_elemhideRules.count(); for (int i = 0; i < count; ++i) if (m_elemhideRules.at(i)->urlMatch(url)) return true; return false; } QString AdBlockMatcher::elementHidingRules() const { return m_elementHidingRules; } QString AdBlockMatcher::elementHidingRulesForDomain(const QString &domain) const { QString rules; int addedRulesCount = 0; int count = m_domainRestrictedCssRules.count(); for (int i = 0; i < count; ++i) { const AdBlockRule* rule = m_domainRestrictedCssRules.at(i); if (!rule->matchDomain(domain)) continue; if (Q_UNLIKELY(addedRulesCount == 1000)) { rules.append(rule->cssSelector()); rules.append(QL1S("{display:none !important;}\n")); addedRulesCount = 0; } else { rules.append(rule->cssSelector() + QLatin1Char(',')); addedRulesCount++; } } if (addedRulesCount != 0) { rules = rules.left(rules.size() - 1); rules.append(QL1S("{display:none !important;}\n")); } return rules; } void AdBlockMatcher::update() { clear(); QHash cssRulesHash; QVector exceptionCssRules; foreach (AdBlockSubscription* subscription, m_manager->subscriptions()) { foreach (const AdBlockRule* rule, subscription->allRules()) { // Don't add internally disabled rules to cache if (rule->isInternalDisabled()) continue; if (rule->isCssRule()) { // We will add only enabled css rules to cache, because there is no enabled/disabled // check on match. They are directly embedded to pages. if (!rule->isEnabled()) continue; if (rule->isException()) exceptionCssRules.append(rule); else cssRulesHash.insert(rule->cssSelector(), rule); } else if (rule->isDocument()) { m_documentRules.append(rule); } else if (rule->isElemhide()) { m_elemhideRules.append(rule); } else if (rule->isException()) { if (!m_networkExceptionTree.add(rule)) m_networkExceptionRules.append(rule); } else { if (!m_networkBlockTree.add(rule)) m_networkBlockRules.append(rule); } } } foreach (const AdBlockRule* rule, exceptionCssRules) { const AdBlockRule* originalRule = cssRulesHash.value(rule->cssSelector()); // If we don't have this selector, the exception does nothing if (!originalRule) continue; AdBlockRule* copiedRule = originalRule->copy(); copiedRule->m_options |= AdBlockRule::DomainRestrictedOption; copiedRule->m_blockedDomains.append(rule->m_allowedDomains); cssRulesHash[rule->cssSelector()] = copiedRule; m_createdRules.append(copiedRule); } // Apparently, excessive amount of selectors for one CSS rule is not what WebKit likes. // (In my testings, 4931 is the number that makes it crash) // So let's split it by 1000 selectors... int hidingRulesCount = 0; QHashIterator it(cssRulesHash); while (it.hasNext()) { it.next(); const AdBlockRule* rule = it.value(); if (rule->isDomainRestricted()) { m_domainRestrictedCssRules.append(rule); } else if (Q_UNLIKELY(hidingRulesCount == 1000)) { m_elementHidingRules.append(rule->cssSelector()); m_elementHidingRules.append(QL1S("{display:none !important;} ")); hidingRulesCount = 0; } else { m_elementHidingRules.append(rule->cssSelector() + QLatin1Char(',')); hidingRulesCount++; } } if (hidingRulesCount != 0) { m_elementHidingRules = m_elementHidingRules.left(m_elementHidingRules.size() - 1); m_elementHidingRules.append(QL1S("{display:none !important;} ")); } } void AdBlockMatcher::clear() { m_networkExceptionTree.clear(); m_networkExceptionRules.clear(); m_networkBlockTree.clear(); m_networkBlockRules.clear(); m_domainRestrictedCssRules.clear(); m_elementHidingRules.clear(); m_documentRules.clear(); m_elemhideRules.clear(); qDeleteAll(m_createdRules); m_createdRules.clear(); } diff --git a/src/lib/adblock/adblockmatcher.h b/src/lib/adblock/adblockmatcher.h index 12ff2318..32892f96 100644 --- a/src/lib/adblock/adblockmatcher.h +++ b/src/lib/adblock/adblockmatcher.h @@ -1,66 +1,66 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2014-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef ADBLOCKMATCHER_H #define ADBLOCKMATCHER_H #include #include #include "qzcommon.h" #include "adblocksearchtree.h" class QWebEngineUrlRequestInfo; class AdBlockManager; -class QUPZILLA_EXPORT AdBlockMatcher : public QObject +class FALKON_EXPORT AdBlockMatcher : public QObject { Q_OBJECT public: explicit AdBlockMatcher(AdBlockManager* manager); ~AdBlockMatcher(); const AdBlockRule* match(const QWebEngineUrlRequestInfo &request, const QString &urlDomain, const QString &urlString) const; bool adBlockDisabledForUrl(const QUrl &url) const; bool elemHideDisabledForUrl(const QUrl &url) const; QString elementHidingRules() const; QString elementHidingRulesForDomain(const QString &domain) const; public slots: void update(); void clear(); private: AdBlockManager* m_manager; QVector m_createdRules; QVector m_networkExceptionRules; QVector m_networkBlockRules; QVector m_domainRestrictedCssRules; QVector m_documentRules; QVector m_elemhideRules; QString m_elementHidingRules; AdBlockSearchTree m_networkBlockTree; AdBlockSearchTree m_networkExceptionTree; }; #endif // ADBLOCKMATCHER_H diff --git a/src/lib/adblock/adblockrule.cpp b/src/lib/adblock/adblockrule.cpp index e48fc2b7..0b7cf9a9 100644 --- a/src/lib/adblock/adblockrule.cpp +++ b/src/lib/adblock/adblockrule.cpp @@ -1,826 +1,826 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ /** * Copyright (c) 2009, Zsombor Gegesy * Copyright (c) 2009, Benjamin C. Meyer * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the Benjamin Meyer nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "adblockrule.h" #include "adblocksubscription.h" #include "qztools.h" #include "qzregexp.h" #include #include #include #include #include static QString toSecondLevelDomain(const QUrl &url) { const QString topLevelDomain = url.topLevelDomain(); const QString urlHost = url.host(); if (topLevelDomain.isEmpty() || urlHost.isEmpty()) { return QString(); } QString domain = urlHost.left(urlHost.size() - topLevelDomain.size()); if (domain.count(QL1C('.')) == 0) { return urlHost; } while (domain.count(QL1C('.')) != 0) { domain = domain.mid(domain.indexOf(QL1C('.')) + 1); } return domain + topLevelDomain; } AdBlockRule::AdBlockRule(const QString &filter, AdBlockSubscription* subscription) : m_subscription(subscription) , m_type(StringContainsMatchRule) , m_caseSensitivity(Qt::CaseInsensitive) , m_isEnabled(true) , m_isException(false) , m_isInternalDisabled(false) , m_regExp(0) { setFilter(filter); } AdBlockRule::~AdBlockRule() { delete m_regExp; } AdBlockRule* AdBlockRule::copy() const { AdBlockRule* rule = new AdBlockRule(); rule->m_subscription = m_subscription; rule->m_type = m_type; rule->m_options = m_options; rule->m_exceptions = m_exceptions; rule->m_filter = m_filter; rule->m_matchString = m_matchString; rule->m_caseSensitivity = m_caseSensitivity; rule->m_isEnabled = m_isEnabled; rule->m_isException = m_isException; rule->m_isInternalDisabled = m_isInternalDisabled; rule->m_allowedDomains = m_allowedDomains; rule->m_blockedDomains = m_blockedDomains; if (m_regExp) { rule->m_regExp = new RegExp; rule->m_regExp->regExp = m_regExp->regExp; rule->m_regExp->matchers = m_regExp->matchers; } return rule; } AdBlockSubscription* AdBlockRule::subscription() const { return m_subscription; } void AdBlockRule::setSubscription(AdBlockSubscription* subscription) { m_subscription = subscription; } QString AdBlockRule::filter() const { return m_filter; } void AdBlockRule::setFilter(const QString &filter) { m_filter = filter; parseFilter(); } bool AdBlockRule::isCssRule() const { return m_type == CssRule; } QString AdBlockRule::cssSelector() const { return m_matchString; } bool AdBlockRule::isDocument() const { return hasOption(DocumentOption); } bool AdBlockRule::isElemhide() const { return hasOption(ElementHideOption); } bool AdBlockRule::isDomainRestricted() const { return hasOption(DomainRestrictedOption); } bool AdBlockRule::isException() const { return m_isException; } bool AdBlockRule::isComment() const { return m_filter.startsWith(QL1C('!')); } bool AdBlockRule::isEnabled() const { return m_isEnabled; } void AdBlockRule::setEnabled(bool enabled) { m_isEnabled = enabled; } bool AdBlockRule::isSlow() const { return m_regExp != 0; } bool AdBlockRule::isInternalDisabled() const { return m_isInternalDisabled; } bool AdBlockRule::urlMatch(const QUrl &url) const { if (!hasOption(DocumentOption) && !hasOption(ElementHideOption)) { return false; } const QString encodedUrl = url.toEncoded(); const QString domain = url.host(); return stringMatch(domain, encodedUrl); } bool AdBlockRule::networkMatch(const QWebEngineUrlRequestInfo &request, const QString &domain, const QString &encodedUrl) const { if (m_type == CssRule || !m_isEnabled || m_isInternalDisabled) { return false; } bool matched = stringMatch(domain, encodedUrl); if (matched) { // Check domain restrictions if (hasOption(DomainRestrictedOption) && !matchDomain(request.firstPartyUrl().host())) { return false; } // Check third-party restriction if (hasOption(ThirdPartyOption) && !matchThirdParty(request)) { return false; } // Check object restrictions if (hasOption(ObjectOption) && !matchObject(request)) { return false; } // Check subdocument restriction if (hasOption(SubdocumentOption) && !matchSubdocument(request)) { return false; } // Check xmlhttprequest restriction if (hasOption(XMLHttpRequestOption) && !matchXmlHttpRequest(request)) { return false; } // Check image restriction if (hasOption(ImageOption) && !matchImage(request)) { return false; } // Check script restriction if (hasOption(ScriptOption) && !matchScript(request)) { return false; } // Check stylesheet restriction if (hasOption(StyleSheetOption) && !matchStyleSheet(request)) { return false; } // Check object-subrequest restriction if (hasOption(ObjectSubrequestOption) && !matchObjectSubrequest(request)) { return false; } // Check ping restriction if (hasOption(PingOption) && !matchPing(request)) { return false; } // Check media restriction if (hasOption(MediaOption) && !matchMedia(request)) { return false; } } return matched; } bool AdBlockRule::matchDomain(const QString &domain) const { if (!m_isEnabled) { return false; } if (!hasOption(DomainRestrictedOption)) { return true; } if (m_blockedDomains.isEmpty()) { foreach (const QString &d, m_allowedDomains) { if (isMatchingDomain(domain, d)) { return true; } } } else if (m_allowedDomains.isEmpty()) { foreach (const QString &d, m_blockedDomains) { if (isMatchingDomain(domain, d)) { return false; } } return true; } else { foreach (const QString &d, m_blockedDomains) { if (isMatchingDomain(domain, d)) { return false; } } foreach (const QString &d, m_allowedDomains) { if (isMatchingDomain(domain, d)) { return true; } } } return false; } bool AdBlockRule::matchThirdParty(const QWebEngineUrlRequestInfo &request) const { // Third-party matching should be performed on second-level domains const QString firstPartyHost = toSecondLevelDomain(request.firstPartyUrl()); const QString host = toSecondLevelDomain(request.requestUrl()); bool match = firstPartyHost != host; return hasException(ThirdPartyOption) ? !match : match; } bool AdBlockRule::matchObject(const QWebEngineUrlRequestInfo &request) const { bool match = request.resourceType() == QWebEngineUrlRequestInfo::ResourceTypeObject; return hasException(ObjectOption) ? !match : match; } bool AdBlockRule::matchSubdocument(const QWebEngineUrlRequestInfo &request) const { bool match = request.resourceType() == QWebEngineUrlRequestInfo::ResourceTypeSubFrame; return hasException(SubdocumentOption) ? !match : match; } bool AdBlockRule::matchXmlHttpRequest(const QWebEngineUrlRequestInfo &request) const { bool match = request.resourceType() == QWebEngineUrlRequestInfo::ResourceTypeXhr; return hasException(XMLHttpRequestOption) ? !match : match; } bool AdBlockRule::matchImage(const QWebEngineUrlRequestInfo &request) const { bool match = request.resourceType() == QWebEngineUrlRequestInfo::ResourceTypeImage; return hasException(ImageOption) ? !match : match; } bool AdBlockRule::matchScript(const QWebEngineUrlRequestInfo &request) const { bool match = request.resourceType() == QWebEngineUrlRequestInfo::ResourceTypeScript; return hasException(ScriptOption) ? !match : match; } bool AdBlockRule::matchStyleSheet(const QWebEngineUrlRequestInfo &request) const { bool match = request.resourceType() == QWebEngineUrlRequestInfo::ResourceTypeStylesheet; return hasException(StyleSheetOption) ? !match : match; } bool AdBlockRule::matchObjectSubrequest(const QWebEngineUrlRequestInfo &request) const { bool match = request.resourceType() == QWebEngineUrlRequestInfo::ResourceTypePluginResource; return hasException(ObjectSubrequestOption) ? !match : match; } bool AdBlockRule::matchPing(const QWebEngineUrlRequestInfo &request) const { bool match = request.resourceType() == QWebEngineUrlRequestInfo::ResourceTypePing; return hasException(PingOption) ? !match : match; } bool AdBlockRule::matchMedia(const QWebEngineUrlRequestInfo &request) const { bool match = request.resourceType() == QWebEngineUrlRequestInfo::ResourceTypeMedia; return hasException(MediaOption) ? !match : match; } bool AdBlockRule::matchOther(const QWebEngineUrlRequestInfo &request) const { bool match = request.resourceType() == QWebEngineUrlRequestInfo::ResourceTypeFontResource || request.resourceType() == QWebEngineUrlRequestInfo::ResourceTypeSubResource || request.resourceType() == QWebEngineUrlRequestInfo::ResourceTypeWorker || request.resourceType() == QWebEngineUrlRequestInfo::ResourceTypeSharedWorker || request.resourceType() == QWebEngineUrlRequestInfo::ResourceTypePrefetch || request.resourceType() == QWebEngineUrlRequestInfo::ResourceTypeFavicon || request.resourceType() == QWebEngineUrlRequestInfo::ResourceTypeServiceWorker || request.resourceType() == QWebEngineUrlRequestInfo::ResourceTypeUnknown; return hasException(MediaOption) ? !match : match; } void AdBlockRule::parseFilter() { QString parsedLine = m_filter; // Empty rule or just comment if (m_filter.trimmed().isEmpty() || m_filter.startsWith(QL1C('!'))) { // We want to differentiate rule disabled by user and rule disabled in subscription file // m_isInternalDisabled is also used when rule is disabled due to all options not being supported m_isEnabled = false; m_isInternalDisabled = true; m_type = Invalid; return; } // CSS Element hiding rule if (parsedLine.contains(QL1S("##")) || parsedLine.contains(QL1S("#@#"))) { m_type = CssRule; int pos = parsedLine.indexOf(QL1C('#')); // Domain restricted rule if (!parsedLine.startsWith(QL1S("##"))) { QString domains = parsedLine.left(pos); parseDomains(domains, QL1C(',')); } m_isException = parsedLine.at(pos + 1) == QL1C('@'); m_matchString = parsedLine.mid(m_isException ? pos + 3 : pos + 2); // CSS rule cannot have more options -> stop parsing return; } // Exception always starts with @@ if (parsedLine.startsWith(QL1S("@@"))) { m_isException = true; parsedLine = parsedLine.mid(2); } // Parse all options following $ char int optionsIndex = parsedLine.indexOf(QL1C('$')); if (optionsIndex >= 0) { const QStringList options = parsedLine.mid(optionsIndex + 1).split(QL1C(','), QString::SkipEmptyParts); int handledOptions = 0; foreach (const QString &option, options) { if (option.startsWith(QL1S("domain="))) { parseDomains(option.mid(7), QL1C('|')); ++handledOptions; } else if (option == QL1S("match-case")) { m_caseSensitivity = Qt::CaseSensitive; ++handledOptions; } else if (option.endsWith(QL1S("third-party"))) { setOption(ThirdPartyOption); setException(ThirdPartyOption, option.startsWith(QL1C('~'))); ++handledOptions; } else if (option.endsWith(QL1S("object"))) { setOption(ObjectOption); setException(ObjectOption, option.startsWith(QL1C('~'))); ++handledOptions; } else if (option.endsWith(QL1S("subdocument"))) { setOption(SubdocumentOption); setException(SubdocumentOption, option.startsWith(QL1C('~'))); ++handledOptions; } else if (option.endsWith(QL1S("xmlhttprequest"))) { setOption(XMLHttpRequestOption); setException(XMLHttpRequestOption, option.startsWith(QL1C('~'))); ++handledOptions; } else if (option.endsWith(QL1S("image"))) { setOption(ImageOption); setException(ImageOption, option.startsWith(QL1C('~'))); ++handledOptions; } else if (option.endsWith(QL1S("script"))) { setOption(ScriptOption); setException(ScriptOption, option.startsWith(QL1C('~'))); ++handledOptions; } else if (option.endsWith(QL1S("stylesheet"))) { setOption(StyleSheetOption); setException(StyleSheetOption, option.startsWith(QL1C('~'))); ++handledOptions; } else if (option.endsWith(QL1S("object-subrequest"))) { setOption(ObjectSubrequestOption); setException(ObjectSubrequestOption, option.startsWith(QL1C('~'))); ++handledOptions; } else if (option.endsWith(QL1S("ping"))) { setOption(PingOption); setException(PingOption, option.startsWith(QL1C('~'))); ++handledOptions; } else if (option.endsWith(QL1S("media"))) { setOption(MediaOption); setException(MediaOption, option.startsWith(QL1C('~'))); ++handledOptions; } else if (option.endsWith(QL1S("other"))) { setOption(OtherOption); setException(OtherOption, option.startsWith(QL1C('~'))); ++handledOptions; } else if (option == QL1S("document") && m_isException) { setOption(DocumentOption); ++handledOptions; } else if (option == QL1S("elemhide") && m_isException) { setOption(ElementHideOption); ++handledOptions; } else if (option == QL1S("collapse")) { // Hiding placeholders of blocked elements is enabled by default ++handledOptions; } } // If we don't handle all options, it's safer to just disable this rule if (handledOptions != options.count()) { m_isInternalDisabled = true; m_type = Invalid; return; } parsedLine = parsedLine.left(optionsIndex); } // Rule is classic regexp if (parsedLine.startsWith(QL1C('/')) && parsedLine.endsWith(QL1C('/'))) { parsedLine = parsedLine.mid(1); parsedLine = parsedLine.left(parsedLine.size() - 1); m_type = RegExpMatchRule; m_regExp = new RegExp; m_regExp->regExp = QzRegExp(parsedLine, m_caseSensitivity); m_regExp->matchers = createStringMatchers(parseRegExpFilter(parsedLine)); return; } // Remove starting and ending wildcards (*) if (parsedLine.startsWith(QL1C('*'))) { parsedLine = parsedLine.mid(1); } if (parsedLine.endsWith(QL1C('*'))) { parsedLine = parsedLine.left(parsedLine.size() - 1); } // We can use fast string matching for domain here if (filterIsOnlyDomain(parsedLine)) { parsedLine = parsedLine.mid(2); parsedLine = parsedLine.left(parsedLine.size() - 1); m_type = DomainMatchRule; m_matchString = parsedLine; return; } // If rule contains only | at end, we can also use string matching if (filterIsOnlyEndsMatch(parsedLine)) { parsedLine = parsedLine.left(parsedLine.size() - 1); m_type = StringEndsMatchRule; m_matchString = parsedLine; return; } // If we still find a wildcard (*) or separator (^) or (|) // we must modify parsedLine to comply with QzRegExp if (parsedLine.contains(QL1C('*')) || parsedLine.contains(QL1C('^')) || parsedLine.contains(QL1C('|')) ) { m_type = RegExpMatchRule; m_regExp = new RegExp; m_regExp->regExp = QzRegExp(createRegExpFromFilter(parsedLine), m_caseSensitivity); m_regExp->matchers = createStringMatchers(parseRegExpFilter(parsedLine)); return; } // This rule matches all urls if (parsedLine.isEmpty()) { if (m_options == NoOption) { qWarning() << "Disabling unrestricted rule that would block all requests" << m_filter; m_isInternalDisabled = true; m_type = Invalid; return; } m_type = MatchAllUrlsRule; return; } // We haven't found anything that needs use of regexp, yay! m_type = StringContainsMatchRule; m_matchString = parsedLine; } void AdBlockRule::parseDomains(const QString &domains, const QChar &separator) { QStringList domainsList = domains.split(separator, QString::SkipEmptyParts); foreach (const QString domain, domainsList) { if (domain.isEmpty()) { continue; } if (domain.startsWith(QL1C('~'))) { m_blockedDomains.append(domain.mid(1)); } else { m_allowedDomains.append(domain); } } if (!m_blockedDomains.isEmpty() || !m_allowedDomains.isEmpty()) { setOption(DomainRestrictedOption); } } bool AdBlockRule::filterIsOnlyDomain(const QString &filter) const { if (!filter.endsWith(QL1C('^')) || !filter.startsWith(QL1S("||"))) return false; for (int i = 0; i < filter.size(); ++i) { switch (filter.at(i).toLatin1()) { case '/': case ':': case '?': case '=': case '&': case '*': return false; default: break; } } return true; } bool AdBlockRule::filterIsOnlyEndsMatch(const QString &filter) const { for (int i = 0; i < filter.size(); ++i) { switch (filter.at(i).toLatin1()) { case '^': case '*': return false; case '|': return i == filter.size() - 1; default: break; } } return false; } static bool wordCharacter(const QChar &c) { return c.isLetterOrNumber() || c.isMark() || c == QL1C('_'); } QString AdBlockRule::createRegExpFromFilter(const QString &filter) const { QString parsed; parsed.reserve(filter.size()); bool hadWildcard = false; // Filter multiple wildcards for (int i = 0; i < filter.size(); ++i) { const QChar c = filter.at(i); switch (c.toLatin1()) { case '^': parsed.append(QL1S("(?:[^\\w\\d\\-.%]|$)")); break; case '*': if (!hadWildcard) parsed.append(QL1S(".*")); break; case '|': if (i == 0) { if (filter.size() > 1 && filter.at(1) == QL1C('|')) { parsed.append(QL1S("^[\\w\\-]+:\\/+(?!\\/)(?:[^\\/]+\\.)?")); i++; } else { parsed.append('^'); } break; } else if (i == filter.size() - 1) { parsed.append(QL1C('$')); break; } // fallthrough default: if (!wordCharacter(c)) parsed.append(QL1C('\\') + c); else parsed.append(c); } hadWildcard = c == QL1C('*'); } return parsed; } QList AdBlockRule::createStringMatchers(const QStringList &filters) const { QList matchers; matchers.reserve(filters.size()); foreach (const QString &filter, filters) { matchers.append(QStringMatcher(filter, m_caseSensitivity)); } return matchers; } bool AdBlockRule::stringMatch(const QString &domain, const QString &encodedUrl) const { switch (m_type) { case StringContainsMatchRule: return encodedUrl.contains(m_matchString, m_caseSensitivity); case DomainMatchRule: return isMatchingDomain(domain, m_matchString); case StringEndsMatchRule: return encodedUrl.endsWith(m_matchString, m_caseSensitivity); case RegExpMatchRule: if (!isMatchingRegExpStrings(encodedUrl)) { return false; } return (m_regExp->regExp.indexIn(encodedUrl) != -1); case MatchAllUrlsRule: return true; default: return false; } } bool AdBlockRule::isMatchingDomain(const QString &domain, const QString &filter) const { return QzTools::matchDomain(filter, domain); } bool AdBlockRule::isMatchingRegExpStrings(const QString &url) const { Q_ASSERT(m_regExp); foreach (const QStringMatcher &matcher, m_regExp->matchers) { if (matcher.indexIn(url) == -1) return false; } return true; } // Split regexp filter into strings that can be used with QString::contains // Don't use parts that contains only 1 char and duplicated parts QStringList AdBlockRule::parseRegExpFilter(const QString &filter) const { QStringList list; int startPos = -1; for (int i = 0; i < filter.size(); ++i) { const QChar c = filter.at(i); // Meta characters in AdBlock rules are | * ^ if (c == QL1C('|') || c == QL1C('*') || c == QL1C('^')) { const QString sub = filter.mid(startPos, i - startPos); if (sub.size() > 1) list.append(sub); startPos = i + 1; } } const QString sub = filter.mid(startPos); if (sub.size() > 1) list.append(sub); list.removeDuplicates(); return list; } bool AdBlockRule::hasOption(const AdBlockRule::RuleOption &opt) const { return (m_options & opt); } bool AdBlockRule::hasException(const AdBlockRule::RuleOption &opt) const { return (m_exceptions & opt); } void AdBlockRule::setOption(const AdBlockRule::RuleOption &opt) { m_options |= opt; } void AdBlockRule::setException(const AdBlockRule::RuleOption &opt, bool on) { if (on) { m_exceptions |= opt; } } diff --git a/src/lib/adblock/adblockrule.h b/src/lib/adblock/adblockrule.h index 385b27c9..76cadc57 100644 --- a/src/lib/adblock/adblockrule.h +++ b/src/lib/adblock/adblockrule.h @@ -1,195 +1,195 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ /** * Copyright (c) 2009, Benjamin C. Meyer * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the Benjamin Meyer nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef ADBLOCKRULE_H #define ADBLOCKRULE_H #include #include #include #include "qzcommon.h" #include "qzregexp.h" class QUrl; class QWebEngineUrlRequestInfo; class AdBlockSubscription; -class QUPZILLA_EXPORT AdBlockRule +class FALKON_EXPORT AdBlockRule { Q_DISABLE_COPY(AdBlockRule) public: AdBlockRule(const QString &filter = QString(), AdBlockSubscription* subscription = 0); ~AdBlockRule(); AdBlockRule* copy() const; AdBlockSubscription* subscription() const; void setSubscription(AdBlockSubscription* subscription); QString filter() const; void setFilter(const QString &filter); bool isCssRule() const; QString cssSelector() const; bool isDocument() const; bool isElemhide() const; bool isDomainRestricted() const; bool isException() const; bool isComment() const; bool isEnabled() const; void setEnabled(bool enabled); bool isSlow() const; bool isInternalDisabled() const; bool urlMatch(const QUrl &url) const; bool networkMatch(const QWebEngineUrlRequestInfo &request, const QString &domain, const QString &encodedUrl) const; bool matchDomain(const QString &domain) const; bool matchThirdParty(const QWebEngineUrlRequestInfo &request) const; bool matchObject(const QWebEngineUrlRequestInfo &request) const; bool matchSubdocument(const QWebEngineUrlRequestInfo &request) const; bool matchXmlHttpRequest(const QWebEngineUrlRequestInfo &request) const; bool matchImage(const QWebEngineUrlRequestInfo &request) const; bool matchScript(const QWebEngineUrlRequestInfo &request) const; bool matchStyleSheet(const QWebEngineUrlRequestInfo &request) const; bool matchObjectSubrequest(const QWebEngineUrlRequestInfo &request) const; bool matchPing(const QWebEngineUrlRequestInfo &request) const; bool matchMedia(const QWebEngineUrlRequestInfo &request) const; bool matchOther(const QWebEngineUrlRequestInfo &request) const; protected: bool stringMatch(const QString &domain, const QString &encodedUrl) const; bool isMatchingDomain(const QString &domain, const QString &filter) const; bool isMatchingRegExpStrings(const QString &url) const; QStringList parseRegExpFilter(const QString &filter) const; private: enum RuleType { CssRule = 0, DomainMatchRule = 1, RegExpMatchRule = 2, StringEndsMatchRule = 3, StringContainsMatchRule = 4, MatchAllUrlsRule = 5, Invalid = 6 }; enum RuleOption { NoOption = 0, DomainRestrictedOption = 1, ThirdPartyOption = 2, ObjectOption = 4, SubdocumentOption = 8, XMLHttpRequestOption = 16, ImageOption = 32, ScriptOption = 64, StyleSheetOption = 128, ObjectSubrequestOption = 256, PingOption = 512, MediaOption = 1024, OtherOption = 2048, // Exception only options DocumentOption = 4096, ElementHideOption = 8192 }; Q_DECLARE_FLAGS(RuleOptions, RuleOption) inline bool hasOption(const RuleOption &opt) const; inline bool hasException(const RuleOption &opt) const; inline void setOption(const RuleOption &opt); inline void setException(const RuleOption &opt, bool on); void parseFilter(); void parseDomains(const QString &domains, const QChar &separator); bool filterIsOnlyDomain(const QString &filter) const; bool filterIsOnlyEndsMatch(const QString &filter) const; QString createRegExpFromFilter(const QString &filter) const; QList createStringMatchers(const QStringList &filters) const; AdBlockSubscription* m_subscription; RuleType m_type; RuleOptions m_options; RuleOptions m_exceptions; // Original rule filter QString m_filter; // Parsed rule for string matching (CSS Selector for CSS rules) QString m_matchString; // Case sensitivity for string matching Qt::CaseSensitivity m_caseSensitivity; bool m_isEnabled; bool m_isException; bool m_isInternalDisabled; QStringList m_allowedDomains; QStringList m_blockedDomains; struct RegExp { QzRegExp regExp; QList matchers; }; // Use dynamic allocation to save memory RegExp* m_regExp; friend class AdBlockMatcher; friend class AdBlockSearchTree; friend class AdBlockSubscription; }; #endif // ADBLOCKRULE_H diff --git a/src/lib/adblock/adblocksearchtree.cpp b/src/lib/adblock/adblocksearchtree.cpp index 398400b2..6e5cf920 100644 --- a/src/lib/adblock/adblocksearchtree.cpp +++ b/src/lib/adblock/adblocksearchtree.cpp @@ -1,137 +1,137 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2013-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "adblocksearchtree.h" #include "adblockrule.h" #include AdBlockSearchTree::AdBlockSearchTree() : m_root(new Node) { } AdBlockSearchTree::~AdBlockSearchTree() { deleteNode(m_root); } void AdBlockSearchTree::clear() { deleteNode(m_root); m_root = new Node; } bool AdBlockSearchTree::add(const AdBlockRule* rule) { if (rule->m_type != AdBlockRule::StringContainsMatchRule) { return false; } const QString filter = rule->m_matchString; int len = filter.size(); if (len <= 0) { qDebug() << "AdBlockSearchTree: Inserting rule with filter len <= 0!" << rule->filter(); return false; } Node* node = m_root; for (int i = 0; i < len; ++i) { const QChar c = filter.at(i); Node *next = node->children.value(c); if (!next) { next = new Node; next->c = c; node->children[c] = next; } node = next; } node->rule = rule; return true; } const AdBlockRule* AdBlockSearchTree::find(const QWebEngineUrlRequestInfo &request, const QString &domain, const QString &urlString) const { int len = urlString.size(); if (len <= 0) { return 0; } const QChar* string = urlString.constData(); for (int i = 0; i < len; ++i) { const AdBlockRule* rule = prefixSearch(request, domain, urlString, string++, len - i); if (rule) { return rule; } } return 0; } const AdBlockRule* AdBlockSearchTree::prefixSearch(const QWebEngineUrlRequestInfo &request, const QString &domain, const QString &urlString, const QChar* string, int len) const { if (len <= 0) { return 0; } QChar c = string[0]; Node* node = m_root->children.value(c); if (!node) { return nullptr; } for (int i = 1; i < len; ++i) { const QChar c = (++string)[0]; if (node->rule && node->rule->networkMatch(request, domain, urlString)) { return node->rule; } node = node->children.value(c); if (!node) { return nullptr; } } if (node->rule && node->rule->networkMatch(request, domain, urlString)) { return node->rule; } return nullptr; } void AdBlockSearchTree::deleteNode(AdBlockSearchTree::Node* node) { if (!node) { return; } QHashIterator i(node->children); while (i.hasNext()) { i.next(); deleteNode(i.value()); } delete node; } diff --git a/src/lib/adblock/adblocksearchtree.h b/src/lib/adblock/adblocksearchtree.h index 878a588f..c9848020 100644 --- a/src/lib/adblock/adblocksearchtree.h +++ b/src/lib/adblock/adblocksearchtree.h @@ -1,58 +1,58 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2013-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef ADBLOCKSEARCHTREE_H #define ADBLOCKSEARCHTREE_H #include #include #include "qzcommon.h" class QWebEngineUrlRequestInfo; class AdBlockRule; -class QUPZILLA_EXPORT AdBlockSearchTree +class FALKON_EXPORT AdBlockSearchTree { public: explicit AdBlockSearchTree(); ~AdBlockSearchTree(); void clear(); bool add(const AdBlockRule* rule); const AdBlockRule* find(const QWebEngineUrlRequestInfo &request, const QString &domain, const QString &urlString) const; private: struct Node { QChar c; const AdBlockRule* rule; QHash children; Node() : c(0) , rule(0) { } }; const AdBlockRule* prefixSearch(const QWebEngineUrlRequestInfo &request, const QString &domain, const QString &urlString, const QChar* string, int len) const; void deleteNode(Node* node); Node* m_root; }; #endif // ADBLOCKSEARCHTREE_H diff --git a/src/lib/adblock/adblocksubscription.cpp b/src/lib/adblock/adblocksubscription.cpp index b4b964fb..b91157f4 100644 --- a/src/lib/adblock/adblocksubscription.cpp +++ b/src/lib/adblock/adblocksubscription.cpp @@ -1,426 +1,426 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ /** * Copyright (c) 2009, Benjamin C. Meyer * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the Benjamin Meyer nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "adblocksubscription.h" #include "adblockmanager.h" #include "adblocksearchtree.h" #include "mainapplication.h" #include "networkmanager.h" #include "datapaths.h" #include "qztools.h" #include #include #include #include AdBlockSubscription::AdBlockSubscription(const QString &title, QObject* parent) : QObject(parent) , m_reply(0) , m_title(title) , m_updated(false) { } QString AdBlockSubscription::title() const { return m_title; } QString AdBlockSubscription::filePath() const { return m_filePath; } void AdBlockSubscription::setFilePath(const QString &path) { m_filePath = path; } QUrl AdBlockSubscription::url() const { return m_url; } void AdBlockSubscription::setUrl(const QUrl &url) { m_url = url; } void AdBlockSubscription::loadSubscription(const QStringList &disabledRules) { QFile file(m_filePath); if (!file.exists()) { QTimer::singleShot(0, this, SLOT(updateSubscription())); return; } if (!file.open(QFile::ReadOnly)) { qWarning() << "AdBlockSubscription::" << __FUNCTION__ << "Unable to open adblock file for reading" << m_filePath; QTimer::singleShot(0, this, SLOT(updateSubscription())); return; } QTextStream textStream(&file); textStream.setCodec("UTF-8"); // Header is on 3rd line textStream.readLine(1024); textStream.readLine(1024); QString header = textStream.readLine(1024); if (!header.startsWith(QLatin1String("[Adblock")) || m_title.isEmpty()) { qWarning() << "AdBlockSubscription::" << __FUNCTION__ << "invalid format of adblock file" << m_filePath; QTimer::singleShot(0, this, SLOT(updateSubscription())); return; } m_rules.clear(); while (!textStream.atEnd()) { AdBlockRule* rule = new AdBlockRule(textStream.readLine(), this); if (disabledRules.contains(rule->filter())) { rule->setEnabled(false); } m_rules.append(rule); } // Initial update if (m_rules.isEmpty() && !m_updated) { QTimer::singleShot(0, this, SLOT(updateSubscription())); } } void AdBlockSubscription::saveSubscription() { } void AdBlockSubscription::updateSubscription() { if (m_reply || !m_url.isValid()) { return; } m_reply = mApp->networkManager()->get(QNetworkRequest(m_url)); connect(m_reply, &QNetworkReply::finished, this, &AdBlockSubscription::subscriptionDownloaded); } void AdBlockSubscription::subscriptionDownloaded() { if (m_reply != qobject_cast(sender())) { return; } bool error = false; const QByteArray response = QString::fromUtf8(m_reply->readAll()).toUtf8(); if (m_reply->error() != QNetworkReply::NoError || !response.startsWith(QByteArray("[Adblock")) || !saveDownloadedData(response) ) { error = true; } m_reply->deleteLater(); m_reply = 0; if (error) { emit subscriptionError(tr("Cannot load subscription!")); return; } loadSubscription(AdBlockManager::instance()->disabledRules()); emit subscriptionUpdated(); emit subscriptionChanged(); } bool AdBlockSubscription::saveDownloadedData(const QByteArray &data) { QSaveFile file(m_filePath); if (!file.open(QFile::WriteOnly)) { qWarning() << "AdBlockSubscription::" << __FUNCTION__ << "Unable to open adblock file for writing:" << m_filePath; return false; } // Write subscription header file.write(QString("Title: %1\nUrl: %2\n").arg(title(), url().toString()).toUtf8()); file.write(data); file.commit(); return true; } const AdBlockRule* AdBlockSubscription::rule(int offset) const { if (!QzTools::containsIndex(m_rules, offset)) { return 0; } return m_rules[offset]; } QVector AdBlockSubscription::allRules() const { return m_rules; } const AdBlockRule* AdBlockSubscription::enableRule(int offset) { if (!QzTools::containsIndex(m_rules, offset)) { return 0; } AdBlockRule* rule = m_rules[offset]; rule->setEnabled(true); AdBlockManager::instance()->removeDisabledRule(rule->filter()); emit subscriptionChanged(); if (rule->isCssRule()) mApp->reloadUserStyleSheet(); return rule; } const AdBlockRule* AdBlockSubscription::disableRule(int offset) { if (!QzTools::containsIndex(m_rules, offset)) { return 0; } AdBlockRule* rule = m_rules[offset]; rule->setEnabled(false); AdBlockManager::instance()->addDisabledRule(rule->filter()); emit subscriptionChanged(); if (rule->isCssRule()) mApp->reloadUserStyleSheet(); return rule; } bool AdBlockSubscription::canEditRules() const { return false; } bool AdBlockSubscription::canBeRemoved() const { return true; } int AdBlockSubscription::addRule(AdBlockRule* rule) { Q_UNUSED(rule) return -1; } bool AdBlockSubscription::removeRule(int offset) { Q_UNUSED(offset) return false; } const AdBlockRule* AdBlockSubscription::replaceRule(AdBlockRule* rule, int offset) { Q_UNUSED(rule) Q_UNUSED(offset) return 0; } AdBlockSubscription::~AdBlockSubscription() { qDeleteAll(m_rules); } // AdBlockCustomList AdBlockCustomList::AdBlockCustomList(QObject* parent) : AdBlockSubscription(tr("Custom Rules"), parent) { setFilePath(DataPaths::currentProfilePath() + QLatin1String("/adblock/customlist.txt")); } void AdBlockCustomList::loadSubscription(const QStringList &disabledRules) { // DuckDuckGo ad whitelist rules // They cannot be removed, but can be disabled. // Please consider not disabling them. Thanks! const QString ddg1 = QSL("@@||duckduckgo.com^$document"); const QString ddg2 = QSL("duckduckgo.com#@#.has-ad"); const QString rules = QzTools::readAllFileContents(filePath()); QFile file(filePath()); if (!file.exists()) { saveSubscription(); } if (file.open(QFile::WriteOnly | QFile::Append)) { QTextStream stream(&file); stream.setCodec("UTF-8"); if (!rules.contains(ddg1 + QL1S("\n"))) stream << ddg1 << endl; if (!rules.contains(QL1S("\n") + ddg2)) stream << ddg2 << endl; } file.close(); AdBlockSubscription::loadSubscription(disabledRules); } void AdBlockCustomList::saveSubscription() { QFile file(filePath()); if (!file.open(QFile::ReadWrite | QFile::Truncate)) { qWarning() << "AdBlockSubscription::" << __FUNCTION__ << "Unable to open adblock file for writing:" << filePath(); return; } QTextStream textStream(&file); textStream.setCodec("UTF-8"); textStream << "Title: " << title() << endl; textStream << "Url: " << url().toString() << endl; textStream << "[Adblock Plus 1.1.1]" << endl; foreach (const AdBlockRule* rule, m_rules) { textStream << rule->filter() << endl; } file.close(); } bool AdBlockCustomList::canEditRules() const { return true; } bool AdBlockCustomList::canBeRemoved() const { return false; } bool AdBlockCustomList::containsFilter(const QString &filter) const { foreach (const AdBlockRule* rule, m_rules) { if (rule->filter() == filter) { return true; } } return false; } bool AdBlockCustomList::removeFilter(const QString &filter) { for (int i = 0; i < m_rules.count(); ++i) { const AdBlockRule* rule = m_rules.at(i); if (rule->filter() == filter) { return removeRule(i); } } return false; } int AdBlockCustomList::addRule(AdBlockRule* rule) { m_rules.append(rule); emit subscriptionChanged(); if (rule->isCssRule()) mApp->reloadUserStyleSheet(); return m_rules.count() - 1; } bool AdBlockCustomList::removeRule(int offset) { if (!QzTools::containsIndex(m_rules, offset)) { return false; } AdBlockRule* rule = m_rules.at(offset); const QString filter = rule->filter(); m_rules.remove(offset); emit subscriptionChanged(); if (rule->isCssRule()) mApp->reloadUserStyleSheet(); AdBlockManager::instance()->removeDisabledRule(filter); delete rule; return true; } const AdBlockRule* AdBlockCustomList::replaceRule(AdBlockRule* rule, int offset) { if (!QzTools::containsIndex(m_rules, offset)) { return 0; } AdBlockRule* oldRule = m_rules.at(offset); m_rules[offset] = rule; emit subscriptionChanged(); if (rule->isCssRule() || oldRule->isCssRule()) mApp->reloadUserStyleSheet(); delete oldRule; return m_rules[offset]; } diff --git a/src/lib/adblock/adblocksubscription.h b/src/lib/adblock/adblocksubscription.h index d66140f8..505e3d6d 100644 --- a/src/lib/adblock/adblocksubscription.h +++ b/src/lib/adblock/adblocksubscription.h @@ -1,136 +1,136 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2016 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ /** * Copyright (c) 2009, Benjamin C. Meyer * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the Benjamin Meyer nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef ADBLOCKSUBSCRIPTION_H #define ADBLOCKSUBSCRIPTION_H #include #include #include "qzcommon.h" #include "adblockrule.h" #include "adblocksearchtree.h" class QUrl; class QNetworkReply; -class QUPZILLA_EXPORT AdBlockSubscription : public QObject +class FALKON_EXPORT AdBlockSubscription : public QObject { Q_OBJECT public: explicit AdBlockSubscription(const QString &title, QObject* parent = 0); ~AdBlockSubscription(); QString title() const; QString filePath() const; void setFilePath(const QString &path); QUrl url() const; void setUrl(const QUrl &url); virtual void loadSubscription(const QStringList &disabledRules); virtual void saveSubscription(); const AdBlockRule* rule(int offset) const; QVector allRules() const; const AdBlockRule* enableRule(int offset); const AdBlockRule* disableRule(int offset); virtual bool canEditRules() const; virtual bool canBeRemoved() const; virtual int addRule(AdBlockRule* rule); virtual bool removeRule(int offset); virtual const AdBlockRule* replaceRule(AdBlockRule* rule, int offset); public slots: void updateSubscription(); signals: void subscriptionChanged(); void subscriptionUpdated(); void subscriptionError(const QString &message); protected slots: void subscriptionDownloaded(); protected: virtual bool saveDownloadedData(const QByteArray &data); QNetworkReply *m_reply; QVector m_rules; private: QString m_title; QString m_filePath; QUrl m_url; bool m_updated; }; class AdBlockCustomList : public AdBlockSubscription { Q_OBJECT public: explicit AdBlockCustomList(QObject* parent = 0); void loadSubscription(const QStringList &disabledRules); void saveSubscription(); bool canEditRules() const; bool canBeRemoved() const; bool containsFilter(const QString &filter) const; bool removeFilter(const QString &filter); int addRule(AdBlockRule* rule); bool removeRule(int offset); const AdBlockRule* replaceRule(AdBlockRule* rule, int offset); }; #endif // ADBLOCKSUBSCRIPTION_H diff --git a/src/lib/adblock/adblocktreewidget.cpp b/src/lib/adblock/adblocktreewidget.cpp index 317e4b61..fa1c5d47 100644 --- a/src/lib/adblock/adblocktreewidget.cpp +++ b/src/lib/adblock/adblocktreewidget.cpp @@ -1,266 +1,266 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "adblocktreewidget.h" #include "adblocksubscription.h" #include #include #include #include #include AdBlockTreeWidget::AdBlockTreeWidget(AdBlockSubscription* subscription, QWidget* parent) : TreeWidget(parent) , m_subscription(subscription) , m_topItem(0) , m_itemChangingBlock(false) { setContextMenuPolicy(Qt::CustomContextMenu); setDefaultItemShowMode(TreeWidget::ItemsExpanded); setHeaderHidden(true); setAlternatingRowColors(true); setLayoutDirection(Qt::LeftToRight); connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextMenuRequested(QPoint))); connect(this, SIGNAL(itemChanged(QTreeWidgetItem*,int)), this, SLOT(itemChanged(QTreeWidgetItem*))); connect(m_subscription, SIGNAL(subscriptionUpdated()), this, SLOT(subscriptionUpdated())); connect(m_subscription, SIGNAL(subscriptionError(QString)), this, SLOT(subscriptionError(QString))); } AdBlockSubscription* AdBlockTreeWidget::subscription() const { return m_subscription; } void AdBlockTreeWidget::showRule(const AdBlockRule* rule) { if (!m_topItem && rule) { m_ruleToBeSelected = rule->filter(); } else if (!m_ruleToBeSelected.isEmpty()) { QList items = findItems(m_ruleToBeSelected, Qt::MatchRecursive); if (!items.isEmpty()) { QTreeWidgetItem* item = items.at(0); setCurrentItem(item); scrollToItem(item, QAbstractItemView::PositionAtCenter); } m_ruleToBeSelected.clear(); } } void AdBlockTreeWidget::contextMenuRequested(const QPoint &pos) { if (!m_subscription->canEditRules()) { return; } QTreeWidgetItem* item = itemAt(pos); if (!item) { return; } QMenu menu; menu.addAction(tr("Add Rule"), this, SLOT(addRule())); menu.addSeparator(); QAction* deleteAction = menu.addAction(tr("Remove Rule"), this, SLOT(removeRule())); if (!item->parent()) { deleteAction->setDisabled(true); } menu.exec(viewport()->mapToGlobal(pos)); } void AdBlockTreeWidget::itemChanged(QTreeWidgetItem* item) { if (!item || m_itemChangingBlock) { return; } m_itemChangingBlock = true; int offset = item->data(0, Qt::UserRole + 10).toInt(); const AdBlockRule* oldRule = m_subscription->rule(offset); if (item->checkState(0) == Qt::Unchecked && oldRule->isEnabled()) { // Disable rule const AdBlockRule* rule = m_subscription->disableRule(offset); adjustItemFeatures(item, rule); } else if (item->checkState(0) == Qt::Checked && !oldRule->isEnabled()) { // Enable rule const AdBlockRule* rule = m_subscription->enableRule(offset); adjustItemFeatures(item, rule); } else if (m_subscription->canEditRules()) { // Custom rule has been changed AdBlockRule* newRule = new AdBlockRule(item->text(0), m_subscription); const AdBlockRule* rule = m_subscription->replaceRule(newRule, offset); adjustItemFeatures(item, rule); } m_itemChangingBlock = false; } void AdBlockTreeWidget::copyFilter() { QTreeWidgetItem* item = currentItem(); if (!item) { return; } QApplication::clipboard()->setText(item->text(0)); } void AdBlockTreeWidget::addRule() { if (!m_subscription->canEditRules()) { return; } QString newRule = QInputDialog::getText(this, tr("Add Custom Rule"), tr("Please write your rule here:")); if (newRule.isEmpty()) { return; } AdBlockRule* rule = new AdBlockRule(newRule, m_subscription); int offset = m_subscription->addRule(rule); QTreeWidgetItem* item = new QTreeWidgetItem(); item->setText(0, newRule); item->setData(0, Qt::UserRole + 10, offset); item->setFlags(item->flags() | Qt::ItemIsEditable); m_itemChangingBlock = true; m_topItem->addChild(item); m_itemChangingBlock = false; adjustItemFeatures(item, rule); } void AdBlockTreeWidget::removeRule() { QTreeWidgetItem* item = currentItem(); if (!item || !m_subscription->canEditRules() || item == m_topItem) { return; } int offset = item->data(0, Qt::UserRole + 10).toInt(); m_subscription->removeRule(offset); deleteItem(item); } void AdBlockTreeWidget::subscriptionUpdated() { refresh(); m_itemChangingBlock = true; m_topItem->setText(0, tr("%1 (recently updated)").arg(m_subscription->title())); m_itemChangingBlock = false; } void AdBlockTreeWidget::subscriptionError(const QString &message) { refresh(); m_itemChangingBlock = true; m_topItem->setText(0, tr("%1 (Error: %2)").arg(m_subscription->title(), message)); m_itemChangingBlock = false; } void AdBlockTreeWidget::adjustItemFeatures(QTreeWidgetItem* item, const AdBlockRule* rule) { if (!rule->isEnabled()) { QFont font; font.setItalic(true); item->setForeground(0, QColor(Qt::gray)); if (!rule->isComment()) { item->setFlags(item->flags() | Qt::ItemIsUserCheckable); item->setCheckState(0, Qt::Unchecked); item->setFont(0, font); } return; } item->setFlags(item->flags() | Qt::ItemIsUserCheckable); item->setCheckState(0, Qt::Checked); if (rule->isException()) { item->setForeground(0, QColor(Qt::darkGreen)); item->setFont(0, QFont()); } else if (rule->isCssRule()) { item->setForeground(0, QColor(Qt::darkBlue)); item->setFont(0, QFont()); } } void AdBlockTreeWidget::keyPressEvent(QKeyEvent* event) { if (event->key() == Qt::Key_C && event->modifiers() & Qt::ControlModifier) { copyFilter(); } if (event->key() == Qt::Key_Delete) { removeRule(); } TreeWidget::keyPressEvent(event); } void AdBlockTreeWidget::refresh() { m_itemChangingBlock = true; clear(); QFont boldFont; boldFont.setBold(true); m_topItem = new QTreeWidgetItem(this); m_topItem->setText(0, m_subscription->title()); m_topItem->setFont(0, boldFont); m_topItem->setExpanded(true); addTopLevelItem(m_topItem); const QVector &allRules = m_subscription->allRules(); int index = 0; foreach (const AdBlockRule* rule, allRules) { QTreeWidgetItem* item = new QTreeWidgetItem(m_topItem); item->setText(0, rule->filter()); item->setData(0, Qt::UserRole + 10, index); if (m_subscription->canEditRules()) { item->setFlags(item->flags() | Qt::ItemIsEditable); } adjustItemFeatures(item, rule); ++index; } showRule(0); m_itemChangingBlock = false; } diff --git a/src/lib/adblock/adblocktreewidget.h b/src/lib/adblock/adblocktreewidget.h index 360035ba..aa056714 100644 --- a/src/lib/adblock/adblocktreewidget.h +++ b/src/lib/adblock/adblocktreewidget.h @@ -1,61 +1,61 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef ADBLOCKTREEWIDGET_H #define ADBLOCKTREEWIDGET_H #include "qzcommon.h" #include "treewidget.h" class AdBlockSubscription; class AdBlockRule; -class QUPZILLA_EXPORT AdBlockTreeWidget : public TreeWidget +class FALKON_EXPORT AdBlockTreeWidget : public TreeWidget { Q_OBJECT public: explicit AdBlockTreeWidget(AdBlockSubscription* subscription, QWidget* parent = 0); AdBlockSubscription* subscription() const; void showRule(const AdBlockRule* rule); void refresh(); public slots: void addRule(); void removeRule(); private slots: void contextMenuRequested(const QPoint &pos); void itemChanged(QTreeWidgetItem* item); void copyFilter(); void subscriptionUpdated(); void subscriptionError(const QString &message); private: void adjustItemFeatures(QTreeWidgetItem* item, const AdBlockRule* rule); void keyPressEvent(QKeyEvent* event); AdBlockSubscription* m_subscription; QTreeWidgetItem* m_topItem; QString m_ruleToBeSelected; bool m_itemChangingBlock; }; #endif // ADBLOCKTREEWIDGET_H diff --git a/src/lib/adblock/adblockurlinterceptor.h b/src/lib/adblock/adblockurlinterceptor.h index e8709636..3e31b1a6 100644 --- a/src/lib/adblock/adblockurlinterceptor.h +++ b/src/lib/adblock/adblockurlinterceptor.h @@ -1,38 +1,38 @@ /* ============================================================ -* QupZilla - QtWebEngine based browser +* Falkon - Qt web browser * Copyright (C) 2015 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef ADBLOCKURLINTERCEPTOR_H #define ADBLOCKURLINTERCEPTOR_H #include "urlinterceptor.h" #include "qzcommon.h" class AdBlockManager; -class QUPZILLA_EXPORT AdBlockUrlInterceptor : public UrlInterceptor +class FALKON_EXPORT AdBlockUrlInterceptor : public UrlInterceptor { public: explicit AdBlockUrlInterceptor(AdBlockManager* manager); void interceptRequest(QWebEngineUrlRequestInfo &info); private: AdBlockManager *m_manager; }; #endif // ADBLOCKURLINTERCEPTOR_H diff --git a/src/lib/app/autosaver.cpp b/src/lib/app/autosaver.cpp index 24f38e78..894d2799 100644 --- a/src/lib/app/autosaver.cpp +++ b/src/lib/app/autosaver.cpp @@ -1,52 +1,52 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2016 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "autosaver.h" #include #define SAVE_DELAY 1000 * 10 // 10 seconds AutoSaver::AutoSaver(QObject* parent) : QObject(parent) { } void AutoSaver::saveIfNecessary() { if (m_timer.isActive()) { m_timer.stop(); emit save(); } } void AutoSaver::changeOccurred() { if (!m_timer.isActive()) { m_timer.start(SAVE_DELAY, this); } } void AutoSaver::timerEvent(QTimerEvent* event) { if (event->timerId() == m_timer.timerId()) { m_timer.stop(); emit save(); } QObject::timerEvent(event); } diff --git a/src/lib/app/autosaver.h b/src/lib/app/autosaver.h index bf9ec32b..01d82d14 100644 --- a/src/lib/app/autosaver.h +++ b/src/lib/app/autosaver.h @@ -1,49 +1,49 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2016 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef AUTOSAVER_H #define AUTOSAVER_H #include #include #include "qzcommon.h" -class QUPZILLA_EXPORT AutoSaver : public QObject +class FALKON_EXPORT AutoSaver : public QObject { Q_OBJECT public: explicit AutoSaver(QObject* parent = 0); // Emits save() if timer is running. Call this from destructor. void saveIfNecessary(); public slots: // Tells AutoSaver that change occurred. Signal save() will be emitted after a delay void changeOccurred(); signals: void save(); private: void timerEvent(QTimerEvent* event); QBasicTimer m_timer; }; #endif // AUTOSAVER_H diff --git a/src/lib/app/browserwindow.cpp b/src/lib/app/browserwindow.cpp index badb942a..9ce4a38a 100644 --- a/src/lib/app/browserwindow.cpp +++ b/src/lib/app/browserwindow.cpp @@ -1,1515 +1,1515 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "browserwindow.h" #include "tabwidget.h" #include "tabbar.h" #include "webpage.h" #include "tabbedwebview.h" #include "lineedit.h" #include "history.h" #include "locationbar.h" #include "websearchbar.h" #include "pluginproxy.h" #include "sidebar.h" #include "downloadmanager.h" #include "cookiejar.h" #include "cookiemanager.h" #include "bookmarkstoolbar.h" #include "clearprivatedata.h" #include "autofill.h" #include "mainapplication.h" #include "checkboxdialog.h" #include "adblockmanager.h" #include "clickablelabel.h" #include "docktitlebarwidget.h" #include "iconprovider.h" #include "progressbar.h" #include "adblockicon.h" #include "closedtabsmanager.h" #include "statusbarmessage.h" #include "browsinglibrary.h" #include "navigationbar.h" #include "bookmarksimport/bookmarksimportdialog.h" #include "qztools.h" #include "reloadstopbutton.h" #include "enhancedmenu.h" #include "navigationcontainer.h" #include "settings.h" #include "qzsettings.h" #include "webtab.h" #include "speeddial.h" #include "menubar.h" #include "bookmarkstools.h" #include "bookmarksmenu.h" #include "historymenu.h" #include "mainmenu.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef QZ_WS_X11 #include #include #include #endif BrowserWindow::BrowserWindow(Qz::BrowserWindowType type, const QUrl &startUrl) : QMainWindow(0) , m_startUrl(startUrl) , m_windowType(type) , m_startTab(0) , m_startPage(0) , m_sideBarManager(new SideBarManager(this)) , m_statusBarMessage(new StatusBarMessage(this)) , m_isHtmlFullScreen(false) , m_hideNavigationTimer(0) { setAttribute(Qt::WA_DeleteOnClose); setAttribute(Qt::WA_DontCreateNativeAncestors); setObjectName("mainwindow"); - setWindowTitle(tr("QupZilla")); + setWindowTitle(tr("Falkon")); setProperty("private", mApp->isPrivate()); setupUi(); setupMenu(); m_hideNavigationTimer = new QTimer(this); m_hideNavigationTimer->setInterval(1000); m_hideNavigationTimer->setSingleShot(true); connect(m_hideNavigationTimer, SIGNAL(timeout()), this, SLOT(hideNavigationSlot())); connect(mApp, SIGNAL(settingsReloaded()), this, SLOT(loadSettings())); QTimer::singleShot(0, this, SLOT(postLaunch())); if (mApp->isPrivate()) { - QzTools::setWmClass("QupZilla Browser (Private Window)", this); + QzTools::setWmClass("Falkon Browser (Private Window)", this); } else { - QzTools::setWmClass("QupZilla Browser", this); + QzTools::setWmClass("Falkon Browser", this); } } BrowserWindow::~BrowserWindow() { mApp->plugins()->emitMainWindowDeleted(this); foreach (const QPointer &pointer, m_deleteOnCloseWidgets) { if (pointer) { pointer->deleteLater(); } } } void BrowserWindow::setStartTab(WebTab* tab) { m_startTab = tab; } void BrowserWindow::setStartPage(WebPage *page) { m_startPage = page; } void BrowserWindow::postLaunch() { loadSettings(); bool addTab = true; QUrl startUrl; switch (mApp->afterLaunch()) { case MainApplication::OpenBlankPage: startUrl = QUrl(); break; case MainApplication::OpenSpeedDial: - startUrl = QUrl("qupzilla:speeddial"); + startUrl = QUrl("falkon:speeddial"); break; case MainApplication::OpenHomePage: case MainApplication::RestoreSession: case MainApplication::SelectSession: startUrl = m_homepage; break; default: break; } switch (m_windowType) { case Qz::BW_FirstAppWindow: if (mApp->isStartingAfterCrash()) { addTab = false; startUrl.clear(); - m_tabWidget->addView(QUrl("qupzilla:restore"), Qz::NT_CleanSelectedTabAtTheEnd); + m_tabWidget->addView(QUrl("falkon:restore"), Qz::NT_CleanSelectedTabAtTheEnd); } else if ((mApp->afterLaunch() == MainApplication::SelectSession || mApp->afterLaunch() == MainApplication::RestoreSession) && mApp->restoreManager()) { addTab = !mApp->restoreSession(this, mApp->restoreManager()->restoreData()); } break; case Qz::BW_NewWindow: case Qz::BW_MacFirstWindow: addTab = true; break; case Qz::BW_OtherRestoredWindow: addTab = false; break; } show(); if (!m_startUrl.isEmpty()) { startUrl = m_startUrl; addTab = true; } if (m_startTab) { addTab = false; m_tabWidget->addView(m_startTab); } if (m_startPage) { addTab = false; m_tabWidget->addView(QUrl()); weView()->setPage(m_startPage); } if (addTab) { m_tabWidget->addView(startUrl, Qz::NT_CleanSelectedTabAtTheEnd); - if (startUrl.isEmpty() || startUrl.toString() == QLatin1String("qupzilla:speeddial")) { + if (startUrl.isEmpty() || startUrl.toString() == QLatin1String("falkon:speeddial")) { locationBar()->setFocus(); } } // Something went really wrong .. add one tab if (m_tabWidget->tabBar()->normalTabsCount() <= 0) { m_tabWidget->addView(m_homepage, Qz::NT_SelectedTabAtTheEnd); } mApp->plugins()->emitMainWindowCreated(this); emit startingCompleted(); raise(); activateWindow(); QTimer::singleShot(0, this, [this]() { // Scroll to current tab tabWidget()->tabBar()->ensureVisible(); // Update focus if (!m_startPage && LocationBar::convertUrlToText(weView()->page()->requestedUrl()).isEmpty()) locationBar()->setFocus(); else weView()->setFocus(); }); } void BrowserWindow::setupUi() { int locationBarWidth; int websearchBarWidth; QDesktopWidget* desktop = mApp->desktop(); int windowWidth = desktop->availableGeometry().width() / 1.3; int windowHeight = desktop->availableGeometry().height() / 1.3; Settings settings; settings.beginGroup("Browser-View-Settings"); if (settings.value("WindowMaximised", false).toBool()) { resize(windowWidth, windowHeight); setWindowState(Qt::WindowMaximized); } else { // Let the WM decides where to put new browser window if ((m_windowType != Qz::BW_FirstAppWindow && m_windowType != Qz::BW_MacFirstWindow) && mApp->getWindow()) { #ifdef Q_WS_WIN // Windows WM places every new window in the middle of screen .. for some reason QPoint p = mApp->getWindow()->geometry().topLeft(); p.setX(p.x() + 30); p.setY(p.y() + 30); if (!desktop->availableGeometry(mApp->getWindow()).contains(p)) { p.setX(desktop->availableGeometry(mApp->getWindow()).x() + 30); p.setY(desktop->availableGeometry(mApp->getWindow()).y() + 30); } setGeometry(QRect(p, mApp->getWindow()->size())); #else resize(mApp->getWindow()->size()); #endif } else if (!restoreGeometry(settings.value("WindowGeometry").toByteArray())) { #ifdef Q_WS_WIN setGeometry(QRect(desktop->availableGeometry(mApp->getWindow()).x() + 30, desktop->availableGeometry(mApp->getWindow()).y() + 30, windowWidth, windowHeight)); #else resize(windowWidth, windowHeight); #endif } } locationBarWidth = settings.value("LocationBarWidth", 480).toInt(); websearchBarWidth = settings.value("WebSearchBarWidth", 140).toInt(); settings.endGroup(); QWidget* widget = new QWidget(this); widget->setCursor(Qt::ArrowCursor); setCentralWidget(widget); m_mainLayout = new QVBoxLayout(widget); m_mainLayout->setContentsMargins(0, 0, 0, 0); m_mainLayout->setSpacing(0); m_mainSplitter = new QSplitter(this); m_mainSplitter->setObjectName("sidebar-splitter"); m_tabWidget = new TabWidget(this); m_superMenu = new QMenu(this); m_navigationToolbar = new NavigationBar(this); m_navigationToolbar->setSplitterSizes(locationBarWidth, websearchBarWidth); m_bookmarksToolbar = new BookmarksToolbar(this); m_navigationContainer = new NavigationContainer(this); m_navigationContainer->addWidget(m_navigationToolbar); m_navigationContainer->addWidget(m_bookmarksToolbar); m_navigationContainer->setTabBar(m_tabWidget->tabBar()); m_mainSplitter->addWidget(m_tabWidget); m_mainSplitter->setCollapsible(0, false); m_mainLayout->addWidget(m_navigationContainer); m_mainLayout->addWidget(m_mainSplitter); statusBar()->setObjectName("mainwindow-statusbar"); statusBar()->setCursor(Qt::ArrowCursor); m_progressBar = new ProgressBar(statusBar()); m_adblockIcon = new AdBlockIcon(this); m_ipLabel = new QLabel(this); m_ipLabel->setObjectName("statusbar-ip-label"); m_ipLabel->setToolTip(tr("IP Address of current page")); statusBar()->addPermanentWidget(m_progressBar); statusBar()->addPermanentWidget(m_ipLabel); statusBar()->addPermanentWidget(m_adblockIcon); // Workaround for Oxygen tooltips not having transparent background QPalette pal = QToolTip::palette(); QColor col = pal.window().color(); col.setAlpha(0); pal.setColor(QPalette::Window, col); QToolTip::setPalette(pal); // Set some sane minimum width setMinimumWidth(300); } void BrowserWindow::setupMenu() { #ifdef Q_OS_MACOS static MainMenu* macMainMenu = 0; if (!macMainMenu) { macMainMenu = new MainMenu(this, 0); macMainMenu->initMenuBar(new QMenuBar(0)); connect(mApp, SIGNAL(activeWindowChanged(BrowserWindow*)), macMainMenu, SLOT(setWindow(BrowserWindow*))); } else { macMainMenu->setWindow(this); } m_mainMenu = macMainMenu; #else setMenuBar(new MenuBar(this)); m_mainMenu = new MainMenu(this, this); m_mainMenu->initMenuBar(menuBar()); #endif m_mainMenu->initSuperMenu(m_superMenu); // Setup other shortcuts QShortcut* reloadBypassCacheAction = new QShortcut(QKeySequence(QSL("Ctrl+F5")), this); QShortcut* reloadBypassCacheAction2 = new QShortcut(QKeySequence(QSL("Ctrl+Shift+R")), this); connect(reloadBypassCacheAction, SIGNAL(activated()), this, SLOT(reloadBypassCache())); connect(reloadBypassCacheAction2, SIGNAL(activated()), this, SLOT(reloadBypassCache())); QShortcut* closeTabAction = new QShortcut(QKeySequence(QSL("Ctrl+W")), this); QShortcut* closeTabAction2 = new QShortcut(QKeySequence(QSL("Ctrl+F4")), this); connect(closeTabAction, SIGNAL(activated()), this, SLOT(closeTab())); connect(closeTabAction2, SIGNAL(activated()), this, SLOT(closeTab())); QShortcut* reloadAction = new QShortcut(QKeySequence("Ctrl+R"), this); connect(reloadAction, SIGNAL(activated()), this, SLOT(reload())); QShortcut* openLocationAction = new QShortcut(QKeySequence("Alt+D"), this); connect(openLocationAction, SIGNAL(activated()), this, SLOT(openLocation())); QShortcut* inspectorAction = new QShortcut(QKeySequence(QSL("F12")), this); connect(inspectorAction, SIGNAL(activated()), this, SLOT(toggleWebInspector())); } QAction* BrowserWindow::createEncodingAction(const QString &codecName, const QString &activeCodecName, QMenu* menu) { QAction* action = new QAction(codecName, menu); action->setData(codecName); action->setCheckable(true); connect(action, SIGNAL(triggered()), this, SLOT(changeEncoding())); if (activeCodecName.compare(codecName, Qt::CaseInsensitive) == 0) { action->setChecked(true); } return action; } void BrowserWindow::createEncodingSubMenu(const QString &name, QStringList &codecNames, QMenu* menu) { if (codecNames.isEmpty()) { return; } QCollator collator; collator.setNumericMode(true); std::sort(codecNames.begin(), codecNames.end(), [collator](const QString &a, const QString &b) { return collator.compare(a, b) < 0; }); QMenu* subMenu = new QMenu(name, menu); const QString activeCodecName = QWebEngineSettings::defaultSettings()->defaultTextEncoding(); foreach (const QString &codecName, codecNames) { subMenu->addAction(createEncodingAction(codecName, activeCodecName, subMenu)); } menu->addMenu(subMenu); } void BrowserWindow::loadSettings() { Settings settings; //Url settings settings.beginGroup("Web-URL-Settings"); - m_homepage = settings.value("homepage", "qupzilla:start").toUrl(); + m_homepage = settings.value("homepage", "falkon:start").toUrl(); settings.endGroup(); //Browser Window settings settings.beginGroup("Browser-View-Settings"); bool showStatusBar = settings.value("showStatusBar", false).toBool(); bool showReloadButton = settings.value("showReloadButton", true).toBool(); bool showHomeButton = settings.value("showHomeButton", true).toBool(); bool showBackForwardButtons = settings.value("showBackForwardButtons", true).toBool(); bool showAddTabButton = settings.value("showAddTabButton", false).toBool(); bool showWebSearchBar = settings.value("showWebSearchBar", true).toBool(); bool showBookmarksToolbar = settings.value("showBookmarksToolbar", true).toBool(); bool showNavigationToolbar = settings.value("showNavigationToolbar", true).toBool(); bool showMenuBar = settings.value("showMenubar", false).toBool(); m_sideBarWidth = settings.value("SideBarWidth", 250).toInt(); m_webViewWidth = settings.value("WebViewWidth", 2000).toInt(); const QString activeSideBar = settings.value("SideBar", "None").toString(); // Make sure both menubar and navigationbar are not hidden // Fixes #781 if (!showNavigationToolbar) { showMenuBar = true; settings.setValue("showMenubar", true); } settings.endGroup(); settings.beginGroup("Shortcuts"); m_useTabNumberShortcuts = settings.value("useTabNumberShortcuts", true).toBool(); m_useSpeedDialNumberShortcuts = settings.value("useSpeedDialNumberShortcuts", true).toBool(); m_useSingleKeyShortcuts = settings.value("useSingleKeyShortcuts", false).toBool(); settings.endGroup(); settings.beginGroup("Web-Browser-Settings"); QAction *quitAction = m_mainMenu->action(QSL("Standard/Quit")); if (settings.value("closeAppWithCtrlQ", true).toBool()) { quitAction->setShortcut(QzTools::actionShortcut(QKeySequence::Quit, QKeySequence(QSL("Ctrl+Q")))); } else { quitAction->setShortcut(QKeySequence()); } settings.endGroup(); m_adblockIcon->setEnabled(settings.value("AdBlock/enabled", true).toBool()); statusBar()->setVisible(!isFullScreen() && showStatusBar); m_bookmarksToolbar->setVisible(showBookmarksToolbar); m_navigationToolbar->setVisible(showNavigationToolbar); #ifndef Q_OS_MACOS menuBar()->setVisible(!isFullScreen() && showMenuBar); #endif m_navigationToolbar->setSuperMenuVisible(!showMenuBar); m_navigationToolbar->buttonReloadStop()->setVisible(showReloadButton); m_navigationToolbar->buttonHome()->setVisible(showHomeButton); m_navigationToolbar->buttonBack()->setVisible(showBackForwardButtons); m_navigationToolbar->buttonForward()->setVisible(showBackForwardButtons); m_navigationToolbar->webSearchBar()->setVisible(showWebSearchBar); m_navigationToolbar->buttonAddTab()->setVisible(showAddTabButton); m_sideBarManager->showSideBar(activeSideBar, false); } void BrowserWindow::goForward() { weView()->forward(); } void BrowserWindow::reload() { weView()->reload(); } void BrowserWindow::reloadBypassCache() { weView()->reloadBypassCache(); } void BrowserWindow::goBack() { weView()->back(); } TabbedWebView* BrowserWindow::weView() const { return weView(m_tabWidget->currentIndex()); } TabbedWebView* BrowserWindow::weView(int index) const { WebTab* webTab = qobject_cast(m_tabWidget->widget(index)); if (!webTab) { return 0; } return webTab->webView(); } LocationBar* BrowserWindow::locationBar() const { return qobject_cast(m_tabWidget->locationBars()->currentWidget()); } TabWidget* BrowserWindow::tabWidget() const { return m_tabWidget; } BookmarksToolbar* BrowserWindow::bookmarksToolbar() const { return m_bookmarksToolbar; } StatusBarMessage* BrowserWindow::statusBarMessage() const { return m_statusBarMessage; } NavigationBar* BrowserWindow::navigationBar() const { return m_navigationToolbar; } SideBarManager* BrowserWindow::sideBarManager() const { return m_sideBarManager; } QLabel* BrowserWindow::ipLabel() const { return m_ipLabel; } AdBlockIcon* BrowserWindow::adBlockIcon() const { return m_adblockIcon; } QMenu* BrowserWindow::superMenu() const { return m_superMenu; } QUrl BrowserWindow::homepageUrl() const { return m_homepage; } Qz::BrowserWindowType BrowserWindow::windowType() const { return m_windowType; } QAction* BrowserWindow::action(const QString &name) const { return m_mainMenu->action(name); } void BrowserWindow::setWindowTitle(const QString &t) { QString title = t; if (mApp->isPrivate()) { title.append(tr(" (Private Browsing)")); } QMainWindow::setWindowTitle(title); } void BrowserWindow::changeEncoding() { if (QAction* action = qobject_cast(sender())) { const QString encoding = action->data().toString(); QWebEngineSettings::defaultSettings()->setDefaultTextEncoding(encoding); Settings settings; settings.setValue("Web-Browser-Settings/DefaultEncoding", encoding); weView()->reload(); } } void BrowserWindow::printPage() { weView()->printPage(); } void BrowserWindow::bookmarkPage() { TabbedWebView* view = weView(); BookmarksTools::addBookmarkDialog(this, view->url(), view->title()); } void BrowserWindow::bookmarkAllTabs() { BookmarksTools::bookmarkAllTabsDialog(this, m_tabWidget); } void BrowserWindow::addBookmark(const QUrl &url, const QString &title) { BookmarksTools::addBookmarkDialog(this, url, title); } void BrowserWindow::goHome() { loadAddress(m_homepage); } void BrowserWindow::goHomeInNewTab() { m_tabWidget->addView(m_homepage, Qz::NT_SelectedTab); } void BrowserWindow::loadActionUrl(QObject* obj) { if (!obj) { obj = sender(); } if (QAction* action = qobject_cast(obj)) { loadAddress(action->data().toUrl()); } } void BrowserWindow::loadActionUrlInNewTab(QObject* obj) { if (!obj) { obj = sender(); } if (QAction* action = qobject_cast(obj)) { m_tabWidget->addView(action->data().toUrl(), Qz::NT_SelectedTabAtTheEnd); } } void BrowserWindow::loadAddress(const QUrl &url) { if (weView()->webTab()->isPinned()) { int index = m_tabWidget->addView(url, qzSettings->newTabPosition); weView(index)->setFocus(); } else { weView()->setFocus(); weView()->load(url); } } void BrowserWindow::showHistoryManager() { mApp->browsingLibrary()->showHistory(this); } void BrowserWindow::showSource(WebView *view) { if (!view) view = weView(); view->showSource(); } void BrowserWindow::showNormal() { if (m_normalWindowState & Qt::WindowMaximized) { QMainWindow::showMaximized(); } else { QMainWindow::showNormal(); } } SideBar* BrowserWindow::addSideBar() { if (m_sideBar) { return m_sideBar.data(); } m_sideBar = new SideBar(m_sideBarManager, this); m_mainSplitter->insertWidget(0, m_sideBar.data()); m_mainSplitter->setCollapsible(0, false); m_mainSplitter->setSizes(QList() << m_sideBarWidth << m_webViewWidth); return m_sideBar.data(); } void BrowserWindow::saveSideBarWidth() { // That +1 is important here, without it, the sidebar width would // decrease by 1 pixel every close m_sideBarWidth = m_mainSplitter->sizes().at(0) + 1; m_webViewWidth = width() - m_sideBarWidth; } void BrowserWindow::toggleShowMenubar() { #ifdef Q_OS_MACOS // We use one shared global menubar on Mac that can't be hidden return; #endif setUpdatesEnabled(false); menuBar()->setVisible(!menuBar()->isVisible()); m_navigationToolbar->setSuperMenuVisible(!menuBar()->isVisible()); setUpdatesEnabled(true); Settings().setValue("Browser-View-Settings/showMenubar", menuBar()->isVisible()); // Make sure we show Navigation Toolbar when Menu Bar is hidden if (!m_navigationToolbar->isVisible() && !menuBar()->isVisible()) { toggleShowNavigationToolbar(); } } void BrowserWindow::toggleShowStatusBar() { setUpdatesEnabled(false); statusBar()->setVisible(!statusBar()->isVisible()); setUpdatesEnabled(true); Settings().setValue("Browser-View-Settings/showStatusBar", statusBar()->isVisible()); } void BrowserWindow::toggleShowBookmarksToolbar() { setUpdatesEnabled(false); m_bookmarksToolbar->setVisible(!m_bookmarksToolbar->isVisible()); setUpdatesEnabled(true); Settings().setValue("Browser-View-Settings/showBookmarksToolbar", m_bookmarksToolbar->isVisible()); Settings().setValue("Browser-View-Settings/instantBookmarksToolbar", false); } void BrowserWindow::toggleShowNavigationToolbar() { setUpdatesEnabled(false); m_navigationToolbar->setVisible(!m_navigationToolbar->isVisible()); setUpdatesEnabled(true); Settings().setValue("Browser-View-Settings/showNavigationToolbar", m_navigationToolbar->isVisible()); #ifndef Q_OS_MACOS // Make sure we show Menu Bar when Navigation Toolbar is hidden if (!m_navigationToolbar->isVisible() && !menuBar()->isVisible()) { toggleShowMenubar(); } #endif } void BrowserWindow::toggleTabsOnTop(bool enable) { qzSettings->tabsOnTop = enable; m_navigationContainer->toggleTabsOnTop(enable); } void BrowserWindow::toggleFullScreen() { if (m_isHtmlFullScreen) { weView()->triggerPageAction(QWebEnginePage::ExitFullScreen); return; } if (isFullScreen()) showNormal(); else showFullScreen(); } void BrowserWindow::toggleHtmlFullScreen(bool enable) { if (enable) showFullScreen(); else showNormal(); if (m_sideBar) m_sideBar.data()->setHidden(enable); m_isHtmlFullScreen = enable; } void BrowserWindow::showWebInspector() { if (weView() && weView()->webTab()) { weView()->webTab()->showWebInspector(); } } void BrowserWindow::toggleWebInspector() { if (weView() && weView()->webTab()) { weView()->webTab()->toggleWebInspector(); } } void BrowserWindow::refreshHistory() { m_navigationToolbar->refreshHistory(); } void BrowserWindow::currentTabChanged() { TabbedWebView* view = weView(); if (!view) { return; } - setWindowTitle(tr("%1 - QupZilla").arg(view->webTab()->title())); + setWindowTitle(tr("%1 - Falkon").arg(view->webTab()->title())); m_ipLabel->setText(view->getIp()); view->setFocus(); updateLoadingActions(); // Setting correct tab order (LocationBar -> WebSearchBar -> WebView) setTabOrder(locationBar(), m_navigationToolbar->webSearchBar()); setTabOrder(m_navigationToolbar->webSearchBar(), view); } void BrowserWindow::updateLoadingActions() { TabbedWebView* view = weView(); if (!view) { return; } bool isLoading = view->isLoading(); m_ipLabel->setVisible(!isLoading); m_progressBar->setVisible(isLoading); action(QSL("View/Stop"))->setEnabled(isLoading); action(QSL("View/Reload"))->setEnabled(!isLoading); if (isLoading) { m_progressBar->setValue(view->loadingProgress()); m_navigationToolbar->showStopButton(); } else { m_navigationToolbar->showReloadButton(); } } void BrowserWindow::addDeleteOnCloseWidget(QWidget* widget) { if (!m_deleteOnCloseWidgets.contains(widget)) { m_deleteOnCloseWidgets.append(widget); } } void BrowserWindow::restoreWindowState(const RestoreManager::WindowData &d) { restoreState(d.windowState); m_tabWidget->restoreState(d.tabsState, d.currentTab); } void BrowserWindow::createToolbarsMenu(QMenu* menu) { removeActions(menu->actions()); menu->clear(); QAction* action; #ifndef Q_OS_MACOS action = menu->addAction(tr("&Menu Bar"), this, SLOT(toggleShowMenubar())); action->setCheckable(true); action->setChecked(menuBar()->isVisible()); #endif action = menu->addAction(tr("&Navigation Toolbar"), this, SLOT(toggleShowNavigationToolbar())); action->setCheckable(true); action->setChecked(m_navigationToolbar->isVisible()); action = menu->addAction(tr("&Bookmarks Toolbar"), this, SLOT(toggleShowBookmarksToolbar())); action->setCheckable(true); action->setChecked(Settings().value("Browser-View-Settings/showBookmarksToolbar").toBool()); menu->addSeparator(); action = menu->addAction(tr("&Tabs on Top"), this, SLOT(toggleTabsOnTop(bool))); action->setCheckable(true); action->setChecked(qzSettings->tabsOnTop); addActions(menu->actions()); } void BrowserWindow::createSidebarsMenu(QMenu* menu) { m_sideBarManager->createMenu(menu); } void BrowserWindow::createEncodingMenu(QMenu* menu) { const QString activeCodecName = QWebEngineSettings::defaultSettings()->defaultTextEncoding(); QStringList isoCodecs; QStringList utfCodecs; QStringList windowsCodecs; QStringList isciiCodecs; QStringList ibmCodecs; QStringList otherCodecs; QStringList allCodecs; foreach (const int mib, QTextCodec::availableMibs()) { const QString codecName = QString::fromUtf8(QTextCodec::codecForMib(mib)->name()); if (!allCodecs.contains(codecName)) allCodecs.append(codecName); else continue; if (codecName.startsWith(QLatin1String("ISO"))) isoCodecs.append(codecName); else if (codecName.startsWith(QLatin1String("UTF"))) utfCodecs.append(codecName); else if (codecName.startsWith(QLatin1String("windows"))) windowsCodecs.append(codecName); else if (codecName.startsWith(QLatin1String("Iscii"))) isciiCodecs.append(codecName); else if (codecName.startsWith(QLatin1String("IBM"))) ibmCodecs.append(codecName); else if (codecName == QLatin1String("System")) menu->addAction(createEncodingAction(codecName, activeCodecName, menu)); else otherCodecs.append(codecName); } if (!menu->isEmpty()) menu->addSeparator(); createEncodingSubMenu("ISO", isoCodecs, menu); createEncodingSubMenu("UTF", utfCodecs, menu); createEncodingSubMenu("Windows", windowsCodecs, menu); createEncodingSubMenu("Iscii", isciiCodecs, menu); createEncodingSubMenu("IBM", ibmCodecs, menu); createEncodingSubMenu(tr("Other"), otherCodecs, menu); } void BrowserWindow::removeActions(const QList &actions) { foreach (QAction *action, actions) { removeAction(action); } } void BrowserWindow::addTab() { m_tabWidget->addView(QUrl(), Qz::NT_SelectedNewEmptyTab, true); m_tabWidget->setCurrentTabFresh(true); if (isFullScreen()) showNavigationWithFullScreen(); } void BrowserWindow::webSearch() { m_navigationToolbar->webSearchBar()->setFocus(); m_navigationToolbar->webSearchBar()->selectAll(); } void BrowserWindow::searchOnPage() { if (weView() && weView()->webTab()) { weView()->webTab()->showSearchToolBar(); } } void BrowserWindow::openFile() { const QString fileTypes = QString("%1(*.html *.htm *.shtml *.shtm *.xhtml);;" "%2(*.png *.jpg *.jpeg *.bmp *.gif *.svg *.tiff);;" "%3(*.txt);;" "%4(*.*)").arg(tr("HTML files"), tr("Image files"), tr("Text files"), tr("All files")); const QString filePath = QzTools::getOpenFileName("MainWindow-openFile", this, tr("Open file..."), QDir::homePath(), fileTypes); if (!filePath.isEmpty()) { loadAddress(QUrl::fromLocalFile(filePath)); } } void BrowserWindow::openLocation() { if (isFullScreen()) { showNavigationWithFullScreen(); } locationBar()->setFocus(); locationBar()->selectAll(); } bool BrowserWindow::fullScreenNavigationVisible() const { return m_navigationContainer->isVisible(); } void BrowserWindow::showNavigationWithFullScreen() { if (m_isHtmlFullScreen) return; if (m_hideNavigationTimer->isActive()) { m_hideNavigationTimer->stop(); } m_navigationContainer->show(); } void BrowserWindow::hideNavigationWithFullScreen() { if (m_tabWidget->isCurrentTabFresh()) return; if (!m_hideNavigationTimer->isActive()) { m_hideNavigationTimer->start(); } } void BrowserWindow::hideNavigationSlot() { TabbedWebView* view = weView(); bool mouseInView = view && view->underMouse(); if (isFullScreen() && mouseInView) { m_navigationContainer->hide(); } } bool BrowserWindow::event(QEvent* event) { switch (event->type()) { case QEvent::WindowStateChange: if (!(m_oldWindowState & Qt::WindowFullScreen) && windowState() & Qt::WindowFullScreen) { // Enter fullscreen m_normalWindowState = m_oldWindowState; m_statusBarVisible = statusBar()->isVisible(); #ifndef Q_OS_MACOS m_menuBarVisible = menuBar()->isVisible(); menuBar()->hide(); #endif statusBar()->hide(); m_navigationContainer->hide(); m_navigationToolbar->buttonExitFullscreen()->show(); } else if (m_oldWindowState & Qt::WindowFullScreen && !(windowState() & Qt::WindowFullScreen)) { // Leave fullscreen statusBar()->setVisible(m_statusBarVisible); #ifndef Q_OS_MACOS menuBar()->setVisible(m_menuBarVisible); #endif m_navigationContainer->show(); m_navigationToolbar->setSuperMenuVisible(!m_menuBarVisible); m_navigationToolbar->buttonExitFullscreen()->hide(); m_isHtmlFullScreen = false; } if (m_hideNavigationTimer) { m_hideNavigationTimer->stop(); } m_oldWindowState = windowState(); break; default: break; } return QMainWindow::event(event); } void BrowserWindow::resizeEvent(QResizeEvent* event) { m_bookmarksToolbar->setMaximumWidth(width()); QMainWindow::resizeEvent(event); } void BrowserWindow::keyPressEvent(QKeyEvent* event) { if (mApp->plugins()->processKeyPress(Qz::ON_BrowserWindow, this, event)) { return; } int number = -1; TabbedWebView* view = weView(); switch (event->key()) { case Qt::Key_Back: if (view) { view->back(); event->accept(); } break; case Qt::Key_Forward: if (view) { view->forward(); event->accept(); } break; case Qt::Key_Stop: if (view) { view->stop(); event->accept(); } break; case Qt::Key_Reload: case Qt::Key_Refresh: if (view) { view->reload(); event->accept(); } break; case Qt::Key_HomePage: goHome(); event->accept(); break; case Qt::Key_Favorites: mApp->browsingLibrary()->showBookmarks(this); event->accept(); break; case Qt::Key_Search: searchOnPage(); event->accept(); break; case Qt::Key_F6: case Qt::Key_OpenUrl: openLocation(); event->accept(); break; case Qt::Key_History: showHistoryManager(); event->accept(); break; case Qt::Key_AddFavorite: bookmarkPage(); event->accept(); break; case Qt::Key_News: action(QSL("Tools/RssReader"))->trigger(); event->accept(); break; case Qt::Key_Tools: action(QSL("Standard/Preferences"))->trigger(); event->accept(); break; case Qt::Key_Tab: if (event->modifiers() == Qt::ControlModifier) { m_tabWidget->nextTab(); event->accept(); } break; case Qt::Key_Backtab: if (event->modifiers() == (Qt::ControlModifier + Qt::ShiftModifier)) { m_tabWidget->previousTab(); event->accept(); } break; case Qt::Key_PageDown: if (event->modifiers() == Qt::ControlModifier) { m_tabWidget->nextTab(); event->accept(); } break; case Qt::Key_PageUp: if (event->modifiers() == Qt::ControlModifier) { m_tabWidget->previousTab(); event->accept(); } break; case Qt::Key_Equal: if (view && event->modifiers() == Qt::ControlModifier) { view->zoomIn(); event->accept(); } break; case Qt::Key_I: if (event->modifiers() == Qt::ControlModifier) { action(QSL("Tools/SiteInfo"))->trigger(); event->accept(); } break; case Qt::Key_U: if (event->modifiers() == Qt::ControlModifier) { action(QSL("View/PageSource"))->trigger(); event->accept(); } break; case Qt::Key_F: if (event->modifiers() == Qt::ControlModifier) { action(QSL("Edit/Find"))->trigger(); event->accept(); } break; case Qt::Key_Slash: if (m_useSingleKeyShortcuts) { action(QSL("Edit/Find"))->trigger(); event->accept(); } break; case Qt::Key_1: number = 1; break; case Qt::Key_2: number = 2; break; case Qt::Key_3: number = 3; break; case Qt::Key_4: number = 4; break; case Qt::Key_5: number = 5; break; case Qt::Key_6: number = 6; break; case Qt::Key_7: number = 7; break; case Qt::Key_8: number = 8; break; case Qt::Key_9: number = 9; break; default: break; } if (number != -1) { if (event->modifiers() & Qt::AltModifier && m_useTabNumberShortcuts) { if (number == 9) { number = m_tabWidget->count(); } m_tabWidget->setCurrentIndex(number - 1); return; } if (event->modifiers() & Qt::ControlModifier && m_useSpeedDialNumberShortcuts) { const QUrl url = mApp->plugins()->speedDial()->urlForShortcut(number - 1); if (url.isValid()) { loadAddress(url); return; } } if (event->modifiers() == Qt::NoModifier && m_useSingleKeyShortcuts) { if (number == 1) m_tabWidget->previousTab(); if (number == 2) m_tabWidget->nextTab(); } } QMainWindow::keyPressEvent(event); } void BrowserWindow::keyReleaseEvent(QKeyEvent* event) { if (mApp->plugins()->processKeyRelease(Qz::ON_BrowserWindow, this, event)) { return; } switch (event->key()) { case Qt::Key_F: if (event->modifiers() == Qt::ControlModifier) { action(QSL("Edit/Find"))->trigger(); event->accept(); } break; default: break; } QMainWindow::keyReleaseEvent(event); } void BrowserWindow::closeEvent(QCloseEvent* event) { if (mApp->isClosing()) { return; } Settings settings; bool askOnClose = settings.value("Browser-Tabs-Settings/AskOnClosing", true).toBool(); if ((mApp->afterLaunch() == MainApplication::SelectSession || mApp->afterLaunch() == MainApplication::RestoreSession) && mApp->windowCount() == 1) { askOnClose = false; } if (askOnClose && m_tabWidget->normalTabsCount() > 1) { CheckBoxDialog dialog(QMessageBox::Yes | QMessageBox::No, this); dialog.setText(tr("There are still %n open tabs and your session won't be stored. \nAre you sure you want to close this window?", "", m_tabWidget->count())); dialog.setCheckBoxText(tr("Don't ask again")); dialog.setWindowTitle(tr("There are still open tabs")); dialog.setIcon(QMessageBox::Warning); if (dialog.exec() != QMessageBox::Yes) { event->ignore(); return; } if (dialog.isChecked()) { settings.setValue("Browser-Tabs-Settings/AskOnClosing", false); } } saveSettings(); #ifndef Q_OS_MACOS if (mApp->windowCount() == 1) mApp->quitApplication(); #endif event->accept(); } void BrowserWindow::closeWindow() { #ifdef Q_OS_MACOS close(); return; #endif if (mApp->windowCount() > 1) { close(); } } void BrowserWindow::saveSettings() { if (m_sideBar) { saveSideBarWidth(); } if (!mApp->isPrivate()) { Settings settings; settings.beginGroup("Browser-View-Settings"); settings.setValue("WindowMaximised", windowState().testFlag(Qt::WindowMaximized)); settings.setValue("LocationBarWidth", m_navigationToolbar->splitter()->sizes().at(0)); settings.setValue("WebSearchBarWidth", m_navigationToolbar->splitter()->sizes().at(1)); settings.setValue("SideBarWidth", m_sideBarWidth); settings.setValue("WebViewWidth", m_webViewWidth); if (!isFullScreen()) settings.setValue("WindowGeometry", saveGeometry()); settings.endGroup(); } } void BrowserWindow::closeTab() { // Don't close pinned tabs with keyboard shortcuts (Ctrl+W, Ctrl+F4) if (weView() && !weView()->webTab()->isPinned()) { m_tabWidget->requestCloseTab(); } } QByteArray BrowserWindow::saveState(int version) const { #ifdef QZ_WS_X11 QByteArray data; QDataStream stream(&data, QIODevice::WriteOnly); stream << QMainWindow::saveState(version); stream << getCurrentVirtualDesktop(); return data; #else return QMainWindow::saveState(version); #endif } bool BrowserWindow::restoreState(const QByteArray &state, int version) { #ifdef QZ_WS_X11 QByteArray windowState; int desktopId = -1; QDataStream stream(state); stream >> windowState; stream >> desktopId; moveToVirtualDesktop(desktopId); return QMainWindow::restoreState(windowState, version); #else return QMainWindow::restoreState(state, version); #endif } #ifdef QZ_WS_X11 int BrowserWindow::getCurrentVirtualDesktop() const { if (QGuiApplication::platformName() != QL1S("xcb")) return 0; xcb_intern_atom_cookie_t intern_atom; xcb_intern_atom_reply_t *atom_reply = 0; xcb_atom_t atom; xcb_get_property_cookie_t cookie; xcb_get_property_reply_t *reply = 0; uint32_t value; intern_atom = xcb_intern_atom(QX11Info::connection(), false, qstrlen("_NET_WM_DESKTOP"), "_NET_WM_DESKTOP"); atom_reply = xcb_intern_atom_reply(QX11Info::connection(), intern_atom, 0); if (!atom_reply) goto error; atom = atom_reply->atom; cookie = xcb_get_property(QX11Info::connection(), false, winId(), atom, XCB_ATOM_CARDINAL, 0, 1); reply = xcb_get_property_reply(QX11Info::connection(), cookie, 0); if (!reply || reply->type != XCB_ATOM_CARDINAL || reply->value_len != 1 || reply->format != sizeof(uint32_t) * 8) goto error; value = *reinterpret_cast(xcb_get_property_value(reply)); free(reply); free(atom_reply); return value; error: free(reply); free(atom_reply); return 0; } void BrowserWindow::moveToVirtualDesktop(int desktopId) { if (QGuiApplication::platformName() != QL1S("xcb")) return; // Don't move when window is already visible or it is first app window if (desktopId < 0 || isVisible() || m_windowType == Qz::BW_FirstAppWindow) return; xcb_intern_atom_cookie_t intern_atom; xcb_intern_atom_reply_t *atom_reply = 0; xcb_atom_t atom; intern_atom = xcb_intern_atom(QX11Info::connection(), false, qstrlen("_NET_WM_DESKTOP"), "_NET_WM_DESKTOP"); atom_reply = xcb_intern_atom_reply(QX11Info::connection(), intern_atom, 0); if (!atom_reply) goto error; atom = atom_reply->atom; xcb_change_property(QX11Info::connection(), XCB_PROP_MODE_REPLACE, winId(), atom, XCB_ATOM_CARDINAL, 32, 1, (const void*) &desktopId); error: free(atom_reply); } #endif diff --git a/src/lib/app/browserwindow.h b/src/lib/app/browserwindow.h index e84c65a2..66271b08 100644 --- a/src/lib/app/browserwindow.h +++ b/src/lib/app/browserwindow.h @@ -1,229 +1,229 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ -#ifndef QUPZILLA_H -#define QUPZILLA_H +#ifndef BROWSERWINDOW_H +#define BROWSERWINDOW_H #include #include #include #include "restoremanager.h" #include "qzcommon.h" class QLabel; class QVBoxLayout; class QSplitter; class QWebEngineFrame; class QTimer; class Menu; class MainMenu; class TabWidget; class TabbedWebView; class LineEdit; class HistoryMenu; class BookmarksMenu; class BookmarksToolbar; class AutoFill; class MainApplication; class WebTab; class WebView; class AdBlockIcon; class SideBar; class SideBarManager; class ProgressBar; class StatusBarMessage; class NavigationBar; class NavigationContainer; class ClickableLabel; class LocationBar; -class QUPZILLA_EXPORT BrowserWindow : public QMainWindow +class FALKON_EXPORT BrowserWindow : public QMainWindow { Q_OBJECT public: explicit BrowserWindow(Qz::BrowserWindowType type, const QUrl &url = QUrl()); ~BrowserWindow(); void setStartTab(WebTab* tab); void setStartPage(WebPage* page); void restoreWindowState(const RestoreManager::WindowData &d); void saveSideBarWidth(); bool fullScreenNavigationVisible() const; void showNavigationWithFullScreen(); void hideNavigationWithFullScreen(); void currentTabChanged(); void updateLoadingActions(); void addBookmark(const QUrl &url, const QString &title); void addDeleteOnCloseWidget(QWidget* widget); void createToolbarsMenu(QMenu* menu); void createSidebarsMenu(QMenu* menu); void createEncodingMenu(QMenu* menu); void removeActions(const QList &actions); SideBar* addSideBar(); QByteArray saveState(int version = 0) const; bool restoreState(const QByteArray &state, int version = 0); TabbedWebView* weView() const; TabbedWebView* weView(int index) const; Qz::BrowserWindowType windowType() const; LocationBar* locationBar() const; TabWidget* tabWidget() const; BookmarksToolbar* bookmarksToolbar() const; StatusBarMessage* statusBarMessage() const; NavigationBar* navigationBar() const; SideBarManager* sideBarManager() const; QLabel* ipLabel() const; AdBlockIcon* adBlockIcon() const; QMenu* superMenu() const; QUrl homepageUrl() const; QAction* action(const QString &name) const; signals: void startingCompleted(); public slots: void goHome(); void goHomeInNewTab(); void goBack(); void goForward(); void reload(); void reloadBypassCache(); void setWindowTitle(const QString &t); void showWebInspector(); void toggleWebInspector(); void showHistoryManager(); void toggleShowMenubar(); void toggleShowStatusBar(); void toggleShowBookmarksToolbar(); void toggleShowNavigationToolbar(); void toggleTabsOnTop(bool enable); void toggleFullScreen(); void toggleHtmlFullScreen(bool enable); void loadActionUrl(QObject* obj = 0); void loadActionUrlInNewTab(QObject* obj = 0); void bookmarkPage(); void bookmarkAllTabs(); void loadAddress(const QUrl &url); void showSource(WebView *view = Q_NULLPTR); void showNormal(); private slots: void addTab(); void openLocation(); void openFile(); void closeWindow(); void closeTab(); void loadSettings(); void postLaunch(); void refreshHistory(); void webSearch(); void searchOnPage(); void changeEncoding(); void printPage(); void saveSettings(); void hideNavigationSlot(); private: bool event(QEvent* event); void resizeEvent(QResizeEvent* event); void keyPressEvent(QKeyEvent* event); void keyReleaseEvent(QKeyEvent* event); void closeEvent(QCloseEvent* event); void setupUi(); void setupMenu(); QAction *createEncodingAction(const QString &codecName, const QString &activeCodecName, QMenu *menu); void createEncodingSubMenu(const QString &name, QStringList &codecNames, QMenu *menu); QUrl m_startUrl; QUrl m_homepage; Qz::BrowserWindowType m_windowType; WebTab* m_startTab; WebPage* m_startPage; QVBoxLayout* m_mainLayout; QSplitter* m_mainSplitter; AdBlockIcon* m_adblockIcon; TabWidget* m_tabWidget; QPointer m_sideBar; SideBarManager* m_sideBarManager; StatusBarMessage* m_statusBarMessage; NavigationContainer* m_navigationContainer; NavigationBar* m_navigationToolbar; BookmarksToolbar* m_bookmarksToolbar; ProgressBar* m_progressBar; QLabel* m_ipLabel; QMenu* m_superMenu; MainMenu* m_mainMenu; int m_sideBarWidth; int m_webViewWidth; // Shortcuts bool m_useTabNumberShortcuts; bool m_useSpeedDialNumberShortcuts; bool m_useSingleKeyShortcuts; // Remember visibility of menubar and statusbar after entering Fullscreen bool m_menuBarVisible; bool m_statusBarVisible; bool m_isHtmlFullScreen; Qt::WindowStates m_oldWindowState = Qt::WindowNoState; Qt::WindowStates m_normalWindowState = Qt::WindowNoState; QTimer* m_hideNavigationTimer; QList > m_deleteOnCloseWidgets; #ifdef QZ_WS_X11 private: int getCurrentVirtualDesktop() const; void moveToVirtualDesktop(int desktopId); #endif }; -#endif // QUPZILLA_H +#endif // BROWSERWINDOW_H diff --git a/src/lib/app/commandlineoptions.cpp b/src/lib/app/commandlineoptions.cpp index 6dd4fd59..681cb42c 100644 --- a/src/lib/app/commandlineoptions.cpp +++ b/src/lib/app/commandlineoptions.cpp @@ -1,205 +1,205 @@ /* ============================================================ -* QupZilla - QtWebEngine based browser +* Falkon - Qt web browser * Copyright (C) 2010-2016 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "commandlineoptions.h" #include #include #include #include CommandLineOptions::CommandLineOptions() { parseActions(); } CommandLineOptions::ActionPairList CommandLineOptions::getActions() { return m_actions; } void CommandLineOptions::parseActions() { // Options QCommandLineOption authorsOption(QStringList({QSL("a"), QSL("authors")})); authorsOption.setDescription(QSL("Displays author information.")); QCommandLineOption profileOption(QStringList({QSL("p"), QSL("profile")})); profileOption.setValueName(QSL("profileName")); profileOption.setDescription(QSL("Starts with specified profile.")); QCommandLineOption noExtensionsOption(QStringList({QSL("e"), QSL("no-extensions")})); noExtensionsOption.setDescription(QSL("Starts without extensions.")); QCommandLineOption privateBrowsingOption(QStringList({QSL("i"), QSL("private-browsing")})); privateBrowsingOption.setDescription(QSL("Starts private browsing.")); QCommandLineOption portableOption(QStringList({QSL("o"), QSL("portable")})); portableOption.setDescription(QSL("Starts in portable mode.")); QCommandLineOption noRemoteOption(QStringList({QSL("r"), QSL("no-remote")})); noRemoteOption.setDescription(QSL("Starts new browser instance.")); QCommandLineOption newTabOption(QStringList({QSL("t"), QSL("new-tab")})); newTabOption.setDescription(QSL("Opens new tab.")); QCommandLineOption newWindowOption(QStringList({QSL("w"), QSL("new-window")})); newWindowOption.setDescription(QSL("Opens new window.")); QCommandLineOption downloadManagerOption(QStringList({QSL("d"), QSL("download-manager")})); downloadManagerOption.setDescription(QSL("Opens download manager.")); QCommandLineOption currentTabOption(QStringList({QSL("c"), QSL("current-tab")})); currentTabOption.setValueName(QSL("URL")); currentTabOption.setDescription(QSL("Opens URL in current tab.")); QCommandLineOption openWindowOption(QStringList({QSL("u"), QSL("open-window")})); openWindowOption.setValueName(QSL("URL")); openWindowOption.setDescription(QSL("Opens URL in new window.")); QCommandLineOption fullscreenOption(QStringList({QSL("f"), QSL("fullscreen")})); fullscreenOption.setDescription(QSL("Toggles fullscreen.")); // Parser QCommandLineParser parser; parser.setApplicationDescription(QSL("QtWebEngine based browser")); QCommandLineOption helpOption = parser.addHelpOption(); QCommandLineOption versionOption = parser.addVersionOption(); parser.addOption(authorsOption); parser.addOption(profileOption); parser.addOption(noExtensionsOption); parser.addOption(privateBrowsingOption); parser.addOption(portableOption); parser.addOption(noRemoteOption); parser.addOption(newTabOption); parser.addOption(newWindowOption); parser.addOption(downloadManagerOption); parser.addOption(currentTabOption); parser.addOption(openWindowOption); parser.addOption(fullscreenOption); parser.addPositionalArgument(QSL("URL"), QSL("URLs to open"), QSL("[URL...]")); // parse() and not process() so we can pass arbitrary options to Chromium parser.parse(QCoreApplication::arguments()); if (parser.isSet(helpOption)) { parser.showHelp(); } if (parser.isSet(versionOption)) { parser.showVersion(); } if (parser.isSet(authorsOption)) { std::cout << "David Rosca " << std::endl; ActionPair pair; pair.action = Qz::CL_ExitAction; m_actions.append(pair); return; } if (parser.isSet(profileOption)) { const QString profileName = parser.value(profileOption); - std::cout << "QupZilla: Starting with profile '" << profileName.toUtf8().data() << "'" << std::endl; + std::cout << "Falkon: Starting with profile '" << profileName.toUtf8().data() << "'" << std::endl; ActionPair pair; pair.action = Qz::CL_StartWithProfile; pair.text = profileName; m_actions.append(pair); } if (parser.isSet(noExtensionsOption)) { ActionPair pair; pair.action = Qz::CL_StartWithoutAddons; m_actions.append(pair); } if (parser.isSet(privateBrowsingOption)) { ActionPair pair; pair.action = Qz::CL_StartPrivateBrowsing; m_actions.append(pair); } if (parser.isSet(portableOption)) { ActionPair pair; pair.action = Qz::CL_StartPortable; m_actions.append(pair); } if (parser.isSet(noRemoteOption)) { ActionPair pair; pair.action = Qz::CL_StartNewInstance; m_actions.append(pair); } if (parser.isSet(newTabOption)) { ActionPair pair; pair.action = Qz::CL_NewTab; m_actions.append(pair); } if (parser.isSet(newWindowOption)) { ActionPair pair; pair.action = Qz::CL_NewWindow; m_actions.append(pair); } if (parser.isSet(downloadManagerOption)) { ActionPair pair; pair.action = Qz::CL_ShowDownloadManager; m_actions.append(pair); } if (parser.isSet(currentTabOption)) { ActionPair pair; pair.action = Qz::CL_OpenUrlInCurrentTab; pair.text = parser.value(currentTabOption); m_actions.append(pair); } if (parser.isSet(openWindowOption)) { ActionPair pair; pair.action = Qz::CL_OpenUrlInNewWindow; pair.text = parser.value(openWindowOption); m_actions.append(pair); } if (parser.isSet(fullscreenOption)) { ActionPair pair; pair.action = Qz::CL_ToggleFullScreen; m_actions.append(pair); } if (parser.positionalArguments().isEmpty()) return; QString url = parser.positionalArguments().last(); QFileInfo fileInfo(url); if (fileInfo.exists()) { url = fileInfo.absoluteFilePath(); } if (!url.isEmpty() && !url.startsWith(QLatin1Char('-'))) { ActionPair pair; pair.action = Qz::CL_OpenUrl; pair.text = url; m_actions.append(pair); } } diff --git a/src/lib/app/commandlineoptions.h b/src/lib/app/commandlineoptions.h index e8b75fd3..d1c25563 100644 --- a/src/lib/app/commandlineoptions.h +++ b/src/lib/app/commandlineoptions.h @@ -1,47 +1,47 @@ /* ============================================================ -* QupZilla - QtWebEngine based browser +* Falkon - Qt web browser * Copyright (C) 2010-2015 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef COMMANDLINEOPTIONS_H #define COMMANDLINEOPTIONS_H #include #include "qzcommon.h" -class QUPZILLA_EXPORT CommandLineOptions +class FALKON_EXPORT CommandLineOptions { public: struct ActionPair { Qz::CommandLineAction action; QString text; }; typedef QVector ActionPairList; explicit CommandLineOptions(); ActionPairList getActions(); private: void parseActions(); ActionPairList m_actions; }; // Hint to QVector to use std::realloc on item moving Q_DECLARE_TYPEINFO(CommandLineOptions::ActionPair, Q_MOVABLE_TYPE); #endif // COMMANDLINEOPTIONS_H diff --git a/src/lib/app/datapaths.cpp b/src/lib/app/datapaths.cpp index cfee9d6a..ab6c5458 100644 --- a/src/lib/app/datapaths.cpp +++ b/src/lib/app/datapaths.cpp @@ -1,157 +1,157 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2014-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "datapaths.h" #include "qztools.h" #include #include #include Q_GLOBAL_STATIC(DataPaths, qz_data_paths) DataPaths::DataPaths() { init(); } // static void DataPaths::setCurrentProfilePath(const QString &profilePath) { qz_data_paths()->initCurrentProfile(profilePath); } // static void DataPaths::setPortableVersion() { DataPaths* d = qz_data_paths(); d->m_paths[Config] = d->m_paths[AppData]; d->m_paths[Profiles] = d->m_paths[Config]; d->m_paths[Profiles].first().append(QLatin1String("/profiles")); d->m_paths[Temp] = d->m_paths[Config]; d->m_paths[Temp].first().append(QLatin1String("/tmp")); // Make sure the Config and Temp paths exists QDir dir; dir.mkpath(d->m_paths[Config].at(0)); dir.mkpath(d->m_paths[Temp].at(0)); } // static QString DataPaths::path(DataPaths::Path path) { Q_ASSERT(!qz_data_paths()->m_paths[path].isEmpty()); return qz_data_paths()->m_paths[path].at(0); } // static QStringList DataPaths::allPaths(DataPaths::Path type) { Q_ASSERT(!qz_data_paths()->m_paths[type].isEmpty()); return qz_data_paths()->m_paths[type]; } // static QString DataPaths::currentProfilePath() { return path(CurrentProfile); } // static void DataPaths::clearTempData() { QzTools::removeDir(path(Temp)); } void DataPaths::init() { // AppData #if defined(Q_OS_MACOS) m_paths[AppData].append(QApplication::applicationDirPath() + QLatin1String("/../Resources")); #elif defined(Q_OS_UNIX) && !defined(NO_SYSTEM_DATAPATH) m_paths[AppData].append(USE_DATADIR); #else m_paths[AppData].append(QApplication::applicationDirPath()); #endif m_paths[Translations].append(m_paths[AppData].at(0) + QLatin1String("/locale")); m_paths[Themes].append(m_paths[AppData].at(0) + QLatin1String("/themes")); m_paths[Plugins].append(m_paths[AppData].at(0) + QLatin1String("/plugins")); // Config #if defined(Q_OS_WIN) || defined(Q_OS_OS2) - // Use %LOCALAPPDATA%/qupzilla as Config path on Windows + // Use %LOCALAPPDATA%/falkon as Config path on Windows m_paths[Config].append(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation)); #elif defined(Q_OS_MACOS) - m_paths[Config].append(QDir::homePath() + QLatin1String("/Library/Application Support/QupZilla")); + m_paths[Config].append(QDir::homePath() + QLatin1String("/Library/Application Support/Falkon")); #else // Unix - m_paths[Config].append(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + QL1S("/qupzilla")); + m_paths[Config].append(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + QL1S("/falkon")); #endif // Profiles m_paths[Profiles].append(m_paths[Config].at(0) + QLatin1String("/profiles")); // Temp #ifdef Q_OS_UNIX const QByteArray &user = qgetenv("USER"); - const QString &tempPath = QString(QSL("%1/qupzilla-%2")).arg(QDir::tempPath(), user.constData()); + const QString &tempPath = QString(QSL("%1/falkon-%2")).arg(QDir::tempPath(), user.constData()); m_paths[Temp].append(tempPath); #else m_paths[Temp].append(m_paths[Config].at(0) + QLatin1String("/tmp")); #endif // Cache #ifdef Q_OS_UNIX const QString &cachePath = QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation); if (!cachePath.isEmpty()) - m_paths[Cache].append(cachePath + QLatin1String("/qupzilla")); + m_paths[Cache].append(cachePath + QLatin1String("/falkon")); #endif // Make sure the Config and Temp paths exists QDir dir; dir.mkpath(m_paths[Config].at(0)); dir.mkpath(m_paths[Temp].at(0)); // We also allow to load data from Config path m_paths[Translations].append(m_paths[Config].at(0) + QLatin1String("/locale")); m_paths[Themes].append(m_paths[Config].at(0) + QLatin1String("/themes")); m_paths[Plugins].append(m_paths[Config].at(0) + QLatin1String("/plugins")); #ifdef USE_LIBPATH - m_paths[Plugins].append(QLatin1String(USE_LIBPATH "/qupzilla")); + m_paths[Plugins].append(QLatin1String(USE_LIBPATH "/falkon")); #endif } void DataPaths::initCurrentProfile(const QString &profilePath) { m_paths[CurrentProfile].append(profilePath); if (m_paths[Cache].isEmpty()) m_paths[Cache].append(m_paths[CurrentProfile].at(0) + QLatin1String("/cache")); if (m_paths[Sessions].isEmpty()) m_paths[Sessions].append(m_paths[CurrentProfile].at(0) + QLatin1String("/sessions")); QDir dir; dir.mkpath(m_paths[Cache].at(0)); dir.mkpath(m_paths[Sessions].at(0)); } diff --git a/src/lib/app/datapaths.h b/src/lib/app/datapaths.h index 7d052810..50b905ff 100644 --- a/src/lib/app/datapaths.h +++ b/src/lib/app/datapaths.h @@ -1,66 +1,66 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef DATAPATHS_H #define DATAPATHS_H #include #include "qzcommon.h" -class QUPZILLA_EXPORT DataPaths +class FALKON_EXPORT DataPaths { public: enum Path { - AppData = 0, // /usr/share/qupzilla or . or ../Resources + AppData = 0, // /usr/share/falkon or . or ../Resources Translations = 1, // $AppData/locale Themes = 2, // $AppData/themes Plugins = 3, // $AppData/plugins - Config = 4, // $XDG_CONFIG_HOME/qupzilla or %LOCALAPPDATA%/qupzilla or $AppData/data (portable) + Config = 4, // $XDG_CONFIG_HOME/falkon or %LOCALAPPDATA%/falkon or $AppData/data (portable) Profiles = 5, // $Config/profiles CurrentProfile = 6, // $Profiles/current_profile Temp = 7, // $Config/tmp - Cache = 8, // $XDG_CACHE_HOME/qupzilla or $CurrentProfile/cache + Cache = 8, // $XDG_CACHE_HOME/falkon or $CurrentProfile/cache Sessions = 9, // $CurrentProfile/sessions LastPath = 10 }; explicit DataPaths(); // Set absolute path of current profile static void setCurrentProfilePath(const QString &profilePath); // Set Config path to $AppData/data static void setPortableVersion(); // Returns main path (Themes -> /usr/share/themes) static QString path(Path type); - // Returns all paths (Themes -> /usr/share/themes, ~/.config/qupzilla/themes) + // Returns all paths (Themes -> /usr/share/themes, ~/.config/falkon/themes) static QStringList allPaths(Path type); // Convenience function for getting CurrentProfile static QString currentProfilePath(); // Remove Temp dir static void clearTempData(); private: void init(); void initCurrentProfile(const QString &profilePath); QStringList m_paths[LastPath]; }; #endif // DATAPATHS_H diff --git a/src/lib/app/mainapplication.cpp b/src/lib/app/mainapplication.cpp index 478cee19..25ac4145 100644 --- a/src/lib/app/mainapplication.cpp +++ b/src/lib/app/mainapplication.cpp @@ -1,1238 +1,1238 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "mainapplication.h" #include "history.h" #include "qztools.h" #include "updater.h" #include "autofill.h" #include "settings.h" #include "qzregexp.h" #include "autosaver.h" #include "datapaths.h" #include "tabwidget.h" #include "cookiejar.h" #include "bookmarks.h" #include "qzsettings.h" #include "proxystyle.h" #include "pluginproxy.h" #include "iconprovider.h" #include "browserwindow.h" #include "checkboxdialog.h" #include "networkmanager.h" #include "profilemanager.h" #include "adblockmanager.h" #include "restoremanager.h" #include "browsinglibrary.h" #include "downloadmanager.h" #include "clearprivatedata.h" #include "useragentmanager.h" #include "commandlineoptions.h" #include "searchenginesmanager.h" #include "desktopnotificationsfactory.h" #include "html5permissions/html5permissionsmanager.h" #include "scripts.h" #include "sessionmanager.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef Q_OS_WIN #include #include #include #endif #include #if defined(Q_OS_WIN) && !defined(Q_OS_OS2) #include "registerqappassociation.h" #endif MainApplication::MainApplication(int &argc, char** argv) : QtSingleApplication(argc, argv) , m_isPrivate(false) , m_isPortable(false) , m_isClosing(false) , m_isRestoring(false) , m_isStartingAfterCrash(false) , m_history(0) , m_bookmarks(0) , m_autoFill(0) , m_cookieJar(0) , m_plugins(0) , m_browsingLibrary(0) , m_networkManager(0) , m_restoreManager(0) , m_sessionManager(0) , m_downloadManager(0) , m_userAgentManager(0) , m_searchEnginesManager(0) , m_html5PermissionsManager(0) , m_desktopNotifications(0) , m_webProfile(0) , m_autoSaver(0) #if defined(Q_OS_WIN) && !defined(Q_OS_OS2) , m_registerQAppAssociation(0) #endif { setAttribute(Qt::AA_UseHighDpiPixmaps); setAttribute(Qt::AA_DontCreateNativeWidgetSiblings); - setApplicationName(QLatin1String("QupZilla")); - setOrganizationDomain(QLatin1String("qupzilla")); + setApplicationName(QLatin1String("Falkon")); + setOrganizationDomain(QLatin1String("org.kde")); setWindowIcon(QIcon::fromTheme(QSL("qupzilla"), QIcon(QSL(":icons/exeicons/qupzilla-window.png")))); - setDesktopFileName(QSL("org.qupzilla.QupZilla")); + setDesktopFileName(QSL("org.kde.Falkon")); #ifdef GIT_REVISION setApplicationVersion(QSL("%1 (%2)").arg(Qz::VERSION, GIT_REVISION)); #else setApplicationVersion(Qz::VERSION); #endif // Set fallback icon theme (eg. on Windows/Mac) if (QIcon::fromTheme(QSL("view-refresh")).isNull()) { QIcon::setThemeSearchPaths(QStringList() << QL1S(":/breeze-fallback")); QIcon::setThemeName(QSL("breeze-fallback")); } // QSQLITE database plugin is required if (!QSqlDatabase::isDriverAvailable(QSL("QSQLITE"))) { QMessageBox::critical(0, QSL("Error"), QSL("Qt SQLite database plugin is not available. Please install it and restart the application.")); m_isClosing = true; return; } #ifdef Q_OS_WIN // Set default app font (needed for N'ko) int fontId = QFontDatabase::addApplicationFont(QSL("font.ttf")); if (fontId != -1) { const QStringList families = QFontDatabase::applicationFontFamilies(fontId); if (!families.empty()) setFont(QFont(families.at(0))); } #endif QUrl startUrl; QString startProfile; QStringList messages; bool noAddons = false; bool newInstance = false; if (argc > 1) { CommandLineOptions cmd; foreach (const CommandLineOptions::ActionPair &pair, cmd.getActions()) { switch (pair.action) { case Qz::CL_StartWithoutAddons: noAddons = true; break; case Qz::CL_StartWithProfile: startProfile = pair.text; break; case Qz::CL_StartPortable: m_isPortable = true; break; case Qz::CL_NewTab: messages.append(QLatin1String("ACTION:NewTab")); m_postLaunchActions.append(OpenNewTab); break; case Qz::CL_NewWindow: messages.append(QLatin1String("ACTION:NewWindow")); break; case Qz::CL_ToggleFullScreen: messages.append(QLatin1String("ACTION:ToggleFullScreen")); m_postLaunchActions.append(ToggleFullScreen); break; case Qz::CL_ShowDownloadManager: messages.append(QLatin1String("ACTION:ShowDownloadManager")); m_postLaunchActions.append(OpenDownloadManager); break; case Qz::CL_StartPrivateBrowsing: m_isPrivate = true; break; case Qz::CL_StartNewInstance: newInstance = true; break; case Qz::CL_OpenUrlInCurrentTab: startUrl = QUrl::fromUserInput(pair.text); messages.append("ACTION:OpenUrlInCurrentTab" + pair.text); break; case Qz::CL_OpenUrlInNewWindow: startUrl = QUrl::fromUserInput(pair.text); messages.append("ACTION:OpenUrlInNewWindow" + pair.text); break; case Qz::CL_OpenUrl: startUrl = QUrl::fromUserInput(pair.text); messages.append("URL:" + pair.text); break; case Qz::CL_ExitAction: m_isClosing = true; return; default: break; } } } if (isPortable()) { - std::cout << "QupZilla: Running in Portable Mode." << std::endl; + std::cout << "Falkon: Running in Portable Mode." << std::endl; DataPaths::setPortableVersion(); } // Don't start single application in private browsing if (!isPrivate()) { - QString appId = QLatin1String("QupZillaWebBrowser"); + QString appId = QLatin1String("FalkonWebBrowser"); if (isPortable()) { appId.append(QLatin1String("Portable")); } if (newInstance) { if (startProfile.isEmpty() || startProfile == QLatin1String("default")) { std::cout << "New instance cannot be started with default profile!" << std::endl; } else { // Generate unique appId so it is possible to start more separate instances // of the same profile. It is dangerous to run more instances of the same profile, // but if the user wants it, we should allow it. appId.append(startProfile + QString::number(QDateTime::currentMSecsSinceEpoch())); } } setAppId(appId); } // If there is nothing to tell other instance, we need to at least wake it if (messages.isEmpty()) { messages.append(QLatin1String(" ")); } if (isRunning()) { m_isClosing = true; foreach (const QString &message, messages) { sendMessage(message); } return; } #ifdef Q_OS_MACOS setQuitOnLastWindowClosed(false); // disable tabbing issue#2261 extern void disableWindowTabbing(); disableWindowTabbing(); #else setQuitOnLastWindowClosed(true); #endif QSettings::setDefaultFormat(QSettings::IniFormat); QDesktopServices::setUrlHandler(QSL("http"), this, "addNewTab"); QDesktopServices::setUrlHandler(QSL("https"), this, "addNewTab"); QDesktopServices::setUrlHandler(QSL("ftp"), this, "addNewTab"); ProfileManager profileManager; profileManager.initConfigDir(); profileManager.initCurrentProfile(startProfile); Settings::createSettings(DataPaths::currentProfilePath() + QLatin1String("/settings.ini")); m_webProfile = isPrivate() ? new QWebEngineProfile(this) : QWebEngineProfile::defaultProfile(); connect(m_webProfile, &QWebEngineProfile::downloadRequested, this, &MainApplication::downloadRequested); m_networkManager = new NetworkManager(this); // Setup QWebChannel userscript QWebEngineScript script; - script.setName(QSL("_qupzilla_webchannel")); + script.setName(QSL("_falkon_webchannel")); script.setInjectionPoint(QWebEngineScript::DocumentCreation); script.setWorldId(QWebEngineScript::MainWorld); script.setRunsOnSubFrames(true); script.setSourceCode(Scripts::setupWebChannel()); m_webProfile->scripts()->insert(script); if (!isPrivate()) { m_sessionManager = new SessionManager(this); m_autoSaver = new AutoSaver(this); connect(m_autoSaver, SIGNAL(save()), m_sessionManager, SLOT(autoSaveLastSession())); Settings settings; m_isStartingAfterCrash = settings.value("SessionRestore/isRunning", false).toBool(); settings.setValue("SessionRestore/isRunning", true); // we have to ask about startup session before creating main window if (!m_isStartingAfterCrash && afterLaunch() == SelectSession) m_restoreManager = new RestoreManager(sessionManager()->askSessionFromUser()); } translateApp(); loadSettings(); m_plugins = new PluginProxy; m_autoFill = new AutoFill(this); if (!noAddons) m_plugins->loadPlugins(); BrowserWindow* window = createWindow(Qz::BW_FirstAppWindow, startUrl); connect(window, SIGNAL(startingCompleted()), this, SLOT(restoreOverrideCursor())); connect(this, SIGNAL(focusChanged(QWidget*,QWidget*)), this, SLOT(onFocusChanged())); if (!isPrivate()) { #ifndef DISABLE_CHECK_UPDATES Settings settings; bool checkUpdates = settings.value("Web-Browser-Settings/CheckUpdates", true).toBool(); if (checkUpdates) { new Updater(window); } #endif sessionManager()->backupSavedSessions(); if (m_isStartingAfterCrash || afterLaunch() == RestoreSession) { m_restoreManager = new RestoreManager(sessionManager()->lastActiveSessionPath()); if (!m_restoreManager->isValid()) { destroyRestoreManager(); } else { // Pinned tabs are saved into session.dat, so remove the old saved pinned tabs QFile::remove(DataPaths::currentProfilePath() + QL1S("/pinnedtabs.dat")); } } } QTimer::singleShot(0, this, SLOT(postLaunch())); } MainApplication::~MainApplication() { IconProvider::instance()->saveIconsToDatabase(); // Wait for all QtConcurrent jobs to finish QThreadPool::globalInstance()->waitForDone(); // Delete all classes that are saving data in destructor delete m_bookmarks; delete m_cookieJar; delete m_plugins; Settings::syncSettings(); } bool MainApplication::isClosing() const { return m_isClosing; } bool MainApplication::isRestoring() const { return m_isRestoring; } bool MainApplication::isPrivate() const { return m_isPrivate; } bool MainApplication::isPortable() const { #ifdef PORTABLE_BUILD return true; #else return m_isPortable; #endif } bool MainApplication::isStartingAfterCrash() const { return m_isStartingAfterCrash; } int MainApplication::windowCount() const { return m_windows.count(); } QList MainApplication::windows() const { return m_windows; } BrowserWindow* MainApplication::getWindow() const { if (m_lastActiveWindow) { return m_lastActiveWindow.data(); } return m_windows.isEmpty() ? 0 : m_windows.at(0); } BrowserWindow* MainApplication::createWindow(Qz::BrowserWindowType type, const QUrl &startUrl) { if (windowCount() == 0 && type != Qz::BW_MacFirstWindow) { type = Qz::BW_FirstAppWindow; } BrowserWindow* window = new BrowserWindow(type, startUrl); connect(window, SIGNAL(destroyed(QObject*)), this, SLOT(windowDestroyed(QObject*))); m_windows.prepend(window); return window; } MainApplication::AfterLaunch MainApplication::afterLaunch() const { return static_cast(Settings().value(QSL("Web-URL-Settings/afterLaunch"), RestoreSession).toInt()); } void MainApplication::openSession(BrowserWindow* window, RestoreData &restoreData) { setOverrideCursor(Qt::BusyCursor); if (!window) window = createWindow(Qz::BW_OtherRestoredWindow); window->setUpdatesEnabled(false); if (m_isRestoring) window->tabWidget()->closeRecoveryTab(); if (window->tabWidget()->normalTabsCount() > 1) { // This can only happen when recovering crashed session! // // Don't restore tabs in current window as user already opened // some new tabs. // Instead create new one and restore pinned tabs there BrowserWindow* newWin = createWindow(Qz::BW_OtherRestoredWindow); newWin->setUpdatesEnabled(false); newWin->restoreWindowState(restoreData.at(0)); newWin->setUpdatesEnabled(true); restoreData.remove(0); } else { // QTabWidget::count() - count of tabs is not updated after closing // recovery tab ... // update: it seems with ComboTabBar QTabWidget::count() is updated, // we add pinnedTabCounts to currentTab! int tabCount = window->tabWidget()->pinnedTabsCount(); RestoreManager::WindowData data = restoreData.at(0); data.currentTab += tabCount; restoreData.remove(0); window->restoreWindowState(data); } window->setUpdatesEnabled(true); processEvents(); foreach (const RestoreManager::WindowData &data, restoreData) { BrowserWindow* window = createWindow(Qz::BW_OtherRestoredWindow); window->setUpdatesEnabled(false); window->restoreWindowState(data); window->setUpdatesEnabled(true); processEvents(); } restoreOverrideCursor(); } bool MainApplication::restoreSession(BrowserWindow* window, RestoreData restoreData) { if (m_isPrivate || restoreData.isEmpty()) { return false; } m_isRestoring = true; openSession(window, restoreData); destroyRestoreManager(); m_isRestoring = false; return true; } void MainApplication::destroyRestoreManager() { delete m_restoreManager; m_restoreManager = 0; } void MainApplication::reloadSettings() { loadSettings(); emit settingsReloaded(); } QString MainApplication::styleName() const { return m_proxyStyle ? m_proxyStyle->name() : QString(); } void MainApplication::setProxyStyle(ProxyStyle *style) { m_proxyStyle = style; setStyle(style); } QString MainApplication::currentLanguageFile() const { return m_languageFile; } QString MainApplication::currentLanguage() const { QString lang = m_languageFile; if (lang.isEmpty()) { return "en_US"; } return lang.left(lang.length() - 3); } History* MainApplication::history() { if (!m_history) { m_history = new History(this); } return m_history; } Bookmarks* MainApplication::bookmarks() { if (!m_bookmarks) { m_bookmarks = new Bookmarks(this); } return m_bookmarks; } AutoFill* MainApplication::autoFill() { return m_autoFill; } CookieJar* MainApplication::cookieJar() { if (!m_cookieJar) { m_cookieJar = new CookieJar(this); } return m_cookieJar; } PluginProxy* MainApplication::plugins() { return m_plugins; } BrowsingLibrary* MainApplication::browsingLibrary() { if (!m_browsingLibrary) { m_browsingLibrary = new BrowsingLibrary(getWindow()); } return m_browsingLibrary; } NetworkManager *MainApplication::networkManager() { return m_networkManager; } RestoreManager* MainApplication::restoreManager() { return m_restoreManager; } SessionManager* MainApplication::sessionManager() { return m_sessionManager; } DownloadManager* MainApplication::downloadManager() { if (!m_downloadManager) { m_downloadManager = new DownloadManager(); } return m_downloadManager; } UserAgentManager* MainApplication::userAgentManager() { if (!m_userAgentManager) { m_userAgentManager = new UserAgentManager(this); } return m_userAgentManager; } SearchEnginesManager* MainApplication::searchEnginesManager() { if (!m_searchEnginesManager) { m_searchEnginesManager = new SearchEnginesManager(this); } return m_searchEnginesManager; } HTML5PermissionsManager* MainApplication::html5PermissionsManager() { if (!m_html5PermissionsManager) { m_html5PermissionsManager = new HTML5PermissionsManager(this); } return m_html5PermissionsManager; } DesktopNotificationsFactory* MainApplication::desktopNotifications() { if (!m_desktopNotifications) { m_desktopNotifications = new DesktopNotificationsFactory(this); } return m_desktopNotifications; } QWebEngineProfile *MainApplication::webProfile() const { return m_webProfile; } // static MainApplication* MainApplication::instance() { return static_cast(QCoreApplication::instance()); } void MainApplication::addNewTab(const QUrl &url) { BrowserWindow* window = getWindow(); if (window) { window->tabWidget()->addView(url, url.isEmpty() ? Qz::NT_SelectedNewEmptyTab : Qz::NT_SelectedTabAtTheEnd); } } void MainApplication::startPrivateBrowsing(const QUrl &startUrl) { QUrl url = startUrl; if (QAction* act = qobject_cast(sender())) { url = act->data().toUrl(); } QStringList args; args.append(QSL("--private-browsing")); args.append(QSL("--profile=") + ProfileManager::currentProfile()); if (!url.isEmpty()) { args << url.toEncoded(); } if (!QProcess::startDetached(applicationFilePath(), args)) { qWarning() << "MainApplication: Cannot start new browser process for private browsing!" << applicationFilePath() << args; } } void MainApplication::reloadUserStyleSheet() { const QString userCssFile = Settings().value("Web-Browser-Settings/userStyleSheet", QString()).toString(); setUserStyleSheet(userCssFile); } void MainApplication::restoreOverrideCursor() { QApplication::restoreOverrideCursor(); } void MainApplication::changeOccurred() { if (m_autoSaver) m_autoSaver->changeOccurred(); } void MainApplication::quitApplication() { if (m_downloadManager && !m_downloadManager->canClose()) { m_downloadManager->show(); return; } if (m_sessionManager && m_windows.count() > 0) { m_sessionManager->autoSaveLastSession(); } m_isClosing = true; // Saving settings in saveSettings() slot called from quit() so // everything gets saved also when quitting application in other // way than clicking Quit action in File menu or closing last window // eg. on Mac (#157) if (!isPrivate()) { removeLockFile(); } quit(); } void MainApplication::postLaunch() { if (m_postLaunchActions.contains(OpenDownloadManager)) { downloadManager()->show(); } if (m_postLaunchActions.contains(OpenNewTab)) { getWindow()->tabWidget()->addView(QUrl(), Qz::NT_SelectedNewEmptyTab); } if (m_postLaunchActions.contains(ToggleFullScreen)) { getWindow()->toggleFullScreen(); } QSettings::setPath(QSettings::IniFormat, QSettings::UserScope, DataPaths::currentProfilePath()); connect(this, SIGNAL(messageReceived(QString)), this, SLOT(messageReceived(QString))); connect(this, SIGNAL(aboutToQuit()), this, SLOT(saveSettings())); createJumpList(); initPulseSupport(); QTimer::singleShot(5000, this, &MainApplication::runDeferredPostLaunchActions); } QByteArray MainApplication::saveState() const { QByteArray data; QDataStream stream(&data, QIODevice::WriteOnly); stream << Qz::sessionVersion; stream << m_windows.count(); foreach (BrowserWindow* w, m_windows) { stream << w->tabWidget()->saveState(); if (w->isFullScreen()) { stream << QByteArray(); } else { stream << w->saveState(); } } return data; } void MainApplication::saveSettings() { if (isPrivate()) { return; } m_isClosing = true; Settings settings; settings.beginGroup("SessionRestore"); settings.setValue("isRunning", false); settings.endGroup(); settings.beginGroup("Web-Browser-Settings"); bool deleteCache = settings.value("deleteCacheOnClose", false).toBool(); bool deleteHistory = settings.value("deleteHistoryOnClose", false).toBool(); bool deleteHtml5Storage = settings.value("deleteHTML5StorageOnClose", false).toBool(); settings.endGroup(); settings.beginGroup("Cookie-Settings"); bool deleteCookies = settings.value("deleteCookiesOnClose", false).toBool(); settings.endGroup(); if (deleteHistory) { m_history->clearHistory(); } if (deleteHtml5Storage) { ClearPrivateData::clearLocalStorage(); } if (deleteCookies) { m_cookieJar->deleteAllCookies(); } if (deleteCache) { QzTools::removeDir(mApp->webProfile()->cachePath()); } m_searchEnginesManager->saveSettings(); m_plugins->shutdown(); m_networkManager->shutdown(); DataPaths::clearTempData(); qzSettings->saveSettings(); AdBlockManager::instance()->save(); QFile::remove(DataPaths::currentProfilePath() + QLatin1String("/WebpageIcons.db")); sessionManager()->saveSettings(); } void MainApplication::messageReceived(const QString &message) { QWidget* actWin = getWindow(); QUrl actUrl; if (message.startsWith(QLatin1String("URL:"))) { const QUrl url = QUrl::fromUserInput(message.mid(4)); addNewTab(url); actWin = getWindow(); } else if (message.startsWith(QLatin1String("ACTION:"))) { const QString text = message.mid(7); if (text == QLatin1String("NewTab")) { addNewTab(); } else if (text == QLatin1String("NewWindow")) { actWin = createWindow(Qz::BW_NewWindow); } else if (text == QLatin1String("ShowDownloadManager")) { downloadManager()->show(); actWin = downloadManager(); } else if (text == QLatin1String("ToggleFullScreen") && actWin) { BrowserWindow* qz = static_cast(actWin); qz->toggleFullScreen(); } else if (text.startsWith(QLatin1String("OpenUrlInCurrentTab"))) { actUrl = QUrl::fromUserInput(text.mid(19)); } else if (text.startsWith(QLatin1String("OpenUrlInNewWindow"))) { createWindow(Qz::BW_NewWindow, QUrl::fromUserInput(text.mid(18))); return; } } else { // User attempted to start another instance, let's open a new window actWin = createWindow(Qz::BW_NewWindow); } if (!actWin) { if (!isClosing()) { // It can only occur if download manager window was still opened createWindow(Qz::BW_NewWindow, actUrl); } return; } actWin->setWindowState(actWin->windowState() & ~Qt::WindowMinimized); actWin->raise(); actWin->activateWindow(); actWin->setFocus(); BrowserWindow* win = qobject_cast(actWin); if (win && !actUrl.isEmpty()) { win->loadAddress(actUrl); } } void MainApplication::windowDestroyed(QObject* window) { // qobject_cast doesn't work because QObject::destroyed is emitted from destructor Q_ASSERT(static_cast(window)); Q_ASSERT(m_windows.contains(static_cast(window))); m_windows.removeOne(static_cast(window)); } void MainApplication::onFocusChanged() { BrowserWindow* activeBrowserWindow = qobject_cast(activeWindow()); if (activeBrowserWindow) { m_lastActiveWindow = activeBrowserWindow; emit activeWindowChanged(m_lastActiveWindow); } } void MainApplication::runDeferredPostLaunchActions() { checkDefaultWebBrowser(); checkOptimizeDatabase(); } void MainApplication::downloadRequested(QWebEngineDownloadItem *download) { downloadManager()->download(download); } void MainApplication::loadSettings() { Settings settings; settings.beginGroup("Themes"); QString activeTheme = settings.value("activeTheme", DEFAULT_THEME_NAME).toString(); settings.endGroup(); loadTheme(activeTheme); QWebEngineSettings* webSettings = QWebEngineSettings::defaultSettings(); // Web browsing settings settings.beginGroup("Web-Browser-Settings"); webSettings->setAttribute(QWebEngineSettings::LocalStorageEnabled, settings.value("HTML5StorageEnabled", true).toBool()); webSettings->setAttribute(QWebEngineSettings::PluginsEnabled, settings.value("allowPlugins", true).toBool()); webSettings->setAttribute(QWebEngineSettings::JavascriptEnabled, settings.value("allowJavaScript", true).toBool()); webSettings->setAttribute(QWebEngineSettings::JavascriptCanOpenWindows, settings.value("allowJavaScriptOpenWindow", false).toBool()); webSettings->setAttribute(QWebEngineSettings::JavascriptCanAccessClipboard, settings.value("allowJavaScriptAccessClipboard", true).toBool()); webSettings->setAttribute(QWebEngineSettings::LinksIncludedInFocusChain, settings.value("IncludeLinkInFocusChain", false).toBool()); webSettings->setAttribute(QWebEngineSettings::XSSAuditingEnabled, settings.value("XSSAuditing", false).toBool()); webSettings->setAttribute(QWebEngineSettings::PrintElementBackgrounds, settings.value("PrintElementBackground", true).toBool()); webSettings->setAttribute(QWebEngineSettings::SpatialNavigationEnabled, settings.value("SpatialNavigation", false).toBool()); webSettings->setAttribute(QWebEngineSettings::ScrollAnimatorEnabled, settings.value("AnimateScrolling", true).toBool()); webSettings->setAttribute(QWebEngineSettings::HyperlinkAuditingEnabled, false); webSettings->setAttribute(QWebEngineSettings::FullScreenSupportEnabled, true); webSettings->setAttribute(QWebEngineSettings::LocalContentCanAccessRemoteUrls, true); webSettings->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, false); webSettings->setDefaultTextEncoding(settings.value("DefaultEncoding", webSettings->defaultTextEncoding()).toString()); setWheelScrollLines(settings.value("wheelScrollLines", wheelScrollLines()).toInt()); const QString userCss = settings.value("userStyleSheet", QString()).toString(); settings.endGroup(); setUserStyleSheet(userCss); settings.beginGroup("Browser-Fonts"); webSettings->setFontFamily(QWebEngineSettings::StandardFont, settings.value("StandardFont", webSettings->fontFamily(QWebEngineSettings::StandardFont)).toString()); webSettings->setFontFamily(QWebEngineSettings::CursiveFont, settings.value("CursiveFont", webSettings->fontFamily(QWebEngineSettings::CursiveFont)).toString()); webSettings->setFontFamily(QWebEngineSettings::FantasyFont, settings.value("FantasyFont", webSettings->fontFamily(QWebEngineSettings::FantasyFont)).toString()); webSettings->setFontFamily(QWebEngineSettings::FixedFont, settings.value("FixedFont", webSettings->fontFamily(QWebEngineSettings::FixedFont)).toString()); webSettings->setFontFamily(QWebEngineSettings::SansSerifFont, settings.value("SansSerifFont", webSettings->fontFamily(QWebEngineSettings::SansSerifFont)).toString()); webSettings->setFontFamily(QWebEngineSettings::SerifFont, settings.value("SerifFont", webSettings->fontFamily(QWebEngineSettings::SerifFont)).toString()); webSettings->setFontSize(QWebEngineSettings::DefaultFontSize, settings.value("DefaultFontSize", 15).toInt()); webSettings->setFontSize(QWebEngineSettings::DefaultFixedFontSize, settings.value("FixedFontSize", 14).toInt()); webSettings->setFontSize(QWebEngineSettings::MinimumFontSize, settings.value("MinimumFontSize", 3).toInt()); webSettings->setFontSize(QWebEngineSettings::MinimumLogicalFontSize, settings.value("MinimumLogicalFontSize", 5).toInt()); settings.endGroup(); QWebEngineProfile* profile = QWebEngineProfile::defaultProfile(); profile->setPersistentCookiesPolicy(QWebEngineProfile::AllowPersistentCookies); profile->setPersistentStoragePath(DataPaths::currentProfilePath()); QString defaultPath = DataPaths::path(DataPaths::Cache); if (!defaultPath.startsWith(DataPaths::currentProfilePath())) defaultPath.append(QLatin1Char('/') + ProfileManager::currentProfile()); const QString &cachePath = settings.value("Web-Browser-Settings/CachePath", defaultPath).toString(); profile->setCachePath(cachePath); const bool allowCache = settings.value(QSL("Web-Browser-Settings/AllowLocalCache"), true).toBool(); profile->setHttpCacheType(allowCache ? QWebEngineProfile::DiskHttpCache : QWebEngineProfile::MemoryHttpCache); const int cacheSize = settings.value(QSL("Web-Browser-Settings/LocalCacheSize"), 50).toInt() * 1000 * 1000; profile->setHttpCacheMaximumSize(cacheSize); settings.beginGroup(QSL("SpellCheck")); profile->setSpellCheckEnabled(settings.value(QSL("Enabled"), false).toBool()); profile->setSpellCheckLanguages(settings.value(QSL("Languages")).toStringList()); settings.endGroup(); if (isPrivate()) { webSettings->setAttribute(QWebEngineSettings::LocalStorageEnabled, false); history()->setSaving(false); } if (m_downloadManager) { m_downloadManager->loadSettings(); } qzSettings->loadSettings(); networkManager()->loadSettings(); userAgentManager()->loadSettings(); } void MainApplication::loadTheme(const QString &name) { QString activeThemePath; const QStringList themePaths = DataPaths::allPaths(DataPaths::Themes); foreach (const QString &path, themePaths) { const QString theme = QString("%1/%2").arg(path, name); if (QFile::exists(theme + QLatin1String("/main.css"))) { activeThemePath = theme; break; } } if (activeThemePath.isEmpty()) { qWarning() << "Cannot load theme " << name; activeThemePath = QString("%1/%2").arg(DataPaths::path(DataPaths::Themes), DEFAULT_THEME_NAME); } QString qss = QzTools::readAllFileContents(activeThemePath + QLatin1String("/main.css")); #if defined(Q_OS_MACOS) qss.append(QzTools::readAllFileContents(activeThemePath + QLatin1String("/mac.css"))); #elif defined(Q_OS_UNIX) qss.append(QzTools::readAllFileContents(activeThemePath + QLatin1String("/linux.css"))); #elif defined(Q_OS_WIN) || defined(Q_OS_OS2) qss.append(QzTools::readAllFileContents(activeThemePath + QLatin1String("/windows.css"))); #endif if (isRightToLeft()) { qss.append(QzTools::readAllFileContents(activeThemePath + QLatin1String("/rtl.css"))); } QString relativePath = QDir::current().relativeFilePath(activeThemePath); qss.replace(QzRegExp(QSL("url\\s*\\(\\s*([^\\*:\\);]+)\\s*\\)"), Qt::CaseSensitive), QString("url(%1/\\1)").arg(relativePath)); setStyleSheet(qss); } void MainApplication::translateApp() { QString file = Settings().value(QSL("Language/language"), QLocale::system().name()).toString(); // It can only be "C" locale, for which we will use default English language if (file.size() < 2) file.clear(); if (!file.isEmpty() && !file.endsWith(QL1S(".qm"))) file.append(QL1S(".qm")); // Either we load default language (with empty file), or we attempt to load xx.qm (xx_yy.qm) Q_ASSERT(file.isEmpty() || file.size() >= 5); QString translationPath = DataPaths::path(DataPaths::Translations); if (!file.isEmpty()) { const QStringList translationsPaths = DataPaths::allPaths(DataPaths::Translations); foreach (const QString &path, translationsPaths) { // If "xx_yy" translation doesn't exists, try to use "xx*" translation // It can only happen when language is chosen from system locale if (!QFile(QString("%1/%2").arg(path, file)).exists()) { QDir dir(path); QString lang = file.left(2) + QL1S("*.qm"); const QStringList translations = dir.entryList(QStringList(lang)); // If no translation can be found, default English will be used file = translations.isEmpty() ? QString() : translations.at(0); } if (!file.isEmpty() && QFile(QString("%1/%2").arg(path, file)).exists()) { translationPath = path; break; } } } // Load application translation QTranslator* app = new QTranslator(this); app->load(file, translationPath); // Load Qt translation (first try to load from Qt path) QTranslator* sys = new QTranslator(this); sys->load(QL1S("qt_") + file, QLibraryInfo::location(QLibraryInfo::TranslationsPath)); // If there is no translation in Qt path for specified language, try to load it from our path if (sys->isEmpty()) { sys->load(QL1S("qt_") + file, translationPath); } m_languageFile = file; installTranslator(app); installTranslator(sys); } void MainApplication::checkDefaultWebBrowser() { if (isPortable()) { return; } #if defined(Q_OS_WIN) && !defined(Q_OS_OS2) Settings settings; bool checkNow = settings.value("Web-Browser-Settings/CheckDefaultBrowser", DEFAULT_CHECK_DEFAULTBROWSER).toBool(); if (!checkNow) { return; } bool checkAgain = true; if (!associationManager()->isDefaultForAllCapabilities()) { CheckBoxDialog dialog(QMessageBox::Yes | QMessageBox::No, getWindow()); - dialog.setText(tr("QupZilla is not currently your default browser. Would you like to make it your default browser?")); - dialog.setCheckBoxText(tr("Always perform this check when starting QupZilla.")); + dialog.setText(tr("Falkon is not currently your default browser. Would you like to make it your default browser?")); + dialog.setCheckBoxText(tr("Always perform this check when starting Falkon.")); dialog.setDefaultCheckState(Qt::Checked); dialog.setWindowTitle(tr("Default Browser")); dialog.setIcon(QMessageBox::Warning); if (dialog.exec() == QMessageBox::Yes) { if (!mApp->associationManager()->showNativeDefaultAppSettingsUi()) mApp->associationManager()->registerAllAssociation(); } checkAgain = dialog.isChecked(); } settings.setValue("Web-Browser-Settings/CheckDefaultBrowser", checkAgain); #endif } void MainApplication::checkOptimizeDatabase() { Settings settings; settings.beginGroup(QSL("Browser")); const int numberOfRuns = settings.value(QSL("RunsWithoutOptimizeDb"), 0).toInt(); settings.setValue(QSL("RunsWithoutOptimizeDb"), numberOfRuns + 1); if (numberOfRuns > 20) { std::cout << "Optimizing database..." << std::endl; IconProvider::instance()->clearOldIconsInDatabase(); settings.setValue(QSL("RunsWithoutOptimizeDb"), 0); } settings.endGroup(); } void MainApplication::setUserStyleSheet(const QString &filePath) { QString userCss; #if !defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) // Don't grey out selection on losing focus (to prevent graying out found text) QString highlightColor; QString highlightedTextColor; #ifdef Q_OS_MACOS highlightColor = QLatin1String("#b6d6fc"); highlightedTextColor = QLatin1String("#000"); #else QPalette pal = style()->standardPalette(); highlightColor = pal.color(QPalette::Highlight).name(); highlightedTextColor = pal.color(QPalette::HighlightedText).name(); #endif userCss += QString("::selection {background: %1; color: %2;} ").arg(highlightColor, highlightedTextColor); #endif userCss += QzTools::readAllFileContents(filePath).remove(QLatin1Char('\n')); - const QString name = QStringLiteral("_qupzilla_userstylesheet"); + const QString name = QStringLiteral("_falkon_userstylesheet"); QWebEngineScript oldScript = m_webProfile->scripts()->findScript(name); if (!oldScript.isNull()) { m_webProfile->scripts()->remove(oldScript); } if (userCss.isEmpty()) return; QWebEngineScript script; script.setName(name); script.setInjectionPoint(QWebEngineScript::DocumentReady); script.setWorldId(WebPage::SafeJsWorld); script.setRunsOnSubFrames(true); script.setSourceCode(Scripts::setCss(userCss)); m_webProfile->scripts()->insert(script); } void MainApplication::createJumpList() { #ifdef Q_OS_WIN QWinJumpList *jumpList = new QWinJumpList(this); jumpList->clear(); // Frequent QWinJumpListCategory *frequent = jumpList->frequent(); frequent->setVisible(true); const QVector mostList = m_history->mostVisited(7); for (const HistoryEntry &entry : mostList) { frequent->addLink(IconProvider::iconForUrl(entry.url), entry.title, applicationFilePath(), QStringList{entry.url.toEncoded()}); } // Tasks QWinJumpListCategory *tasks = jumpList->tasks(); tasks->setVisible(true); tasks->addLink(IconProvider::newTabIcon(), tr("Open new tab"), applicationFilePath(), {QSL("--new-tab")}); tasks->addLink(IconProvider::newWindowIcon(), tr("Open new window"), applicationFilePath(), {QSL("--new-window")}); tasks->addLink(IconProvider::privateBrowsingIcon(), tr("Open new private window"), applicationFilePath(), {QSL("--private-browsing")}); #endif } void MainApplication::initPulseSupport() { - qputenv("PULSE_PROP_OVERRIDE_application.name", "QupZilla"); + qputenv("PULSE_PROP_OVERRIDE_application.name", "Falkon"); qputenv("PULSE_PROP_OVERRIDE_application.icon_name", "qupzilla"); qputenv("PULSE_PROP_OVERRIDE_media.icon_name", "qupzilla"); } #if defined(Q_OS_WIN) && !defined(Q_OS_OS2) RegisterQAppAssociation* MainApplication::associationManager() { if (!m_registerQAppAssociation) { - QString desc = tr("QupZilla is a new, fast and secure open-source WWW browser. QupZilla is licensed under GPL version 3 or (at your option) any later version. It is based on WebKit core and Qt Framework."); + QString desc = tr("Falkon is a new, fast and secure open-source WWW browser. Falkon is licensed under GPL version 3 or (at your option) any later version. It is based on WebKit core and Qt Framework."); QString fileIconPath = QApplication::applicationFilePath() + ",1"; QString appIconPath = QApplication::applicationFilePath() + ",0"; - m_registerQAppAssociation = new RegisterQAppAssociation("QupZilla", QApplication::applicationFilePath(), appIconPath, desc, this); - m_registerQAppAssociation->addCapability(".html", "QupZilla.HTML", "HTML File", fileIconPath, RegisterQAppAssociation::FileAssociation); - m_registerQAppAssociation->addCapability(".htm", "QupZilla.HTM", "HTM File", fileIconPath, RegisterQAppAssociation::FileAssociation); - m_registerQAppAssociation->addCapability("http", "QupZilla.HTTP", "URL:HyperText Transfer Protocol", appIconPath, RegisterQAppAssociation::UrlAssociation); - m_registerQAppAssociation->addCapability("https", "QupZilla.HTTPS", "URL:HyperText Transfer Protocol with Privacy", appIconPath, RegisterQAppAssociation::UrlAssociation); + m_registerQAppAssociation = new RegisterQAppAssociation("Falkon", QApplication::applicationFilePath(), appIconPath, desc, this); + m_registerQAppAssociation->addCapability(".html", "Falkon.HTML", "HTML File", fileIconPath, RegisterQAppAssociation::FileAssociation); + m_registerQAppAssociation->addCapability(".htm", "Falkon.HTM", "HTM File", fileIconPath, RegisterQAppAssociation::FileAssociation); + m_registerQAppAssociation->addCapability("http", "Falkon.HTTP", "URL:HyperText Transfer Protocol", appIconPath, RegisterQAppAssociation::UrlAssociation); + m_registerQAppAssociation->addCapability("https", "Falkon.HTTPS", "URL:HyperText Transfer Protocol with Privacy", appIconPath, RegisterQAppAssociation::UrlAssociation); } return m_registerQAppAssociation; } #endif #ifdef Q_OS_MACOS #include bool MainApplication::event(QEvent* e) { switch (e->type()) { case QEvent::FileOpen: { QFileOpenEvent *ev = static_cast(e); if (!ev->url().isEmpty()) { addNewTab(ev->url()); } else if (!ev->file().isEmpty()) { addNewTab(QUrl::fromLocalFile(ev->file())); } else { return false; } return true; } case QEvent::ApplicationActivate: if (!activeWindow() && m_windows.isEmpty()) createWindow(Qz::BW_NewWindow); break; default: break; } return QtSingleApplication::event(e); } #endif diff --git a/src/lib/app/mainapplication.h b/src/lib/app/mainapplication.h index 0a09b8ef..223f9c3d 100644 --- a/src/lib/app/mainapplication.h +++ b/src/lib/app/mainapplication.h @@ -1,212 +1,212 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef MAINAPPLICATION_H #define MAINAPPLICATION_H #define mApp MainApplication::instance() #include #include #include "qtsingleapplication/qtsingleapplication.h" #include "restoremanager.h" #include "qzcommon.h" class QMenu; class QWebEngineProfile; class QNetworkAccessManager; class QWebEngineDownloadItem; class History; class AutoFill; class MainMenu; class Bookmarks; class CookieJar; class AutoSaver; class PluginProxy; class BrowserWindow; class NetworkManager; class BrowsingLibrary; class DownloadManager; class UserAgentManager; class SearchEnginesManager; class HTML5PermissionsManager; class RegisterQAppAssociation; class DesktopNotificationsFactory; class ProxyStyle; class SessionManager; -class QUPZILLA_EXPORT MainApplication : public QtSingleApplication +class FALKON_EXPORT MainApplication : public QtSingleApplication { Q_OBJECT public: enum AfterLaunch { OpenBlankPage = 0, OpenHomePage = 1, OpenSpeedDial = 2, RestoreSession = 3, SelectSession = 4 }; explicit MainApplication(int &argc, char** argv); ~MainApplication(); bool isClosing() const; bool isRestoring() const; bool isPrivate() const; bool isPortable() const; bool isStartingAfterCrash() const; int windowCount() const; QList windows() const; BrowserWindow* getWindow() const; BrowserWindow* createWindow(Qz::BrowserWindowType type, const QUrl &startUrl = QUrl()); AfterLaunch afterLaunch() const; void openSession(BrowserWindow* window, RestoreData &restoreData); bool restoreSession(BrowserWindow* window, RestoreData restoreData); void destroyRestoreManager(); void reloadSettings(); // Name of current Qt style QString styleName() const; void setProxyStyle(ProxyStyle *style); QString currentLanguageFile() const; QString currentLanguage() const; History* history(); Bookmarks* bookmarks(); AutoFill* autoFill(); CookieJar* cookieJar(); PluginProxy* plugins(); BrowsingLibrary* browsingLibrary(); NetworkManager* networkManager(); RestoreManager* restoreManager(); SessionManager* sessionManager(); DownloadManager* downloadManager(); UserAgentManager* userAgentManager(); SearchEnginesManager* searchEnginesManager(); HTML5PermissionsManager* html5PermissionsManager(); DesktopNotificationsFactory* desktopNotifications(); QWebEngineProfile* webProfile() const; QByteArray saveState() const; static MainApplication* instance(); public slots: void addNewTab(const QUrl &url = QUrl()); void startPrivateBrowsing(const QUrl &startUrl = QUrl()); void reloadUserStyleSheet(); void restoreOverrideCursor(); void changeOccurred(); void quitApplication(); signals: void settingsReloaded(); void activeWindowChanged(BrowserWindow* window); private slots: void postLaunch(); void saveSettings(); void messageReceived(const QString &message); void windowDestroyed(QObject* window); void onFocusChanged(); void runDeferredPostLaunchActions(); void downloadRequested(QWebEngineDownloadItem *download); private: enum PostLaunchAction { OpenDownloadManager, OpenNewTab, ToggleFullScreen }; void loadSettings(); void loadTheme(const QString &name); void translateApp(); void setUserStyleSheet(const QString &filePath); void checkDefaultWebBrowser(); void checkOptimizeDatabase(); bool m_isPrivate; bool m_isPortable; bool m_isClosing; bool m_isRestoring; bool m_isStartingAfterCrash; History* m_history; Bookmarks* m_bookmarks; AutoFill* m_autoFill; CookieJar* m_cookieJar; PluginProxy* m_plugins; BrowsingLibrary* m_browsingLibrary; NetworkManager* m_networkManager; RestoreManager* m_restoreManager; SessionManager* m_sessionManager; DownloadManager* m_downloadManager; UserAgentManager* m_userAgentManager; SearchEnginesManager* m_searchEnginesManager; HTML5PermissionsManager* m_html5PermissionsManager; DesktopNotificationsFactory* m_desktopNotifications; QWebEngineProfile* m_webProfile; AutoSaver* m_autoSaver; ProxyStyle *m_proxyStyle = nullptr; QList m_windows; QPointer m_lastActiveWindow; QList m_postLaunchActions; QString m_languageFile; void createJumpList(); void initPulseSupport(); #if defined(Q_OS_WIN) && !defined(Q_OS_OS2) public: RegisterQAppAssociation* associationManager(); private: RegisterQAppAssociation* m_registerQAppAssociation; #endif #ifdef Q_OS_MACOS public: bool event(QEvent* e); #endif }; #endif // MAINAPPLICATION_H diff --git a/src/lib/app/mainmenu.cpp b/src/lib/app/mainmenu.cpp index 022d402a..6e50a8d3 100644 --- a/src/lib/app/mainmenu.cpp +++ b/src/lib/app/mainmenu.cpp @@ -1,713 +1,713 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2014-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "mainmenu.h" #include "siteinfo.h" #include "tabwidget.h" #include "historymenu.h" #include "aboutdialog.h" #include "preferences.h" #include "iconprovider.h" #include "cookiemanager.h" #include "bookmarksmenu.h" #include "tabbedwebview.h" #include "browserwindow.h" #include "adblockmanager.h" #include "downloadmanager.h" #include "mainapplication.h" #include "clearprivatedata.h" #include "qzsettings.h" #include "pluginproxy.h" #include "webinspector.h" #include "sessionmanager.h" #include #include #include #include #include #include #ifdef Q_OS_MACOS extern void qt_mac_set_dock_menu(QMenu* menu); #endif MainMenu::MainMenu(BrowserWindow* window, QWidget* parent) : QMenu(parent) , m_window(window) { Q_ASSERT(m_window); init(); } void MainMenu::setWindow(BrowserWindow* window) { Q_ASSERT(window); m_window = window; addActionsToWindow(); } void MainMenu::initMenuBar(QMenuBar* menuBar) const { menuBar->addMenu(m_menuFile); menuBar->addMenu(m_menuEdit); menuBar->addMenu(m_menuView); menuBar->addMenu(m_menuHistory); menuBar->addMenu(m_menuBookmarks); menuBar->addMenu(m_menuTools); menuBar->addMenu(m_menuHelp); } void MainMenu::initSuperMenu(QMenu* superMenu) const { superMenu->addAction(m_actions[QSL("File/NewTab")]); superMenu->addAction(m_actions[QSL("File/NewWindow")]); superMenu->addAction(m_actions[QSL("File/NewPrivateWindow")]); superMenu->addAction(m_actions[QSL("File/OpenFile")]); superMenu->addSeparator(); QMenu* sessionsSubmenu = new QMenu(tr("Sessions")); connect(sessionsSubmenu, SIGNAL(aboutToShow()), mApp->sessionManager(), SLOT(aboutToShowSessionsMenu())); superMenu->addMenu(sessionsSubmenu); superMenu->addAction(m_actions[QSL("File/SessionManager")]); superMenu->addSeparator(); superMenu->addAction(m_actions[QSL("File/SendLink")]); superMenu->addAction(m_actions[QSL("File/Print")]); superMenu->addSeparator(); superMenu->addAction(m_actions[QSL("Edit/SelectAll")]); superMenu->addAction(m_actions[QSL("Edit/Find")]); superMenu->addSeparator(); superMenu->addAction(m_menuHistory->actions().at(3)); superMenu->addAction(m_menuBookmarks->actions().at(2)); superMenu->addSeparator(); superMenu->addMenu(m_menuView); superMenu->addMenu(m_menuHistory); superMenu->addMenu(m_menuBookmarks); superMenu->addMenu(m_menuTools); superMenu->addMenu(m_menuHelp); superMenu->addSeparator(); superMenu->addAction(m_actions[QSL("Standard/Preferences")]); superMenu->addAction(m_actions[QSL("Standard/About")]); superMenu->addSeparator(); superMenu->addAction(m_actions[QSL("Standard/Quit")]); connect(superMenu, &QMenu::aboutToShow, this, &MainMenu::aboutToShowSuperMenu); connect(superMenu, &QMenu::aboutToHide, this, &MainMenu::aboutToHideSuperMenu); } QAction* MainMenu::action(const QString &name) const { Q_ASSERT(m_actions.value(name)); return m_actions.value(name); } void MainMenu::showAboutDialog() { AboutDialog* dialog = new AboutDialog(m_window); dialog->open(); } void MainMenu::showPreferences() { if (!m_preferences) m_preferences = new Preferences(m_window); m_preferences->show(); m_preferences->raise(); m_preferences->activateWindow(); } void MainMenu::quitApplication() { mApp->quitApplication(); } void MainMenu::newTab() { callSlot("addTab"); } void MainMenu::newWindow() { mApp->createWindow(Qz::BW_NewWindow); } void MainMenu::newPrivateWindow() { mApp->startPrivateBrowsing(); } void MainMenu::openLocation() { callSlot("openLocation"); } void MainMenu::openFile() { callSlot("openFile"); } void MainMenu::closeWindow() { callSlot("closeWindow"); } void MainMenu::savePageAs() { if (m_window) { QMetaObject::invokeMethod(m_window->weView(), "savePageAs"); } } void MainMenu::sendLink() { const QUrl mailUrl = QUrl::fromEncoded("mailto:%20?body=" + QUrl::toPercentEncoding(m_window->weView()->url().toEncoded()) + "&subject=" + QUrl::toPercentEncoding(m_window->weView()->title())); QDesktopServices::openUrl(mailUrl); } void MainMenu::printPage() { callSlot("printPage"); } void MainMenu::editUndo() { if (m_window) { m_window->weView()->editUndo(); } } void MainMenu::editRedo() { if (m_window) { m_window->weView()->editRedo(); } } void MainMenu::editCut() { if (m_window) { m_window->weView()->editCut(); } } void MainMenu::editCopy() { if (m_window) { m_window->weView()->editCopy(); } } void MainMenu::editPaste() { if (m_window) { m_window->weView()->editPaste(); } } void MainMenu::editSelectAll() { if (m_window) { m_window->weView()->editSelectAll(); } } void MainMenu::editFind() { callSlot("searchOnPage"); } void MainMenu::showStatusBar() { if (m_window) { m_window->toggleShowStatusBar(); } } void MainMenu::stop() { if (m_window) { m_window->weView()->stop(); } } void MainMenu::reload() { if (m_window) { m_window->weView()->reload(); } } void MainMenu::zoomIn() { if (m_window) { m_window->weView()->zoomIn(); } } void MainMenu::zoomOut() { if (m_window) { m_window->weView()->zoomOut(); } } void MainMenu::zoomReset() { if (m_window) { m_window->weView()->zoomReset(); } } void MainMenu::showPageSource() { callSlot("showSource"); } void MainMenu::showFullScreen() { if (m_window) { m_window->toggleFullScreen(); } } void MainMenu::webSearch() { callSlot("webSearch"); } void MainMenu::showSiteInfo() { if (m_window && SiteInfo::canShowSiteInfo(m_window->weView()->url())) { SiteInfo* info = new SiteInfo(m_window->weView()); info->show(); } } void MainMenu::showDownloadManager() { DownloadManager* m = mApp->downloadManager(); m->show(); m->raise(); } void MainMenu::showCookieManager() { CookieManager* m = new CookieManager(); m->show(); m->raise(); } void MainMenu::showAdBlockDialog() { AdBlockManager::instance()->showDialog(); } void MainMenu::toggleWebInspector() { callSlot("toggleWebInspector"); } void MainMenu::showClearRecentHistoryDialog() { ClearPrivateData* dialog = new ClearPrivateData(m_window); dialog->open(); } void MainMenu::aboutQt() { QApplication::aboutQt(); } void MainMenu::showInfoAboutApp() { if (m_window) { - m_window->tabWidget()->addView(QUrl(QSL("qupzilla:about")), Qz::NT_CleanSelectedTab); + m_window->tabWidget()->addView(QUrl(QSL("falkon:about")), Qz::NT_CleanSelectedTab); } } void MainMenu::showConfigInfo() { if (m_window) { - m_window->tabWidget()->addView(QUrl(QSL("qupzilla:config")), Qz::NT_CleanSelectedTab); + m_window->tabWidget()->addView(QUrl(QSL("falkon:config")), Qz::NT_CleanSelectedTab); } } void MainMenu::reportIssue() { if (m_window) { - m_window->tabWidget()->addView(QUrl(QSL("qupzilla:reportbug")), Qz::NT_CleanSelectedTab); + m_window->tabWidget()->addView(QUrl(QSL("falkon:reportbug")), Qz::NT_CleanSelectedTab); } } void MainMenu::restoreClosedTab() { if (m_window) { m_window->tabWidget()->restoreClosedTab(); } } void MainMenu::aboutToShowFileMenu() { #ifndef Q_OS_MACOS m_actions[QSL("File/CloseWindow")]->setEnabled(mApp->windowCount() > 1); #endif } void MainMenu::aboutToHideFileMenu() { m_actions[QSL("File/CloseWindow")]->setEnabled(true); } void MainMenu::aboutToShowViewMenu() { if (!m_window) { return; } m_actions[QSL("View/ShowStatusBar")]->setChecked(m_window->statusBar()->isVisible()); m_actions[QSL("View/FullScreen")]->setChecked(m_window->isFullScreen()); m_actions[QSL("View/PageSource")]->setEnabled(true); } void MainMenu::aboutToHideViewMenu() { m_actions[QSL("View/PageSource")]->setEnabled(false); } void MainMenu::aboutToShowEditMenu() { if (!m_window) { return; } WebView* view = m_window->weView(); m_actions[QSL("Edit/Undo")]->setEnabled(view->pageAction(QWebEnginePage::Undo)->isEnabled()); m_actions[QSL("Edit/Redo")]->setEnabled(view->pageAction(QWebEnginePage::Redo)->isEnabled()); m_actions[QSL("Edit/Cut")]->setEnabled(view->pageAction(QWebEnginePage::Cut)->isEnabled()); m_actions[QSL("Edit/Copy")]->setEnabled(view->pageAction(QWebEnginePage::Copy)->isEnabled()); m_actions[QSL("Edit/Paste")]->setEnabled(view->pageAction(QWebEnginePage::Paste)->isEnabled()); m_actions[QSL("Edit/SelectAll")]->setEnabled(view->pageAction(QWebEnginePage::SelectAll)->isEnabled()); m_actions[QSL("Edit/Find")]->setEnabled(true); } void MainMenu::aboutToHideEditMenu() { m_actions[QSL("Edit/Undo")]->setEnabled(false); m_actions[QSL("Edit/Redo")]->setEnabled(false); m_actions[QSL("Edit/Cut")]->setEnabled(false); m_actions[QSL("Edit/Copy")]->setEnabled(false); m_actions[QSL("Edit/Paste")]->setEnabled(false); m_actions[QSL("Edit/SelectAll")]->setEnabled(false); m_actions[QSL("Edit/Find")]->setEnabled(false); } void MainMenu::aboutToShowToolsMenu() { if (!m_window) return; m_actions[QSL("Tools/SiteInfo")]->setEnabled(SiteInfo::canShowSiteInfo(m_window->weView()->url())); m_submenuExtensions->clear(); mApp->plugins()->populateExtensionsMenu(m_submenuExtensions); m_submenuExtensions->menuAction()->setVisible(!m_submenuExtensions->actions().isEmpty()); } void MainMenu::aboutToHideToolsMenu() { m_actions[QSL("Tools/SiteInfo")]->setEnabled(false); } void MainMenu::aboutToShowSuperMenu() { if (!m_window) { return; } WebView* view = m_window->weView(); m_actions[QSL("Edit/Find")]->setEnabled(true); m_actions[QSL("Edit/SelectAll")]->setEnabled(view->pageAction(QWebEnginePage::SelectAll)->isEnabled()); } void MainMenu::aboutToHideSuperMenu() { m_actions[QSL("Edit/Find")]->setEnabled(true); m_actions[QSL("Edit/SelectAll")]->setEnabled(false); } void MainMenu::aboutToShowToolbarsMenu() { QMenu* menu = qobject_cast(sender()); Q_ASSERT(menu); if (m_window) { menu->clear(); m_window->createToolbarsMenu(menu); } } void MainMenu::aboutToShowSidebarsMenu() { QMenu* menu = qobject_cast(sender()); Q_ASSERT(menu); if (m_window) { m_window->createSidebarsMenu(menu); } } void MainMenu::aboutToShowEncodingMenu() { QMenu* menu = qobject_cast(sender()); Q_ASSERT(menu); if (m_window) { menu->clear(); m_window->createEncodingMenu(menu); } } void MainMenu::init() { #define ADD_ACTION(name, menu, icon, trName, slot, shortcut) \ action = menu->addAction(icon, trName); \ action->setShortcut(QKeySequence(QSL(shortcut))); \ connect(action, SIGNAL(triggered()), this, slot); \ m_actions[QSL(name)] = action #define ADD_CHECKABLE_ACTION(name, menu, icon, trName, slot, shortcut) \ action = menu->addAction(icon, trName); \ action->setShortcut(QKeySequence(QSL(shortcut))); \ action->setCheckable(true); \ connect(action, SIGNAL(triggered(bool)), this, slot); \ m_actions[QSL(name)] = action // Standard actions - needed on Mac to be placed correctly in "application" menu - QAction* action = new QAction(QIcon::fromTheme(QSL("help-about")), tr("&About QupZilla"), this); + QAction* action = new QAction(QIcon::fromTheme(QSL("help-about")), tr("&About Falkon"), this); action->setMenuRole(QAction::AboutRole); connect(action, SIGNAL(triggered()), this, SLOT(showAboutDialog())); m_actions[QSL("Standard/About")] = action; action = new QAction(IconProvider::settingsIcon(), tr("Pr&eferences"), this); action->setMenuRole(QAction::PreferencesRole); action->setShortcut(QKeySequence(QKeySequence::Preferences)); connect(action, SIGNAL(triggered()), this, SLOT(showPreferences())); m_actions[QSL("Standard/Preferences")] = action; action = new QAction(QIcon::fromTheme(QSL("application-exit")), tr("Quit"), this); action->setMenuRole(QAction::QuitRole); // shortcut set from browserwindow connect(action, SIGNAL(triggered()), this, SLOT(quitApplication())); m_actions[QSL("Standard/Quit")] = action; // File menu m_menuFile = new QMenu(tr("&File")); connect(m_menuFile, SIGNAL(aboutToShow()), this, SLOT(aboutToShowFileMenu())); connect(m_menuFile, SIGNAL(aboutToHide()), this, SLOT(aboutToHideFileMenu())); ADD_ACTION("File/NewTab", m_menuFile, IconProvider::newTabIcon(), tr("New Tab"), SLOT(newTab()), "Ctrl+T"); ADD_ACTION("File/NewWindow", m_menuFile, IconProvider::newWindowIcon(), tr("&New Window"), SLOT(newWindow()), "Ctrl+N"); ADD_ACTION("File/NewPrivateWindow", m_menuFile, IconProvider::privateBrowsingIcon(), tr("New &Private Window"), SLOT(newPrivateWindow()), "Ctrl+Shift+P"); ADD_ACTION("File/OpenLocation", m_menuFile, QIcon::fromTheme(QSL("document-open-remote")), tr("Open Location"), SLOT(openLocation()), "Ctrl+L"); ADD_ACTION("File/OpenFile", m_menuFile, QIcon::fromTheme(QSL("document-open")), tr("Open &File..."), SLOT(openFile()), "Ctrl+O"); ADD_ACTION("File/CloseWindow", m_menuFile, QIcon::fromTheme(QSL("window-close")), tr("Close Window"), SLOT(closeWindow()), "Ctrl+Shift+W"); m_menuFile->addSeparator(); if (!mApp->isPrivate()) { QMenu* sessionsSubmenu = new QMenu(tr("Sessions")); connect(sessionsSubmenu, SIGNAL(aboutToShow()), mApp->sessionManager(), SLOT(aboutToShowSessionsMenu())); m_menuFile->addMenu(sessionsSubmenu); action = new QAction(tr("Session Manager"), this); connect(action, SIGNAL(triggered()), mApp->sessionManager(), SLOT(openSessionManagerDialog())); m_actions[QSL("File/SessionManager")] = action; m_menuFile->addAction(action); m_menuFile->addSeparator(); } ADD_ACTION("File/SavePageAs", m_menuFile, QIcon::fromTheme(QSL("document-save")), tr("&Save Page As..."), SLOT(savePageAs()), "Ctrl+S"); ADD_ACTION("File/SendLink", m_menuFile, QIcon::fromTheme(QSL("mail-message-new")), tr("Send Link..."), SLOT(sendLink()), ""); ADD_ACTION("File/Print", m_menuFile, QIcon::fromTheme(QSL("document-print")), tr("&Print..."), SLOT(printPage()), "Ctrl+P"); m_menuFile->addSeparator(); m_menuFile->addAction(m_actions[QSL("Standard/Quit")]); // Edit menu m_menuEdit = new QMenu(tr("&Edit")); connect(m_menuEdit, SIGNAL(aboutToShow()), this, SLOT(aboutToShowEditMenu())); connect(m_menuEdit, SIGNAL(aboutToHide()), this, SLOT(aboutToHideEditMenu())); ADD_ACTION("Edit/Undo", m_menuEdit, QIcon::fromTheme(QSL("edit-undo")), tr("&Undo"), SLOT(editUndo()), "Ctrl+Z"); ADD_ACTION("Edit/Redo", m_menuEdit, QIcon::fromTheme(QSL("edit-redo")), tr("&Redo"), SLOT(editRedo()), "Ctrl+Shift+Z"); m_menuEdit->addSeparator(); ADD_ACTION("Edit/Cut", m_menuEdit, QIcon::fromTheme(QSL("edit-cut")), tr("&Cut"), SLOT(editCut()), "Ctrl+X"); ADD_ACTION("Edit/Copy", m_menuEdit, QIcon::fromTheme(QSL("edit-copy")), tr("C&opy"), SLOT(editCopy()), "Ctrl+C"); ADD_ACTION("Edit/Paste", m_menuEdit, QIcon::fromTheme(QSL("edit-paste")), tr("&Paste"), SLOT(editPaste()), "Ctrl+V"); m_menuEdit->addSeparator(); ADD_ACTION("Edit/SelectAll", m_menuEdit, QIcon::fromTheme(QSL("edit-select-all")), tr("Select &All"), SLOT(editSelectAll()), "Ctrl+A"); ADD_ACTION("Edit/Find", m_menuEdit, QIcon::fromTheme(QSL("edit-find")), tr("&Find"), SLOT(editFind()), "Ctrl+F"); m_menuEdit->addSeparator(); // View menu m_menuView = new QMenu(tr("&View")); connect(m_menuView, SIGNAL(aboutToShow()), this, SLOT(aboutToShowViewMenu())); connect(m_menuView, SIGNAL(aboutToHide()), this, SLOT(aboutToHideViewMenu())); QMenu* toolbarsMenu = new QMenu(tr("Toolbars")); connect(toolbarsMenu, SIGNAL(aboutToShow()), this, SLOT(aboutToShowToolbarsMenu())); QMenu* sidebarMenu = new QMenu(tr("Sidebar")); connect(sidebarMenu, SIGNAL(aboutToShow()), this, SLOT(aboutToShowSidebarsMenu())); QMenu* encodingMenu = new QMenu(tr("Character &Encoding")); connect(encodingMenu, SIGNAL(aboutToShow()), this, SLOT(aboutToShowEncodingMenu())); // Create menus to make shortcuts available even before first showing the menu m_window->createToolbarsMenu(toolbarsMenu); m_window->createSidebarsMenu(sidebarMenu); m_menuView->addMenu(toolbarsMenu); m_menuView->addMenu(sidebarMenu); ADD_CHECKABLE_ACTION("View/ShowStatusBar", m_menuView, QIcon(), tr("Sta&tus Bar"), SLOT(showStatusBar()), ""); m_menuView->addSeparator(); ADD_ACTION("View/Stop", m_menuView, QIcon::fromTheme(QSL("process-stop")), tr("&Stop"), SLOT(stop()), "Esc"); ADD_ACTION("View/Reload", m_menuView, QIcon::fromTheme(QSL("view-refresh")), tr("&Reload"), SLOT(reload()), "F5"); m_menuView->addSeparator(); ADD_ACTION("View/ZoomIn", m_menuView, QIcon::fromTheme(QSL("zoom-in")), tr("Zoom &In"), SLOT(zoomIn()), "Ctrl++"); ADD_ACTION("View/ZoomOut", m_menuView, QIcon::fromTheme(QSL("zoom-out")), tr("Zoom &Out"), SLOT(zoomOut()), "Ctrl+-"); ADD_ACTION("View/ZoomReset", m_menuView, QIcon::fromTheme(QSL("zoom-original")), tr("Reset"), SLOT(zoomReset()), "Ctrl+0"); m_menuView->addSeparator(); m_menuView->addMenu(encodingMenu); m_menuView->addSeparator(); ADD_ACTION("View/PageSource", m_menuView, QIcon::fromTheme(QSL("text-html")), tr("&Page Source"), SLOT(showPageSource()), "Ctrl+U"); ADD_CHECKABLE_ACTION("View/FullScreen", m_menuView, QIcon(), tr("&FullScreen"), SLOT(showFullScreen()), "F11"); // Tools menu m_menuTools = new QMenu(tr("&Tools")); connect(m_menuTools, SIGNAL(aboutToShow()), this, SLOT(aboutToShowToolsMenu())); connect(m_menuTools, SIGNAL(aboutToHide()), this, SLOT(aboutToHideToolsMenu())); ADD_ACTION("Tools/WebSearch", m_menuTools, QIcon(), tr("&Web Search"), SLOT(webSearch()), "Ctrl+K"); ADD_ACTION("Tools/SiteInfo", m_menuTools, QIcon::fromTheme(QSL("dialog-information")), tr("Site &Info"), SLOT(showSiteInfo()), "Ctrl+I"); m_menuTools->addSeparator(); ADD_ACTION("Tools/DownloadManager", m_menuTools, QIcon(), tr("&Download Manager"), SLOT(showDownloadManager()), "Ctrl+Y"); ADD_ACTION("Tools/CookiesManager", m_menuTools, QIcon(), tr("&Cookies Manager"), SLOT(showCookieManager()), ""); ADD_ACTION("Tools/AdBlock", m_menuTools, QIcon(), tr("&AdBlock"), SLOT(showAdBlockDialog()), ""); ADD_ACTION("Tools/WebInspector", m_menuTools, QIcon(), tr("Web In&spector"), SLOT(toggleWebInspector()), "Ctrl+Shift+I"); ADD_ACTION("Tools/ClearRecentHistory", m_menuTools, QIcon::fromTheme(QSL("edit-clear")), tr("Clear Recent &History"), SLOT(showClearRecentHistoryDialog()), "Ctrl+Shift+Del"); if (!WebInspector::isEnabled()) m_actions.value(QSL("Tools/WebInspector"))->setVisible(false); m_submenuExtensions = new QMenu(tr("&Extensions")); m_submenuExtensions->menuAction()->setVisible(false); m_menuTools->addMenu(m_submenuExtensions); m_menuTools->addSeparator(); // Help menu m_menuHelp = new QMenu(tr("&Help")); #ifndef Q_OS_MACOS ADD_ACTION("Help/AboutQt", m_menuHelp, QIcon(), tr("About &Qt"), SLOT(aboutQt()), ""); m_menuHelp->addAction(m_actions[QSL("Standard/About")]); m_menuHelp->addSeparator(); #endif ADD_ACTION("Help/InfoAboutApp", m_menuHelp, QIcon::fromTheme(QSL("help-contents")), tr("Information about application"), SLOT(showInfoAboutApp()), ""); ADD_ACTION("Help/ConfigInfo", m_menuHelp, QIcon(), tr("Configuration Information"), SLOT(showConfigInfo()), ""); ADD_ACTION("Help/ReportIssue", m_menuHelp, QIcon(), tr("Report &Issue"), SLOT(reportIssue()), ""); m_actions[QSL("Help/InfoAboutApp")]->setShortcut(QKeySequence(QKeySequence::HelpContents)); // History menu m_menuHistory = new HistoryMenu(); m_menuHistory->setMainWindow(m_window); // Bookmarks menu m_menuBookmarks = new BookmarksMenu(); m_menuBookmarks->setMainWindow(m_window); // Other actions action = new QAction(QIcon::fromTheme(QSL("user-trash")), tr("Restore &Closed Tab"), this); action->setShortcut(QKeySequence(QSL("Ctrl+Shift+T"))); connect(action, SIGNAL(triggered()), this, SLOT(restoreClosedTab())); m_actions[QSL("Other/RestoreClosedTab")] = action; #ifdef Q_OS_MACOS m_actions[QSL("View/FullScreen")]->setShortcut(QKeySequence(QSL("Ctrl+Meta+F"))); // Add standard actions to File Menu (as it won't be ever cleared) and Mac menubar should move them to "Application" menu m_menuFile->addAction(m_actions[QSL("Standard/About")]); m_menuFile->addAction(m_actions[QSL("Standard/Preferences")]); // Prevent ConfigInfo action to be detected as "Preferences..." action in Mac menubar m_actions[QSL("Help/ConfigInfo")]->setMenuRole(QAction::NoRole); // Create Dock menu QMenu* dockMenu = new QMenu(0); dockMenu->addAction(m_actions[QSL("File/NewTab")]); dockMenu->addAction(m_actions[QSL("File/NewWindow")]); dockMenu->addAction(m_actions[QSL("File/NewPrivateWindow")]); qt_mac_set_dock_menu(dockMenu); #endif #if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) m_menuEdit->addAction(m_actions[QSL("Standard/Preferences")]); #elif !defined(Q_OS_MACOS) m_menuTools->addAction(m_actions[QSL("Standard/Preferences")]); #endif // Menus are hidden by default aboutToHideFileMenu(); aboutToHideViewMenu(); aboutToHideEditMenu(); aboutToHideToolsMenu(); addActionsToWindow(); } void MainMenu::addActionsToWindow() { // Make shortcuts available even in fullscreen (hidden menu) QList actions; actions << m_menuFile->actions(); actions << m_menuEdit->actions(); actions << m_menuView->actions(); actions << m_menuTools->actions(); actions << m_menuHelp->actions(); actions << m_menuHistory->actions(); actions << m_menuBookmarks->actions(); actions << m_actions[QSL("Other/RestoreClosedTab")]; for (int i = 0; i < actions.size(); ++i) { QAction* action = actions.at(i); if (action->menu()) { actions += action->menu()->actions(); } m_window->addAction(action); } } void MainMenu::callSlot(const char* slot) { if (m_window) { QMetaObject::invokeMethod(m_window, slot); } } diff --git a/src/lib/app/mainmenu.h b/src/lib/app/mainmenu.h index 32e2301e..c259361c 100644 --- a/src/lib/app/mainmenu.h +++ b/src/lib/app/mainmenu.h @@ -1,138 +1,138 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2014-2016 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef MAINMENU_H #define MAINMENU_H #include #include #include #include "qzcommon.h" class QMenuBar; class Preferences; class HistoryMenu; class BookmarksMenu; class BrowserWindow; -class QUPZILLA_EXPORT MainMenu : public QMenu +class FALKON_EXPORT MainMenu : public QMenu { Q_OBJECT public: explicit MainMenu(BrowserWindow* window, QWidget* parent = 0); void initMenuBar(QMenuBar* menuBar) const; void initSuperMenu(QMenu* superMenu) const; QAction* action(const QString &name) const; public slots: void setWindow(BrowserWindow* window); private slots: // Standard actions void showAboutDialog(); void showPreferences(); void quitApplication(); // File menu void newTab(); void newWindow(); void newPrivateWindow(); void openLocation(); void openFile(); void closeWindow(); void savePageAs(); void sendLink(); void printPage(); // Edit menu void editUndo(); void editRedo(); void editCut(); void editCopy(); void editPaste(); void editSelectAll(); void editFind(); // View menu void showStatusBar(); void stop(); void reload(); void zoomIn(); void zoomOut(); void zoomReset(); void showPageSource(); void showFullScreen(); // Tools menu void webSearch(); void showSiteInfo(); void showDownloadManager(); void showCookieManager(); void showAdBlockDialog(); void toggleWebInspector(); void showClearRecentHistoryDialog(); // Help menu void aboutQt(); void showInfoAboutApp(); void showConfigInfo(); void reportIssue(); // Other actions void restoreClosedTab(); void aboutToShowFileMenu(); void aboutToHideFileMenu(); void aboutToShowViewMenu(); void aboutToHideViewMenu(); void aboutToShowEditMenu(); void aboutToHideEditMenu(); void aboutToShowToolsMenu(); void aboutToHideToolsMenu(); void aboutToShowSuperMenu(); void aboutToHideSuperMenu(); void aboutToShowToolbarsMenu(); void aboutToShowSidebarsMenu(); void aboutToShowEncodingMenu(); private: void init(); void addActionsToWindow(); void callSlot(const char* slot); QHash m_actions; QPointer m_window; QPointer m_preferences; QMenu* m_menuFile; QMenu* m_menuEdit; QMenu* m_menuView; QMenu* m_menuTools; QMenu* m_menuHelp; QMenu* m_submenuExtensions; HistoryMenu* m_menuHistory; BookmarksMenu* m_menuBookmarks; }; #endif // MAINMENU_H diff --git a/src/lib/app/profilemanager.cpp b/src/lib/app/profilemanager.cpp index 54bcf44f..6946fc28 100644 --- a/src/lib/app/profilemanager.cpp +++ b/src/lib/app/profilemanager.cpp @@ -1,264 +1,264 @@ /* ============================================================ * QupZilla - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "profilemanager.h" #include "mainapplication.h" #include "datapaths.h" #include "updater.h" #include "qztools.h" #include #include #include #include #include ProfileManager::ProfileManager() : m_databaseConnected(false) { } void ProfileManager::initConfigDir() { QDir dir(DataPaths::path(DataPaths::Config)); if (dir.exists() && QFile(dir.filePath(QLatin1String("profiles/profiles.ini"))).exists()) { return; } - std::cout << "QupZilla: Creating new profile directory" << std::endl; + std::cout << "Falkon: Creating new profile directory" << std::endl; if (!dir.exists()) { dir.mkpath(dir.absolutePath()); } dir.mkdir(QLatin1String("profiles")); dir.cd(QLatin1String("profiles")); // $Config/profiles QFile(dir.filePath(QLatin1String("profiles.ini"))).remove(); QFile(QLatin1String(":data/profiles.ini")).copy(dir.filePath(QLatin1String("profiles.ini"))); QFile(dir.filePath(QLatin1String("profiles.ini"))).setPermissions(QFile::ReadUser | QFile::WriteUser); dir.mkdir(QLatin1String("default")); dir.cd(QLatin1String("default")); // $Config/profiles/default QFile(dir.filePath(QLatin1String("browsedata.db"))).remove(); QFile(QLatin1String(":data/browsedata.db")).copy(dir.filePath(QLatin1String("browsedata.db"))); QFile(dir.filePath(QLatin1String("browsedata.db"))).setPermissions(QFile::ReadUser | QFile::WriteUser); QFile(QLatin1String(":data/bookmarks.json")).copy(dir.filePath(QLatin1String("bookmarks.json"))); QFile(dir.filePath(QLatin1String("bookmarks.json"))).setPermissions(QFile::ReadUser | QFile::WriteUser); QFile versionFile(dir.filePath(QLatin1String("version"))); versionFile.open(QFile::WriteOnly); versionFile.write(Qz::VERSION); versionFile.close(); } void ProfileManager::initCurrentProfile(const QString &profileName) { QString profilePath = DataPaths::path(DataPaths::Profiles) + QLatin1Char('/'); if (profileName.isEmpty()) { profilePath.append(startingProfile()); } else { profilePath.append(profileName); } DataPaths::setCurrentProfilePath(profilePath); updateCurrentProfile(); connectDatabase(); } int ProfileManager::createProfile(const QString &profileName) { QDir dir(DataPaths::path(DataPaths::Profiles)); if (QDir(dir.absolutePath() + QLatin1Char('/') + profileName).exists()) { return -1; } if (!dir.mkdir(profileName)) { return -2; } dir.cd(profileName); QFile(QLatin1String(":data/browsedata.db")).copy(dir.filePath(QLatin1String("browsedata.db"))); QFile(dir.filePath(QLatin1String("browsedata.db"))).setPermissions(QFile::ReadUser | QFile::WriteUser); QFile versionFile(dir.filePath(QLatin1String("version"))); versionFile.open(QFile::WriteOnly); versionFile.write(Qz::VERSION); versionFile.close(); return 0; } bool ProfileManager::removeProfile(const QString &profileName) { QDir dir(DataPaths::path(DataPaths::Profiles) + QLatin1Char('/') + profileName); if (!dir.exists()) { return false; } QzTools::removeDir(dir.absolutePath()); return true; } // static QString ProfileManager::currentProfile() { QString path = DataPaths::currentProfilePath(); return path.mid(path.lastIndexOf(QLatin1Char('/')) + 1); } // static QString ProfileManager::startingProfile() { QSettings settings(DataPaths::path(DataPaths::Profiles) + QLatin1String("/profiles.ini"), QSettings::IniFormat); return settings.value(QLatin1String("Profiles/startProfile"), QLatin1String("default")).toString(); } // static void ProfileManager::setStartingProfile(const QString &profileName) { QSettings settings(DataPaths::path(DataPaths::Profiles) + QLatin1String("/profiles.ini"), QSettings::IniFormat); settings.setValue(QLatin1String("Profiles/startProfile"), profileName); } // static QStringList ProfileManager::availableProfiles() { QDir dir(DataPaths::path(DataPaths::Profiles)); return dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot); } void ProfileManager::updateCurrentProfile() { QDir profileDir(DataPaths::currentProfilePath()); if (!profileDir.exists()) { QDir newDir(profileDir.path().remove(profileDir.dirName())); newDir.mkdir(profileDir.dirName()); } QFile versionFile(profileDir.filePath(QLatin1String("version"))); // If file exists, just update the profile to current version if (versionFile.exists()) { versionFile.open(QFile::ReadOnly); QString profileVersion = versionFile.readAll(); versionFile.close(); updateProfile(Qz::VERSION, profileVersion.trimmed()); } else { copyDataToProfile(); } versionFile.open(QFile::WriteOnly); versionFile.write(Qz::VERSION); versionFile.close(); } void ProfileManager::updateProfile(const QString ¤t, const QString &profile) { if (current == profile) { return; } Updater::Version prof(profile); if (prof < Updater::Version("1.9.0")) { - std::cout << "QupZilla: Using profile from QupZilla " << qPrintable(profile) << " is not supported!" << std::endl; + std::cout << "Falkon: Using profile from QupZilla " << qPrintable(profile) << " is not supported!" << std::endl; return; } // No change in 2.0 if (prof < Updater::Version("2.0.99")) { return; } // No change in 2.1 if (prof < Updater::Version("2.1.99")) { return; } // Nothing for now } void ProfileManager::copyDataToProfile() { QDir profileDir(DataPaths::currentProfilePath()); QFile browseData(profileDir.filePath(QLatin1String("browsedata.db"))); if (browseData.exists()) { const QString browseDataBackup = QzTools::ensureUniqueFilename(profileDir.filePath(QLatin1String("browsedata-backup.db"))); browseData.copy(browseDataBackup); browseData.remove(); QFile settings(profileDir.filePath(QSL("settings.ini"))); if (settings.exists()) { const QString settingsBackup = QzTools::ensureUniqueFilename(profileDir.filePath(QSL("settings-backup.ini"))); settings.copy(settingsBackup); settings.remove(); } const QString text = "Incompatible profile version has been detected. To avoid losing your profile data, they were " "backed up in following file:

" + browseDataBackup + "
"; - QMessageBox::warning(0, "QupZilla: Incompatible profile version", text); + QMessageBox::warning(0, "Falkon: Incompatible profile version", text); } QFile(QLatin1String(":data/browsedata.db")).copy(profileDir.filePath(QLatin1String("browsedata.db"))); QFile(profileDir.filePath(QLatin1String("browsedata.db"))).setPermissions(QFile::ReadUser | QFile::WriteUser); } void ProfileManager::connectDatabase() { const QString dbFile = DataPaths::currentProfilePath() + QLatin1String("/browsedata.db"); // Reconnect if (m_databaseConnected) { QSqlDatabase::removeDatabase(QSqlDatabase::database().connectionName()); } QSqlDatabase db = QSqlDatabase::addDatabase(QLatin1String("QSQLITE")); db.setDatabaseName(dbFile); if (!QFile::exists(dbFile)) { qWarning("Cannot find SQLite database file! Copying and using the defaults!"); QFile(":data/browsedata.db").copy(dbFile); QFile(dbFile).setPermissions(QFile::ReadUser | QFile::WriteUser); db.setDatabaseName(dbFile); } if (mApp->isPrivate()) { db.setConnectOptions("QSQLITE_OPEN_READONLY"); } if (!db.open()) { qWarning("Cannot open SQLite database! Continuing without database...."); } m_databaseConnected = true; } diff --git a/src/lib/app/profilemanager.h b/src/lib/app/profilemanager.h index 57317ba2..43b84b4f 100644 --- a/src/lib/app/profilemanager.h +++ b/src/lib/app/profilemanager.h @@ -1,60 +1,60 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef PROFILEMANAGER_H #define PROFILEMANAGER_H #include #include "qzcommon.h" class ProfileManager { public: explicit ProfileManager(); // Make sure the config dir exists and have correct structure void initConfigDir(); // Set current profile name (from profiles.ini) and ensure dir exists with correct structure void initCurrentProfile(const QString &profileName); // Return 0 on success, -1 profile already exists, -2 cannot create directory static int createProfile(const QString &profileName); // Return false on error (profile does not exists) static bool removeProfile(const QString &profileName); // Name of current profile static QString currentProfile(); // Name of starting profile static QString startingProfile(); static void setStartingProfile(const QString &profileName); // Names of available profiles static QStringList availableProfiles(); private: void updateCurrentProfile(); void updateProfile(const QString ¤t, const QString &profile); void copyDataToProfile(); void connectDatabase(); bool m_databaseConnected; }; #endif // PROFILEMANAGER_H diff --git a/src/lib/app/proxystyle.cpp b/src/lib/app/proxystyle.cpp index ecca64a1..fdcef5bc 100644 --- a/src/lib/app/proxystyle.cpp +++ b/src/lib/app/proxystyle.cpp @@ -1,62 +1,62 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "proxystyle.h" ProxyStyle::ProxyStyle() : QProxyStyle() , m_TabBarTabHSpace(-1) { } int ProxyStyle::styleHint(StyleHint hint, const QStyleOption* option, const QWidget* widget, QStyleHintReturn* returnData) const { switch (hint) { case QStyle::SH_Menu_Scrollable: return int(true); case QStyle::SH_TabBar_Alignment: return Qt::AlignLeft; default: return QProxyStyle::styleHint(hint, option, widget, returnData); } } int ProxyStyle::pixelMetric(PixelMetric metric, const QStyleOption* option, const QWidget* widget) const { switch (metric) { case PM_TabBarTabHSpace: if (m_TabBarTabHSpace == -1) { m_TabBarTabHSpace = qMin(QProxyStyle::pixelMetric(PM_TabBarTabHSpace, option, widget), 14); if (name() == QLatin1String("oxygen")) { m_TabBarTabHSpace = 14; } } return m_TabBarTabHSpace; default: return QProxyStyle::pixelMetric(metric, option, widget); } } QString ProxyStyle::name() const { return baseStyle()->objectName(); } diff --git a/src/lib/app/proxystyle.h b/src/lib/app/proxystyle.h index 14d17157..4473e2ef 100644 --- a/src/lib/app/proxystyle.h +++ b/src/lib/app/proxystyle.h @@ -1,39 +1,39 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef PROXYSTYLE_H #define PROXYSTYLE_H #include #include "qzcommon.h" -class QUPZILLA_EXPORT ProxyStyle : public QProxyStyle +class FALKON_EXPORT ProxyStyle : public QProxyStyle { public: explicit ProxyStyle(); int styleHint(StyleHint hint, const QStyleOption* option = 0, const QWidget* widget = 0, QStyleHintReturn* returnData = 0) const; int pixelMetric(PixelMetric metric, const QStyleOption* option, const QWidget* widget) const; QString name() const; private: mutable int m_TabBarTabHSpace; }; #endif // PROXYSTYLE_H diff --git a/src/lib/app/qzcommon.cpp b/src/lib/app/qzcommon.cpp index 0166389d..fd8664b3 100644 --- a/src/lib/app/qzcommon.cpp +++ b/src/lib/app/qzcommon.cpp @@ -1,32 +1,32 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2014-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "qzcommon.h" namespace Qz { const int sessionVersion = 0x0003; const int sessionVersionQt5 = 0x0003 | 0x050000; const int bookmarksVersion = 1; -QUPZILLA_EXPORT const char* APPNAME = "QupZilla"; -QUPZILLA_EXPORT const char* VERSION = QUPZILLA_VERSION; -QUPZILLA_EXPORT const char* AUTHOR = "David Rosca"; -QUPZILLA_EXPORT const char* COPYRIGHT = "2010-2017"; -QUPZILLA_EXPORT const char* WWWADDRESS = "https://www.qupzilla.com"; -QUPZILLA_EXPORT const char* WIKIADDRESS = "https://github.com/QupZilla/qupzilla/wiki"; +FALKON_EXPORT const char* APPNAME = "Falkon"; +FALKON_EXPORT const char* VERSION = FALKON_VERSION; +FALKON_EXPORT const char* AUTHOR = "David Rosca"; +FALKON_EXPORT const char* COPYRIGHT = "2010-2017"; +FALKON_EXPORT const char* WWWADDRESS = "https://www.qupzilla.com"; +FALKON_EXPORT const char* WIKIADDRESS = "https://github.com/QupZilla/qupzilla/wiki"; } diff --git a/src/lib/app/qzcommon.h b/src/lib/app/qzcommon.h index c97f5958..f02b6086 100644 --- a/src/lib/app/qzcommon.h +++ b/src/lib/app/qzcommon.h @@ -1,143 +1,143 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef QZCOMMON_H #define QZCOMMON_H #include #include -#ifdef QUPZILLA_SHAREDLIBRARY -#define QUPZILLA_EXPORT Q_DECL_EXPORT +#ifdef FALKON_SHAREDLIBRARY +#define FALKON_EXPORT Q_DECL_EXPORT #else -#define QUPZILLA_EXPORT Q_DECL_IMPORT +#define FALKON_EXPORT Q_DECL_IMPORT #endif #ifndef Q_UNLIKELY #define Q_UNLIKELY(x) x #endif #ifndef Q_LIKELY #define Q_LIKELY(x) x #endif #ifndef QSL #define QSL(x) QStringLiteral(x) #endif #ifndef QL1S #define QL1S(x) QLatin1String(x) #endif #ifndef QL1C #define QL1C(x) QLatin1Char(x) #endif namespace Qz { // Version of session.dat file extern const int sessionVersion; // Backwards compatibility (used to be different for Qt4 and Qt5) extern const int sessionVersionQt5; // Version of bookmarks.json file extern const int bookmarksVersion; -QUPZILLA_EXPORT extern const char* APPNAME; -QUPZILLA_EXPORT extern const char* VERSION; -QUPZILLA_EXPORT extern const char* AUTHOR; -QUPZILLA_EXPORT extern const char* COPYRIGHT; -QUPZILLA_EXPORT extern const char* WWWADDRESS; -QUPZILLA_EXPORT extern const char* WIKIADDRESS; +FALKON_EXPORT extern const char* APPNAME; +FALKON_EXPORT extern const char* VERSION; +FALKON_EXPORT extern const char* AUTHOR; +FALKON_EXPORT extern const char* COPYRIGHT; +FALKON_EXPORT extern const char* WWWADDRESS; +FALKON_EXPORT extern const char* WIKIADDRESS; enum BrowserWindowType { BW_FirstAppWindow, BW_OtherRestoredWindow, BW_NewWindow, BW_MacFirstWindow }; enum CommandLineAction { CL_NoAction, CL_OpenUrl, CL_OpenUrlInCurrentTab, CL_OpenUrlInNewWindow, CL_StartWithProfile, CL_StartWithoutAddons, CL_NewTab, CL_NewWindow, CL_ShowDownloadManager, CL_ToggleFullScreen, CL_StartPrivateBrowsing, CL_StartNewInstance, CL_StartPortable, CL_ExitAction }; enum ObjectName { ON_WebView, ON_TabBar, ON_BrowserWindow }; enum NewTabPositionFlag { NT_SelectedTab = 1, NT_NotSelectedTab = 2, NT_CleanTab = 4, NT_TabAtTheEnd = 8, NT_NewEmptyTab = 16, NT_SelectedNewEmptyTab = NT_SelectedTab | NT_TabAtTheEnd | NT_NewEmptyTab, NT_SelectedTabAtTheEnd = NT_SelectedTab | NT_TabAtTheEnd, NT_NotSelectedTabAtTheEnd = NT_NotSelectedTab | NT_TabAtTheEnd, NT_CleanSelectedTabAtTheEnd = NT_SelectedTab | NT_TabAtTheEnd | NT_CleanTab, NT_CleanSelectedTab = NT_CleanTab | NT_SelectedTab, NT_CleanNotSelectedTab = NT_CleanTab | NT_NotSelectedTab }; Q_DECLARE_FLAGS(NewTabPositionFlags, NewTabPositionFlag) Q_DECLARE_OPERATORS_FOR_FLAGS(Qz::NewTabPositionFlags) } #define ADBLOCK_EASYLIST_URL "https://easylist-downloads.adblockplus.org/easylist.txt" #if defined(Q_OS_WIN) || defined(Q_OS_OS2) #define DEFAULT_THEME_NAME "windows" #elif defined(Q_OS_MACOS) #define DEFAULT_THEME_NAME "mac" #elif defined(Q_OS_UNIX) #define DEFAULT_THEME_NAME "linux" #else #define DEFAULT_THEME_NAME "default" #endif #ifdef Q_OS_WIN #define DISABLE_CHECK_UPDATES false #else #define DISABLE_CHECK_UPDATES true #endif #define DEFAULT_CHECK_DEFAULTBROWSER false #ifdef Q_OS_WIN #define DEFAULT_DOWNLOAD_USE_NATIVE_DIALOG false #else #define DEFAULT_DOWNLOAD_USE_NATIVE_DIALOG true #endif #endif // QZCOMMON_H diff --git a/src/lib/app/settings.cpp b/src/lib/app/settings.cpp index ffcaafb9..c9ec64fe 100644 --- a/src/lib/app/settings.cpp +++ b/src/lib/app/settings.cpp @@ -1,89 +1,89 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "settings.h" #include "qzsettings.h" #include QSettings* Settings::s_settings = 0; QzSettings* Settings::s_qzSettings = 0; Settings::Settings() { // Save currently opened group if (!s_settings->group().isEmpty()) { m_openedGroup = s_settings->group(); s_settings->endGroup(); } } void Settings::createSettings(const QString &fileName) { s_settings = new QSettings(fileName, QSettings::IniFormat); s_qzSettings = new QzSettings(); } void Settings::syncSettings() { if (!s_settings) return; s_settings->sync(); } void Settings::setValue(const QString &key, const QVariant &defaultValue) { s_settings->setValue(key, defaultValue); } QVariant Settings::value(const QString &key, const QVariant &defaultValue) { return s_settings->value(key, defaultValue); } void Settings::beginGroup(const QString &prefix) { s_settings->beginGroup(prefix); } void Settings::endGroup() { s_settings->endGroup(); } QSettings* Settings::globalSettings() { return s_settings; } QzSettings* Settings::staticSettings() { return s_qzSettings; } Settings::~Settings() { if (!s_settings->group().isEmpty()) { qDebug() << "Settings: Deleting object with opened group!"; s_settings->endGroup(); } // Restore opened group if (!m_openedGroup.isEmpty()) s_settings->beginGroup(m_openedGroup); } diff --git a/src/lib/app/settings.h b/src/lib/app/settings.h index 8bb2e29c..b45a8cd4 100644 --- a/src/lib/app/settings.h +++ b/src/lib/app/settings.h @@ -1,55 +1,55 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef SETTINGS_H #define SETTINGS_H #include #include "qzcommon.h" class QSettings; class QzSettings; -class QUPZILLA_EXPORT Settings +class FALKON_EXPORT Settings { public: explicit Settings(); ~Settings(); static void createSettings(const QString &fileName); static void syncSettings(); static QSettings* globalSettings(); static QzSettings* staticSettings(); void setValue(const QString &key, const QVariant &defaultValue = QVariant()); QVariant value(const QString &key, const QVariant &defaultValue = QVariant()); void beginGroup(const QString &prefix); void endGroup(); private: static QSettings* s_settings; static QzSettings* s_qzSettings; QString m_openedGroup; }; #endif // SETTINGS_H diff --git a/src/lib/autofill/autofill.cpp b/src/lib/autofill/autofill.cpp index d3759383..55ae94ad 100644 --- a/src/lib/autofill/autofill.cpp +++ b/src/lib/autofill/autofill.cpp @@ -1,357 +1,357 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "autofill.h" #include "browserwindow.h" #include "webpage.h" #include "sqldatabase.h" #include "tabbedwebview.h" #include "popupwebview.h" #include "mainapplication.h" #include "autofillnotification.h" #include "settings.h" #include "passwordmanager.h" #include "qztools.h" #include "scripts.h" #include #include #include #include #include AutoFill::AutoFill(QObject* parent) : QObject(parent) , m_manager(new PasswordManager(this)) , m_isStoring(false) { loadSettings(); // Setup AutoFill userscript QWebEngineScript script; - script.setName(QSL("_qupzilla_autofill")); + script.setName(QSL("_falkon_autofill")); script.setInjectionPoint(QWebEngineScript::DocumentReady); script.setWorldId(QWebEngineScript::MainWorld); script.setRunsOnSubFrames(true); script.setSourceCode(Scripts::setupFormObserver()); mApp->webProfile()->scripts()->insert(script); } PasswordManager* AutoFill::passwordManager() const { return m_manager; } void AutoFill::loadSettings() { Settings settings; settings.beginGroup("Web-Browser-Settings"); m_isStoring = settings.value("SavePasswordsOnSites", true).toBool(); settings.endGroup(); } bool AutoFill::isStored(const QUrl &url) { if (!isStoringEnabled(url)) { return false; } return !m_manager->getEntries(url).isEmpty(); } bool AutoFill::isStoringEnabled(const QUrl &url) { if (!m_isStoring) { return false; } QString server = url.host(); if (server.isEmpty()) { server = url.toString(); } QSqlQuery query; query.prepare("SELECT count(id) FROM autofill_exceptions WHERE server=?"); query.addBindValue(server); query.exec(); if (!query.next()) { return false; } return query.value(0).toInt() <= 0; } void AutoFill::blockStoringforUrl(const QUrl &url) { QString server = url.host(); if (server.isEmpty()) { server = url.toString(); } QSqlQuery query; query.prepare("INSERT INTO autofill_exceptions (server) VALUES (?)"); query.addBindValue(server); SqlDatabase::instance()->execAsync(query); } QVector AutoFill::getFormData(const QUrl &url) { return m_manager->getEntries(url); } QVector AutoFill::getAllFormData() { return m_manager->getAllEntries(); } void AutoFill::updateLastUsed(PasswordEntry &data) { m_manager->updateLastUsed(data); } // HTTP Authorization void AutoFill::addEntry(const QUrl &url, const QString &name, const QString &pass) { PasswordEntry entry; entry.host = PasswordManager::createHost(url); entry.username = name; entry.password = pass; m_manager->addEntry(entry); } // WEB Form void AutoFill::addEntry(const QUrl &url, const PageFormData &formData) { PasswordEntry entry; entry.host = PasswordManager::createHost(url); entry.username = formData.username; entry.password = formData.password; entry.data = formData.postData; m_manager->addEntry(entry); } // HTTP Authorization void AutoFill::updateEntry(const QUrl &url, const QString &name, const QString &pass) { PasswordEntry entry; entry.host = PasswordManager::createHost(url); entry.username = name; entry.password = pass; m_manager->updateEntry(entry); } // WEB Form bool AutoFill::updateEntry(const PasswordEntry &entry) { return m_manager->updateEntry(entry); } void AutoFill::removeEntry(const PasswordEntry &entry) { m_manager->removeEntry(entry); } void AutoFill::removeAllEntries() { m_manager->removeAllEntries(); } void AutoFill::saveForm(WebPage *page, const QUrl &frameUrl, const PageFormData &formData) { // Don't save in private browsing if (mApp->isPrivate() || !page) return; if (!isStoringEnabled(frameUrl)) return; PasswordEntry updateData; if (isStored(frameUrl)) { const QVector &list = getFormData(frameUrl); foreach (const PasswordEntry &data, list) { if (data.username == formData.username) { updateData = data; updateLastUsed(updateData); if (data.password == formData.password) { updateData.password.clear(); return; } updateData.username = formData.username; updateData.password = formData.password; updateData.data = formData.postData; break; } } } if (m_lastNotification && m_lastNotificationPage == page) { m_lastNotification->close(); } AutoFillNotification* aWidget = new AutoFillNotification(frameUrl, formData, updateData); page->view()->addNotification(aWidget); m_lastNotification = aWidget; m_lastNotificationPage = page; } // Returns all saved passwords on this page QVector AutoFill::completePage(WebPage *page, const QUrl &frameUrl) { QVector list; if (!page || !isStored(frameUrl)) return list; list = getFormData(frameUrl); if (!list.isEmpty()) { const PasswordEntry entry = list.at(0); page->runJavaScript(Scripts::completeFormData(entry.data), WebPage::SafeJsWorld); } return list; } QByteArray AutoFill::exportPasswords() { QByteArray output; QXmlStreamWriter stream(&output); stream.setCodec("UTF-8"); stream.setAutoFormatting(true); stream.writeStartDocument(); stream.writeStartElement("passwords"); stream.writeAttribute("version", "1.0"); QVector entries = m_manager->getAllEntries(); foreach (const PasswordEntry &entry, entries) { stream.writeStartElement("entry"); stream.writeTextElement("server", entry.host); stream.writeTextElement("username", entry.username); stream.writeTextElement("password", entry.password); stream.writeTextElement("data", entry.data); stream.writeEndElement(); } QSqlQuery query; query.exec("SELECT server FROM autofill_exceptions"); while (query.next()) { stream.writeStartElement("exception"); stream.writeTextElement("server", query.value(0).toString()); stream.writeEndElement(); } stream.writeEndElement(); stream.writeEndDocument(); return output; } bool AutoFill::importPasswords(const QByteArray &data) { QSqlDatabase db = QSqlDatabase::database(); db.transaction(); QXmlStreamReader xml(data); while (!xml.atEnd()) { xml.readNext(); if (xml.isStartElement()) { if (xml.name() == QLatin1String("entry")) { PasswordEntry entry; while (xml.readNext()) { if (xml.name() == QLatin1String("server")) { entry.host = xml.readElementText(); } else if (xml.name() == QLatin1String("username")) { entry.username = xml.readElementText(); } else if (xml.name() == QLatin1String("password")) { entry.password = xml.readElementText(); } else if (xml.name() == QLatin1String("data")) { entry.data = xml.readElementText().toUtf8(); } if (xml.isEndElement() && xml.name() == QLatin1String("entry")) { break; } } if (entry.isValid()) { bool containsEntry = false; foreach (const PasswordEntry &e, m_manager->getEntries(QUrl(entry.host))) { if (e.username == entry.username) { containsEntry = true; break; } } if (!containsEntry) { m_manager->addEntry(entry); } } } else if (xml.name() == QLatin1String("exception")) { QString server; while (xml.readNext()) { if (xml.name() == QLatin1String("server")) { server = xml.readElementText(); } if (xml.isEndElement() && xml.name() == QLatin1String("exception")) { break; } } if (!server.isEmpty()) { QSqlQuery query; query.prepare("SELECT id FROM autofill_exceptions WHERE server=?"); query.addBindValue(server); query.exec(); if (!query.next()) { query.prepare("INSERT INTO autofill_exceptions (server) VALUES (?)"); query.addBindValue(server); query.exec(); } } } } } db.commit(); return !xml.hasError(); } diff --git a/src/lib/autofill/autofill.h b/src/lib/autofill/autofill.h index a0d08143..2458b1af 100644 --- a/src/lib/autofill/autofill.h +++ b/src/lib/autofill/autofill.h @@ -1,88 +1,88 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef AUTOFILL_H #define AUTOFILL_H #include #include #include "qzcommon.h" class QUrl; class QWebEnginePage; class WebPage; class BrowserWindow; class PasswordManager; class AutoFillNotification; struct PageFormData; struct PasswordEntry; struct PageFormData { QString username; QString password; QByteArray postData; bool isValid() const { return !password.isEmpty(); } }; -class QUPZILLA_EXPORT AutoFill : public QObject +class FALKON_EXPORT AutoFill : public QObject { Q_OBJECT public: explicit AutoFill(QObject* parent = 0); PasswordManager* passwordManager() const; void loadSettings(); bool isStored(const QUrl &url); bool isStoringEnabled(const QUrl &url); void blockStoringforUrl(const QUrl &url); QVector getFormData(const QUrl &url); QVector getAllFormData(); void updateLastUsed(PasswordEntry &data); void addEntry(const QUrl &url, const QString &name, const QString &pass); void addEntry(const QUrl &url, const PageFormData &formData); void updateEntry(const QUrl &url, const QString &name, const QString &pass); bool updateEntry(const PasswordEntry &entry); void removeEntry(const PasswordEntry &entry); void removeAllEntries(); void saveForm(WebPage *page, const QUrl &frameUrl, const PageFormData &formData); QVector completePage(WebPage *page, const QUrl &frameUrl); QByteArray exportPasswords(); bool importPasswords(const QByteArray &data); private: PasswordManager* m_manager; bool m_isStoring; QPointer m_lastNotification; WebPage *m_lastNotificationPage = nullptr; }; #endif // AUTOFILL_H diff --git a/src/lib/autofill/autofillicon.cpp b/src/lib/autofill/autofillicon.cpp index 1c4d0052..e45faa3b 100644 --- a/src/lib/autofill/autofillicon.cpp +++ b/src/lib/autofill/autofillicon.cpp @@ -1,68 +1,68 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2013-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "autofillicon.h" #include "autofillwidget.h" #include AutoFillIcon::AutoFillIcon(QWidget* parent) : ClickableLabel(parent) , m_view(0) { setObjectName("locationbar-autofillicon"); setCursor(Qt::PointingHandCursor); setToolTip(AutoFillWidget::tr("Choose username to login")); setFocusPolicy(Qt::ClickFocus); connect(this, SIGNAL(clicked(QPoint)), this, SLOT(iconClicked())); } void AutoFillIcon::setWebView(WebView* view) { m_view = view; } void AutoFillIcon::setFormData(const QVector &data) { m_data = data; } void AutoFillIcon::iconClicked() { if (!m_view) { return; } AutoFillWidget* widget = new AutoFillWidget(m_view, this); widget->setFormData(m_data); widget->showAt(parentWidget()); } void AutoFillIcon::contextMenuEvent(QContextMenuEvent* ev) { // Prevent propagating to LocationBar ev->accept(); } void AutoFillIcon::mousePressEvent(QMouseEvent* ev) { ClickableLabel::mousePressEvent(ev); // Prevent propagating to LocationBar ev->accept(); } diff --git a/src/lib/autofill/autofillicon.h b/src/lib/autofill/autofillicon.h index 1a183cf4..1f62698e 100644 --- a/src/lib/autofill/autofillicon.h +++ b/src/lib/autofill/autofillicon.h @@ -1,50 +1,50 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2013-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef AUTOFILLICON_H #define AUTOFILLICON_H #include "qzcommon.h" #include "clickablelabel.h" #include "passwordmanager.h" class WebView; -class QUPZILLA_EXPORT AutoFillIcon : public ClickableLabel +class FALKON_EXPORT AutoFillIcon : public ClickableLabel { Q_OBJECT public: explicit AutoFillIcon(QWidget* parent = 0); void setWebView(WebView* view); void setFormData(const QVector &data); private slots: void iconClicked(); private: void contextMenuEvent(QContextMenuEvent* ev); void mousePressEvent(QMouseEvent* ev); WebView* m_view; QVector m_data; }; #endif // AUTOFILLICON_H diff --git a/src/lib/autofill/autofillnotification.cpp b/src/lib/autofill/autofillnotification.cpp index a62ee24f..3c8524aa 100644 --- a/src/lib/autofill/autofillnotification.cpp +++ b/src/lib/autofill/autofillnotification.cpp @@ -1,90 +1,90 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "autofillnotification.h" #include "ui_autofillnotification.h" #include "autofill.h" #include "mainapplication.h" #include "animatedwidget.h" #include "iconprovider.h" AutoFillNotification::AutoFillNotification(const QUrl &url, const PageFormData &formData, const PasswordEntry &updateData) : AnimatedWidget(AnimatedWidget::Down, 300, 0) , ui(new Ui::AutoFillNotification) , m_url(url) , m_formData(formData) , m_updateData(updateData) { setAutoFillBackground(true); setAttribute(Qt::WA_DeleteOnClose); ui->setupUi(widget()); ui->closeButton->setIcon(IconProvider::standardIcon(QStyle::SP_DialogCloseButton)); QString hostPart; QString userPart; if (!url.host().isEmpty()) { hostPart = tr("on %1").arg(url.host()); } if (!m_formData.username.isEmpty()) { userPart = tr("for %1").arg(m_formData.username); } if (m_updateData.isValid()) { - ui->label->setText(tr("Do you want QupZilla to update saved password %1?").arg(userPart)); + ui->label->setText(tr("Do you want Falkon to update saved password %1?").arg(userPart)); ui->remember->setVisible(false); ui->never->setVisible(false); } else { - ui->label->setText(tr("Do you want QupZilla to remember the password %1 %2?").arg(userPart, hostPart)); + ui->label->setText(tr("Do you want Falkon to remember the password %1 %2?").arg(userPart, hostPart)); ui->update->setVisible(false); } connect(ui->update, SIGNAL(clicked()), this, SLOT(update())); connect(ui->remember, SIGNAL(clicked()), this, SLOT(remember())); connect(ui->never, SIGNAL(clicked()), this, SLOT(never())); connect(ui->notnow, SIGNAL(clicked()), this, SLOT(hide())); connect(ui->closeButton, SIGNAL(clicked()), this, SLOT(hide())); startAnimation(); } void AutoFillNotification::update() { mApp->autoFill()->updateEntry(m_updateData); hide(); } void AutoFillNotification::never() { mApp->autoFill()->blockStoringforUrl(m_url); hide(); } void AutoFillNotification::remember() { mApp->autoFill()->addEntry(m_url, m_formData); hide(); } AutoFillNotification::~AutoFillNotification() { delete ui; } diff --git a/src/lib/autofill/autofillnotification.h b/src/lib/autofill/autofillnotification.h index 2b5de56b..f519b17b 100644 --- a/src/lib/autofill/autofillnotification.h +++ b/src/lib/autofill/autofillnotification.h @@ -1,58 +1,58 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef AUTOFILLNOTIFICATION_H #define AUTOFILLNOTIFICATION_H #include #include "qzcommon.h" #include "animatedwidget.h" #include "passwordmanager.h" #include "autofill.h" namespace Ui { class AutoFillNotification; } class AnimatedWidget; -class QUPZILLA_EXPORT AutoFillNotification : public AnimatedWidget +class FALKON_EXPORT AutoFillNotification : public AnimatedWidget { Q_OBJECT public: explicit AutoFillNotification(const QUrl &url, const PageFormData &formData, const PasswordEntry &updateData); ~AutoFillNotification(); private slots: void update(); void remember(); void never(); private: Ui::AutoFillNotification* ui; QUrl m_url; PageFormData m_formData; PasswordEntry m_updateData; }; #endif // AUTOFILLNOTIFICATION_H diff --git a/src/lib/autofill/autofillwidget.cpp b/src/lib/autofill/autofillwidget.cpp index 9e5f39d1..c85a46a6 100644 --- a/src/lib/autofill/autofillwidget.cpp +++ b/src/lib/autofill/autofillwidget.cpp @@ -1,79 +1,79 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2013-2016 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "autofillwidget.h" #include "ui_autofillwidget.h" #include "autofill.h" #include "qztools.h" #include "webview.h" #include "webpage.h" #include "scripts.h" #include AutoFillWidget::AutoFillWidget(WebView* view, QWidget* parent) : LocationBarPopup(parent) , ui(new Ui::AutoFillWidget) , m_view(view) { ui->setupUi(this); } void AutoFillWidget::setFormData(const QVector &data) { m_data = data; for (int i = 0; i < data.count(); ++i) { const PasswordEntry d = data.at(i); if (d.username.isEmpty()) { continue; } QPushButton* button = new QPushButton(this); button->setIcon(QIcon(":icons/other/login.png")); button->setStyleSheet("text-align:left;font-weight:bold;"); button->setText(d.username); button->setProperty("data-index", i); button->setFlat(true); ui->gridLayout->addWidget(button, i, 0); connect(button, SIGNAL(clicked()), this, SLOT(loginToPage())); } } void AutoFillWidget::loginToPage() { QPushButton* button = qobject_cast(sender()); if (!button || !m_view) { return; } bool ok; int index = button->property("data-index").toInt(&ok); if (ok && QzTools::containsIndex(m_data, index)) { const PasswordEntry entry = m_data.at(index); m_view->page()->runJavaScript(Scripts::completeFormData(entry.data), WebPage::SafeJsWorld); } close(); } AutoFillWidget::~AutoFillWidget() { delete ui; } diff --git a/src/lib/autofill/autofillwidget.h b/src/lib/autofill/autofillwidget.h index 2dc43691..2e246b5a 100644 --- a/src/lib/autofill/autofillwidget.h +++ b/src/lib/autofill/autofillwidget.h @@ -1,55 +1,55 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2013-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef AUTOFILLWIDGET_H #define AUTOFILLWIDGET_H #include #include #include "qzcommon.h" #include "locationbarpopup.h" namespace Ui { class AutoFillWidget; } class WebView; struct PasswordEntry; -class QUPZILLA_EXPORT AutoFillWidget : public LocationBarPopup +class FALKON_EXPORT AutoFillWidget : public LocationBarPopup { Q_OBJECT public: explicit AutoFillWidget(WebView* view, QWidget* parent = 0); ~AutoFillWidget(); void setFormData(const QVector &data); private slots: void loginToPage(); private: Ui::AutoFillWidget* ui; WebView* m_view; QVector m_data; }; #endif // AUTOFILLWIDGET_H diff --git a/src/lib/autofill/passwordbackends/databaseencryptedpasswordbackend.cpp b/src/lib/autofill/passwordbackends/databaseencryptedpasswordbackend.cpp index 5ecdbb51..2cda02b9 100644 --- a/src/lib/autofill/passwordbackends/databaseencryptedpasswordbackend.cpp +++ b/src/lib/autofill/passwordbackends/databaseencryptedpasswordbackend.cpp @@ -1,703 +1,703 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2013-2014 S. Razi Alavizadeh * Copyright (C) 2013-2016 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "databaseencryptedpasswordbackend.h" #include "mainapplication.h" #include "autofill.h" #include "aesinterface.h" #include "browserwindow.h" #include "ui_masterpassworddialog.h" #include #include #include -#define INTERNAL_SERVER_ID QLatin1String("qupzilla.internal") +#define INTERNAL_SERVER_ID QLatin1String("falkon.internal") DatabaseEncryptedPasswordBackend::DatabaseEncryptedPasswordBackend() : PasswordBackend() , m_stateOfMasterPassword(UnKnownState) , m_askPasswordDialogVisible(false) , m_askMasterPassword(false) { QSqlDatabase db = QSqlDatabase::database(); if (!db.tables().contains(QLatin1String("autofill_encrypted"))) { db.exec("CREATE TABLE autofill_encrypted (data_encrypted TEXT, id INTEGER PRIMARY KEY," "password_encrypted TEXT, server TEXT, username_encrypted TEXT, last_used NUMERIC)"); db.exec("CREATE INDEX autofillEncryptedServer ON autofill_encrypted(server ASC)"); } } DatabaseEncryptedPasswordBackend::~DatabaseEncryptedPasswordBackend() { } QVector DatabaseEncryptedPasswordBackend::getEntries(const QUrl &url) { QVector list; AesInterface aesDecryptor; const QString host = PasswordManager::createHost(url); QSqlQuery query; query.prepare("SELECT id, username_encrypted, password_encrypted, data_encrypted FROM autofill_encrypted " "WHERE server=? ORDER BY last_used DESC"); query.addBindValue(host); query.exec(); if (query.next() && hasPermission()) { do { PasswordEntry data; data.id = query.value(0); data.host = host; data.username = query.value(1).toString(); data.password = query.value(2).toString(); data.data = query.value(3).toByteArray(); if (decryptPasswordEntry(data, &aesDecryptor)) { list.append(data); } } while (query.next()); } return list; } QVector DatabaseEncryptedPasswordBackend::getAllEntries() { QVector list; AesInterface aesDecryptor; QSqlQuery query; query.exec("SELECT id, server, username_encrypted, password_encrypted, data_encrypted FROM autofill_encrypted"); if (query.next() && hasPermission()) { do { PasswordEntry data; data.id = query.value(0); data.host = query.value(1).toString(); if (data.host == INTERNAL_SERVER_ID) { continue; } data.username = query.value(2).toString(); data.password = query.value(3).toString(); data.data = query.value(4).toByteArray(); if (decryptPasswordEntry(data, &aesDecryptor)) { list.append(data); } } while (query.next()); } return list; } void DatabaseEncryptedPasswordBackend::setActive(bool active) { if (active == isActive()) { return; } PasswordBackend::setActive(active); if (active) { setAskMasterPasswordState(isMasterPasswordSetted()); if (!isMasterPasswordSetted()) { // master-password is not setted this backend needs master-password showMasterPasswordDialog(); } } else { // maybe ask from user for decrypting data // remove password from memory m_masterPassword.clear(); setAskMasterPasswordState(isMasterPasswordSetted()); } } void DatabaseEncryptedPasswordBackend::addEntry(const PasswordEntry &entry) { // Data is empty only for HTTP/FTP authorization if (entry.data.isEmpty()) { // Multiple-usernames for HTTP/FTP authorization not supported QSqlQuery query; query.prepare("SELECT username_encrypted FROM autofill_encrypted WHERE server=?"); query.addBindValue(entry.host); query.exec(); if (query.next()) { return; } } PasswordEntry encryptedEntry = entry; AesInterface aesEncryptor; if (hasPermission() && encryptPasswordEntry(encryptedEntry, &aesEncryptor)) { QSqlQuery query; query.prepare("INSERT INTO autofill_encrypted (server, data_encrypted, username_encrypted, password_encrypted, last_used) " "VALUES (?,?,?,?,strftime('%s', 'now'))"); query.bindValue(0, encryptedEntry.host); query.bindValue(1, encryptedEntry.data); query.bindValue(2, encryptedEntry.username); query.bindValue(3, encryptedEntry.password); query.exec(); } } bool DatabaseEncryptedPasswordBackend::updateEntry(const PasswordEntry &entry) { AesInterface aesEncryptor; PasswordEntry encryptedEntry = entry; if (hasPermission() && encryptPasswordEntry(encryptedEntry, &aesEncryptor)) { QSqlQuery query; // Data is empty only for HTTP/FTP authorization if (entry.data.isEmpty()) { query.prepare("UPDATE autofill_encrypted SET username_encrypted=?, password_encrypted=? WHERE server=?"); query.bindValue(0, encryptedEntry.username); query.bindValue(1, encryptedEntry.password); query.bindValue(2, encryptedEntry.host); } else { query.prepare("UPDATE autofill_encrypted SET data_encrypted=?, username_encrypted=?, password_encrypted=? WHERE id=?"); query.addBindValue(encryptedEntry.data); query.addBindValue(encryptedEntry.username); query.addBindValue(encryptedEntry.password); query.addBindValue(encryptedEntry.id); } return query.exec(); } return false; } void DatabaseEncryptedPasswordBackend::updateLastUsed(PasswordEntry &entry) { QSqlQuery query; query.prepare("UPDATE autofill_encrypted SET last_used=strftime('%s', 'now') WHERE id=?"); query.addBindValue(entry.id); query.exec(); } void DatabaseEncryptedPasswordBackend::removeEntry(const PasswordEntry &entry) { if (!hasPermission()) { return; } QSqlQuery query; query.prepare("DELETE FROM autofill_encrypted WHERE id=?"); query.addBindValue(entry.id); query.exec(); m_stateOfMasterPassword = UnKnownState; if (someDataFromDatabase().isEmpty()) { updateSampleData(m_masterPassword); } } void DatabaseEncryptedPasswordBackend::removeAll() { if (!hasPermission()) { return; } QSqlQuery query; query.prepare("DELETE FROM autofill_encrypted"); query.exec(); m_stateOfMasterPassword = PasswordIsSetted; updateSampleData(m_masterPassword); } QString DatabaseEncryptedPasswordBackend::name() const { return AutoFill::tr("Database (encrypted)"); } bool DatabaseEncryptedPasswordBackend::hasSettings() const { return true; } void DatabaseEncryptedPasswordBackend::showSettings(QWidget* parent) { MasterPasswordDialog* masterPasswordDialog = new MasterPasswordDialog(this, parent); masterPasswordDialog->showSettingPage(); } bool DatabaseEncryptedPasswordBackend::isMasterPasswordSetted() { if (m_stateOfMasterPassword == UnKnownState) { m_stateOfMasterPassword = someDataFromDatabase().isEmpty() ? PasswordIsNotSetted : PasswordIsSetted; } return m_stateOfMasterPassword == PasswordIsSetted; } QByteArray DatabaseEncryptedPasswordBackend::masterPassword() const { return m_masterPassword; } bool DatabaseEncryptedPasswordBackend::hasPermission() { if (!m_askMasterPassword) { return true; } if (m_askPasswordDialogVisible) { return false; } m_askPasswordDialogVisible = true; AskMasterPassword* dialog = new AskMasterPassword(this); bool authorized = dialog->exec() == QDialog::Accepted; m_askPasswordDialogVisible = false; return authorized; } bool DatabaseEncryptedPasswordBackend::isPasswordVerified(const QByteArray &password) { if (password.isEmpty()) { return false; } if (m_masterPassword == password) { return true; } else if (!m_masterPassword.isEmpty()) { return false; } else { // m_masterPassword is empty we need to check entered password with // decoding some data by it and then save it to m_masterPassword AesInterface aes; aes.decrypt(someDataFromDatabase(), password); if (aes.isOk()) { m_masterPassword = password; return true; } } return false; } bool DatabaseEncryptedPasswordBackend::decryptPasswordEntry(PasswordEntry &entry, AesInterface* aesInterface) { entry.username = QString::fromUtf8(aesInterface->decrypt(entry.username.toUtf8(), m_masterPassword)); entry.password = QString::fromUtf8(aesInterface->decrypt(entry.password.toUtf8(), m_masterPassword)); entry.data = aesInterface->decrypt(entry.data, m_masterPassword); return aesInterface->isOk(); } bool DatabaseEncryptedPasswordBackend::encryptPasswordEntry(PasswordEntry &entry, AesInterface* aesInterface) { entry.username = QString::fromUtf8(aesInterface->encrypt(entry.username.toUtf8(), m_masterPassword)); entry.password = QString::fromUtf8(aesInterface->encrypt(entry.password.toUtf8(), m_masterPassword)); entry.data = aesInterface->encrypt(entry.data, m_masterPassword); return aesInterface->isOk(); } void DatabaseEncryptedPasswordBackend::showMasterPasswordDialog() { MasterPasswordDialog* masterPasswordDialog = new MasterPasswordDialog(this, mApp->getWindow()); masterPasswordDialog->showSetMasterPasswordPage(); masterPasswordDialog->delayedExec(); } void DatabaseEncryptedPasswordBackend::tryToChangeMasterPassword(const QByteArray &newPassword) { if (m_masterPassword == newPassword) { return; } if (newPassword.isEmpty()) { removeMasterPassword(); return; } encryptDataBaseTableOnFly(m_masterPassword, newPassword); m_masterPassword = newPassword; updateSampleData(m_masterPassword); } void DatabaseEncryptedPasswordBackend::removeMasterPassword() { if (!m_masterPassword.isEmpty()) { encryptDataBaseTableOnFly(m_masterPassword, QByteArray()); m_masterPassword.clear(); updateSampleData(QByteArray()); } } void DatabaseEncryptedPasswordBackend::setAskMasterPasswordState(bool ask) { m_askMasterPassword = ask; } void DatabaseEncryptedPasswordBackend::encryptDataBaseTableOnFly(const QByteArray &decryptorPassword, const QByteArray &encryptorPassword) { if (encryptorPassword == decryptorPassword) { return; } QSqlQuery query; query.prepare("SELECT id, data_encrypted, password_encrypted, username_encrypted, server FROM autofill_encrypted"); query.exec(); AesInterface encryptor; AesInterface decryptor; while (query.next()) { QString server = query.value(4).toString(); if (server == INTERNAL_SERVER_ID) { continue; } int id = query.value(0).toInt(); QByteArray data = query.value(1).toString().toUtf8(); QByteArray password = query.value(2).toString().toUtf8(); QByteArray username = query.value(3).toString().toUtf8(); if (!decryptorPassword.isEmpty()) { data = decryptor.decrypt(data, decryptorPassword); password = decryptor.decrypt(password, decryptorPassword); username = decryptor.decrypt(username, decryptorPassword); } if (!encryptorPassword.isEmpty()) { data = encryptor.encrypt(data, encryptorPassword); password = encryptor.encrypt(password, encryptorPassword); username = encryptor.encrypt(username, encryptorPassword); } QSqlQuery updateQuery; updateQuery.prepare("UPDATE autofill_encrypted SET data_encrypted = ?, password_encrypted = ?, username_encrypted = ? WHERE id = ?"); updateQuery.addBindValue(data); updateQuery.addBindValue(password); updateQuery.addBindValue(username); updateQuery.addBindValue(id); updateQuery.exec(); } } QByteArray DatabaseEncryptedPasswordBackend::someDataFromDatabase() { if (m_stateOfMasterPassword != UnKnownState && !m_someDataStoredOnDataBase.isEmpty()) { return m_someDataStoredOnDataBase; } QSqlQuery query; query.prepare("SELECT password_encrypted, data_encrypted, username_encrypted FROM autofill_encrypted"); query.exec(); QByteArray someData; if (query.next()) { int i = 0; while (someData.isEmpty()) { if (i > 2) { if (query.next()) { i = 0; continue; } else { break; } } someData = query.value(i).toByteArray(); ++i; } } m_someDataStoredOnDataBase = someData; return m_someDataStoredOnDataBase; } void DatabaseEncryptedPasswordBackend::updateSampleData(const QByteArray &password) { QSqlQuery query; query.prepare("SELECT id FROM autofill_encrypted WHERE server = ?"); query.addBindValue(INTERNAL_SERVER_ID); query.exec(); if (!password.isEmpty()) { AesInterface aes; m_someDataStoredOnDataBase = aes.encrypt(AesInterface::createRandomData(16), password); if (query.next()) { query.prepare("UPDATE autofill_encrypted SET password_encrypted = ? WHERE server=?"); } else { query.prepare("INSERT INTO autofill_encrypted (password_encrypted, server) VALUES (?,?)"); } query.addBindValue(QString::fromUtf8(m_someDataStoredOnDataBase)); query.addBindValue(INTERNAL_SERVER_ID); query.exec(); m_stateOfMasterPassword = PasswordIsSetted; } else if (query.next()) { query.prepare("DELETE FROM autofill_encrypted WHERE server = ?"); query.addBindValue(INTERNAL_SERVER_ID); query.exec(); m_stateOfMasterPassword = PasswordIsNotSetted; m_someDataStoredOnDataBase.clear(); return; } } /****************************** * MasterPasswordDialog class * ******************************/ #include MasterPasswordDialog::MasterPasswordDialog(DatabaseEncryptedPasswordBackend* backend, QWidget* parent) : QDialog(parent, Qt::WindowStaysOnTopHint | Qt::MSWindowsFixedSizeDialogHint) , ui(new Ui::MasterPasswordDialog) , m_backend(backend) { setAttribute(Qt::WA_DeleteOnClose, true); ui->setupUi(this); ui->currentPassword->setVisible(m_backend->isMasterPasswordSetted()); ui->labelCurrentPassword->setVisible(m_backend->isMasterPasswordSetted()); connect(ui->setMasterPassword, SIGNAL(clicked()), this, SLOT(showSetMasterPasswordPage())); connect(ui->clearMasterPassword, SIGNAL(clicked()), this, SLOT(clearMasterPasswordAndConvert())); connect(ui->buttonBox, SIGNAL(rejected()), this, SLOT(reject())); connect(ui->buttonBoxMasterPassword, SIGNAL(rejected()), this, SLOT(reject())); connect(ui->buttonBoxMasterPassword, SIGNAL(accepted()), this, SLOT(accept())); } MasterPasswordDialog::~MasterPasswordDialog() { delete ui; } void MasterPasswordDialog::delayedExec() { QTimer::singleShot(0, this, SLOT(exec())); } void MasterPasswordDialog::accept() { if (ui->stackedWidget->currentIndex() != 1) { QDialog::accept(); return; } QByteArray currentPassField = AesInterface::passwordToHash(ui->currentPassword->text()); if (m_backend->isMasterPasswordSetted() && !m_backend->isPasswordVerified(currentPassField)) { QMessageBox::information(this, tr("Warning!"), tr("You entered a wrong password!")); return; } if (ui->newPassword->text() != ui->confirmPassword->text()) { QMessageBox::information(this, tr("Warning!"), tr("New/Confirm password fields do not match!")); return; } if (ui->newPassword->text().isEmpty()) { if (!m_backend->isMasterPasswordSetted()) { return; } clearMasterPasswordAndConvert(false); } else { // for security reason we don't save master-password as plain in memory QByteArray newPassField = AesInterface::passwordToHash(ui->newPassword->text()); if (m_backend->masterPassword() != newPassField) { m_backend->tryToChangeMasterPassword(newPassField); } } QDialog::accept(); } void MasterPasswordDialog::reject() { QDialog::reject(); if (m_backend->isActive() && !m_backend->isMasterPasswordSetted()) { // master password not setted QMessageBox::information(this, AutoFill::tr("Warning!"), AutoFill::tr("This backend needs a master password to be set! " - "QupZilla just switches to its default backend")); + "Falkon just switches to its default backend")); // active default backend mApp->autoFill()->passwordManager()->switchBackend("database"); return; } } void MasterPasswordDialog::showSettingPage() { ui->stackedWidget->setCurrentIndex(0); delayedExec(); } void MasterPasswordDialog::showSetMasterPasswordPage() { ui->stackedWidget->setCurrentIndex(1); } void MasterPasswordDialog::clearMasterPasswordAndConvert(bool forcedAskPass) { if (QMessageBox::information(this, tr("Warning!"), tr("Are you sure you want to clear master password and decrypt data?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) { reject(); return; } if (forcedAskPass) { m_backend->setAskMasterPasswordState(true); } if (m_backend->hasPermission()) { QVector list = m_backend->getAllEntries(); PasswordBackend* databaseBackend = mApp->autoFill()->passwordManager()->availableBackends().value("database"); if (!databaseBackend) { return; } QVector databaseList = databaseBackend->getAllEntries(); bool allDataMoved = true; foreach (const PasswordEntry &entry, list) { bool sameEntry = false; foreach (const PasswordEntry &dbEntry, databaseList) { sameEntry = samePasswordEntry(dbEntry, entry); if (sameEntry) { allDataMoved = false; break; } } if (!sameEntry) { databaseBackend->addEntry(entry); m_backend->removeEntry(entry); } } if (allDataMoved) { m_backend->removeAll(); m_backend->removeMasterPassword(); m_backend->setAskMasterPasswordState(false); mApp->autoFill()->passwordManager()->switchBackend("database"); } else { QMessageBox::information(this, tr("Warning!"), tr("Some data has not been decrypted. The master password was not cleared!")); mApp->autoFill()->passwordManager()->switchBackend("database"); } } reject(); } bool MasterPasswordDialog::samePasswordEntry(const PasswordEntry &entry1, const PasswordEntry &entry2) { // Multiple-usernames for HTTP/FTP authorization not supported if ((entry1.data.isEmpty() || entry2.data.isEmpty()) && entry1.host == entry2.host) { return true; } if (entry1.host != entry2.host || entry1.username != entry2.username) { return false; } return true; } AskMasterPassword::AskMasterPassword(DatabaseEncryptedPasswordBackend* backend, QWidget* parent) : QDialog(parent, Qt::WindowStaysOnTopHint | Qt::MSWindowsFixedSizeDialogHint) , m_backend(backend) { setWindowModality(Qt::ApplicationModal); setWindowTitle(AutoFill::tr("Enter Master Password")); QVBoxLayout* verticalLayout = new QVBoxLayout(this); QLabel* label = new QLabel(this); label->setText(AutoFill::tr("Permission is required, please enter Master Password:")); m_lineEdit = new QLineEdit(this); m_lineEdit->setEchoMode(QLineEdit::Password); m_buttonBox = new QDialogButtonBox(this); m_buttonBox->setStandardButtons(QDialogButtonBox::Cancel | QDialogButtonBox::Ok); m_labelWarning = new QLabel(this); m_labelWarning->setText(AutoFill::tr("Entered password is wrong!")); QPalette pal = m_labelWarning->palette(); pal.setBrush(QPalette::WindowText, Qt::red); m_labelWarning->setPalette(pal); m_labelWarning->hide(); verticalLayout->addWidget(label); verticalLayout->addWidget(m_lineEdit); verticalLayout->addWidget(m_labelWarning); verticalLayout->addWidget(m_buttonBox); setLayout(verticalLayout); connect(m_lineEdit, SIGNAL(returnPressed()), this, SLOT(verifyPassword())); connect(m_buttonBox, SIGNAL(accepted()), this, SLOT(verifyPassword())); connect(m_buttonBox, SIGNAL(rejected()), this, SLOT(reject())); setAttribute(Qt::WA_DeleteOnClose); } void AskMasterPassword::verifyPassword() { QByteArray enteredPassword = AesInterface::passwordToHash(m_lineEdit->text()); if (!m_backend->isPasswordVerified(enteredPassword)) { m_backend->setAskMasterPasswordState(true); m_labelWarning->show(); m_lineEdit->clear(); m_lineEdit->setFocus(); } else { m_backend->setAskMasterPasswordState(false); //TODO: start timer for reset ask state to true accept(); } } diff --git a/src/lib/autofill/passwordbackends/databaseencryptedpasswordbackend.h b/src/lib/autofill/passwordbackends/databaseencryptedpasswordbackend.h index b14d3dac..d4c53484 100644 --- a/src/lib/autofill/passwordbackends/databaseencryptedpasswordbackend.h +++ b/src/lib/autofill/passwordbackends/databaseencryptedpasswordbackend.h @@ -1,141 +1,141 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2013-2014 S. Razi Alavizadeh * Copyright (C) 2013-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef DATABASEENCRYPTEDPASSWORDBACKEND_H #define DATABASEENCRYPTEDPASSWORDBACKEND_H #include "passwordbackend.h" #include "qzcommon.h" #include class AesInterface; class MasterPasswordDialog; -class QUPZILLA_EXPORT DatabaseEncryptedPasswordBackend : public PasswordBackend +class FALKON_EXPORT DatabaseEncryptedPasswordBackend : public PasswordBackend { public: enum MasterPasswordState { PasswordIsSetted, PasswordIsNotSetted, UnKnownState = -1 }; explicit DatabaseEncryptedPasswordBackend(); ~DatabaseEncryptedPasswordBackend(); QVector getEntries(const QUrl &url); QVector getAllEntries(); void setActive(bool active); void addEntry(const PasswordEntry &entry); bool updateEntry(const PasswordEntry &entry); void updateLastUsed(PasswordEntry &entry); void removeEntry(const PasswordEntry &entry); void removeAll(); QString name() const; bool hasSettings() const; void showSettings(QWidget* parent); bool isMasterPasswordSetted(); QByteArray masterPassword() const; bool hasPermission(); bool isPasswordVerified(const QByteArray &password); bool decryptPasswordEntry(PasswordEntry &entry, AesInterface* aesInterface); bool encryptPasswordEntry(PasswordEntry &entry, AesInterface* aesInterface); void tryToChangeMasterPassword(const QByteArray &newPassword); void removeMasterPassword(); void setAskMasterPasswordState(bool ask); void encryptDataBaseTableOnFly(const QByteArray &decryptorPassword, const QByteArray &encryptorPassword); void updateSampleData(const QByteArray &password); void showMasterPasswordDialog(); private: QByteArray someDataFromDatabase(); MasterPasswordState m_stateOfMasterPassword; QByteArray m_someDataStoredOnDataBase; bool m_askPasswordDialogVisible; bool m_askMasterPassword; QByteArray m_masterPassword; }; namespace Ui { class MasterPasswordDialog; } class MasterPasswordDialog : public QDialog { Q_OBJECT public: explicit MasterPasswordDialog(DatabaseEncryptedPasswordBackend* backend, QWidget* parent = 0); ~MasterPasswordDialog(); void delayedExec(); public slots: void accept(); void reject(); void showSettingPage(); void showSetMasterPasswordPage(); void clearMasterPasswordAndConvert(bool forcedAskPass = true); bool samePasswordEntry(const PasswordEntry &entry1, const PasswordEntry &entry2); private: Ui::MasterPasswordDialog* ui; DatabaseEncryptedPasswordBackend* m_backend; }; class QDialogButtonBox; class QLineEdit; class QLabel; class AskMasterPassword : public QDialog { Q_OBJECT public: explicit AskMasterPassword(DatabaseEncryptedPasswordBackend* backend, QWidget* parent = 0); private slots: void verifyPassword(); private: DatabaseEncryptedPasswordBackend* m_backend; QDialogButtonBox* m_buttonBox; QLineEdit* m_lineEdit; QLabel* m_labelWarning; }; #endif // DATABASEENCRYPTEDPASSWORDBACKEND_H diff --git a/src/lib/autofill/passwordbackends/databasepasswordbackend.cpp b/src/lib/autofill/passwordbackends/databasepasswordbackend.cpp index 2914fe57..d51b52e4 100644 --- a/src/lib/autofill/passwordbackends/databasepasswordbackend.cpp +++ b/src/lib/autofill/passwordbackends/databasepasswordbackend.cpp @@ -1,150 +1,150 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2013-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "databasepasswordbackend.h" #include "mainapplication.h" #include "autofill.h" #include #include DatabasePasswordBackend::DatabasePasswordBackend() : PasswordBackend() { } QString DatabasePasswordBackend::name() const { return AutoFill::tr("Database (plaintext)"); } QVector DatabasePasswordBackend::getEntries(const QUrl &url) { const QString host = PasswordManager::createHost(url); QSqlQuery query; query.prepare("SELECT id, username, password, data FROM autofill " "WHERE server=? ORDER BY last_used DESC"); query.addBindValue(host); query.exec(); QVector list; while (query.next()) { PasswordEntry data; data.id = query.value(0); data.host = host; data.username = query.value(1).toString(); data.password = query.value(2).toString(); data.data = query.value(3).toByteArray(); list.append(data); } return list; } QVector DatabasePasswordBackend::getAllEntries() { QVector list; QSqlQuery query; query.exec("SELECT id, server, username, password, data FROM autofill"); while (query.next()) { PasswordEntry data; data.id = query.value(0); data.host = query.value(1).toString(); data.username = query.value(2).toString(); data.password = query.value(3).toString(); data.data = query.value(4).toByteArray(); list.append(data); } return list; } void DatabasePasswordBackend::addEntry(const PasswordEntry &entry) { // Data is empty only for HTTP/FTP authorization if (entry.data.isEmpty()) { // Multiple-usernames for HTTP/FTP authorization not supported QSqlQuery query; query.prepare("SELECT username FROM autofill WHERE server=?"); query.addBindValue(entry.host); query.exec(); if (query.next()) { return; } } QSqlQuery query; query.prepare("INSERT INTO autofill (server, data, username, password, last_used) " "VALUES (?,?,?,?,strftime('%s', 'now'))"); query.bindValue(0, entry.host); query.bindValue(1, entry.data); query.bindValue(2, entry.username); query.bindValue(3, entry.password); query.exec(); } bool DatabasePasswordBackend::updateEntry(const PasswordEntry &entry) { QSqlQuery query; // Data is empty only for HTTP/FTP authorization if (entry.data.isEmpty()) { query.prepare("UPDATE autofill SET username=?, password=? WHERE server=?"); query.bindValue(0, entry.username); query.bindValue(1, entry.password); query.bindValue(2, entry.host); } else { query.prepare("UPDATE autofill SET data=?, username=?, password=? WHERE id=?"); query.addBindValue(entry.data); query.addBindValue(entry.username); query.addBindValue(entry.password); query.addBindValue(entry.id); } return query.exec(); } void DatabasePasswordBackend::updateLastUsed(PasswordEntry &entry) { QSqlQuery query; query.prepare("UPDATE autofill SET last_used=strftime('%s', 'now') WHERE id=?"); query.addBindValue(entry.id); query.exec(); } void DatabasePasswordBackend::removeEntry(const PasswordEntry &entry) { QSqlQuery query; query.prepare("DELETE FROM autofill WHERE id=?"); query.addBindValue(entry.id); query.exec(); } void DatabasePasswordBackend::removeAll() { QSqlQuery query; query.prepare("DELETE FROM autofill"); query.exec(); } diff --git a/src/lib/autofill/passwordbackends/databasepasswordbackend.h b/src/lib/autofill/passwordbackends/databasepasswordbackend.h index 05415de1..d651f7a9 100644 --- a/src/lib/autofill/passwordbackends/databasepasswordbackend.h +++ b/src/lib/autofill/passwordbackends/databasepasswordbackend.h @@ -1,42 +1,42 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2013-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef DATABASEPASSWORDBACKEND_H #define DATABASEPASSWORDBACKEND_H #include "passwordbackend.h" #include "qzcommon.h" -class QUPZILLA_EXPORT DatabasePasswordBackend : public PasswordBackend +class FALKON_EXPORT DatabasePasswordBackend : public PasswordBackend { public: explicit DatabasePasswordBackend(); QString name() const; QVector getEntries(const QUrl &url); QVector getAllEntries(); void addEntry(const PasswordEntry &entry); bool updateEntry(const PasswordEntry &entry); void updateLastUsed(PasswordEntry &entry); void removeEntry(const PasswordEntry &entry); void removeAll(); }; #endif // DATABASEPASSWORDBACKEND_H diff --git a/src/lib/autofill/passwordbackends/passwordbackend.cpp b/src/lib/autofill/passwordbackends/passwordbackend.cpp index d6542ca6..b5fc5a95 100644 --- a/src/lib/autofill/passwordbackends/passwordbackend.cpp +++ b/src/lib/autofill/passwordbackends/passwordbackend.cpp @@ -1,43 +1,43 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2013-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "passwordbackend.h" PasswordBackend::PasswordBackend() : m_active(false) { } void PasswordBackend::setActive(bool active) { m_active = active; } bool PasswordBackend::isActive() const { return m_active; } bool PasswordBackend::hasSettings() const { return false; } void PasswordBackend::showSettings(QWidget* parent) { Q_UNUSED(parent) } diff --git a/src/lib/autofill/passwordbackends/passwordbackend.h b/src/lib/autofill/passwordbackends/passwordbackend.h index 2a5f0e3d..bd15df1b 100644 --- a/src/lib/autofill/passwordbackends/passwordbackend.h +++ b/src/lib/autofill/passwordbackends/passwordbackend.h @@ -1,54 +1,54 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2013-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef PASSWORDBACKEND_H #define PASSWORDBACKEND_H #include "passwordmanager.h" #include "qzcommon.h" class QWidget; -class QUPZILLA_EXPORT PasswordBackend +class FALKON_EXPORT PasswordBackend { public: explicit PasswordBackend(); virtual ~PasswordBackend() { } virtual QString name() const = 0; virtual QVector getEntries(const QUrl &url) = 0; virtual QVector getAllEntries() = 0; virtual void addEntry(const PasswordEntry &entry) = 0; virtual bool updateEntry(const PasswordEntry &entry) = 0; virtual void updateLastUsed(PasswordEntry &entry) = 0; virtual void removeEntry(const PasswordEntry &entry) = 0; virtual void removeAll() = 0; virtual void setActive(bool active); bool isActive() const; virtual bool hasSettings() const; virtual void showSettings(QWidget* parent); private: bool m_active; }; #endif // PASSWORDBACKEND_H diff --git a/src/lib/autofill/passwordmanager.cpp b/src/lib/autofill/passwordmanager.cpp index 7707f29c..ca0f1c84 100644 --- a/src/lib/autofill/passwordmanager.cpp +++ b/src/lib/autofill/passwordmanager.cpp @@ -1,214 +1,214 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2013-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "passwordmanager.h" #include "passwordbackends/passwordbackend.h" #include "passwordbackends/databasepasswordbackend.h" #include "passwordbackends/databaseencryptedpasswordbackend.h" #include "settings.h" #include #include static const int passwordEntryVersion = 2; QDataStream &operator <<(QDataStream &stream, const PasswordEntry &entry) { stream << passwordEntryVersion; stream << entry.host; stream << entry.id; stream << entry.username; stream << entry.password; stream << entry.data; stream << entry.updated; return stream; } QDataStream &operator >>(QDataStream &stream, PasswordEntry &entry) { int version; stream >> version; if (version != passwordEntryVersion) { return stream; } stream >> entry.host; stream >> entry.id; stream >> entry.username; stream >> entry.password; stream >> entry.data; stream >> entry.updated; return stream; } PasswordManager::PasswordManager(QObject* parent) : QObject(parent) , m_loaded(false) , m_backend(0) , m_databaseBackend(new DatabasePasswordBackend) , m_databaseEncryptedBackend(new DatabaseEncryptedPasswordBackend) { m_backends["database"] = m_databaseBackend; m_backends["database-encrypted"] = m_databaseEncryptedBackend; } void PasswordManager::loadSettings() { Settings settings; settings.beginGroup("PasswordManager"); QString backendId = settings.value("Backend", "database").toString(); settings.endGroup(); m_backend = m_backends[m_backends.contains(backendId) ? backendId : "database"]; m_backend->setActive(true); } QVector PasswordManager::getEntries(const QUrl &url) { ensureLoaded(); return m_backend->getEntries(url); } QVector PasswordManager::getAllEntries() { ensureLoaded(); return m_backend->getAllEntries(); } void PasswordManager::addEntry(const PasswordEntry &entry) { ensureLoaded(); m_backend->addEntry(entry); } bool PasswordManager::updateEntry(const PasswordEntry &entry) { ensureLoaded(); return m_backend->updateEntry(entry); } void PasswordManager::updateLastUsed(PasswordEntry &entry) { ensureLoaded(); m_backend->updateLastUsed(entry); } void PasswordManager::removeEntry(const PasswordEntry &entry) { ensureLoaded(); m_backend->removeEntry(entry); } void PasswordManager::removeAllEntries() { ensureLoaded(); m_backend->removeAll(); } QHash PasswordManager::availableBackends() { ensureLoaded(); return m_backends; } PasswordBackend* PasswordManager::activeBackend() { ensureLoaded(); return m_backend; } void PasswordManager::switchBackend(const QString &backendID) { PasswordBackend* backend = m_backends.value(backendID); if (!backend) { return; } m_backend->setActive(false); m_backend = backend; m_backend->setActive(true); Settings settings; settings.beginGroup("PasswordManager"); settings.setValue("Backend", backendID); settings.endGroup(); emit passwordBackendChanged(); } bool PasswordManager::registerBackend(const QString &id, PasswordBackend* backend) { if (m_backends.contains(id)) { return false; } m_backends[id] = backend; return true; } void PasswordManager::unregisterBackend(PasswordBackend* backend) { const QString key = m_backends.key(backend); m_backends.remove(key); if (m_backend == backend) { m_backend = m_databaseBackend; } } QString PasswordManager::createHost(const QUrl &url) { QString host = url.host(); if (host.isEmpty()) { host = url.toString(); } if (url.port() != -1) { host.append(QLatin1Char(':')); host.append(QString::number(url.port())); } return host; } QByteArray PasswordManager::urlEncodePassword(const QString &password) { // Exclude space to properly decode to + QByteArray encodedPass = QUrl::toPercentEncoding(password, " "); encodedPass.replace(' ', '+'); // space has to be encoded to + encodedPass.replace('~', "%7E"); // ~ is unreserved char, needs to be manually encoded return encodedPass; } void PasswordManager::ensureLoaded() { if (!m_loaded) { loadSettings(); m_loaded = true; } } PasswordManager::~PasswordManager() { delete m_databaseBackend; delete m_databaseEncryptedBackend; } diff --git a/src/lib/autofill/passwordmanager.h b/src/lib/autofill/passwordmanager.h index c67a07dc..a216e770 100644 --- a/src/lib/autofill/passwordmanager.h +++ b/src/lib/autofill/passwordmanager.h @@ -1,106 +1,106 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2013-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef PASSWORDMANAGER_H #define PASSWORDMANAGER_H #include #include #include #include "qzcommon.h" class PasswordBackend; class DatabasePasswordBackend; class DatabaseEncryptedPasswordBackend; -struct QUPZILLA_EXPORT PasswordEntry { +struct FALKON_EXPORT PasswordEntry { QVariant id; QString host; QString username; QString password; QByteArray data; int updated; PasswordEntry() : updated(-1) { } bool isValid() const { return !password.isEmpty() && !host.isEmpty(); } bool operator==(const PasswordEntry &other) const { return id == other.id; } bool operator<(const PasswordEntry &other) const { return updated > other.updated; } - friend QUPZILLA_EXPORT QDataStream &operator<<(QDataStream &stream, const PasswordEntry &entry); - friend QUPZILLA_EXPORT QDataStream &operator>>(QDataStream &stream, PasswordEntry &entry); + friend FALKON_EXPORT QDataStream &operator<<(QDataStream &stream, const PasswordEntry &entry); + friend FALKON_EXPORT QDataStream &operator>>(QDataStream &stream, PasswordEntry &entry); }; -class QUPZILLA_EXPORT PasswordManager : public QObject +class FALKON_EXPORT PasswordManager : public QObject { Q_OBJECT public: explicit PasswordManager(QObject* parent = 0); ~PasswordManager(); void loadSettings(); QVector getEntries(const QUrl &url); QVector getAllEntries(); void addEntry(const PasswordEntry &entry); bool updateEntry(const PasswordEntry &entry); void updateLastUsed(PasswordEntry &entry); void removeEntry(const PasswordEntry &entry); void removeAllEntries(); QHash availableBackends(); PasswordBackend* activeBackend(); void switchBackend(const QString &backendID); bool registerBackend(const QString &id, PasswordBackend* backend); void unregisterBackend(PasswordBackend* backend); static QString createHost(const QUrl &url); static QByteArray urlEncodePassword(const QString &password); private: void ensureLoaded(); bool m_loaded; PasswordBackend* m_backend; DatabasePasswordBackend* m_databaseBackend; DatabaseEncryptedPasswordBackend* m_databaseEncryptedBackend; QHash m_backends; signals: void passwordBackendChanged(); }; // Hint to QVector to use std::realloc on item moving Q_DECLARE_TYPEINFO(PasswordEntry, Q_MOVABLE_TYPE); Q_DECLARE_METATYPE(PasswordEntry) #endif // PASSWORDMANAGER_H diff --git a/src/lib/bookmarks/bookmarkitem.cpp b/src/lib/bookmarks/bookmarkitem.cpp index 4c673d2e..eac30bbc 100644 --- a/src/lib/bookmarks/bookmarkitem.cpp +++ b/src/lib/bookmarks/bookmarkitem.cpp @@ -1,231 +1,231 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "bookmarkitem.h" #include "iconprovider.h" BookmarkItem::BookmarkItem(BookmarkItem::Type type, BookmarkItem* parent) : m_type(type) , m_parent(parent) , m_visitCount(0) , m_expanded(false) , m_sidebarExpanded(false) { if (m_parent) { parent->addChild(this); } } BookmarkItem::~BookmarkItem() { qDeleteAll(m_children); } BookmarkItem::Type BookmarkItem::type() const { return m_type; } void BookmarkItem::setType(BookmarkItem::Type type) { m_type = type; } bool BookmarkItem::isFolder() const { return m_type == Folder; } bool BookmarkItem::isUrl() const { return m_type == Url; } bool BookmarkItem::isSeparator() const { return m_type == Separator; } BookmarkItem* BookmarkItem::parent() const { return m_parent; } QList BookmarkItem::children() const { return m_children; } QIcon BookmarkItem::icon() { // Cache icon for 20 seconds const int iconCacheTime = 20 * 1000; switch (m_type) { case Url: if (m_iconTime.isNull() || m_iconTime.elapsed() > iconCacheTime) { m_icon = IconProvider::iconForUrl(m_url); m_iconTime.restart(); } return m_icon; case Folder: return IconProvider::standardIcon(QStyle::SP_DirIcon); default: return QIcon(); } } void BookmarkItem::setIcon(const QIcon &icon) { m_icon = icon; } QString BookmarkItem::urlString() const { return QString::fromUtf8(m_url.toEncoded()); } QUrl BookmarkItem::url() const { return m_url; } void BookmarkItem::setUrl(const QUrl &url) { m_url = url; } QString BookmarkItem::title() const { return m_title; } void BookmarkItem::setTitle(const QString &title) { m_title = title; } QString BookmarkItem::description() const { return m_description; } void BookmarkItem::setDescription(const QString &description) { m_description = description; } QString BookmarkItem::keyword() const { return m_keyword; } void BookmarkItem::setKeyword(const QString &keyword) { m_keyword = keyword; } int BookmarkItem::visitCount() const { return m_visitCount; } void BookmarkItem::setVisitCount(int count) { m_visitCount = count; } void BookmarkItem::updateVisitCount() { m_visitCount++; } bool BookmarkItem::isExpanded() const { return m_type == Root ? true : m_expanded; } void BookmarkItem::setExpanded(bool expanded) { m_expanded = expanded; } bool BookmarkItem::isSidebarExpanded() const { return m_type == Root ? true : m_sidebarExpanded; } void BookmarkItem::setSidebarExpanded(bool expanded) { m_sidebarExpanded = expanded; } void BookmarkItem::addChild(BookmarkItem* child, int index) { if (child->m_parent) { child->m_parent->removeChild(child); } child->m_parent = this; if (index < 0) { m_children.append(child); } else { m_children.insert(index, child); } } void BookmarkItem::removeChild(BookmarkItem* child) { child->m_parent = 0; m_children.removeOne(child); } BookmarkItem::Type BookmarkItem::typeFromString(const QString &string) { if (string == QLatin1String("url")) { return Url; } if (string == QLatin1String("folder")) { return Folder; } if (string == QLatin1String("separator")) { return Separator; } return Invalid; } QString BookmarkItem::typeToString(BookmarkItem::Type type) { switch (type) { case Url: return QString("url"); case Folder: return QString("folder"); case Separator: return QString("separator"); default: return QString("invalid"); } } diff --git a/src/lib/bookmarks/bookmarkitem.h b/src/lib/bookmarks/bookmarkitem.h index 25af10da..48e33cb9 100644 --- a/src/lib/bookmarks/bookmarkitem.h +++ b/src/lib/bookmarks/bookmarkitem.h @@ -1,106 +1,106 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef BOOKMARKITEM_H #define BOOKMARKITEM_H #include #include #include #include #include #include "qzcommon.h" -class QUPZILLA_EXPORT BookmarkItem +class FALKON_EXPORT BookmarkItem { public: enum Type { Root, Url, Folder, Separator, Invalid }; explicit BookmarkItem(Type type, BookmarkItem* parent = 0); ~BookmarkItem(); Type type() const; void setType(Type type); bool isFolder() const; bool isUrl() const; bool isSeparator() const; BookmarkItem* parent() const; QList children() const; QIcon icon(); void setIcon(const QIcon &icon); QString urlString() const; QUrl url() const; void setUrl(const QUrl &url); QString title() const; void setTitle(const QString &title); QString description() const; void setDescription(const QString &description); QString keyword() const; void setKeyword(const QString &keyword); int visitCount() const; void setVisitCount(int count); // Increments visitCount() (may also update last load time when implemented) void updateVisitCount(); // Expanded state in Manager bool isExpanded() const; void setExpanded(bool expanded); // Expanded state in Sidebar bool isSidebarExpanded() const; void setSidebarExpanded(bool expanded); void addChild(BookmarkItem* child, int index = -1); void removeChild(BookmarkItem* child); static Type typeFromString(const QString &string); static QString typeToString(Type type); private: Type m_type; BookmarkItem* m_parent; QList m_children; QUrl m_url; QString m_title; QString m_description; QString m_keyword; QIcon m_icon; QTime m_iconTime; int m_visitCount; bool m_expanded; bool m_sidebarExpanded; }; #endif // BOOKMARKITEM_H diff --git a/src/lib/bookmarks/bookmarks.cpp b/src/lib/bookmarks/bookmarks.cpp index 747717ce..56768dfb 100644 --- a/src/lib/bookmarks/bookmarks.cpp +++ b/src/lib/bookmarks/bookmarks.cpp @@ -1,475 +1,475 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "bookmarks.h" #include "bookmarkitem.h" #include "bookmarksmodel.h" #include "bookmarkstools.h" #include "autosaver.h" #include "datapaths.h" #include "settings.h" #include "qztools.h" #include #include Bookmarks::Bookmarks(QObject* parent) : QObject(parent) , m_autoSaver(0) { m_autoSaver = new AutoSaver(this); connect(m_autoSaver, SIGNAL(save()), this, SLOT(saveSettings())); init(); loadSettings(); } Bookmarks::~Bookmarks() { m_autoSaver->saveIfNecessary(); delete m_root; } void Bookmarks::loadSettings() { Settings settings; settings.beginGroup("Bookmarks"); m_showOnlyIconsInToolbar = settings.value("showOnlyIconsInToolbar", false).toBool(); m_showOnlyTextInToolbar = settings.value("showOnlyTextInToolbar", false).toBool(); settings.endGroup(); } bool Bookmarks::showOnlyIconsInToolbar() const { return m_showOnlyIconsInToolbar; } bool Bookmarks::showOnlyTextInToolbar() const { return m_showOnlyTextInToolbar; } BookmarkItem* Bookmarks::rootItem() const { return m_root; } BookmarkItem* Bookmarks::toolbarFolder() const { return m_folderToolbar; } BookmarkItem* Bookmarks::menuFolder() const { return m_folderMenu; } BookmarkItem* Bookmarks::unsortedFolder() const { return m_folderUnsorted; } BookmarkItem* Bookmarks::lastUsedFolder() const { return m_lastFolder; } BookmarksModel* Bookmarks::model() const { return m_model; } bool Bookmarks::isBookmarked(const QUrl &url) { return !searchBookmarks(url).isEmpty(); } bool Bookmarks::canBeModified(BookmarkItem* item) const { Q_ASSERT(item); return item != m_root && item != m_folderToolbar && item != m_folderMenu && item != m_folderUnsorted; } QList Bookmarks::searchBookmarks(const QUrl &url) const { QList items; search(&items, m_root, url); return items; } QList Bookmarks::searchBookmarks(const QString &string, int limit, Qt::CaseSensitivity sensitive) const { QList items; search(&items, m_root, string, limit, sensitive); return items; } QList Bookmarks::searchKeyword(const QString &keyword) const { QList items; searchKeyword(&items, m_root, keyword); return items; } void Bookmarks::addBookmark(BookmarkItem* parent, BookmarkItem* item) { Q_ASSERT(parent); Q_ASSERT(parent->isFolder()); Q_ASSERT(item); insertBookmark(parent, parent->children().count(), item); } void Bookmarks::insertBookmark(BookmarkItem* parent, int row, BookmarkItem* item) { Q_ASSERT(parent); Q_ASSERT(parent->isFolder()); Q_ASSERT(item); m_lastFolder = parent; m_model->addBookmark(parent, row, item); emit bookmarkAdded(item); m_autoSaver->changeOccurred(); } bool Bookmarks::removeBookmark(BookmarkItem* item) { if (!canBeModified(item)) { return false; } m_model->removeBookmark(item); emit bookmarkRemoved(item); m_autoSaver->changeOccurred(); return true; } void Bookmarks::changeBookmark(BookmarkItem* item) { Q_ASSERT(item); emit bookmarkChanged(item); m_autoSaver->changeOccurred(); } void Bookmarks::setShowOnlyIconsInToolbar(bool state) { m_showOnlyIconsInToolbar = state; emit showOnlyIconsInToolbarChanged(state); m_autoSaver->changeOccurred(); } void Bookmarks::setShowOnlyTextInToolbar(bool state) { m_showOnlyTextInToolbar = state; emit showOnlyTextInToolbarChanged(state); m_autoSaver->changeOccurred(); } void Bookmarks::saveSettings() { Settings settings; settings.beginGroup("Bookmarks"); settings.setValue("showOnlyIconsInToolbar", m_showOnlyIconsInToolbar); settings.setValue("showOnlyTextInToolbar", m_showOnlyTextInToolbar); settings.endGroup(); saveBookmarks(); } void Bookmarks::init() { m_root = new BookmarkItem(BookmarkItem::Root); m_folderToolbar = new BookmarkItem(BookmarkItem::Folder, m_root); m_folderToolbar->setTitle(tr("Bookmarks Toolbar")); m_folderToolbar->setDescription(tr("Bookmarks located in Bookmarks Toolbar")); m_folderMenu = new BookmarkItem(BookmarkItem::Folder, m_root); m_folderMenu->setTitle(tr("Bookmarks Menu")); m_folderMenu->setDescription(tr("Bookmarks located in Bookmarks Menu")); m_folderUnsorted = new BookmarkItem(BookmarkItem::Folder, m_root); m_folderUnsorted->setTitle(tr("Unsorted Bookmarks")); m_folderUnsorted->setDescription(tr("All other bookmarks")); if (BookmarksTools::migrateBookmarksIfNecessary(this)) { // Bookmarks migrated just now, let's save them ASAP saveBookmarks(); } else { // Bookmarks don't need to be migrated, just load them as usual loadBookmarks(); } m_lastFolder = m_folderUnsorted; m_model = new BookmarksModel(m_root, this, this); } void Bookmarks::loadBookmarks() { const QString bookmarksFile = DataPaths::currentProfilePath() + QLatin1String("/bookmarks.json"); const QString backupFile = bookmarksFile + QLatin1String(".old"); QJsonParseError err; QJsonDocument json = QJsonDocument::fromJson(QzTools::readAllFileByteContents(bookmarksFile), &err); const QVariant res = json.toVariant(); if (err.error != QJsonParseError::NoError || res.type() != QVariant::Map) { if (QFile(bookmarksFile).exists()) { qWarning() << "Bookmarks::init() Error parsing bookmarks! Using default bookmarks!"; qWarning() << "Bookmarks::init() Your bookmarks have been backed up in" << backupFile; // Backup the user bookmarks QFile::remove(backupFile); QFile::copy(bookmarksFile, backupFile); } // Load default bookmarks json = QJsonDocument::fromJson(QzTools::readAllFileByteContents(QSL(":data/bookmarks.json")), &err); const QVariant data = json.toVariant(); Q_ASSERT(err.error == QJsonParseError::NoError); Q_ASSERT(data.type() == QVariant::Map); loadBookmarksFromMap(data.toMap().value("roots").toMap()); // Don't forget to save the bookmarks m_autoSaver->changeOccurred(); } else { loadBookmarksFromMap(res.toMap().value("roots").toMap()); } } void Bookmarks::saveBookmarks() { QVariantMap bookmarksMap; #define WRITE_FOLDER(name, mapName, folder) \ QVariantMap mapName; \ mapName.insert("children", writeBookmarks(folder)); \ mapName.insert("expanded", folder->isExpanded()); \ mapName.insert("expanded_sidebar", folder->isSidebarExpanded()); \ mapName.insert("name", folder->title()); \ mapName.insert("description", folder->description()); \ mapName.insert("type", "folder"); \ bookmarksMap.insert(name, mapName); WRITE_FOLDER("bookmark_bar", toolbarMap, m_folderToolbar) WRITE_FOLDER("bookmark_menu", menuMap, m_folderMenu) WRITE_FOLDER("other", unsortedMap, m_folderUnsorted) #undef WRITE_FOLDER QVariantMap map; map.insert("version", Qz::bookmarksVersion); map.insert("roots", bookmarksMap); const QJsonDocument json = QJsonDocument::fromVariant(map); const QByteArray data = json.toJson(); if (data.isEmpty()) { qWarning() << "Bookmarks::saveBookmarks() Error serializing bookmarks!"; return; } QSaveFile file(DataPaths::currentProfilePath() + QLatin1String("/bookmarks.json")); if (!file.open(QFile::WriteOnly)) { qWarning() << "Bookmarks::saveBookmarks() Error opening bookmarks file for writing!"; } file.write(data); file.commit(); } void Bookmarks::loadBookmarksFromMap(const QVariantMap &map) { #define READ_FOLDER(name, folder) \ readBookmarks(map.value(name).toMap().value("children").toList(), folder); \ folder->setExpanded(map.value(name).toMap().value("expanded").toBool()); \ folder->setSidebarExpanded(map.value(name).toMap().value("expanded_sidebar").toBool()); READ_FOLDER("bookmark_bar", m_folderToolbar) READ_FOLDER("bookmark_menu", m_folderMenu) READ_FOLDER("other", m_folderUnsorted) #undef READ_FOLDER } void Bookmarks::readBookmarks(const QVariantList &list, BookmarkItem* parent) { Q_ASSERT(parent); foreach (const QVariant &entry, list) { const QVariantMap map = entry.toMap(); BookmarkItem::Type type = BookmarkItem::typeFromString(map.value("type").toString()); if (type == BookmarkItem::Invalid) { continue; } BookmarkItem* item = new BookmarkItem(type, parent); switch (type) { case BookmarkItem::Url: item->setUrl(QUrl::fromEncoded(map.value("url").toByteArray())); item->setTitle(map.value("name").toString()); item->setDescription(map.value("description").toString()); item->setKeyword(map.value("keyword").toString()); item->setVisitCount(map.value("visit_count").toInt()); break; case BookmarkItem::Folder: item->setTitle(map.value("name").toString()); item->setDescription(map.value("description").toString()); item->setExpanded(map.value("expanded").toBool()); item->setSidebarExpanded(map.value("expanded_sidebar").toBool()); break; default: break; } if (map.contains("children")) { readBookmarks(map.value("children").toList(), item); } } } QVariantList Bookmarks::writeBookmarks(BookmarkItem* parent) { Q_ASSERT(parent); QVariantList list; foreach (BookmarkItem* child, parent->children()) { QVariantMap map; map.insert("type", BookmarkItem::typeToString(child->type())); switch (child->type()) { case BookmarkItem::Url: map.insert("url", child->urlString()); map.insert("name", child->title()); map.insert("description", child->description()); map.insert("keyword", child->keyword()); map.insert("visit_count", child->visitCount()); break; case BookmarkItem::Folder: map.insert("name", child->title()); map.insert("description", child->description()); map.insert("expanded", child->isExpanded()); map.insert("expanded_sidebar", child->isSidebarExpanded()); break; default: break; } if (!child->children().isEmpty()) { map.insert("children", writeBookmarks(child)); } list.append(map); } return list; } void Bookmarks::search(QList* items, BookmarkItem* parent, const QUrl &url) const { Q_ASSERT(items); Q_ASSERT(parent); switch (parent->type()) { case BookmarkItem::Root: case BookmarkItem::Folder: foreach (BookmarkItem* child, parent->children()) { search(items, child, url); } break; case BookmarkItem::Url: if (parent->url() == url) { items->append(parent); } break; default: break; } } void Bookmarks::search(QList* items, BookmarkItem* parent, const QString &string, int limit, Qt::CaseSensitivity sensitive) const { Q_ASSERT(items); Q_ASSERT(parent); if (limit == items->count()) { return; } switch (parent->type()) { case BookmarkItem::Root: case BookmarkItem::Folder: foreach (BookmarkItem* child, parent->children()) { search(items, child, string, limit, sensitive); } break; case BookmarkItem::Url: if (parent->title().contains(string, sensitive) || parent->urlString().contains(string, sensitive) || parent->description().contains(string, sensitive) || parent->keyword().compare(string, sensitive) == 0 ) { items->append(parent); } break; default: break; } } void Bookmarks::searchKeyword(QList* items, BookmarkItem* parent, const QString &keyword) const { Q_ASSERT(items); Q_ASSERT(parent); switch (parent->type()) { case BookmarkItem::Root: case BookmarkItem::Folder: foreach (BookmarkItem* child, parent->children()) searchKeyword(items, child, keyword); break; case BookmarkItem::Url: if (parent->keyword() == keyword) items->append(parent); break; default: break; } } diff --git a/src/lib/bookmarks/bookmarks.h b/src/lib/bookmarks/bookmarks.h index 7a2888c0..92db9285 100644 --- a/src/lib/bookmarks/bookmarks.h +++ b/src/lib/bookmarks/bookmarks.h @@ -1,111 +1,111 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef BOOKMARKS_H #define BOOKMARKS_H #include #include #include "qzcommon.h" class QUrl; class BookmarkItem; class BookmarksModel; class AutoSaver; -class QUPZILLA_EXPORT Bookmarks : public QObject +class FALKON_EXPORT Bookmarks : public QObject { Q_OBJECT public: explicit Bookmarks(QObject* parent = 0); ~Bookmarks(); void loadSettings(); bool showOnlyIconsInToolbar() const; bool showOnlyTextInToolbar() const; BookmarkItem* rootItem() const; BookmarkItem* toolbarFolder() const; BookmarkItem* menuFolder() const; BookmarkItem* unsortedFolder() const; BookmarkItem* lastUsedFolder() const; BookmarksModel* model() const; bool isBookmarked(const QUrl &url); bool canBeModified(BookmarkItem* item) const; // Search bookmarks (urls only) for exact url match QList searchBookmarks(const QUrl &url) const; // Search bookmarks for contains match through all properties QList searchBookmarks(const QString &string, int limit = -1, Qt::CaseSensitivity sensitive = Qt::CaseInsensitive) const; // Search bookmarks for exact match of keyword QList searchKeyword(const QString &keyword) const; void addBookmark(BookmarkItem* parent, BookmarkItem* item); void insertBookmark(BookmarkItem* parent, int row, BookmarkItem* item); bool removeBookmark(BookmarkItem* item); void changeBookmark(BookmarkItem* item); public slots: void setShowOnlyIconsInToolbar(bool state); void setShowOnlyTextInToolbar(bool state); signals: // Item was added to bookmarks void bookmarkAdded(BookmarkItem* item); // Item was removed from bookmarks void bookmarkRemoved(BookmarkItem* item); // Item data has changed void bookmarkChanged(BookmarkItem* item); void showOnlyIconsInToolbarChanged(bool show); void showOnlyTextInToolbarChanged(bool show); private slots: void saveSettings(); private: void init(); void loadBookmarks(); void saveBookmarks(); void loadBookmarksFromMap(const QVariantMap &map); void readBookmarks(const QVariantList &list, BookmarkItem* parent); QVariantList writeBookmarks(BookmarkItem* parent); void search(QList* items, BookmarkItem* parent, const QUrl &url) const; void search(QList* items, BookmarkItem* parent, const QString &string, int limit, Qt::CaseSensitivity sensitive) const; void searchKeyword(QList* items, BookmarkItem* parent, const QString &keyword) const; BookmarkItem* m_root; BookmarkItem* m_folderToolbar; BookmarkItem* m_folderMenu; BookmarkItem* m_folderUnsorted; BookmarkItem* m_lastFolder; BookmarksModel* m_model; AutoSaver* m_autoSaver; bool m_showOnlyIconsInToolbar; bool m_showOnlyTextInToolbar; }; #endif // BOOKMARKS_H diff --git a/src/lib/bookmarks/bookmarksexport/bookmarksexportdialog.cpp b/src/lib/bookmarks/bookmarksexport/bookmarksexportdialog.cpp index bf70f911..780a6ea6 100644 --- a/src/lib/bookmarks/bookmarksexport/bookmarksexportdialog.cpp +++ b/src/lib/bookmarks/bookmarksexport/bookmarksexportdialog.cpp @@ -1,80 +1,80 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "bookmarksexportdialog.h" #include "ui_bookmarksexportdialog.h" #include "htmlexporter.h" #include "mainapplication.h" #include "bookmarks.h" #include BookmarksExportDialog::BookmarksExportDialog(QWidget* parent) : QDialog(parent) , ui(new Ui::BookmarksExportDialog) , m_currentExporter(0) { setAttribute(Qt::WA_DeleteOnClose); ui->setupUi(this); init(); connect(ui->chooseOutput, SIGNAL(clicked()), this, SLOT(setPath())); connect(ui->buttonBox, SIGNAL(accepted()), this, SLOT(exportBookmarks())); connect(ui->buttonBox, SIGNAL(rejected()), this, SLOT(close())); } BookmarksExportDialog::~BookmarksExportDialog() { delete ui; } void BookmarksExportDialog::setPath() { Q_ASSERT(m_currentExporter); ui->output->setText(m_currentExporter->getPath(this)); } void BookmarksExportDialog::exportBookmarks() { Q_ASSERT(m_currentExporter); if (ui->output->text().isEmpty()) { return; } bool ok = m_currentExporter->exportBookmarks(mApp->bookmarks()->rootItem()); if (!ok) { QMessageBox::critical(this, tr("Error!"), m_currentExporter->errorString()); } else { close(); } } void BookmarksExportDialog::init() { m_exporters.append(new HtmlExporter(this)); foreach (BookmarksExporter* exporter, m_exporters) { ui->format->addItem(exporter->name()); } m_currentExporter = m_exporters.at(0); } diff --git a/src/lib/bookmarks/bookmarksexport/bookmarksexportdialog.h b/src/lib/bookmarks/bookmarksexport/bookmarksexportdialog.h index 285f1c75..ef5650ce 100644 --- a/src/lib/bookmarks/bookmarksexport/bookmarksexportdialog.h +++ b/src/lib/bookmarks/bookmarksexport/bookmarksexportdialog.h @@ -1,52 +1,52 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef BOOKMARKSEXPORTDIALOG_H #define BOOKMARKSEXPORTDIALOG_H #include #include "qzcommon.h" namespace Ui { class BookmarksExportDialog; } class BookmarksExporter; -class QUPZILLA_EXPORT BookmarksExportDialog : public QDialog +class FALKON_EXPORT BookmarksExportDialog : public QDialog { Q_OBJECT public: explicit BookmarksExportDialog(QWidget* parent = 0); ~BookmarksExportDialog(); private slots: void setPath(); void exportBookmarks(); private: void init(); Ui::BookmarksExportDialog* ui; QList m_exporters; BookmarksExporter* m_currentExporter; }; #endif // BOOKMARKSEXPORTDIALOG_H diff --git a/src/lib/bookmarks/bookmarksexport/bookmarksexporter.cpp b/src/lib/bookmarks/bookmarksexport/bookmarksexporter.cpp index d7f0af28..7e674630 100644 --- a/src/lib/bookmarks/bookmarksexport/bookmarksexporter.cpp +++ b/src/lib/bookmarks/bookmarksexport/bookmarksexporter.cpp @@ -1,42 +1,42 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "bookmarksexporter.h" BookmarksExporter::BookmarksExporter(QObject* parent) : QObject(parent) { } BookmarksExporter::~BookmarksExporter() { } bool BookmarksExporter::error() const { return !m_error.isEmpty(); } QString BookmarksExporter::errorString() const { return m_error; } void BookmarksExporter::setError(const QString &error) { m_error = error; } diff --git a/src/lib/bookmarks/bookmarksexport/bookmarksexporter.h b/src/lib/bookmarks/bookmarksexport/bookmarksexporter.h index f0bc5b3b..aec54819 100644 --- a/src/lib/bookmarks/bookmarksexport/bookmarksexporter.h +++ b/src/lib/bookmarks/bookmarksexport/bookmarksexporter.h @@ -1,54 +1,54 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef BOOKMARKSEXPORTER_H #define BOOKMARKSEXPORTER_H #include #include "qzcommon.h" class BookmarkItem; -class QUPZILLA_EXPORT BookmarksExporter : public QObject +class FALKON_EXPORT BookmarksExporter : public QObject { Q_OBJECT public: explicit BookmarksExporter(QObject* parent = 0); virtual ~BookmarksExporter(); bool error() const; QString errorString() const; virtual QString name() const = 0; // Get filename from user (or a directory) virtual QString getPath(QWidget* parent) = 0; // Export bookmarks, return false on error virtual bool exportBookmarks(BookmarkItem* root) = 0; protected: // Empty error = no error void setError(const QString &error); private: QString m_error; }; #endif // BOOKMARKSEXPORTER_H diff --git a/src/lib/bookmarks/bookmarksexport/htmlexporter.cpp b/src/lib/bookmarks/bookmarksexport/htmlexporter.cpp index 5f3fe09d..6b2d1fbd 100644 --- a/src/lib/bookmarks/bookmarksexport/htmlexporter.cpp +++ b/src/lib/bookmarks/bookmarksexport/htmlexporter.cpp @@ -1,106 +1,106 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "htmlexporter.h" #include "bookmarkitem.h" #include "qztools.h" #include HtmlExporter::HtmlExporter(QObject* parent) : BookmarksExporter(parent) { } QString HtmlExporter::name() const { return BookmarksExporter::tr("HTML File") + QL1S(" (bookmarks.html)"); } QString HtmlExporter::getPath(QWidget* parent) { const QString defaultPath = QDir::homePath() + QLatin1String("/bookmarks.html"); const QString filter = BookmarksExporter::tr("HTML Bookmarks") + QL1S(" (.html)"); m_path = QzTools::getSaveFileName("HtmlExporter", parent, BookmarksExporter::tr("Choose file..."), defaultPath, filter); return m_path; } bool HtmlExporter::exportBookmarks(BookmarkItem* root) { QFile file(m_path); if (!file.open(QFile::WriteOnly | QFile::Truncate)) { setError(BookmarksExporter::tr("Cannot open file for writing!")); return false; } QTextStream stream(&file); stream.setCodec("UTF-8"); stream << "" << endl; stream << "" << endl; stream << "" << endl; stream << "Bookmarks" << endl; stream << "

Bookmarks

" << endl; writeBookmark(root, stream, 0); return true; } void HtmlExporter::writeBookmark(BookmarkItem* item, QTextStream &stream, int level) { Q_ASSERT(item); QString indent; indent.fill(QLatin1Char(' '), level * 4); switch (item->type()) { case BookmarkItem::Url: stream << indent << "
urlString() << "\">" << item->title() << "" << endl; break; case BookmarkItem::Separator: stream << indent << "
" << endl; break; case BookmarkItem::Folder: stream << indent << "

" << item->title() << "

" << endl; stream << indent << "

" << endl; foreach (BookmarkItem* child, item->children()) { writeBookmark(child, stream, level + 1); } stream << indent << "

" << endl; break; case BookmarkItem::Root: stream << indent << "

" << endl; foreach (BookmarkItem* child, item->children()) { writeBookmark(child, stream, level + 1); } stream << indent << "

" << endl; break; default: break; } } diff --git a/src/lib/bookmarks/bookmarksexport/htmlexporter.h b/src/lib/bookmarks/bookmarksexport/htmlexporter.h index cc48bd30..3003ccac 100644 --- a/src/lib/bookmarks/bookmarksexport/htmlexporter.h +++ b/src/lib/bookmarks/bookmarksexport/htmlexporter.h @@ -1,42 +1,42 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef HTMLEXPORTER_H #define HTMLEXPORTER_H #include "bookmarksexporter.h" class QTextStream; class BookmarkItem; class HtmlExporter : public BookmarksExporter { public: explicit HtmlExporter(QObject* parent = 0); QString name() const; QString getPath(QWidget* parent); bool exportBookmarks(BookmarkItem* root); private: void writeBookmark(BookmarkItem* item, QTextStream &stream, int level); QString m_path; }; #endif // HTMLEXPORTER_H diff --git a/src/lib/bookmarks/bookmarksicon.cpp b/src/lib/bookmarks/bookmarksicon.cpp index f1337de9..656a8566 100644 --- a/src/lib/bookmarks/bookmarksicon.cpp +++ b/src/lib/bookmarks/bookmarksicon.cpp @@ -1,120 +1,120 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "bookmarksicon.h" #include "bookmarkswidget.h" #include "bookmarks.h" #include "mainapplication.h" #include "webview.h" #include "locationbar.h" #include "pluginproxy.h" #include "speeddial.h" #include #include BookmarksIcon::BookmarksIcon(QWidget* parent) : ClickableLabel(parent) , m_view(0) , m_bookmark(0) { setObjectName("locationbar-bookmarkicon"); setCursor(Qt::PointingHandCursor); setToolTip(tr("Bookmark this Page")); setFocusPolicy(Qt::ClickFocus); connect(mApp->bookmarks(), SIGNAL(bookmarkAdded(BookmarkItem*)), this, SLOT(bookmarksChanged())); connect(mApp->bookmarks(), SIGNAL(bookmarkRemoved(BookmarkItem*)), this, SLOT(bookmarksChanged())); connect(mApp->bookmarks(), SIGNAL(bookmarkChanged(BookmarkItem*)), this, SLOT(bookmarksChanged())); connect(mApp->plugins()->speedDial(), SIGNAL(pagesChanged()), this, SLOT(speedDialChanged())); connect(this, SIGNAL(clicked(QPoint)), this, SLOT(iconClicked())); } void BookmarksIcon::setWebView(WebView* view) { m_view = view; } void BookmarksIcon::checkBookmark(const QUrl &url, bool forceCheck) { if (!forceCheck && m_lastUrl == url) { return; } QList items = mApp->bookmarks()->searchBookmarks(url); m_bookmark = items.isEmpty() ? 0 : items.at(0); if (m_bookmark || mApp->plugins()->speedDial()->pageForUrl(url).isValid()) { setBookmarkSaved(); } else { setBookmarkDisabled(); } m_lastUrl = url; } void BookmarksIcon::bookmarksChanged() { checkBookmark(m_lastUrl, true); } void BookmarksIcon::speedDialChanged() { checkBookmark(m_lastUrl, true); } void BookmarksIcon::iconClicked() { if (!m_view) { return; } BookmarksWidget* widget = new BookmarksWidget(m_view, m_bookmark, parentWidget()); widget->showAt(parentWidget()); } void BookmarksIcon::setBookmarkSaved() { setProperty("bookmarked", QVariant(true)); style()->unpolish(this); style()->polish(this); setToolTip(tr("Edit this bookmark")); } void BookmarksIcon::setBookmarkDisabled() { setProperty("bookmarked", QVariant(false)); style()->unpolish(this); style()->polish(this); setToolTip(tr("Bookmark this Page")); } void BookmarksIcon::contextMenuEvent(QContextMenuEvent* ev) { // Prevent propagating to LocationBar ev->accept(); } void BookmarksIcon::mousePressEvent(QMouseEvent* ev) { ClickableLabel::mousePressEvent(ev); // Prevent propagating to LocationBar ev->accept(); } diff --git a/src/lib/bookmarks/bookmarksicon.h b/src/lib/bookmarks/bookmarksicon.h index 01c0d925..2c4314be 100644 --- a/src/lib/bookmarks/bookmarksicon.h +++ b/src/lib/bookmarks/bookmarksicon.h @@ -1,56 +1,56 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef BOOKMARKSICON_H #define BOOKMARKSICON_H #include #include "clickablelabel.h" #include "qzcommon.h" class WebView; class BookmarkItem; -class QUPZILLA_EXPORT BookmarksIcon : public ClickableLabel +class FALKON_EXPORT BookmarksIcon : public ClickableLabel { Q_OBJECT public: explicit BookmarksIcon(QWidget* parent = 0); void setWebView(WebView* view); void checkBookmark(const QUrl &url, bool forceCheck = false); private slots: void bookmarksChanged(); void speedDialChanged(); void iconClicked(); private: void contextMenuEvent(QContextMenuEvent* ev); void mousePressEvent(QMouseEvent* ev); void setBookmarkSaved(); void setBookmarkDisabled(); WebView* m_view; BookmarkItem* m_bookmark; QUrl m_lastUrl; }; #endif // BOOKMARKSICON_H diff --git a/src/lib/bookmarks/bookmarksimport/bookmarksimportdialog.cpp b/src/lib/bookmarks/bookmarksimport/bookmarksimportdialog.cpp index d9e895ef..1f278eff 100644 --- a/src/lib/bookmarks/bookmarksimport/bookmarksimportdialog.cpp +++ b/src/lib/bookmarks/bookmarksimport/bookmarksimportdialog.cpp @@ -1,203 +1,203 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "bookmarksimportdialog.h" #include "ui_bookmarksimportdialog.h" #include "firefoximporter.h" #include "chromeimporter.h" #include "operaimporter.h" #include "htmlimporter.h" #include "ieimporter.h" #include "bookmarks.h" #include "bookmarkitem.h" #include "bookmarksmodel.h" #include "bookmarksitemdelegate.h" #include "mainapplication.h" #include BookmarksImportDialog::BookmarksImportDialog(QWidget* parent) : QDialog(parent) , ui(new Ui::BookmarksImportDialog) , m_currentPage(0) , m_importer(0) , m_importedFolder(0) , m_model(0) { setAttribute(Qt::WA_DeleteOnClose); ui->setupUi(this); ui->browserList->setCurrentRow(0); ui->treeView->setItemDelegate(new BookmarksItemDelegate(ui->treeView)); connect(ui->nextButton, SIGNAL(clicked()), this, SLOT(nextPage())); connect(ui->backButton, SIGNAL(clicked()), this, SLOT(previousPage())); connect(ui->chooseFile, SIGNAL(clicked()), this, SLOT(setFile())); connect(ui->cancelButton, SIGNAL(rejected()), this, SLOT(close())); #ifndef Q_OS_WIN ui->browserList->setItemHidden(ui->browserList->item(IE), true); #endif } BookmarksImportDialog::~BookmarksImportDialog() { ui->treeView->setModel(0); delete m_model; delete m_importedFolder; delete m_importer; delete ui; } void BookmarksImportDialog::nextPage() { switch (m_currentPage) { case 0: if (!ui->browserList->currentItem()) { return; } switch (ui->browserList->currentRow()) { case Firefox: m_importer = new FirefoxImporter; break; case Chrome: m_importer = new ChromeImporter; break; case Opera: m_importer = new OperaImporter; break; case IE: m_importer = new IeImporter; break; case Html: m_importer = new HtmlImporter; break; default: Q_ASSERT(!"Unreachable"); break; } ui->fileLine->clear(); showImporterPage(); ui->nextButton->setEnabled(false); ui->backButton->setEnabled(true); ui->stackedWidget->setCurrentIndex(++m_currentPage); break; case 1: if (ui->fileLine->text().isEmpty()) { return; } if (m_importer->prepareImport()) { m_importedFolder = m_importer->importBookmarks(); } if (m_importer->error()) { QMessageBox::critical(this, tr("Error!"), m_importer->errorString()); return; } if (!m_importedFolder || m_importedFolder->children().isEmpty()) { QMessageBox::warning(this, tr("Error!"), tr("No bookmarks were found.")); return; } Q_ASSERT(m_importedFolder->isFolder()); ui->stackedWidget->setCurrentIndex(++m_currentPage); ui->nextButton->setText(tr("Finish")); showExportedBookmarks(); break; case 2: addExportedBookmarks(); close(); break; default: Q_ASSERT(!"Unreachable"); } } void BookmarksImportDialog::previousPage() { switch (m_currentPage) { case 0: break; case 1: ui->nextButton->setEnabled(true); ui->backButton->setEnabled(false); ui->stackedWidget->setCurrentIndex(--m_currentPage); delete m_importer; m_importer = 0; break; case 2: showImporterPage(); ui->nextButton->setText(tr("Next >")); ui->nextButton->setEnabled(true); ui->backButton->setEnabled(true); ui->stackedWidget->setCurrentIndex(--m_currentPage); ui->treeView->setModel(0); delete m_model; m_model = 0; delete m_importedFolder; m_importedFolder = 0; break; default: Q_ASSERT(!"Unreachable"); } } void BookmarksImportDialog::setFile() { Q_ASSERT(m_importer); ui->fileLine->setText(m_importer->getPath(this)); ui->nextButton->setEnabled(!ui->fileLine->text().isEmpty()); } void BookmarksImportDialog::showImporterPage() { ui->iconLabel->setPixmap(ui->browserList->currentItem()->icon().pixmap(48)); ui->importingFromLabel->setText(tr("Importing from %1").arg(ui->browserList->currentItem()->text())); ui->fileText1->setText(m_importer->description()); ui->standardDirLabel->setText(QString("%1").arg(m_importer->standardPath())); } void BookmarksImportDialog::showExportedBookmarks() { m_model = new BookmarksModel(m_importedFolder, 0, this); ui->treeView->setModel(m_model); ui->treeView->header()->resizeSection(0, ui->treeView->header()->width() / 2); ui->treeView->expandAll(); } void BookmarksImportDialog::addExportedBookmarks() { mApp->bookmarks()->addBookmark(mApp->bookmarks()->unsortedFolder(), m_importedFolder); m_importedFolder = 0; } diff --git a/src/lib/bookmarks/bookmarksimport/bookmarksimportdialog.h b/src/lib/bookmarks/bookmarksimport/bookmarksimportdialog.h index 65fb038a..b41e778d 100644 --- a/src/lib/bookmarks/bookmarksimport/bookmarksimportdialog.h +++ b/src/lib/bookmarks/bookmarksimport/bookmarksimportdialog.h @@ -1,68 +1,68 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef BOOKMARKSIMPORTDIALOG_H #define BOOKMARKSIMPORTDIALOG_H #include #include "qzcommon.h" namespace Ui { class BookmarksImportDialog; } class BookmarkItem; class BookmarksModel; class BookmarksImporter; -class QUPZILLA_EXPORT BookmarksImportDialog : public QDialog +class FALKON_EXPORT BookmarksImportDialog : public QDialog { Q_OBJECT public: explicit BookmarksImportDialog(QWidget* parent = 0); ~BookmarksImportDialog(); private slots: void nextPage(); void previousPage(); void setFile(); private: enum Browser { Firefox = 0, Chrome = 1, Opera = 2, IE = 3, Html = 4 }; void showImporterPage(); void showExportedBookmarks(); void addExportedBookmarks(); Ui::BookmarksImportDialog* ui; int m_currentPage; BookmarksImporter* m_importer; BookmarkItem* m_importedFolder; BookmarksModel* m_model; }; #endif // BOOKMARKSIMPORTDIALOG_H diff --git a/src/lib/bookmarks/bookmarksimport/bookmarksimporter.cpp b/src/lib/bookmarks/bookmarksimport/bookmarksimporter.cpp index fabc6103..f2754edb 100644 --- a/src/lib/bookmarks/bookmarksimport/bookmarksimporter.cpp +++ b/src/lib/bookmarks/bookmarksimport/bookmarksimporter.cpp @@ -1,42 +1,42 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "bookmarksimporter.h" BookmarksImporter::BookmarksImporter(QObject* parent) : QObject(parent) { } BookmarksImporter::~BookmarksImporter() { } bool BookmarksImporter::error() const { return !m_error.isEmpty(); } QString BookmarksImporter::errorString() const { return m_error; } void BookmarksImporter::setError(const QString &error) { m_error = error; } diff --git a/src/lib/bookmarks/bookmarksimport/bookmarksimporter.h b/src/lib/bookmarks/bookmarksimport/bookmarksimporter.h index 786c0156..182540f4 100644 --- a/src/lib/bookmarks/bookmarksimport/bookmarksimporter.h +++ b/src/lib/bookmarks/bookmarksimport/bookmarksimporter.h @@ -1,60 +1,60 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef BOOKMARKSIMPORTER_H #define BOOKMARKSIMPORTER_H #include #include "qzcommon.h" class QIcon; class BookmarkItem; -class QUPZILLA_EXPORT BookmarksImporter : public QObject +class FALKON_EXPORT BookmarksImporter : public QObject { Q_OBJECT public: explicit BookmarksImporter(QObject* parent = 0); virtual ~BookmarksImporter(); bool error() const; QString errorString() const; virtual QString description() const = 0; virtual QString standardPath() const = 0; // Get filename from user (or a directory) virtual QString getPath(QWidget* parent) = 0; // Prepare import (check if file exists, ...), return false on error virtual bool prepareImport() = 0; // Import bookmarks (it must return root folder) virtual BookmarkItem* importBookmarks() = 0; protected: // Empty error = no error void setError(const QString &error); private: QString m_error; }; #endif // BOOKMARKSIMPORTER_H diff --git a/src/lib/bookmarks/bookmarksimport/chromeimporter.cpp b/src/lib/bookmarks/bookmarksimport/chromeimporter.cpp index e81fddf7..814e24b7 100644 --- a/src/lib/bookmarks/bookmarksimport/chromeimporter.cpp +++ b/src/lib/bookmarks/bookmarksimport/chromeimporter.cpp @@ -1,130 +1,130 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2016 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "chromeimporter.h" #include "bookmarkitem.h" #include #include #include #include ChromeImporter::ChromeImporter(QObject* parent) : BookmarksImporter(parent) { } QString ChromeImporter::description() const { return BookmarksImporter::tr("Google Chrome stores its bookmarks in Bookmarks text file. " "This file is usually located in"); } QString ChromeImporter::standardPath() const { #if defined(Q_OS_WIN) return QString("%APPDATA%/Chrome/"); #elif defined(Q_OS_OSX) return QDir::homePath() + QLatin1String("/Library/Application Support/Google/Chrome/"); #else return QDir::homePath() + QLatin1String("/.config/chrome/"); #endif } QString ChromeImporter::getPath(QWidget* parent) { m_path = QFileDialog::getOpenFileName(parent, BookmarksImporter::tr("Choose file..."), standardPath(), "Bookmarks (Bookmarks)"); return m_path; } bool ChromeImporter::prepareImport() { m_file.setFileName(m_path); if (!m_file.open(QFile::ReadOnly)) { setError(BookmarksImporter::tr("Unable to open file.")); return false; } return true; } BookmarkItem* ChromeImporter::importBookmarks() { const QByteArray data = m_file.readAll(); m_file.close(); QJsonParseError err; QJsonDocument json = QJsonDocument::fromJson(data, &err); const QVariant res = json.toVariant(); if (err.error != QJsonParseError::NoError || res.type() != QVariant::Map) { setError(BookmarksImporter::tr("Cannot parse JSON file!")); return 0; } QVariantMap rootMap = res.toMap().value("roots").toMap(); BookmarkItem* root = new BookmarkItem(BookmarkItem::Folder); root->setTitle("Chrome Import"); BookmarkItem* toolbar = new BookmarkItem(BookmarkItem::Folder, root); toolbar->setTitle(rootMap.value("bookmark_bar").toMap().value("name").toString()); readBookmarks(rootMap.value("bookmark_bar").toMap().value("children").toList(), toolbar); BookmarkItem* other = new BookmarkItem(BookmarkItem::Folder, root); other->setTitle(rootMap.value("other").toMap().value("name").toString()); readBookmarks(rootMap.value("other").toMap().value("children").toList(), other); BookmarkItem* synced = new BookmarkItem(BookmarkItem::Folder, root); synced->setTitle(rootMap.value("synced").toMap().value("name").toString()); readBookmarks(rootMap.value("synced").toMap().value("synced").toList(), other); return root; } void ChromeImporter::readBookmarks(const QVariantList &list, BookmarkItem* parent) { Q_ASSERT(parent); foreach (const QVariant &entry, list) { const QVariantMap map = entry.toMap(); const QString typeString = map.value("type").toString(); BookmarkItem::Type type; if (typeString == QLatin1String("url")) { type = BookmarkItem::Url; } else if (typeString == QLatin1String("folder")) { type = BookmarkItem::Folder; } else { continue; } BookmarkItem* item = new BookmarkItem(type, parent); item->setTitle(map.value("name").toString()); if (item->isUrl()) { item->setUrl(QUrl::fromEncoded(map.value("url").toByteArray())); } if (map.contains("children")) { readBookmarks(map.value("children").toList(), item); } } } diff --git a/src/lib/bookmarks/bookmarksimport/chromeimporter.h b/src/lib/bookmarks/bookmarksimport/chromeimporter.h index bff26a2e..1f5bfb74 100644 --- a/src/lib/bookmarks/bookmarksimport/chromeimporter.h +++ b/src/lib/bookmarks/bookmarksimport/chromeimporter.h @@ -1,46 +1,46 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef CHROMEIMPORTER_H #define CHROMEIMPORTER_H #include #include #include "bookmarksimporter.h" -class QUPZILLA_EXPORT ChromeImporter : public BookmarksImporter +class FALKON_EXPORT ChromeImporter : public BookmarksImporter { public: explicit ChromeImporter(QObject* parent = 0); QString description() const; QString standardPath() const; QString getPath(QWidget* parent); bool prepareImport(); BookmarkItem* importBookmarks(); private: void readBookmarks(const QVariantList &list, BookmarkItem* parent); QString m_path; QFile m_file; }; #endif // CHROMEIMPORTER_H diff --git a/src/lib/bookmarks/bookmarksimport/firefoximporter.cpp b/src/lib/bookmarks/bookmarksimport/firefoximporter.cpp index a93b1aa9..fc00d840 100644 --- a/src/lib/bookmarks/bookmarksimport/firefoximporter.cpp +++ b/src/lib/bookmarks/bookmarksimport/firefoximporter.cpp @@ -1,152 +1,152 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "firefoximporter.h" #include "bookmarksimportdialog.h" #include #include #include #include #include #include #define CONNECTION "firefox-places-import" FirefoxImporter::FirefoxImporter(QObject* parent) : BookmarksImporter(parent) { } FirefoxImporter::~FirefoxImporter() { QSqlDatabase::removeDatabase(CONNECTION); } QString FirefoxImporter::description() const { return BookmarksImporter::tr("Mozilla Firefox stores its bookmarks in places.sqlite SQLite " "database. This file is usually located in"); } QString FirefoxImporter::standardPath() const { #ifdef Q_OS_WIN return QString("%APPDATA%/Mozilla/"); #else return QDir::homePath() + QLatin1String("/.mozilla/firefox/"); #endif } QString FirefoxImporter::getPath(QWidget* parent) { m_path = QFileDialog::getOpenFileName(parent, BookmarksImporter::tr("Choose file..."), standardPath(), "Places (places.sqlite)"); return m_path; } bool FirefoxImporter::prepareImport() { // Make sure this connection is properly closed if already opened QSqlDatabase::removeDatabase(CONNECTION); // Create new connection QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", CONNECTION); if (!QFile::exists(m_path)) { setError(BookmarksImportDialog::tr("File does not exist.")); return false; } db.setDatabaseName(m_path); if (!db.open()) { setError(BookmarksImportDialog::tr("Unable to open database. Is Firefox running?")); return false; } return true; } BookmarkItem* FirefoxImporter::importBookmarks() { QList items; BookmarkItem* root = new BookmarkItem(BookmarkItem::Folder); root->setTitle("Firefox Import"); QSqlQuery query(QSqlDatabase::database(CONNECTION)); query.exec("SELECT id, parent, type, title, fk FROM moz_bookmarks WHERE title != '' OR type = 3"); while (query.next()) { Item item; item.id = query.value(0).toInt(); item.parent = query.value(1).toInt(); item.type = typeFromValue(query.value(2).toInt()); item.title = query.value(3).toString(); int fk = query.value(4).toInt(); if (item.type == BookmarkItem::Invalid) { continue; } QSqlQuery query(QSqlDatabase::database(CONNECTION)); query.prepare("SELECT url FROM moz_places WHERE id=?"); query.addBindValue(fk); query.exec(); if (query.next()) { item.url = query.value(0).toUrl(); } if (item.url.scheme() == QLatin1String("place")) { continue; } items.append(item); } if (query.lastError().isValid()) { setError(query.lastError().text()); } QHash hash; foreach (const Item &item, items) { BookmarkItem* parent = hash.value(item.parent); BookmarkItem* bookmark = new BookmarkItem(item.type, parent ? parent : root); bookmark->setTitle(item.title); bookmark->setUrl(item.url); hash.insert(item.id, bookmark); } return root; } BookmarkItem::Type FirefoxImporter::typeFromValue(int value) { switch (value) { case 1: return BookmarkItem::Url; case 2: return BookmarkItem::Folder; case 3: return BookmarkItem::Separator; default: return BookmarkItem::Invalid; } } diff --git a/src/lib/bookmarks/bookmarksimport/firefoximporter.h b/src/lib/bookmarks/bookmarksimport/firefoximporter.h index 4a26bfc7..376c9e22 100644 --- a/src/lib/bookmarks/bookmarksimport/firefoximporter.h +++ b/src/lib/bookmarks/bookmarksimport/firefoximporter.h @@ -1,62 +1,62 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef FIREFOXIMPORTER_H #define FIREFOXIMPORTER_H #include #include "bookmarksimporter.h" #include "bookmarkitem.h" -class QUPZILLA_EXPORT FirefoxImporter : public BookmarksImporter +class FALKON_EXPORT FirefoxImporter : public BookmarksImporter { public: explicit FirefoxImporter(QObject* parent = 0); ~FirefoxImporter(); QString description() const; QString standardPath() const; QString getPath(QWidget* parent); bool prepareImport(); BookmarkItem* importBookmarks(); private: enum Type { Url, Folder, Separator, Invalid }; struct Item { int id; int parent; BookmarkItem::Type type; QString title; QUrl url; }; BookmarkItem::Type typeFromValue(int value); QString m_path; }; #endif // FIREFOXIMPORTER_H diff --git a/src/lib/bookmarks/bookmarksimport/htmlimporter.cpp b/src/lib/bookmarks/bookmarksimport/htmlimporter.cpp index 3c3a5b68..76857dd5 100644 --- a/src/lib/bookmarks/bookmarksimport/htmlimporter.cpp +++ b/src/lib/bookmarks/bookmarksimport/htmlimporter.cpp @@ -1,165 +1,165 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "htmlimporter.h" #include "bookmarkitem.h" #include "qzregexp.h" #include #include HtmlImporter::HtmlImporter(QObject* parent) : BookmarksImporter(parent) { } QString HtmlImporter::description() const { return BookmarksImporter::tr("You can import bookmarks from any browser that supports HTML exporting. " "This file has usually these suffixes"); } QString HtmlImporter::standardPath() const { return QString(".htm, .html"); } QString HtmlImporter::getPath(QWidget* parent) { const QString filter = BookmarksImporter::tr("HTML Bookmarks") + QLatin1String(" (*.htm *.html)"); m_path = QFileDialog::getOpenFileName(parent, BookmarksImporter::tr("Choose file..."), QDir::homePath(), filter); return m_path; } bool HtmlImporter::prepareImport() { m_file.setFileName(m_path); if (!m_file.open(QFile::ReadOnly)) { setError(BookmarksImporter::tr("Unable to open file.")); return false; } return true; } static int qzMin(int a, int b) { if (a > -1 && b > -1) { return qMin(a, b); } if (a > -1) { return a; } else { return b; } } BookmarkItem* HtmlImporter::importBookmarks() { QString bookmarks = QString::fromUtf8(m_file.readAll()); m_file.close(); // Converting tags to lower case -,- // For some reason Qt::CaseInsensitive is not everytime insensitive :-D bookmarks.replace(QLatin1String("

"))); int start = bookmarks.indexOf(QLatin1String("

")); BookmarkItem* root = new BookmarkItem(BookmarkItem::Folder); root->setTitle("HTML Import"); QList folders; folders.append(root); while (start > 0) { QString string = bookmarks.mid(start); int posOfFolder = string.indexOf(QLatin1String("

")); int posOfLink = string.indexOf(QLatin1String("

(.*)"); rx.setMinimal(true); rx.indexIn(string); // QString arguments = rx.cap(1); QString folderName = rx.cap(2).trimmed(); BookmarkItem* folder = new BookmarkItem(BookmarkItem::Folder, folders.isEmpty() ? root : folders.last()); folder->setTitle(folderName); folders.append(folder); start += posOfFolder + rx.cap(0).size(); } else if (nearest == posOfEndFolder) { // Next is end of folder if (!folders.isEmpty()) { folders.removeLast(); } start += posOfEndFolder + 8; } else { // Next is link QzRegExp rx("
(.*)"); rx.setMinimal(true); rx.indexIn(string); QString arguments = rx.cap(1); QString linkName = rx.cap(2).trimmed(); QzRegExp rx2("href=\"(.*)\""); rx2.setMinimal(true); rx2.indexIn(arguments); QUrl url = QUrl::fromEncoded(rx2.cap(1).trimmed().toUtf8()); start += posOfLink + rx.cap(0).size(); if (linkName.isEmpty() || url.isEmpty() || url.scheme() == QL1S("place") || url.scheme() == QL1S("about")) continue; BookmarkItem* b = new BookmarkItem(BookmarkItem::Url, folders.isEmpty() ? root : folders.last()); b->setTitle(linkName); b->setUrl(url); } } return root; } diff --git a/src/lib/bookmarks/bookmarksimport/htmlimporter.h b/src/lib/bookmarks/bookmarksimport/htmlimporter.h index 17712234..1ce0ffe0 100644 --- a/src/lib/bookmarks/bookmarksimport/htmlimporter.h +++ b/src/lib/bookmarks/bookmarksimport/htmlimporter.h @@ -1,43 +1,43 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef HTMLIMPORTER_H #define HTMLIMPORTER_H #include #include "bookmarksimporter.h" -class QUPZILLA_EXPORT HtmlImporter : public BookmarksImporter +class FALKON_EXPORT HtmlImporter : public BookmarksImporter { public: explicit HtmlImporter(QObject* parent = 0); QString description() const; QString standardPath() const; QString getPath(QWidget* parent); bool prepareImport(); BookmarkItem* importBookmarks(); private: QString m_path; QFile m_file; }; #endif // HTMLIMPORTER_H diff --git a/src/lib/bookmarks/bookmarksimport/ieimporter.cpp b/src/lib/bookmarks/bookmarksimport/ieimporter.cpp index f6802115..5b5d59df 100644 --- a/src/lib/bookmarks/bookmarksimport/ieimporter.cpp +++ b/src/lib/bookmarks/bookmarksimport/ieimporter.cpp @@ -1,88 +1,88 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2013-2014 Mattias Cibien * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "ieimporter.h" #include "bookmarkitem.h" #include #include #include #include IeImporter::IeImporter(QObject* parent) : BookmarksImporter(parent) { } QString IeImporter::description() const { return BookmarksImporter::tr("Internet Explorer stores its bookmarks in Favorites folder. " "This folder is usually located in"); } QString IeImporter::standardPath() const { return QDir::homePath() + QLatin1String("/Favorites/"); } QString IeImporter::getPath(QWidget* parent) { m_path = QFileDialog::getExistingDirectory(parent, BookmarksImporter::tr("Choose file..."), standardPath()); return m_path; } bool IeImporter::prepareImport() { QDir dir(m_path); if (!dir.exists()) { setError(BookmarksImporter::tr("Directory does not exist.")); return false; } return true; } BookmarkItem* IeImporter::importBookmarks() { BookmarkItem* root = new BookmarkItem(BookmarkItem::Folder); root->setTitle("Internet Explorer Import"); readDir(QDir(m_path), root); return root; } void IeImporter::readDir(const QDir &dir, BookmarkItem *parent) { foreach (const QFileInfo &file, dir.entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot)) { if (file.isDir()) { BookmarkItem* folder = new BookmarkItem(BookmarkItem::Folder, parent); folder->setTitle(file.baseName()); QDir folderDir = dir; folderDir.cd(file.baseName()); readDir(folderDir, folder); } else if (file.isFile()) { QSettings urlFile(file.absoluteFilePath(), QSettings::IniFormat); const QUrl url = urlFile.value("InternetShortcut/URL").toUrl(); BookmarkItem* item = new BookmarkItem(BookmarkItem::Url, parent); item->setTitle(file.baseName()); item->setUrl(url); } } } diff --git a/src/lib/bookmarks/bookmarksimport/ieimporter.h b/src/lib/bookmarks/bookmarksimport/ieimporter.h index ca09b44b..2991baca 100644 --- a/src/lib/bookmarks/bookmarksimport/ieimporter.h +++ b/src/lib/bookmarks/bookmarksimport/ieimporter.h @@ -1,44 +1,44 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2013-2014 Mattias Cibien * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef IEIMPORTER_H #define IEIMPORTER_H #include #include "bookmarksimporter.h" class IeImporter : public BookmarksImporter { public: explicit IeImporter(QObject* parent = 0); QString description() const; QString standardPath() const; QString getPath(QWidget* parent); bool prepareImport(); BookmarkItem* importBookmarks(); private: void readDir(const QDir &dir, BookmarkItem* parent); QString m_path; }; #endif // IEIMPORTER_H diff --git a/src/lib/bookmarks/bookmarksimport/operaimporter.cpp b/src/lib/bookmarks/bookmarksimport/operaimporter.cpp index 573c535e..0e112bdd 100644 --- a/src/lib/bookmarks/bookmarksimport/operaimporter.cpp +++ b/src/lib/bookmarks/bookmarksimport/operaimporter.cpp @@ -1,195 +1,195 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "operaimporter.h" #include "bookmarkitem.h" #include "qzregexp.h" #include #include #include #include OperaImporter::OperaImporter(QObject* parent) : BookmarksImporter(parent) { m_stream.setCodec("UTF-8"); } QString OperaImporter::description() const { return BookmarksImporter::tr("Opera stores its bookmarks in bookmarks.adr text file. " "This file is usually located in"); } QString OperaImporter::standardPath() const { #ifdef Q_OS_WIN return QString("%APPDATA%/Opera/"); #else return QDir::homePath() + QLatin1String("/.opera/"); #endif } QString OperaImporter::getPath(QWidget* parent) { m_path = QFileDialog::getOpenFileName(parent, BookmarksImporter::tr("Choose file..."), standardPath(), "Bookmarks (*.adr)"); return m_path; } bool OperaImporter::prepareImport() { m_file.setFileName(m_path); if (!m_file.open(QFile::ReadOnly)) { setError(BookmarksImporter::tr("Unable to open file.")); return false; } m_stream.setDevice(&m_file); if (m_stream.readLine() != QLatin1String("Opera Hotlist version 2.0")) { setError(BookmarksImporter::tr("File is not valid Opera bookmarks file!")); return false; } if (!m_stream.readLine().startsWith(QLatin1String("Options: encoding = utf8"))) { setError(BookmarksImporter::tr("Only UTF-8 encoded Opera bookmarks file is supported!")); return false; } return true; } BookmarkItem* OperaImporter::importBookmarks() { BookmarkItem* root = new BookmarkItem(BookmarkItem::Folder); root->setTitle(QSL("Opera Import")); QList folders; folders.append(root); BookmarkItem* item = 0; #define PARENT folders.isEmpty() ? root : folders.last() while (!m_stream.atEnd()) { switch (parseLine(m_stream.readLine())) { case StartFolder: item = new BookmarkItem(BookmarkItem::Folder, PARENT); while (!m_stream.atEnd()) { Token tok = parseLine(m_stream.readLine()); if (tok == EmptyLine) break; else if (tok == KeyValuePair && m_key == QLatin1String("NAME")) item->setTitle(m_value); } folders.append(item); break; case EndFolder: if (folders.count() > 0) { folders.removeLast(); } break; case StartUrl: item = new BookmarkItem(BookmarkItem::Url, PARENT); while (!m_stream.atEnd()) { Token tok = parseLine(m_stream.readLine()); if (tok == EmptyLine) { break; } else if (tok == KeyValuePair) { if (m_key == QL1S("NAME")) item->setTitle(m_value); else if (m_key == QL1S("URL")) item->setUrl(QUrl(m_value)); else if (m_key == QL1S("DESCRIPTION")) item->setDescription(m_value); else if (m_key == QL1S("SHORT NAME")) item->setKeyword(m_value); } } break; case StartSeparator: item = new BookmarkItem(BookmarkItem::Separator, PARENT); while (!m_stream.atEnd()) { if (parseLine(m_stream.readLine()) == EmptyLine) { break; } } break; case StartDeleted: while (!m_stream.atEnd()) { if (parseLine(m_stream.readLine()) == EmptyLine) { break; } } break; default: // EmptyLine break; } } #undef PARENT return root; } OperaImporter::Token OperaImporter::parseLine(const QString &line) { const QString str = line.trimmed(); if (str.isEmpty()) { return EmptyLine; } if (str == QLatin1String("#FOLDER")) { return StartFolder; } if (str == QLatin1String("-")) { return EndFolder; } if (str == QLatin1String("#URL")) { return StartUrl; } if (str == QLatin1String("#SEPERATOR")) { return StartSeparator; } if (str == QLatin1String("#DELETED")) { return StartDeleted; } int index = str.indexOf(QLatin1Char('=')); // Let's assume "key=" is valid line with empty value (but not "=value") if (index > 0) { m_key = str.mid(0, index); m_value = str.mid(index + 1); return KeyValuePair; } return Invalid; } diff --git a/src/lib/bookmarks/bookmarksimport/operaimporter.h b/src/lib/bookmarks/bookmarksimport/operaimporter.h index c36358fc..bb5ca64b 100644 --- a/src/lib/bookmarks/bookmarksimport/operaimporter.h +++ b/src/lib/bookmarks/bookmarksimport/operaimporter.h @@ -1,59 +1,59 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef OPERAIMPORTER_H #define OPERAIMPORTER_H #include #include #include "bookmarksimporter.h" -class QUPZILLA_EXPORT OperaImporter : public BookmarksImporter +class FALKON_EXPORT OperaImporter : public BookmarksImporter { public: explicit OperaImporter(QObject* parent = 0); QString description() const; QString standardPath() const; QString getPath(QWidget* parent); bool prepareImport(); BookmarkItem* importBookmarks(); private: enum Token { EmptyLine, StartFolder, EndFolder, StartUrl, StartSeparator, StartDeleted, KeyValuePair, Invalid }; Token parseLine(const QString &line); QString m_key; QString m_value; QString m_path; QFile m_file; QTextStream m_stream; }; #endif // OPERAIMPORTER_H diff --git a/src/lib/bookmarks/bookmarksitemdelegate.cpp b/src/lib/bookmarks/bookmarksitemdelegate.cpp index aad46f27..ac2b665b 100644 --- a/src/lib/bookmarks/bookmarksitemdelegate.cpp +++ b/src/lib/bookmarks/bookmarksitemdelegate.cpp @@ -1,55 +1,55 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "bookmarksitemdelegate.h" #include "bookmarkstreeview.h" #include "bookmarksmodel.h" #include "bookmarkitem.h" #include #include #include BookmarksItemDelegate::BookmarksItemDelegate(QTreeView* parent) : QStyledItemDelegate(parent) , m_tree(parent) { Q_ASSERT(m_tree); } void BookmarksItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { QStyledItemDelegate::paint(painter, option, index); if (index.data(BookmarksModel::TypeRole).toInt() == BookmarkItem::Separator) { QStyleOption opt = option; opt.state &= ~QStyle::State_Horizontal; // We need to fake continuous line over 2 columns if (m_tree->model()->columnCount(index) == 2) { if (index.column() == 1) { opt.rect = m_lastRect; } else { opt.rect.setWidth(opt.rect.width() + m_tree->columnWidth(1)); m_lastRect = opt.rect; } } QApplication::style()->drawPrimitive(QStyle::PE_IndicatorToolBarSeparator, &opt, painter); } } diff --git a/src/lib/bookmarks/bookmarksitemdelegate.h b/src/lib/bookmarks/bookmarksitemdelegate.h index 8fd3788b..19e3aa41 100644 --- a/src/lib/bookmarks/bookmarksitemdelegate.h +++ b/src/lib/bookmarks/bookmarksitemdelegate.h @@ -1,41 +1,41 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef BOOKMARKSITEMDELEGATE_H #define BOOKMARKSITEMDELEGATE_H #include #include "qzcommon.h" class QTreeView; -class QUPZILLA_EXPORT BookmarksItemDelegate : public QStyledItemDelegate +class FALKON_EXPORT BookmarksItemDelegate : public QStyledItemDelegate { Q_OBJECT public: explicit BookmarksItemDelegate(QTreeView* parent = 0); void paint(QPainter* painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; private: QTreeView* m_tree; mutable QRect m_lastRect; }; #endif // BOOKMARKSITEMDELEGATE_H diff --git a/src/lib/bookmarks/bookmarksmanager.cpp b/src/lib/bookmarks/bookmarksmanager.cpp index 9dd5b4c1..2341bbaa 100644 --- a/src/lib/bookmarks/bookmarksmanager.cpp +++ b/src/lib/bookmarks/bookmarksmanager.cpp @@ -1,348 +1,348 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "bookmarksmanager.h" #include "ui_bookmarksmanager.h" #include "bookmarksmodel.h" #include "bookmarkstools.h" #include "bookmarkitem.h" #include "bookmarks.h" #include "mainapplication.h" #include "browserwindow.h" #include "iconprovider.h" #include "qztools.h" #include #include BookmarksManager::BookmarksManager(BrowserWindow* window, QWidget* parent) : QWidget(parent) , ui(new Ui::BookmarksManager) , m_window(window) , m_bookmarks(mApp->bookmarks()) , m_selectedBookmark(0) , m_blockDescriptionChangedSignal(false) , m_adjustHeaderSizesOnShow(true) { ui->setupUi(this); ui->tree->setViewType(BookmarksTreeView::BookmarksManagerViewType); connect(ui->tree, SIGNAL(bookmarkActivated(BookmarkItem*)), this, SLOT(bookmarkActivated(BookmarkItem*))); connect(ui->tree, SIGNAL(bookmarkCtrlActivated(BookmarkItem*)), this, SLOT(bookmarkCtrlActivated(BookmarkItem*))); connect(ui->tree, SIGNAL(bookmarkShiftActivated(BookmarkItem*)), this, SLOT(bookmarkShiftActivated(BookmarkItem*))); connect(ui->tree, SIGNAL(bookmarksSelected(QList)), this, SLOT(bookmarksSelected(QList))); connect(ui->tree, SIGNAL(contextMenuRequested(QPoint)), this, SLOT(createContextMenu(QPoint))); // Box for editing bookmarks updateEditBox(0); connect(ui->title, SIGNAL(textEdited(QString)), this, SLOT(bookmarkEdited())); connect(ui->address, SIGNAL(textEdited(QString)), this, SLOT(bookmarkEdited())); connect(ui->keyword, SIGNAL(textEdited(QString)), this, SLOT(bookmarkEdited())); connect(ui->description, SIGNAL(textChanged()), this, SLOT(descriptionEdited())); } BookmarksManager::~BookmarksManager() { delete ui; } void BookmarksManager::setMainWindow(BrowserWindow* window) { if (window) { m_window = window; } } void BookmarksManager::search(const QString &string) { ui->tree->search(string); } void BookmarksManager::bookmarkActivated(BookmarkItem* item) { openBookmark(item); } void BookmarksManager::bookmarkCtrlActivated(BookmarkItem* item) { openBookmarkInNewTab(item); } void BookmarksManager::bookmarkShiftActivated(BookmarkItem* item) { openBookmarkInNewWindow(item); } void BookmarksManager::bookmarksSelected(const QList &items) { if (items.size() != 1) { m_selectedBookmark = 0; updateEditBox(0); } else { m_selectedBookmark = items.at(0); updateEditBox(m_selectedBookmark); } } void BookmarksManager::createContextMenu(const QPoint &pos) { QMenu menu; QAction* actNewTab = menu.addAction(IconProvider::newTabIcon(), tr("Open in new tab")); QAction* actNewWindow = menu.addAction(IconProvider::newWindowIcon(), tr("Open in new window")); QAction* actNewPrivateWindow = menu.addAction(IconProvider::privateBrowsingIcon(), tr("Open in new private window")); menu.addSeparator(); menu.addAction(tr("New Bookmark"), this, SLOT(addBookmark())); menu.addAction(tr("New Folder"), this, SLOT(addFolder())); menu.addAction(tr("New Separator"), this, SLOT(addSeparator())); menu.addSeparator(); QAction* actDelete = menu.addAction(QIcon::fromTheme("edit-delete"), tr("Delete")); connect(actNewTab, SIGNAL(triggered()), this, SLOT(openBookmarkInNewTab())); connect(actNewWindow, SIGNAL(triggered()), this, SLOT(openBookmarkInNewWindow())); connect(actNewPrivateWindow, SIGNAL(triggered()), this, SLOT(openBookmarkInNewPrivateWindow())); connect(actDelete, SIGNAL(triggered()), this, SLOT(deleteBookmarks())); bool canBeDeleted = false; QList items = ui->tree->selectedBookmarks(); foreach (BookmarkItem* item, items) { if (m_bookmarks->canBeModified(item)) { canBeDeleted = true; break; } } if (!canBeDeleted) { actDelete->setDisabled(true); } if (!m_selectedBookmark || !m_selectedBookmark->isUrl()) { actNewTab->setDisabled(true); actNewWindow->setDisabled(true); actNewPrivateWindow->setDisabled(true); } menu.exec(pos); } void BookmarksManager::openBookmark(BookmarkItem* item) { item = item ? item : m_selectedBookmark; - BookmarksTools::openBookmark(getQupZilla(), item); + BookmarksTools::openBookmark(getWindow(), item); } void BookmarksManager::openBookmarkInNewTab(BookmarkItem* item) { item = item ? item : m_selectedBookmark; - BookmarksTools::openBookmarkInNewTab(getQupZilla(), item); + BookmarksTools::openBookmarkInNewTab(getWindow(), item); } void BookmarksManager::openBookmarkInNewWindow(BookmarkItem* item) { item = item ? item : m_selectedBookmark; BookmarksTools::openBookmarkInNewWindow(item); } void BookmarksManager::openBookmarkInNewPrivateWindow(BookmarkItem* item) { item = item ? item : m_selectedBookmark; BookmarksTools::openBookmarkInNewPrivateWindow(item); } void BookmarksManager::addBookmark() { BookmarkItem* item = new BookmarkItem(BookmarkItem::Url); item->setTitle(tr("New Bookmark")); item->setUrl(QUrl("http://")); addBookmark(item); } void BookmarksManager::addFolder() { BookmarkItem* item = new BookmarkItem(BookmarkItem::Folder); item->setTitle(tr("New Folder")); addBookmark(item); } void BookmarksManager::addSeparator() { BookmarkItem* item = new BookmarkItem(BookmarkItem::Separator); addBookmark(item); } void BookmarksManager::deleteBookmarks() { QList items = ui->tree->selectedBookmarks(); foreach (BookmarkItem* item, items) { if (m_bookmarks->canBeModified(item)) { m_bookmarks->removeBookmark(item); } } } void BookmarksManager::bookmarkEdited() { Q_ASSERT(ui->tree->selectedBookmarks().count() == 1); BookmarkItem* item = ui->tree->selectedBookmarks().at(0); item->setTitle(ui->title->text()); item->setUrl(QUrl::fromEncoded(ui->address->text().toUtf8())); item->setKeyword(ui->keyword->text()); item->setDescription(ui->description->toPlainText()); m_bookmarks->changeBookmark(item); } void BookmarksManager::descriptionEdited() { // There is no textEdited() signal in QPlainTextEdit // textChanged() is emitted also when text is changed programatically if (!m_blockDescriptionChangedSignal) { bookmarkEdited(); } } void BookmarksManager::enableUpdates() { setUpdatesEnabled(true); } void BookmarksManager::updateEditBox(BookmarkItem* item) { setUpdatesEnabled(false); m_blockDescriptionChangedSignal = true; bool editable = bookmarkEditable(item); bool showAddressAndKeyword = item && item->isUrl(); if (!item) { ui->title->clear(); ui->address->clear(); ui->keyword->clear(); ui->description->clear(); } else { ui->title->setText(item->title()); ui->address->setText(item->url().toEncoded()); ui->keyword->setText(item->keyword()); ui->description->setPlainText(item->description()); ui->title->setCursorPosition(0); ui->address->setCursorPosition(0); ui->keyword->setCursorPosition(0); ui->description->moveCursor(QTextCursor::Start); } ui->title->setReadOnly(!editable); ui->address->setReadOnly(!editable); ui->keyword->setReadOnly(!editable); ui->description->setReadOnly(!editable); ui->labelAddress->setVisible(showAddressAndKeyword); ui->address->setVisible(showAddressAndKeyword); ui->labelKeyword->setVisible(showAddressAndKeyword); ui->keyword->setVisible(showAddressAndKeyword); // Without removing widgets from layout, there is unwanted extra spacing QFormLayout* l = static_cast(ui->editBox->layout()); if (showAddressAndKeyword) { // Show Address + Keyword l->insertRow(1, ui->labelAddress, ui->address); l->insertRow(2, ui->labelKeyword, ui->keyword); } else { // Hide Address + Keyword l->removeWidget(ui->labelAddress); l->removeWidget(ui->labelKeyword); l->removeWidget(ui->address); l->removeWidget(ui->keyword); } m_blockDescriptionChangedSignal = false; // Prevent flickering QTimer::singleShot(10, this, SLOT(enableUpdates())); } bool BookmarksManager::bookmarkEditable(BookmarkItem* item) const { return item && (item->isFolder() || item->isUrl()) && m_bookmarks->canBeModified(item); } void BookmarksManager::addBookmark(BookmarkItem* item) { BookmarkItem* parent = parentForNewBookmark(); Q_ASSERT(parent); m_bookmarks->insertBookmark(parent, 0, item); // Select newly added bookmark ui->tree->selectBookmark(item); ui->tree->ensureBookmarkVisible(item); // Start editing title if (!item->isSeparator()) { ui->title->setFocus(); ui->title->selectAll(); } } BookmarkItem* BookmarksManager::parentForNewBookmark() const { if (m_selectedBookmark && m_selectedBookmark->isFolder()) { return m_selectedBookmark; } if (!m_selectedBookmark || m_selectedBookmark->parent() == m_bookmarks->rootItem()) { return m_bookmarks->unsortedFolder(); } return m_selectedBookmark->parent(); } void BookmarksManager::keyPressEvent(QKeyEvent* event) { switch (event->key()) { case Qt::Key_Delete: deleteBookmarks(); break; } QWidget::keyPressEvent(event); } -BrowserWindow* BookmarksManager::getQupZilla() +BrowserWindow* BookmarksManager::getWindow() { if (!m_window) { m_window = mApp->getWindow(); } return m_window.data(); } void BookmarksManager::showEvent(QShowEvent* event) { QWidget::showEvent(event); if (m_adjustHeaderSizesOnShow) { ui->tree->header()->resizeSection(0, ui->tree->header()->width() / 1.9); m_adjustHeaderSizesOnShow = false; } } diff --git a/src/lib/bookmarks/bookmarksmanager.h b/src/lib/bookmarks/bookmarksmanager.h index 68af400e..fb417ec3 100644 --- a/src/lib/bookmarks/bookmarksmanager.h +++ b/src/lib/bookmarks/bookmarksmanager.h @@ -1,91 +1,91 @@ /* ============================================================ * QupZilla - WebKit based browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef BOOKMARKSMANAGER_H #define BOOKMARKSMANAGER_H #include #include #include "qzcommon.h" namespace Ui { class BookmarksManager; } class QUrl; class BrowserWindow; class Bookmarks; class BookmarkItem; -class QUPZILLA_EXPORT BookmarksManager : public QWidget +class FALKON_EXPORT BookmarksManager : public QWidget { Q_OBJECT public: explicit BookmarksManager(BrowserWindow* window, QWidget* parent = 0); ~BookmarksManager(); void setMainWindow(BrowserWindow* window); public slots: void search(const QString &string); private slots: void bookmarkActivated(BookmarkItem* item); void bookmarkCtrlActivated(BookmarkItem* item); void bookmarkShiftActivated(BookmarkItem* item); void bookmarksSelected(const QList &items); void createContextMenu(const QPoint &pos); void openBookmark(BookmarkItem* item = 0); void openBookmarkInNewTab(BookmarkItem* item = 0); void openBookmarkInNewWindow(BookmarkItem* item = 0); void openBookmarkInNewPrivateWindow(BookmarkItem* item = 0); void addBookmark(); void addFolder(); void addSeparator(); void deleteBookmarks(); void bookmarkEdited(); void descriptionEdited(); void enableUpdates(); private: void updateEditBox(BookmarkItem* item); bool bookmarkEditable(BookmarkItem* item) const; void addBookmark(BookmarkItem* item); BookmarkItem* parentForNewBookmark() const; - BrowserWindow* getQupZilla(); + BrowserWindow* getWindow(); void showEvent(QShowEvent* event); void keyPressEvent(QKeyEvent* event); Ui::BookmarksManager* ui; QPointer m_window; Bookmarks* m_bookmarks; BookmarkItem* m_selectedBookmark; bool m_blockDescriptionChangedSignal; bool m_adjustHeaderSizesOnShow; }; #endif // BOOKMARKSMANAGER_H diff --git a/src/lib/bookmarks/bookmarksmenu.cpp b/src/lib/bookmarks/bookmarksmenu.cpp index 78202a78..4dd12a22 100644 --- a/src/lib/bookmarks/bookmarksmenu.cpp +++ b/src/lib/bookmarks/bookmarksmenu.cpp @@ -1,197 +1,197 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "bookmarksmenu.h" #include "bookmarkstools.h" #include "bookmarkitem.h" #include "bookmarks.h" #include "mainapplication.h" #include "browsinglibrary.h" #include "browserwindow.h" #include "qzsettings.h" #include "tabwidget.h" #include "iconprovider.h" BookmarksMenu::BookmarksMenu(QWidget* parent) : Menu(parent) , m_window(0) , m_changed(true) { init(); connect(mApp->bookmarks(), SIGNAL(bookmarkAdded(BookmarkItem*)), this, SLOT(bookmarksChanged())); connect(mApp->bookmarks(), SIGNAL(bookmarkRemoved(BookmarkItem*)), this, SLOT(bookmarksChanged())); connect(mApp->bookmarks(), SIGNAL(bookmarkChanged(BookmarkItem*)), this, SLOT(bookmarksChanged())); } void BookmarksMenu::setMainWindow(BrowserWindow* window) { Q_ASSERT(window); m_window = window; } void BookmarksMenu::bookmarkPage() { if (m_window) { m_window->bookmarkPage(); } } void BookmarksMenu::bookmarkAllTabs() { if (m_window) { BookmarksTools::bookmarkAllTabsDialog(m_window, m_window->tabWidget()); } } void BookmarksMenu::showBookmarksManager() { if (m_window) { mApp->browsingLibrary()->showBookmarks(m_window); } } void BookmarksMenu::bookmarksChanged() { m_changed = true; } void BookmarksMenu::aboutToShow() { if (m_changed) { refresh(); m_changed = false; } } void BookmarksMenu::menuAboutToShow() { Q_ASSERT(qobject_cast(sender())); Menu *menu = static_cast(sender()); foreach (QAction *action, menu->actions()) { BookmarkItem *item = static_cast(action->data().value()); if (item && item->type() == BookmarkItem::Url && action->icon().isNull()) { action->setIcon(item->icon()); } } } void BookmarksMenu::menuMiddleClicked(Menu* menu) { BookmarkItem* item = static_cast(menu->menuAction()->data().value()); Q_ASSERT(item); openFolder(item); } void BookmarksMenu::bookmarkActivated() { if (QAction* action = qobject_cast(sender())) { BookmarkItem* item = static_cast(action->data().value()); Q_ASSERT(item); openBookmark(item); } } void BookmarksMenu::bookmarkCtrlActivated() { if (QAction* action = qobject_cast(sender())) { BookmarkItem* item = static_cast(action->data().value()); Q_ASSERT(item); openBookmarkInNewTab(item); } } void BookmarksMenu::bookmarkShiftActivated() { if (QAction* action = qobject_cast(sender())) { BookmarkItem* item = static_cast(action->data().value()); Q_ASSERT(item); openBookmarkInNewWindow(item); } } void BookmarksMenu::openFolder(BookmarkItem* item) { Q_ASSERT(item->isFolder()); if (m_window) { BookmarksTools::openFolderInTabs(m_window, item); } } void BookmarksMenu::openBookmark(BookmarkItem* item) { Q_ASSERT(item->isUrl()); if (m_window) { BookmarksTools::openBookmark(m_window, item); } } void BookmarksMenu::openBookmarkInNewTab(BookmarkItem* item) { Q_ASSERT(item->isUrl()); if (m_window) { BookmarksTools::openBookmarkInNewTab(m_window, item); } } void BookmarksMenu::openBookmarkInNewWindow(BookmarkItem* item) { Q_ASSERT(item->isUrl()); BookmarksTools::openBookmarkInNewWindow(item); } void BookmarksMenu::init() { setTitle(tr("&Bookmarks")); addAction(tr("Bookmark &This Page"), this, SLOT(bookmarkPage()))->setShortcut(QKeySequence("Ctrl+D")); addAction(tr("Bookmark &All Tabs"), this, SLOT(bookmarkAllTabs())); addAction(QIcon::fromTheme("bookmarks-organize"), tr("Organize &Bookmarks"), this, SLOT(showBookmarksManager()))->setShortcut(QKeySequence("Ctrl+Shift+O")); addSeparator(); connect(this, SIGNAL(aboutToShow()), this, SLOT(aboutToShow())); connect(this, SIGNAL(aboutToShow()), this, SLOT(menuAboutToShow())); connect(this, SIGNAL(menuMiddleClicked(Menu*)), this, SLOT(menuMiddleClicked(Menu*))); } void BookmarksMenu::refresh() { while (actions().count() != 4) { QAction* act = actions().at(4); if (act->menu()) { act->menu()->clear(); } removeAction(act); delete act; } BookmarksTools::addActionToMenu(this, this, mApp->bookmarks()->toolbarFolder()); addSeparator(); foreach (BookmarkItem* child, mApp->bookmarks()->menuFolder()->children()) { BookmarksTools::addActionToMenu(this, this, child); } addSeparator(); BookmarksTools::addActionToMenu(this, this, mApp->bookmarks()->unsortedFolder()); } diff --git a/src/lib/bookmarks/bookmarksmenu.h b/src/lib/bookmarks/bookmarksmenu.h index e780c22b..edb6c412 100644 --- a/src/lib/bookmarks/bookmarksmenu.h +++ b/src/lib/bookmarks/bookmarksmenu.h @@ -1,65 +1,65 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef BOOKMARKSMENU_H #define BOOKMARKSMENU_H #include #include "enhancedmenu.h" #include "qzcommon.h" class BrowserWindow; class BookmarkItem; -class QUPZILLA_EXPORT BookmarksMenu : public Menu +class FALKON_EXPORT BookmarksMenu : public Menu { Q_OBJECT public: explicit BookmarksMenu(QWidget* parent = 0); void setMainWindow(BrowserWindow* window); private slots: void bookmarkPage(); void bookmarkAllTabs(); void showBookmarksManager(); void bookmarksChanged(); void aboutToShow(); void menuAboutToShow(); void menuMiddleClicked(Menu* menu); void bookmarkActivated(); void bookmarkCtrlActivated(); void bookmarkShiftActivated(); void openFolder(BookmarkItem* item); void openBookmark(BookmarkItem* item); void openBookmarkInNewTab(BookmarkItem* item); void openBookmarkInNewWindow(BookmarkItem* item); private: void init(); void refresh(); QPointer m_window; bool m_changed; }; #endif // BOOKMARKSMENU_H diff --git a/src/lib/bookmarks/bookmarksmodel.cpp b/src/lib/bookmarks/bookmarksmodel.cpp index 1c4604d7..9d69b13e 100644 --- a/src/lib/bookmarks/bookmarksmodel.cpp +++ b/src/lib/bookmarks/bookmarksmodel.cpp @@ -1,351 +1,351 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2014-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "bookmarksmodel.h" #include "bookmarkitem.h" #include "bookmarks.h" #include #include #include #include //#define BOOKMARKSMODEL_DEBUG #ifdef BOOKMARKSMODEL_DEBUG #include "modeltest.h" #endif BookmarksModel::BookmarksModel(BookmarkItem* root, Bookmarks* bookmarks, QObject* parent) : QAbstractItemModel(parent) , m_root(root) , m_bookmarks(bookmarks) { if (m_bookmarks) { connect(m_bookmarks, SIGNAL(bookmarkChanged(BookmarkItem*)), this, SLOT(bookmarkChanged(BookmarkItem*))); } #ifdef BOOKMARKSMODEL_DEBUG new ModelTest(this, this); #endif } void BookmarksModel::addBookmark(BookmarkItem* parent, int row, BookmarkItem* item) { Q_ASSERT(parent); Q_ASSERT(item); Q_ASSERT(row >= 0); Q_ASSERT(row <= parent->children().count()); beginInsertRows(index(parent), row, row); parent->addChild(item, row); endInsertRows(); } void BookmarksModel::removeBookmark(BookmarkItem* item) { Q_ASSERT(item); Q_ASSERT(item->parent()); int idx = item->parent()->children().indexOf(item); beginRemoveRows(index(item->parent()), idx, idx); item->parent()->removeChild(item); endRemoveRows(); } Qt::ItemFlags BookmarksModel::flags(const QModelIndex &index) const { BookmarkItem* itm = item(index); if (!index.isValid() || !itm) { return Qt::NoItemFlags; } Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable; if (itm->isFolder()) { flags |= Qt::ItemIsDropEnabled; } if (m_bookmarks && m_bookmarks->canBeModified(itm)) { flags |= Qt::ItemIsDragEnabled; } return flags; } QVariant BookmarksModel::data(const QModelIndex &index, int role) const { BookmarkItem* itm = item(index); if (!itm) { return QVariant(); } switch (role) { case TypeRole: return itm->type(); case UrlRole: return itm->url(); case UrlStringRole: return itm->urlString(); case TitleRole: return itm->title(); case DescriptionRole: return itm->description(); case KeywordRole: return itm->keyword(); case VisitCountRole: return -1; case ExpandedRole: return itm->isExpanded(); case SidebarExpandedRole: return itm->isSidebarExpanded(); case Qt::ToolTipRole: if (index.column() == 0 && itm->isUrl()) { return QString("%1\n%2").arg(itm->title(), QString::fromUtf8(itm->url().toEncoded())); } // fallthrough case Qt::DisplayRole: switch (index.column()) { case 0: return itm->title(); case 1: return itm->url().toEncoded(); default: return QVariant(); } case Qt::DecorationRole: if (index.column() == 0) { return itm->icon(); } return QVariant(); default: return QVariant(); } } QVariant BookmarksModel::headerData(int section, Qt::Orientation orientation, int role) const { if (orientation == Qt::Horizontal && role == Qt::DisplayRole) { switch (section) { case 0: return tr("Title"); case 1: return tr("Address"); } } return QAbstractItemModel::headerData(section, orientation, role); } int BookmarksModel::rowCount(const QModelIndex &parent) const { if (parent.column() > 0) { return 0; } BookmarkItem* itm = item(parent); return itm->children().count(); } int BookmarksModel::columnCount(const QModelIndex &parent) const { if (parent.column() > 0) { return 0; } return 2; } bool BookmarksModel::hasChildren(const QModelIndex &parent) const { BookmarkItem* itm = item(parent); return !itm->children().isEmpty(); } Qt::DropActions BookmarksModel::supportedDropActions() const { return Qt::CopyAction | Qt::MoveAction; } -#define MIMETYPE QLatin1String("application/qupzilla.bookmarks") +#define MIMETYPE QLatin1String("application/falkon.bookmarks") QStringList BookmarksModel::mimeTypes() const { QStringList types; types.append(MIMETYPE); return types; } QMimeData* BookmarksModel::mimeData(const QModelIndexList &indexes) const { QMimeData* mimeData = new QMimeData(); QByteArray encodedData; QDataStream stream(&encodedData, QIODevice::WriteOnly); foreach (const QModelIndex &index, indexes) { // If item's parent (=folder) is also selected, we will just move the whole folder if (index.isValid() && index.column() == 0 && !indexes.contains(index.parent())) { stream << index.row() << (quintptr) index.internalPointer(); } } mimeData->setData(MIMETYPE, encodedData); return mimeData; } bool BookmarksModel::dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex &parent) { Q_UNUSED(column) if (action == Qt::IgnoreAction) { return true; } if (!m_bookmarks || !data->hasFormat(MIMETYPE) || !parent.isValid()) { return false; } BookmarkItem* parentItm = item(parent); Q_ASSERT(parentItm->isFolder()); QByteArray encodedData = data->data(MIMETYPE); QDataStream stream(&encodedData, QIODevice::ReadOnly); QList items; while (!stream.atEnd()) { int row; quintptr ptr; stream >> row >> ptr; QModelIndex index = createIndex(row, 0, (void*) ptr); BookmarkItem* itm = item(index); Q_ASSERT(index.isValid()); Q_ASSERT(itm != m_bookmarks->rootItem()); // Cannot move bookmark to itself if (itm == parentItm) { return false; } items.append(itm); } row = qMax(row, 0); foreach (BookmarkItem* itm, items) { // If we are moving an item through the folder and item is above the row to insert, // we must decrease row by one (by the dropped folder) if (itm->parent() == parentItm && itm->parent()->children().indexOf(itm) < row) { row--; } m_bookmarks->removeBookmark(itm); m_bookmarks->insertBookmark(parentItm, row++, itm); } return true; } QModelIndex BookmarksModel::parent(const QModelIndex &child) const { if (!child.isValid()) { return QModelIndex(); } BookmarkItem* itm = item(child); return index(itm->parent()); } QModelIndex BookmarksModel::index(int row, int column, const QModelIndex &parent) const { if (!hasIndex(row, column, parent)) { return QModelIndex(); } BookmarkItem* parentItem = item(parent); return createIndex(row, column, parentItem->children().at(row)); } QModelIndex BookmarksModel::index(BookmarkItem* item, int column) const { BookmarkItem* parent = item->parent(); if (!parent) { return QModelIndex(); } return createIndex(parent->children().indexOf(item), column, item); } BookmarkItem* BookmarksModel::item(const QModelIndex &index) const { BookmarkItem* itm = static_cast(index.internalPointer()); return itm ? itm : m_root; } void BookmarksModel::bookmarkChanged(BookmarkItem* item) { QModelIndex idx = index(item); emit dataChanged(idx, idx); } // BookmarksFilterModel BookmarksFilterModel::BookmarksFilterModel(QAbstractItemModel* parent) : QSortFilterProxyModel(parent) { setSourceModel(parent); setFilterCaseSensitivity(Qt::CaseInsensitive); m_filterTimer = new QTimer(this); m_filterTimer->setSingleShot(true); m_filterTimer->setInterval(300); connect(m_filterTimer, SIGNAL(timeout()), this, SLOT(startFiltering())); } void BookmarksFilterModel::setFilterFixedString(const QString &pattern) { m_pattern = pattern; m_filterTimer->start(); } bool BookmarksFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const { const QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent); if (index.data(BookmarksModel::TypeRole).toInt() == BookmarkItem::Folder) { return true; } return (index.data(BookmarksModel::TitleRole).toString().contains(m_pattern, filterCaseSensitivity()) || index.data(BookmarksModel::UrlStringRole).toString().contains(m_pattern, filterCaseSensitivity()) || index.data(BookmarksModel::DescriptionRole).toString().contains(m_pattern, filterCaseSensitivity()) || index.data(BookmarksModel::KeywordRole).toString().compare(m_pattern, filterCaseSensitivity()) == 0); } void BookmarksFilterModel::startFiltering() { QSortFilterProxyModel::setFilterFixedString(m_pattern); } diff --git a/src/lib/bookmarks/bookmarksmodel.h b/src/lib/bookmarks/bookmarksmodel.h index ad3b498a..e5bccc4a 100644 --- a/src/lib/bookmarks/bookmarksmodel.h +++ b/src/lib/bookmarks/bookmarksmodel.h @@ -1,102 +1,102 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef BOOKMARKSMODEL_H #define BOOKMARKSMODEL_H #include #include #include "qzcommon.h" class QTimer; class Bookmarks; class BookmarkItem; -class QUPZILLA_EXPORT BookmarksModel : public QAbstractItemModel +class FALKON_EXPORT BookmarksModel : public QAbstractItemModel { Q_OBJECT public: enum Roles { TypeRole = Qt::UserRole + 1, UrlRole = Qt::UserRole + 2, UrlStringRole = Qt::UserRole + 3, TitleRole = Qt::UserRole + 4, IconRole = Qt::UserRole + 5, DescriptionRole = Qt::UserRole + 6, KeywordRole = Qt::UserRole + 7, VisitCountRole = Qt::UserRole + 8, ExpandedRole = Qt::UserRole + 9, SidebarExpandedRole = Qt::UserRole + 10, MaxRole = SidebarExpandedRole }; explicit BookmarksModel(BookmarkItem* root, Bookmarks* bookmarks, QObject* parent = 0); void addBookmark(BookmarkItem* parent, int row, BookmarkItem* item); void removeBookmark(BookmarkItem* item); Qt::ItemFlags flags(const QModelIndex &index) const; QVariant data(const QModelIndex &index, int role) const; QVariant headerData(int section, Qt::Orientation orientation, int role) const; int rowCount(const QModelIndex &parent) const; int columnCount(const QModelIndex &parent) const; bool hasChildren(const QModelIndex &parent) const; Qt::DropActions supportedDropActions() const; QStringList mimeTypes() const; QMimeData* mimeData(const QModelIndexList &indexes) const; bool dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex &parent); QModelIndex parent(const QModelIndex &child) const; QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; QModelIndex index(BookmarkItem* item, int column = 0) const; BookmarkItem* item(const QModelIndex &index) const; private slots: void bookmarkChanged(BookmarkItem* item); private: BookmarkItem* m_root; Bookmarks* m_bookmarks; }; -class QUPZILLA_EXPORT BookmarksFilterModel : public QSortFilterProxyModel +class FALKON_EXPORT BookmarksFilterModel : public QSortFilterProxyModel { Q_OBJECT public: explicit BookmarksFilterModel(QAbstractItemModel* parent); public slots: void setFilterFixedString(const QString &pattern); protected: bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const; private slots: void startFiltering(); private: QString m_pattern; QTimer* m_filterTimer; }; #endif // BOOKMARKSMODEL_H diff --git a/src/lib/bookmarks/bookmarkstoolbar.cpp b/src/lib/bookmarks/bookmarkstoolbar.cpp index 56749f56..ffc8b5b5 100644 --- a/src/lib/bookmarks/bookmarkstoolbar.cpp +++ b/src/lib/bookmarks/bookmarkstoolbar.cpp @@ -1,260 +1,260 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "bookmarkstoolbar.h" #include "bookmarkstoolbarbutton.h" #include "bookmarkstools.h" #include "bookmarkitem.h" #include "bookmarks.h" #include "mainapplication.h" #include "iconprovider.h" #include #include #include #include #include BookmarksToolbar::BookmarksToolbar(BrowserWindow* window, QWidget* parent) : QWidget(parent) , m_window(window) , m_bookmarks(mApp->bookmarks()) , m_clickedBookmark(0) { setObjectName("bookmarksbar"); setAcceptDrops(true); setContextMenuPolicy(Qt::CustomContextMenu); m_layout = new QHBoxLayout(this); m_layout->setMargin(1); #ifndef Q_OS_MACOS m_layout->setSpacing(0); #endif setLayout(m_layout); // Set some sane value, will be updated to correct value on first added button setMinimumHeight(25); m_updateTimer = new QTimer(this); m_updateTimer->setInterval(300); m_updateTimer->setSingleShot(true); connect(m_updateTimer, SIGNAL(timeout()), this, SLOT(refresh())); connect(m_bookmarks, SIGNAL(bookmarkAdded(BookmarkItem*)), this, SLOT(bookmarksChanged())); connect(m_bookmarks, SIGNAL(bookmarkRemoved(BookmarkItem*)), this, SLOT(bookmarksChanged())); connect(m_bookmarks, SIGNAL(bookmarkChanged(BookmarkItem*)), this, SLOT(bookmarksChanged())); connect(m_bookmarks, SIGNAL(showOnlyIconsInToolbarChanged(bool)), this, SLOT(showOnlyIconsChanged(bool))); connect(m_bookmarks, SIGNAL(showOnlyTextInToolbarChanged(bool)), this, SLOT(showOnlyTextChanged(bool))); connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextMenuRequested(QPoint))); refresh(); } void BookmarksToolbar::contextMenuRequested(const QPoint &pos) { BookmarksToolbarButton* button = buttonAt(pos); m_clickedBookmark = button ? button->bookmark() : 0; QMenu menu; QAction* actNewTab = menu.addAction(IconProvider::newTabIcon(), tr("Open in new tab")); QAction* actNewWindow = menu.addAction(IconProvider::newWindowIcon(), tr("Open in new window")); QAction* actNewPrivateWindow = menu.addAction(IconProvider::privateBrowsingIcon(), tr("Open in new private window")); menu.addSeparator(); QAction* actEdit = menu.addAction(tr("Edit")); QAction* actDelete = menu.addAction(QIcon::fromTheme("edit-delete"), tr("Delete")); menu.addSeparator(); m_actShowOnlyIcons = menu.addAction(tr("Show Only Icons")); m_actShowOnlyIcons->setCheckable(true); m_actShowOnlyIcons->setChecked(m_bookmarks->showOnlyIconsInToolbar()); connect(m_actShowOnlyIcons, SIGNAL(toggled(bool)), m_bookmarks, SLOT(setShowOnlyIconsInToolbar(bool))); m_actShowOnlyText = menu.addAction(tr("Show Only Text")); m_actShowOnlyText->setCheckable(true); m_actShowOnlyText->setChecked(m_bookmarks->showOnlyTextInToolbar()); connect(m_actShowOnlyText, SIGNAL(toggled(bool)), m_bookmarks, SLOT(setShowOnlyTextInToolbar(bool))); connect(actNewTab, SIGNAL(triggered()), this, SLOT(openBookmarkInNewTab())); connect(actNewWindow, SIGNAL(triggered()), this, SLOT(openBookmarkInNewWindow())); connect(actNewPrivateWindow, SIGNAL(triggered()), this, SLOT(openBookmarkInNewPrivateWindow())); connect(actEdit, SIGNAL(triggered()), this, SLOT(editBookmark())); connect(actDelete, SIGNAL(triggered()), this, SLOT(deleteBookmark())); actEdit->setEnabled(m_clickedBookmark && m_bookmarks->canBeModified(m_clickedBookmark)); actDelete->setEnabled(m_clickedBookmark && m_bookmarks->canBeModified(m_clickedBookmark)); actNewTab->setEnabled(m_clickedBookmark && m_clickedBookmark->isUrl()); actNewWindow->setEnabled(m_clickedBookmark && m_clickedBookmark->isUrl()); actNewPrivateWindow->setEnabled(m_clickedBookmark && m_clickedBookmark->isUrl()); menu.exec(mapToGlobal(pos)); if (button) { // Clear mouseover state after closing menu button->update(); } m_clickedBookmark = nullptr; m_actShowOnlyIcons = nullptr; m_actShowOnlyText = nullptr; } void BookmarksToolbar::refresh() { clear(); BookmarkItem* folder = mApp->bookmarks()->toolbarFolder(); foreach (BookmarkItem* child, folder->children()) { addItem(child); } m_layout->addStretch(); } void BookmarksToolbar::bookmarksChanged() { m_updateTimer->start(); } void BookmarksToolbar::showOnlyIconsChanged(bool state) { if (state && m_actShowOnlyText) { m_actShowOnlyText->setChecked(false); } for (int i = 0; i < m_layout->count(); ++i) { BookmarksToolbarButton* b = qobject_cast(m_layout->itemAt(i)->widget()); if (b) { b->setShowOnlyIcon(state); } } } void BookmarksToolbar::showOnlyTextChanged(bool state) { if (state && m_actShowOnlyIcons) { m_actShowOnlyIcons->setChecked(false); } for (int i = 0; i < m_layout->count(); ++i) { BookmarksToolbarButton* b = qobject_cast(m_layout->itemAt(i)->widget()); if (b) { b->setShowOnlyText(state); } } } void BookmarksToolbar::openBookmarkInNewTab() { if (m_clickedBookmark) { BookmarksTools::openBookmarkInNewTab(m_window, m_clickedBookmark); } } void BookmarksToolbar::openBookmarkInNewWindow() { if (m_clickedBookmark) { BookmarksTools::openBookmarkInNewWindow(m_clickedBookmark); } } void BookmarksToolbar::openBookmarkInNewPrivateWindow() { if (m_clickedBookmark) { BookmarksTools::openBookmarkInNewPrivateWindow(m_clickedBookmark); } } void BookmarksToolbar::editBookmark() { if (m_clickedBookmark) { BookmarksTools::editBookmarkDialog(this, m_clickedBookmark); m_bookmarks->changeBookmark(m_clickedBookmark); } } void BookmarksToolbar::deleteBookmark() { if (m_clickedBookmark) { m_bookmarks->removeBookmark(m_clickedBookmark); } } void BookmarksToolbar::clear() { int count = m_layout->count(); for (int i = 0; i < count; ++i) { QLayoutItem* item = m_layout->takeAt(0); delete item->widget(); delete item; } Q_ASSERT(m_layout->isEmpty()); } void BookmarksToolbar::addItem(BookmarkItem* item) { Q_ASSERT(item); BookmarksToolbarButton* button = new BookmarksToolbarButton(item, this); button->setMainWindow(m_window); button->setShowOnlyIcon(m_bookmarks->showOnlyIconsInToolbar()); button->setShowOnlyText(m_bookmarks->showOnlyTextInToolbar()); m_layout->addWidget(button); setFixedHeight(m_layout->spacing() * 2 + button->preferredHeight()); } BookmarksToolbarButton* BookmarksToolbar::buttonAt(const QPoint &pos) { return qobject_cast(QApplication::widgetAt(mapToGlobal(pos))); } void BookmarksToolbar::dropEvent(QDropEvent* e) { const QMimeData* mime = e->mimeData(); if (!mime->hasUrls()) { QWidget::dropEvent(e); return; } QUrl url = mime->urls().at(0); QString title = mime->hasText() ? mime->text() : url.toEncoded(QUrl::RemoveScheme); BookmarkItem* parent = m_bookmarks->toolbarFolder(); BookmarksToolbarButton* button = buttonAt(e->pos()); if (button && button->bookmark()->isFolder()) { parent = button->bookmark(); } BookmarkItem* bookmark = new BookmarkItem(BookmarkItem::Url); bookmark->setTitle(title); bookmark->setUrl(url); m_bookmarks->addBookmark(parent, bookmark); } void BookmarksToolbar::dragEnterEvent(QDragEnterEvent* e) { const QMimeData* mime = e->mimeData(); if (mime->hasUrls() && mime->hasText()) { e->acceptProposedAction(); return; } QWidget::dragEnterEvent(e); } diff --git a/src/lib/bookmarks/bookmarkstoolbar.h b/src/lib/bookmarks/bookmarkstoolbar.h index f3f39e98..a9e3413f 100644 --- a/src/lib/bookmarks/bookmarkstoolbar.h +++ b/src/lib/bookmarks/bookmarkstoolbar.h @@ -1,70 +1,70 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef BOOKMARKSTOOLBAR_H #define BOOKMARKSTOOLBAR_H #include #include "qzcommon.h" class QHBoxLayout; class QTimer; class BrowserWindow; class Bookmarks; class BookmarkItem; class BookmarksToolbarButton; -class QUPZILLA_EXPORT BookmarksToolbar : public QWidget +class FALKON_EXPORT BookmarksToolbar : public QWidget { Q_OBJECT public: explicit BookmarksToolbar(BrowserWindow* window, QWidget* parent = 0); private slots: void contextMenuRequested(const QPoint &pos); void refresh(); void bookmarksChanged(); void showOnlyIconsChanged(bool state); void showOnlyTextChanged(bool state); void openBookmarkInNewTab(); void openBookmarkInNewWindow(); void openBookmarkInNewPrivateWindow(); void editBookmark(); void deleteBookmark(); private: void clear(); void addItem(BookmarkItem* item); BookmarksToolbarButton* buttonAt(const QPoint &pos); void dropEvent(QDropEvent* e); void dragEnterEvent(QDragEnterEvent* e); BrowserWindow* m_window; Bookmarks* m_bookmarks; BookmarkItem* m_clickedBookmark; QHBoxLayout* m_layout; QTimer* m_updateTimer; QAction* m_actShowOnlyIcons = nullptr; QAction* m_actShowOnlyText = nullptr; }; #endif // BOOKMARKSTOOLBAR_H diff --git a/src/lib/bookmarks/bookmarkstoolbarbutton.cpp b/src/lib/bookmarks/bookmarkstoolbarbutton.cpp index b04d802a..8dcd27f3 100644 --- a/src/lib/bookmarks/bookmarkstoolbarbutton.cpp +++ b/src/lib/bookmarks/bookmarkstoolbarbutton.cpp @@ -1,365 +1,365 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "bookmarkstoolbarbutton.h" #include "bookmarkstools.h" #include "bookmarkitem.h" #include "bookmarks.h" #include "mainapplication.h" #include "enhancedmenu.h" #include #include #include #include #define MAX_WIDTH 150 #define SEPARATOR_WIDTH 8 #define PADDING 5 BookmarksToolbarButton::BookmarksToolbarButton(BookmarkItem* bookmark, QWidget* parent) : QPushButton(parent) , m_bookmark(bookmark) , m_window(0) , m_showOnlyIcon(false) { init(); } BookmarkItem* BookmarksToolbarButton::bookmark() const { return m_bookmark; } void BookmarksToolbarButton::setMainWindow(BrowserWindow* window) { m_window = window; } bool BookmarksToolbarButton::showOnlyIcon() const { return m_showOnlyIcon; } void BookmarksToolbarButton::setShowOnlyIcon(bool show) { m_showOnlyIcon = show; updateGeometry(); update(); } bool BookmarksToolbarButton::showOnlyText() const { return m_showOnlyText; } void BookmarksToolbarButton::setShowOnlyText(bool show) { m_showOnlyText = show; updateGeometry(); update(); } QSize BookmarksToolbarButton::sizeHint() const { int width = PADDING * 2; if (!m_showOnlyText) { width += 16; } if (m_bookmark->isSeparator()) { width = SEPARATOR_WIDTH; } else if (!m_showOnlyIcon) { width += PADDING * 2 + fontMetrics().width(m_bookmark->title()); if (menu()) { width += PADDING + 8; } } return QSize(qMin(width, MAX_WIDTH), preferredHeight()); } QSize BookmarksToolbarButton::minimumSizeHint() const { int width = PADDING * 2; if (!m_showOnlyText) { width += 16; } if (m_bookmark->isSeparator()) { width = SEPARATOR_WIDTH; } else if (!m_showOnlyIcon && menu()) { width += PADDING + 8; } return QSize(width, preferredHeight()); } int BookmarksToolbarButton::preferredHeight() const { return fontMetrics().height() + PADDING * 2; } void BookmarksToolbarButton::createMenu() { if (!menu()->isEmpty()) { return; } Menu* m = qobject_cast(menu()); Q_ASSERT(m); BookmarksTools::addFolderContentsToMenu(this, m, m_bookmark); } void BookmarksToolbarButton::menuAboutToShow() { Q_ASSERT(qobject_cast(sender())); Menu *menu = static_cast(sender()); foreach (QAction *action, menu->actions()) { BookmarkItem *item = static_cast(action->data().value()); if (item && item->type() == BookmarkItem::Url && action->icon().isNull()) { action->setIcon(item->icon()); } } } void BookmarksToolbarButton::menuMiddleClicked(Menu* menu) { BookmarkItem* item = static_cast(menu->menuAction()->data().value()); Q_ASSERT(item); openFolder(item); } void BookmarksToolbarButton::bookmarkActivated(BookmarkItem* item) { if (QAction* action = qobject_cast(sender())) { item = static_cast(action->data().value()); } Q_ASSERT(item); openBookmark(item); } void BookmarksToolbarButton::bookmarkCtrlActivated(BookmarkItem* item) { if (QAction* action = qobject_cast(sender())) { item = static_cast(action->data().value()); } Q_ASSERT(item); openBookmarkInNewTab(item); } void BookmarksToolbarButton::bookmarkShiftActivated(BookmarkItem* item) { if (QAction* action = qobject_cast(sender())) { item = static_cast(action->data().value()); } Q_ASSERT(item); openBookmarkInNewWindow(item); } void BookmarksToolbarButton::openFolder(BookmarkItem* item) { Q_ASSERT(item->isFolder()); if (m_window) { BookmarksTools::openFolderInTabs(m_window, item); } } void BookmarksToolbarButton::openBookmark(BookmarkItem* item) { Q_ASSERT(item->isUrl()); if (m_window) { BookmarksTools::openBookmark(m_window, item); } } void BookmarksToolbarButton::openBookmarkInNewTab(BookmarkItem* item) { Q_ASSERT(item->isUrl()); if (m_window) { BookmarksTools::openBookmarkInNewTab(m_window, item); } } void BookmarksToolbarButton::openBookmarkInNewWindow(BookmarkItem* item) { Q_ASSERT(item->isUrl()); BookmarksTools::openBookmarkInNewWindow(item); } void BookmarksToolbarButton::init() { Q_ASSERT(m_bookmark); setFocusPolicy(Qt::NoFocus); setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred); setToolTip(createTooltip()); if (m_bookmark->isFolder()) { Menu* m = new Menu(this); setMenu(m); createMenu(); } } QString BookmarksToolbarButton::createTooltip() const { if (!m_bookmark->description().isEmpty()) { if (!m_bookmark->urlString().isEmpty()) { return QString("%1\n%2").arg(m_bookmark->description(), m_bookmark->urlString()); } return m_bookmark->description(); } if (!m_bookmark->url().isEmpty()) { return QString("%1\n%2").arg(m_bookmark->title(), m_bookmark->urlString()); } return m_bookmark->title(); } void BookmarksToolbarButton::enterEvent(QEvent* event) { QPushButton::enterEvent(event); update(); } void BookmarksToolbarButton::leaveEvent(QEvent* event) { QPushButton::leaveEvent(event); update(); } void BookmarksToolbarButton::mousePressEvent(QMouseEvent* event) { if (m_bookmark && m_bookmark->isFolder()) { if (event->buttons() == Qt::LeftButton && event->modifiers() == Qt::ControlModifier) { openFolder(m_bookmark); return; } } QPushButton::mousePressEvent(event); } void BookmarksToolbarButton::mouseReleaseEvent(QMouseEvent* event) { if (m_bookmark && rect().contains(event->pos())) { Qt::MouseButton button = event->button(); Qt::KeyboardModifiers modifiers = event->modifiers(); if (m_bookmark->isUrl()) { if (button == Qt::LeftButton && modifiers == Qt::NoModifier) { bookmarkActivated(m_bookmark); } else if (button == Qt::LeftButton && modifiers == Qt::ShiftModifier) { bookmarkShiftActivated(m_bookmark); } else if (button == Qt::MiddleButton || modifiers == Qt::ControlModifier) { bookmarkCtrlActivated(m_bookmark); } } else if (m_bookmark->isFolder() && button == Qt::MiddleButton) { openFolder(m_bookmark); } } QPushButton::mouseReleaseEvent(event); } void BookmarksToolbarButton::paintEvent(QPaintEvent* event) { Q_UNUSED(event) QPainter p(this); // Just draw separator if (m_bookmark->isSeparator()) { QStyleOption opt; opt.initFrom(this); opt.state |= QStyle::State_Horizontal; style()->drawPrimitive(QStyle::PE_IndicatorToolBarSeparator, &opt, &p); return; } QStyleOptionButton option; initStyleOption(&option); // We are manually drawing the arrow option.features &= ~QStyleOptionButton::HasMenu; // Draw button base (only under mouse, this is autoraise button) if (isDown() || underMouse()) { option.state |= QStyle::State_AutoRaise | QStyle::State_Raised; style()->drawPrimitive(QStyle::PE_PanelButtonTool, &option, &p, this); } const int shiftX = isDown() ? style()->pixelMetric(QStyle::PM_ButtonShiftHorizontal, &option, this) : 0; const int shiftY = isDown() ? style()->pixelMetric(QStyle::PM_ButtonShiftVertical, &option, this) : 0; const int height = option.rect.height(); const int center = height / 2 + option.rect.top() + shiftY; const int iconSize = 16; const int iconYPos = center - iconSize / 2; int leftPosition = PADDING + shiftX; int rightPosition = option.rect.right() - PADDING; // Draw icon if (!m_showOnlyText) { QRect iconRect(leftPosition, iconYPos, iconSize, iconSize); p.drawPixmap(QStyle::visualRect(option.direction, option.rect, iconRect), m_bookmark->icon().pixmap(iconSize)); leftPosition = iconRect.right() + PADDING; } // Draw menu arrow if (!m_showOnlyIcon && menu()) { const int arrowSize = 8; QStyleOption opt; opt.initFrom(this); const QRect rect = QRect(rightPosition - 8, center - arrowSize / 2, arrowSize, arrowSize); opt.rect = QStyle::visualRect(option.direction, option.rect, rect); opt.state &= ~QStyle::State_MouseOver; style()->drawPrimitive(QStyle::PE_IndicatorArrowDown, &opt, &p, this); rightPosition = rect.left() - PADDING; } // Draw text if (!m_showOnlyIcon) { const int textWidth = rightPosition - leftPosition; const int textYPos = center - fontMetrics().height() / 2; const QString txt = fontMetrics().elidedText(m_bookmark->title(), Qt::ElideRight, textWidth); QRect textRect(leftPosition, textYPos, textWidth, fontMetrics().height()); style()->drawItemText(&p, QStyle::visualRect(option.direction, option.rect, textRect), Qt::TextSingleLine | Qt::AlignCenter, option.palette, true, txt); } } diff --git a/src/lib/bookmarks/bookmarkstoolbarbutton.h b/src/lib/bookmarks/bookmarkstoolbarbutton.h index 1d5bac93..05faf29a 100644 --- a/src/lib/bookmarks/bookmarkstoolbarbutton.h +++ b/src/lib/bookmarks/bookmarkstoolbarbutton.h @@ -1,80 +1,80 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef BOOKMARKSTOOLBARBUTTON_H #define BOOKMARKSTOOLBARBUTTON_H #include #include "qzcommon.h" class Menu; class BrowserWindow; class BookmarkItem; -class QUPZILLA_EXPORT BookmarksToolbarButton : public QPushButton +class FALKON_EXPORT BookmarksToolbarButton : public QPushButton { Q_OBJECT public: explicit BookmarksToolbarButton(BookmarkItem* bookmark, QWidget* parent = 0); BookmarkItem* bookmark() const; void setMainWindow(BrowserWindow* window); bool showOnlyIcon() const; void setShowOnlyIcon(bool show); bool showOnlyText() const; void setShowOnlyText(bool show); QSize sizeHint() const; QSize minimumSizeHint() const; int preferredHeight() const; private slots: void createMenu(); void menuAboutToShow(); void menuMiddleClicked(Menu* menu); void bookmarkActivated(BookmarkItem* item = 0); void bookmarkCtrlActivated(BookmarkItem* item = 0); void bookmarkShiftActivated(BookmarkItem* item = 0); void openFolder(BookmarkItem* item); void openBookmark(BookmarkItem* item); void openBookmarkInNewTab(BookmarkItem* item); void openBookmarkInNewWindow(BookmarkItem* item); private: void init(); QString createTooltip() const; void enterEvent(QEvent* event); void leaveEvent(QEvent* event); void mousePressEvent(QMouseEvent* event); void mouseReleaseEvent(QMouseEvent* event); void paintEvent(QPaintEvent* event); BookmarkItem* m_bookmark; BrowserWindow* m_window; bool m_showOnlyIcon; bool m_showOnlyText; }; #endif // BOOKMARKSTOOLBARBUTTON_H diff --git a/src/lib/bookmarks/bookmarkstools.cpp b/src/lib/bookmarks/bookmarkstools.cpp index fc8d1b56..cd434751 100644 --- a/src/lib/bookmarks/bookmarkstools.cpp +++ b/src/lib/bookmarks/bookmarkstools.cpp @@ -1,489 +1,489 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2014-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "bookmarkstools.h" #include "bookmarkitem.h" #include "bookmarks.h" #include "mainapplication.h" #include "iconprovider.h" #include "enhancedmenu.h" #include "tabwidget.h" #include "qzsettings.h" #include "browserwindow.h" #include #include #include #include #include #include #include #include #include #include #include // BookmarksFoldersMenu BookmarksFoldersMenu::BookmarksFoldersMenu(QWidget* parent) : QMenu(parent) , m_selectedFolder(0) { init(); } BookmarkItem* BookmarksFoldersMenu::selectedFolder() const { return m_selectedFolder; } void BookmarksFoldersMenu::folderChoosed() { if (QAction* act = qobject_cast(sender())) { BookmarkItem* folder = static_cast(act->data().value()); emit folderSelected(folder); } } void BookmarksFoldersMenu::init() { #define ADD_MENU(name) \ BookmarkItem* f_##name = mApp->bookmarks()->name(); \ QMenu* m_##name = addMenu(f_##name->icon(), f_##name->title()); \ createMenu(m_##name, f_##name); ADD_MENU(toolbarFolder) ADD_MENU(menuFolder) ADD_MENU(unsortedFolder) #undef ADD_MENU } void BookmarksFoldersMenu::createMenu(QMenu* menu, BookmarkItem* parent) { QAction* act = menu->addAction(tr("Choose %1").arg(parent->title())); act->setData(QVariant::fromValue(static_cast(parent))); connect(act, SIGNAL(triggered()), this, SLOT(folderChoosed())); menu->addSeparator(); foreach (BookmarkItem* child, parent->children()) { if (child->isFolder()) { QMenu* m = menu->addMenu(child->icon(), child->title()); createMenu(m, child); } } } // BookmarksFoldersButton BookmarksFoldersButton::BookmarksFoldersButton(QWidget* parent, BookmarkItem* folder) : QPushButton(parent) , m_menu(new BookmarksFoldersMenu(this)) , m_selectedFolder(folder ? folder : mApp->bookmarks()->lastUsedFolder()) { init(); connect(m_menu, SIGNAL(folderSelected(BookmarkItem*)), this, SLOT(setSelectedFolder(BookmarkItem*))); } BookmarkItem* BookmarksFoldersButton::selectedFolder() const { return m_selectedFolder; } void BookmarksFoldersButton::setSelectedFolder(BookmarkItem* folder) { Q_ASSERT(folder); Q_ASSERT(folder->isFolder()); m_selectedFolder = folder; setText(folder->title()); setIcon(folder->icon()); if (sender()) { emit selectedFolderChanged(folder); } } void BookmarksFoldersButton::init() { setMenu(m_menu); setSelectedFolder(m_selectedFolder); } // BookmarksTools bool BookmarksTools::addBookmarkDialog(QWidget* parent, const QUrl &url, const QString &title, BookmarkItem* folder) { if (url.isEmpty() || title.isEmpty()) { return false; } QDialog* dialog = new QDialog(parent); QBoxLayout* layout = new QBoxLayout(QBoxLayout::TopToBottom, dialog); QLabel* label = new QLabel(dialog); QLineEdit* edit = new QLineEdit(dialog); BookmarksFoldersButton* folderButton = new BookmarksFoldersButton(dialog, folder); QDialogButtonBox* box = new QDialogButtonBox(dialog); box->addButton(QDialogButtonBox::Ok); box->addButton(QDialogButtonBox::Cancel); QObject::connect(box, SIGNAL(rejected()), dialog, SLOT(reject())); QObject::connect(box, SIGNAL(accepted()), dialog, SLOT(accept())); layout->addWidget(label); layout->addWidget(edit); layout->addWidget(folderButton); layout->addWidget(box); label->setText(Bookmarks::tr("Choose name and location of this bookmark.")); edit->setText(title); edit->setCursorPosition(0); dialog->setWindowIcon(IconProvider::iconForUrl(url)); dialog->setWindowTitle(Bookmarks::tr("Add New Bookmark")); QSize size = dialog->size(); size.setWidth(350); dialog->resize(size); dialog->exec(); if (dialog->result() == QDialog::Rejected || edit->text().isEmpty()) { delete dialog; return false; } BookmarkItem* bookmark = new BookmarkItem(BookmarkItem::Url); bookmark->setTitle(edit->text()); bookmark->setUrl(url); mApp->bookmarks()->addBookmark(folderButton->selectedFolder(), bookmark); delete dialog; return true; } bool BookmarksTools::bookmarkAllTabsDialog(QWidget* parent, TabWidget* tabWidget, BookmarkItem* folder) { Q_ASSERT(tabWidget); QDialog* dialog = new QDialog(parent); QBoxLayout* layout = new QBoxLayout(QBoxLayout::TopToBottom, dialog); QLabel* label = new QLabel(dialog); BookmarksFoldersButton* folderButton = new BookmarksFoldersButton(dialog, folder); QDialogButtonBox* box = new QDialogButtonBox(dialog); box->addButton(QDialogButtonBox::Ok); box->addButton(QDialogButtonBox::Cancel); QObject::connect(box, SIGNAL(rejected()), dialog, SLOT(reject())); QObject::connect(box, SIGNAL(accepted()), dialog, SLOT(accept())); layout->addWidget(label); layout->addWidget(folderButton); layout->addWidget(box); label->setText(Bookmarks::tr("Choose folder for bookmarks:")); dialog->setWindowTitle(Bookmarks::tr("Bookmark All Tabs")); QSize size = dialog->size(); size.setWidth(350); dialog->resize(size); dialog->exec(); if (dialog->result() == QDialog::Rejected) { return false; } foreach (WebTab* tab, tabWidget->allTabs(false)) { if (!tab->url().isEmpty()) { BookmarkItem* bookmark = new BookmarkItem(BookmarkItem::Url); bookmark->setTitle(tab->title()); bookmark->setUrl(tab->url()); mApp->bookmarks()->addBookmark(folderButton->selectedFolder(), bookmark); } } delete dialog; return true; } bool BookmarksTools::editBookmarkDialog(QWidget* parent, BookmarkItem *item) { QDialog* dialog = new QDialog(parent); QFormLayout* layout = new QFormLayout(dialog); QLineEdit* title = new QLineEdit; QLineEdit* address = new QLineEdit; QLineEdit* keyword = new QLineEdit; QPlainTextEdit* description = new QPlainTextEdit; QDialogButtonBox* box = new QDialogButtonBox(dialog); box->addButton(QDialogButtonBox::Ok); box->addButton(QDialogButtonBox::Cancel); QObject::connect(box, &QDialogButtonBox::accepted, dialog, &QDialog::accept); QObject::connect(box, &QDialogButtonBox::rejected, dialog, &QDialog::reject); layout->addRow(Bookmarks::tr("Title:"), title); title->setText(item->title()); if (!item->isFolder()) { layout->addRow(Bookmarks::tr("Address:"), address); address->setText(item->urlString()); layout->addRow(Bookmarks::tr("Keyword:"), keyword); keyword->setText(item->keyword()); } layout->addRow(Bookmarks::tr("Description:"), description); description->document()->setPlainText(item->description()); layout->addWidget(box); dialog->setWindowIcon(item->icon()); dialog->setWindowTitle(Bookmarks::tr("Edit Bookmark")); dialog->exec(); if (dialog->result() == QDialog::Rejected) { delete dialog; return false; } item->setTitle(title->text()); if (!item->isFolder()) { item->setUrl(QUrl::fromEncoded(address->text().toUtf8())); item->setKeyword(keyword->text()); } item->setDescription(description->toPlainText()); delete dialog; return true; } void BookmarksTools::openBookmark(BrowserWindow* window, BookmarkItem* item) { Q_ASSERT(window); if (!item || !item->isUrl()) { return; } if (item->isFolder()) { openFolderInTabs(window, item); } else if (item->isUrl()) { item->updateVisitCount(); window->loadAddress(item->url()); } } void BookmarksTools::openBookmarkInNewTab(BrowserWindow* window, BookmarkItem* item) { Q_ASSERT(window); if (!item) { return; } if (item->isFolder()) { openFolderInTabs(window, item); } else if (item->isUrl()) { item->updateVisitCount(); window->tabWidget()->addView(item->url(), item->title(), qzSettings->newTabPosition); } } void BookmarksTools::openBookmarkInNewWindow(BookmarkItem* item) { if (!item->isUrl()) { return; } item->updateVisitCount(); mApp->createWindow(Qz::BW_NewWindow, item->url()); } void BookmarksTools::openBookmarkInNewPrivateWindow(BookmarkItem* item) { if (!item->isUrl()) { return; } item->updateVisitCount(); mApp->startPrivateBrowsing(item->url()); } void BookmarksTools::openFolderInTabs(BrowserWindow* window, BookmarkItem* folder) { Q_ASSERT(window); Q_ASSERT(folder->isFolder()); bool showWarning = folder->children().size() > 10; if (!showWarning) { foreach (BookmarkItem* child, folder->children()) { if (child->isFolder()) { showWarning = true; break; } } } if (showWarning) { const auto button = QMessageBox::warning(window, Bookmarks::tr("Confirmation"), Bookmarks::tr("Are you sure you want to open all bookmarks from '%1' folder in tabs?").arg(folder->title()), QMessageBox::Yes | QMessageBox::No); if (button != QMessageBox::Yes) { return; } } foreach (BookmarkItem* child, folder->children()) { if (child->isUrl()) { openBookmarkInNewTab(window, child); } else if (child->isFolder()) { openFolderInTabs(window, child); } } } void BookmarksTools::addActionToMenu(QObject* receiver, Menu* menu, BookmarkItem* item) { Q_ASSERT(menu); Q_ASSERT(item); switch (item->type()) { case BookmarkItem::Url: addUrlToMenu(receiver, menu, item); break; case BookmarkItem::Folder: addFolderToMenu(receiver, menu, item); break; case BookmarkItem::Separator: addSeparatorToMenu(menu, item); break; default: break; } } void BookmarksTools::addFolderToMenu(QObject* receiver, Menu* menu, BookmarkItem* folder) { Q_ASSERT(menu); Q_ASSERT(folder); Q_ASSERT(folder->isFolder()); Menu* m = new Menu(menu); QString title = QFontMetrics(m->font()).elidedText(folder->title(), Qt::ElideRight, 250); m->setTitle(title); m->setIcon(folder->icon()); addFolderContentsToMenu(receiver, m, folder); QAction* act = menu->addMenu(m); act->setData(QVariant::fromValue(static_cast(folder))); act->setIconVisibleInMenu(true); } void BookmarksTools::addUrlToMenu(QObject* receiver, Menu* menu, BookmarkItem* bookmark) { Q_ASSERT(menu); Q_ASSERT(bookmark); Q_ASSERT(bookmark->isUrl()); Action* act = new Action(menu); QString title = QFontMetrics(act->font()).elidedText(bookmark->title(), Qt::ElideRight, 250); act->setText(title); act->setData(QVariant::fromValue(static_cast(bookmark))); act->setIconVisibleInMenu(true); QObject::connect(act, SIGNAL(triggered()), receiver, SLOT(bookmarkActivated())); QObject::connect(act, SIGNAL(ctrlTriggered()), receiver, SLOT(bookmarkCtrlActivated())); QObject::connect(act, SIGNAL(shiftTriggered()), receiver, SLOT(bookmarkShiftActivated())); menu->addAction(act); } void BookmarksTools::addSeparatorToMenu(Menu* menu, BookmarkItem* separator) { Q_UNUSED(separator) Q_ASSERT(menu); Q_ASSERT(separator->isSeparator()); menu->addSeparator(); } void BookmarksTools::addFolderContentsToMenu(QObject *receiver, Menu *menu, BookmarkItem *folder) { QObject::connect(menu, SIGNAL(aboutToShow()), receiver, SLOT(menuAboutToShow())); QObject::connect(menu, SIGNAL(menuMiddleClicked(Menu*)), receiver, SLOT(menuMiddleClicked(Menu*))); foreach (BookmarkItem* child, folder->children()) { addActionToMenu(receiver, menu, child); } if (menu->isEmpty()) { menu->addAction(Bookmarks::tr("Empty"))->setDisabled(true); } } bool BookmarksTools::migrateBookmarksIfNecessary(Bookmarks* bookmarks) { QSqlQuery query; query.exec("SELECT name FROM sqlite_master WHERE type='table' AND name='folders'"); if (!query.next()) { return false; } std::cout << "Bookmarks: Migrating your bookmarks from SQLite to JSON..." << std::endl; QHash folders; folders.insert("bookmarksToolbar", bookmarks->toolbarFolder()); folders.insert("bookmarksMenu", bookmarks->menuFolder()); folders.insert("unsorted", bookmarks->unsortedFolder()); query.exec("SELECT name, subfolder FROM folders"); while (query.next()) { const QString title = query.value(0).toString(); bool subfolder = query.value(1).toString() == QLatin1String("yes"); BookmarkItem* parent = subfolder ? bookmarks->toolbarFolder() : bookmarks->unsortedFolder(); BookmarkItem* folder = new BookmarkItem(BookmarkItem::Folder, parent); folder->setTitle(title); folders.insert(folder->title(), folder); } query.exec("SELECT title, folder, url FROM bookmarks ORDER BY position ASC"); while (query.next()) { const QString title = query.value(0).toString(); const QString folder = query.value(1).toString(); const QUrl url = query.value(2).toUrl(); BookmarkItem* parent = folders.value(folder); if (!parent) { parent = bookmarks->unsortedFolder(); } Q_ASSERT(parent); BookmarkItem* bookmark = new BookmarkItem(BookmarkItem::Url, parent); bookmark->setTitle(title); bookmark->setUrl(url); } query.exec("DROP TABLE folders"); query.exec("DROP TABLE bookmarks"); query.exec("VACUUM"); std::cout << "Bookmarks: Bookmarks successfully migrated!" << std::endl; return true; } diff --git a/src/lib/bookmarks/bookmarkstools.h b/src/lib/bookmarks/bookmarkstools.h index a31f34b3..d0710d7f 100644 --- a/src/lib/bookmarks/bookmarkstools.h +++ b/src/lib/bookmarks/bookmarkstools.h @@ -1,106 +1,106 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef BOOKMARKSTOOLS_H #define BOOKMARKSTOOLS_H #include #include #include "qzcommon.h" class Bookmarks; class BookmarkItem; -class QUPZILLA_EXPORT BookmarksFoldersMenu : public QMenu +class FALKON_EXPORT BookmarksFoldersMenu : public QMenu { Q_OBJECT public: explicit BookmarksFoldersMenu(QWidget* parent = 0); BookmarkItem* selectedFolder() const; signals: void folderSelected(BookmarkItem* folder); private slots: void folderChoosed(); private: void init(); void createMenu(QMenu* menu, BookmarkItem* parent); BookmarkItem* m_selectedFolder; }; -class QUPZILLA_EXPORT BookmarksFoldersButton : public QPushButton +class FALKON_EXPORT BookmarksFoldersButton : public QPushButton { Q_OBJECT public: explicit BookmarksFoldersButton(QWidget* parent, BookmarkItem* folder = 0); BookmarkItem* selectedFolder() const; signals: void selectedFolderChanged(BookmarkItem* folder); public slots: void setSelectedFolder(BookmarkItem* folder); private: void init(); BookmarksFoldersMenu* m_menu; BookmarkItem* m_selectedFolder; }; class BrowserWindow; class TabWidget; class Action; class Menu; -class QUPZILLA_EXPORT BookmarksTools +class FALKON_EXPORT BookmarksTools { public: // Add Bookmark Dialogs static bool addBookmarkDialog(QWidget* parent, const QUrl &url, const QString &title, BookmarkItem* folder = 0); static bool bookmarkAllTabsDialog(QWidget* parent, TabWidget* tabWidget, BookmarkItem* folder = 0); // Edit Bookmark Dialog static bool editBookmarkDialog(QWidget* parent, BookmarkItem* item); // Open Bookmarks static void openBookmark(BrowserWindow* window, BookmarkItem* item); static void openBookmarkInNewTab(BrowserWindow* window, BookmarkItem* item); static void openBookmarkInNewWindow(BookmarkItem* item); static void openBookmarkInNewPrivateWindow(BookmarkItem* item); static void openFolderInTabs(BrowserWindow* window, BookmarkItem* folder); // Create Menu static void addActionToMenu(QObject* receiver, Menu* menu, BookmarkItem* item); static void addFolderToMenu(QObject* receiver, Menu* menu, BookmarkItem* folder); static void addUrlToMenu(QObject* receiver, Menu* menu, BookmarkItem* bookmark); static void addSeparatorToMenu(Menu* menu, BookmarkItem* separator); static void addFolderContentsToMenu(QObject* receiver, Menu* menu, BookmarkItem* folder); // Migration from Sql Bookmarks (returns true if bookmarks migrated) static bool migrateBookmarksIfNecessary(Bookmarks* bookmarks); }; #endif // BOOKMARKSTOOLS_H diff --git a/src/lib/bookmarks/bookmarkstreeview.cpp b/src/lib/bookmarks/bookmarkstreeview.cpp index 030d1fa6..2ed3d328 100644 --- a/src/lib/bookmarks/bookmarkstreeview.cpp +++ b/src/lib/bookmarks/bookmarkstreeview.cpp @@ -1,291 +1,291 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "bookmarkstreeview.h" #include "bookmarksitemdelegate.h" #include "bookmarksmodel.h" #include "bookmarkitem.h" #include "bookmarks.h" #include "mainapplication.h" #include "iconprovider.h" #include #include BookmarksTreeView::BookmarksTreeView(QWidget* parent) : QTreeView(parent) , m_bookmarks(mApp->bookmarks()) , m_model(m_bookmarks->model()) , m_filter(new BookmarksFilterModel(m_model)) , m_type(BookmarksManagerViewType) { setModel(m_filter); setDragEnabled(true); setAcceptDrops(true); setUniformRowHeights(true); setDropIndicatorShown(true); setAllColumnsShowFocus(true); setItemDelegate(new BookmarksItemDelegate(this)); header()->resizeSections(QHeaderView::ResizeToContents); connect(this, &QTreeView::expanded, this, &BookmarksTreeView::indexExpanded); connect(this, &QTreeView::collapsed, this, &BookmarksTreeView::indexCollapsed); } BookmarksTreeView::ViewType BookmarksTreeView::viewType() const { return m_type; } void BookmarksTreeView::setViewType(BookmarksTreeView::ViewType type) { m_type = type; switch (m_type) { case BookmarksManagerViewType: setColumnHidden(1, false); setHeaderHidden(false); setMouseTracking(false); setSelectionMode(QAbstractItemView::ExtendedSelection); break; case BookmarksSidebarViewType: setColumnHidden(1, true); setHeaderHidden(true); setMouseTracking(true); setSelectionMode(QAbstractItemView::SingleSelection); break; default: break; } restoreExpandedState(QModelIndex()); } BookmarkItem* BookmarksTreeView::selectedBookmark() const { QList items = selectedBookmarks(); return items.count() == 1 ? items.at(0) : 0; } QList BookmarksTreeView::selectedBookmarks() const { QList items; foreach (const QModelIndex &index, selectionModel()->selectedRows()) { BookmarkItem* item = m_model->item(m_filter->mapToSource(index)); items.append(item); } return items; } void BookmarksTreeView::selectBookmark(BookmarkItem* item) { QModelIndex col0 = m_filter->mapFromSource(m_model->index(item, 0)); QModelIndex col1 = m_filter->mapFromSource(m_model->index(item, 1)); selectionModel()->clearSelection(); selectionModel()->select(col0, QItemSelectionModel::Select); selectionModel()->select(col1, QItemSelectionModel::Select); } void BookmarksTreeView::ensureBookmarkVisible(BookmarkItem* item) { QModelIndex index = m_filter->mapFromSource(m_model->index(item)); QModelIndex parent = m_filter->parent(index); while (parent.isValid()) { setExpanded(parent, true); parent = m_filter->parent(parent); } } void BookmarksTreeView::search(const QString &string) { m_filter->setFilterFixedString(string); } void BookmarksTreeView::indexExpanded(const QModelIndex &parent) { BookmarkItem* item = m_model->item(m_filter->mapToSource(parent)); switch (m_type) { case BookmarksManagerViewType: item->setExpanded(true); break; case BookmarksSidebarViewType: item->setSidebarExpanded(true); break; default: break; } } void BookmarksTreeView::indexCollapsed(const QModelIndex &parent) { BookmarkItem* item = m_model->item(m_filter->mapToSource(parent)); switch (m_type) { case BookmarksManagerViewType: item->setExpanded(false); break; case BookmarksSidebarViewType: item->setSidebarExpanded(false); break; default: break; } } void BookmarksTreeView::restoreExpandedState(const QModelIndex &parent) { for (int i = 0; i < m_filter->rowCount(parent); ++i) { QModelIndex index = m_filter->index(i, 0, parent); BookmarkItem* item = m_model->item(m_filter->mapToSource(index)); setExpanded(index, m_type == BookmarksManagerViewType ? item->isExpanded() : item->isSidebarExpanded()); restoreExpandedState(index); } } void BookmarksTreeView::rowsInserted(const QModelIndex &parent, int start, int end) { restoreExpandedState(parent); QTreeView::rowsInserted(parent, start, end); } void BookmarksTreeView::selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) { Q_UNUSED(selected) Q_UNUSED(deselected) emit bookmarksSelected(selectedBookmarks()); } void BookmarksTreeView::contextMenuEvent(QContextMenuEvent* event) { emit contextMenuRequested(viewport()->mapToGlobal(event->pos())); } void BookmarksTreeView::mouseMoveEvent(QMouseEvent* event) { QTreeView::mouseMoveEvent(event); if (m_type == BookmarksSidebarViewType) { QCursor cursor = Qt::ArrowCursor; if (event->buttons() == Qt::NoButton) { QModelIndex index = indexAt(event->pos()); if (index.isValid() && index.data(BookmarksModel::TypeRole).toInt() == BookmarkItem::Url) { cursor = Qt::PointingHandCursor; } } viewport()->setCursor(cursor); } } void BookmarksTreeView::mousePressEvent(QMouseEvent* event) { QTreeView::mousePressEvent(event); if (selectionModel()->selectedRows().count() == 1) { QModelIndex index = indexAt(event->pos()); Qt::MouseButtons buttons = event->buttons(); Qt::KeyboardModifiers modifiers = event->modifiers(); if (index.isValid()) { BookmarkItem* item = m_model->item(m_filter->mapToSource(index)); if (buttons == Qt::LeftButton && modifiers == Qt::ShiftModifier) { emit bookmarkShiftActivated(item); } else if (buttons == Qt::MiddleButton || (buttons == Qt::LeftButton && modifiers == Qt::ControlModifier)) { emit bookmarkCtrlActivated(item); } } } } void BookmarksTreeView::mouseReleaseEvent(QMouseEvent* event) { QTreeView::mouseReleaseEvent(event); if (selectionModel()->selectedRows().count() == 1) { QModelIndex index = indexAt(event->pos()); if (index.isValid()) { BookmarkItem* item = m_model->item(m_filter->mapToSource(index)); // Activate bookmarks with single mouse click in Sidebar if (m_type == BookmarksSidebarViewType && event->button() == Qt::LeftButton && event->modifiers() == Qt::NoModifier) { emit bookmarkActivated(item); } } } } void BookmarksTreeView::mouseDoubleClickEvent(QMouseEvent* event) { QTreeView::mouseDoubleClickEvent(event); if (selectionModel()->selectedRows().count() == 1) { QModelIndex index = indexAt(event->pos()); if (index.isValid()) { BookmarkItem* item = m_model->item(m_filter->mapToSource(index)); Qt::MouseButtons buttons = event->buttons(); Qt::KeyboardModifiers modifiers = QApplication::keyboardModifiers(); if (buttons == Qt::LeftButton && modifiers == Qt::NoModifier) { emit bookmarkActivated(item); } else if (buttons == Qt::LeftButton && modifiers == Qt::ShiftModifier) { emit bookmarkShiftActivated(item); } } } } void BookmarksTreeView::keyPressEvent(QKeyEvent* event) { QTreeView::keyPressEvent(event); if (selectionModel()->selectedRows().count() == 1) { QModelIndex index = selectionModel()->selectedRows().at(0); BookmarkItem* item = m_model->item(m_filter->mapToSource(index)); switch (event->key()) { case Qt::Key_Return: case Qt::Key_Enter: if (item->isFolder() && (event->modifiers() == Qt::NoModifier || event->modifiers() == Qt::KeypadModifier)) { setExpanded(index, !isExpanded(index)); } else { Qt::KeyboardModifiers modifiers = event->modifiers(); if (modifiers == Qt::NoModifier || modifiers == Qt::KeypadModifier) { emit bookmarkActivated(item); } else if (modifiers == Qt::ControlModifier) { emit bookmarkCtrlActivated(item); } else if (modifiers == Qt::ShiftModifier) { emit bookmarkShiftActivated(item); } } break; } } } diff --git a/src/lib/bookmarks/bookmarkstreeview.h b/src/lib/bookmarks/bookmarkstreeview.h index ede6dba6..1dcf00cd 100644 --- a/src/lib/bookmarks/bookmarkstreeview.h +++ b/src/lib/bookmarks/bookmarkstreeview.h @@ -1,91 +1,91 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef BOOKMARKSTREEVIEW_H #define BOOKMARKSTREEVIEW_H #include #include "qzcommon.h" class Bookmarks; class BookmarkItem; class BookmarksModel; class BookmarksFilterModel; -class QUPZILLA_EXPORT BookmarksTreeView : public QTreeView +class FALKON_EXPORT BookmarksTreeView : public QTreeView { Q_OBJECT public: enum ViewType { BookmarksManagerViewType, BookmarksSidebarViewType }; explicit BookmarksTreeView(QWidget* parent = 0); ViewType viewType() const; void setViewType(ViewType type); // Returns null if more than one (or zero) bookmarks are selected BookmarkItem* selectedBookmark() const; // Returns all selected bookmarks QList selectedBookmarks() const; void selectBookmark(BookmarkItem* item); // Expand up to root item void ensureBookmarkVisible(BookmarkItem* item); public slots: void search(const QString &string); signals: // Open bookmark in current tab void bookmarkActivated(BookmarkItem* item); // Open bookmark in new tab void bookmarkCtrlActivated(BookmarkItem* item); // Open bookmark in new window void bookmarkShiftActivated(BookmarkItem* item); // Context menu signal with point mapped to global void contextMenuRequested(const QPoint &point); // If all bookmarks have been deselected, items is empty void bookmarksSelected(QList items); private slots: void indexExpanded(const QModelIndex &parent); void indexCollapsed(const QModelIndex &parent); private: void restoreExpandedState(const QModelIndex &parent); void rowsInserted(const QModelIndex &parent, int start, int end); void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected); void contextMenuEvent(QContextMenuEvent* event); void mouseMoveEvent(QMouseEvent* event); void mousePressEvent(QMouseEvent* event); void mouseReleaseEvent(QMouseEvent* event); void mouseDoubleClickEvent(QMouseEvent* event); void keyPressEvent(QKeyEvent* event); Bookmarks* m_bookmarks; BookmarksModel* m_model; BookmarksFilterModel* m_filter; ViewType m_type; }; #endif // BOOKMARKSTREEVIEW_H diff --git a/src/lib/bookmarks/bookmarkswidget.cpp b/src/lib/bookmarks/bookmarkswidget.cpp index 1159d520..f0665200 100644 --- a/src/lib/bookmarks/bookmarkswidget.cpp +++ b/src/lib/bookmarks/bookmarkswidget.cpp @@ -1,142 +1,142 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "bookmarkswidget.h" #include "ui_bookmarkswidget.h" #include "bookmarks.h" #include "bookmarkitem.h" #include "mainapplication.h" #include "pluginproxy.h" #include "speeddial.h" #include "webview.h" #include "browserwindow.h" #include #define HIDE_DELAY 270 BookmarksWidget::BookmarksWidget(WebView* view, BookmarkItem* bookmark, QWidget* parent) : LocationBarPopup(parent) , ui(new Ui::BookmarksWidget) , m_view(view) , m_bookmark(bookmark) , m_bookmarks(mApp->bookmarks()) , m_speedDial(mApp->plugins()->speedDial()) , m_edited(false) { ui->setupUi(this); ui->bookmarksButton->setIcon(QIcon::fromTheme(QSL("bookmark-new"))); init(); } BookmarksWidget::~BookmarksWidget() { delete ui; } void BookmarksWidget::toggleSpeedDial() { const SpeedDial::Page page = m_speedDial->pageForUrl(m_view->url()); if (page.url.isEmpty()) { QString title = m_view->title(); m_speedDial->addPage(m_view->url(), title); } else { m_speedDial->removePage(page); } closePopup(); } void BookmarksWidget::toggleBookmark() { if (m_bookmark) { if (m_edited) { // Change folder m_bookmarks->removeBookmark(m_bookmark); m_bookmarks->addBookmark(ui->folderButton->selectedFolder(), m_bookmark); } else { // Remove m_bookmarks->removeBookmark(m_bookmark); } } else { // Save bookmark BookmarkItem* bookmark = new BookmarkItem(BookmarkItem::Url); bookmark->setTitle(m_view->title()); bookmark->setUrl(m_view->url()); m_bookmarks->addBookmark(ui->folderButton->selectedFolder(), bookmark); } closePopup(); } void BookmarksWidget::bookmarkEdited() { if (m_edited) { return; } m_edited = true; ui->bookmarksButton->setText(tr("Update Bookmark")); ui->bookmarksButton->setFlat(true); } void BookmarksWidget::init() { // The locationbar's direction is direction of its text, // it dynamically changes and so, it's not good choice for this widget. setLayoutDirection(QApplication::layoutDirection()); // Init SpeedDial button const SpeedDial::Page page = m_speedDial->pageForUrl(m_view->url()); if (page.url.isEmpty()) { ui->speeddialButton->setFlat(true); ui->speeddialButton->setText(tr("Add to Speed Dial")); } else { ui->speeddialButton->setFlat(false); ui->speeddialButton->setText(tr("Remove from Speed Dial")); } // Init Bookmarks button if (m_bookmark) { ui->bookmarksButton->setText(tr("Remove from Bookmarks")); ui->bookmarksButton->setFlat(false); Q_ASSERT(m_bookmark->parent()); ui->folderButton->setSelectedFolder(m_bookmark->parent()); connect(ui->folderButton, SIGNAL(selectedFolderChanged(BookmarkItem*)), SLOT(bookmarkEdited())); } connect(ui->speeddialButton, SIGNAL(clicked()), this, SLOT(toggleSpeedDial())); connect(ui->bookmarksButton, SIGNAL(clicked()), this, SLOT(toggleBookmark())); } void BookmarksWidget::closePopup() { // Prevent clicking again on buttons while popup is being closed disconnect(ui->speeddialButton, SIGNAL(clicked()), this, SLOT(toggleSpeedDial())); disconnect(ui->bookmarksButton, SIGNAL(clicked()), this, SLOT(toggleBookmark())); QTimer::singleShot(HIDE_DELAY, this, SLOT(close())); } diff --git a/src/lib/bookmarks/bookmarkswidget.h b/src/lib/bookmarks/bookmarkswidget.h index 3f39881f..6ee37182 100644 --- a/src/lib/bookmarks/bookmarkswidget.h +++ b/src/lib/bookmarks/bookmarkswidget.h @@ -1,61 +1,61 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef BOOKMARKSWIDGET_H #define BOOKMARKSWIDGET_H #include #include "qzcommon.h" #include "locationbarpopup.h" namespace Ui { class BookmarksWidget; } class WebView; class SpeedDial; class Bookmarks; class BookmarkItem; -class QUPZILLA_EXPORT BookmarksWidget : public LocationBarPopup +class FALKON_EXPORT BookmarksWidget : public LocationBarPopup { Q_OBJECT public: explicit BookmarksWidget(WebView* view, BookmarkItem* bookmark, QWidget* parent = 0); ~BookmarksWidget(); private slots: void toggleSpeedDial(); void toggleBookmark(); void bookmarkEdited(); private: void init(); void closePopup(); Ui::BookmarksWidget* ui; WebView* m_view; BookmarkItem* m_bookmark; Bookmarks* m_bookmarks; SpeedDial* m_speedDial; bool m_edited; }; #endif // BOOKMARKSWIDGET_H diff --git a/src/lib/cookies/cookiejar.cpp b/src/lib/cookies/cookiejar.cpp index 18a17dd7..0c968cff 100644 --- a/src/lib/cookies/cookiejar.cpp +++ b/src/lib/cookies/cookiejar.cpp @@ -1,172 +1,172 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "cookiejar.h" #include "mainapplication.h" #include "datapaths.h" #include "autosaver.h" #include "settings.h" #include "qztools.h" #include #include #include #include //#define COOKIE_DEBUG CookieJar::CookieJar(QObject* parent) : QObject(parent) , m_client(mApp->webProfile()->cookieStore()) { loadSettings(); m_client->loadAllCookies(); connect(m_client, &QWebEngineCookieStore::cookieAdded, this, &CookieJar::slotCookieAdded); connect(m_client, &QWebEngineCookieStore::cookieRemoved, this, &CookieJar::slotCookieRemoved); } void CookieJar::loadSettings() { Settings settings; settings.beginGroup("Cookie-Settings"); m_allowCookies = settings.value("allowCookies", true).toBool(); m_filterThirdParty = settings.value("filterThirdPartyCookies", false).toBool(); m_filterTrackingCookie = settings.value("filterTrackingCookie", false).toBool(); m_whitelist = settings.value("whitelist", QStringList()).toStringList(); m_blacklist = settings.value("blacklist", QStringList()).toStringList(); settings.endGroup(); } void CookieJar::setAllowCookies(bool allow) { m_allowCookies = allow; } void CookieJar::deleteCookie(const QNetworkCookie &cookie) { m_client->deleteCookie(cookie); } QVector CookieJar::getAllCookies() const { return m_cookies; } void CookieJar::deleteAllCookies() { m_client->deleteAllCookies(); } bool CookieJar::matchDomain(QString cookieDomain, QString siteDomain) const { // According to RFC 6265 // Remove leading dot if (cookieDomain.startsWith(QLatin1Char('.'))) { cookieDomain = cookieDomain.mid(1); } if (siteDomain.startsWith(QLatin1Char('.'))) { siteDomain = siteDomain.mid(1); } return QzTools::matchDomain(cookieDomain, siteDomain); } bool CookieJar::listMatchesDomain(const QStringList &list, const QString &cookieDomain) const { foreach (const QString &d, list) { if (matchDomain(d, cookieDomain)) { return true; } } return false; } void CookieJar::slotCookieAdded(const QNetworkCookie &cookie) { if (rejectCookie(QString(), cookie, cookie.domain())) { m_client->deleteCookie(cookie); return; } m_cookies.append(cookie); emit cookieAdded(cookie); } void CookieJar::slotCookieRemoved(const QNetworkCookie &cookie) { if (m_cookies.removeOne(cookie)) emit cookieRemoved(cookie); } bool CookieJar::acceptCookie(const QUrl &firstPartyUrl, const QByteArray &cookieLine, const QUrl &cookieSource) const { const QList cookies = QNetworkCookie::parseCookies(cookieLine); Q_ASSERT(cookies.size() == 1); const QNetworkCookie cookie = cookies.at(0); return !rejectCookie(firstPartyUrl.host(), cookie, cookieSource.host()); } bool CookieJar::rejectCookie(const QString &domain, const QNetworkCookie &cookie, const QString &cookieDomain) const { Q_UNUSED(domain) if (!m_allowCookies) { bool result = listMatchesDomain(m_whitelist, cookieDomain); if (!result) { #ifdef COOKIE_DEBUG qDebug() << "not in whitelist" << cookie; #endif return true; } } if (m_allowCookies) { bool result = listMatchesDomain(m_blacklist, cookieDomain); if (result) { #ifdef COOKIE_DEBUG qDebug() << "found in blacklist" << cookie; #endif return true; } } #if QTWEBENGINE_DISABLED if (m_filterThirdParty) { bool result = matchDomain(cookieDomain, domain); if (!result) { #ifdef COOKIE_DEBUG qDebug() << "purged for domain mismatch" << cookie << cookieDomain << domain; #endif return true; } } #endif if (m_filterTrackingCookie && cookie.name().startsWith("__utm")) { #ifdef COOKIE_DEBUG qDebug() << "purged as tracking " << cookie; #endif return true; } return false; } diff --git a/src/lib/cookies/cookiejar.h b/src/lib/cookies/cookiejar.h index 4fd4fcf8..5c8633ec 100644 --- a/src/lib/cookies/cookiejar.h +++ b/src/lib/cookies/cookiejar.h @@ -1,71 +1,71 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2016 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef COOKIEJAR_H #define COOKIEJAR_H #include #include #include #include "qzcommon.h" class AutoSaver; -class QUPZILLA_EXPORT CookieJar : public QObject +class FALKON_EXPORT CookieJar : public QObject { Q_OBJECT public: explicit CookieJar(QObject* parent = 0); void loadSettings(); void setAllowCookies(bool allow); void deleteCookie(const QNetworkCookie &cookie); QVector getAllCookies() const; void deleteAllCookies(); signals: void cookieAdded(const QNetworkCookie &cookie); void cookieRemoved(const QNetworkCookie &cookie); protected: bool matchDomain(QString cookieDomain, QString siteDomain) const; bool listMatchesDomain(const QStringList &list, const QString &cookieDomain) const; private: void slotCookieAdded(const QNetworkCookie &cookie); void slotCookieRemoved(const QNetworkCookie &cookie); bool acceptCookie(const QUrl &firstPartyUrl, const QByteArray &cookieLine, const QUrl &cookieSource) const; bool rejectCookie(const QString &domain, const QNetworkCookie &cookie, const QString &cookieDomain) const; bool m_allowCookies; bool m_filterTrackingCookie; bool m_filterThirdParty; QStringList m_whitelist; QStringList m_blacklist; QWebEngineCookieStore *m_client; QVector m_cookies; }; #endif // COOKIEJAR_H diff --git a/src/lib/cookies/cookiemanager.cpp b/src/lib/cookies/cookiemanager.cpp index c18aef9a..f767971b 100644 --- a/src/lib/cookies/cookiemanager.cpp +++ b/src/lib/cookies/cookiemanager.cpp @@ -1,357 +1,357 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "cookiemanager.h" #include "ui_cookiemanager.h" #include "browserwindow.h" #include "cookiejar.h" #include "mainapplication.h" #include "qztools.h" #include "settings.h" #include "iconprovider.h" #include #include #include #include #include #include #include CookieManager::CookieManager() : QWidget() , ui(new Ui::CookieManager) { setAttribute(Qt::WA_DeleteOnClose); ui->setupUi(this); QzTools::centerWidgetOnScreen(this); if (isRightToLeft()) { ui->cookieTree->headerItem()->setTextAlignment(0, Qt::AlignRight | Qt::AlignVCenter); ui->cookieTree->headerItem()->setTextAlignment(1, Qt::AlignRight | Qt::AlignVCenter); ui->cookieTree->setLayoutDirection(Qt::LeftToRight); ui->whiteList->setLayoutDirection(Qt::LeftToRight); ui->blackList->setLayoutDirection(Qt::LeftToRight); } // Stored Cookies connect(ui->cookieTree, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*))); connect(ui->removeAll, SIGNAL(clicked()), this, SLOT(removeAll())); connect(ui->removeOne, SIGNAL(clicked()), this, SLOT(remove())); connect(ui->close, SIGNAL(clicked(QAbstractButton*)), this, SLOT(close())); connect(ui->close2, SIGNAL(clicked(QAbstractButton*)), this, SLOT(close())); connect(ui->close3, SIGNAL(clicked(QAbstractButton*)), this, SLOT(close())); connect(ui->search, SIGNAL(textChanged(QString)), this, SLOT(filterString(QString))); // Cookie Filtering connect(ui->whiteAdd, SIGNAL(clicked()), this, SLOT(addWhitelist())); connect(ui->whiteRemove, SIGNAL(clicked()), this, SLOT(removeWhitelist())); connect(ui->blackAdd, SIGNAL(clicked()), this, SLOT(addBlacklist())); connect(ui->blackRemove, SIGNAL(clicked()), this, SLOT(removeBlacklist())); // Cookie Settings Settings settings; settings.beginGroup("Cookie-Settings"); ui->saveCookies->setChecked(settings.value("allowCookies", true).toBool()); ui->filter3rdParty->setChecked(settings.value("filterThirdPartyCookies", false).toBool()); ui->filterTracking->setChecked(settings.value("filterTrackingCookie", false).toBool()); ui->deleteCookiesOnClose->setChecked(settings.value("deleteCookiesOnClose", false).toBool()); ui->whiteList->addItems(settings.value("whitelist", QStringList()).toStringList()); ui->blackList->addItems(settings.value("blacklist", QStringList()).toStringList()); settings.endGroup(); // QTWEBENGINE_DISABLED ui->filter3rdParty->hide(); ui->search->setPlaceholderText(tr("Search")); ui->cookieTree->setDefaultItemShowMode(TreeWidget::ItemsCollapsed); ui->cookieTree->sortItems(0, Qt::AscendingOrder); ui->cookieTree->header()->setDefaultSectionSize(220); ui->cookieTree->setFocus(); QShortcut* removeShortcut = new QShortcut(QKeySequence("Del"), this); connect(removeShortcut, SIGNAL(activated()), this, SLOT(deletePressed())); connect(ui->search, SIGNAL(textChanged(QString)), this, SLOT(filterString(QString))); connect(mApp->cookieJar(), &CookieJar::cookieAdded, this, &CookieManager::addCookie); connect(mApp->cookieJar(), &CookieJar::cookieRemoved, this, &CookieManager::removeCookie); // Load cookies foreach (const QNetworkCookie &cookie, mApp->cookieJar()->getAllCookies()) addCookie(cookie); QzTools::setWmClass("Cookies", this); } void CookieManager::removeAll() { QMessageBox::StandardButton button = QMessageBox::warning(this, tr("Confirmation"), tr("Are you sure you want to delete all cookies on your computer?"), QMessageBox::Yes | QMessageBox::No); if (button != QMessageBox::Yes) { return; } mApp->cookieJar()->deleteAllCookies(); m_itemHash.clear(); m_domainHash.clear(); ui->cookieTree->clear(); } void CookieManager::remove() { QTreeWidgetItem* current = ui->cookieTree->currentItem(); if (!current) { return; } QList cookies; if (current->childCount()) { for (int i = 0; i < current->childCount(); ++i) { QTreeWidgetItem *item = current->child(i); if (item && m_itemHash.contains(item)) { cookies.append(m_itemHash.value(item)); } } } else if (m_itemHash.contains(current)) { cookies.append(m_itemHash.value(current)); } foreach (const QNetworkCookie &cookie, cookies) { mApp->cookieJar()->deleteCookie(cookie); } } void CookieManager::currentItemChanged(QTreeWidgetItem* current, QTreeWidgetItem* parent) { Q_UNUSED(parent); if (!current) { return; } if (current->text(1).isEmpty()) { ui->name->setText(tr("")); ui->value->setText(tr("")); ui->server->setText(tr("")); ui->path->setText(tr("")); ui->secure->setText(tr("")); ui->expiration->setText(tr("")); ui->removeOne->setText(tr("Remove cookies")); return; } const QNetworkCookie cookie = qvariant_cast(current->data(0, Qt::UserRole + 10)); ui->name->setText(cookie.name()); ui->value->setText(cookie.value()); ui->server->setText(cookie.domain()); ui->path->setText(cookie.path()); cookie.isSecure() ? ui->secure->setText(tr("Secure only")) : ui->secure->setText(tr("All connections")); cookie.isSessionCookie() ? ui->expiration->setText(tr("Session cookie")) : ui->expiration->setText(QDateTime(cookie.expirationDate()).toString("hh:mm:ss dddd d. MMMM yyyy")); ui->removeOne->setText(tr("Remove cookie")); } void CookieManager::addWhitelist() { const QString server = QInputDialog::getText(this, tr("Add to whitelist"), tr("Server:")); if (server.isEmpty()) { return; } if (!ui->blackList->findItems(server, Qt::MatchFixedString).isEmpty()) { QMessageBox::information(this, tr("Already blacklisted!"), tr("The server \"%1\" is already in blacklist, please remove it first.").arg(server)); return; } if (ui->whiteList->findItems(server, Qt::MatchFixedString).isEmpty()) { ui->whiteList->addItem(server); } } void CookieManager::removeWhitelist() { delete ui->whiteList->currentItem(); } void CookieManager::addBlacklist() { const QString server = QInputDialog::getText(this, tr("Add to blacklist"), tr("Server:")); addBlacklist(server); } void CookieManager::addBlacklist(const QString &server) { if (server.isEmpty()) { return; } if (!ui->whiteList->findItems(server, Qt::MatchFixedString).isEmpty()) { QMessageBox::information(this, tr("Already whitelisted!"), tr("The server \"%1\" is already in whitelist, please remove it first.").arg(server)); return; } if (ui->blackList->findItems(server, Qt::MatchFixedString).isEmpty()) { ui->blackList->addItem(server); } } QString CookieManager::cookieDomain(const QNetworkCookie &cookie) const { QString domain = cookie.domain(); if (domain.startsWith(QLatin1Char('.'))) { domain = domain.mid(1); } return domain; } QTreeWidgetItem *CookieManager::cookieItem(const QNetworkCookie &cookie) const { QHashIterator it(m_itemHash); while (it.hasNext()) { it.next(); if (it.value() == cookie) return it.key(); } return Q_NULLPTR; } void CookieManager::removeBlacklist() { delete ui->blackList->currentItem(); } void CookieManager::deletePressed() { if (ui->cookieTree->hasFocus()) { remove(); } else if (ui->whiteList->hasFocus()) { removeWhitelist(); } else if (ui->blackList->hasFocus()) { removeBlacklist(); } } void CookieManager::filterString(const QString &string) { if (string.isEmpty()) { for (int i = 0; i < ui->cookieTree->topLevelItemCount(); ++i) { ui->cookieTree->topLevelItem(i)->setHidden(false); ui->cookieTree->topLevelItem(i)->setExpanded(ui->cookieTree->defaultItemShowMode() == TreeWidget::ItemsExpanded); } } else { for (int i = 0; i < ui->cookieTree->topLevelItemCount(); ++i) { QString text = "." + ui->cookieTree->topLevelItem(i)->text(0); ui->cookieTree->topLevelItem(i)->setHidden(!text.contains(string, Qt::CaseInsensitive)); ui->cookieTree->topLevelItem(i)->setExpanded(true); } } } void CookieManager::addCookie(const QNetworkCookie &cookie) { QTreeWidgetItem* item; const QString domain = cookieDomain(cookie); QTreeWidgetItem* findParent = m_domainHash.value(domain); if (findParent) { item = new QTreeWidgetItem(findParent); } else { QTreeWidgetItem* newParent = new QTreeWidgetItem(ui->cookieTree); newParent->setText(0, domain); newParent->setIcon(0, IconProvider::standardIcon(QStyle::SP_DirIcon)); newParent->setData(0, Qt::UserRole + 10, cookie.domain()); ui->cookieTree->addTopLevelItem(newParent); m_domainHash[domain] = newParent; item = new QTreeWidgetItem(newParent); } item->setText(0, "." + domain); item->setText(1, cookie.name()); item->setData(0, Qt::UserRole + 10, QVariant::fromValue(cookie)); ui->cookieTree->addTopLevelItem(item); m_itemHash[item] = cookie; } void CookieManager::removeCookie(const QNetworkCookie &cookie) { QTreeWidgetItem *item = cookieItem(cookie); if (!item) return; m_itemHash.remove(item); if (item->parent() && item->parent()->childCount() == 1) { m_domainHash.remove(cookieDomain(cookie)); delete item->parent(); item = Q_NULLPTR; } delete item; } void CookieManager::closeEvent(QCloseEvent* e) { QStringList whitelist; QStringList blacklist; for (int i = 0; i < ui->whiteList->count(); ++i) { whitelist.append(ui->whiteList->item(i)->text()); } for (int i = 0; i < ui->blackList->count(); ++i) { blacklist.append(ui->blackList->item(i)->text()); } Settings settings; settings.beginGroup("Cookie-Settings"); settings.setValue("allowCookies", ui->saveCookies->isChecked()); settings.setValue("filterThirdPartyCookies", ui->filter3rdParty->isChecked()); settings.setValue("filterTrackingCookie", ui->filterTracking->isChecked()); settings.setValue("deleteCookiesOnClose", ui->deleteCookiesOnClose->isChecked()); settings.setValue("whitelist", whitelist); settings.setValue("blacklist", blacklist); settings.endGroup(); mApp->cookieJar()->loadSettings(); e->accept(); } void CookieManager::keyPressEvent(QKeyEvent* e) { if (e->key() == Qt::Key_Escape) { close(); } QWidget::keyPressEvent(e); } CookieManager::~CookieManager() { delete ui; } diff --git a/src/lib/cookies/cookiemanager.h b/src/lib/cookies/cookiemanager.h index 750454a0..f58f62c5 100644 --- a/src/lib/cookies/cookiemanager.h +++ b/src/lib/cookies/cookiemanager.h @@ -1,74 +1,74 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef COOKIEMANAGER_H #define COOKIEMANAGER_H #include #include "qzcommon.h" namespace Ui { class CookieManager; } class QTreeWidgetItem; class QNetworkCookie; class BrowserWindow; -class QUPZILLA_EXPORT CookieManager : public QWidget +class FALKON_EXPORT CookieManager : public QWidget { Q_OBJECT public: explicit CookieManager(); ~CookieManager(); private slots: void currentItemChanged(QTreeWidgetItem* current, QTreeWidgetItem* parent); void remove(); void removeAll(); void addWhitelist(); void removeWhitelist(); void addBlacklist(); void removeBlacklist(); void deletePressed(); void filterString(const QString &string); void addCookie(const QNetworkCookie &cookie); void removeCookie(const QNetworkCookie &cookie); private: void closeEvent(QCloseEvent* e); void keyPressEvent(QKeyEvent* e); void addBlacklist(const QString &server); QString cookieDomain(const QNetworkCookie &cookie) const; QTreeWidgetItem *cookieItem(const QNetworkCookie &cookie) const; Ui::CookieManager* ui; QHash m_domainHash; QHash m_itemHash; }; #endif // COOKIEMANAGER_H diff --git a/src/lib/data/html/about.html b/src/lib/data/html/about.html index 82c2109f..2af582fa 100644 --- a/src/lib/data/html/about.html +++ b/src/lib/data/html/about.html @@ -1,38 +1,38 @@ %TITLE%
-

%ABOUT-QUPZILLA%

+

%ABOUT-FALKON%

%INFORMATIONS-ABOUT-VERSION%

%VERSION-INFO%

%MAIN-DEVELOPER%

%MAIN-DEVELOPER-TEXT%

%CONTRIBUTORS%

%CONTRIBUTORS-TEXT%

%TRANSLATORS%

%TRANSLATORS-TEXT%

%COPYRIGHT%

 %COPYRIGHT-INCLUDE%
 
diff --git a/src/lib/data/html/copyright b/src/lib/data/html/copyright index c94b9ba9..b44a1a70 100644 --- a/src/lib/data/html/copyright +++ b/src/lib/data/html/copyright @@ -1,124 +1,124 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ ------------------------------------------------------------------------ AdBlock, LineEdit class and SqueezeLabel class: ------------------------------------------------------------------------ * Copyright (c) 2008 - 2009, Benjamin C. Meyer * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the Benjamin Meyer nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. ----------------------------------------------------------------------------- QtSingleApplication class: ----------------------------------------------------------------------------- ** ** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of a Qt Solutions component. ** ** Commercial Usage ** Licensees holding valid Qt Commercial licenses may use this file in ** accordance with the Qt Solutions Commercial License Agreement provided ** with the Software or, alternatively, in accordance with the terms ** contained in a written agreement between you and Nokia. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain ** additional rights. These rights are described in the Nokia Qt LGPL ** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this ** package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3.0 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU General Public License version 3.0 requirements will be ** met: http://www.gnu.org/copyleft/gpl.html. ** ** Please note Third Party Software included with Qt Solutions may impose ** additional restrictions and it is the user's responsibility to ensure ** that they have met the licensing requirements of the GPL, LGPL, or Qt ** Solutions Commercial license and the relevant license of the Third ** Party Software they are using. ** ** If you are unsure which license is appropriate for your use, please ** contact Nokia at qt-info@nokia.com. ** ----------------------------------------------------------------------------- OpenSearchReader + OpenSearchEngine class: ----------------------------------------------------------------------------- /* * Copyright 2009 Jakub Wieczorek * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA */ ----------------------------------------------------------------------------- In application are used also some icons from Breeze icon set. More info at https://cgit.kde.org/breeze-icons.git ----------------------------------------------------------------------------- Speed Dial uses some icons from Faenza icon set, which are licensed under the GNU/GPL license. More info at http://tiheum.deviantart.com/art/Faenza-Icons-173323228 ----------------------------------------------------------------------------- diff --git a/src/lib/data/html/restore.html b/src/lib/data/html/restore.html index 5002612c..be6e56b7 100644 --- a/src/lib/data/html/restore.html +++ b/src/lib/data/html/restore.html @@ -1,327 +1,327 @@ %TITLE%

%OOPS%

%APOLOGIZE%

  • %TRY-REMOVING%
  • %START-NEW%
%WINDOWS-AND-TABS%
diff --git a/src/lib/data/html/speeddial.html b/src/lib/data/html/speeddial.html index 813dd14e..8b0d8f34 100644 --- a/src/lib/data/html/speeddial.html +++ b/src/lib/data/html/speeddial.html @@ -1,561 +1,561 @@ %SITE-TITLE%
diff --git a/src/lib/data/html/start.html b/src/lib/data/html/start.html index e72b7bc3..10322a34 100644 --- a/src/lib/data/html/start.html +++ b/src/lib/data/html/start.html @@ -1,31 +1,31 @@ %TITLE%
%PRIVATE-BROWSING%
- +
-

%SEARCH-BY% | %ABOUT-QUPZILLA%

+

%SEARCH-BY% | %ABOUT-FALKON%

diff --git a/src/lib/downloads/downloaditem.cpp b/src/lib/downloads/downloaditem.cpp index 6414186b..4817f178 100644 --- a/src/lib/downloads/downloaditem.cpp +++ b/src/lib/downloads/downloaditem.cpp @@ -1,330 +1,330 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "downloaditem.h" #include "ui_downloaditem.h" #include "mainapplication.h" #include "browserwindow.h" #include "tabwidget.h" #include "webpage.h" #include "downloadmanager.h" #include "networkmanager.h" #include "qztools.h" #include "datapaths.h" #include #include #include #include #include #include #include #include #include #include #ifdef Q_OS_WIN #include "Shlwapi.h" #endif //#define DOWNMANAGER_DEBUG DownloadItem::DownloadItem(QListWidgetItem *item, QWebEngineDownloadItem* downloadItem, const QString &path, const QString &fileName, bool openFile, DownloadManager* manager) : QWidget() , ui(new Ui::DownloadItem) , m_item(item) , m_download(downloadItem) , m_path(path) , m_fileName(fileName) , m_downUrl(downloadItem->url()) , m_openFile(openFile) , m_downloading(false) , m_downloadStopped(false) , m_currSpeed(0) , m_received(downloadItem->receivedBytes()) , m_total(downloadItem->totalBytes()) { #ifdef DOWNMANAGER_DEBUG qDebug() << __FUNCTION__ << item << reply << path << fileName; #endif ui->setupUi(this); setMaximumWidth(525); ui->button->setPixmap(QIcon::fromTheme(QSL("process-stop")).pixmap(20, 20)); ui->fileName->setText(m_fileName); ui->downloadInfo->setText(tr("Remaining time unavailable")); setContextMenuPolicy(Qt::CustomContextMenu); connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(customContextMenuRequested(QPoint))); connect(ui->button, SIGNAL(clicked(QPoint)), this, SLOT(stop())); connect(manager, SIGNAL(resized(QSize)), this, SLOT(parentResized(QSize))); startDownloading(); } void DownloadItem::startDownloading() { connect(m_download, &QWebEngineDownloadItem::finished, this, &DownloadItem::finished); connect(m_download, &QWebEngineDownloadItem::downloadProgress, this, &DownloadItem::downloadProgress); m_downloading = true; m_downTimer.start(); updateDownloadInfo(0, m_download->receivedBytes(), m_download->totalBytes()); #ifdef Q_OS_LINUX // QFileIconProvider uses only suffix on Linux QFileIconProvider iconProvider; QIcon fileIcon = iconProvider.icon(QFileInfo(m_fileName)); if (!fileIcon.isNull()) { ui->fileIcon->setPixmap(fileIcon.pixmap(30)); } else { ui->fileIcon->setPixmap(style()->standardIcon(QStyle::SP_FileIcon).pixmap(30)); } #else ui->fileIcon->hide(); #endif } void DownloadItem::parentResized(const QSize &size) { if (size.width() < 200) { return; } setMaximumWidth(size.width()); } void DownloadItem::finished() { #ifdef DOWNMANAGER_DEBUG qDebug() << __FUNCTION__ << m_reply; #endif bool success = false; QString host = m_download->url().host(); switch (m_download->state()) { case QWebEngineDownloadItem::DownloadCompleted: success = true; ui->downloadInfo->setText(tr("Done - %1 (%2)").arg(host, QDateTime::currentDateTime().toString(Qt::DefaultLocaleShortDate))); break; case QWebEngineDownloadItem::DownloadInterrupted: ui->downloadInfo->setText(tr("Error - %1").arg(host)); break; case QWebEngineDownloadItem::DownloadCancelled: ui->downloadInfo->setText(tr("Cancelled - %1").arg(host)); break; default: break; } ui->progressBar->hide(); ui->button->hide(); ui->frame->hide(); m_item->setSizeHint(sizeHint()); m_downloading = false; if (success && m_openFile) openFile(); emit downloadFinished(true); } void DownloadItem::downloadProgress(qint64 received, qint64 total) { #ifdef DOWNMANAGER_DEBUG qDebug() << __FUNCTION__ << received << total; #endif qint64 currentValue = 0; qint64 totalValue = 0; if (total > 0) { currentValue = received * 100 / total; totalValue = 100; } ui->progressBar->setValue(currentValue); ui->progressBar->setMaximum(totalValue); m_currSpeed = received * 1000.0 / m_downTimer.elapsed(); m_received = received; m_total = total; updateDownloadInfo(m_currSpeed, m_received, m_total); } int DownloadItem::progress() { return ui->progressBar->value(); } bool DownloadItem::isCancelled() { return ui->downloadInfo->text().startsWith(tr("Cancelled")); } QString DownloadItem::remaingTimeToString(QTime time) { if (time < QTime(0, 0, 10)) { return tr("few seconds"); } else if (time < QTime(0, 1)) { return tr("%n seconds", "", time.second()); } else if (time < QTime(1, 0)) { return tr("%n minutes", "", time.minute()); } else { return tr("%n hours", "", time.hour()); } } QString DownloadItem::currentSpeedToString(double speed) { if (speed < 0) { return tr("Unknown speed"); } speed /= 1024; // kB if (speed < 1000) { return QString::number(speed, 'f', 0) + QLatin1String(" ") + tr("kB/s"); } speed /= 1024; //MB if (speed < 1000) { return QString::number(speed, 'f', 2) + QLatin1String(" ") + tr("MB/s"); } speed /= 1024; //GB return QString::number(speed, 'f', 2) + QLatin1String(" ") + tr("GB/s"); } void DownloadItem::updateDownloadInfo(double currSpeed, qint64 received, qint64 total) { #ifdef DOWNMANAGER_DEBUG qDebug() << __FUNCTION__ << currSpeed << received << total; #endif // QString QString QString QString // | m_remTime | |m_currSize| |m_fileSize| |m_speed| // Remaining 26 minutes - 339MB of 693 MB (350kB/s) int estimatedTime = ((total - received) / 1024) / (currSpeed / 1024); QString speed = currentSpeedToString(currSpeed); // We have QString speed now QTime time; time = time.addSecs(estimatedTime); QString remTime = remaingTimeToString(time); m_remTime = time; QString currSize = QzTools::fileSizeToString(received); QString fileSize = QzTools::fileSizeToString(total); if (fileSize == tr("Unknown size")) { ui->downloadInfo->setText(tr("%2 - unknown size (%3)").arg(currSize, speed)); } else { ui->downloadInfo->setText(tr("Remaining %1 - %2 of %3 (%4)").arg(remTime, currSize, fileSize, speed)); } } void DownloadItem::stop() { #ifdef DOWNMANAGER_DEBUG qDebug() << __FUNCTION__; #endif if (m_downloadStopped) { return; } m_downloadStopped = true; ui->progressBar->hide(); ui->button->hide(); m_item->setSizeHint(sizeHint()); ui->downloadInfo->setText(tr("Cancelled - %1").arg(m_download->url().host())); m_download->cancel(); m_downloading = false; emit downloadFinished(false); } void DownloadItem::mouseDoubleClickEvent(QMouseEvent* e) { openFile(); e->accept(); } void DownloadItem::customContextMenuRequested(const QPoint &pos) { QMenu menu; menu.addAction(QIcon::fromTheme("document-open"), tr("Open File"), this, SLOT(openFile())); menu.addAction(tr("Open Folder"), this, SLOT(openFolder())); menu.addSeparator(); menu.addAction(QIcon::fromTheme("edit-copy"), tr("Copy Download Link"), this, SLOT(copyDownloadLink())); menu.addSeparator(); menu.addAction(QIcon::fromTheme("process-stop"), tr("Cancel downloading"), this, SLOT(stop()))->setEnabled(m_downloading); menu.addAction(QIcon::fromTheme("list-remove"), tr("Remove From List"), this, SLOT(clear()))->setEnabled(!m_downloading); if (m_downloading || ui->downloadInfo->text().startsWith(tr("Cancelled")) || ui->downloadInfo->text().startsWith(tr("Error"))) { menu.actions().at(0)->setEnabled(false); } menu.exec(mapToGlobal(pos)); } void DownloadItem::copyDownloadLink() { QApplication::clipboard()->setText(m_downUrl.toString()); } void DownloadItem::clear() { emit deleteItem(this); } void DownloadItem::openFile() { if (m_downloading) { return; } QFileInfo info(m_path, m_fileName); if (info.exists()) { QDesktopServices::openUrl(QUrl::fromLocalFile(info.absoluteFilePath())); } else { QMessageBox::warning(m_item->listWidget()->parentWidget(), tr("Not found"), tr("Sorry, the file \n %1 \n was not found!").arg(info.absoluteFilePath())); } } void DownloadItem::openFolder() { #ifdef Q_OS_WIN QString winFileName = QSL("%1/%2").arg(m_path, m_fileName); winFileName.replace(QLatin1Char('/'), "\\"); QString shExArg = "/e,/select,\"" + winFileName + "\""; ShellExecute(NULL, NULL, TEXT("explorer.exe"), shExArg.toStdWString().c_str(), NULL, SW_SHOW); #else QDesktopServices::openUrl(QUrl::fromLocalFile(m_path)); #endif } DownloadItem::~DownloadItem() { delete ui; delete m_item; } diff --git a/src/lib/downloads/downloaditem.h b/src/lib/downloads/downloaditem.h index 17f46fa5..db7b4ba3 100644 --- a/src/lib/downloads/downloaditem.h +++ b/src/lib/downloads/downloaditem.h @@ -1,97 +1,97 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef DOWNLOADITEM_H #define DOWNLOADITEM_H #include #include #include #include #include #include #include "qzcommon.h" namespace Ui { class DownloadItem; } class QListWidgetItem; class QWebEngineDownloadItem; class DownloadManager; -class QUPZILLA_EXPORT DownloadItem : public QWidget +class FALKON_EXPORT DownloadItem : public QWidget { Q_OBJECT public: explicit DownloadItem(QListWidgetItem* item, QWebEngineDownloadItem* downloadItem, const QString &path, const QString &fileName, bool openFile, DownloadManager* manager); bool isDownloading() { return m_downloading; } bool isCancelled(); QTime remainingTime() { return m_remTime; } double currentSpeed() { return m_currSpeed; } int progress(); ~DownloadItem(); static QString remaingTimeToString(QTime time); static QString currentSpeedToString(double speed); signals: void deleteItem(DownloadItem*); void downloadFinished(bool success); private slots: void parentResized(const QSize &size); void finished(); void downloadProgress(qint64 received, qint64 total); void stop(); void openFile(); void openFolder(); void customContextMenuRequested(const QPoint &pos); void clear(); void copyDownloadLink(); private: void startDownloading(); void updateDownloadInfo(double currSpeed, qint64 received, qint64 total); void mouseDoubleClickEvent(QMouseEvent* e); Ui::DownloadItem* ui; QListWidgetItem* m_item; QWebEngineDownloadItem* m_download; QString m_path; QString m_fileName; QTime m_downTimer; QTime m_remTime; QBasicTimer m_timer; QUrl m_downUrl; bool m_openFile; bool m_downloading; bool m_downloadStopped; double m_currSpeed; qint64 m_received; qint64 m_total; }; #endif // DOWNLOADITEM_H diff --git a/src/lib/downloads/downloadmanager.cpp b/src/lib/downloads/downloadmanager.cpp index d397ef22..924ed483 100644 --- a/src/lib/downloads/downloadmanager.cpp +++ b/src/lib/downloads/downloadmanager.cpp @@ -1,467 +1,467 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "downloadmanager.h" #include "ui_downloadmanager.h" #include "browserwindow.h" #include "mainapplication.h" #include "downloadoptionsdialog.h" #include "downloaditem.h" #include "networkmanager.h" #include "desktopnotificationsfactory.h" #include "qztools.h" #include "webpage.h" #include "webview.h" #include "settings.h" #include "datapaths.h" #include "tabwidget.h" #include "tabbedwebview.h" #include "tabbar.h" #include "locationbar.h" #include #include #include #include #include #include #include #ifdef Q_OS_WIN #include #include #include #endif DownloadManager::DownloadManager(QWidget* parent) : QWidget(parent) , ui(new Ui::DownloadManager) , m_isClosing(false) , m_lastDownloadOption(NoOption) { setWindowFlags(windowFlags() ^ Qt::WindowMaximizeButtonHint); ui->setupUi(this); #ifdef Q_OS_WIN if (QtWin::isCompositionEnabled()) { QtWin::extendFrameIntoClientArea(this, -1, -1, -1, -1); } #endif ui->clearButton->setIcon(QIcon::fromTheme("edit-clear")); QzTools::centerWidgetOnScreen(this); connect(ui->clearButton, SIGNAL(clicked()), this, SLOT(clearList())); QShortcut* clearShortcut = new QShortcut(QKeySequence("CTRL+L"), this); connect(clearShortcut, SIGNAL(activated()), this, SLOT(clearList())); loadSettings(); QzTools::setWmClass("Download Manager", this); } void DownloadManager::loadSettings() { Settings settings; settings.beginGroup("DownloadManager"); m_downloadPath = settings.value("defaultDownloadPath", QString()).toString(); m_lastDownloadPath = settings.value("lastDownloadPath", QDir::homePath().append(QLatin1Char('/'))).toString(); m_closeOnFinish = settings.value("CloseManagerOnFinish", false).toBool(); m_useNativeDialog = settings.value("useNativeDialog", DEFAULT_DOWNLOAD_USE_NATIVE_DIALOG).toBool(); m_useExternalManager = settings.value("UseExternalManager", false).toBool(); m_externalExecutable = settings.value("ExternalManagerExecutable", QString()).toString(); m_externalArguments = settings.value("ExternalManagerArguments", QString()).toString(); settings.endGroup(); if (!m_externalArguments.contains(QLatin1String("%d"))) { m_externalArguments.append(QLatin1String(" %d")); } } void DownloadManager::show() { m_timer.start(500, this); QWidget::show(); raise(); activateWindow(); } void DownloadManager::resizeEvent(QResizeEvent* e) { QWidget::resizeEvent(e); emit resized(size()); } void DownloadManager::keyPressEvent(QKeyEvent* e) { if (e->key() == Qt::Key_Escape || (e->key() == Qt::Key_W && e->modifiers() == Qt::ControlModifier)) { close(); } QWidget::keyPressEvent(e); } void DownloadManager::closeDownloadTab(const QUrl &url) const { // Attempt to close empty tab that was opened only for loading the download url auto testWebView = [](TabbedWebView *view, const QUrl &url) { if (view->browserWindow()->tabWidget()->tabBar()->normalTabsCount() < 2) { return false; } WebPage *page = view->page(); if (page->history()->count() != 0) { return false; } if (page->url() != QUrl()) { return false; } QUrl tabUrl = page->requestedUrl(); if (tabUrl.isEmpty()) { tabUrl = QUrl(view->webTab()->locationBar()->text()); } return tabUrl.host() == url.host(); }; if (testWebView(mApp->getWindow()->weView(), url)) { mApp->getWindow()->weView()->closeView(); return; } const auto windows = mApp->windows(); for (auto *window : windows) { const auto tabs = window->tabWidget()->allTabs(); for (auto *tab : tabs) { auto *view = tab->webView(); if (testWebView(view, url)) { view->closeView(); return; } } } } void DownloadManager::startExternalManager(const QUrl &url) { QString arguments = m_externalArguments; arguments.replace(QLatin1String("%d"), url.toEncoded()); QzTools::startExternalProcess(m_externalExecutable, arguments); m_lastDownloadOption = ExternalManager; } void DownloadManager::timerEvent(QTimerEvent* e) { QVector remTimes; QVector progresses; QVector speeds; if (e->timerId() == m_timer.timerId()) { if (!ui->list->count()) { ui->speedLabel->clear(); setWindowTitle(tr("Download Manager")); #ifdef Q_OS_WIN if (m_taskbarButton) { m_taskbarButton->progress()->hide(); } #endif return; } for (int i = 0; i < ui->list->count(); i++) { DownloadItem* downItem = qobject_cast(ui->list->itemWidget(ui->list->item(i))); if (!downItem || downItem->isCancelled() || !downItem->isDownloading()) { continue; } progresses.append(downItem->progress()); remTimes.append(downItem->remainingTime()); speeds.append(downItem->currentSpeed()); } if (remTimes.isEmpty()) { return; } QTime remaining; foreach (const QTime &time, remTimes) { if (time > remaining) { remaining = time; } } int progress = 0; foreach (int prog, progresses) { progress += prog; } progress = progress / progresses.count(); double speed = 0.00; foreach (double spee, speeds) { speed += spee; } #ifndef Q_OS_WIN ui->speedLabel->setText(tr("%1% of %2 files (%3) %4 remaining").arg(QString::number(progress), QString::number(progresses.count()), DownloadItem::currentSpeedToString(speed), DownloadItem::remaingTimeToString(remaining))); #endif setWindowTitle(tr("%1% - Download Manager").arg(progress)); #ifdef Q_OS_WIN if (m_taskbarButton) { m_taskbarButton->progress()->show(); m_taskbarButton->progress()->setValue(progress); } #endif } QWidget::timerEvent(e); } void DownloadManager::clearList() { QList items; for (int i = 0; i < ui->list->count(); i++) { DownloadItem* downItem = qobject_cast(ui->list->itemWidget(ui->list->item(i))); if (!downItem) { continue; } if (downItem->isDownloading()) { continue; } items.append(downItem); } qDeleteAll(items); } void DownloadManager::download(QWebEngineDownloadItem *downloadItem) { closeDownloadTab(downloadItem->url()); QString downloadPath; bool openFile = false; QString fileName = QFileInfo(downloadItem->path()).fileName(); fileName = QUrl::fromPercentEncoding(fileName.toUtf8()); // Filename may have been percent encoded and actually containing path fileName = QFileInfo(fileName).fileName(); const bool forceAsk = downloadItem->savePageFormat() != QWebEngineDownloadItem::UnknownSaveFormat || downloadItem->type() == QWebEngineDownloadItem::UserRequested; if (m_useExternalManager) { startExternalManager(downloadItem->url()); } else if (forceAsk || m_downloadPath.isEmpty()) { enum Result { Open = 1, Save = 2, ExternalManager = 3, SavePage = 4, Unknown = 0 }; Result result = Unknown; if (downloadItem->savePageFormat() != QWebEngineDownloadItem::UnknownSaveFormat) { // Save Page requested result = SavePage; } else if (downloadItem->type() == QWebEngineDownloadItem::UserRequested) { // Save x as... requested result = Save; } else { // Ask what to do DownloadOptionsDialog optionsDialog(fileName, downloadItem, mApp->activeWindow()); optionsDialog.showExternalManagerOption(m_useExternalManager); optionsDialog.setLastDownloadOption(m_lastDownloadOption); result = Result(optionsDialog.exec()); } switch (result) { case Open: openFile = true; downloadPath = QzTools::ensureUniqueFilename(DataPaths::path(DataPaths::Temp) + QLatin1Char('/') + fileName); m_lastDownloadOption = OpenFile; break; case Save: downloadPath = QFileDialog::getSaveFileName(mApp->activeWindow(), tr("Save file as..."), m_lastDownloadPath + QLatin1Char('/') + fileName); if (!downloadPath.isEmpty()) { m_lastDownloadPath = QFileInfo(downloadPath).absolutePath(); Settings().setValue(QSL("DownloadManager/lastDownloadPath"), m_lastDownloadPath); m_lastDownloadOption = SaveFile; } break; case SavePage: { const QString mhtml = tr("MIME HTML Archive (*.mhtml)"); const QString htmlSingle = tr("HTML Page, single (*.html)"); const QString htmlComplete = tr("HTML Page, complete (*.html)"); const QString filter = QStringLiteral("%1;;%2;;%3").arg(mhtml, htmlSingle, htmlComplete); QString selectedFilter; downloadPath = QFileDialog::getSaveFileName(mApp->activeWindow(), tr("Save page as..."), m_lastDownloadPath + QLatin1Char('/') + fileName, filter, &selectedFilter); if (!downloadPath.isEmpty()) { m_lastDownloadPath = QFileInfo(downloadPath).absolutePath(); Settings().setValue(QSL("DownloadManager/lastDownloadPath"), m_lastDownloadPath); m_lastDownloadOption = SaveFile; QWebEngineDownloadItem::SavePageFormat format = QWebEngineDownloadItem::UnknownSaveFormat; if (selectedFilter == mhtml) { format = QWebEngineDownloadItem::MimeHtmlSaveFormat; } else if (selectedFilter == htmlSingle) { format = QWebEngineDownloadItem::SingleHtmlSaveFormat; } else if (selectedFilter == htmlComplete) { format = QWebEngineDownloadItem::CompleteHtmlSaveFormat; } if (format != QWebEngineDownloadItem::UnknownSaveFormat) { downloadItem->setSavePageFormat(format); } } break; } case ExternalManager: startExternalManager(downloadItem->url()); // fallthrough default: downloadItem->cancel(); return; } } else { downloadPath = QzTools::ensureUniqueFilename(m_downloadPath + QL1C('/') + fileName); } if (downloadPath.isEmpty()) { downloadItem->cancel(); return; } // Set download path and accept downloadItem->setPath(downloadPath); downloadItem->accept(); // Create download item QListWidgetItem* listItem = new QListWidgetItem(ui->list); DownloadItem* downItem = new DownloadItem(listItem, downloadItem, QFileInfo(downloadPath).absolutePath(), QFileInfo(downloadPath).fileName(), openFile, this); connect(downItem, SIGNAL(deleteItem(DownloadItem*)), this, SLOT(deleteItem(DownloadItem*))); connect(downItem, SIGNAL(downloadFinished(bool)), this, SLOT(downloadFinished(bool))); ui->list->setItemWidget(listItem, downItem); listItem->setSizeHint(downItem->sizeHint()); downItem->show(); show(); raise(); activateWindow(); } void DownloadManager::downloadFinished(bool success) { bool downloadingAllFilesFinished = true; for (int i = 0; i < ui->list->count(); i++) { DownloadItem* downItem = qobject_cast(ui->list->itemWidget(ui->list->item(i))); if (!downItem || downItem->isCancelled() || !downItem->isDownloading()) { continue; } downloadingAllFilesFinished = false; } if (downloadingAllFilesFinished) { if (success && qApp->activeWindow() != this) { mApp->desktopNotifications()->showNotification(QIcon::fromTheme(QSL("download"), QIcon(QSL(":icons/other/download.svg"))).pixmap(48), tr("Download Finished"), tr("All files have been successfully downloaded.")); if (!m_closeOnFinish) { raise(); activateWindow(); } } ui->speedLabel->clear(); setWindowTitle(tr("Download Manager")); #ifdef Q_OS_WIN if (m_taskbarButton) { m_taskbarButton->progress()->hide(); } #endif if (m_closeOnFinish) { close(); } } } void DownloadManager::showEvent(QShowEvent *event) { QWidget::showEvent(event); #ifdef Q_OS_WIN if (!m_taskbarButton) { m_taskbarButton = new QWinTaskbarButton(this); } m_taskbarButton->setWindow(windowHandle()); m_taskbarButton->progress()->setRange(0, 100); #endif } void DownloadManager::deleteItem(DownloadItem* item) { if (item && !item->isDownloading()) { delete item; } } bool DownloadManager::canClose() { if (m_isClosing) { return true; } bool isDownloading = false; for (int i = 0; i < ui->list->count(); i++) { DownloadItem* downItem = qobject_cast(ui->list->itemWidget(ui->list->item(i))); if (!downItem) { continue; } if (downItem->isDownloading()) { isDownloading = true; break; } } return !isDownloading; } bool DownloadManager::useExternalManager() const { return m_useExternalManager; } void DownloadManager::closeEvent(QCloseEvent* e) { if (mApp->windowCount() == 0) { // No main windows -> we are going to quit if (!canClose()) { QMessageBox::StandardButton button = QMessageBox::warning(this, tr("Warning"), tr("Are you sure you want to quit? All uncompleted downloads will be cancelled!"), QMessageBox::Yes | QMessageBox::No); if (button != QMessageBox::Yes) { e->ignore(); return; } m_isClosing = true; } mApp->quitApplication(); } e->accept(); } DownloadManager::~DownloadManager() { delete ui; } diff --git a/src/lib/downloads/downloadmanager.h b/src/lib/downloads/downloadmanager.h index e6b8797e..7613fb1e 100644 --- a/src/lib/downloads/downloadmanager.h +++ b/src/lib/downloads/downloadmanager.h @@ -1,114 +1,114 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef DOWNLOADMANAGER_H #define DOWNLOADMANAGER_H #include #include #include "qzcommon.h" namespace Ui { class DownloadManager; } class QUrl; class QNetworkAccessManager; class QListWidgetItem; class QWebEngineDownloadItem; class QWinTaskbarButton; class DownloadItem; class WebPage; -class QUPZILLA_EXPORT DownloadManager : public QWidget +class FALKON_EXPORT DownloadManager : public QWidget { Q_OBJECT public: enum DownloadOption { OpenFile, SaveFile, ExternalManager, NoOption }; struct DownloadInfo { WebPage* page; QString suggestedFileName; bool askWhatToDo; bool forceChoosingPath; DownloadInfo(WebPage* p = 0) { page = p; suggestedFileName = QString(); askWhatToDo = true; forceChoosingPath = false; } }; explicit DownloadManager(QWidget* parent = 0); ~DownloadManager(); void loadSettings(); void download(QWebEngineDownloadItem *downloadItem); bool canClose(); bool useExternalManager() const; void startExternalManager(const QUrl &url); void setLastDownloadPath(const QString &lastPath) { m_lastDownloadPath = lastPath; } void setLastDownloadOption(const DownloadOption &option) { m_lastDownloadOption = option; } public slots: void show(); private slots: void clearList(); void deleteItem(DownloadItem* item); void downloadFinished(bool success); signals: void resized(QSize); private: void showEvent(QShowEvent *event) override; void timerEvent(QTimerEvent* e); void closeEvent(QCloseEvent* e); void resizeEvent(QResizeEvent* e); void keyPressEvent(QKeyEvent* e); void closeDownloadTab(const QUrl &url) const; Ui::DownloadManager* ui; QBasicTimer m_timer; QString m_lastDownloadPath; QString m_downloadPath; bool m_useNativeDialog; bool m_isClosing; bool m_closeOnFinish; bool m_useExternalManager; QString m_externalExecutable; QString m_externalArguments; DownloadOption m_lastDownloadOption; QWinTaskbarButton *m_taskbarButton = nullptr; }; #endif // DOWNLOADMANAGER_H diff --git a/src/lib/downloads/downloadoptionsdialog.cpp b/src/lib/downloads/downloadoptionsdialog.cpp index 69d32735..0a893fd0 100644 --- a/src/lib/downloads/downloadoptionsdialog.cpp +++ b/src/lib/downloads/downloadoptionsdialog.cpp @@ -1,140 +1,140 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "downloadoptionsdialog.h" #include "ui_downloadoptionsdialog.h" #include "iconprovider.h" #include #include #include DownloadOptionsDialog::DownloadOptionsDialog(const QString &fileName, QWebEngineDownloadItem *downloadItem, QWidget *parent) : QDialog(parent) , ui(new Ui::DownloadOptionsDialog) , m_downloadItem(downloadItem) , m_signalEmited(false) { ui->setupUi(this); ui->fileName->setText("" + fileName + ""); ui->fromServer->setText(m_downloadItem->url().host()); const QIcon fileIcon = IconProvider::instance()->standardIcon(QStyle::SP_FileIcon); QMimeDatabase db; const QMimeType mime = db.mimeTypeForName(downloadItem->mimeType()); if (mime.isValid() && !mime.isDefault()) { ui->mimeName->setText(mime.comment()); ui->iconLabel->setPixmap(QIcon::fromTheme(mime.iconName(), fileIcon).pixmap(22)); } else { ui->mimeFrame->hide(); ui->iconLabel->setPixmap(fileIcon.pixmap(22)); } setWindowTitle(tr("Opening %1").arg(fileName)); ui->buttonBox->setFocus(); connect(ui->copyDownloadLink, SIGNAL(clicked(QPoint)), this, SLOT(copyDownloadLink())); connect(this, SIGNAL(finished(int)), this, SLOT(emitDialogFinished(int))); } void DownloadOptionsDialog::showExternalManagerOption(bool show) { ui->radioExternal->setVisible(show); } void DownloadOptionsDialog::showFromLine(bool show) { ui->fromFrame->setVisible(show); } void DownloadOptionsDialog::setLastDownloadOption(const DownloadManager::DownloadOption &option) { switch (option) { case DownloadManager::ExternalManager: if (!ui->radioExternal->isHidden()) { ui->radioExternal->setChecked(true); break; } // fallthrough case DownloadManager::OpenFile: ui->radioOpen->setChecked(true); break; case DownloadManager::SaveFile: ui->radioSave->setChecked(true); break; default: break; } } int DownloadOptionsDialog::exec() { int status = QDialog::exec(); if (status != 0) { if (ui->radioOpen->isChecked()) { status = 1; } else if (ui->radioSave->isChecked()) { status = 2; } else if (ui->radioExternal->isChecked()) { status = 3; } } return status; } void DownloadOptionsDialog::copyDownloadLink() { QApplication::clipboard()->setText(m_downloadItem->url().toString()); ui->copyDownloadLink->setText(tr("Download link copied.")); } void DownloadOptionsDialog::emitDialogFinished(int status) { if (status != 0) { if (ui->radioOpen->isChecked()) { status = 1; } else if (ui->radioSave->isChecked()) { status = 2; } else if (ui->radioExternal->isChecked()) { status = 3; } } m_signalEmited = true; emit dialogFinished(status); } DownloadOptionsDialog::~DownloadOptionsDialog() { if (!m_signalEmited) { emit dialogFinished(-1); } delete ui; } diff --git a/src/lib/downloads/downloadoptionsdialog.h b/src/lib/downloads/downloadoptionsdialog.h index ed4c2510..208c8d90 100644 --- a/src/lib/downloads/downloadoptionsdialog.h +++ b/src/lib/downloads/downloadoptionsdialog.h @@ -1,63 +1,63 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef DOWNLOADOPTIONSDIALOG_H #define DOWNLOADOPTIONSDIALOG_H #include #include #include "qzcommon.h" #include "downloadmanager.h" namespace Ui { class DownloadOptionsDialog; } class QWebEngineDownloadItem; -class QUPZILLA_EXPORT DownloadOptionsDialog : public QDialog +class FALKON_EXPORT DownloadOptionsDialog : public QDialog { Q_OBJECT public: explicit DownloadOptionsDialog(const QString &fileName, QWebEngineDownloadItem *downloadItem, QWidget* parent = 0); ~DownloadOptionsDialog(); void showExternalManagerOption(bool show); void showFromLine(bool show); void setLastDownloadOption(const DownloadManager::DownloadOption &option); int exec(); private slots: void copyDownloadLink(); void emitDialogFinished(int status); signals: void dialogFinished(int); private: Ui::DownloadOptionsDialog* ui; QWebEngineDownloadItem *m_downloadItem; bool m_signalEmited; }; #endif // DOWNLOADOPTIONSDIALOG_H diff --git a/src/lib/downloads/downloadoptionsdialog.ui b/src/lib/downloads/downloadoptionsdialog.ui index cadee69b..7a4938da 100644 --- a/src/lib/downloads/downloadoptionsdialog.ui +++ b/src/lib/downloads/downloadoptionsdialog.ui @@ -1,323 +1,323 @@ DownloadOptionsDialog 400 0 Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok - What should QupZilla do with this file? + What should Falkon do with this file? Qt::Horizontal QSizePolicy::Fixed 20 20 Open... Save File true Download with External Manager 0 7 Qt::Horizontal QSizePolicy::Fixed 8 20 24 24 24 24 Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse 0 0 0 0 Qt::Horizontal QSizePolicy::Fixed 40 20 0 0 which is: 0 0 0 0 Qt::Horizontal QSizePolicy::Fixed 40 20 0 0 from: 0 0 Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse PointingHandCursor Copy download link true You have chosen to open Qt::Vertical Qt::Vertical SqueezeLabelV2 QLabel
squeezelabelv2.h
ClickableLabel QLabel
clickablelabel.h
buttonBox accepted() DownloadOptionsDialog accept() 248 254 157 274 buttonBox rejected() DownloadOptionsDialog reject() 316 260 286 274
diff --git a/src/lib/history/history.cpp b/src/lib/history/history.cpp index 8ce388b0..c1764101 100644 --- a/src/lib/history/history.cpp +++ b/src/lib/history/history.cpp @@ -1,292 +1,292 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "history.h" #include "historymodel.h" #include "tabbedwebview.h" #include "browserwindow.h" #include "iconprovider.h" #include "settings.h" #include #include History::History(QObject* parent) : QObject(parent) , m_isSaving(true) , m_model(0) { loadSettings(); } HistoryModel* History::model() { if (!m_model) { m_model = new HistoryModel(this); } return m_model; } void History::loadSettings() { Settings settings; settings.beginGroup("Web-Browser-Settings"); m_isSaving = settings.value("allowHistory", true).toBool(); settings.endGroup(); } // AddHistoryEntry void History::addHistoryEntry(WebView* view) { if (!m_isSaving) { return; } const QUrl url = view->url(); const QString title = view->title(); addHistoryEntry(url, title); } void History::addHistoryEntry(const QUrl &url, QString title) { if (!m_isSaving) { return; } const QStringList ignoredSchemes = { - QStringLiteral("qupzilla"), + QStringLiteral("falkon"), QStringLiteral("view-source"), QStringLiteral("data"), QStringLiteral("about") }; if (url.isEmpty() || ignoredSchemes.contains(url.scheme())) { return; } if (title.isEmpty()) { title = tr("Empty Page"); } QSqlQuery query; query.prepare("SELECT id, count, date, title FROM history WHERE url=?"); query.bindValue(0, url); query.exec(); if (!query.next()) { query.prepare("INSERT INTO history (count, date, url, title) VALUES (1,?,?,?)"); query.bindValue(0, QDateTime::currentMSecsSinceEpoch()); query.bindValue(1, url); query.bindValue(2, title); query.exec(); int id = query.lastInsertId().toInt(); HistoryEntry entry; entry.id = id; entry.count = 1; entry.date = QDateTime::currentDateTime(); entry.url = url; entry.urlString = url.toEncoded(); entry.title = title; emit historyEntryAdded(entry); } else { int id = query.value(0).toInt(); int count = query.value(1).toInt(); QDateTime date = QDateTime::fromMSecsSinceEpoch(query.value(2).toLongLong()); QString oldTitle = query.value(3).toString(); query.prepare("UPDATE history SET count = count + 1, date=?, title=? WHERE url=?"); query.bindValue(0, QDateTime::currentMSecsSinceEpoch()); query.bindValue(1, title); query.bindValue(2, url); query.exec(); HistoryEntry before; before.id = id; before.count = count; before.date = date; before.url = url; before.urlString = url.toEncoded(); before.title = oldTitle; HistoryEntry after = before; after.count = count + 1; after.date = QDateTime::currentDateTime(); after.title = title; emit historyEntryEdited(before, after); } } // DeleteHistoryEntry void History::deleteHistoryEntry(int index) { QList list; list.append(index); deleteHistoryEntry(list); } void History::deleteHistoryEntry(const QList &list) { QSqlDatabase db = QSqlDatabase::database(); db.transaction(); foreach (int index, list) { QSqlQuery query; query.prepare("SELECT count, date, url, title FROM history WHERE id=?"); query.addBindValue(index); if (!query.exec() || !query.next()) { continue; } HistoryEntry entry; entry.id = index; entry.count = query.value(0).toInt(); entry.date = QDateTime::fromMSecsSinceEpoch(query.value(1).toLongLong()); entry.url = query.value(2).toUrl(); entry.urlString = entry.url.toEncoded(); entry.title = query.value(3).toString(); query.prepare("DELETE FROM history WHERE id=?"); query.addBindValue(index); query.exec(); query.prepare("DELETE FROM icons WHERE url=?"); query.addBindValue(entry.url.toEncoded(QUrl::RemoveFragment)); query.exec(); emit historyEntryDeleted(entry); } db.commit(); } void History::deleteHistoryEntry(const QString &url, const QString &title) { QSqlQuery query; query.prepare("SELECT id FROM history WHERE url=? AND title=?"); query.bindValue(0, url); query.bindValue(1, title); query.exec(); if (query.next()) { int id = query.value(0).toInt(); deleteHistoryEntry(id); } } QList History::indexesFromTimeRange(qint64 start, qint64 end) { QList list; if (start < 0 || end < 0) { return list; } QSqlQuery query; query.prepare("SELECT id FROM history WHERE date BETWEEN ? AND ?"); query.addBindValue(end); query.addBindValue(start); query.exec(); while (query.next()) { list.append(query.value(0).toInt()); } return list; } bool History::urlIsStored(const QString &url) { QSqlQuery query; query.prepare("SELECT id FROM history WHERE url=?"); query.bindValue(0, url); query.exec(); return query.next(); } QVector History::mostVisited(int count) { QVector list; QSqlQuery query; query.exec(QString("SELECT count, date, id, title, url FROM history ORDER BY count DESC LIMIT %1").arg(count)); while (query.next()) { HistoryEntry entry; entry.count = query.value(0).toInt(); entry.date = query.value(1).toDateTime(); entry.id = query.value(2).toInt(); entry.title = query.value(3).toString(); entry.url = query.value(4).toUrl(); list.append(entry); } return list; } void History::clearHistory() { QSqlQuery query; query.exec(QSL("DELETE FROM history")); query.exec(QSL("VACUUM")); emit resetHistory(); } void History::setSaving(bool state) { m_isSaving = state; } bool History::isSaving() { return m_isSaving; } QString History::titleCaseLocalizedMonth(int month) { switch (month) { case 1: return tr("January"); case 2: return tr("February"); case 3: return tr("March"); case 4: return tr("April"); case 5: return tr("May"); case 6: return tr("June"); case 7: return tr("July"); case 8: return tr("August"); case 9: return tr("September"); case 10: return tr("October"); case 11: return tr("November"); case 12: return tr("December"); default: qWarning("Month number out of range!"); return QString(); } } diff --git a/src/lib/history/history.h b/src/lib/history/history.h index 059ae1b5..e6730ae7 100644 --- a/src/lib/history/history.h +++ b/src/lib/history/history.h @@ -1,88 +1,88 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef HISTORY_H #define HISTORY_H #include #include #include #include #include "qzcommon.h" class QIcon; class WebView; class HistoryModel; -class QUPZILLA_EXPORT History : public QObject +class FALKON_EXPORT History : public QObject { Q_OBJECT public: History(QObject* parent); struct HistoryEntry { int id; int count; QDateTime date; QUrl url; QString urlString; QString title; }; static QString titleCaseLocalizedMonth(int month); HistoryModel* model(); void addHistoryEntry(WebView* view); void addHistoryEntry(const QUrl &url, QString title); void deleteHistoryEntry(int index); void deleteHistoryEntry(const QList &list); void deleteHistoryEntry(const QString &url, const QString &title); QList indexesFromTimeRange(qint64 start, qint64 end); bool urlIsStored(const QString &url); QVector mostVisited(int count); void clearHistory(); bool isSaving(); void setSaving(bool state); void loadSettings(); signals: void historyEntryAdded(const HistoryEntry &entry); void historyEntryDeleted(const HistoryEntry &entry); void historyEntryEdited(const HistoryEntry &before, const HistoryEntry &after); void resetHistory(); private: bool m_isSaving; HistoryModel* m_model; }; typedef History::HistoryEntry HistoryEntry; // Hint to QVector to use std::realloc on item moving Q_DECLARE_TYPEINFO(HistoryEntry, Q_MOVABLE_TYPE); #endif // HISTORY_H diff --git a/src/lib/history/historyitem.cpp b/src/lib/history/historyitem.cpp index 90b5559c..7672054c 100644 --- a/src/lib/history/historyitem.cpp +++ b/src/lib/history/historyitem.cpp @@ -1,165 +1,165 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "historyitem.h" #include "qztools.h" HistoryItem::HistoryItem(HistoryItem* parent) : canFetchMore(false) , m_parent(parent) , m_startTimestamp(0) , m_endTimestamp(0) { if (m_parent) { m_parent->appendChild(this); } } void HistoryItem::changeParent(HistoryItem* parent) { if (m_parent) { m_parent->removeChild(this); } m_parent = parent; if (m_parent) { m_parent->prependChild(this); } } HistoryItem* HistoryItem::parent() const { return m_parent; } void HistoryItem::prependChild(HistoryItem* child) { if (m_children.contains(child)) { m_children.removeAll(child); } child->m_parent = this; m_children.prepend(child); } void HistoryItem::appendChild(HistoryItem* child) { if (m_children.contains(child)) { m_children.removeAll(child); } child->m_parent = this; m_children.append(child); } void HistoryItem::insertChild(int row, HistoryItem* child) { if (m_children.contains(child)) { m_children.removeAll(child); } if (m_children.count() >= row) { child->m_parent = this; m_children.insert(row, child); } } void HistoryItem::removeChild(int row) { if (QzTools::containsIndex(m_children, row)) { removeChild(m_children.at(row)); } } void HistoryItem::removeChild(HistoryItem* child) { m_children.removeOne(child); } HistoryItem* HistoryItem::child(int row) const { if (QzTools::containsIndex(m_children, row)) { return m_children.at(row); } return 0; } int HistoryItem::childCount() const { return m_children.count(); } int HistoryItem::row() { return m_parent ? m_parent->indexOfChild(this) : 0; } int HistoryItem::indexOfChild(HistoryItem* child) { return m_children.indexOf(child); } bool HistoryItem::isTopLevel() const { return (m_startTimestamp != 0); } QIcon HistoryItem::icon() const { return m_icon; } void HistoryItem::setIcon(const QIcon &icon) { m_icon = icon; } void HistoryItem::setStartTimestamp(qint64 start) { m_startTimestamp = start; } qint64 HistoryItem::startTimestamp() const { if (m_startTimestamp == -1) { return QDateTime::currentDateTime().toMSecsSinceEpoch(); } return m_startTimestamp; } void HistoryItem::setEndTimestamp(qint64 end) { m_endTimestamp = end; } qint64 HistoryItem::endTimestamp() const { return m_endTimestamp; } HistoryItem::~HistoryItem() { if (m_parent) { m_parent->removeChild(this); } qDeleteAll(m_children); } diff --git a/src/lib/history/historyitem.h b/src/lib/history/historyitem.h index bf1babd5..2397eba4 100644 --- a/src/lib/history/historyitem.h +++ b/src/lib/history/historyitem.h @@ -1,73 +1,73 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef HISTORYITEM_H #define HISTORYITEM_H #include #include "qzcommon.h" #include "history.h" -class QUPZILLA_EXPORT HistoryItem +class FALKON_EXPORT HistoryItem { public: explicit HistoryItem(HistoryItem* parent = 0); ~HistoryItem(); void changeParent(HistoryItem* parent); HistoryItem* parent() const; HistoryItem* child(int row) const; int childCount() const; void prependChild(HistoryItem* child); void appendChild(HistoryItem* child); void insertChild(int row, HistoryItem* child); void removeChild(int row); void removeChild(HistoryItem* child); int row(); int indexOfChild(HistoryItem* child); bool isTopLevel() const; QIcon icon() const; void setIcon(const QIcon &icon); void setStartTimestamp(qint64 start); qint64 startTimestamp() const; void setEndTimestamp(qint64 end); qint64 endTimestamp() const; HistoryEntry historyEntry; QString title; bool canFetchMore; private: HistoryItem* m_parent; QList m_children; QIcon m_icon; qint64 m_startTimestamp; qint64 m_endTimestamp; }; #endif // HISTORYITEM_H diff --git a/src/lib/history/historymanager.cpp b/src/lib/history/historymanager.cpp index 872f2120..b006c806 100644 --- a/src/lib/history/historymanager.cpp +++ b/src/lib/history/historymanager.cpp @@ -1,185 +1,185 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "historymanager.h" #include "ui_historymanager.h" #include "browserwindow.h" #include "mainapplication.h" #include "history.h" #include "tabwidget.h" #include "tabbedwebview.h" #include "headerview.h" #include "qzsettings.h" #include "iconprovider.h" #include #include #include HistoryManager::HistoryManager(BrowserWindow* window, QWidget* parent) : QWidget(parent) , ui(new Ui::HistoryManager) , m_window(window) { ui->setupUi(this); ui->historyTree->setViewType(HistoryTreeView::HistoryManagerViewType); connect(ui->historyTree, SIGNAL(urlActivated(QUrl)), this, SLOT(urlActivated(QUrl))); connect(ui->historyTree, SIGNAL(urlCtrlActivated(QUrl)), this, SLOT(urlCtrlActivated(QUrl))); connect(ui->historyTree, SIGNAL(urlShiftActivated(QUrl)), this, SLOT(urlShiftActivated(QUrl))); connect(ui->historyTree, SIGNAL(contextMenuRequested(QPoint)), this, SLOT(createContextMenu(QPoint))); connect(ui->deleteB, SIGNAL(clicked()), ui->historyTree, SLOT(removeSelectedItems())); connect(ui->clearAll, SIGNAL(clicked()), this, SLOT(clearHistory())); ui->historyTree->setFocus(); } BrowserWindow* HistoryManager::getWindow() { if (!m_window) m_window = mApp->getWindow(); return m_window.data(); } void HistoryManager::setMainWindow(BrowserWindow* window) { if (window) { m_window = window; } } void HistoryManager::restoreState(const QByteArray &state) { ui->historyTree->header()->restoreState(state); } QByteArray HistoryManager::saveState() { return ui->historyTree->header()->saveState(); } void HistoryManager::clearHistory() { QMessageBox::StandardButton button = QMessageBox::warning(this, tr("Confirmation"), tr("Are you sure you want to delete all history?"), QMessageBox::Yes | QMessageBox::No); if (button != QMessageBox::Yes) { return; } mApp->history()->clearHistory(); } void HistoryManager::keyPressEvent(QKeyEvent *event) { switch (event->key()) { case Qt::Key_Delete: ui->historyTree->removeSelectedItems(); break; } QWidget::keyPressEvent(event); } void HistoryManager::search(const QString &searchText) { ui->historyTree->search(searchText); } void HistoryManager::urlActivated(const QUrl &url) { openUrl(url); } void HistoryManager::urlCtrlActivated(const QUrl &url) { openUrlInNewTab(url); } void HistoryManager::urlShiftActivated(const QUrl &url) { openUrlInNewWindow(url); } void HistoryManager::openUrl(const QUrl &url) { const QUrl u = !url.isEmpty() ? url : ui->historyTree->selectedUrl(); m_window->weView()->load(u); } void HistoryManager::openUrlInNewTab(const QUrl &url) { const QUrl u = !url.isEmpty() ? url : ui->historyTree->selectedUrl(); m_window->tabWidget()->addView(u, qzSettings->newTabPosition); } void HistoryManager::openUrlInNewWindow(const QUrl &url) { const QUrl u = !url.isEmpty() ? url : ui->historyTree->selectedUrl(); mApp->createWindow(Qz::BW_NewWindow, u); } void HistoryManager::openUrlInNewPrivateWindow(const QUrl &url) { const QUrl u = !url.isEmpty() ? url : ui->historyTree->selectedUrl(); mApp->startPrivateBrowsing(u); } void HistoryManager::createContextMenu(const QPoint &pos) { QMenu menu; QAction* actNewTab = menu.addAction(IconProvider::newTabIcon(), tr("Open in new tab")); QAction* actNewWindow = menu.addAction(IconProvider::newWindowIcon(), tr("Open in new window")); QAction* actNewPrivateWindow = menu.addAction(IconProvider::privateBrowsingIcon(), tr("Open in new private window")); menu.addSeparator(); QAction* actCopyUrl = menu.addAction(tr("Copy url"), this, SLOT(copyUrl())); QAction* actCopyTitle = menu.addAction(tr("Copy title"), this, SLOT(copyTitle())); menu.addSeparator(); QAction* actDelete = menu.addAction(QIcon::fromTheme(QSL("edit-delete")), tr("Delete")); connect(actNewTab, SIGNAL(triggered()), this, SLOT(openUrlInNewTab())); connect(actNewWindow, SIGNAL(triggered()), this, SLOT(openUrlInNewWindow())); connect(actNewPrivateWindow, SIGNAL(triggered()), this, SLOT(openUrlInNewPrivateWindow())); connect(actDelete, SIGNAL(triggered()), ui->historyTree, SLOT(removeSelectedItems())); if (ui->historyTree->selectedUrl().isEmpty()) { actNewTab->setDisabled(true); actNewWindow->setDisabled(true); actNewPrivateWindow->setDisabled(true); actCopyTitle->setDisabled(true); actCopyUrl->setDisabled(true); } menu.exec(pos); } void HistoryManager::copyUrl() { QApplication::clipboard()->setText(ui->historyTree->selectedUrl().toString()); } void HistoryManager::copyTitle() { QApplication::clipboard()->setText(ui->historyTree->currentIndex().data().toString()); } HistoryManager::~HistoryManager() { delete ui; } diff --git a/src/lib/history/historymanager.h b/src/lib/history/historymanager.h index 367be890..524f4fa6 100644 --- a/src/lib/history/historymanager.h +++ b/src/lib/history/historymanager.h @@ -1,77 +1,77 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef HISTORYMANAGER_H #define HISTORYMANAGER_H #include #include #include #include "qzcommon.h" namespace Ui { class HistoryManager; } class QTreeWidgetItem; class BrowserWindow; -class QUPZILLA_EXPORT HistoryManager : public QWidget +class FALKON_EXPORT HistoryManager : public QWidget { Q_OBJECT public: explicit HistoryManager(BrowserWindow* window, QWidget* parent = 0); ~HistoryManager(); void setMainWindow(BrowserWindow* window); void restoreState(const QByteArray &state); QByteArray saveState(); public slots: void search(const QString &searchText); private slots: void urlActivated(const QUrl &url); void urlCtrlActivated(const QUrl &url); void urlShiftActivated(const QUrl &url); void openUrl(const QUrl &url = QUrl()); void openUrlInNewTab(const QUrl &url = QUrl()); void openUrlInNewWindow(const QUrl &url = QUrl()); void openUrlInNewPrivateWindow(const QUrl &url = QUrl()); void createContextMenu(const QPoint &pos); void copyUrl(); void copyTitle(); void clearHistory(); private: void keyPressEvent(QKeyEvent *event) override; BrowserWindow* getWindow(); Ui::HistoryManager* ui; QPointer m_window; }; #endif // HISTORYMANAGER_H diff --git a/src/lib/history/historymenu.cpp b/src/lib/history/historymenu.cpp index aeeca267..f1880b49 100644 --- a/src/lib/history/historymenu.cpp +++ b/src/lib/history/historymenu.cpp @@ -1,236 +1,236 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "historymenu.h" #include "iconprovider.h" #include "browserwindow.h" #include "tabbedwebview.h" #include "mainapplication.h" #include "closedtabsmanager.h" #include "tabwidget.h" #include "qztools.h" #include "history.h" #include "qzsettings.h" #include #include #include HistoryMenu::HistoryMenu(QWidget* parent) : Menu(parent) { init(); } void HistoryMenu::setMainWindow(BrowserWindow* window) { m_window = window; } void HistoryMenu::goBack() { if (m_window) { m_window->goBack(); } } void HistoryMenu::goForward() { if (m_window) { m_window->goForward(); } } void HistoryMenu::goHome() { if (m_window) { m_window->goHome(); } } void HistoryMenu::showHistoryManager() { if (m_window) { m_window->showHistoryManager(); } } void HistoryMenu::aboutToShow() { // Set enabled states for Back/Forward actions according to current WebView TabbedWebView* view = m_window ? m_window->weView() : 0; if (view) { actions().at(0)->setEnabled(view->history()->canGoBack()); actions().at(1)->setEnabled(view->history()->canGoForward()); } while (actions().count() != 7) { QAction* act = actions().at(7); if (act->menu()) { act->menu()->clear(); } removeAction(act); delete act; } addSeparator(); QSqlQuery query; query.exec(QSL("SELECT title, url FROM history ORDER BY date DESC LIMIT 10")); while (query.next()) { const QUrl url = query.value(1).toUrl(); const QString title = QzTools::truncatedText(query.value(0).toString(), 40); Action* act = new Action(title); act->setData(url); act->setIcon(IconProvider::iconForUrl(url)); connect(act, SIGNAL(triggered()), this, SLOT(historyEntryActivated())); connect(act, SIGNAL(ctrlTriggered()), this, SLOT(historyEntryCtrlActivated())); connect(act, SIGNAL(shiftTriggered()), this, SLOT(historyEntryShiftActivated())); addAction(act); } } void HistoryMenu::aboutToHide() { // Enable Back/Forward actions to ensure shortcuts are working actions().at(0)->setEnabled(true); actions().at(1)->setEnabled(true); } void HistoryMenu::aboutToShowMostVisited() { m_menuMostVisited->clear(); const QVector mostVisited = mApp->history()->mostVisited(10); foreach (const HistoryEntry &entry, mostVisited) { Action* act = new Action(QzTools::truncatedText(entry.title, 40)); act->setData(entry.url); act->setIcon(IconProvider::iconForUrl(entry.url)); connect(act, SIGNAL(triggered()), this, SLOT(historyEntryActivated())); connect(act, SIGNAL(ctrlTriggered()), this, SLOT(historyEntryCtrlActivated())); connect(act, SIGNAL(shiftTriggered()), this, SLOT(historyEntryShiftActivated())); m_menuMostVisited->addAction(act); } if (m_menuMostVisited->isEmpty()) { m_menuMostVisited->addAction(tr("Empty"))->setEnabled(false); } } void HistoryMenu::aboutToShowClosedTabs() { m_menuClosedTabs->clear(); if (!m_window) { return; } TabWidget* tabWidget = m_window->tabWidget(); int i = 0; const QLinkedList closedTabs = tabWidget->closedTabsManager()->allClosedTabs(); foreach (const ClosedTabsManager::Tab &tab, closedTabs) { const QString title = QzTools::truncatedText(tab.title, 40); QAction* act = m_menuClosedTabs->addAction(tab.icon, title, tabWidget, SLOT(restoreClosedTab())); act->setData(i++); } if (m_menuClosedTabs->isEmpty()) { m_menuClosedTabs->addAction(tr("Empty"))->setEnabled(false); } else { m_menuClosedTabs->addSeparator(); m_menuClosedTabs->addAction(tr("Restore All Closed Tabs"), tabWidget, SLOT(restoreAllClosedTabs())); m_menuClosedTabs->addAction(tr("Clear list"), tabWidget, SLOT(clearClosedTabsList())); } } void HistoryMenu::historyEntryActivated() { if (QAction* action = qobject_cast(sender())) { openUrl(action->data().toUrl()); } } void HistoryMenu::historyEntryCtrlActivated() { if (QAction* action = qobject_cast(sender())) { openUrlInNewTab(action->data().toUrl()); } } void HistoryMenu::historyEntryShiftActivated() { if (QAction* action = qobject_cast(sender())) { openUrlInNewWindow(action->data().toUrl()); } } void HistoryMenu::openUrl(const QUrl &url) { if (m_window) { m_window->loadAddress(url); } } void HistoryMenu::openUrlInNewTab(const QUrl &url) { if (m_window) { m_window->tabWidget()->addView(url, qzSettings->newTabPosition); } } void HistoryMenu::openUrlInNewWindow(const QUrl &url) { mApp->createWindow(Qz::BW_NewWindow, url); } void HistoryMenu::init() { setTitle(tr("Hi&story")); QAction* act = addAction(IconProvider::standardIcon(QStyle::SP_ArrowBack), tr("&Back"), this, SLOT(goBack())); act->setShortcut(QzTools::actionShortcut(QKeySequence::Back, Qt::ALT + Qt::Key_Left, QKeySequence::Forward, Qt::ALT + Qt::Key_Right)); act = addAction(IconProvider::standardIcon(QStyle::SP_ArrowForward), tr("&Forward"), this, SLOT(goForward())); act->setShortcut(QzTools::actionShortcut(QKeySequence::Forward, Qt::ALT + Qt::Key_Right, QKeySequence::Back, Qt::ALT + Qt::Key_Left)); act = addAction(QIcon::fromTheme("go-home"), tr("&Home"), this, SLOT(goHome())); act->setShortcut(QKeySequence(Qt::ALT + Qt::Key_Home)); act = addAction(QIcon::fromTheme("deep-history", QIcon(":/icons/menu/history.svg")), tr("Show &All History"), this, SLOT(showHistoryManager())); act->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_H)); addSeparator(); connect(this, SIGNAL(aboutToShow()), this, SLOT(aboutToShow())); connect(this, SIGNAL(aboutToHide()), this, SLOT(aboutToHide())); m_menuMostVisited = new Menu(tr("Most Visited"), this); connect(m_menuMostVisited, SIGNAL(aboutToShow()), this, SLOT(aboutToShowMostVisited())); m_menuClosedTabs = new Menu(tr("Closed Tabs")); connect(m_menuClosedTabs, SIGNAL(aboutToShow()), this, SLOT(aboutToShowClosedTabs())); addMenu(m_menuMostVisited); addMenu(m_menuClosedTabs); } diff --git a/src/lib/history/historymenu.h b/src/lib/history/historymenu.h index 446c7c01..8e9fe25e 100644 --- a/src/lib/history/historymenu.h +++ b/src/lib/history/historymenu.h @@ -1,67 +1,67 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef HISTORYMENU_H #define HISTORYMENU_H #include #include "enhancedmenu.h" #include "qzcommon.h" class BrowserWindow; -class QUPZILLA_EXPORT HistoryMenu : public Menu +class FALKON_EXPORT HistoryMenu : public Menu { Q_OBJECT public: explicit HistoryMenu(QWidget* parent = 0); void setMainWindow(BrowserWindow* window); signals: private slots: void goBack(); void goForward(); void goHome(); void showHistoryManager(); void aboutToShow(); void aboutToHide(); void aboutToShowMostVisited(); void aboutToShowClosedTabs(); void historyEntryActivated(); void historyEntryCtrlActivated(); void historyEntryShiftActivated(); void openUrl(const QUrl &url); void openUrlInNewTab(const QUrl &url); void openUrlInNewWindow(const QUrl &url); private: void init(); QPointer m_window; Menu* m_menuMostVisited; Menu* m_menuClosedTabs; }; #endif // HISTORYMENU_H diff --git a/src/lib/history/historymodel.cpp b/src/lib/history/historymodel.cpp index 5739bd79..01c1e7c6 100644 --- a/src/lib/history/historymodel.cpp +++ b/src/lib/history/historymodel.cpp @@ -1,563 +1,563 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "historymodel.h" #include "historyitem.h" #include "iconprovider.h" #include #include #include #include static QString dateTimeToString(const QDateTime &dateTime) { const QDateTime current = QDateTime::currentDateTime(); if (current.date() == dateTime.date()) { return dateTime.time().toString("h:mm"); } return dateTime.toString("d.M.yyyy h:mm"); } HistoryModel::HistoryModel(History* history) : QAbstractItemModel(history) , m_rootItem(new HistoryItem(0)) , m_todayItem(0) , m_history(history) { init(); connect(m_history, SIGNAL(resetHistory()), this, SLOT(resetHistory())); connect(m_history, SIGNAL(historyEntryAdded(HistoryEntry)), this, SLOT(historyEntryAdded(HistoryEntry))); connect(m_history, SIGNAL(historyEntryDeleted(HistoryEntry)), this, SLOT(historyEntryDeleted(HistoryEntry))); connect(m_history, SIGNAL(historyEntryEdited(HistoryEntry,HistoryEntry)), this, SLOT(historyEntryEdited(HistoryEntry,HistoryEntry))); } QVariant HistoryModel::headerData(int section, Qt::Orientation orientation, int role) const { if (orientation == Qt::Horizontal && role == Qt::DisplayRole) { switch (section) { case 0: return tr("Title"); case 1: return tr("Address"); case 2: return tr("Visit Date"); case 3: return tr("Visit Count"); } } return QAbstractItemModel::headerData(section, orientation, role); } QVariant HistoryModel::data(const QModelIndex &index, int role) const { HistoryItem* item = itemFromIndex(index); if (index.row() < 0 || !item) { return QVariant(); } if (item->isTopLevel()) { switch (role) { case IsTopLevelRole: return true; case TimestampStartRole: return item->startTimestamp(); case TimestampEndRole: return item->endTimestamp(); case Qt::DisplayRole: case Qt::EditRole: return index.column() == 0 ? item->title : QVariant(); case Qt::DecorationRole: return index.column() == 0 ? QIcon::fromTheme(QSL("view-calendar"), QIcon(":/icons/menu/history_entry.svg")) : QVariant(); } return QVariant(); } const HistoryEntry entry = item->historyEntry; switch (role) { case IdRole: return entry.id; case TitleRole: return entry.title; case UrlRole: return entry.url; case UrlStringRole: return entry.urlString; case IconRole: return item->icon(); case IsTopLevelRole: return false; case TimestampStartRole: return -1; case TimestampEndRole: return -1; case Qt::ToolTipRole: if (index.column() == 0) { return QString("%1\n%2").arg(entry.title, entry.urlString); } // fallthrough case Qt::DisplayRole: case Qt::EditRole: switch (index.column()) { case 0: return entry.title; case 1: return entry.urlString; case 2: return dateTimeToString(entry.date); case 3: return entry.count; } break; case Qt::DecorationRole: if (index.column() == 0) { return item->icon().isNull() ? IconProvider::emptyWebIcon() : item->icon(); } } return QVariant(); } bool HistoryModel::setData(const QModelIndex &index, const QVariant &value, int role) { HistoryItem* item = itemFromIndex(index); if (index.row() < 0 || !item || item->isTopLevel()) { return false; } if (role == IconRole) { item->setIcon(value.value()); emit dataChanged(index, index); return true; } return false; } QModelIndex HistoryModel::index(int row, int column, const QModelIndex &parent) const { if (!hasIndex(row, column, parent)) { return QModelIndex(); } HistoryItem* parentItem = itemFromIndex(parent); HistoryItem* childItem = parentItem->child(row); return childItem ? createIndex(row, column, childItem) : QModelIndex(); } QModelIndex HistoryModel::parent(const QModelIndex &index) const { if (!index.isValid()) { return QModelIndex(); } HistoryItem* childItem = itemFromIndex(index); HistoryItem* parentItem = childItem->parent(); if (!parentItem || parentItem == m_rootItem) { return QModelIndex(); } return createIndex(parentItem->row(), 0, parentItem); } Qt::ItemFlags HistoryModel::flags(const QModelIndex &index) const { if (!index.isValid()) { return 0; } return Qt::ItemIsEnabled | Qt::ItemIsSelectable; } int HistoryModel::rowCount(const QModelIndex &parent) const { if (parent.column() > 0) { return 0; } HistoryItem* parentItem = itemFromIndex(parent); return parentItem->childCount(); } int HistoryModel::columnCount(const QModelIndex &parent) const { Q_UNUSED(parent) return 4; } bool HistoryModel::hasChildren(const QModelIndex &parent) const { if (!parent.isValid()) { return true; } HistoryItem* item = itemFromIndex(parent); return item ? item->isTopLevel() : false; } HistoryItem* HistoryModel::itemFromIndex(const QModelIndex &index) const { if (index.isValid()) { HistoryItem* item = static_cast(index.internalPointer()); if (item) { return item; } } return m_rootItem; } void HistoryModel::removeTopLevelIndexes(const QList &indexes) { foreach (const QPersistentModelIndex &index, indexes) { if (index.parent().isValid()) { continue; } int row = index.row(); HistoryItem* item = m_rootItem->child(row); if (!item) { return; } beginRemoveRows(QModelIndex(), row, row); delete item; endRemoveRows(); if (item == m_todayItem) { m_todayItem = 0; } } } void HistoryModel::resetHistory() { beginResetModel(); delete m_rootItem; m_todayItem = 0; m_rootItem = new HistoryItem(0); init(); endResetModel(); } bool HistoryModel::canFetchMore(const QModelIndex &parent) const { HistoryItem* parentItem = itemFromIndex(parent); return parentItem ? parentItem->canFetchMore : false; } void HistoryModel::fetchMore(const QModelIndex &parent) { HistoryItem* parentItem = itemFromIndex(parent); if (!parent.isValid() || !parentItem) { return; } parentItem->canFetchMore = false; QList idList; for (int i = 0; i < parentItem->childCount(); ++i) { idList.append(parentItem->child(i)->historyEntry.id); } QSqlQuery query; query.prepare("SELECT id, count, title, url, date FROM history WHERE date BETWEEN ? AND ? ORDER BY date DESC"); query.addBindValue(parentItem->endTimestamp()); query.addBindValue(parentItem->startTimestamp()); query.exec(); QVector list; while (query.next()) { HistoryEntry entry; entry.id = query.value(0).toInt(); entry.count = query.value(1).toInt(); entry.title = query.value(2).toString(); entry.url = query.value(3).toUrl(); entry.date = QDateTime::fromMSecsSinceEpoch(query.value(4).toLongLong()); entry.urlString = entry.url.toEncoded(); if (!idList.contains(entry.id)) { list.append(entry); } } if (list.isEmpty()) { return; } beginInsertRows(parent, 0, list.size() - 1); foreach (const HistoryEntry &entry, list) { HistoryItem* newItem = new HistoryItem(parentItem); newItem->historyEntry = entry; } endInsertRows(); } void HistoryModel::historyEntryAdded(const HistoryEntry &entry) { if (!m_todayItem) { beginInsertRows(QModelIndex(), 0, 0); m_todayItem = new HistoryItem(0); m_todayItem->setStartTimestamp(-1); m_todayItem->setEndTimestamp(QDateTime(QDate::currentDate()).toMSecsSinceEpoch()); m_todayItem->title = tr("Today"); m_rootItem->prependChild(m_todayItem); endInsertRows(); } beginInsertRows(createIndex(0, 0, m_todayItem), 0, 0); HistoryItem* item = new HistoryItem(); item->historyEntry = entry; m_todayItem->prependChild(item); endInsertRows(); } void HistoryModel::historyEntryDeleted(const HistoryEntry &entry) { HistoryItem* item = findHistoryItem(entry); if (!item) { return; } HistoryItem* parentItem = item->parent(); int row = item->row(); beginRemoveRows(createIndex(parentItem->row(), 0, parentItem), row, row); delete item; endRemoveRows(); checkEmptyParentItem(parentItem); } void HistoryModel::historyEntryEdited(const HistoryEntry &before, const HistoryEntry &after) { #if 0 HistoryItem* item = findHistoryItem(before); if (item) { HistoryItem* parentItem = item->parent(); const QModelIndex sourceParent = createIndex(parentItem->row(), 0, parentItem); const QModelIndex destinationParent = createIndex(m_todayItem->row(), 0, m_todayItem); int row = item->row(); beginMoveRows(sourceParent, row, row, destinationParent, 0); item->historyEntry = after; item->refreshIcon(); item->changeParent(m_todayItem); endMoveRows(); // This line sometimes throw "std::bad_alloc" ... I don't know why ?! checkEmptyParentItem(parentItem); } else { historyEntryAdded(after); } #endif historyEntryDeleted(before); historyEntryAdded(after); } HistoryItem* HistoryModel::findHistoryItem(const HistoryEntry &entry) { HistoryItem* parentItem = 0; qint64 timestamp = entry.date.toMSecsSinceEpoch(); for (int i = 0; i < m_rootItem->childCount(); ++i) { HistoryItem* item = m_rootItem->child(i); if (item->endTimestamp() < timestamp) { parentItem = item; break; } } if (!parentItem) { return 0; } for (int i = 0; i < parentItem->childCount(); ++i) { HistoryItem* item = parentItem->child(i); if (item->historyEntry.id == entry.id) { return item; } } return 0; } void HistoryModel::checkEmptyParentItem(HistoryItem* item) { if (item->childCount() == 0 && item->isTopLevel()) { int row = item->row(); beginRemoveRows(QModelIndex(), row, row); delete item; endRemoveRows(); if (item == m_todayItem) { m_todayItem = 0; } } } void HistoryModel::init() { QSqlQuery query; query.exec("SELECT MIN(date) FROM history"); if (!query.next()) { return; } const qint64 minTimestamp = query.value(0).toLongLong(); if (minTimestamp <= 0) { return; } const QDate today = QDate::currentDate(); const QDate week = today.addDays(1 - today.dayOfWeek()); const QDate month = QDate(today.year(), today.month(), 1); const qint64 currentTimestamp = QDateTime::currentMSecsSinceEpoch(); qint64 timestamp = currentTimestamp; while (timestamp > minTimestamp) { QDate timestampDate = QDateTime::fromMSecsSinceEpoch(timestamp).date(); qint64 endTimestamp; QString itemName; if (timestampDate == today) { endTimestamp = QDateTime(today).toMSecsSinceEpoch(); itemName = tr("Today"); } else if (timestampDate >= week) { endTimestamp = QDateTime(week).toMSecsSinceEpoch(); itemName = tr("This Week"); } else if (timestampDate.month() == month.month() && timestampDate.year() == month.year()) { endTimestamp = QDateTime(month).toMSecsSinceEpoch(); itemName = tr("This Month"); } else { QDate startDate(timestampDate.year(), timestampDate.month(), timestampDate.daysInMonth()); QDate endDate(startDate.year(), startDate.month(), 1); timestamp = QDateTime(startDate, QTime(23, 59, 59)).toMSecsSinceEpoch(); endTimestamp = QDateTime(endDate).toMSecsSinceEpoch(); itemName = QString("%1 %2").arg(History::titleCaseLocalizedMonth(timestampDate.month()), QString::number(timestampDate.year())); } QSqlQuery query; query.prepare("SELECT id FROM history WHERE date BETWEEN ? AND ? LIMIT 1"); query.addBindValue(endTimestamp); query.addBindValue(timestamp); query.exec(); if (query.next()) { HistoryItem* item = new HistoryItem(m_rootItem); item->setStartTimestamp(timestamp == currentTimestamp ? -1 : timestamp); item->setEndTimestamp(endTimestamp); item->title = itemName; item->canFetchMore = true; if (timestamp == currentTimestamp) { m_todayItem = item; } } timestamp = endTimestamp - 1; } } // HistoryFilterModel HistoryFilterModel::HistoryFilterModel(QAbstractItemModel* parent) : QSortFilterProxyModel(parent) { setSourceModel(parent); setFilterCaseSensitivity(Qt::CaseInsensitive); m_filterTimer = new QTimer(this); m_filterTimer->setSingleShot(true); m_filterTimer->setInterval(300); connect(m_filterTimer, SIGNAL(timeout()), this, SLOT(startFiltering())); } void HistoryFilterModel::setFilterFixedString(const QString &pattern) { m_pattern = pattern; m_filterTimer->start(); } void HistoryFilterModel::startFiltering() { if (m_pattern.isEmpty()) { emit collapseAllItems(); QSortFilterProxyModel::setFilterFixedString(m_pattern); return; } QApplication::setOverrideCursor(Qt::WaitCursor); // Expand all items also calls fetchmore emit expandAllItems(); QSortFilterProxyModel::setFilterFixedString(m_pattern); QApplication::restoreOverrideCursor(); } bool HistoryFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const { const QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent); if (index.data(HistoryModel::IsTopLevelRole).toBool()) { return true; } return (index.data(HistoryModel::UrlStringRole).toString().contains(m_pattern, Qt::CaseInsensitive) || index.data(HistoryModel::TitleRole).toString().contains(m_pattern, Qt::CaseInsensitive)); } diff --git a/src/lib/history/historymodel.h b/src/lib/history/historymodel.h index 11bc8f06..1d663c38 100644 --- a/src/lib/history/historymodel.h +++ b/src/lib/history/historymodel.h @@ -1,113 +1,113 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef HISTORYMODEL_H #define HISTORYMODEL_H #include #include #include "qzcommon.h" #include "history.h" class QTimer; class History; class HistoryItem; -class QUPZILLA_EXPORT HistoryModel : public QAbstractItemModel +class FALKON_EXPORT HistoryModel : public QAbstractItemModel { Q_OBJECT public: enum Roles { IdRole = Qt::UserRole + 1, TitleRole = Qt::UserRole + 2, UrlRole = Qt::UserRole + 3, UrlStringRole = Qt::UserRole + 4, IconRole = Qt::UserRole + 5, IsTopLevelRole = Qt::UserRole + 7, TimestampStartRole = Qt::UserRole + 8, TimestampEndRole = Qt::UserRole + 9, MaxRole = TimestampEndRole }; explicit HistoryModel(History* history); QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; QVariant data(const QModelIndex &index, int role) const; bool setData(const QModelIndex &index, const QVariant &value, int role); QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; QModelIndex parent(const QModelIndex &child) const; Qt::ItemFlags flags(const QModelIndex &index) const; int rowCount(const QModelIndex &parent = QModelIndex()) const; int columnCount(const QModelIndex &parent = QModelIndex()) const; bool canFetchMore(const QModelIndex &parent) const; void fetchMore(const QModelIndex &parent); bool hasChildren(const QModelIndex &parent) const; HistoryItem* itemFromIndex(const QModelIndex &index) const; void removeTopLevelIndexes(const QList &indexes); signals: private slots: void resetHistory(); void historyEntryAdded(const HistoryEntry &entry); void historyEntryDeleted(const HistoryEntry &entry); void historyEntryEdited(const HistoryEntry &before, const HistoryEntry &after); private: HistoryItem* findHistoryItem(const HistoryEntry &entry); void checkEmptyParentItem(HistoryItem* item); void init(); HistoryItem* m_rootItem; HistoryItem* m_todayItem; History* m_history; }; -class QUPZILLA_EXPORT HistoryFilterModel : public QSortFilterProxyModel +class FALKON_EXPORT HistoryFilterModel : public QSortFilterProxyModel { Q_OBJECT public: explicit HistoryFilterModel(QAbstractItemModel* parent); public slots: void setFilterFixedString(const QString &pattern); signals: void expandAllItems(); void collapseAllItems(); protected: bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const; private slots: void startFiltering(); private: QString m_pattern; QTimer* m_filterTimer; }; #endif // HISTORYMODEL_H diff --git a/src/lib/history/historytreeview.cpp b/src/lib/history/historytreeview.cpp index a1106840..e14e87e3 100644 --- a/src/lib/history/historytreeview.cpp +++ b/src/lib/history/historytreeview.cpp @@ -1,266 +1,266 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "historytreeview.h" #include "historymodel.h" #include "historyitem.h" #include "headerview.h" #include "mainapplication.h" #include "iconprovider.h" #include #include #include #include HistoryTreeView::HistoryTreeView(QWidget* parent) : QTreeView(parent) , m_history(mApp->history()) , m_filter(new HistoryFilterModel(m_history->model())) , m_type(HistoryManagerViewType) { setModel(m_filter); setUniformRowHeights(true); setAllColumnsShowFocus(true); m_header = new HeaderView(this); m_header->setDefaultSectionSizes(QList() << 0.4 << 0.35 << 0.10 << 0.08); m_header->setSectionHidden(4, true); setHeader(m_header); connect(m_filter, SIGNAL(expandAllItems()), this, SLOT(expandAll())); connect(m_filter, SIGNAL(collapseAllItems()), this, SLOT(collapseAll())); } HistoryTreeView::ViewType HistoryTreeView::viewType() const { return m_type; } void HistoryTreeView::setViewType(HistoryTreeView::ViewType type) { m_type = type; switch (m_type) { case HistoryManagerViewType: setColumnHidden(1, false); setColumnHidden(2, false); setColumnHidden(3, false); setHeaderHidden(false); setMouseTracking(false); setSelectionMode(QAbstractItemView::ExtendedSelection); break; case HistorySidebarViewType: setColumnHidden(1, true); setColumnHidden(2, true); setColumnHidden(3, true); setHeaderHidden(true); setMouseTracking(true); setSelectionMode(QAbstractItemView::SingleSelection); break; default: break; } } QUrl HistoryTreeView::selectedUrl() const { const QList indexes = selectionModel()->selectedRows(); if (indexes.count() != 1) return QUrl(); // TopLevelItems have invalid (empty) UrlRole data return indexes.at(0).data(HistoryModel::UrlRole).toUrl(); } HeaderView* HistoryTreeView::header() const { return m_header; } void HistoryTreeView::search(const QString &string) { m_filter->setFilterFixedString(string); } void HistoryTreeView::removeSelectedItems() { QList list; QApplication::setOverrideCursor(Qt::WaitCursor); QList topLevelIndexes; foreach (const QModelIndex &index, selectedIndexes()) { if (index.column() > 0) { continue; } if (index.data(HistoryModel::IsTopLevelRole).toBool()) { qint64 start = index.data(HistoryModel::TimestampStartRole).toLongLong(); qint64 end = index.data(HistoryModel::TimestampEndRole).toLongLong(); list.append(m_history->indexesFromTimeRange(start, end)); topLevelIndexes.append(index); } else { int id = index.data(HistoryModel::IdRole).toInt(); if (!list.contains(id)) { list.append(id); } } } m_history->deleteHistoryEntry(list); m_history->model()->removeTopLevelIndexes(topLevelIndexes); QApplication::restoreOverrideCursor(); } void HistoryTreeView::contextMenuEvent(QContextMenuEvent* event) { emit contextMenuRequested(viewport()->mapToGlobal(event->pos())); } void HistoryTreeView::mouseMoveEvent(QMouseEvent* event) { QTreeView::mouseMoveEvent(event); if (m_type == HistorySidebarViewType) { QCursor cursor = Qt::ArrowCursor; if (event->buttons() == Qt::NoButton) { QModelIndex index = indexAt(event->pos()); if (index.isValid() && !index.data(HistoryModel::IsTopLevelRole).toBool()) { cursor = Qt::PointingHandCursor; } } viewport()->setCursor(cursor); } } void HistoryTreeView::mousePressEvent(QMouseEvent* event) { QTreeView::mousePressEvent(event); if (selectionModel()->selectedRows().count() == 1) { QModelIndex index = indexAt(event->pos()); Qt::MouseButtons buttons = event->buttons(); Qt::KeyboardModifiers modifiers = event->modifiers(); if (index.isValid() && !index.data(HistoryModel::IsTopLevelRole).toBool()) { const QUrl url = index.data(HistoryModel::UrlRole).toUrl(); if (buttons == Qt::LeftButton && modifiers == Qt::ShiftModifier) { emit urlShiftActivated(url); } else if (buttons == Qt::MiddleButton || (buttons == Qt::LeftButton && modifiers == Qt::ControlModifier)) { emit urlCtrlActivated(url); } } } } void HistoryTreeView::mouseReleaseEvent(QMouseEvent* event) { QTreeView::mouseReleaseEvent(event); if (selectionModel()->selectedRows().count() == 1) { QModelIndex index = indexAt(event->pos()); if (index.isValid() && !index.data(HistoryModel::IsTopLevelRole).toBool()) { const QUrl url = index.data(HistoryModel::UrlRole).toUrl(); // Activate urls with single mouse click in Sidebar if (m_type == HistorySidebarViewType && event->button() == Qt::LeftButton && event->modifiers() == Qt::NoModifier) { emit urlActivated(url); } } } } void HistoryTreeView::mouseDoubleClickEvent(QMouseEvent* event) { QTreeView::mouseDoubleClickEvent(event); if (selectionModel()->selectedRows().count() == 1) { QModelIndex index = indexAt(event->pos()); if (index.isValid() && !index.data(HistoryModel::IsTopLevelRole).toBool()) { const QUrl url = index.data(HistoryModel::UrlRole).toUrl(); Qt::MouseButtons buttons = event->buttons(); Qt::KeyboardModifiers modifiers = QApplication::keyboardModifiers(); if (buttons == Qt::LeftButton && modifiers == Qt::NoModifier) { emit urlActivated(url); } else if (buttons == Qt::LeftButton && modifiers == Qt::ShiftModifier) { emit urlShiftActivated(url); } } } } void HistoryTreeView::keyPressEvent(QKeyEvent* event) { QTreeView::keyPressEvent(event); if (selectionModel()->selectedRows().count() == 1) { QModelIndex index = selectionModel()->selectedRows().at(0); const QUrl url = index.data(HistoryModel::UrlRole).toUrl(); const bool isTopLevel = index.data(HistoryModel::IsTopLevelRole).toBool(); switch (event->key()) { case Qt::Key_Return: case Qt::Key_Enter: if (isTopLevel && (event->modifiers() == Qt::NoModifier || event->modifiers() == Qt::KeypadModifier)) { setExpanded(index, !isExpanded(index)); } else { Qt::KeyboardModifiers modifiers = event->modifiers(); if (modifiers == Qt::NoModifier || modifiers == Qt::KeypadModifier) { emit urlActivated(url); } else if (modifiers == Qt::ControlModifier) { emit urlCtrlActivated(url); } else if (modifiers == Qt::ShiftModifier) { emit urlShiftActivated(url); } } break; case Qt::Key_Delete: removeSelectedItems(); break; } } } void HistoryTreeView::drawRow(QPainter* painter, const QStyleOptionViewItem &options, const QModelIndex &index) const { bool itemTopLevel = index.data(HistoryModel::IsTopLevelRole).toBool(); bool iconLoaded = !index.data(HistoryModel::IconRole).value().isNull(); if (index.isValid() && !itemTopLevel && !iconLoaded) { const QPersistentModelIndex idx = index; model()->setData(idx, IconProvider::iconForUrl(index.data(HistoryModel::UrlRole).toUrl()), HistoryModel::IconRole); } QTreeView::drawRow(painter, options, index); } diff --git a/src/lib/history/historytreeview.h b/src/lib/history/historytreeview.h index cf923b81..47fd5836 100644 --- a/src/lib/history/historytreeview.h +++ b/src/lib/history/historytreeview.h @@ -1,77 +1,77 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef HISTORYTREEVIEW_H #define HISTORYTREEVIEW_H #include class History; class HistoryFilterModel; class HeaderView; class HistoryTreeView : public QTreeView { Q_OBJECT public: enum ViewType { HistoryManagerViewType, HistorySidebarViewType }; explicit HistoryTreeView(QWidget* parent = 0); ViewType viewType() const; void setViewType(ViewType type); // Returns empty url if more than one (or zero) urls are selected QUrl selectedUrl() const; HeaderView* header() const; signals: // Open url in current tab void urlActivated(const QUrl &url); // Open url in new tab void urlCtrlActivated(const QUrl &url); // Open url in new window void urlShiftActivated(const QUrl &url); // Context menu signal with point mapped to global void contextMenuRequested(const QPoint &point); public slots: void search(const QString &string); void removeSelectedItems(); protected: void contextMenuEvent(QContextMenuEvent* event); void mouseMoveEvent(QMouseEvent* event); void mousePressEvent(QMouseEvent* event); void mouseReleaseEvent(QMouseEvent* event); void mouseDoubleClickEvent(QMouseEvent* event); void keyPressEvent(QKeyEvent* event); void drawRow(QPainter* painter, const QStyleOptionViewItem &options, const QModelIndex &index) const; private: History* m_history; HistoryFilterModel* m_filter; HeaderView* m_header; ViewType m_type; }; #endif // HISTORYTREEVIEW_H diff --git a/src/lib/lib.pro b/src/lib/lib.pro index 040b651b..19784d16 100644 --- a/src/lib/lib.pro +++ b/src/lib/lib.pro @@ -1,501 +1,501 @@ QT += webenginecore webenginewidgets webchannel network widgets sql quickwidgets printsupport -TARGET = QupZilla +TARGET = Falkon TEMPLATE = lib -DEFINES *= QUPZILLA_SHAREDLIBRARY +DEFINES *= FALKON_SHAREDLIBRARY CONFIG += c++14 include(../defines.pri) include(../../translations/translations.pri) include(3rdparty/qtsingleapplication/qtsingleapplication.pri) CONFIG(debug, debug|release): include(../../tests/modeltest/modeltest.pri) unix:!contains(DEFINES, "DISABLE_DBUS") QT += dbus INCLUDEPATH += 3rdparty \ adblock \ app \ autofill \ bookmarks \ cookies \ downloads \ history \ navigation \ network \ notifications \ opensearch \ other \ plugins \ popupwindow \ preferences \ session \ sidebar \ tabwidget \ tools \ webengine \ webtab \ DEPENDPATH += $$INCLUDEPATH \ data \ SOURCES += \ 3rdparty/fancytabwidget.cpp \ 3rdparty/lineedit.cpp \ 3rdparty/processinfo.cpp \ 3rdparty/squeezelabelv1.cpp \ 3rdparty/squeezelabelv2.cpp \ 3rdparty/stylehelper.cpp \ adblock/adblockaddsubscriptiondialog.cpp \ adblock/adblockurlinterceptor.cpp \ adblock/adblockdialog.cpp \ adblock/adblockicon.cpp \ adblock/adblockmanager.cpp \ adblock/adblockmatcher.cpp \ adblock/adblockrule.cpp \ adblock/adblocksearchtree.cpp \ adblock/adblocksubscription.cpp \ adblock/adblocktreewidget.cpp \ app/autosaver.cpp \ app/browserwindow.cpp \ app/commandlineoptions.cpp \ app/datapaths.cpp \ app/mainapplication.cpp \ app/mainmenu.cpp \ app/profilemanager.cpp \ app/proxystyle.cpp \ app/qzcommon.cpp \ app/settings.cpp \ autofill/autofill.cpp \ autofill/autofillicon.cpp \ autofill/autofillnotification.cpp \ autofill/autofillwidget.cpp \ autofill/passwordbackends/databaseencryptedpasswordbackend.cpp \ autofill/passwordbackends/databasepasswordbackend.cpp \ autofill/passwordbackends/passwordbackend.cpp \ autofill/passwordmanager.cpp \ bookmarks/bookmarkitem.cpp \ bookmarks/bookmarks.cpp \ bookmarks/bookmarksexport/bookmarksexportdialog.cpp \ bookmarks/bookmarksexport/bookmarksexporter.cpp \ bookmarks/bookmarksexport/htmlexporter.cpp \ bookmarks/bookmarksicon.cpp \ bookmarks/bookmarksimport/bookmarksimportdialog.cpp \ bookmarks/bookmarksimport/bookmarksimporter.cpp \ bookmarks/bookmarksimport/firefoximporter.cpp \ bookmarks/bookmarksimport/htmlimporter.cpp \ bookmarks/bookmarksimport/chromeimporter.cpp \ bookmarks/bookmarksimport/ieimporter.cpp \ bookmarks/bookmarksimport/operaimporter.cpp \ bookmarks/bookmarksitemdelegate.cpp \ bookmarks/bookmarksmanager.cpp \ bookmarks/bookmarksmenu.cpp \ bookmarks/bookmarksmodel.cpp \ bookmarks/bookmarkstoolbarbutton.cpp \ bookmarks/bookmarkstoolbar.cpp \ bookmarks/bookmarkstools.cpp \ bookmarks/bookmarkstreeview.cpp \ bookmarks/bookmarkswidget.cpp \ cookies/cookiejar.cpp \ cookies/cookiemanager.cpp \ downloads/downloaditem.cpp \ downloads/downloadmanager.cpp \ downloads/downloadoptionsdialog.cpp \ history/history.cpp \ history/historyitem.cpp \ history/historymanager.cpp \ history/historymenu.cpp \ history/historymodel.cpp \ history/historytreeview.cpp \ navigation/completer/locationcompleter.cpp \ navigation/completer/locationcompleterdelegate.cpp \ navigation/completer/locationcompletermodel.cpp \ navigation/completer/locationcompleterrefreshjob.cpp \ navigation/completer/locationcompleterview.cpp \ navigation/downicon.cpp \ navigation/goicon.cpp \ navigation/locationbar.cpp \ navigation/locationbarpopup.cpp \ navigation/navigationbar.cpp \ navigation/navigationcontainer.cpp \ navigation/reloadstopbutton.cpp \ navigation/siteicon.cpp \ navigation/websearchbar.cpp \ network/networkmanager.cpp \ network/networkproxyfactory.cpp \ network/networkurlinterceptor.cpp \ #network/schemehandlers/fileschemehandler.cpp \ - network/schemehandlers/qupzillaschemehandler.cpp \ + network/schemehandlers/falkonschemehandler.cpp \ network/sslerrordialog.cpp \ notifications/desktopnotification.cpp \ notifications/desktopnotificationsfactory.cpp \ opensearch/editsearchengine.cpp \ opensearch/opensearchengine.cpp \ opensearch/opensearchenginedelegate.cpp \ opensearch/opensearchreader.cpp \ opensearch/searchenginesdialog.cpp \ opensearch/searchenginesmanager.cpp \ other/aboutdialog.cpp \ other/browsinglibrary.cpp \ other/clearprivatedata.cpp \ other/checkboxdialog.cpp \ other/iconchooser.cpp \ other/licenseviewer.cpp \ other/qzsettings.cpp \ other/siteinfo.cpp \ other/siteinfowidget.cpp \ other/statusbarmessage.cpp \ other/updater.cpp \ other/useragentmanager.cpp \ plugins/pluginproxy.cpp \ plugins/plugins.cpp \ plugins/speeddial.cpp \ popupwindow/popuplocationbar.cpp \ popupwindow/popupstatusbarmessage.cpp \ popupwindow/popupwebview.cpp \ popupwindow/popupwindow.cpp \ preferences/acceptlanguage.cpp \ preferences/autofillmanager.cpp \ preferences/jsoptions.cpp \ preferences/pluginlistdelegate.cpp \ preferences/pluginsmanager.cpp \ preferences/preferences.cpp \ preferences/thememanager.cpp \ preferences/useragentdialog.cpp \ session/recoveryjsobject.cpp \ session/restoremanager.cpp \ session/sessionmanager.cpp \ session/sessionmanagerdialog.cpp \ sidebar/bookmarkssidebar.cpp \ sidebar/historysidebar.cpp \ sidebar/sidebar.cpp \ tabwidget/combotabbar.cpp \ tabwidget/tabbar.cpp \ tabwidget/tabicon.cpp \ tabwidget/tabstackedwidget.cpp \ tabwidget/tabwidget.cpp \ tools/aesinterface.cpp \ tools/animatedwidget.cpp \ tools/buttonbox.cpp \ tools/buttonwithmenu.cpp \ tools/certificateinfowidget.cpp \ tools/clickablelabel.cpp \ tools/closedtabsmanager.cpp \ tools/colors.cpp \ tools/delayedfilewatcher.cpp \ tools/docktitlebarwidget.cpp \ tools/emptynetworkreply.cpp \ tools/enhancedmenu.cpp \ tools/focusselectlineedit.cpp \ tools/frame.cpp \ tools/headerview.cpp \ tools/horizontallistwidget.cpp \ tools/html5permissions/html5permissionsdialog.cpp \ tools/html5permissions/html5permissionsmanager.cpp \ tools/html5permissions/html5permissionsnotification.cpp \ tools/iconprovider.cpp \ tools/listitemdelegate.cpp \ tools/mactoolbutton.cpp \ tools/menubar.cpp \ tools/pagethumbnailer.cpp \ tools/progressbar.cpp \ tools/qzregexp.cpp \ tools/qztools.cpp \ tools/removeitemfocusdelegate.cpp \ tools/scripts.cpp \ tools/sqldatabase.cpp \ tools/toolbutton.cpp \ tools/treewidget.cpp \ tools/widget.cpp \ tools/wheelhelper.cpp \ webengine/javascript/autofilljsobject.cpp \ webengine/javascript/externaljsobject.cpp \ webengine/loadrequest.cpp \ webengine/webhittestresult.cpp \ webengine/webinspector.cpp \ webengine/webpage.cpp \ webengine/webview.cpp \ webengine/webscrollbar.cpp \ webengine/webscrollbarmanager.cpp \ webtab/searchtoolbar.cpp \ webtab/tabbedwebview.cpp \ webtab/webtab.cpp \ HEADERS += \ 3rdparty/fancytabwidget.h \ 3rdparty/lineedit.h \ 3rdparty/processinfo.h \ 3rdparty/squeezelabelv1.h \ 3rdparty/squeezelabelv2.h \ 3rdparty/stylehelper.h \ adblock/adblockaddsubscriptiondialog.h \ adblock/adblockurlinterceptor.h \ adblock/adblockdialog.h \ adblock/adblockicon.h \ adblock/adblockmanager.h \ adblock/adblockmatcher.h \ adblock/adblockrule.h \ adblock/adblocksearchtree.h \ adblock/adblocksubscription.h \ adblock/adblocktreewidget.h \ app/autosaver.h \ app/browserwindow.h \ app/commandlineoptions.h \ app/datapaths.h \ app/mainapplication.h \ app/mainmenu.h \ app/profilemanager.h \ app/proxystyle.h \ app/qzcommon.h \ app/settings.h \ autofill/autofill.h \ autofill/autofillicon.h \ autofill/autofillnotification.h \ autofill/autofillwidget.h \ autofill/passwordbackends/databaseencryptedpasswordbackend.h \ autofill/passwordbackends/databasepasswordbackend.h \ autofill/passwordbackends/passwordbackend.h \ autofill/passwordmanager.h \ bookmarks/bookmarkitem.h \ bookmarks/bookmarksexport/bookmarksexportdialog.h \ bookmarks/bookmarksexport/bookmarksexporter.h \ bookmarks/bookmarksexport/htmlexporter.h \ bookmarks/bookmarks.h \ bookmarks/bookmarksicon.h \ bookmarks/bookmarksimport/bookmarksimportdialog.h \ bookmarks/bookmarksimport/bookmarksimporter.h \ bookmarks/bookmarksimport/firefoximporter.h \ bookmarks/bookmarksimport/htmlimporter.h \ bookmarks/bookmarksimport/chromeimporter.h \ bookmarks/bookmarksimport/ieimporter.h \ bookmarks/bookmarksimport/operaimporter.h \ bookmarks/bookmarksitemdelegate.h \ bookmarks/bookmarksmanager.h \ bookmarks/bookmarksmenu.h \ bookmarks/bookmarksmodel.h \ bookmarks/bookmarkstoolbarbutton.h \ bookmarks/bookmarkstoolbar.h \ bookmarks/bookmarkstools.h \ bookmarks/bookmarkstreeview.h \ bookmarks/bookmarkswidget.h \ cookies/cookiejar.h \ cookies/cookiemanager.h \ downloads/downloaditem.h \ downloads/downloadmanager.h \ downloads/downloadoptionsdialog.h \ history/history.h \ history/historyitem.h \ history/historymanager.h \ history/historymenu.h \ history/historymodel.h \ history/historytreeview.h \ navigation/completer/locationcompleterdelegate.h \ navigation/completer/locationcompleter.h \ navigation/completer/locationcompletermodel.h \ navigation/completer/locationcompleterrefreshjob.h \ navigation/completer/locationcompleterview.h \ navigation/downicon.h \ navigation/goicon.h \ navigation/locationbar.h \ navigation/locationbarpopup.h \ navigation/navigationbar.h \ navigation/navigationcontainer.h \ navigation/reloadstopbutton.h \ navigation/siteicon.h \ navigation/websearchbar.h \ network/networkmanager.h \ network/networkproxyfactory.h \ network/networkurlinterceptor.h \ #network/schemehandlers/fileschemehandler.h \ - network/schemehandlers/qupzillaschemehandler.h \ + network/schemehandlers/falkonschemehandler.h \ network/urlinterceptor.h \ network/sslerrordialog.h \ notifications/desktopnotification.h \ notifications/desktopnotificationsfactory.h \ opensearch/editsearchengine.h \ opensearch/opensearchenginedelegate.h \ opensearch/opensearchengine.h \ opensearch/opensearchreader.h \ opensearch/searchenginesdialog.h \ opensearch/searchenginesmanager.h \ other/aboutdialog.h \ other/browsinglibrary.h \ other/clearprivatedata.h \ other/checkboxdialog.h \ other/iconchooser.h \ other/licenseviewer.h \ other/qzsettings.h \ other/siteinfo.h \ other/siteinfowidget.h \ other/statusbarmessage.h \ other/updater.h \ other/useragentmanager.h \ plugins/plugininterface.h \ plugins/pluginproxy.h \ plugins/plugins.h \ plugins/speeddial.h \ popupwindow/popuplocationbar.h \ popupwindow/popupstatusbarmessage.h \ popupwindow/popupwebview.h \ popupwindow/popupwindow.h \ preferences/acceptlanguage.h \ preferences/autofillmanager.h \ preferences/jsoptions.h \ preferences/pluginlistdelegate.h \ preferences/pluginsmanager.h \ preferences/preferences.h \ preferences/thememanager.h \ preferences/useragentdialog.h \ session/recoveryjsobject.h \ session/restoremanager.h \ session/sessionmanager.h \ session/sessionmanagerdialog.h \ sidebar/bookmarkssidebar.h \ sidebar/historysidebar.h \ sidebar/sidebar.h \ sidebar/sidebarinterface.h \ tabwidget/combotabbar.h \ tabwidget/tabbar.h \ tabwidget/tabicon.h \ tabwidget/tabstackedwidget.h \ tabwidget/tabwidget.h \ tools/aesinterface.h \ tools/animatedwidget.h \ tools/buttonbox.h \ tools/buttonwithmenu.h \ tools/certificateinfowidget.h \ tools/clickablelabel.h \ tools/closedtabsmanager.h \ tools/colors.h \ tools/delayedfilewatcher.h \ tools/docktitlebarwidget.h \ tools/emptynetworkreply.h \ tools/enhancedmenu.h \ tools/focusselectlineedit.h \ tools/frame.h \ tools/headerview.h \ tools/horizontallistwidget.h \ tools/html5permissions/html5permissionsdialog.h \ tools/html5permissions/html5permissionsmanager.h \ tools/html5permissions/html5permissionsnotification.h \ tools/iconprovider.h \ tools/listitemdelegate.h \ tools/mactoolbutton.h \ tools/menubar.h \ tools/pagethumbnailer.h \ tools/progressbar.h \ tools/qzregexp.h \ tools/qztools.h \ tools/removeitemfocusdelegate.h \ tools/scripts.h \ tools/sqldatabase.h \ tools/toolbutton.h \ tools/treewidget.h \ tools/widget.h \ tools/wheelhelper.h \ webengine/javascript/autofilljsobject.h \ webengine/javascript/externaljsobject.h \ webengine/loadrequest.h \ webengine/webhittestresult.cpp \ webengine/webinspector.h \ webengine/webpage.h \ webengine/webview.h \ webengine/webscrollbar.h \ webengine/webscrollbarmanager.h \ webtab/searchtoolbar.h \ webtab/tabbedwebview.h \ webtab/webtab.h \ FORMS += \ adblock/adblockaddsubscriptiondialog.ui \ adblock/adblockdialog.ui \ autofill/autofillnotification.ui \ autofill/autofillwidget.ui \ autofill/passwordbackends/masterpassworddialog.ui \ bookmarks/bookmarksexport/bookmarksexportdialog.ui \ bookmarks/bookmarksimport/bookmarksimportdialog.ui \ bookmarks/bookmarksmanager.ui \ bookmarks/bookmarkswidget.ui \ cookies/cookiemanager.ui \ downloads/downloaditem.ui \ downloads/downloadmanager.ui \ downloads/downloadoptionsdialog.ui \ history/historymanager.ui \ network/sslerrordialog.ui \ notifications/desktopnotification.ui \ opensearch/editsearchengine.ui \ opensearch/searchenginesdialog.ui \ other/aboutdialog.ui \ other/browsinglibrary.ui \ other/clearprivatedata.ui \ other/iconchooser.ui \ other/siteinfo.ui \ other/siteinfowidget.ui \ preferences/acceptlanguage.ui \ preferences/addacceptlanguage.ui \ preferences/autofillmanager.ui \ preferences/jsoptions.ui \ preferences/pluginslist.ui \ preferences/preferences.ui \ preferences/thememanager.ui \ preferences/useragentdialog.ui \ session/sessionmanagerdialog.ui \ sidebar/bookmarkssidebar.ui \ sidebar/historysidebar.ui \ tools/certificateinfowidget.ui \ tools/docktitlebarwidget.ui \ tools/html5permissions/html5permissionsdialog.ui \ tools/html5permissions/html5permissionsnotification.ui \ webengine/jsalert.ui \ webengine/jsconfirm.ui \ webengine/jsprompt.ui \ webtab/searchtoolbar.ui \ RESOURCES += \ data/data.qrc \ data/html.qrc \ data/icons.qrc \ data/breeze-fallback.qrc !mac:unix { target.path = $$library_folder INSTALLS += target !contains(DEFINES, NO_X11) { LIBS += -lxcb QT *= x11extras } LIBS += -lcrypto } win32 { QT *= winextras HEADERS += other/registerqappassociation.h SOURCES += other/registerqappassociation.cpp LIBS += -llibeay32 } os2 { LIBS += -lcrypto } mac { # homebrew openssl BREW_OPENSSL = /usr/local$$system("readlink `brew --prefix openssl` | sed 's/..//'") INCLUDEPATH += $$BREW_OPENSSL/include LIBS += -L$$BREW_OPENSSL/lib LIBS += -lcrypto -framework CoreServices OBJECTIVE_SOURCES += tools/disablewindowtabbbing.mm LIBS += -framework AppKit } message(===========================================) message( Using following defines:) message( $$DEFINES) diff --git a/src/lib/navigation/completer/locationcompleter.cpp b/src/lib/navigation/completer/locationcompleter.cpp index 70c380da..9f7a55d7 100644 --- a/src/lib/navigation/completer/locationcompleter.cpp +++ b/src/lib/navigation/completer/locationcompleter.cpp @@ -1,382 +1,382 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "locationcompleter.h" #include "locationcompletermodel.h" #include "locationcompleterview.h" #include "locationcompleterrefreshjob.h" #include "locationbar.h" #include "mainapplication.h" #include "browserwindow.h" #include "tabbedwebview.h" #include "tabwidget.h" #include "history.h" #include "bookmarks.h" #include "bookmarkitem.h" #include "qzsettings.h" #include "opensearchengine.h" #include "networkmanager.h" #include LocationCompleterView* LocationCompleter::s_view = 0; LocationCompleterModel* LocationCompleter::s_model = 0; LocationCompleter::LocationCompleter(QObject* parent) : QObject(parent) , m_window(0) , m_locationBar(0) , m_lastRefreshTimestamp(0) , m_popupClosed(false) { if (!s_view) { s_model = new LocationCompleterModel; s_view = new LocationCompleterView; s_view->setModel(s_model); } } void LocationCompleter::setMainWindow(BrowserWindow* window) { m_window = window; } void LocationCompleter::setLocationBar(LocationBar* locationBar) { m_locationBar = locationBar; } void LocationCompleter::closePopup() { m_popupClosed = true; s_view->close(); } void LocationCompleter::complete(const QString &string) { QString trimmedStr = string.trimmed(); // Indicates that new completion was requested by user // Eg. popup was not closed yet this completion session m_popupClosed = false; emit cancelRefreshJob(); LocationCompleterRefreshJob* job = new LocationCompleterRefreshJob(trimmedStr); connect(job, SIGNAL(finished()), this, SLOT(refreshJobFinished())); connect(this, SIGNAL(cancelRefreshJob()), job, SLOT(jobCancelled())); if (qzSettings->searchFromAddressBar && trimmedStr.length() > 2) { if (!m_openSearchEngine) { m_openSearchEngine = new OpenSearchEngine(this); m_openSearchEngine->setNetworkAccessManager(mApp->networkManager()); connect(m_openSearchEngine, &OpenSearchEngine::suggestions, this, &LocationCompleter::addSuggestions); } m_openSearchEngine->setSuggestionsUrl(LocationBar::searchEngine().suggestionsUrl); m_openSearchEngine->setSuggestionsParameters(LocationBar::searchEngine().suggestionsParameters); m_suggestionsTerm = trimmedStr; m_openSearchEngine->requestSuggestions(m_suggestionsTerm); } } void LocationCompleter::showMostVisited() { complete(QString()); } void LocationCompleter::refreshJobFinished() { LocationCompleterRefreshJob* job = qobject_cast(sender()); Q_ASSERT(job); // Don't show results of older jobs // Also don't open the popup again when it was already closed if (job->timestamp() > m_lastRefreshTimestamp && !m_popupClosed) { s_model->setCompletions(job->completions()); m_lastRefreshTimestamp = job->timestamp(); showPopup(); addSuggestions(m_oldSuggestions); if (!s_view->currentIndex().isValid() && s_model->index(0, 0).data(LocationCompleterModel::VisitSearchItemRole).toBool()) { m_ignoreCurrentChanged = true; s_view->setCurrentIndex(s_model->index(0, 0)); m_ignoreCurrentChanged = false; } if (qzSettings->useInlineCompletion) { emit showDomainCompletion(job->domainCompletion()); m_originalText = m_locationBar->text(); s_view->setOriginalText(m_originalText); } } job->deleteLater(); } void LocationCompleter::slotPopupClosed() { m_oldSuggestions.clear(); disconnect(s_view, SIGNAL(closed()), this, SLOT(slotPopupClosed())); disconnect(s_view, SIGNAL(indexActivated(QModelIndex)), this, SLOT(indexActivated(QModelIndex))); disconnect(s_view, SIGNAL(indexCtrlActivated(QModelIndex)), this, SLOT(indexCtrlActivated(QModelIndex))); disconnect(s_view, SIGNAL(indexShiftActivated(QModelIndex)), this, SLOT(indexShiftActivated(QModelIndex))); disconnect(s_view, SIGNAL(indexDeleteRequested(QModelIndex)), this, SLOT(indexDeleteRequested(QModelIndex))); disconnect(s_view->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), this, SLOT(currentChanged(QModelIndex))); emit popupClosed(); } void LocationCompleter::addSuggestions(const QStringList &suggestions) { const auto suggestionItems = s_model->suggestionItems(); // Delete existing suggestions for (QStandardItem *item : suggestionItems) { s_model->takeRow(item->row()); delete item; } // Add new suggestions QList items; for (const QString &suggestion : suggestions) { QStandardItem* item = new QStandardItem(); item->setText(suggestion); item->setData(suggestion, LocationCompleterModel::TitleRole); item->setData(suggestion, LocationCompleterModel::UrlRole); item->setData(m_suggestionsTerm, LocationCompleterModel::SearchStringRole); item->setData(true, LocationCompleterModel::SearchSuggestionRole); items.append(item); } s_model->addCompletions(items); adjustPopupSize(); m_oldSuggestions = suggestions; } void LocationCompleter::currentChanged(const QModelIndex &index) { if (m_ignoreCurrentChanged) { return; } QString completion = index.data().toString(); bool completeDomain = index.data(LocationCompleterModel::VisitSearchItemRole).toBool(); // Domain completion was dismissed if (completeDomain && completion == m_originalText) { completeDomain = false; } if (completion.isEmpty()) { completeDomain = true; completion = m_originalText; } emit showCompletion(completion, completeDomain); } void LocationCompleter::indexActivated(const QModelIndex &index) { Q_ASSERT(index.isValid()); QUrl url = index.data(LocationCompleterModel::UrlRole).toUrl(); bool ok; const int tabPos = index.data(LocationCompleterModel::TabPositionTabRole).toInt(&ok); // Switch to tab with simple index activation if (ok && tabPos > -1) { BrowserWindow* window = static_cast(index.data(LocationCompleterModel::TabPositionWindowRole).value()); Q_ASSERT(window); switchToTab(window, tabPos); return; } if (index.data(LocationCompleterModel::BookmarkRole).toBool()) { BookmarkItem* bookmark = static_cast(index.data(LocationCompleterModel::BookmarkItemRole).value()); bookmark->updateVisitCount(); } if (index.data(LocationCompleterModel::VisitSearchItemRole).toBool()) { url = QUrl(m_originalText); } loadUrl(url); } void LocationCompleter::indexCtrlActivated(const QModelIndex &index) { Q_ASSERT(index.isValid()); Q_ASSERT(m_window); if (index.data(LocationCompleterModel::BookmarkRole).toBool()) { BookmarkItem* bookmark = static_cast(index.data(LocationCompleterModel::BookmarkItemRole).value()); bookmark->updateVisitCount(); } const QUrl url = index.data(LocationCompleterModel::UrlRole).toUrl(); const QString title = index.data(LocationCompleterModel::TitleRole).toString(); closePopup(); // Clear locationbar emit clearCompletion(); // Open url in new tab m_window->tabWidget()->addView(url, title, Qz::NT_CleanSelectedTab); } void LocationCompleter::indexShiftActivated(const QModelIndex &index) { Q_ASSERT(index.isValid()); if (index.data(LocationCompleterModel::BookmarkRole).toBool()) { BookmarkItem* bookmark = static_cast(index.data(LocationCompleterModel::BookmarkItemRole).value()); bookmark->updateVisitCount(); } const QUrl url = index.data(LocationCompleterModel::UrlRole).toUrl(); const int tabPos = index.data(LocationCompleterModel::TabPositionTabRole).toInt(); // Load url (instead of switching to tab) with shift activation if (tabPos > -1) { loadUrl(url); return; } closePopup(); // Clear locationbar emit clearCompletion(); // Open new window mApp->createWindow(Qz::BW_NewWindow, url); } void LocationCompleter::indexDeleteRequested(const QModelIndex &index) { if (!index.isValid()) { return; } if (index.data(LocationCompleterModel::BookmarkRole).toBool()) { BookmarkItem* bookmark = static_cast(index.data(LocationCompleterModel::BookmarkItemRole).value()); mApp->bookmarks()->removeBookmark(bookmark); } else { int id = index.data(LocationCompleterModel::IdRole).toInt(); mApp->history()->deleteHistoryEntry(id); } s_view->setUpdatesEnabled(false); s_model->removeRow(index.row(), index.parent()); s_view->setUpdatesEnabled(true); // Close popup when removing last item if (s_model->rowCount() == 0) { closePopup(); } else { adjustPopupSize(); } } void LocationCompleter::switchToTab(BrowserWindow* window, int tab) { Q_ASSERT(window); Q_ASSERT(tab >= 0); closePopup(); // Clear locationbar emit clearCompletion(); TabWidget* tabWidget = window->tabWidget(); if (window->isActiveWindow() || tabWidget->currentIndex() != tab) { tabWidget->setCurrentIndex(tab); window->show(); window->activateWindow(); window->raise(); } else { window->weView()->setFocus(); } } void LocationCompleter::loadUrl(const QUrl &url) { closePopup(); // Show url in locationbar emit showCompletion(url.toString(), false); // Load url emit loadCompletion(); } void LocationCompleter::showPopup() { Q_ASSERT(m_locationBar); if (s_model->rowCount() == 0) { s_view->close(); return; } if (s_view->isVisible()) { adjustPopupSize(); return; } QRect popupRect(m_locationBar->mapToGlobal(m_locationBar->pos()), m_locationBar->size()); popupRect.setY(popupRect.bottom()); s_view->setGeometry(popupRect); s_view->setFocusProxy(m_locationBar); s_view->setCurrentIndex(QModelIndex()); connect(s_view, SIGNAL(closed()), this, SLOT(slotPopupClosed())); connect(s_view, SIGNAL(indexActivated(QModelIndex)), this, SLOT(indexActivated(QModelIndex))); connect(s_view, SIGNAL(indexCtrlActivated(QModelIndex)), this, SLOT(indexCtrlActivated(QModelIndex))); connect(s_view, SIGNAL(indexShiftActivated(QModelIndex)), this, SLOT(indexShiftActivated(QModelIndex))); connect(s_view, SIGNAL(indexDeleteRequested(QModelIndex)), this, SLOT(indexDeleteRequested(QModelIndex))); connect(s_view->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), this, SLOT(currentChanged(QModelIndex))); if (m_locationBar->nativeParentWidget()) { s_view->createWinId(); s_view->windowHandle()->setTransientParent(m_locationBar->nativeParentWidget()->windowHandle()); } adjustPopupSize(); } void LocationCompleter::adjustPopupSize() { const int maxItemsCount = 12; const int popupHeight = s_view->sizeHintForRow(0) * qMin(maxItemsCount, s_model->rowCount()) + 2 * s_view->frameWidth(); m_originalText = m_locationBar->text(); s_view->setOriginalText(m_originalText); s_view->resize(s_view->width(), popupHeight); s_view->show(); } diff --git a/src/lib/navigation/completer/locationcompleter.h b/src/lib/navigation/completer/locationcompleter.h index 8e3542d5..f94adeb1 100644 --- a/src/lib/navigation/completer/locationcompleter.h +++ b/src/lib/navigation/completer/locationcompleter.h @@ -1,89 +1,89 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef LOCATIONCOMPLETER_H #define LOCATIONCOMPLETER_H #include #include "qzcommon.h" class QUrl; class QModelIndex; class LocationBar; class BrowserWindow; class OpenSearchEngine; class LocationCompleterModel; class LocationCompleterView; -class QUPZILLA_EXPORT LocationCompleter : public QObject +class FALKON_EXPORT LocationCompleter : public QObject { Q_OBJECT public: explicit LocationCompleter(QObject* parent = 0); void setMainWindow(BrowserWindow* window); void setLocationBar(LocationBar* locationBar); void closePopup(); public slots: void complete(const QString &string); void showMostVisited(); signals: void showCompletion(const QString &completion, bool completeDomain); void showDomainCompletion(const QString &completion); void loadCompletion(); void clearCompletion(); void popupClosed(); void cancelRefreshJob(); private slots: void refreshJobFinished(); void slotPopupClosed(); void addSuggestions(const QStringList &suggestions); void currentChanged(const QModelIndex &index); void indexActivated(const QModelIndex &index); void indexCtrlActivated(const QModelIndex &index); void indexShiftActivated(const QModelIndex &index); void indexDeleteRequested(const QModelIndex &index); private: void switchToTab(BrowserWindow* window, int tab); void loadUrl(const QUrl &url); void showPopup(); void adjustPopupSize(); BrowserWindow* m_window; LocationBar* m_locationBar; qint64 m_lastRefreshTimestamp; QString m_originalText; bool m_popupClosed; bool m_ignoreCurrentChanged = false; OpenSearchEngine* m_openSearchEngine = nullptr; QStringList m_oldSuggestions; QString m_suggestionsTerm; static LocationCompleterView* s_view; static LocationCompleterModel* s_model; }; #endif // LOCATIONCOMPLETER_H diff --git a/src/lib/navigation/completer/locationcompleterdelegate.cpp b/src/lib/navigation/completer/locationcompleterdelegate.cpp index 96582001..d9f3f7ee 100644 --- a/src/lib/navigation/completer/locationcompleterdelegate.cpp +++ b/src/lib/navigation/completer/locationcompleterdelegate.cpp @@ -1,387 +1,387 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "locationcompleterdelegate.h" #include "locationcompletermodel.h" #include "locationbar.h" #include "iconprovider.h" #include "qzsettings.h" #include "mainapplication.h" #include #include #include #include #include static bool isUrlOrDomain(const QString &text) { QUrl url(text); if (!url.scheme().isEmpty() && (!url.host().isEmpty() || !url.path().isEmpty())) { return true; } if (text.contains(QL1C('.')) && !text.contains(QL1C(' '))) { return true; } if (text == QL1S("localhost")) { return true; } return false; } LocationCompleterDelegate::LocationCompleterDelegate(QObject *parent) : QStyledItemDelegate(parent) , m_rowHeight(0) , m_padding(0) , m_drawSwitchToTab(true) { } void LocationCompleterDelegate::paint(QPainter* painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { QStyleOptionViewItem opt = option; initStyleOption(&opt, index); const QWidget* w = opt.widget; const QStyle* style = w ? w->style() : QApplication::style(); const int height = opt.rect.height(); const int center = height / 2 + opt.rect.top(); // Prepare title font QFont titleFont = opt.font; titleFont.setPointSize(titleFont.pointSize() + 1); const QFontMetrics titleMetrics(titleFont); int leftPosition = m_padding * 2; int rightPosition = opt.rect.right() - m_padding; opt.state |= QStyle::State_Active; const QIcon::Mode iconMode = opt.state & QStyle::State_Selected ? QIcon::Selected : QIcon::Normal; const QPalette::ColorRole colorRole = opt.state & QStyle::State_Selected ? QPalette::HighlightedText : QPalette::Text; const QPalette::ColorRole colorLinkRole = opt.state & QStyle::State_Selected ? QPalette::HighlightedText : QPalette::Link; #ifdef Q_OS_WIN opt.palette.setColor(QPalette::All, QPalette::HighlightedText, opt.palette.color(QPalette::Active, QPalette::Text)); opt.palette.setColor(QPalette::All, QPalette::Highlight, opt.palette.base().color().darker(108)); #endif QPalette textPalette = opt.palette; textPalette.setCurrentColorGroup(opt.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled); // Draw background style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, w); const bool isVisitSearchItem = index.data(LocationCompleterModel::VisitSearchItemRole).toBool(); const bool isSearchSuggestion = index.data(LocationCompleterModel::SearchSuggestionRole).toBool(); const bool isWebSearch = qzSettings->searchFromAddressBar && !isUrlOrDomain(m_originalText.trimmed()); // Draw icon const int iconSize = 16; const int iconYPos = center - (iconSize / 2); QRect iconRect(leftPosition, iconYPos, iconSize, iconSize); QPixmap pixmap = index.data(Qt::DecorationRole).value().pixmap(iconSize, iconMode); if (isSearchSuggestion || (isVisitSearchItem && isWebSearch)) { pixmap = QIcon::fromTheme(QSL("edit-find"), QIcon(QSL(":icons/menu/search-icon.svg"))).pixmap(iconSize, iconMode); } painter->drawPixmap(iconRect, pixmap); leftPosition = iconRect.right() + m_padding * 2; // Draw star to bookmark items int starPixmapWidth = 0; if (index.data(LocationCompleterModel::BookmarkRole).toBool()) { const QIcon icon = IconProvider::instance()->bookmarkIcon(); const QSize starSize(16, 16); starPixmapWidth = starSize.width(); QPoint pos(rightPosition - starPixmapWidth, center - starSize.height() / 2); QRect starRect(pos, starSize); painter->drawPixmap(starRect, icon.pixmap(starSize, iconMode)); } QString searchText = index.data(LocationCompleterModel::SearchStringRole).toString(); // Draw title leftPosition += 2; QRect titleRect(leftPosition, center - titleMetrics.height() / 2, opt.rect.width() * 0.6, titleMetrics.height()); QString title = index.data(LocationCompleterModel::TitleRole).toString(); painter->setFont(titleFont); if (isVisitSearchItem) { title = m_originalText.trimmed(); if (searchText == title) { searchText.clear(); } } leftPosition += viewItemDrawText(painter, &opt, titleRect, title, textPalette.color(colorRole), searchText); leftPosition += m_padding * 2; // Trim link to maximum number of characters that can be visible, otherwise there may be perf issue with huge URLs const int maxChars = (opt.rect.width() - leftPosition) / opt.fontMetrics.width(QL1C('i')); QString link; const QByteArray linkArray = index.data(Qt::DisplayRole).toByteArray(); if (!linkArray.startsWith("data") && !linkArray.startsWith("javascript")) { link = QString::fromUtf8(QByteArray::fromPercentEncoding(linkArray)).left(maxChars); } else { link = QString::fromLatin1(linkArray.left(maxChars)); } if (isVisitSearchItem || isSearchSuggestion) { if (!isSearchSuggestion && !isWebSearch) { link = tr("Visit"); } else if (opt.state.testFlag(QStyle::State_Selected) || opt.state.testFlag(QStyle::State_MouseOver)) { QString searchEngineName; const int firstSpacePos = title.indexOf(QL1C(' ')); if (firstSpacePos != -1) { const QString shortcut = title.left(firstSpacePos); searchEngineName = mApp->searchEnginesManager()->engineForShortcut(shortcut).name; } if (searchEngineName.isEmpty()) { searchEngineName = LocationBar::searchEngine().name; } link = tr("Search with %1").arg(searchEngineName); } else { link.clear(); } } // Draw separator if (!link.isEmpty()) { QChar separator = QL1C('-'); QRect separatorRect(leftPosition, center - titleMetrics.height() / 2, titleMetrics.width(separator), titleMetrics.height()); style->drawItemText(painter, separatorRect, Qt::AlignCenter, textPalette, true, separator, colorRole); leftPosition += separatorRect.width() + m_padding * 2; } // Draw link const int leftLinkEdge = leftPosition; const int rightLinkEdge = rightPosition - m_padding - starPixmapWidth; QRect linkRect(leftLinkEdge, center - opt.fontMetrics.height() / 2, rightLinkEdge - leftLinkEdge, opt.fontMetrics.height()); painter->setFont(opt.font); // Draw url (or switch to tab) int tabPos = index.data(LocationCompleterModel::TabPositionTabRole).toInt(); if (drawSwitchToTab() && tabPos != -1) { const QIcon tabIcon = QIcon(QSL(":icons/menu/tab.svg")); QRect iconRect(linkRect); iconRect.setX(iconRect.x()); iconRect.setWidth(16); painter->drawPixmap(iconRect, tabIcon.pixmap(iconRect.size(), iconMode)); QRect textRect(linkRect); textRect.setX(textRect.x() + m_padding + 16 + m_padding); viewItemDrawText(painter, &opt, textRect, tr("Switch to tab"), textPalette.color(colorLinkRole)); } else if (isVisitSearchItem || isSearchSuggestion) { viewItemDrawText(painter, &opt, linkRect, link, textPalette.color(colorLinkRole)); } else { viewItemDrawText(painter, &opt, linkRect, link, textPalette.color(colorLinkRole), searchText); } // Draw line at the very bottom of item if the item is not highlighted if (!(opt.state & QStyle::State_Selected)) { QRect lineRect(opt.rect.left(), opt.rect.bottom(), opt.rect.width(), 1); painter->fillRect(lineRect, opt.palette.color(QPalette::AlternateBase)); } } QSize LocationCompleterDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const { Q_UNUSED(index) if (!m_rowHeight) { QStyleOptionViewItem opt(option); initStyleOption(&opt, index); const QWidget* w = opt.widget; const QStyle* style = w ? w->style() : QApplication::style(); const int padding = style->pixelMetric(QStyle::PM_FocusFrameHMargin, 0) + 1; QFont titleFont = opt.font; titleFont.setPointSize(titleFont.pointSize() + 1); m_padding = padding > 3 ? padding : 3; const QFontMetrics titleMetrics(titleFont); m_rowHeight = 4 * m_padding + qMax(16, titleMetrics.height()); } return QSize(200, m_rowHeight); } void LocationCompleterDelegate::setShowSwitchToTab(bool enable) { m_drawSwitchToTab = enable; } void LocationCompleterDelegate::setOriginalText(const QString &originalText) { m_originalText = originalText; } bool LocationCompleterDelegate::drawSwitchToTab() const { return qzSettings->showSwitchTab && m_drawSwitchToTab; } static bool sizeBiggerThan(const QString &s1, const QString &s2) { return s1.size() > s2.size(); } static QSizeF viewItemTextLayout(QTextLayout &textLayout, int lineWidth) { qreal height = 0; qreal widthUsed = 0; textLayout.beginLayout(); QTextLine line = textLayout.createLine(); if (line.isValid()) { line.setLineWidth(lineWidth); line.setPosition(QPointF(0, height)); height += line.height(); widthUsed = qMax(widthUsed, line.naturalTextWidth()); textLayout.endLayout(); } return QSizeF(widthUsed, height); } // most of codes taken from QCommonStylePrivate::viewItemDrawText() // added highlighting and simplified for single-line textlayouts int LocationCompleterDelegate::viewItemDrawText(QPainter *p, const QStyleOptionViewItem *option, const QRect &rect, const QString &text, const QColor &color, const QString &searchText) const { if (text.isEmpty()) { return 0; } const QFontMetrics fontMetrics(p->font()); QString elidedText = fontMetrics.elidedText(text, option->textElideMode, rect.width()); QTextOption textOption; textOption.setWrapMode(QTextOption::NoWrap); textOption.setTextDirection(text.isRightToLeft() ? Qt::RightToLeft : Qt::LeftToRight); textOption.setAlignment(QStyle::visualAlignment(textOption.textDirection(), option->displayAlignment)); QTextLayout textLayout; textLayout.setFont(p->font()); textLayout.setText(elidedText); textLayout.setTextOption(textOption); if (!searchText.isEmpty()) { QList delimiters; QStringList searchStrings = searchText.split(QLatin1Char(' '), QString::SkipEmptyParts); // Look for longer parts first std::sort(searchStrings.begin(), searchStrings.end(), sizeBiggerThan); foreach (const QString &string, searchStrings) { int delimiter = text.indexOf(string, 0, Qt::CaseInsensitive); while (delimiter != -1) { int start = delimiter; int end = delimiter + string.length(); bool alreadyContains = false; for (int i = 0; i < delimiters.count(); ++i) { int dStart = delimiters.at(i); int dEnd = delimiters.at(++i); if (dStart <= start && dEnd >= end) { alreadyContains = true; break; } } if (!alreadyContains) { delimiters.append(start); delimiters.append(end); } delimiter = text.indexOf(string, end, Qt::CaseInsensitive); } } // We need to sort delimiters to properly paint all parts that user typed std::sort(delimiters.begin(), delimiters.end()); // If we don't find any match, just paint it without any highlight if (!delimiters.isEmpty() && !(delimiters.count() % 2)) { QList highlightParts; QTextLayout::FormatRange lighterWholeLine; lighterWholeLine.start = 0; lighterWholeLine.length = elidedText.size(); QColor lighterColor = color.lighter(130); if (lighterColor == color) { lighterColor = QColor(Qt::gray).darker(180); } lighterWholeLine.format.setForeground(lighterColor); highlightParts << lighterWholeLine; while (!delimiters.isEmpty()) { QTextLayout::FormatRange highlightedPart; int start = delimiters.takeFirst(); int end = delimiters.takeFirst(); highlightedPart.start = start; highlightedPart.length = end - start; highlightedPart.format.setFontWeight(QFont::Bold); highlightedPart.format.setUnderlineStyle(QTextCharFormat::SingleUnderline); highlightedPart.format.setForeground(color); highlightParts << highlightedPart; } textLayout.setAdditionalFormats(highlightParts); } } // do layout viewItemTextLayout(textLayout, rect.width()); if (textLayout.lineCount() <= 0) { return 0; } QTextLine textLine = textLayout.lineAt(0); // if elidedText after highlighting is longer // than available width then re-elide it and redo layout int diff = textLine.naturalTextWidth() - rect.width(); if (diff > 0) { elidedText = fontMetrics.elidedText(elidedText, option->textElideMode, rect.width() - diff); textLayout.setText(elidedText); // redo layout viewItemTextLayout(textLayout, rect.width()); if (textLayout.lineCount() <= 0) { return 0; } textLine = textLayout.lineAt(0); } // draw line p->setPen(color); qreal width = qMax(rect.width(), textLayout.lineAt(0).width()); const QRect &layoutRect = QStyle::alignedRect(option->direction, option->displayAlignment, QSize(int(width), int(textLine.height())), rect); const QPointF &position = layoutRect.topLeft(); textLine.draw(p, position); return qMin(rect.width(), textLayout.lineAt(0).naturalTextWidth()); } diff --git a/src/lib/navigation/completer/locationcompleterdelegate.h b/src/lib/navigation/completer/locationcompleterdelegate.h index dcf5c25b..37ef7c4d 100644 --- a/src/lib/navigation/completer/locationcompleterdelegate.h +++ b/src/lib/navigation/completer/locationcompleterdelegate.h @@ -1,49 +1,49 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef LOCATIONCOMPLETERDELEGATE_H #define LOCATIONCOMPLETERDELEGATE_H #include #include "qzcommon.h" -class QUPZILLA_EXPORT LocationCompleterDelegate : public QStyledItemDelegate +class FALKON_EXPORT LocationCompleterDelegate : public QStyledItemDelegate { public: explicit LocationCompleterDelegate(QObject *parent = 0); void paint(QPainter* painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const; void setShowSwitchToTab(bool enable); void setOriginalText(const QString &originalText); private: bool drawSwitchToTab() const; int viewItemDrawText(QPainter *p, const QStyleOptionViewItem *option, const QRect &rect, const QString &text, const QColor &color, const QString &searchText = QString()) const; mutable int m_rowHeight; mutable int m_padding; bool m_drawSwitchToTab; QString m_originalText; }; #endif // LOCATIONCOMPLETERDELEGATE_H diff --git a/src/lib/navigation/completer/locationcompletermodel.cpp b/src/lib/navigation/completer/locationcompletermodel.cpp index 1cc9fbbf..9225d4e7 100644 --- a/src/lib/navigation/completer/locationcompletermodel.cpp +++ b/src/lib/navigation/completer/locationcompletermodel.cpp @@ -1,177 +1,177 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "locationcompletermodel.h" #include "mainapplication.h" #include "iconprovider.h" #include "bookmarkitem.h" #include "bookmarks.h" #include "qzsettings.h" #include "browserwindow.h" #include "tabwidget.h" #include LocationCompleterModel::LocationCompleterModel(QObject* parent) : QStandardItemModel(parent) { } void LocationCompleterModel::setCompletions(const QList &items) { clear(); addCompletions(items); } void LocationCompleterModel::addCompletions(const QList &items) { for (QStandardItem *item : items) { item->setIcon(QPixmap::fromImage(item->data(ImageRole).value())); setTabPosition(item); if (item->icon().isNull()) { item->setIcon(IconProvider::emptyWebIcon()); } appendRow(QList{item}); } } QList LocationCompleterModel::suggestionItems() const { QList items; for (int i = 0; i < rowCount(); ++i) { QStandardItem *it = item(i); if (it->data(SearchSuggestionRole).toBool()) { items.append(it); } } return items; } QSqlQuery LocationCompleterModel::createDomainQuery(const QString &text) { if (text.isEmpty() || text == QLatin1String("www.")) { return QSqlQuery(); } bool withoutWww = text.startsWith(QLatin1Char('w')) && !text.startsWith(QLatin1String("www.")); QString query = "SELECT url FROM history WHERE "; if (withoutWww) { query.append(QLatin1String("url NOT LIKE ? AND url NOT LIKE ? AND ")); } else { query.append(QLatin1String("url LIKE ? OR url LIKE ? OR ")); } query.append(QLatin1String("(url LIKE ? OR url LIKE ?) LIMIT 1")); QSqlQuery sqlQuery; sqlQuery.prepare(query); if (withoutWww) { sqlQuery.addBindValue(QString("http://www.%")); sqlQuery.addBindValue(QString("https://www.%")); sqlQuery.addBindValue(QString("http://%1%").arg(text)); sqlQuery.addBindValue(QString("https://%1%").arg(text)); } else { sqlQuery.addBindValue(QString("http://%1%").arg(text)); sqlQuery.addBindValue(QString("https://%1%").arg(text)); sqlQuery.addBindValue(QString("http://www.%1%").arg(text)); sqlQuery.addBindValue(QString("https://www.%1%").arg(text)); } return sqlQuery; } QSqlQuery LocationCompleterModel::createHistoryQuery(const QString &searchString, int limit, bool exactMatch) { QStringList searchList; QString query = QLatin1String("SELECT id, url, title, count FROM history WHERE "); if (exactMatch) { query.append(QLatin1String("title LIKE ? OR url LIKE ? ")); } else { searchList = searchString.split(QLatin1Char(' '), QString::SkipEmptyParts); const int slSize = searchList.size(); for (int i = 0; i < slSize; ++i) { query.append(QLatin1String("(title LIKE ? OR url LIKE ?) ")); if (i < slSize - 1) { query.append(QLatin1String("AND ")); } } } query.append(QLatin1String("ORDER BY date DESC LIMIT ?")); QSqlQuery sqlQuery; sqlQuery.prepare(query); if (exactMatch) { sqlQuery.addBindValue(QString("%%1%").arg(searchString)); sqlQuery.addBindValue(QString("%%1%").arg(searchString)); } else { foreach (const QString &str, searchList) { sqlQuery.addBindValue(QString("%%1%").arg(str)); sqlQuery.addBindValue(QString("%%1%").arg(str)); } } sqlQuery.addBindValue(limit); return sqlQuery; } void LocationCompleterModel::setTabPosition(QStandardItem* item) const { Q_ASSERT(item); if (!qzSettings->showSwitchTab) { return; } const QUrl url = item->data(UrlRole).toUrl(); const QList windows = mApp->windows(); foreach (BrowserWindow* window, windows) { QList tabs = window->tabWidget()->allTabs(); for (int i = 0; i < tabs.count(); ++i) { WebTab* tab = tabs.at(i); if (tab->url() == url) { item->setData(QVariant::fromValue(static_cast(window)), TabPositionWindowRole); item->setData(i, TabPositionTabRole); return; } } } // Tab wasn't found item->setData(QVariant::fromValue(static_cast(0)), TabPositionWindowRole); item->setData(-1, TabPositionTabRole); } void LocationCompleterModel::refreshTabPositions() const { for (int row = 0; row < rowCount(); ++row) { QStandardItem* itm = item(row); if (itm) { setTabPosition(itm); } } } diff --git a/src/lib/navigation/completer/locationcompletermodel.h b/src/lib/navigation/completer/locationcompletermodel.h index 139c4b16..d2c7aa78 100644 --- a/src/lib/navigation/completer/locationcompletermodel.h +++ b/src/lib/navigation/completer/locationcompletermodel.h @@ -1,68 +1,68 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef LOCATIONCOMPLETERMODEL_H #define LOCATIONCOMPLETERMODEL_H #include #include "qzcommon.h" class QSqlQuery; class QUrl; class LocationCompleterModel : public QStandardItemModel { public: enum Role { IdRole = Qt::UserRole + 1, TitleRole, UrlRole, CountRole, BookmarkRole, BookmarkItemRole, SearchStringRole, TabPositionWindowRole, TabPositionTabRole, ImageRole, VisitSearchItemRole, SearchSuggestionRole }; explicit LocationCompleterModel(QObject* parent = 0); void setCompletions(const QList &items); void addCompletions(const QList &items); QList suggestionItems() const; static QSqlQuery createHistoryQuery(const QString &searchString, int limit, bool exactMatch = false); static QSqlQuery createDomainQuery(const QString &text); private: enum Type { HistoryAndBookmarks = 0, History = 1, Bookmarks = 2, Nothing = 4 }; void setTabPosition(QStandardItem* item) const; void refreshTabPositions() const; }; #endif // LOCATIONCOMPLETERMODEL_H diff --git a/src/lib/navigation/completer/locationcompleterrefreshjob.cpp b/src/lib/navigation/completer/locationcompleterrefreshjob.cpp index 1952da10..ef0043c8 100644 --- a/src/lib/navigation/completer/locationcompleterrefreshjob.cpp +++ b/src/lib/navigation/completer/locationcompleterrefreshjob.cpp @@ -1,225 +1,225 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2014-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "locationcompleterrefreshjob.h" #include "locationcompletermodel.h" #include "mainapplication.h" #include "bookmarkitem.h" #include "iconprovider.h" #include "sqldatabase.h" #include "qzsettings.h" #include "bookmarks.h" #include "qztools.h" #include #include #include LocationCompleterRefreshJob::LocationCompleterRefreshJob(const QString &searchString) : QObject() , m_timestamp(QDateTime::currentMSecsSinceEpoch()) , m_searchString(searchString) , m_jobCancelled(false) { m_watcher = new QFutureWatcher(this); connect(m_watcher, SIGNAL(finished()), this, SLOT(slotFinished())); QFuture future = QtConcurrent::run(this, &LocationCompleterRefreshJob::runJob); m_watcher->setFuture(future); } qint64 LocationCompleterRefreshJob::timestamp() const { return m_timestamp; } QString LocationCompleterRefreshJob::searchString() const { return m_searchString; } QList LocationCompleterRefreshJob::completions() const { return m_items; } QString LocationCompleterRefreshJob::domainCompletion() const { return m_domainCompletion; } void LocationCompleterRefreshJob::jobCancelled() { m_jobCancelled = true; } void LocationCompleterRefreshJob::slotFinished() { emit finished(); } static bool countBiggerThan(const QStandardItem* i1, const QStandardItem* i2) { int i1Count = i1->data(LocationCompleterModel::CountRole).toInt(); int i2Count = i2->data(LocationCompleterModel::CountRole).toInt(); return i1Count > i2Count; } void LocationCompleterRefreshJob::runJob() { if (m_jobCancelled || mApp->isClosing() || !mApp) { return; } if (m_searchString.isEmpty()) { completeMostVisited(); } else { completeFromHistory(); } // Load all icons into QImage foreach (QStandardItem* item, m_items) { if (m_jobCancelled) { return; } const QUrl url = item->data(LocationCompleterModel::UrlRole).toUrl(); item->setData(IconProvider::imageForUrl(url), LocationCompleterModel::ImageRole); } // Get domain completion if (!m_searchString.isEmpty() && qzSettings->useInlineCompletion) { QSqlQuery domainQuery = LocationCompleterModel::createDomainQuery(m_searchString); if (domainQuery.lastQuery().isEmpty()) { return; } SqlDatabase::instance()->exec(domainQuery); if (domainQuery.next()) { m_domainCompletion = createDomainCompletion(domainQuery.value(0).toUrl().host()); } } // Add search/visit item if (!m_searchString.isEmpty()) { QStandardItem* item = new QStandardItem(); item->setText(m_searchString); item->setData(m_searchString, LocationCompleterModel::UrlRole); item->setData(m_searchString, LocationCompleterModel::SearchStringRole); item->setData(QVariant(true), LocationCompleterModel::VisitSearchItemRole); if (!m_domainCompletion.isEmpty()) { const QUrl url = QUrl(QSL("http://%1").arg(m_domainCompletion)); item->setData(IconProvider::imageForDomain(url), LocationCompleterModel::ImageRole); } m_items.prepend(item); } } void LocationCompleterRefreshJob::completeFromHistory() { QList urlList; Type showType = (Type) qzSettings->showLocationSuggestions; // Search in bookmarks if (showType == HistoryAndBookmarks || showType == Bookmarks) { const int bookmarksLimit = 10; QList bookmarks = mApp->bookmarks()->searchBookmarks(m_searchString, bookmarksLimit); foreach (BookmarkItem* bookmark, bookmarks) { Q_ASSERT(bookmark->isUrl()); QStandardItem* item = new QStandardItem(); item->setText(bookmark->url().toEncoded()); item->setData(-1, LocationCompleterModel::IdRole); item->setData(bookmark->title(), LocationCompleterModel::TitleRole); item->setData(bookmark->url(), LocationCompleterModel::UrlRole); item->setData(bookmark->visitCount(), LocationCompleterModel::CountRole); item->setData(QVariant(true), LocationCompleterModel::BookmarkRole); item->setData(QVariant::fromValue(static_cast(bookmark)), LocationCompleterModel::BookmarkItemRole); item->setData(m_searchString, LocationCompleterModel::SearchStringRole); urlList.append(bookmark->url()); m_items.append(item); } } // Sort by count std::sort(m_items.begin(), m_items.end(), countBiggerThan); // Search in history if (showType == HistoryAndBookmarks || showType == History) { const int historyLimit = 20; QSqlQuery query = LocationCompleterModel::createHistoryQuery(m_searchString, historyLimit); SqlDatabase::instance()->exec(query); while (query.next()) { const QUrl url = query.value(1).toUrl(); if (urlList.contains(url)) { continue; } QStandardItem* item = new QStandardItem(); item->setText(url.toEncoded()); item->setData(query.value(0), LocationCompleterModel::IdRole); item->setData(query.value(2), LocationCompleterModel::TitleRole); item->setData(url, LocationCompleterModel::UrlRole); item->setData(query.value(3), LocationCompleterModel::CountRole); item->setData(QVariant(false), LocationCompleterModel::BookmarkRole); item->setData(m_searchString, LocationCompleterModel::SearchStringRole); m_items.append(item); } } } void LocationCompleterRefreshJob::completeMostVisited() { QSqlQuery query(QSL("SELECT id, url, title FROM history ORDER BY count DESC LIMIT 15")); SqlDatabase::instance()->exec(query); while (query.next()) { QStandardItem* item = new QStandardItem(); const QUrl url = query.value(1).toUrl(); item->setText(url.toEncoded()); item->setData(query.value(0), LocationCompleterModel::IdRole); item->setData(query.value(2), LocationCompleterModel::TitleRole); item->setData(url, LocationCompleterModel::UrlRole); item->setData(QVariant(false), LocationCompleterModel::BookmarkRole); m_items.append(item); } } QString LocationCompleterRefreshJob::createDomainCompletion(const QString &completion) const { // Make sure search string and completion matches if (m_searchString.startsWith(QL1S("www.")) && !completion.startsWith(QL1S("www."))) { return QL1S("www.") + completion; } if (!m_searchString.startsWith(QL1S("www.")) && completion.startsWith(QL1S("www."))) { return completion.mid(4); } return completion; } diff --git a/src/lib/navigation/completer/locationcompleterrefreshjob.h b/src/lib/navigation/completer/locationcompleterrefreshjob.h index 7913fa56..9f215790 100644 --- a/src/lib/navigation/completer/locationcompleterrefreshjob.h +++ b/src/lib/navigation/completer/locationcompleterrefreshjob.h @@ -1,70 +1,70 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef LOCATIONCOMPLETERREFRESHJOB_H #define LOCATIONCOMPLETERREFRESHJOB_H #include #include "qzcommon.h" class QStandardItem; -class QUPZILLA_EXPORT LocationCompleterRefreshJob : public QObject +class FALKON_EXPORT LocationCompleterRefreshJob : public QObject { Q_OBJECT public: explicit LocationCompleterRefreshJob(const QString &searchString); // Timestamp when the job was created qint64 timestamp() const; QString searchString() const; QList completions() const; QString domainCompletion() const; signals: void finished(); private slots: void slotFinished(); void jobCancelled(); private: enum Type { HistoryAndBookmarks = 0, History = 1, Bookmarks = 2, Nothing = 4 }; void runJob(); void completeFromHistory(); void completeMostVisited(); QString createDomainCompletion(const QString &completion) const; qint64 m_timestamp; QString m_searchString; QString m_domainCompletion; QList m_items; QFutureWatcher* m_watcher; bool m_jobCancelled; }; #endif // LOCATIONCOMPLETERREFRESHJOB_H diff --git a/src/lib/navigation/completer/locationcompleterview.cpp b/src/lib/navigation/completer/locationcompleterview.cpp index 1ee14619..58522198 100644 --- a/src/lib/navigation/completer/locationcompleterview.cpp +++ b/src/lib/navigation/completer/locationcompleterview.cpp @@ -1,287 +1,287 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "locationcompleterview.h" #include "locationcompletermodel.h" #include "locationcompleterdelegate.h" #include #include #include LocationCompleterView::LocationCompleterView() : QListView(0) , m_ignoreNextMouseMove(false) { setAttribute(Qt::WA_ShowWithoutActivating); setAttribute(Qt::WA_X11NetWmWindowTypeCombo); if (qApp->platformName() == QL1S("xcb")) { setWindowFlags(Qt::Window | Qt::FramelessWindowHint | Qt::BypassWindowManagerHint); } else { setWindowFlags(Qt::Popup); } setUniformItemSizes(true); setEditTriggers(QAbstractItemView::NoEditTriggers); setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setSelectionBehavior(QAbstractItemView::SelectRows); setSelectionMode(QAbstractItemView::SingleSelection); setMouseTracking(true); qApp->installEventFilter(this); m_delegate = new LocationCompleterDelegate(this); setItemDelegate(m_delegate); } void LocationCompleterView::setOriginalText(const QString &originalText) { m_delegate->setOriginalText(originalText); } bool LocationCompleterView::eventFilter(QObject* object, QEvent* event) { // Event filter based on QCompleter::eventFilter from qcompleter.cpp if (object == this || !isVisible()) { return false; } switch (event->type()) { case QEvent::KeyPress: { QKeyEvent* keyEvent = static_cast(event); Qt::KeyboardModifiers modifiers = keyEvent->modifiers(); const QModelIndex idx = currentIndex(); const QModelIndex visitSearchIdx = model()->index(0, 0).data(LocationCompleterModel::VisitSearchItemRole).toBool() ? model()->index(0, 0) : QModelIndex(); if ((keyEvent->key() == Qt::Key_Up || keyEvent->key() == Qt::Key_Down) && currentIndex() != idx) { setCurrentIndex(idx); } switch (keyEvent->key()) { case Qt::Key_Return: case Qt::Key_Enter: if (!idx.isValid()) { break; } if (modifiers == Qt::NoModifier || modifiers == Qt::KeypadModifier) { emit indexActivated(idx); return true; } if (modifiers == Qt::ControlModifier) { emit indexCtrlActivated(idx); return true; } if (modifiers == Qt::ShiftModifier) { emit indexShiftActivated(idx); return true; } break; case Qt::Key_End: if (modifiers & Qt::ControlModifier) { setCurrentIndex(model()->index(model()->rowCount() - 1, 0)); return true; } else { close(); } break; case Qt::Key_Home: if (modifiers & Qt::ControlModifier) { setCurrentIndex(model()->index(0, 0)); scrollToTop(); return true; } else { close(); } break; case Qt::Key_Escape: close(); return true; case Qt::Key_F4: if (modifiers == Qt::AltModifier) { close(); return false; } break; case Qt::Key_Tab: case Qt::Key_Backtab: { if (keyEvent->modifiers() != Qt::NoModifier) { return false; } Qt::Key k = keyEvent->key() == Qt::Key_Tab ? Qt::Key_Down : Qt::Key_Up; QKeyEvent ev(QKeyEvent::KeyPress, k, Qt::NoModifier); QApplication::sendEvent(focusProxy(), &ev); return true; } case Qt::Key_Up: if (!idx.isValid() || idx == visitSearchIdx) { int rowCount = model()->rowCount(); QModelIndex lastIndex = model()->index(rowCount - 1, 0); setCurrentIndex(lastIndex); } else if (idx.row() == 0) { setCurrentIndex(QModelIndex()); } else { setCurrentIndex(model()->index(idx.row() - 1, 0)); } return true; case Qt::Key_Down: if (!idx.isValid()) { QModelIndex firstIndex = model()->index(0, 0); setCurrentIndex(firstIndex); } else if (idx != visitSearchIdx && idx.row() == model()->rowCount() - 1) { setCurrentIndex(visitSearchIdx); scrollToTop(); } else { setCurrentIndex(model()->index(idx.row() + 1, 0)); } return true; case Qt::Key_Delete: if (idx != visitSearchIdx && viewport()->rect().contains(visualRect(idx))) { emit indexDeleteRequested(idx); return true; } break; case Qt::Key_PageUp: if (keyEvent->modifiers() != Qt::NoModifier) { return false; } selectionModel()->setCurrentIndex(moveCursor(QAbstractItemView::MovePageUp, Qt::NoModifier), QItemSelectionModel::SelectCurrent); return true; case Qt::Key_PageDown: if (keyEvent->modifiers() != Qt::NoModifier) { return false; } selectionModel()->setCurrentIndex(moveCursor(QAbstractItemView::MovePageDown, Qt::NoModifier), QItemSelectionModel::SelectCurrent); return true; case Qt::Key_Shift: // don't switch if there is no hovered or selected index to not disturb typing if (idx != visitSearchIdx || underMouse()) { m_delegate->setShowSwitchToTab(false); viewport()->update(); return true; } break; } // switch (keyEvent->key()) if (focusProxy()) { (static_cast(focusProxy()))->event(keyEvent); } return true; } case QEvent::KeyRelease: { QKeyEvent* keyEvent = static_cast(event); switch (keyEvent->key()) { case Qt::Key_Shift: m_delegate->setShowSwitchToTab(true); viewport()->update(); return true; } break; } case QEvent::Show: // Don't hover item when showing completer and mouse is currently in rect m_ignoreNextMouseMove = true; break; case QEvent::Wheel: case QEvent::MouseButtonPress: if (!underMouse()) { close(); return false; } break; case QEvent::FocusOut: { QFocusEvent *focusEvent = static_cast(event); if (focusEvent->reason() != Qt::PopupFocusReason && focusEvent->reason() != Qt::MouseFocusReason) { close(); } break; } case QEvent::Move: case QEvent::Resize: { QWidget *w = qobject_cast(object); if (w && w->isWindow() && focusProxy() && w == focusProxy()->window()) { close(); } break; } default: break; } // switch (event->type()) return false; } void LocationCompleterView::close() { QListView::hide(); verticalScrollBar()->setValue(0); m_delegate->setShowSwitchToTab(true); emit closed(); } void LocationCompleterView::mouseReleaseEvent(QMouseEvent* event) { QModelIndex idx = indexAt(event->pos()); if (!idx.isValid()) { return; } Qt::MouseButton button = event->button(); Qt::KeyboardModifiers modifiers = event->modifiers(); if (button == Qt::LeftButton && modifiers == Qt::NoModifier) { emit indexActivated(idx); return; } if (button == Qt::MiddleButton || (button == Qt::LeftButton && modifiers == Qt::ControlModifier)) { emit indexCtrlActivated(idx); return; } if (button == Qt::LeftButton && modifiers == Qt::ShiftModifier) { emit indexShiftActivated(idx); return; } QListView::mouseReleaseEvent(event); } diff --git a/src/lib/navigation/completer/locationcompleterview.h b/src/lib/navigation/completer/locationcompleterview.h index 67dfa888..eb3f5385 100644 --- a/src/lib/navigation/completer/locationcompleterview.h +++ b/src/lib/navigation/completer/locationcompleterview.h @@ -1,59 +1,59 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef LOCATIONCOMPLETERVIEW_H #define LOCATIONCOMPLETERVIEW_H #include #include "qzcommon.h" class LocationCompleterDelegate; -class QUPZILLA_EXPORT LocationCompleterView : public QListView +class FALKON_EXPORT LocationCompleterView : public QListView { Q_OBJECT public: explicit LocationCompleterView(); QPersistentModelIndex hoveredIndex() const; void setOriginalText(const QString &originalText); bool eventFilter(QObject* object, QEvent* event); signals: void closed(); void indexActivated(const QModelIndex &index); void indexCtrlActivated(const QModelIndex &index); void indexShiftActivated(const QModelIndex &index); void indexDeleteRequested(const QModelIndex &index); public slots: void close(); protected: void mouseReleaseEvent(QMouseEvent* event); private: bool m_ignoreNextMouseMove; LocationCompleterDelegate* m_delegate; }; #endif // LOCATIONCOMPLETERVIEW_H diff --git a/src/lib/navigation/downicon.cpp b/src/lib/navigation/downicon.cpp index 1316a690..c951d14c 100644 --- a/src/lib/navigation/downicon.cpp +++ b/src/lib/navigation/downicon.cpp @@ -1,41 +1,41 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "downicon.h" #include DownIcon::DownIcon(QWidget* parent) : ClickableLabel(parent) { setObjectName("locationbar-down-icon"); setCursor(Qt::ArrowCursor); } void DownIcon::contextMenuEvent(QContextMenuEvent* ev) { // Prevent propagating to LocationBar ev->accept(); } void DownIcon::mousePressEvent(QMouseEvent* ev) { ClickableLabel::mousePressEvent(ev); // Prevent propagating to LocationBar ev->accept(); } diff --git a/src/lib/navigation/downicon.h b/src/lib/navigation/downicon.h index e1ba0cfd..435dd989 100644 --- a/src/lib/navigation/downicon.h +++ b/src/lib/navigation/downicon.h @@ -1,35 +1,35 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef DOWNICON_H #define DOWNICON_H #include "qzcommon.h" #include "clickablelabel.h" -class QUPZILLA_EXPORT DownIcon : public ClickableLabel +class FALKON_EXPORT DownIcon : public ClickableLabel { public: explicit DownIcon(QWidget* parent = 0); private: void contextMenuEvent(QContextMenuEvent* ev); void mousePressEvent(QMouseEvent* ev); }; #endif // DOWNICON_H diff --git a/src/lib/navigation/goicon.cpp b/src/lib/navigation/goicon.cpp index 181d9f8c..eaff70a7 100644 --- a/src/lib/navigation/goicon.cpp +++ b/src/lib/navigation/goicon.cpp @@ -1,43 +1,43 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "goicon.h" #include GoIcon::GoIcon(QWidget* parent) : ClickableLabel(parent) { setObjectName("locationbar-goicon"); setCursor(Qt::PointingHandCursor); setFocusProxy(parent); } void GoIcon::contextMenuEvent(QContextMenuEvent* ev) { // Prevent propagating to LocationBar ev->accept(); } void GoIcon::mousePressEvent(QMouseEvent* ev) { ClickableLabel::mousePressEvent(ev); // Prevent propagating to LocationBar ev->accept(); } diff --git a/src/lib/navigation/goicon.h b/src/lib/navigation/goicon.h index bd879bab..f4e7f261 100644 --- a/src/lib/navigation/goicon.h +++ b/src/lib/navigation/goicon.h @@ -1,35 +1,35 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef GOICON_H #define GOICON_H #include "qzcommon.h" #include "clickablelabel.h" -class QUPZILLA_EXPORT GoIcon : public ClickableLabel +class FALKON_EXPORT GoIcon : public ClickableLabel { public: explicit GoIcon(QWidget* parent = 0); private: void contextMenuEvent(QContextMenuEvent* ev); void mousePressEvent(QMouseEvent* ev); }; #endif // GOICON_H diff --git a/src/lib/navigation/locationbar.cpp b/src/lib/navigation/locationbar.cpp index 5f9f41d1..ae514e03 100644 --- a/src/lib/navigation/locationbar.cpp +++ b/src/lib/navigation/locationbar.cpp @@ -1,668 +1,668 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "locationbar.h" #include "browserwindow.h" #include "tabbedwebview.h" #include "mainapplication.h" #include "webpage.h" #include "tabwidget.h" #include "bookmarksicon.h" #include "bookmarks.h" #include "bookmarkitem.h" #include "bookmarkstoolbar.h" #include "siteicon.h" #include "goicon.h" #include "downicon.h" #include "qztools.h" #include "iconprovider.h" #include "qzsettings.h" #include "colors.h" #include "autofillicon.h" #include "completer/locationcompleter.h" #include #include #include #include #include #include LocationBar::LocationBar(BrowserWindow* window) : LineEdit(window) , m_window(window) , m_webView(0) , m_holdingAlt(false) , m_oldTextLength(0) , m_currentTextLength(0) , m_loadProgress(0) , m_progressVisible(false) { setObjectName("locationbar"); setDragEnabled(true); // Disable Oxygen QLineEdit transitions, it breaks with setText() && home() setProperty("_kde_no_animations", QVariant(true)); m_bookmarkIcon = new BookmarksIcon(this); m_goIcon = new GoIcon(this); m_siteIcon = new SiteIcon(m_window, this); m_autofillIcon = new AutoFillIcon(this); DownIcon* down = new DownIcon(this); addWidget(m_siteIcon, LineEdit::LeftSide); addWidget(m_autofillIcon, LineEdit::RightSide); addWidget(m_bookmarkIcon, LineEdit::RightSide); addWidget(m_goIcon, LineEdit::RightSide); addWidget(down, LineEdit::RightSide); m_completer = new LocationCompleter(this); m_completer->setMainWindow(m_window); m_completer->setLocationBar(this); connect(m_completer, SIGNAL(showCompletion(QString,bool)), this, SLOT(showCompletion(QString,bool))); connect(m_completer, SIGNAL(showDomainCompletion(QString)), this, SLOT(showDomainCompletion(QString))); connect(m_completer, SIGNAL(loadCompletion()), this, SLOT(requestLoadUrl())); connect(m_completer, SIGNAL(clearCompletion()), this, SLOT(clearCompletion())); m_domainCompleterModel = new QStringListModel(this); QCompleter* domainCompleter = new QCompleter(this); domainCompleter->setCompletionMode(QCompleter::InlineCompletion); domainCompleter->setModel(m_domainCompleterModel); setCompleter(domainCompleter); m_progressTimer = new QTimer(this); m_progressTimer->setInterval(700); m_progressTimer->setSingleShot(true); connect(m_progressTimer, &QTimer::timeout, this, &LocationBar::hideProgress); editAction(PasteAndGo)->setText(tr("Paste And &Go")); editAction(PasteAndGo)->setIcon(QIcon::fromTheme(QSL("edit-paste"))); connect(editAction(PasteAndGo), SIGNAL(triggered()), this, SLOT(pasteAndGo())); connect(this, SIGNAL(textEdited(QString)), this, SLOT(textEdited(QString))); connect(m_goIcon, SIGNAL(clicked(QPoint)), this, SLOT(requestLoadUrl())); connect(down, SIGNAL(clicked(QPoint)), m_completer, SLOT(showMostVisited())); connect(mApp->searchEnginesManager(), SIGNAL(activeEngineChanged()), this, SLOT(updatePlaceHolderText())); connect(mApp->searchEnginesManager(), SIGNAL(defaultEngineChanged()), this, SLOT(updatePlaceHolderText())); connect(mApp, SIGNAL(settingsReloaded()), SLOT(loadSettings())); loadSettings(); updateSiteIcon(); // Hide icons by default m_goIcon->setVisible(qzSettings->alwaysShowGoIcon); m_autofillIcon->hide(); QTimer::singleShot(0, this, SLOT(updatePlaceHolderText())); } TabbedWebView* LocationBar::webView() const { return m_webView; } void LocationBar::setWebView(TabbedWebView* view) { m_webView = view; m_bookmarkIcon->setWebView(m_webView); m_siteIcon->setWebView(m_webView); m_autofillIcon->setWebView(m_webView); connect(m_webView, SIGNAL(loadStarted()), SLOT(loadStarted())); connect(m_webView, SIGNAL(loadProgress(int)), SLOT(loadProgress(int))); connect(m_webView, SIGNAL(loadFinished(bool)), SLOT(loadFinished())); connect(m_webView, SIGNAL(urlChanged(QUrl)), this, SLOT(showUrl(QUrl))); connect(m_webView, SIGNAL(privacyChanged(bool)), this, SLOT(setPrivacyState(bool))); connect(m_webView, &TabbedWebView::iconChanged, this, &LocationBar::updateSiteIcon); } void LocationBar::setText(const QString &text) { m_oldTextLength = text.length(); m_currentTextLength = m_oldTextLength; LineEdit::setText(text); refreshTextFormat(); } void LocationBar::updatePlaceHolderText() { if (qzSettings->searchFromAddressBar) { setPlaceholderText(tr("Enter address or search with %1").arg(searchEngine().name)); } else setPlaceholderText(tr("Enter address")); } void LocationBar::showCompletion(const QString &completion, bool completeDomain) { LineEdit::setText(completion); // Move cursor to the end end(false); if (completeDomain) { completer()->complete(); } } void LocationBar::clearCompletion() { m_webView->setFocus(); showUrl(m_webView->url()); } void LocationBar::showDomainCompletion(const QString &completion) { m_domainCompleterModel->setStringList(QStringList() << completion); // We need to manually force the completion because model is updated asynchronously // But only force completion when the user actually added new text if (m_oldTextLength < m_currentTextLength) completer()->complete(); } LoadRequest LocationBar::createLoadRequest() const { LoadRequest req; const QString &t = text().trimmed(); // Check for Search Engine shortcut int firstSpacePos = t.indexOf(QLatin1Char(' ')); if (firstSpacePos != -1) { const QString shortcut = t.left(firstSpacePos); const QString searchedString = t.mid(firstSpacePos).trimmed(); SearchEngine en = mApp->searchEnginesManager()->engineForShortcut(shortcut); if (!en.name.isEmpty()) { req = mApp->searchEnginesManager()->searchResult(en, searchedString); } } // Check for Bookmark keyword QList items = mApp->bookmarks()->searchKeyword(t); if (!items.isEmpty()) { BookmarkItem* item = items.at(0); item->updateVisitCount(); req.setUrl(item->url()); } if (req.isEmpty()) { // One word needs special handling, because QUrl::fromUserInput // would convert it to QUrl("http://WORD") if (!t.contains(QL1C(' ')) && !t.contains(QL1C('.'))) { req.setUrl(QUrl(t)); } else { const QUrl &guessed = QUrl::fromUserInput(t); if (!guessed.isEmpty()) req.setUrl(guessed); else req.setUrl(QUrl::fromEncoded(t.toUtf8())); } } return req; } QString LocationBar::convertUrlToText(const QUrl &url) { // It was most probably entered by user, so don't urlencode it if (url.scheme().isEmpty()) { return QUrl::fromPercentEncoding(url.toEncoded()); } QString stringUrl = QzTools::urlEncodeQueryString(url); - if (stringUrl == QL1S("qupzilla:speeddial") || stringUrl == QL1S("about:blank")) { + if (stringUrl == QL1S("falkon:speeddial") || stringUrl == QL1S("about:blank")) { stringUrl.clear(); } return stringUrl; } SearchEnginesManager::Engine LocationBar::searchEngine() { if (!qzSettings->searchFromAddressBar) { return SearchEnginesManager::Engine(); } else if (qzSettings->searchWithDefaultEngine) { return mApp->searchEnginesManager()->defaultEngine(); } else { return mApp->searchEnginesManager()->activeEngine(); } } void LocationBar::refreshTextFormat() { if (!m_webView) { return; } TextFormat textFormat; const QString hostName = m_webView->url().isEmpty() ? QUrl(text()).host() : m_webView->url().host(); if (!hostName.isEmpty()) { const int hostPos = text().indexOf(hostName); if (hostPos > 0) { QTextCharFormat format; format.setForeground(Colors::mid(palette().color(QPalette::Base), palette().color(QPalette::Text), 1, 1)); QTextLayout::FormatRange schemePart; schemePart.start = 0; schemePart.length = hostPos; schemePart.format = format; QTextLayout::FormatRange hostPart; hostPart.start = hostPos; hostPart.length = hostName.size(); QTextLayout::FormatRange remainingPart; remainingPart.start = hostPos + hostName.size(); remainingPart.length = text().size() - remainingPart.start; remainingPart.format = format; textFormat.append(schemePart); textFormat.append(hostPart); textFormat.append(remainingPart); } } setTextFormat(textFormat); } void LocationBar::requestLoadUrl() { const LoadRequest req = createLoadRequest(); const QString urlString = convertUrlToText(req.url()); m_completer->closePopup(); m_webView->setFocus(); if (urlString != text()) { setText(urlString); } m_webView->userLoadAction(req); } void LocationBar::textEdited(const QString &text) { m_oldTextLength = m_currentTextLength; m_currentTextLength = text.length(); if (!text.isEmpty()) { m_completer->complete(text); } else { m_completer->closePopup(); } setGoIconVisible(true); } void LocationBar::setGoIconVisible(bool state) { if (state) { m_bookmarkIcon->hide(); m_goIcon->show(); } else { m_bookmarkIcon->show(); if (!qzSettings->alwaysShowGoIcon) { m_goIcon->hide(); } } updateTextMargins(); } void LocationBar::showUrl(const QUrl &url) { if (hasFocus() || url.isEmpty()) { return; } const QString stringUrl = convertUrlToText(url); if (text() == stringUrl) { home(false); refreshTextFormat(); return; } // Set converted url as text setText(stringUrl); // Move cursor to the start home(false); m_bookmarkIcon->checkBookmark(url); } void LocationBar::updateSiteIcon() { QIcon icon = m_webView ? m_webView->icon() : IconProvider::emptyWebIcon(); if (m_webView && m_webView->url().scheme() == QL1S("https")) icon = QIcon::fromTheme(QSL("document-encrypted"), icon); m_siteIcon->setIcon(QIcon(icon.pixmap(16))); } void LocationBar::setPrivacyState(bool state) { m_siteIcon->setProperty("secured", QVariant(state)); m_siteIcon->style()->unpolish(m_siteIcon); m_siteIcon->style()->polish(m_siteIcon); setProperty("secured", QVariant(state)); style()->unpolish(this); style()->polish(this); } void LocationBar::pasteAndGo() { clear(); paste(); requestLoadUrl(); } void LocationBar::contextMenuEvent(QContextMenuEvent* event) { QMenu* menu = createContextMenu(); menu->setAttribute(Qt::WA_DeleteOnClose); // Prevent choosing first option with double rightclick QPoint pos = event->globalPos(); pos.setY(pos.y() + 1); menu->popup(pos); } void LocationBar::showEvent(QShowEvent* event) { LineEdit::showEvent(event); refreshTextFormat(); } void LocationBar::focusInEvent(QFocusEvent* event) { if (m_webView) { const QString stringUrl = convertUrlToText(m_webView->url()); // Text has been edited, let's show go button if (stringUrl != text()) { setGoIconVisible(true); } } clearTextFormat(); LineEdit::focusInEvent(event); if (Settings().value("Browser-View-Settings/instantBookmarksToolbar").toBool()) { m_window->bookmarksToolbar()->show(); } } void LocationBar::focusOutEvent(QFocusEvent* event) { // Context menu or completer popup were opened // Let's block focusOutEvent to trick QLineEdit and paint cursor properly if (event->reason() == Qt::PopupFocusReason) { return; } LineEdit::focusOutEvent(event); setGoIconVisible(false); if (text().trimmed().isEmpty()) { clear(); } refreshTextFormat(); if (Settings().value("Browser-View-Settings/instantBookmarksToolbar").toBool()) { m_window->bookmarksToolbar()->hide(); } } void LocationBar::dropEvent(QDropEvent* event) { if (event->mimeData()->hasUrls()) { const QUrl dropUrl = event->mimeData()->urls().at(0); if (WebView::isUrlValid(dropUrl)) { setText(dropUrl.toString()); m_webView->setFocus(); m_webView->userLoadAction(dropUrl); QFocusEvent event(QFocusEvent::FocusOut); LineEdit::focusOutEvent(&event); return; } } else if (event->mimeData()->hasText()) { const QString dropText = event->mimeData()->text().trimmed(); const QUrl dropUrl = QUrl(dropText); if (WebView::isUrlValid(dropUrl)) { setText(dropUrl.toString()); m_webView->setFocus(); m_webView->userLoadAction(dropUrl); QFocusEvent event(QFocusEvent::FocusOut); LineEdit::focusOutEvent(&event); return; } else { setText(dropText); setFocus(); return; } } LineEdit::dropEvent(event); } void LocationBar::keyPressEvent(QKeyEvent* event) { switch (event->key()) { case Qt::Key_V: if (event->modifiers() == (Qt::ControlModifier | Qt::ShiftModifier)) { pasteAndGo(); event->accept(); return; } break; case Qt::Key_Down: m_completer->complete(text()); break; case Qt::Key_Left: m_completer->closePopup(); break; case Qt::Key_Escape: m_webView->setFocus(); showUrl(m_webView->url()); event->accept(); break; case Qt::Key_Alt: m_holdingAlt = true; break; case Qt::Key_Return: case Qt::Key_Enter: switch (event->modifiers()) { case Qt::ControlModifier: if (!text().endsWith(QL1S(".com"))) setText(text().append(QL1S(".com"))); requestLoadUrl(); m_holdingAlt = false; break; case Qt::AltModifier: m_completer->closePopup(); m_window->tabWidget()->addView(createLoadRequest()); m_holdingAlt = false; break; default: requestLoadUrl(); m_holdingAlt = false; } break; case Qt::Key_0: case Qt::Key_1: case Qt::Key_2: case Qt::Key_3: case Qt::Key_4: case Qt::Key_5: case Qt::Key_6: case Qt::Key_7: case Qt::Key_8: case Qt::Key_9: if (event->modifiers() & Qt::AltModifier || event->modifiers() & Qt::ControlModifier) { event->ignore(); m_holdingAlt = false; return; } break; default: m_holdingAlt = false; } LineEdit::keyPressEvent(event); } void LocationBar::loadStarted() { m_progressVisible = true; m_progressTimer->stop(); m_autofillIcon->hide(); m_siteIcon->setIcon(IconProvider::emptyWebIcon()); } void LocationBar::loadProgress(int progress) { if (qzSettings->showLoadingProgress) { m_loadProgress = progress; update(); } } void LocationBar::loadFinished() { if (qzSettings->showLoadingProgress) { m_progressTimer->start(); } WebPage* page = qobject_cast(m_webView->page()); if (page && page->hasMultipleUsernames()) { m_autofillIcon->setFormData(page->autoFillData()); m_autofillIcon->show(); } updateSiteIcon(); } void LocationBar::loadSettings() { Settings settings; settings.beginGroup("AddressBar"); m_progressStyle = static_cast(settings.value("ProgressStyle", 0).toInt()); bool customColor = settings.value("UseCustomProgressColor", false).toBool(); m_progressColor = customColor ? settings.value("CustomProgressColor", palette().color(QPalette::Highlight)).value() : QColor(); settings.endGroup(); } void LocationBar::hideProgress() { if (qzSettings->showLoadingProgress) { m_progressVisible = false; update(); } } void LocationBar::paintEvent(QPaintEvent* event) { LineEdit::paintEvent(event); // Show loading progress if (qzSettings->showLoadingProgress && m_progressVisible) { QStyleOptionFrame option; initStyleOption(&option); int lm, tm, rm, bm; getTextMargins(&lm, &tm, &rm, &bm); QRect contentsRect = style()->subElementRect(QStyle::SE_LineEditContents, &option, this); contentsRect.adjust(lm, tm, -rm, -bm); QColor bg = m_progressColor; if (!bg.isValid() || bg.alpha() == 0) { bg = Colors::mid(palette().color(QPalette::Base), palette().color(QPalette::Text), m_progressStyle > 0 ? 4 : 8, 1); } QPainter p(this); p.setBrush(QBrush(bg)); // We are painting over text, make sure the text stays visible p.setOpacity(0.5); QPen outlinePen(bg.darker(110), 0.8); p.setPen(outlinePen); switch (m_progressStyle) { case ProgressFilled: { QRect bar = contentsRect.adjusted(0, 1, 0, -1); bar.setWidth(bar.width() * m_loadProgress / 100); const int roundness = bar.height() / 4.0; p.drawRoundedRect(bar, roundness, roundness); break; } case ProgressBottom: { outlinePen.setWidthF(0.3); outlinePen.setColor(outlinePen.color().darker(130)); p.setPen(outlinePen); QRect bar(contentsRect.x(), contentsRect.bottom() - 3, contentsRect.width() * m_loadProgress / 100.0, 3); p.drawRoundedRect(bar, 1, 1); break; } case ProgressTop: { outlinePen.setWidthF(0.3); outlinePen.setColor(outlinePen.color().darker(130)); p.setPen(outlinePen); QRect bar(contentsRect.x(), contentsRect.top() + 1, contentsRect.width() * m_loadProgress / 100.0, 3); p.drawRoundedRect(bar, 1, 1); break; } default: break; } } } diff --git a/src/lib/navigation/locationbar.h b/src/lib/navigation/locationbar.h index 0260bce8..e09b2e90 100644 --- a/src/lib/navigation/locationbar.h +++ b/src/lib/navigation/locationbar.h @@ -1,116 +1,116 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef LOCATIONBAR_H #define LOCATIONBAR_H #include "qzcommon.h" #include "lineedit.h" #include "searchenginesmanager.h" class QStringListModel; class BrowserWindow; class LocationCompleter; class ClickableLabel; class TabbedWebView; class BookmarksIcon; class SiteIcon; class GoIcon; class AutoFillIcon; class LoadRequest; -class QUPZILLA_EXPORT LocationBar : public LineEdit +class FALKON_EXPORT LocationBar : public LineEdit { Q_OBJECT public: explicit LocationBar(BrowserWindow* window); TabbedWebView* webView() const; void setWebView(TabbedWebView* view); static QString convertUrlToText(const QUrl &url); static SearchEnginesManager::Engine searchEngine(); public slots: void setText(const QString &text); void showUrl(const QUrl &url); private slots: void textEdited(const QString &text); void requestLoadUrl(); void pasteAndGo(); void updateSiteIcon(); void updatePlaceHolderText(); void setPrivacyState(bool state); void setGoIconVisible(bool state); void showCompletion(const QString &completion, bool completeDomain); void showDomainCompletion(const QString &completion); void clearCompletion(); void loadStarted(); void loadProgress(int progress); void loadFinished(); void hideProgress(); void loadSettings(); private: enum ProgressStyle { ProgressFilled, ProgressBottom, ProgressTop }; void contextMenuEvent(QContextMenuEvent* event); void showEvent(QShowEvent* event); void focusInEvent(QFocusEvent* event); void focusOutEvent(QFocusEvent* event); void keyPressEvent(QKeyEvent* event); void dropEvent(QDropEvent* event); void paintEvent(QPaintEvent* event); LoadRequest createLoadRequest() const; void refreshTextFormat(); LocationCompleter* m_completer; QStringListModel* m_domainCompleterModel; BookmarksIcon* m_bookmarkIcon; GoIcon* m_goIcon; SiteIcon* m_siteIcon; AutoFillIcon* m_autofillIcon; BrowserWindow* m_window; TabbedWebView* m_webView; bool m_holdingAlt; int m_oldTextLength; int m_currentTextLength; int m_loadProgress; bool m_progressVisible; ProgressStyle m_progressStyle; QColor m_progressColor; QTimer *m_progressTimer; }; #endif // LOCATIONBAR_H diff --git a/src/lib/navigation/locationbarpopup.cpp b/src/lib/navigation/locationbarpopup.cpp index a6bdf2b9..a248f269 100644 --- a/src/lib/navigation/locationbarpopup.cpp +++ b/src/lib/navigation/locationbarpopup.cpp @@ -1,64 +1,64 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2012-2014 Franz Fellner * Copyright (C) 2012-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "locationbarpopup.h" #include LocationBarPopup::LocationBarPopup(QWidget* parent) : QFrame(parent, Qt::Popup) , m_alignment(Qt::AlignRight) { setAttribute(Qt::WA_DeleteOnClose); setFrameStyle(QFrame::StyledPanel | QFrame::Raised); setLineWidth(1); setMidLineWidth(2); } void LocationBarPopup::showAt(QWidget* parent) { if (!parent || !parent->parentWidget()) return; parent = parent->parentWidget(); // Calculate sizes before showing layout()->invalidate(); layout()->activate(); QPoint p = parent->mapToGlobal(QPoint(0, 0)); if (m_alignment == Qt::AlignRight) { p.setX(p.x() + parent->width() - width()); } p.setY(p.y() + parent->height()); move(p); QFrame::show(); } void LocationBarPopup::setPopupAlignment(Qt::Alignment alignment) { m_alignment = alignment; } Qt::Alignment LocationBarPopup::popupAlignment() const { return m_alignment; } diff --git a/src/lib/navigation/locationbarpopup.h b/src/lib/navigation/locationbarpopup.h index 16537edc..2f9ad039 100644 --- a/src/lib/navigation/locationbarpopup.h +++ b/src/lib/navigation/locationbarpopup.h @@ -1,40 +1,40 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 Franz Fellner * David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef LOCATIONBARPOPUP_H #define LOCATIONBARPOPUP_H #include #include "qzcommon.h" -class QUPZILLA_EXPORT LocationBarPopup : public QFrame +class FALKON_EXPORT LocationBarPopup : public QFrame { public: explicit LocationBarPopup(QWidget* parent); void showAt(QWidget* parent); void setPopupAlignment(Qt::Alignment alignment); Qt::Alignment popupAlignment() const; private: Qt::Alignment m_alignment; }; #endif // LOCATIONBARPOPUP_H diff --git a/src/lib/navigation/navigationbar.cpp b/src/lib/navigation/navigationbar.cpp index b88b017e..2357ff1f 100644 --- a/src/lib/navigation/navigationbar.cpp +++ b/src/lib/navigation/navigationbar.cpp @@ -1,409 +1,409 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2016 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "navigationbar.h" #include "toolbutton.h" #include "browserwindow.h" #include "mainapplication.h" #include "iconprovider.h" #include "websearchbar.h" #include "reloadstopbutton.h" #include "enhancedmenu.h" #include "tabwidget.h" #include "tabbedwebview.h" #include "webpage.h" #include "qzsettings.h" #include "qztools.h" #include #include #include #include #include #include #include NavigationBar::NavigationBar(BrowserWindow* window) : QWidget(window) , m_window(window) { setObjectName(QSL("navigationbar")); m_layout = new QHBoxLayout(this); m_layout->setMargin(style()->pixelMetric(QStyle::PM_ToolBarItemMargin, 0, this)); m_layout->setSpacing(style()->pixelMetric(QStyle::PM_ToolBarItemSpacing, 0, this)); setLayout(m_layout); m_buttonBack = new ToolButton(this); m_buttonBack->setObjectName("navigation-button-back"); m_buttonBack->setToolTip(tr("Back")); m_buttonBack->setToolButtonStyle(Qt::ToolButtonIconOnly); m_buttonBack->setToolbarButtonLook(true); m_buttonBack->setAutoRaise(true); m_buttonBack->setEnabled(false); m_buttonBack->setFocusPolicy(Qt::NoFocus); m_buttonForward = new ToolButton(this); m_buttonForward->setObjectName("navigation-button-next"); m_buttonForward->setToolTip(tr("Forward")); m_buttonForward->setToolButtonStyle(Qt::ToolButtonIconOnly); m_buttonForward->setToolbarButtonLook(true); m_buttonForward->setAutoRaise(true); m_buttonForward->setEnabled(false); m_buttonForward->setFocusPolicy(Qt::NoFocus); QHBoxLayout* backNextLayout = new QHBoxLayout(); backNextLayout->setContentsMargins(0, 0, 0, 0); backNextLayout->setSpacing(0); backNextLayout->addWidget(m_buttonBack); backNextLayout->addWidget(m_buttonForward); m_reloadStop = new ReloadStopButton(this); m_buttonHome = new ToolButton(this); m_buttonHome->setObjectName("navigation-button-home"); m_buttonHome->setToolTip(tr("Home")); m_buttonHome->setToolButtonStyle(Qt::ToolButtonIconOnly); m_buttonHome->setToolbarButtonLook(true); m_buttonHome->setAutoRaise(true); m_buttonHome->setFocusPolicy(Qt::NoFocus); m_buttonAddTab = new ToolButton(this); m_buttonAddTab->setObjectName("navigation-button-addtab"); m_buttonAddTab->setToolTip(tr("New Tab")); m_buttonAddTab->setToolButtonStyle(Qt::ToolButtonIconOnly); m_buttonAddTab->setToolbarButtonLook(true); m_buttonAddTab->setAutoRaise(true); m_buttonAddTab->setFocusPolicy(Qt::NoFocus); m_menuBack = new Menu(this); m_menuBack->setCloseOnMiddleClick(true); m_buttonBack->setMenu(m_menuBack); connect(m_buttonBack, SIGNAL(aboutToShowMenu()), this, SLOT(aboutToShowHistoryBackMenu())); m_menuForward = new Menu(this); m_menuForward->setCloseOnMiddleClick(true); m_buttonForward->setMenu(m_menuForward); connect(m_buttonForward, SIGNAL(aboutToShowMenu()), this, SLOT(aboutToShowHistoryNextMenu())); m_supMenu = new ToolButton(this); m_supMenu->setObjectName("navigation-button-supermenu"); m_supMenu->setPopupMode(QToolButton::InstantPopup); m_supMenu->setToolbarButtonLook(true); m_supMenu->setToolTip(tr("Main Menu")); m_supMenu->setAutoRaise(true); m_supMenu->setFocusPolicy(Qt::NoFocus); m_supMenu->setMenu(m_window->superMenu()); m_supMenu->setShowMenuInside(true); m_searchLine = new WebSearchBar(m_window); m_navigationSplitter = new QSplitter(this); m_navigationSplitter->addWidget(m_window->tabWidget()->locationBars()); m_navigationSplitter->addWidget(m_searchLine); m_navigationSplitter->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum); m_navigationSplitter->setCollapsible(0, false); m_exitFullscreen = new ToolButton(this); m_exitFullscreen->setObjectName("navigation-button-exitfullscreen"); m_exitFullscreen->setToolTip(tr("Exit Fullscreen")); m_exitFullscreen->setToolButtonStyle(Qt::ToolButtonIconOnly); m_exitFullscreen->setToolbarButtonLook(true); m_exitFullscreen->setFocusPolicy(Qt::NoFocus); m_exitFullscreen->setAutoRaise(true); m_exitFullscreen->setVisible(false); m_layout->addLayout(backNextLayout); m_layout->addWidget(m_reloadStop); m_layout->addWidget(m_buttonHome); m_layout->addWidget(m_buttonAddTab); m_layout->addWidget(m_navigationSplitter); m_layout->addWidget(m_exitFullscreen); m_layout->addWidget(m_supMenu); setContextMenuPolicy(Qt::CustomContextMenu); connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextMenuRequested(QPoint))); connect(m_buttonBack, SIGNAL(clicked()), this, SLOT(goBack())); connect(m_buttonBack, SIGNAL(middleMouseClicked()), this, SLOT(goBackInNewTab())); connect(m_buttonBack, SIGNAL(controlClicked()), this, SLOT(goBackInNewTab())); connect(m_buttonForward, SIGNAL(clicked()), this, SLOT(goForward())); connect(m_buttonForward, SIGNAL(middleMouseClicked()), this, SLOT(goForwardInNewTab())); connect(m_buttonForward, SIGNAL(controlClicked()), this, SLOT(goForwardInNewTab())); connect(m_reloadStop, SIGNAL(stopClicked()), this, SLOT(stop())); connect(m_reloadStop, SIGNAL(reloadClicked()), this, SLOT(reload())); connect(m_buttonHome, SIGNAL(clicked()), m_window, SLOT(goHome())); connect(m_buttonHome, SIGNAL(middleMouseClicked()), m_window, SLOT(goHomeInNewTab())); connect(m_buttonHome, SIGNAL(controlClicked()), m_window, SLOT(goHomeInNewTab())); connect(m_buttonAddTab, SIGNAL(clicked()), m_window, SLOT(addTab())); connect(m_buttonAddTab, SIGNAL(middleMouseClicked()), m_window->tabWidget(), SLOT(addTabFromClipboard())); connect(m_exitFullscreen, SIGNAL(clicked(bool)), m_window, SLOT(toggleFullScreen())); } void NavigationBar::setSplitterSizes(int locationBar, int websearchBar) { QList sizes; if (locationBar == 0) { int splitterWidth = m_navigationSplitter->width(); sizes << (int)((double)splitterWidth * .80) << (int)((double)splitterWidth * .20); } else { sizes << locationBar << websearchBar; } m_navigationSplitter->setSizes(sizes); } void NavigationBar::showReloadButton() { m_reloadStop->showReloadButton(); } void NavigationBar::showStopButton() { m_reloadStop->showStopButton(); } void NavigationBar::setSuperMenuVisible(bool visible) { m_supMenu->setVisible(visible); } int NavigationBar::layoutMargin() const { return m_layout->margin(); } void NavigationBar::setLayoutMargin(int margin) { m_layout->setMargin(margin); } int NavigationBar::layoutSpacing() const { return m_layout->spacing(); } void NavigationBar::setLayoutSpacing(int spacing) { m_layout->setSpacing(spacing); } void NavigationBar::aboutToShowHistoryBackMenu() { if (!m_menuBack || !m_window->weView()) { return; } m_menuBack->clear(); QWebEngineHistory* history = m_window->weView()->history(); int curindex = history->currentItemIndex(); int count = 0; for (int i = curindex - 1; i >= 0; i--) { QWebEngineHistoryItem item = history->itemAt(i); if (item.isValid()) { QString title = titleForUrl(item.title(), item.url()); const QIcon icon = iconForPage(item.url(), IconProvider::standardIcon(QStyle::SP_ArrowBack)); Action* act = new Action(icon, title); act->setData(i); connect(act, SIGNAL(triggered()), this, SLOT(loadHistoryIndex())); connect(act, SIGNAL(ctrlTriggered()), this, SLOT(loadHistoryIndexInNewTab())); m_menuBack->addAction(act); } count++; if (count == 20) { break; } } m_menuBack->addSeparator(); m_menuBack->addAction(tr("Clear history"), this, SLOT(clearHistory())); } void NavigationBar::aboutToShowHistoryNextMenu() { if (!m_menuForward || !m_window->weView()) { return; } m_menuForward->clear(); QWebEngineHistory* history = m_window->weView()->history(); int curindex = history->currentItemIndex(); int count = 0; for (int i = curindex + 1; i < history->count(); i++) { QWebEngineHistoryItem item = history->itemAt(i); if (item.isValid()) { QString title = titleForUrl(item.title(), item.url()); const QIcon icon = iconForPage(item.url(), IconProvider::standardIcon(QStyle::SP_ArrowForward)); Action* act = new Action(icon, title); act->setData(i); connect(act, SIGNAL(triggered()), this, SLOT(loadHistoryIndex())); connect(act, SIGNAL(ctrlTriggered()), this, SLOT(loadHistoryIndexInNewTab())); m_menuForward->addAction(act); } count++; if (count == 20) { break; } } m_menuForward->addSeparator(); m_menuForward->addAction(tr("Clear history"), this, SLOT(clearHistory())); } void NavigationBar::clearHistory() { QWebEngineHistory* history = m_window->weView()->page()->history(); history->clear(); refreshHistory(); } void NavigationBar::contextMenuRequested(const QPoint &pos) { QMenu menu; m_window->createToolbarsMenu(&menu); menu.exec(mapToGlobal(pos)); } void NavigationBar::loadHistoryIndex() { QWebEngineHistory* history = m_window->weView()->page()->history(); if (QAction* action = qobject_cast(sender())) { loadHistoryItem(history->itemAt(action->data().toInt())); } } void NavigationBar::loadHistoryIndexInNewTab(int index) { if (QAction* action = qobject_cast(sender())) { index = action->data().toInt(); } if (index == -1) { return; } QWebEngineHistory* history = m_window->weView()->page()->history(); loadHistoryItemInNewTab(history->itemAt(index)); } void NavigationBar::refreshHistory() { if (mApp->isClosing() || !m_window->weView()) { return; } QWebEngineHistory* history = m_window->weView()->page()->history(); m_buttonBack->setEnabled(history->canGoBack()); m_buttonForward->setEnabled(history->canGoForward()); } void NavigationBar::stop() { m_window->action(QSL("View/Stop"))->trigger(); } void NavigationBar::reload() { m_window->action(QSL("View/Reload"))->trigger(); } void NavigationBar::goBack() { QWebEngineHistory* history = m_window->weView()->page()->history(); history->back(); } void NavigationBar::goBackInNewTab() { QWebEngineHistory* history = m_window->weView()->page()->history(); if (!history->canGoBack()) { return; } loadHistoryItemInNewTab(history->backItem()); } void NavigationBar::goForward() { QWebEngineHistory* history = m_window->weView()->page()->history(); history->forward(); } void NavigationBar::goForwardInNewTab() { QWebEngineHistory* history = m_window->weView()->page()->history(); if (!history->canGoForward()) { return; } loadHistoryItemInNewTab(history->forwardItem()); } QString NavigationBar::titleForUrl(QString title, const QUrl &url) { if (title.isEmpty()) { title = url.toString(QUrl::RemoveFragment); } if (title.isEmpty()) { return tr("Empty Page"); } return QzTools::truncatedText(title, 40); } QIcon NavigationBar::iconForPage(const QUrl &url, const QIcon &sIcon) { QIcon icon; - icon.addPixmap(url.scheme() == QL1S("qupzilla") ? QIcon(QSL(":icons/qupzilla.png")).pixmap(16) : IconProvider::iconForUrl(url).pixmap(16)); + icon.addPixmap(url.scheme() == QL1S("falkon") ? QIcon(QSL(":icons/qupzilla.png")).pixmap(16) : IconProvider::iconForUrl(url).pixmap(16)); icon.addPixmap(sIcon.pixmap(16), QIcon::Active); return icon; } void NavigationBar::loadHistoryItem(const QWebEngineHistoryItem &item) { m_window->weView()->page()->history()->goToItem(item); refreshHistory(); } void NavigationBar::loadHistoryItemInNewTab(const QWebEngineHistoryItem &item) { TabWidget* tabWidget = m_window->tabWidget(); int tabIndex = tabWidget->duplicateTab(tabWidget->currentIndex()); QWebEngineHistory* history = m_window->weView(tabIndex)->page()->history(); history->goToItem(item); if (qzSettings->newTabPosition == Qz::NT_SelectedTab) { tabWidget->setCurrentIndex(tabIndex); } } diff --git a/src/lib/navigation/navigationbar.h b/src/lib/navigation/navigationbar.h index ec6b4f3a..031da23d 100644 --- a/src/lib/navigation/navigationbar.h +++ b/src/lib/navigation/navigationbar.h @@ -1,114 +1,114 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef NAVIGATIONBAR_H #define NAVIGATIONBAR_H #include #include "qzcommon.h" class QHBoxLayout; class QSplitter; class QWebEngineHistoryItem; class ToolButton; class WebSearchBar; class BrowserWindow; class ReloadStopButton; class Menu; class QUrl; -class QUPZILLA_EXPORT NavigationBar : public QWidget +class FALKON_EXPORT NavigationBar : public QWidget { Q_OBJECT public: explicit NavigationBar(BrowserWindow* window); Q_PROPERTY(int layoutMargin READ layoutMargin WRITE setLayoutMargin) Q_PROPERTY(int layoutSpacing READ layoutSpacing WRITE setLayoutSpacing) void setSplitterSizes(int locationBar, int websearchBar); void showReloadButton(); void showStopButton(); ToolButton* buttonBack() { return m_buttonBack; } ToolButton* buttonForward() { return m_buttonForward; } ToolButton* buttonHome() { return m_buttonHome; } ToolButton* buttonAddTab() { return m_buttonAddTab; } ToolButton* buttonExitFullscreen() { return m_exitFullscreen; } ReloadStopButton* buttonReloadStop() { return m_reloadStop; } WebSearchBar* webSearchBar() { return m_searchLine; } QSplitter* splitter() { return m_navigationSplitter; } void setSuperMenuVisible(bool visible); int layoutMargin() const; void setLayoutMargin(int margin); int layoutSpacing() const; void setLayoutSpacing(int spacing); signals: public slots: void refreshHistory(); void stop(); void reload(); void goBack(); void goBackInNewTab(); void goForward(); void goForwardInNewTab(); private slots: void aboutToShowHistoryNextMenu(); void aboutToShowHistoryBackMenu(); void loadHistoryIndex(); void loadHistoryIndexInNewTab(int index = -1); void clearHistory(); void contextMenuRequested(const QPoint &pos); private: QString titleForUrl(QString title, const QUrl &url); QIcon iconForPage(const QUrl &url, const QIcon &sIcon); void loadHistoryItem(const QWebEngineHistoryItem &item); void loadHistoryItemInNewTab(const QWebEngineHistoryItem &item); BrowserWindow* m_window; QHBoxLayout* m_layout; QSplitter* m_navigationSplitter; ToolButton* m_buttonBack; ToolButton* m_buttonForward; ToolButton* m_buttonHome; ToolButton* m_buttonAddTab; ToolButton* m_supMenu; ToolButton* m_exitFullscreen; ReloadStopButton* m_reloadStop; Menu* m_menuBack; Menu* m_menuForward; WebSearchBar* m_searchLine; }; #endif // NAVIGATIONBAR_H diff --git a/src/lib/navigation/navigationcontainer.cpp b/src/lib/navigation/navigationcontainer.cpp index 71061a25..d56967a6 100644 --- a/src/lib/navigation/navigationcontainer.cpp +++ b/src/lib/navigation/navigationcontainer.cpp @@ -1,74 +1,74 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2013-2016 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "navigationcontainer.h" #include "qzsettings.h" #include "tabbar.h" #include #include NavigationContainer::NavigationContainer(QWidget* parent) : QWidget(parent) , m_tabBar(0) { m_layout = new QVBoxLayout(this); m_layout->setContentsMargins(0, 0, 0, 0); m_layout->setSpacing(0); setLayout(m_layout); setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum); } void NavigationContainer::addWidget(QWidget* widget) { m_layout->addWidget(widget); } void NavigationContainer::setTabBar(TabBar* tabBar) { m_tabBar = tabBar; m_layout->addWidget(m_tabBar); toggleTabsOnTop(qzSettings->tabsOnTop); } void NavigationContainer::toggleTabsOnTop(bool enable) { setUpdatesEnabled(false); m_layout->removeWidget(m_tabBar); m_layout->insertWidget(enable ? 0 : m_layout->count(), m_tabBar); m_layout->setContentsMargins(0, enable ? 2 : 0, 0, 0); setUpdatesEnabled(true); } void NavigationContainer::paintEvent(QPaintEvent* event) { QWidget::paintEvent(event); // Draw line at the bottom of navigation bar if tabs are on top // To visually distinguish navigation bar from the page if (qzSettings->tabsOnTop) { QPainter p(this); QRect lineRect(0, height() - 1, width(), 1); QColor c = palette().window().color().darker(125); p.fillRect(lineRect, c); } } diff --git a/src/lib/navigation/navigationcontainer.h b/src/lib/navigation/navigationcontainer.h index 8378ca30..f7256214 100644 --- a/src/lib/navigation/navigationcontainer.h +++ b/src/lib/navigation/navigationcontainer.h @@ -1,46 +1,46 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2013-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef NAVIGATIONCONTAINER_H #define NAVIGATIONCONTAINER_H #include #include "qzcommon.h" class QVBoxLayout; class TabBar; -class QUPZILLA_EXPORT NavigationContainer : public QWidget +class FALKON_EXPORT NavigationContainer : public QWidget { public: explicit NavigationContainer(QWidget* parent = 0); void addWidget(QWidget* widget); void setTabBar(TabBar* tabBar); void toggleTabsOnTop(bool enable); private: void paintEvent(QPaintEvent* event); QVBoxLayout* m_layout; TabBar* m_tabBar; }; #endif // NAVIGATIONCONTAINER_H diff --git a/src/lib/navigation/reloadstopbutton.cpp b/src/lib/navigation/reloadstopbutton.cpp index 3c2daafd..efe57f1a 100644 --- a/src/lib/navigation/reloadstopbutton.cpp +++ b/src/lib/navigation/reloadstopbutton.cpp @@ -1,76 +1,76 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "reloadstopbutton.h" #include #include ReloadStopButton::ReloadStopButton(QWidget* parent) : ToolButton(parent) , m_loadInProgress(false) { setToolButtonStyle(Qt::ToolButtonIconOnly); setToolbarButtonLook(true); setAutoRaise(true); setFocusPolicy(Qt::NoFocus); m_updateTimer = new QTimer(this); m_updateTimer->setInterval(50); m_updateTimer->setSingleShot(true); connect(m_updateTimer, SIGNAL(timeout()), this, SLOT(updateButton())); connect(this, SIGNAL(clicked()), this, SLOT(buttonClicked())); updateButton(); } void ReloadStopButton::showStopButton() { m_loadInProgress = true; m_updateTimer->start(); } void ReloadStopButton::showReloadButton() { m_loadInProgress = false; m_updateTimer->start(); } void ReloadStopButton::updateButton() { if (m_loadInProgress) { setToolTip(tr("Stop")); setObjectName(QSL("navigation-button-stop")); } else { setToolTip(tr("Reload")); setObjectName(QSL("navigation-button-reload")); } // Update the stylesheet for the changed object name style()->unpolish(this); style()->polish(this); } void ReloadStopButton::buttonClicked() { if (m_loadInProgress) emit stopClicked(); else emit reloadClicked(); } diff --git a/src/lib/navigation/reloadstopbutton.h b/src/lib/navigation/reloadstopbutton.h index 5c796cc3..f91556f2 100644 --- a/src/lib/navigation/reloadstopbutton.h +++ b/src/lib/navigation/reloadstopbutton.h @@ -1,49 +1,49 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef RELOADSTOPBUTTON_H #define RELOADSTOPBUTTON_H #include "qzcommon.h" #include "toolbutton.h" class QTimer; -class QUPZILLA_EXPORT ReloadStopButton : public ToolButton +class FALKON_EXPORT ReloadStopButton : public ToolButton { Q_OBJECT public: explicit ReloadStopButton(QWidget* parent = 0); void showStopButton(); void showReloadButton(); signals: void stopClicked(); void reloadClicked(); private slots: void updateButton(); void buttonClicked(); private: bool m_loadInProgress; QTimer* m_updateTimer; }; #endif // RELOADSTOPBUTTON_H diff --git a/src/lib/navigation/siteicon.cpp b/src/lib/navigation/siteicon.cpp index 192e6a36..b65a354a 100644 --- a/src/lib/navigation/siteicon.cpp +++ b/src/lib/navigation/siteicon.cpp @@ -1,174 +1,174 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "siteicon.h" #include "siteinfowidget.h" #include "locationbar.h" #include "tabbedwebview.h" #include "qztools.h" #include "siteinfo.h" #include #include #include #include #include SiteIcon::SiteIcon(BrowserWindow* window, LocationBar* parent) : ToolButton(parent) , m_window(window) , m_locationBar(parent) , m_view(0) { setObjectName("locationbar-siteicon"); setToolButtonStyle(Qt::ToolButtonIconOnly); setCursor(Qt::ArrowCursor); setToolTip(LocationBar::tr("Show information about this page")); setFocusPolicy(Qt::ClickFocus); m_updateTimer = new QTimer(this); m_updateTimer->setInterval(100); m_updateTimer->setSingleShot(true); connect(m_updateTimer, SIGNAL(timeout()), this, SLOT(updateIcon())); } void SiteIcon::setWebView(WebView* view) { m_view = view; } void SiteIcon::setIcon(const QIcon &icon) { bool wasNull = m_icon.isNull(); m_icon = icon; if (wasNull) { updateIcon(); } else { m_updateTimer->start(); } } void SiteIcon::updateIcon() { ToolButton::setIcon(m_icon); } void SiteIcon::popupClosed() { setDown(false); } void SiteIcon::contextMenuEvent(QContextMenuEvent* e) { // Prevent propagating to LocationBar e->accept(); } void SiteIcon::mousePressEvent(QMouseEvent* e) { if (e->buttons() == Qt::LeftButton) { m_dragStartPosition = e->pos(); } // Prevent propagating to LocationBar e->accept(); ToolButton::mousePressEvent(e); } void SiteIcon::mouseReleaseEvent(QMouseEvent* e) { // Mouse release event is restoring Down state // So we pause updates to prevent flicker bool activated = false; if (e->button() == Qt::LeftButton && rect().contains(e->pos())) { - // Popup may not be always shown, eg. on qupzilla: pages + // Popup may not be always shown, eg. on falkon: pages activated = showPopup(); } if (activated) { setUpdatesEnabled(false); } ToolButton::mouseReleaseEvent(e); if (activated) { setDown(true); setUpdatesEnabled(true); } } void SiteIcon::mouseMoveEvent(QMouseEvent* e) { if (!m_locationBar || e->buttons() != Qt::LeftButton) { ToolButton::mouseMoveEvent(e); return; } int manhattanLength = (e->pos() - m_dragStartPosition).manhattanLength(); if (manhattanLength <= QApplication::startDragDistance()) { ToolButton::mouseMoveEvent(e); return; } const QUrl url = m_locationBar->webView()->url(); const QString title = m_locationBar->webView()->title(); if (url.isEmpty() || title.isEmpty()) { ToolButton::mouseMoveEvent(e); return; } QDrag* drag = new QDrag(this); QMimeData* mime = new QMimeData; mime->setUrls(QList() << url); mime->setText(title); mime->setImageData(icon().pixmap(16).toImage()); drag->setMimeData(mime); drag->setPixmap(QzTools::createPixmapForSite(icon(), title, url.toString())); drag->exec(); // Restore Down state setDown(false); } bool SiteIcon::showPopup() { if (!m_view || !m_window) { return false; } QUrl url = m_view->url(); if (!SiteInfo::canShowSiteInfo(url)) return false; setDown(true); SiteInfoWidget* info = new SiteInfoWidget(m_window); info->showAt(parentWidget()); connect(info, SIGNAL(destroyed()), this, SLOT(popupClosed())); return true; } diff --git a/src/lib/navigation/siteicon.h b/src/lib/navigation/siteicon.h index 6482b4fa..542f275d 100644 --- a/src/lib/navigation/siteicon.h +++ b/src/lib/navigation/siteicon.h @@ -1,61 +1,61 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef SITEICON_H #define SITEICON_H #include "qzcommon.h" #include "toolbutton.h" class QTimer; class LocationBar; class WebView; class BrowserWindow; -class QUPZILLA_EXPORT SiteIcon : public ToolButton +class FALKON_EXPORT SiteIcon : public ToolButton { Q_OBJECT public: explicit SiteIcon(BrowserWindow* window, LocationBar* parent); void setWebView(WebView* view); void setIcon(const QIcon &icon); private slots: void updateIcon(); void popupClosed(); private: void contextMenuEvent(QContextMenuEvent* e); void mousePressEvent(QMouseEvent* e); void mouseReleaseEvent(QMouseEvent* e); void mouseMoveEvent(QMouseEvent* e); bool showPopup(); BrowserWindow* m_window; LocationBar* m_locationBar; WebView* m_view; QTimer* m_updateTimer; QPoint m_dragStartPosition; QIcon m_icon; }; #endif // SITEICON_H diff --git a/src/lib/navigation/websearchbar.cpp b/src/lib/navigation/websearchbar.cpp index de46e6e3..0166b10a 100644 --- a/src/lib/navigation/websearchbar.cpp +++ b/src/lib/navigation/websearchbar.cpp @@ -1,337 +1,337 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "websearchbar.h" #include "browserwindow.h" #include "mainapplication.h" #include "tabbedwebview.h" #include "webpage.h" #include "settings.h" #include "qzsettings.h" #include "tabwidget.h" #include "clickablelabel.h" #include "buttonwithmenu.h" #include "searchenginesmanager.h" #include "searchenginesdialog.h" #include "networkmanager.h" #include "iconprovider.h" #include "scripts.h" #include #include #include #include #include #include #include #include WebSearchBar_Button::WebSearchBar_Button(QWidget* parent) : ClickableLabel(parent) { setObjectName("websearchbar-searchbutton"); setCursor(QCursor(Qt::PointingHandCursor)); setFocusPolicy(Qt::ClickFocus); } void WebSearchBar_Button::contextMenuEvent(QContextMenuEvent* event) { event->accept(); } WebSearchBar::WebSearchBar(BrowserWindow* window) : LineEdit(window) , m_window(window) , m_reloadingEngines(false) { setObjectName("websearchbar"); setDragEnabled(true); m_buttonSearch = new WebSearchBar_Button(this); m_boxSearchType = new ButtonWithMenu(this); m_boxSearchType->setObjectName("websearchbar-searchprovider-comobobox"); // RTL Support // If we don't add 'm_boxSearchType' by following code, then we should use suitable padding-left value // but then, when typing RTL text the layout dynamically changed and within RTL layout direction // padding-left is equivalent to padding-right and vice versa, and because style sheet is // not changed dynamically this create padding problems. addWidget(m_boxSearchType, LineEdit::LeftSide); addWidget(m_buttonSearch, LineEdit::RightSide); connect(m_buttonSearch, SIGNAL(clicked(QPoint)), this, SLOT(search())); connect(m_buttonSearch, SIGNAL(middleClicked(QPoint)), this, SLOT(searchInNewTab())); connect(m_boxSearchType, SIGNAL(activeItemChanged(ButtonWithMenu::Item)), this, SLOT(searchChanged(ButtonWithMenu::Item))); setWidgetSpacing(0); m_searchManager = mApp->searchEnginesManager(); connect(m_boxSearchType->menu(), SIGNAL(aboutToShow()), this, SLOT(aboutToShowMenu())); m_completer = new QCompleter(this); m_completer->setCompletionMode(QCompleter::UnfilteredPopupCompletion); m_completerModel = new QStringListModel(this); m_completer->setModel(m_completerModel); m_completer->popup()->setMinimumHeight(90); setCompleter(m_completer); connect(m_completer->popup(), &QAbstractItemView::activated, this, &WebSearchBar::search); m_openSearchEngine = new OpenSearchEngine(this); m_openSearchEngine->setNetworkAccessManager(mApp->networkManager()); connect(m_openSearchEngine, SIGNAL(suggestions(QStringList)), this, SLOT(addSuggestions(QStringList))); connect(this, SIGNAL(textEdited(QString)), m_openSearchEngine, SLOT(requestSuggestions(QString))); editAction(PasteAndGo)->setText(tr("Paste And &Search")); editAction(PasteAndGo)->setIcon(QIcon::fromTheme(QSL("edit-paste"))); connect(editAction(PasteAndGo), SIGNAL(triggered()), this, SLOT(pasteAndGo())); QTimer::singleShot(0, this, SLOT(setupEngines())); } void WebSearchBar::aboutToShowMenu() { QMenu* menu = m_boxSearchType->menu(); menu->addSeparator(); m_window->weView()->page()->runJavaScript(Scripts::getOpenSearchLinks(), WebPage::SafeJsWorld, [this, menu](const QVariant &res) { const QVariantList &list = res.toList(); Q_FOREACH (const QVariant &val, list) { const QVariantMap &link = val.toMap(); QUrl url = m_window->weView()->url().resolved(link.value(QSL("url")).toUrl()); QString title = link.value(QSL("title")).toString(); if (url.isEmpty()) continue; if (title.isEmpty()) title = m_window->weView()->title(); menu->addAction(m_window->weView()->icon(), tr("Add %1 ...").arg(title), this, SLOT(addEngineFromAction()))->setData(url); } menu->addSeparator(); menu->addAction(IconProvider::settingsIcon(), tr("Manage Search Engines"), this, SLOT(openSearchEnginesDialog())); }); } void WebSearchBar::addSuggestions(const QStringList &list) { if (qzSettings->showSearchSuggestions) { QStringList list_ = list.mid(0, 6); m_completerModel->setStringList(list_); m_completer->complete(); } } void WebSearchBar::openSearchEnginesDialog() { if (!m_searchDialog) m_searchDialog = new SearchEnginesDialog(this); m_searchDialog->open(); m_searchDialog->raise(); m_searchDialog->activateWindow(); } void WebSearchBar::enableSearchSuggestions(bool enable) { Settings settings; settings.beginGroup("SearchEngines"); settings.setValue("showSuggestions", enable); settings.endGroup(); qzSettings->showSearchSuggestions = enable; m_completerModel->setStringList(QStringList()); } void WebSearchBar::setupEngines() { disconnect(m_searchManager, SIGNAL(enginesChanged()), this, SLOT(setupEngines())); m_reloadingEngines = true; QString activeEngine = m_searchManager->startingEngineName(); if (m_boxSearchType->allItems().count() != 0) { activeEngine = m_activeEngine.name; } m_boxSearchType->clearItems(); foreach (const SearchEngine &en, m_searchManager->allEngines()) { ButtonWithMenu::Item item; item.icon = en.icon; item.text = en.name; QVariant v; v.setValue(en); item.userData = v; m_boxSearchType->addItem(item); if (item.text == activeEngine) { m_boxSearchType->setCurrentItem(item, false); } } searchChanged(m_boxSearchType->currentItem()); connect(m_searchManager, SIGNAL(enginesChanged()), this, SLOT(setupEngines())); m_reloadingEngines = false; } void WebSearchBar::searchChanged(const ButtonWithMenu::Item &item) { setPlaceholderText(item.text); m_completerModel->setStringList(QStringList()); m_activeEngine = item.userData.value(); m_openSearchEngine->setSuggestionsUrl(m_activeEngine.suggestionsUrl); m_openSearchEngine->setSuggestionsParameters(m_activeEngine.suggestionsParameters); m_searchManager->setActiveEngine(m_activeEngine); if (qzSettings->searchOnEngineChange && !m_reloadingEngines && !text().isEmpty()) { search(); } } void WebSearchBar::instantSearchChanged(bool enable) { Settings settings; settings.beginGroup("SearchEngines"); settings.setValue("SearchOnEngineChange", enable); settings.endGroup(); qzSettings->searchOnEngineChange = enable; } void WebSearchBar::search() { m_window->weView()->setFocus(); m_window->weView()->load(m_searchManager->searchResult(m_activeEngine, text())); } void WebSearchBar::searchInNewTab() { int index = m_window->tabWidget()->addView(QUrl()); m_window->weView(index)->setFocus(); m_window->weView(index)->load(m_searchManager->searchResult(m_activeEngine, text())); } void WebSearchBar::addEngineFromAction() { if (QAction* action = qobject_cast(sender())) { m_searchManager->addEngine(action->data().toUrl()); } } void WebSearchBar::pasteAndGo() { clear(); paste(); search(); } void WebSearchBar::contextMenuEvent(QContextMenuEvent* event) { Q_UNUSED(event) QMenu* menu = createContextMenu(); menu->setAttribute(Qt::WA_DeleteOnClose); menu->addSeparator(); QAction* act = menu->addAction(tr("Show suggestions")); act->setCheckable(true); act->setChecked(qzSettings->showSearchSuggestions); connect(act, SIGNAL(triggered(bool)), this, SLOT(enableSearchSuggestions(bool))); QAction* instantSearch = menu->addAction(tr("Search when engine changed")); instantSearch->setCheckable(true); instantSearch->setChecked(qzSettings->searchOnEngineChange); connect(instantSearch, SIGNAL(triggered(bool)), this, SLOT(instantSearchChanged(bool))); // Prevent choosing first option with double rightclick QPoint pos = event->globalPos(); pos.setY(pos.y() + 1); menu->popup(pos); } void WebSearchBar::focusOutEvent(QFocusEvent* e) { if (text().isEmpty()) { QString search = m_boxSearchType->currentItem().text; setPlaceholderText(search); } LineEdit::focusOutEvent(e); } void WebSearchBar::dropEvent(QDropEvent* event) { if (event->mimeData()->hasText()) { QString dropText = event->mimeData()->text(); setText(dropText); search(); QFocusEvent event(QFocusEvent::FocusOut); LineEdit::focusOutEvent(&event); return; } LineEdit::dropEvent(event); } void WebSearchBar::keyPressEvent(QKeyEvent* event) { switch (event->key()) { case Qt::Key_V: if (event->modifiers() == (Qt::ControlModifier | Qt::ShiftModifier)) { pasteAndGo(); event->accept(); return; } break; case Qt::Key_Return: case Qt::Key_Enter: if (event->modifiers() == Qt::AltModifier) { searchInNewTab(); } else { search(); } break; case Qt::Key_Up: if (event->modifiers() == Qt::ControlModifier) { m_boxSearchType->selectPreviousItem(); } break; case Qt::Key_Down: if (event->modifiers() == Qt::ControlModifier) { m_boxSearchType->selectNextItem(); } break; default: break; } LineEdit::keyPressEvent(event); } diff --git a/src/lib/navigation/websearchbar.h b/src/lib/navigation/websearchbar.h index e4bb6290..04c9972e 100644 --- a/src/lib/navigation/websearchbar.h +++ b/src/lib/navigation/websearchbar.h @@ -1,94 +1,94 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef WEBSEARCHBAR_H #define WEBSEARCHBAR_H #include #include "qzcommon.h" #include "lineedit.h" #include "buttonwithmenu.h" #include "searchenginesmanager.h" #include "clickablelabel.h" class QStringListModel; class BrowserWindow; class LineEdit; class ClickableLabel; class SearchEnginesManager; class SearchEnginesDialog; class OpenSearchEngine; -class QUPZILLA_EXPORT WebSearchBar_Button : public ClickableLabel +class FALKON_EXPORT WebSearchBar_Button : public ClickableLabel { public: explicit WebSearchBar_Button(QWidget* parent = 0); private: void contextMenuEvent(QContextMenuEvent* event); }; -class QUPZILLA_EXPORT WebSearchBar : public LineEdit +class FALKON_EXPORT WebSearchBar : public LineEdit { Q_OBJECT public: explicit WebSearchBar(BrowserWindow* window); private slots: void searchChanged(const ButtonWithMenu::Item &item); void setupEngines(); void search(); void searchInNewTab(); void aboutToShowMenu(); void openSearchEnginesDialog(); void enableSearchSuggestions(bool enable); void addSuggestions(const QStringList &list); void addEngineFromAction(); void pasteAndGo(); void instantSearchChanged(bool); private: void focusOutEvent(QFocusEvent* e); void dropEvent(QDropEvent* event); void keyPressEvent(QKeyEvent* event); void contextMenuEvent(QContextMenuEvent* event); QCompleter* m_completer; QStringListModel* m_completerModel; OpenSearchEngine* m_openSearchEngine; SearchEngine m_activeEngine; BrowserWindow* m_window; WebSearchBar_Button* m_buttonSearch; ButtonWithMenu* m_boxSearchType; SearchEnginesManager* m_searchManager; QPointer m_searchDialog; bool m_reloadingEngines; }; #endif // WEBSEARCHBAR_H diff --git a/src/lib/network/networkmanager.cpp b/src/lib/network/networkmanager.cpp index 1b0fb667..fdc0fd8f 100644 --- a/src/lib/network/networkmanager.cpp +++ b/src/lib/network/networkmanager.cpp @@ -1,264 +1,264 @@ /* ============================================================ * QupZilla - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "networkmanager.h" #include "autofill.h" #include "qztools.h" #include "settings.h" #include "cookiejar.h" #include "acceptlanguage.h" #include "mainapplication.h" #include "passwordmanager.h" #include "sslerrordialog.h" #include "networkurlinterceptor.h" -#include "schemehandlers/qupzillaschemehandler.h" +#include "schemehandlers/falkonschemehandler.h" #include #include #include #include #include #include #include #include #include #include #include NetworkManager::NetworkManager(QObject *parent) : QNetworkAccessManager(parent) { // Create scheme handlers - mApp->webProfile()->installUrlSchemeHandler(QByteArrayLiteral("qupzilla"), new QupZillaSchemeHandler()); + mApp->webProfile()->installUrlSchemeHandler(QByteArrayLiteral("falkon"), new FalkonSchemeHandler()); // Create url interceptor m_urlInterceptor = new NetworkUrlInterceptor(this); mApp->webProfile()->setRequestInterceptor(m_urlInterceptor); // Create cookie jar mApp->cookieJar(); connect(this, &QNetworkAccessManager::authenticationRequired, this, [this](QNetworkReply *reply, QAuthenticator *auth) { authentication(reply->url(), auth); }); connect(this, &QNetworkAccessManager::proxyAuthenticationRequired, this, [this](const QNetworkProxy &proxy, QAuthenticator *auth) { proxyAuthentication(proxy.hostName(), auth); }); } bool NetworkManager::certificateError(const QWebEngineCertificateError &error, QWidget *parent) { const QString &host = error.url().host(); if (m_ignoredSslErrors.contains(host) && m_ignoredSslErrors.value(host) == error.error()) return true; QString title = tr("SSL Certificate Error!"); QString text1 = tr("The page you are trying to access has the following errors in the SSL certificate:"); QString text2 = tr("Would you like to make an exception for this certificate?"); QString message = QSL("%1

%2

  • %3

%4

").arg(title, text1, error.errorDescription(), text2); SslErrorDialog dialog(parent); dialog.setText(message); dialog.exec(); switch (dialog.result()) { case SslErrorDialog::Yes: // TODO: Permanent exceptions case SslErrorDialog::OnlyForThisSession: m_ignoredSslErrors[error.url().host()] = error.error(); return true; case SslErrorDialog::No: default: return false; } } void NetworkManager::authentication(const QUrl &url, QAuthenticator *auth, QWidget *parent) { QDialog* dialog = new QDialog(parent); dialog->setWindowTitle(tr("Authorisation required")); QFormLayout* formLa = new QFormLayout(dialog); QLabel* label = new QLabel(dialog); QLabel* userLab = new QLabel(dialog); QLabel* passLab = new QLabel(dialog); userLab->setText(tr("Username: ")); passLab->setText(tr("Password: ")); QLineEdit* user = new QLineEdit(dialog); QLineEdit* pass = new QLineEdit(dialog); pass->setEchoMode(QLineEdit::Password); QCheckBox* save = new QCheckBox(dialog); save->setText(tr("Save username and password for this site")); QDialogButtonBox* box = new QDialogButtonBox(dialog); box->addButton(QDialogButtonBox::Ok); box->addButton(QDialogButtonBox::Cancel); connect(box, SIGNAL(rejected()), dialog, SLOT(reject())); connect(box, SIGNAL(accepted()), dialog, SLOT(accept())); label->setText(tr("A username and password are being requested by %1. " "The site says: \"%2\"").arg(url.host(), auth->realm().toHtmlEscaped())); formLa->addRow(label); formLa->addRow(userLab, user); formLa->addRow(passLab, pass); formLa->addRow(save); formLa->addWidget(box); AutoFill* fill = mApp->autoFill(); QString storedUser; QString storedPassword; bool shouldUpdateEntry = false; if (fill->isStored(url)) { const QVector &data = fill->getFormData(url); if (!data.isEmpty()) { save->setChecked(true); shouldUpdateEntry = true; storedUser = data.at(0).username; storedPassword = data.at(0).password; user->setText(storedUser); pass->setText(storedPassword); } } // Do not save when private browsing is enabled if (mApp->isPrivate()) { save->setVisible(false); } if (dialog->exec() != QDialog::Accepted) { *auth = QAuthenticator(); delete dialog; return; } auth->setUser(user->text()); auth->setPassword(pass->text()); if (save->isChecked()) { if (shouldUpdateEntry) { if (storedUser != user->text() || storedPassword != pass->text()) { fill->updateEntry(url, user->text(), pass->text()); } } else { fill->addEntry(url, user->text(), pass->text()); } } delete dialog; } void NetworkManager::proxyAuthentication(const QString &proxyHost, QAuthenticator *auth, QWidget *parent) { const QNetworkProxy proxy = QNetworkProxy::applicationProxy(); if (!proxy.user().isEmpty() && !proxy.password().isEmpty()) { auth->setUser(proxy.user()); auth->setPassword(proxy.password()); return; } QDialog* dialog = new QDialog(parent); dialog->setWindowTitle(tr("Proxy authorisation required")); QFormLayout* formLa = new QFormLayout(dialog); QLabel* label = new QLabel(dialog); QLabel* userLab = new QLabel(dialog); QLabel* passLab = new QLabel(dialog); userLab->setText(tr("Username: ")); passLab->setText(tr("Password: ")); QLineEdit* user = new QLineEdit(dialog); QLineEdit* pass = new QLineEdit(dialog); pass->setEchoMode(QLineEdit::Password); QDialogButtonBox* box = new QDialogButtonBox(dialog); box->addButton(QDialogButtonBox::Ok); box->addButton(QDialogButtonBox::Cancel); connect(box, SIGNAL(rejected()), dialog, SLOT(reject())); connect(box, SIGNAL(accepted()), dialog, SLOT(accept())); label->setText(tr("A username and password are being requested by proxy %1. ").arg(proxyHost)); formLa->addRow(label); formLa->addRow(userLab, user); formLa->addRow(passLab, pass); formLa->addWidget(box); if (dialog->exec() != QDialog::Accepted) { *auth = QAuthenticator(); delete dialog; return; } auth->setUser(user->text()); auth->setPassword(pass->text()); delete dialog; } void NetworkManager::installUrlInterceptor(UrlInterceptor *interceptor) { m_urlInterceptor->installUrlInterceptor(interceptor); } void NetworkManager::removeUrlInterceptor(UrlInterceptor *interceptor) { m_urlInterceptor->removeUrlInterceptor(interceptor); } void NetworkManager::loadSettings() { Settings settings; settings.beginGroup("Language"); QStringList langs = settings.value("acceptLanguage", AcceptLanguage::defaultLanguage()).toStringList(); settings.endGroup(); mApp->webProfile()->setHttpAcceptLanguage(AcceptLanguage::generateHeader(langs)); QNetworkProxy proxy; settings.beginGroup("Web-Proxy"); proxy.setType(QNetworkProxy::ProxyType(settings.value("ProxyType", QNetworkProxy::NoProxy).toInt())); proxy.setHostName(settings.value("HostName", QString()).toString()); proxy.setPort(settings.value("Port", 8080).toInt()); proxy.setUser(settings.value("Username", QString()).toString()); proxy.setPassword(settings.value("Password", QString()).toString()); settings.endGroup(); QNetworkProxy::setApplicationProxy(proxy); m_urlInterceptor->loadSettings(); } void NetworkManager::shutdown() { mApp->webProfile()->setRequestInterceptor(nullptr); } QNetworkReply *NetworkManager::createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest &request, QIODevice *outgoingData) { QNetworkRequest req = request; req.setAttribute(QNetworkRequest::SpdyAllowedAttribute, true); req.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true); return QNetworkAccessManager::createRequest(op, req, outgoingData); } diff --git a/src/lib/network/networkmanager.h b/src/lib/network/networkmanager.h index 7bfaff99..4a072b23 100644 --- a/src/lib/network/networkmanager.h +++ b/src/lib/network/networkmanager.h @@ -1,54 +1,54 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef NETWORKMANAGER_H #define NETWORKMANAGER_H #include #include #include "qzcommon.h" class UrlInterceptor; class NetworkUrlInterceptor; -class QUPZILLA_EXPORT NetworkManager : public QNetworkAccessManager +class FALKON_EXPORT NetworkManager : public QNetworkAccessManager { Q_OBJECT public: explicit NetworkManager(QObject *parent = Q_NULLPTR); bool certificateError(const QWebEngineCertificateError &error, QWidget *parent = Q_NULLPTR); void authentication(const QUrl &url, QAuthenticator *auth, QWidget *parent = Q_NULLPTR); void proxyAuthentication(const QString &proxyHost, QAuthenticator *auth, QWidget *parent = Q_NULLPTR); void installUrlInterceptor(UrlInterceptor *interceptor); void removeUrlInterceptor(UrlInterceptor *interceptor); void loadSettings(); void shutdown(); protected: QNetworkReply *createRequest(Operation op, const QNetworkRequest &request, QIODevice *outgoingData) Q_DECL_OVERRIDE; private: NetworkUrlInterceptor *m_urlInterceptor; QHash m_ignoredSslErrors; }; #endif // NETWORKMANAGER_H diff --git a/src/lib/network/networkproxyfactory.cpp b/src/lib/network/networkproxyfactory.cpp index 5c75bf95..aa5d23a2 100644 --- a/src/lib/network/networkproxyfactory.cpp +++ b/src/lib/network/networkproxyfactory.cpp @@ -1,171 +1,171 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "networkproxyfactory.h" #include "mainapplication.h" #include "settings.h" WildcardMatcher::WildcardMatcher(const QString &pattern) : m_regExp(0) { setPattern(pattern); } WildcardMatcher::~WildcardMatcher() { delete m_regExp; } void WildcardMatcher::setPattern(const QString &pattern) { m_pattern = pattern; if (m_pattern.contains(QLatin1Char('?')) || m_pattern.contains(QLatin1Char('*'))) { QString regexp = m_pattern; regexp.replace(QLatin1Char('.'), QLatin1String("\\.")) .replace(QLatin1Char('*'), QLatin1String(".*")) .replace(QLatin1Char('?'), QLatin1Char('.')); regexp = QString("^.*%1.*$").arg(regexp); m_regExp = new QzRegExp(regexp, Qt::CaseInsensitive); } } QString WildcardMatcher::pattern() const { return m_pattern; } bool WildcardMatcher::match(const QString &str) const { if (!m_regExp) { return str.contains(m_pattern, Qt::CaseInsensitive); } return m_regExp->indexIn(str) > -1; } NetworkProxyFactory::NetworkProxyFactory() : QNetworkProxyFactory() , m_proxyPreference(SystemProxy) , m_proxyType(QNetworkProxy::NoProxy) , m_port(0) , m_httpsPort(0) , m_useDifferentProxyForHttps(false) { } void NetworkProxyFactory::loadSettings() { Settings settings; settings.beginGroup("Web-Proxy"); m_proxyPreference = ProxyPreference(settings.value("UseProxy", SystemProxy).toInt()); m_proxyType = QNetworkProxy::ProxyType(settings.value("ProxyType", QNetworkProxy::NoProxy).toInt()); m_useDifferentProxyForHttps = settings.value("UseDifferentProxyForHttps", false).toBool(); m_hostName = settings.value("HostName", QString()).toString(); m_port = settings.value("Port", 8080).toInt(); m_username = settings.value("Username", QString()).toString(); m_password = settings.value("Password", QString()).toString(); m_httpsHostName = settings.value("HttpsHostName", QString()).toString(); m_httpsPort = settings.value("HttpsPort", 8080).toInt(); m_httpsUsername = settings.value("HttpsUsername", QString()).toString(); m_httpsPassword = settings.value("HttpsPassword", QString()).toString(); QStringList exceptions = settings.value("ProxyExceptions", QStringList() << "localhost" << "127.0.0.1").toStringList(); settings.endGroup(); qDeleteAll(m_proxyExceptions); m_proxyExceptions.clear(); foreach (const QString &exception, exceptions) { m_proxyExceptions.append(new WildcardMatcher(exception.trimmed())); } } NetworkProxyFactory::ProxyPreference NetworkProxyFactory::proxyPreference() const { return m_proxyPreference; } QList NetworkProxyFactory::queryProxy(const QNetworkProxyQuery &query) { QList proxyList; if (m_proxyPreference == NoProxy) { proxyList.append(QNetworkProxy::NoProxy); return proxyList; } const QString urlHost = query.url().host(); foreach (WildcardMatcher* m, m_proxyExceptions) { if (m->match(urlHost)) { proxyList.append(QNetworkProxy::NoProxy); return proxyList; } } switch (m_proxyPreference) { case SystemProxy: proxyList.append(systemProxyForQuery(query)); break; case ProxyAutoConfig: qWarning() << "PAC Not Implemented!"; break; case DefinedProxy: { QNetworkProxy proxy(m_proxyType); if (m_useDifferentProxyForHttps && query.protocolTag() == QLatin1String("https")) { proxy.setHostName(m_httpsHostName); proxy.setPort(m_httpsPort); proxy.setUser(m_httpsUsername); proxy.setPassword(m_httpsPassword); } else { proxy.setHostName(m_hostName); proxy.setPort(m_port); proxy.setUser(m_username); proxy.setPassword(m_password); } if (proxy.hostName().isEmpty()) { proxy = QNetworkProxy::NoProxy; } proxyList.append(proxy); break; } default: qWarning("NetworkProxyFactory::queryProxy Unknown proxy type!"); break; } if (!proxyList.contains(QNetworkProxy::NoProxy)) { proxyList.append(QNetworkProxy::NoProxy); } return proxyList; } NetworkProxyFactory::~NetworkProxyFactory() { qDeleteAll(m_proxyExceptions); } diff --git a/src/lib/network/networkproxyfactory.h b/src/lib/network/networkproxyfactory.h index 8e529659..471a5018 100644 --- a/src/lib/network/networkproxyfactory.h +++ b/src/lib/network/networkproxyfactory.h @@ -1,75 +1,75 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef NETWORKPROXYFACTORY_H #define NETWORKPROXYFACTORY_H #include #include #include "qzcommon.h" #include "qzregexp.h" class WildcardMatcher { public: explicit WildcardMatcher(const QString &pattern = QString()); ~WildcardMatcher(); void setPattern(const QString &pattern); QString pattern() const; bool match(const QString &str) const; private: QString m_pattern; QzRegExp* m_regExp; }; -class QUPZILLA_EXPORT NetworkProxyFactory : public QNetworkProxyFactory +class FALKON_EXPORT NetworkProxyFactory : public QNetworkProxyFactory { public: enum ProxyPreference { SystemProxy, NoProxy, ProxyAutoConfig, DefinedProxy }; explicit NetworkProxyFactory(); ~NetworkProxyFactory(); void loadSettings(); ProxyPreference proxyPreference() const; QList queryProxy(const QNetworkProxyQuery &query = QNetworkProxyQuery()); private: ProxyPreference m_proxyPreference; QNetworkProxy::ProxyType m_proxyType; QString m_hostName; quint16 m_port; QString m_username; QString m_password; QString m_httpsHostName; quint16 m_httpsPort; QString m_httpsUsername; QString m_httpsPassword; QList m_proxyExceptions; bool m_useDifferentProxyForHttps; }; #endif // NETWORKPROXYFACTORY_H diff --git a/src/lib/network/networkurlinterceptor.cpp b/src/lib/network/networkurlinterceptor.cpp index 299c06ca..d9079ec3 100644 --- a/src/lib/network/networkurlinterceptor.cpp +++ b/src/lib/network/networkurlinterceptor.cpp @@ -1,59 +1,59 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2015-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "networkurlinterceptor.h" #include "urlinterceptor.h" #include "settings.h" #include "mainapplication.h" #include "useragentmanager.h" NetworkUrlInterceptor::NetworkUrlInterceptor(QObject *parent) : QWebEngineUrlRequestInterceptor(parent) , m_sendDNT(false) { } void NetworkUrlInterceptor::interceptRequest(QWebEngineUrlRequestInfo &info) { if (m_sendDNT) info.setHttpHeader(QByteArrayLiteral("DNT"), QByteArrayLiteral("1")); info.setHttpHeader(QByteArrayLiteral("User-Agent"), mApp->userAgentManager()->userAgentForUrl(info.firstPartyUrl()).toUtf8()); foreach (UrlInterceptor *interceptor, m_interceptors) { interceptor->interceptRequest(info); } } void NetworkUrlInterceptor::installUrlInterceptor(UrlInterceptor *interceptor) { if (!m_interceptors.contains(interceptor)) m_interceptors.append(interceptor); } void NetworkUrlInterceptor::removeUrlInterceptor(UrlInterceptor *interceptor) { m_interceptors.removeOne(interceptor); } void NetworkUrlInterceptor::loadSettings() { Settings settings; settings.beginGroup("Web-Browser-Settings"); m_sendDNT = settings.value("DoNotTrack", false).toBool(); settings.endGroup(); } diff --git a/src/lib/network/networkurlinterceptor.h b/src/lib/network/networkurlinterceptor.h index 8f862d7f..ab63f693 100644 --- a/src/lib/network/networkurlinterceptor.h +++ b/src/lib/network/networkurlinterceptor.h @@ -1,45 +1,45 @@ /* ============================================================ -* QupZilla - QtWebEngine based browser +* Falkon - Qt web browser * Copyright (C) 2015 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef NETWORKURLINTERCEPTOR_H #define NETWORKURLINTERCEPTOR_H #include #include "qzcommon.h" class UrlInterceptor; -class QUPZILLA_EXPORT NetworkUrlInterceptor : public QWebEngineUrlRequestInterceptor +class FALKON_EXPORT NetworkUrlInterceptor : public QWebEngineUrlRequestInterceptor { public: explicit NetworkUrlInterceptor(QObject* parent = Q_NULLPTR); void interceptRequest(QWebEngineUrlRequestInfo &info) Q_DECL_OVERRIDE; void installUrlInterceptor(UrlInterceptor *interceptor); void removeUrlInterceptor(UrlInterceptor *interceptor); void loadSettings(); private: QList m_interceptors; bool m_sendDNT; }; #endif // NETWORKURLINTERCEPTOR_H diff --git a/src/lib/network/schemehandlers/qupzillaschemehandler.cpp b/src/lib/network/schemehandlers/falkonschemehandler.cpp similarity index 94% rename from src/lib/network/schemehandlers/qupzillaschemehandler.cpp rename to src/lib/network/schemehandlers/falkonschemehandler.cpp index 45c838ba..55be1ccc 100644 --- a/src/lib/network/schemehandlers/qupzillaschemehandler.cpp +++ b/src/lib/network/schemehandlers/falkonschemehandler.cpp @@ -1,494 +1,494 @@ /* ============================================================ * QupZilla - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ -#include "qupzillaschemehandler.h" +#include "falkonschemehandler.h" #include "qztools.h" #include "browserwindow.h" #include "mainapplication.h" #include "tabbedwebview.h" #include "speeddial.h" #include "pluginproxy.h" #include "plugininterface.h" #include "settings.h" #include "datapaths.h" #include "iconprovider.h" #include "useragentmanager.h" #include "sessionmanager.h" #include #include #include #include static QString authorString(const char* name, const QString &mail) { return QSL("%1 <%2>").arg(QString::fromUtf8(name), mail); } -QupZillaSchemeHandler::QupZillaSchemeHandler(QObject *parent) +FalkonSchemeHandler::FalkonSchemeHandler(QObject *parent) : QWebEngineUrlSchemeHandler(parent) { } -void QupZillaSchemeHandler::requestStarted(QWebEngineUrlRequestJob *job) +void FalkonSchemeHandler::requestStarted(QWebEngineUrlRequestJob *job) { QStringList knownPages; knownPages << "about" << "reportbug" << "start" << "speeddial" << "config" << "restore" << "adblock"; if (knownPages.contains(job->requestUrl().path())) - job->reply(QByteArrayLiteral("text/html"), new QupZillaSchemeReply(job)); + job->reply(QByteArrayLiteral("text/html"), new FalkonSchemeReply(job)); else job->fail(QWebEngineUrlRequestJob::UrlInvalid); } -QupZillaSchemeReply::QupZillaSchemeReply(QWebEngineUrlRequestJob *job, QObject *parent) +FalkonSchemeReply::FalkonSchemeReply(QWebEngineUrlRequestJob *job, QObject *parent) : QIODevice(parent) , m_loaded(false) , m_job(job) { m_pageName = m_job->requestUrl().path(); open(QIODevice::ReadOnly); m_buffer.open(QIODevice::ReadWrite); } -void QupZillaSchemeReply::loadPage() +void FalkonSchemeReply::loadPage() { if (m_loaded) return; QTextStream stream(&m_buffer); stream.setCodec("UTF-8"); if (m_pageName == QLatin1String("about")) { stream << aboutPage(); } else if (m_pageName == QLatin1String("reportbug")) { stream << reportbugPage(); } else if (m_pageName == QLatin1String("start")) { stream << startPage(); } else if (m_pageName == QLatin1String("speeddial")) { stream << speeddialPage(); } else if (m_pageName == QLatin1String("config")) { stream << configPage(); } else if (m_pageName == QLatin1String("restore")) { stream << restorePage(); } else if (m_pageName == QLatin1String("adblock")) { stream << adblockPage(); } stream.flush(); m_buffer.reset(); m_loaded = true; } -qint64 QupZillaSchemeReply::bytesAvailable() const +qint64 FalkonSchemeReply::bytesAvailable() const { return m_buffer.bytesAvailable(); } -qint64 QupZillaSchemeReply::readData(char *data, qint64 maxSize) +qint64 FalkonSchemeReply::readData(char *data, qint64 maxSize) { loadPage(); return m_buffer.read(data, maxSize); } -qint64 QupZillaSchemeReply::writeData(const char *data, qint64 len) +qint64 FalkonSchemeReply::writeData(const char *data, qint64 len) { Q_UNUSED(data); Q_UNUSED(len); return 0; } -QString QupZillaSchemeReply::reportbugPage() +QString FalkonSchemeReply::reportbugPage() { static QString bPage; if (!bPage.isEmpty()) { return bPage; } bPage.append(QzTools::readAllFileContents(":html/reportbug.html")); bPage.replace(QLatin1String("%TITLE%"), tr("Report Issue")); bPage.replace(QLatin1String("%REPORT-ISSUE%"), tr("Report Issue")); - bPage.replace(QLatin1String("%PLUGINS-TEXT%"), tr("If you are experiencing problems with QupZilla, please try to disable" + bPage.replace(QLatin1String("%PLUGINS-TEXT%"), tr("If you are experiencing problems with Falkon, please try to disable" " all extensions first.
If this does not fix it, then please fill out this form: ")); bPage.replace(QLatin1String("%EMAIL%"), tr("Your E-mail")); bPage.replace(QLatin1String("%TYPE%"), tr("Issue type")); bPage.replace(QLatin1String("%DESCRIPTION%"), tr("Issue description")); bPage.replace(QLatin1String("%SEND%"), tr("Send")); bPage.replace(QLatin1String("%E-MAIL-OPTIONAL%"), tr("E-mail is optional
Note: Please read how to make a " "bug report here first.").arg("https://github.com/QupZilla/qupzilla/wiki/Bug-Reports target=_blank")); bPage.replace(QLatin1String("%FIELDS-ARE-REQUIRED%"), tr("Please fill out all required fields!")); bPage.replace(QLatin1String("%INFO_OS%"), QzTools::operatingSystemLong()); bPage.replace(QLatin1String("%INFO_APP%"), #ifdef GIT_REVISION QString("%1 (%2)").arg(Qz::VERSION, GIT_REVISION) #else Qz::VERSION #endif ); bPage.replace(QLatin1String("%INFO_QT%"), QString("%1 (built with %2)").arg(qVersion(), QT_VERSION_STR)); bPage.replace(QLatin1String("%INFO_WEBKIT%"), QSL("QtWebEngine")), bPage = QzTools::applyDirectionToPage(bPage); return bPage; } -QString QupZillaSchemeReply::startPage() +QString FalkonSchemeReply::startPage() { static QString sPage; if (!sPage.isEmpty()) { return sPage; } sPage.append(QzTools::readAllFileContents(":html/start.html")); sPage.replace(QLatin1String("%ABOUT-IMG%"), QzTools::pixmapToDataUrl(QzTools::dpiAwarePixmap(QSL(":icons/other/startpage.png"))).toString()); sPage.replace(QLatin1String("%TITLE%"), tr("Start Page")); sPage.replace(QLatin1String("%BUTTON-LABEL%"), tr("Search on Web")); sPage.replace(QLatin1String("%SEARCH-BY%"), tr("Search results provided by DuckDuckGo")); sPage.replace(QLatin1String("%WWW%"), Qz::WIKIADDRESS); - sPage.replace(QLatin1String("%ABOUT-QUPZILLA%"), tr("About QupZilla")); + sPage.replace(QLatin1String("%ABOUT-FALKON%"), tr("About Falkon")); sPage.replace(QLatin1String("%PRIVATE-BROWSING%"), mApp->isPrivate() ? tr("

Private Browsing

") : QString()); sPage = QzTools::applyDirectionToPage(sPage); return sPage; } -QString QupZillaSchemeReply::aboutPage() +QString FalkonSchemeReply::aboutPage() { static QString aPage; if (aPage.isEmpty()) { aPage.append(QzTools::readAllFileContents(":html/about.html")); aPage.replace(QLatin1String("%ABOUT-IMG%"), QzTools::pixmapToDataUrl(QzTools::dpiAwarePixmap(QSL(":icons/other/about.png"))).toString()); aPage.replace(QLatin1String("%COPYRIGHT-INCLUDE%"), QzTools::readAllFileContents(":html/copyright").toHtmlEscaped()); - aPage.replace(QLatin1String("%TITLE%"), tr("About QupZilla")); - aPage.replace(QLatin1String("%ABOUT-QUPZILLA%"), tr("About QupZilla")); + aPage.replace(QLatin1String("%TITLE%"), tr("About Falkon")); + aPage.replace(QLatin1String("%ABOUT-FALKON%"), tr("About Falkon")); aPage.replace(QLatin1String("%INFORMATIONS-ABOUT-VERSION%"), tr("Information about version")); aPage.replace(QLatin1String("%COPYRIGHT%"), tr("Copyright")); aPage.replace(QLatin1String("%VERSION-INFO%"), QString("
%1
%2
").arg(tr("Version"), #ifdef GIT_REVISION QString("%1 (%2)").arg(Qz::VERSION, GIT_REVISION))); #else Qz::VERSION)); #endif aPage.replace(QLatin1String("%MAIN-DEVELOPER%"), tr("Main developer")); aPage.replace(QLatin1String("%MAIN-DEVELOPER-TEXT%"), authorString(Qz::AUTHOR, "nowrep@gmail.com")); aPage.replace(QLatin1String("%CONTRIBUTORS%"), tr("Contributors")); aPage.replace(QLatin1String("%CONTRIBUTORS-TEXT%"), authorString("Mladen Pejaković", "pejakm@autistici.org") + "
" + authorString("Adrien Vigneron", "adrienvigneron@ml1.net") + "
" + authorString("Elio Qoshi", "ping@elioqoshi.me") + "
" + authorString("Seyyed Razi Alavizadeh", "s.r.alavizadeh@gmail.com") + "
" + authorString("Alexander Samilov", "alexsamilovskih@gmail.com") + "
" + authorString("Franz Fellner", "alpine.art.de@googlemail.com") + "
" + authorString("Bryan M Dunsmore", "dunsmoreb@gmail.com") + "
" + authorString("Mariusz Fik", "fisiu@opensuse.org") + "
" + authorString("Daniele Cocca", "jmc@chakra-project.org") ); aPage.replace(QLatin1String("%TRANSLATORS%"), tr("Translators")); aPage.replace(QLatin1String("%TRANSLATORS-TEXT%"), authorString("Heimen Stoffels", "vistausss@gmail.com") + " (Dutch)
" + authorString("Peter Vacula", "pvacula1989@gmail.com") + " (Slovak)
" + authorString("Ján Ďanovský", "dagsoftware@yahoo.com") + " (Slovak)
" + authorString("Jonathan Hooverman", "jonathan.hooverman@gmail.com") + " (German)
" + authorString("Federico Fabiani", "federico.fabiani85@gmail.com") + " (Italian)
" + authorString("Francesco Marinucci", "framarinucci@gmail.com") + " (Italian)
" + authorString("Jorge Sevilla", "jsevi@ozu.es") + " (Spanish)
" + authorString("Ștefan Comănescu", "sdfanq@gmail.com") + " (Romanian)
" + authorString("Michał Szymanowski", "tylkobuba@gmail.com") + " (Polish)
" + authorString("Mariusz Fik", "fisiu@opensuse.org") + " (Polish)
" + authorString("Jérôme Giry", "baikalink@hotmail.fr") + " (French)
" + authorString("Nicolas Ourceau", "lamessen@hotmail.fr") + " (French)
" + authorString("Vasilis Tsivikis", "vasitsiv.dev@gmail.com") + " (Greek)
" + authorString("Rustam Salakhutdinov", "salahutd@gmail.com") + " (Russian)
" + authorString("Oleg Brezhnev", "oleg-423@yandex.ru") + " (Russian)
" + authorString("Sérgio Marques", "smarquespt@gmail.com") + " (Portuguese)
" + authorString("Alexandre Carvalho", "alexandre05@live.com") + " (Brazilian Portuguese)
" + authorString("Mladen Pejaković", "pejakm@autistici.org") + " (Serbian)
" + authorString("Unink-Lio", "unink4451@163.com") + " (Chinese)
" + authorString("Yu Hai", "yohanprc@eml.cc") + " (Chinese)
" + authorString("Wu Cheng-Hong", "stu2731652@gmail.com") + " (Traditional Chinese)
" + authorString("Widya Walesa", "walecha99@gmail.com") + " (Indonesian)
" + authorString("Beqa Arabuli", "arabulibeqa@gmail.com") + " (Georgian)
" + authorString("Daiki Noda", "sys.pdr.pdm9@gmail.com") + " (Japanese)
" + authorString("Gábor Oberle", "oberleg@myopera.com") + " (Hungarian)
" + authorString("Piccoro McKay Lenz", "mckaygerhard@gmail.com") + " (Venezuelan Spanish)
" + authorString("Stanislav Kuznietsov", "stanislav_kuznetsov@ukr.net") + " (Ukrainian)
" + authorString("Seyyed Razi Alavizadeh", "s.r.alavizadeh@gmail.com") + " (Persian)
" + authorString("Guillem Prats", "guprej@gmail.com") + " (Catalan)
" + authorString("Clara Villalba", "cvilmon@gmail.com") + " (Catalan)
" + authorString("Muhammad Fawwaz Orabi", "mfawwaz93@gmail.com") + " (Arabic)
" + authorString("Lasso Kante", "kantemou@gmail.com") + " (N'ko)
" + authorString("Kizito Birabwa", "kbirabwa@yahoo.co.uk") + " (Luganda)
" + authorString("Juan Carlos Sánchez", "hollow1984angel@gmail.com") + " (Mexican Spanish)
" + authorString("Xabier Aramendi", "azpidatziak@gmail.com") + " (Basque)
" + authorString("Ferhat AYDIN", "ferhataydin44@gmail.com") + " (Turkish)" ); aPage = QzTools::applyDirectionToPage(aPage); } return aPage; } -QString QupZillaSchemeReply::speeddialPage() +QString FalkonSchemeReply::speeddialPage() { static QString dPage; if (dPage.isEmpty()) { dPage.append(QzTools::readAllFileContents(":html/speeddial.html")); dPage.replace(QLatin1String("%IMG_PLUS%"), QLatin1String("qrc:html/plus.png")); dPage.replace(QLatin1String("%IMG_CLOSE%"), QLatin1String("qrc:html/close.png")); dPage.replace(QLatin1String("%IMG_EDIT%"), QLatin1String("qrc:html/edit.png")); dPage.replace(QLatin1String("%IMG_RELOAD%"), QLatin1String("qrc:html/reload.png")); dPage.replace(QLatin1String("%JQUERY%"), QLatin1String("qrc:html/jquery.js")); dPage.replace(QLatin1String("%JQUERY-UI%"), QLatin1String("qrc:html/jquery-ui.js")); dPage.replace(QLatin1String("%LOADING-IMG%"), QLatin1String("qrc:html/loading.gif")); dPage.replace(QLatin1String("%IMG_SETTINGS%"), QLatin1String("qrc:html/configure.png")); dPage.replace(QLatin1String("%SITE-TITLE%"), tr("Speed Dial")); dPage.replace(QLatin1String("%ADD-TITLE%"), tr("Add New Page")); dPage.replace(QLatin1String("%TITLE-EDIT%"), tr("Edit")); dPage.replace(QLatin1String("%TITLE-REMOVE%"), tr("Remove")); dPage.replace(QLatin1String("%TITLE-RELOAD%"), tr("Reload")); dPage.replace(QLatin1String("%TITLE-WARN%"), tr("Are you sure you want to remove this speed dial?")); dPage.replace(QLatin1String("%TITLE-WARN-REL%"), tr("Are you sure you want to reload all speed dials?")); dPage.replace(QLatin1String("%TITLE-FETCHTITLE%"), tr("Load title from page")); dPage.replace(QLatin1String("%URL%"), tr("Url")); dPage.replace(QLatin1String("%TITLE%"), tr("Title")); dPage.replace(QLatin1String("%APPLY%"), tr("Apply")); dPage.replace(QLatin1String("%CLOSE%"), tr("Close")); dPage.replace(QLatin1String("%NEW-PAGE%"), tr("New Page")); dPage.replace(QLatin1String("%SETTINGS-TITLE%"), tr("Speed Dial settings")); dPage.replace(QLatin1String("%TXT_PLACEMENT%"), tr("Placement: ")); dPage.replace(QLatin1String("%TXT_AUTO%"), tr("Auto")); dPage.replace(QLatin1String("%TXT_COVER%"), tr("Cover")); dPage.replace(QLatin1String("%TXT_FIT%"), tr("Fit")); dPage.replace(QLatin1String("%TXT_FWIDTH%"), tr("Fit Width")); dPage.replace(QLatin1String("%TXT_FHEIGHT%"), tr("Fit Height")); dPage.replace(QLatin1String("%TXT_NOTE%"), tr("Use background image")); dPage.replace(QLatin1String("%TXT_SELECTIMAGE%"), tr("Select image")); dPage.replace(QLatin1String("%TXT_NRROWS%"), tr("Maximum pages in a row:")); dPage.replace(QLatin1String("%TXT_SDSIZE%"), tr("Change size of pages:")); dPage.replace(QLatin1String("%TXT_CNTRDLS%"), tr("Center speed dials")); dPage = QzTools::applyDirectionToPage(dPage); } QString page = dPage; SpeedDial* dial = mApp->plugins()->speedDial(); page.replace(QLatin1String("%INITIAL-SCRIPT%"), dial->initialScript()); page.replace(QLatin1String("%IMG_BACKGROUND%"), dial->backgroundImage()); page.replace(QLatin1String("%URL_BACKGROUND%"), dial->backgroundImageUrl()); page.replace(QLatin1String("%B_SIZE%"), dial->backgroundImageSize()); page.replace(QLatin1String("%ROW-PAGES%"), QString::number(dial->pagesInRow())); page.replace(QLatin1String("%SD-SIZE%"), QString::number(dial->sdSize())); page.replace(QLatin1String("%SD-CENTER%"), dial->sdCenter() ? QSL("true") : QSL("false")); return page; } -QString QupZillaSchemeReply::restorePage() +QString FalkonSchemeReply::restorePage() { static QString rPage; if (rPage.isEmpty()) { rPage.append(QzTools::readAllFileContents(":html/restore.html")); rPage.replace(QLatin1String("%IMAGE%"), QzTools::pixmapToDataUrl(IconProvider::standardIcon(QStyle::SP_MessageBoxWarning).pixmap(45)).toString()); rPage.replace(QLatin1String("%TITLE%"), tr("Restore Session")); - rPage.replace(QLatin1String("%OOPS%"), tr("Oops, QupZilla crashed.")); + rPage.replace(QLatin1String("%OOPS%"), tr("Oops, Falkon crashed.")); rPage.replace(QLatin1String("%APOLOGIZE%"), tr("We apologize for this. Would you like to restore the last saved state?")); rPage.replace(QLatin1String("%TRY-REMOVING%"), tr("Try removing one or more tabs that you think cause troubles")); rPage.replace(QLatin1String("%START-NEW%"), tr("Or you can start completely new session")); rPage.replace(QLatin1String("%WINDOW%"), tr("Window")); rPage.replace(QLatin1String("%WINDOWS-AND-TABS%"), tr("Windows and Tabs")); rPage.replace(QLatin1String("%BUTTON-START-NEW%"), tr("Start New Session")); rPage.replace(QLatin1String("%BUTTON-RESTORE%"), tr("Restore")); rPage = QzTools::applyDirectionToPage(rPage); } return rPage; } -QString QupZillaSchemeReply::configPage() +QString FalkonSchemeReply::configPage() { static QString cPage; if (cPage.isEmpty()) { cPage.append(QzTools::readAllFileContents(":html/config.html")); cPage.replace(QLatin1String("%ABOUT-IMG%"), QzTools::pixmapToDataUrl(QzTools::dpiAwarePixmap(QSL(":icons/other/about.png"))).toString()); cPage.replace(QLatin1String("%TITLE%"), tr("Configuration Information")); cPage.replace(QLatin1String("%CONFIG%"), tr("Configuration Information")); cPage.replace(QLatin1String("%INFORMATIONS-ABOUT-VERSION%"), tr("Information about version")); - cPage.replace(QLatin1String("%CONFIG-ABOUT%"), tr("This page contains information about QupZilla's current configuration - relevant for troubleshooting. Please include this information when submitting bug reports.")); + cPage.replace(QLatin1String("%CONFIG-ABOUT%"), tr("This page contains information about Falkon's current configuration - relevant for troubleshooting. Please include this information when submitting bug reports.")); cPage.replace(QLatin1String("%BROWSER-IDENTIFICATION%"), tr("Browser Identification")); cPage.replace(QLatin1String("%PATHS%"), tr("Paths")); cPage.replace(QLatin1String("%BUILD-CONFIG%"), tr("Build Configuration")); cPage.replace(QLatin1String("%PREFS%"), tr("Preferences")); cPage.replace(QLatin1String("%OPTION%"), tr("Option")); cPage.replace(QLatin1String("%VALUE%"), tr("Value")); cPage.replace(QLatin1String("%PLUGINS%"), tr("Extensions")); cPage.replace(QLatin1String("%PL-NAME%"), tr("Name")); cPage.replace(QLatin1String("%PL-VER%"), tr("Version")); cPage.replace(QLatin1String("%PL-AUTH%"), tr("Author")); cPage.replace(QLatin1String("%PL-DESC%"), tr("Description")); cPage.replace(QLatin1String("%VERSION-INFO%"), QString("
%1
%2
").arg(tr("Application version"), #ifdef GIT_REVISION QString("%1 (%2)").arg(Qz::VERSION, GIT_REVISION) #else Qz::VERSION #endif ) + QString("
%1
%2
").arg(tr("Qt version"), qVersion()) + QString("
%1
%2
").arg(tr("Platform"), QzTools::operatingSystemLong())); cPage.replace(QLatin1String("%PATHS-TEXT%"), QString("
%1
%2
").arg(tr("Profile"), DataPaths::currentProfilePath()) + QString("
%1
%2
").arg(tr("Settings"), DataPaths::currentProfilePath() + "/settings.ini") + QString("
%1
%2
").arg(tr("Saved session"), SessionManager::defaultSessionPath()) + QString("
%1
%2
").arg(tr("Pinned tabs"), DataPaths::currentProfilePath() + "/pinnedtabs.dat") + QString("
%1
%2
").arg(tr("Data"), DataPaths::path(DataPaths::AppData)) + QString("
%1
%2
").arg(tr("Themes"), DataPaths::path(DataPaths::Themes)) + QString("
%1
%2
").arg(tr("Translations"), DataPaths::path(DataPaths::Translations))); -#ifdef QUPZILLA_DEBUG_BUILD +#ifdef FALKON_DEBUG_BUILD QString debugBuild = tr("Enabled"); #else QString debugBuild = tr("Disabled"); #endif #ifdef Q_OS_WIN #if defined(Q_OS_WIN) && defined(W7API) QString w7APIEnabled = tr("Enabled"); #else QString w7APIEnabled = tr("Disabled"); #endif #endif QString portableBuild = mApp->isPortable() ? tr("Enabled") : tr("Disabled"); cPage.replace(QLatin1String("%BUILD-CONFIG-TEXT%"), QString("
%1
%2
").arg(tr("Debug build"), debugBuild) + #ifdef Q_OS_WIN QString("
%1
%2
").arg(tr("Windows 7 API"), w7APIEnabled) + #endif QString("
%1
%2
").arg(tr("Portable build"), portableBuild)); cPage = QzTools::applyDirectionToPage(cPage); } QString page = cPage; page.replace(QLatin1String("%USER-AGENT%"), mApp->userAgentManager()->userAgentForUrl(QUrl())); QString pluginsString; const QList &availablePlugins = mApp->plugins()->getAvailablePlugins(); foreach (const Plugins::Plugin &plugin, availablePlugins) { PluginSpec spec = plugin.pluginSpec; pluginsString.append(QString("%1%2%3%4").arg( spec.name, spec.version, spec.author.toHtmlEscaped(), spec.description)); } if (pluginsString.isEmpty()) { pluginsString = QString("%1").arg(tr("No available extensions.")); } page.replace(QLatin1String("%PLUGINS-INFO%"), pluginsString); QString allGroupsString; QSettings* settings = Settings::globalSettings(); foreach (const QString &group, settings->childGroups()) { QString groupString = QString("[%1]").arg(group); settings->beginGroup(group); foreach (const QString &key, settings->childKeys()) { const QVariant keyValue = settings->value(key); QString keyString; switch (keyValue.type()) { case QVariant::ByteArray: keyString = QLatin1String("QByteArray"); break; case QVariant::Point: { const QPoint point = keyValue.toPoint(); keyString = QString("QPoint(%1, %2)").arg(point.x()).arg(point.y()); break; } case QVariant::StringList: keyString = keyValue.toStringList().join(","); break; default: keyString = keyValue.toString(); } if (keyString.isEmpty()) { keyString = QLatin1String("\"empty\""); } groupString.append(QString("%1%2").arg(key, keyString.toHtmlEscaped())); } settings->endGroup(); allGroupsString.append(groupString); } page.replace(QLatin1String("%PREFS-INFO%"), allGroupsString); return page; } -QString QupZillaSchemeReply::adblockPage() +QString FalkonSchemeReply::adblockPage() { static QString aPage; if (aPage.isEmpty()) { aPage.append(QzTools::readAllFileContents(":html/adblock.html")); aPage.replace(QLatin1String("%FAVICON%"), QLatin1String("qrc:html/adblock_big.png")); aPage.replace(QLatin1String("%IMAGE%"), QLatin1String("qrc:html/adblock_big.png")); aPage.replace(QLatin1String("%TITLE%"), tr("Blocked content")); aPage = QzTools::applyDirectionToPage(aPage); } QString page = aPage; QUrlQuery query(m_job->requestUrl()); const QString rule = query.queryItemValue(QSL("rule")); const QString subscription = query.queryItemValue(QSL("subscription")); page.replace(QLatin1String("%RULE%"), tr("Blocked by %1 (%2)").arg(rule, subscription)); return page; } diff --git a/src/lib/network/schemehandlers/qupzillaschemehandler.h b/src/lib/network/schemehandlers/falkonschemehandler.h similarity index 80% rename from src/lib/network/schemehandlers/qupzillaschemehandler.h rename to src/lib/network/schemehandlers/falkonschemehandler.h index 48d3b5c7..6abba367 100644 --- a/src/lib/network/schemehandlers/qupzillaschemehandler.h +++ b/src/lib/network/schemehandlers/falkonschemehandler.h @@ -1,64 +1,64 @@ /* ============================================================ * QupZilla - WebKit based browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ -#ifndef QUPZILLASCHEMEHANDLER_H -#define QUPZILLASCHEMEHANDLER_H +#ifndef FALKONSCHEMEHANDLER_H +#define FALKONSCHEMEHANDLER_H #include #include #include #include "qzcommon.h" -class QUPZILLA_EXPORT QupZillaSchemeHandler : public QWebEngineUrlSchemeHandler +class FALKON_EXPORT FalkonSchemeHandler : public QWebEngineUrlSchemeHandler { public: - explicit QupZillaSchemeHandler(QObject *parent = Q_NULLPTR); + explicit FalkonSchemeHandler(QObject *parent = Q_NULLPTR); void requestStarted(QWebEngineUrlRequestJob *job) Q_DECL_OVERRIDE; }; -class QUPZILLA_EXPORT QupZillaSchemeReply : public QIODevice +class FALKON_EXPORT FalkonSchemeReply : public QIODevice { Q_OBJECT public: - explicit QupZillaSchemeReply(QWebEngineUrlRequestJob *job, QObject *parent = Q_NULLPTR); + explicit FalkonSchemeReply(QWebEngineUrlRequestJob *job, QObject *parent = Q_NULLPTR); qint64 bytesAvailable() const Q_DECL_OVERRIDE; qint64 readData(char *data, qint64 maxSize) Q_DECL_OVERRIDE; qint64 writeData(const char *data, qint64 len) Q_DECL_OVERRIDE; private slots: void loadPage(); private: QString aboutPage(); QString reportbugPage(); QString startPage(); QString speeddialPage(); QString restorePage(); QString configPage(); QString adblockPage(); bool m_loaded; QBuffer m_buffer; QString m_pageName; QWebEngineUrlRequestJob *m_job; }; -#endif // QUPZILLASCHEMEHANDLER_H +#endif // FALKONSCHEMEHANDLER_H diff --git a/src/lib/network/sslerrordialog.cpp b/src/lib/network/sslerrordialog.cpp index 827ab038..8d1455e0 100644 --- a/src/lib/network/sslerrordialog.cpp +++ b/src/lib/network/sslerrordialog.cpp @@ -1,71 +1,71 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2013-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "sslerrordialog.h" #include "ui_sslerrordialog.h" #include "iconprovider.h" #include SslErrorDialog::SslErrorDialog(QWidget* parent) : QDialog(parent) , ui(new Ui::SslErrorDialog) , m_result(No) { ui->setupUi(this); ui->icon->setPixmap(IconProvider::standardIcon(QStyle::SP_MessageBoxCritical).pixmap(52)); // Disabled until there is reliable way to save certificate error //ui->buttonBox->addButton(tr("Only for this session"), QDialogButtonBox::ApplyRole); ui->buttonBox->button(QDialogButtonBox::No)->setFocus(); connect(ui->buttonBox, SIGNAL(clicked(QAbstractButton*)), this, SLOT(buttonClicked(QAbstractButton*))); } SslErrorDialog::~SslErrorDialog() { delete ui; } void SslErrorDialog::setText(const QString &text) { ui->text->setText(text); } SslErrorDialog::Result SslErrorDialog::result() { return m_result; } void SslErrorDialog::buttonClicked(QAbstractButton* button) { switch (ui->buttonBox->buttonRole(button)) { case QDialogButtonBox::YesRole: m_result = Yes; accept(); break; case QDialogButtonBox::ApplyRole: m_result = OnlyForThisSession; accept(); break; default: m_result = No; reject(); break; } } diff --git a/src/lib/network/sslerrordialog.h b/src/lib/network/sslerrordialog.h index 1f979581..a6bdde24 100644 --- a/src/lib/network/sslerrordialog.h +++ b/src/lib/network/sslerrordialog.h @@ -1,54 +1,54 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2013-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef SSLERRORDIALOG_H #define SSLERRORDIALOG_H #include namespace Ui { class SslErrorDialog; } class QAbstractButton; #include "qzcommon.h" -class QUPZILLA_EXPORT SslErrorDialog : public QDialog +class FALKON_EXPORT SslErrorDialog : public QDialog { Q_OBJECT public: enum Result { Yes, No, OnlyForThisSession }; explicit SslErrorDialog(QWidget* parent = 0); ~SslErrorDialog(); void setText(const QString &text); Result result(); private slots: void buttonClicked(QAbstractButton* button); private: Ui::SslErrorDialog* ui; Result m_result; }; #endif // SSLERRORDIALOG_H diff --git a/src/lib/network/urlinterceptor.h b/src/lib/network/urlinterceptor.h index ac25bc35..55d9380e 100644 --- a/src/lib/network/urlinterceptor.h +++ b/src/lib/network/urlinterceptor.h @@ -1,32 +1,32 @@ /* ============================================================ -* QupZilla - QtWebEngine based browser +* Falkon - Qt web browser * Copyright (C) 2015 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef URLINTERCEPTOR_H #define URLINTERCEPTOR_H #include #include class UrlInterceptor : public QObject { public: explicit UrlInterceptor(QObject *parent = Q_NULLPTR) : QObject(parent) { } virtual void interceptRequest(QWebEngineUrlRequestInfo &info) = 0; }; #endif // URLINTERCEPTOR_H diff --git a/src/lib/notifications/desktopnotification.cpp b/src/lib/notifications/desktopnotification.cpp index 31d80d58..08818ae8 100644 --- a/src/lib/notifications/desktopnotification.cpp +++ b/src/lib/notifications/desktopnotification.cpp @@ -1,100 +1,100 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "desktopnotification.h" #include "ui_desktopnotification.h" #include #include DesktopNotification::DesktopNotification(bool setPosition) : QWidget(0) , ui(new Ui::DesktopNotification) , m_settingPosition(setPosition) , m_timeout(6000) , m_timer(new QTimer(this)) { ui->setupUi(this); setAttribute(Qt::WA_DeleteOnClose); Qt::WindowFlags flags = Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint; setWindowFlags(flags); setAttribute(Qt::WA_TranslucentBackground); setWindowOpacity(0.9); m_timer->setSingleShot(true); connect(m_timer, SIGNAL(timeout()), this, SLOT(close())); if (m_settingPosition) { setCursor(Qt::OpenHandCursor); } } void DesktopNotification::show() { ui->icon->setPixmap(m_icon); ui->icon->setVisible(!m_icon.isNull()); ui->heading->setText(m_heading); ui->text->setText(m_text); if (!m_settingPosition) { m_timer->setInterval(m_timeout); m_timer->start(); } QWidget::show(); } void DesktopNotification::enterEvent(QEvent*) { if (!m_settingPosition) { setWindowOpacity(0.5); } } void DesktopNotification::leaveEvent(QEvent*) { if (!m_settingPosition) { setWindowOpacity(0.9); } } void DesktopNotification::mousePressEvent(QMouseEvent* e) { if (!m_settingPosition) { close(); return; } if (e->buttons() == Qt::LeftButton) { m_dragPosition = e->globalPos() - frameGeometry().topLeft(); e->accept(); } } void DesktopNotification::mouseMoveEvent(QMouseEvent* e) { if (e->buttons() & Qt::LeftButton) { move(e->globalPos() - m_dragPosition); e->accept(); } } DesktopNotification::~DesktopNotification() { delete ui; } diff --git a/src/lib/notifications/desktopnotification.h b/src/lib/notifications/desktopnotification.h index 6d51e4c4..da76864e 100644 --- a/src/lib/notifications/desktopnotification.h +++ b/src/lib/notifications/desktopnotification.h @@ -1,61 +1,61 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef DESKTOPNOTIFICATION_H #define DESKTOPNOTIFICATION_H #include "qzcommon.h" #include #include namespace Ui { class DesktopNotification; } -class QUPZILLA_EXPORT DesktopNotification : public QWidget +class FALKON_EXPORT DesktopNotification : public QWidget { Q_OBJECT public: explicit DesktopNotification(bool setPosition = false); void setPixmap(const QPixmap &icon) { m_icon = icon; } void setHeading(const QString &heading) { m_heading = heading; } void setText(const QString &text) { m_text = text; } void setTimeout(int timeout) { m_timeout = timeout; } void show(); ~DesktopNotification(); private: void enterEvent(QEvent* e); void leaveEvent(QEvent* e); void mousePressEvent(QMouseEvent* e); void mouseMoveEvent(QMouseEvent* e); Ui::DesktopNotification* ui; bool m_settingPosition; QPoint m_dragPosition; QPixmap m_icon; QString m_heading; QString m_text; int m_timeout; QTimer* m_timer; }; #endif // DESKTOPNOTIFICATION_H diff --git a/src/lib/notifications/desktopnotificationsfactory.cpp b/src/lib/notifications/desktopnotificationsfactory.cpp index 193607b0..c6273944 100644 --- a/src/lib/notifications/desktopnotificationsfactory.cpp +++ b/src/lib/notifications/desktopnotificationsfactory.cpp @@ -1,131 +1,131 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "desktopnotificationsfactory.h" #include "desktopnotification.h" #include "datapaths.h" #include "settings.h" #include #include #if defined(Q_OS_UNIX) && !defined(DISABLE_DBUS) #include #endif DesktopNotificationsFactory::DesktopNotificationsFactory(QObject* parent) : QObject(parent) , m_uint(0) { loadSettings(); } void DesktopNotificationsFactory::loadSettings() { Settings settings; settings.beginGroup("Notifications"); m_enabled = settings.value("Enabled", true).toBool(); m_timeout = settings.value("Timeout", 6000).toInt(); #if defined(Q_OS_UNIX) && !defined(DISABLE_DBUS) m_notifType = settings.value("UseNativeDesktop", true).toBool() ? DesktopNative : PopupWidget; #else m_notifType = PopupWidget; #endif m_position = settings.value("Position", QPoint(10, 10)).toPoint(); settings.endGroup(); } bool DesktopNotificationsFactory::supportsNativeNotifications() const { #if defined(Q_OS_UNIX) && !defined(DISABLE_DBUS) return true; #else return false; #endif } void DesktopNotificationsFactory::showNotification(const QPixmap &icon, const QString &heading, const QString &text) { if (!m_enabled) { return; } switch (m_notifType) { case PopupWidget: if (!m_desktopNotif) { m_desktopNotif = new DesktopNotification(); } m_desktopNotif.data()->setPixmap(icon); m_desktopNotif.data()->setHeading(heading); m_desktopNotif.data()->setText(text); m_desktopNotif.data()->setTimeout(m_timeout); m_desktopNotif.data()->move(m_position); m_desktopNotif.data()->show(); break; case DesktopNative: #if defined(Q_OS_UNIX) && !defined(DISABLE_DBUS) - QFile tmp(DataPaths::path(DataPaths::Temp) + QLatin1String("/qupzilla_notif.png")); + QFile tmp(DataPaths::path(DataPaths::Temp) + QLatin1String("/falkon_notif.png")); tmp.open(QFile::WriteOnly); icon.save(tmp.fileName()); QDBusInterface dbus("org.freedesktop.Notifications", "/org/freedesktop/Notifications", "org.freedesktop.Notifications", QDBusConnection::sessionBus()); QVariantList args; - args.append(QLatin1String("qupzilla")); + args.append(QLatin1String("falkon")); args.append(m_uint); args.append(tmp.fileName()); args.append(heading); args.append(text); args.append(QStringList()); args.append(QVariantMap()); args.append(m_timeout); dbus.callWithCallback("Notify", args, this, SLOT(updateLastId(QDBusMessage)), SLOT(error(QDBusError))); #endif break; } } void DesktopNotificationsFactory::nativeNotificationPreview() { #if defined(Q_OS_UNIX) && !defined(DISABLE_DBUS) QDBusInterface dbus("org.freedesktop.Notifications", "/org/freedesktop/Notifications", "org.freedesktop.Notifications", QDBusConnection::sessionBus()); QVariantList args; - args.append(QLatin1String("qupzilla")); + args.append(QLatin1String("falkon")); args.append(m_uint); args.append(QString()); args.append(QObject::tr("Native System Notification")); args.append(QString()); args.append(QStringList()); args.append(QVariantMap()); args.append(m_timeout); dbus.callWithCallback("Notify", args, this, SLOT(updateLastId(QDBusMessage)), SLOT(error(QDBusError))); #endif } #if defined(Q_OS_UNIX) && !defined(DISABLE_DBUS) void DesktopNotificationsFactory::updateLastId(const QDBusMessage &msg) { QVariantList list = msg.arguments(); if (list.count() > 0) { m_uint = list.at(0).toInt(); } } void DesktopNotificationsFactory::error(const QDBusError &error) { qWarning() << "QDBusError:" << error.message(); } #endif diff --git a/src/lib/notifications/desktopnotificationsfactory.h b/src/lib/notifications/desktopnotificationsfactory.h index b7511a22..cc32299a 100644 --- a/src/lib/notifications/desktopnotificationsfactory.h +++ b/src/lib/notifications/desktopnotificationsfactory.h @@ -1,65 +1,65 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef DESKTOPNOTIFICATIONSFACTORY_H #define DESKTOPNOTIFICATIONSFACTORY_H #include "qzcommon.h" #include #include #include class QPixmap; class QDBusMessage; class QDBusError; class DesktopNotification; -class QUPZILLA_EXPORT DesktopNotificationsFactory : public QObject +class FALKON_EXPORT DesktopNotificationsFactory : public QObject { Q_OBJECT public: enum Type { DesktopNative, PopupWidget }; explicit DesktopNotificationsFactory(QObject* parent = 0); void loadSettings(); bool supportsNativeNotifications() const; void showNotification(const QPixmap &icon, const QString &heading, const QString &text); void nativeNotificationPreview(); private slots: #if defined(Q_OS_UNIX) && !defined(DISABLE_DBUS) void updateLastId(const QDBusMessage &msg); void error(const QDBusError &error); #endif private: bool m_enabled; int m_timeout; Type m_notifType; QPoint m_position; QPointer m_desktopNotif; quint32 m_uint; }; #endif // DESKTOPNOTIFICATIONSFACTORY_H diff --git a/src/lib/opensearch/editsearchengine.cpp b/src/lib/opensearch/editsearchengine.cpp index 0f045bb4..e3116e23 100644 --- a/src/lib/opensearch/editsearchengine.cpp +++ b/src/lib/opensearch/editsearchengine.cpp @@ -1,108 +1,108 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "editsearchengine.h" #include "ui_editsearchengine.h" #include "iconchooser.h" #include EditSearchEngine::EditSearchEngine(const QString &title, QWidget* parent) : QDialog(parent) , ui(new Ui::EditSearchEngine) { setWindowTitle(title); ui->setupUi(this); connect(ui->iconFromFile, SIGNAL(clicked()), this, SLOT(chooseIcon())); ui->buttonBox->setFocus(); setFixedHeight(sizeHint().height()); } QString EditSearchEngine::name() { return ui->name->text().trimmed(); } void EditSearchEngine::setName(const QString &name) { ui->name->setText(name); ui->name->setCursorPosition(0); } QString EditSearchEngine::url() { return ui->url->text().trimmed(); } QString EditSearchEngine::postData() { return ui->postData->text().trimmed(); } void EditSearchEngine::setUrl(const QString &url) { ui->url->setText(url); ui->url->setCursorPosition(0); } void EditSearchEngine::setPostData(const QString &postData) { ui->postData->setText(postData); ui->postData->setCursorPosition(0); } QString EditSearchEngine::shortcut() { return ui->shortcut->text().trimmed(); } void EditSearchEngine::setShortcut(const QString &shortcut) { ui->shortcut->setText(shortcut); ui->shortcut->setCursorPosition(0); } QIcon EditSearchEngine::icon() { return QIcon(*ui->icon->pixmap()); } void EditSearchEngine::setIcon(const QIcon &icon) { ui->icon->setPixmap(icon.pixmap(16)); } void EditSearchEngine::hideIconLabels() { ui->iconLabel->hide(); ui->editIconFrame->hide(); resize(width(), sizeHint().height()); } void EditSearchEngine::chooseIcon() { IconChooser chooser(this); QIcon icon = chooser.getIcon(); if (!icon.isNull()) { setIcon(icon); } } diff --git a/src/lib/opensearch/editsearchengine.h b/src/lib/opensearch/editsearchengine.h index fb6f70bc..df46cf5f 100644 --- a/src/lib/opensearch/editsearchengine.h +++ b/src/lib/opensearch/editsearchengine.h @@ -1,62 +1,62 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef EDITSEARCHENGINES_H #define EDITSEARCHENGINES_H #include "qzcommon.h" #include namespace Ui { class EditSearchEngine; } -class QUPZILLA_EXPORT EditSearchEngine : public QDialog +class FALKON_EXPORT EditSearchEngine : public QDialog { Q_OBJECT public: explicit EditSearchEngine(const QString &title, QWidget* parent = 0); void setName(const QString &name); void setUrl(const QString &url); void setPostData(const QString &postData); void setShortcut(const QString &shortcut); void setIcon(const QIcon &icon); QString name(); QString url(); QString postData(); QString shortcut(); QIcon icon(); void hideIconLabels(); signals: public slots: private slots: void chooseIcon(); private: Ui::EditSearchEngine* ui; }; #endif // EDITSEARCHENGINES_H diff --git a/src/lib/opensearch/opensearchengine.cpp b/src/lib/opensearch/opensearchengine.cpp index b9818a58..16e2c972 100644 --- a/src/lib/opensearch/opensearchengine.cpp +++ b/src/lib/opensearch/opensearchengine.cpp @@ -1,704 +1,704 @@ /* * Copyright 2009 Jakub Wieczorek * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA */ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2016 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "opensearchengine.h" #include "qzregexp.h" #include "opensearchenginedelegate.h" #include #include #include #include #include #include #include #include #include /*! \class OpenSearchEngine \brief A class representing a single search engine described in OpenSearch format OpenSearchEngine is a class that represents a single search engine based on the OpenSearch format. For more information about the format, see http://www.opensearch.org/. Instances of the class hold all the data associated with the corresponding search engines, such as name(), description() and also URL templates that are used to construct URLs, which can be used later to perform search queries. Search engine can also have an image, even an external one, in this case it will be downloaded automatically from the network. OpenSearchEngine instances can be constructed from scratch but also read from external sources and written back to them. OpenSearchReader and OpenSearchWriter are the classes provided for reading and writing OpenSearch descriptions. Default constructed engines need to be filled with the necessary information before they can be used to peform search requests. First of all, a search engine should have the metadata including the name and the description. However, the most important are URL templates, which are the construction of URLs but can also contain template parameters, that are replaced with corresponding values at the time of constructing URLs. There are two types of URL templates: search URL template and suggestions URL template. Search URL template is needed for constructing search URLs, which point directly to search results. Suggestions URL template is necessary to construct suggestion queries URLs, which are then used for requesting contextual suggestions, a popular service offered along with search results that provides search terms related to what has been supplied by the user. Both types of URLs are constructed by the class, by searchUrl() and suggestionsUrl() functions respectively. However, search requests are supposed to be performed outside the class, while suggestion queries can be executed using the requestSuggestions() method. The class will take care of peforming the network request and parsing the JSON response. Both the image request and suggestion queries need network access. The class can perform network requests on its own, though the client application needs to provide a network access manager, which then will to be used for network operations. Without that, both images delivered from remote locations and contextual suggestions will be disabled. \sa OpenSearchReader, OpenSearchWriter */ /*! Constructs an engine with a given \a parent. */ OpenSearchEngine::OpenSearchEngine(QObject* parent) : QObject(parent) , m_searchMethod(QLatin1String("get")) , m_suggestionsMethod(QLatin1String("get")) , m_networkAccessManager(0) , m_suggestionsReply(0) , m_delegate(0) { m_requestMethods.insert(QLatin1String("get"), QNetworkAccessManager::GetOperation); m_requestMethods.insert(QLatin1String("post"), QNetworkAccessManager::PostOperation); } /*! A destructor. */ OpenSearchEngine::~OpenSearchEngine() { } QString OpenSearchEngine::parseTemplate(const QString &searchTerm, const QString &searchTemplate) { QString language = QLocale().name(); // Simple conversion to RFC 3066. language = language.replace(QLatin1Char('_'), QLatin1Char('-')); QString result = searchTemplate; result.replace(QLatin1String("{count}"), QLatin1String("20")); result.replace(QLatin1String("{startIndex}"), QLatin1String("0")); result.replace(QLatin1String("{startPage}"), QLatin1String("0")); result.replace(QLatin1String("{language}"), language); result.replace(QLatin1String("{inputEncoding}"), QLatin1String("UTF-8")); result.replace(QLatin1String("{outputEncoding}"), QLatin1String("UTF-8")); result.replace(QzRegExp(QLatin1String("\\{([^\\}]*:|)source\\??\\}")), QCoreApplication::applicationName()); result.replace(QLatin1String("{searchTerms}"), QLatin1String(QUrl::toPercentEncoding(searchTerm))); return result; } /*! \property OpenSearchEngine::name \brief the name of the engine \sa description() */ QString OpenSearchEngine::name() const { return m_name; } void OpenSearchEngine::setName(const QString &name) { m_name = name; } /*! \property OpenSearchEngine::description \brief the description of the engine \sa name() */ QString OpenSearchEngine::description() const { return m_description; } void OpenSearchEngine::setDescription(const QString &description) { m_description = description; } /*! \property OpenSearchEngine::searchUrlTemplate \brief the template of the search URL \sa searchUrl(), searchParameters(), suggestionsUrlTemplate() */ QString OpenSearchEngine::searchUrlTemplate() const { return m_searchUrlTemplate; } void OpenSearchEngine::setSearchUrlTemplate(const QString &searchUrlTemplate) { if (!searchUrlTemplate.startsWith(QL1S("http://")) && !searchUrlTemplate.startsWith(QL1S("https://"))) { return; } m_searchUrlTemplate = searchUrlTemplate; } /*! Constructs and returns a search URL with a given \a searchTerm. The URL template is processed according to the specification: http://www.opensearch.org/Specifications/OpenSearch/1.1#OpenSearch_URL_template_syntax A list of template parameters currently supported and what they are replaced with: \table \header \o parameter \o value \row \o "{count}" \o "20" \row \o "{startIndex}" \o "0" \row \o "{startPage}" \o "0" \row \o "{language}" \o "the default language code (RFC 3066)" \row \o "{inputEncoding}" \o "UTF-8" \row \o "{outputEncoding}" \o "UTF-8" \row \o "{*:source}" \o "application name, QCoreApplication::applicationName()" \row \o "{searchTerms}" \o "the string supplied by the user" \endtable \sa searchUrlTemplate(), searchParameters(), suggestionsUrl() */ QUrl OpenSearchEngine::searchUrl(const QString &searchTerm) const { if (m_searchUrlTemplate.isEmpty()) { return QUrl(); } QUrl retVal = QUrl::fromEncoded(parseTemplate(searchTerm, m_searchUrlTemplate).toUtf8()); QUrlQuery query(retVal); if (m_searchMethod != QLatin1String("post")) { Parameters::const_iterator end = m_searchParameters.constEnd(); Parameters::const_iterator i = m_searchParameters.constBegin(); for (; i != end; ++i) { query.addQueryItem(i->first, parseTemplate(searchTerm, i->second)); } retVal.setQuery(query); } return retVal; } QByteArray OpenSearchEngine::getPostData(const QString &searchTerm) const { if (m_searchMethod != QLatin1String("post")) { return QByteArray(); } QUrl retVal = QUrl("http://foo.bar"); QUrlQuery query(retVal); Parameters::const_iterator end = m_searchParameters.constEnd(); Parameters::const_iterator i = m_searchParameters.constBegin(); for (; i != end; ++i) { query.addQueryItem(i->first, parseTemplate(searchTerm, i->second)); } retVal.setQuery(query); QByteArray data = retVal.toEncoded(QUrl::RemoveScheme); return data.contains('?') ? data.mid(data.lastIndexOf('?') + 1) : QByteArray(); } /*! \property providesSuggestions \brief indicates whether the engine supports contextual suggestions */ bool OpenSearchEngine::providesSuggestions() const { return (!m_suggestionsUrlTemplate.isEmpty() || !m_preparedSuggestionsUrl.isEmpty()); } /*! \property OpenSearchEngine::suggestionsUrlTemplate \brief the template of the suggestions URL \sa suggestionsUrl(), suggestionsParameters(), searchUrlTemplate() */ QString OpenSearchEngine::suggestionsUrlTemplate() const { return m_suggestionsUrlTemplate; } void OpenSearchEngine::setSuggestionsUrlTemplate(const QString &suggestionsUrlTemplate) { if (!suggestionsUrlTemplate.startsWith(QL1S("http://")) && !suggestionsUrlTemplate.startsWith(QL1S("https://"))) { return; } m_suggestionsUrlTemplate = suggestionsUrlTemplate; } /*! Constructs a suggestions URL with a given \a searchTerm. The URL template is processed according to the specification: http://www.opensearch.org/Specifications/OpenSearch/1.1#OpenSearch_URL_template_syntax See searchUrl() for more information about processing template parameters. \sa suggestionsUrlTemplate(), suggestionsParameters(), searchUrl() */ QUrl OpenSearchEngine::suggestionsUrl(const QString &searchTerm) const { if (!m_preparedSuggestionsUrl.isEmpty()) { QString s = m_preparedSuggestionsUrl; s.replace(QLatin1String("%s"), searchTerm); return QUrl(s); } if (m_suggestionsUrlTemplate.isEmpty()) { return QUrl(); } QUrl retVal = QUrl::fromEncoded(parseTemplate(searchTerm, m_suggestionsUrlTemplate).toUtf8()); QUrlQuery query(retVal); if (m_suggestionsMethod != QLatin1String("post")) { Parameters::const_iterator end = m_suggestionsParameters.constEnd(); Parameters::const_iterator i = m_suggestionsParameters.constBegin(); for (; i != end; ++i) { query.addQueryItem(i->first, parseTemplate(searchTerm, i->second)); } retVal.setQuery(query); } return retVal; } /*! \property searchParameters \brief additional parameters that will be included in the search URL For more information see: http://www.opensearch.org/Specifications/OpenSearch/Extensions/Parameter/1.0 */ OpenSearchEngine::Parameters OpenSearchEngine::searchParameters() const { return m_searchParameters; } void OpenSearchEngine::setSearchParameters(const Parameters &searchParameters) { m_searchParameters = searchParameters; } /*! \property suggestionsParameters \brief additional parameters that will be included in the suggestions URL For more information see: http://www.opensearch.org/Specifications/OpenSearch/Extensions/Parameter/1.0 */ OpenSearchEngine::Parameters OpenSearchEngine::suggestionsParameters() const { return m_suggestionsParameters; } void OpenSearchEngine::setSuggestionsParameters(const Parameters &suggestionsParameters) { m_suggestionsParameters = suggestionsParameters; } /*! \property searchMethod \brief HTTP request method that will be used to perform search requests */ QString OpenSearchEngine::searchMethod() const { return m_searchMethod; } void OpenSearchEngine::setSearchMethod(const QString &method) { QString requestMethod = method.toLower(); if (!m_requestMethods.contains(requestMethod)) { return; } m_searchMethod = requestMethod; } /*! \property suggestionsMethod \brief HTTP request method that will be used to perform suggestions requests */ QString OpenSearchEngine::suggestionsMethod() const { return m_suggestionsMethod; } void OpenSearchEngine::setSuggestionsMethod(const QString &method) { QString requestMethod = method.toLower(); if (!m_requestMethods.contains(requestMethod)) { return; } m_suggestionsMethod = requestMethod; } /*! \property imageUrl \brief the image URL of the engine When setting a new image URL, it won't be loaded immediately. The first request will be deferred until image() is called for the first time. \note To be able to request external images, you need to provide a network access manager, which will be used for network operations. \sa image(), networkAccessManager() */ QString OpenSearchEngine::imageUrl() const { return m_imageUrl; } void OpenSearchEngine::setImageUrl(const QString &imageUrl) { m_imageUrl = imageUrl; } void OpenSearchEngine::loadImage() const { if (!m_networkAccessManager || m_imageUrl.isEmpty()) { return; } QNetworkReply* reply = m_networkAccessManager->get(QNetworkRequest(QUrl::fromEncoded(m_imageUrl.toUtf8()))); connect(reply, SIGNAL(finished()), this, SLOT(imageObtained())); } void OpenSearchEngine::imageObtained() { QNetworkReply* reply = qobject_cast(sender()); if (!reply) { return; } QByteArray response = reply->readAll(); reply->close(); reply->deleteLater(); if (response.isEmpty()) { return; } m_image.loadFromData(response); emit imageChanged(); } /*! \property image \brief the image of the engine When no image URL has been set and an image will be set explicitly, a new data URL will be constructed, holding the image data encoded with Base64. \sa imageUrl() */ QImage OpenSearchEngine::image() const { if (m_image.isNull()) { loadImage(); } return m_image; } void OpenSearchEngine::setImage(const QImage &image) { if (m_imageUrl.isEmpty()) { QBuffer imageBuffer; imageBuffer.open(QBuffer::ReadWrite); if (image.save(&imageBuffer, "PNG")) { m_imageUrl = QString(QLatin1String("data:image/png;base64,%1")) .arg(QLatin1String(imageBuffer.buffer().toBase64())); } } m_image = image; emit imageChanged(); } /*! \property valid \brief indicates whether the engine is valid i.e. the description was properly formed and included all necessary information */ bool OpenSearchEngine::isValid() const { return (!m_name.isEmpty() && !m_searchUrlTemplate.isEmpty()); } bool OpenSearchEngine::operator==(const OpenSearchEngine &other) const { return (m_name == other.m_name && m_description == other.m_description && m_imageUrl == other.m_imageUrl && m_searchUrlTemplate == other.m_searchUrlTemplate && m_suggestionsUrlTemplate == other.m_suggestionsUrlTemplate && m_searchParameters == other.m_searchParameters && m_suggestionsParameters == other.m_suggestionsParameters); } bool OpenSearchEngine::operator<(const OpenSearchEngine &other) const { return (m_name < other.m_name); } /*! Requests contextual suggestions on the search engine, for a given \a searchTerm. If succeeded, suggestions() signal will be emitted once the suggestions are received. \note To be able to request suggestions, you need to provide a network access manager, which will be used for network operations. \sa requestSearchResults() */ void OpenSearchEngine::setSuggestionsParameters(const QByteArray ¶meters) { m_preparedSuggestionsParameters = parameters; } void OpenSearchEngine::setSuggestionsUrl(const QString &string) { m_preparedSuggestionsUrl = string; } QString OpenSearchEngine::getSuggestionsUrl() { return suggestionsUrl("searchstring").toString().replace(QLatin1String("searchstring"), QLatin1String("%s")); } QByteArray OpenSearchEngine::getSuggestionsParameters() { QStringList parameters; Parameters::const_iterator end = m_suggestionsParameters.constEnd(); Parameters::const_iterator i = m_suggestionsParameters.constBegin(); for (; i != end; ++i) { parameters.append(i->first + QLatin1String("=") + i->second); } QByteArray data = parameters.join(QLatin1String("&")).toUtf8(); return data; } void OpenSearchEngine::requestSuggestions(const QString &searchTerm) { if (searchTerm.isEmpty() || !providesSuggestions()) { return; } Q_ASSERT(m_networkAccessManager); if (!m_networkAccessManager) { return; } if (m_suggestionsReply) { m_suggestionsReply->disconnect(this); m_suggestionsReply->abort(); m_suggestionsReply->deleteLater(); m_suggestionsReply = 0; } Q_ASSERT(m_requestMethods.contains(m_suggestionsMethod)); if (m_suggestionsMethod == QLatin1String("get")) { m_suggestionsReply = m_networkAccessManager->get(QNetworkRequest(suggestionsUrl(searchTerm))); } else { QStringList parameters; Parameters::const_iterator end = m_suggestionsParameters.constEnd(); Parameters::const_iterator i = m_suggestionsParameters.constBegin(); for (; i != end; ++i) { parameters.append(i->first + QLatin1String("=") + i->second); } QByteArray data = parameters.join(QLatin1String("&")).toUtf8(); m_suggestionsReply = m_networkAccessManager->post(QNetworkRequest(suggestionsUrl(searchTerm)), data); } connect(m_suggestionsReply, SIGNAL(finished()), this, SLOT(suggestionsObtained())); } /*! Requests search results on the search engine, for a given \a searchTerm. The default implementation does nothing, to supply your own you need to create your own OpenSearchEngineDelegate subclass and supply it to the engine. Then the function will call the performSearchRequest() method of the delegate, which can then handle the request in a custom way. \sa requestSuggestions(), delegate() */ void OpenSearchEngine::requestSearchResults(const QString &searchTerm) { if (!m_delegate || searchTerm.isEmpty()) { return; } Q_ASSERT(m_requestMethods.contains(m_searchMethod)); QNetworkRequest request(QUrl(searchUrl(searchTerm))); QByteArray data; QNetworkAccessManager::Operation operation = m_requestMethods.value(m_searchMethod); if (operation == QNetworkAccessManager::PostOperation) { QStringList parameters; Parameters::const_iterator end = m_searchParameters.constEnd(); Parameters::const_iterator i = m_searchParameters.constBegin(); for (; i != end; ++i) { parameters.append(i->first + QLatin1String("=") + i->second); } data = parameters.join(QLatin1String("&")).toUtf8(); } m_delegate->performSearchRequest(request, operation, data); } void OpenSearchEngine::suggestionsObtained() { const QByteArray response = m_suggestionsReply->readAll(); m_suggestionsReply->close(); m_suggestionsReply->deleteLater(); m_suggestionsReply = 0; QJsonParseError err; QJsonDocument json = QJsonDocument::fromJson(response, &err); const QVariant res = json.toVariant(); if (err.error != QJsonParseError::NoError || res.type() != QVariant::List) return; const QVariantList list = res.toList(); if (list.size() < 2) return; QStringList out; foreach (const QVariant &v, list.at(1).toList()) out.append(v.toString()); emit suggestions(out); } /*! \property networkAccessManager \brief the network access manager that is used to perform network requests It is required for network operations: loading external images and requesting contextual suggestions. */ QNetworkAccessManager* OpenSearchEngine::networkAccessManager() const { return m_networkAccessManager; } void OpenSearchEngine::setNetworkAccessManager(QNetworkAccessManager* networkAccessManager) { m_networkAccessManager = networkAccessManager; } /*! \property delegate \brief the delegate that is used to perform specific tasks. It can be currently supplied to provide a custom behaviour ofthe requetSearchResults() method. The default implementation does nothing. */ OpenSearchEngineDelegate* OpenSearchEngine::delegate() const { return m_delegate; } void OpenSearchEngine::setDelegate(OpenSearchEngineDelegate* delegate) { m_delegate = delegate; } /*! \fn void OpenSearchEngine::imageChanged() This signal is emitted whenever the image of the engine changes. \sa image(), imageUrl() */ /*! \fn void OpenSearchEngine::suggestions(const QStringList &suggestions) This signal is emitted whenever new contextual suggestions have been provided by the search engine. To request suggestions, use requestSuggestions(). The suggestion set is specified by \a suggestions. \sa requestSuggestions() */ diff --git a/src/lib/opensearch/opensearchengine.h b/src/lib/opensearch/opensearchengine.h index 6fa1dc5a..e32689c3 100644 --- a/src/lib/opensearch/opensearchengine.h +++ b/src/lib/opensearch/opensearchengine.h @@ -1,170 +1,170 @@ /* * Copyright 2009 Jakub Wieczorek * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA */ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef OPENSEARCHENGINE_H #define OPENSEARCHENGINE_H #include "qzcommon.h" #include #include #include #include #include #include class QNetworkReply; class OpenSearchEngineDelegate; -class QUPZILLA_EXPORT OpenSearchEngine : public QObject +class FALKON_EXPORT OpenSearchEngine : public QObject { Q_OBJECT signals: void imageChanged(); void suggestions(const QStringList &suggestions); public: typedef QPair Parameter; typedef QList Parameters; Q_PROPERTY(QString name READ name WRITE setName) Q_PROPERTY(QString description READ description WRITE setDescription) Q_PROPERTY(QString searchUrlTemplate READ searchUrlTemplate WRITE setSearchUrlTemplate) Q_PROPERTY(Parameters searchParameters READ searchParameters WRITE setSearchParameters) Q_PROPERTY(QString searchMethod READ searchMethod WRITE setSearchMethod) Q_PROPERTY(QString suggestionsUrlTemplate READ suggestionsUrlTemplate WRITE setSuggestionsUrlTemplate) Q_PROPERTY(Parameters suggestionsParameters READ suggestionsParameters WRITE setSuggestionsParameters) Q_PROPERTY(QString suggestionsMethod READ suggestionsMethod WRITE setSuggestionsMethod) Q_PROPERTY(bool providesSuggestions READ providesSuggestions) Q_PROPERTY(QString imageUrl READ imageUrl WRITE setImageUrl) Q_PROPERTY(bool valid READ isValid) Q_PROPERTY(QNetworkAccessManager* networkAccessManager READ networkAccessManager WRITE setNetworkAccessManager) OpenSearchEngine(QObject* parent = 0); ~OpenSearchEngine(); QString name() const; void setName(const QString &name); QString description() const; void setDescription(const QString &description); QString searchUrlTemplate() const; void setSearchUrlTemplate(const QString &searchUrl); QUrl searchUrl(const QString &searchTerm) const; QByteArray getPostData(const QString &searchTerm) const; bool providesSuggestions() const; QString suggestionsUrlTemplate() const; void setSuggestionsUrlTemplate(const QString &suggestionsUrl); QUrl suggestionsUrl(const QString &searchTerm) const; Parameters searchParameters() const; void setSearchParameters(const Parameters &searchParameters); Parameters suggestionsParameters() const; void setSuggestionsParameters(const Parameters &suggestionsParameters); QString searchMethod() const; void setSearchMethod(const QString &method); QString suggestionsMethod() const; void setSuggestionsMethod(const QString &method); QString imageUrl() const; void setImageUrl(const QString &url); QImage image() const; void setImage(const QImage &image); bool isValid() const; void setSuggestionsUrl(const QString &string); void setSuggestionsParameters(const QByteArray ¶meters); QString getSuggestionsUrl(); QByteArray getSuggestionsParameters(); QNetworkAccessManager* networkAccessManager() const; void setNetworkAccessManager(QNetworkAccessManager* networkAccessManager); OpenSearchEngineDelegate* delegate() const; void setDelegate(OpenSearchEngineDelegate* delegate); bool operator==(const OpenSearchEngine &other) const; bool operator<(const OpenSearchEngine &other) const; public slots: void requestSuggestions(const QString &searchTerm); void requestSearchResults(const QString &searchTerm); protected: static QString parseTemplate(const QString &searchTerm, const QString &searchTemplate); void loadImage() const; private slots: void imageObtained(); void suggestionsObtained(); private: QString m_name; QString m_description; QString m_imageUrl; QImage m_image; QString m_searchUrlTemplate; QString m_suggestionsUrlTemplate; Parameters m_searchParameters; Parameters m_suggestionsParameters; QString m_searchMethod; QString m_suggestionsMethod; QByteArray m_preparedSuggestionsParameters; QString m_preparedSuggestionsUrl; QMap m_requestMethods; QNetworkAccessManager* m_networkAccessManager; QNetworkReply* m_suggestionsReply; OpenSearchEngineDelegate* m_delegate; }; #endif // OPENSEARCHENGINE_H diff --git a/src/lib/opensearch/opensearchreader.cpp b/src/lib/opensearch/opensearchreader.cpp index e44d5aa8..3e7356b5 100644 --- a/src/lib/opensearch/opensearchreader.cpp +++ b/src/lib/opensearch/opensearchreader.cpp @@ -1,214 +1,214 @@ /* * Copyright 2009 Jakub Wieczorek * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA */ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "opensearchreader.h" #include "opensearchengine.h" #include /*! \class OpenSearchReader \brief A class reading a search engine description from an external source OpenSearchReader is a class that can be used to read search engine descriptions formed using the OpenSearch format. It inherits QXmlStreamReader and thus provides additional functions, such as QXmlStreamReader::error(), QXmlStreamReader::hasError() that can be used to make sure the reading procedure succeeded. For more information see: http://www.opensearch.org/Specifications/OpenSearch/1.1/Draft_4#OpenSearch_description_document \sa OpenSearchEngine, OpenSearchWriter */ /*! Constructs a new reader. \note One instance can be used to read multiple files, one by one. */ OpenSearchReader::OpenSearchReader() : QXmlStreamReader() { } /*! Reads an OpenSearch engine from the \a device and returns an OpenSearchEngine object, filled in with all the data that has been retrieved from the document. If the \a device is closed, it will be opened. To make sure if the procedure succeeded, check QXmlStreamReader::error(). \return a new constructed OpenSearchEngine object \note The function returns an object of the OpenSearchEngine class even if the document is bad formed or doesn't conform to the specification. It needs to be manually deleted afterwards, if intended. \note The lifetime of the returned OpenSearchEngine object is up to the user. The object should be deleted once it is not used anymore to avoid memory leaks. */ OpenSearchEngine* OpenSearchReader::read(QIODevice* device) { clear(); if (!device->isOpen()) { device->open(QIODevice::ReadOnly); } setDevice(device); return read(); } OpenSearchEngine* OpenSearchReader::read() { OpenSearchEngine* engine = new OpenSearchEngine(); m_searchXml = device()->peek(1024 * 5); if (!m_searchXml.contains(QLatin1String("http://a9.com/-/spec/opensearch/1.1/")) && !m_searchXml.contains(QLatin1String("http://www.mozilla.org/2006/browser/search/")) ) { raiseError(QObject::tr("The file is not an OpenSearch 1.1 file.")); return engine; } // It just skips the XML declaration // The parsing code bellow for some reason doesn't like it -,- int index = m_searchXml.indexOf(QLatin1String(" 0) { int end = m_searchXml.indexOf(QLatin1String("?>"), index); if (end > 0) { device()->read(end + 2); } } while (!isStartElement() && !atEnd()) { readNext(); } while (!atEnd()) { readNext(); if (!isStartElement()) { continue; } if (name() == QLatin1String("ShortName") || name() == QLatin1String("os:ShortName")) { engine->setName(readElementText()); } else if (name() == QLatin1String("Description") || name() == QLatin1String("os:Description")) { engine->setDescription(readElementText()); } else if (name() == QLatin1String("Url") || name() == QLatin1String("os:Url")) { QString type = attributes().value(QLatin1String("type")).toString(); QString url = attributes().value(QLatin1String("template")).toString(); QString method = attributes().value(QLatin1String("method")).toString(); if (type == QLatin1String("application/x-suggestions+json") && !engine->suggestionsUrlTemplate().isEmpty() ) { continue; } if ((type.isEmpty() || type == QLatin1String("text/html") || type == QLatin1String("application/xhtml+xml")) && !engine->searchUrlTemplate().isEmpty() ) { continue; } if (url.isEmpty()) { continue; } QList parameters; readNext(); while (!isEndElement() || (name() != QLatin1String("Url") && name() != QLatin1String("os:Url"))) { if (!isStartElement() || (name() != QLatin1String("Param") && name() != QLatin1String("Parameter") && name() != QLatin1String("os:Param") && name() != QLatin1String("os:Parameter")) ) { readNext(); continue; } QString key = attributes().value(QLatin1String("name")).toString(); QString value = attributes().value(QLatin1String("value")).toString(); if (!key.isEmpty() && !value.isEmpty()) { parameters.append(OpenSearchEngine::Parameter(key, value)); } while (!isEndElement()) { readNext(); } } if (type == QLatin1String("application/x-suggestions+json")) { engine->setSuggestionsUrlTemplate(url); engine->setSuggestionsParameters(parameters); engine->setSuggestionsMethod(method); } else if (type.isEmpty() || type == QLatin1String("text/html") || type == QLatin1String("application/xhtml+xml")) { engine->setSearchUrlTemplate(url); engine->setSearchParameters(parameters); engine->setSearchMethod(method); } } else if (name() == QLatin1String("Image") || name() == QLatin1String("os:Image")) { engine->setImageUrl(readElementText()); } if (!engine->name().isEmpty() && !engine->description().isEmpty() && !engine->suggestionsUrlTemplate().isEmpty() && !engine->searchUrlTemplate().isEmpty() && !engine->imageUrl().isEmpty() ) { break; } } return engine; } diff --git a/src/lib/opensearch/opensearchreader.h b/src/lib/opensearch/opensearchreader.h index 8378ca68..9d89f596 100644 --- a/src/lib/opensearch/opensearchreader.h +++ b/src/lib/opensearch/opensearchreader.h @@ -1,59 +1,59 @@ /* * Copyright 2009 Jakub Wieczorek * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA */ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef OPENSEARCHREADER_H #define OPENSEARCHREADER_H #include "qzcommon.h" #include class OpenSearchEngine; -class QUPZILLA_EXPORT OpenSearchReader : public QXmlStreamReader +class FALKON_EXPORT OpenSearchReader : public QXmlStreamReader { public: OpenSearchReader(); OpenSearchEngine* read(QIODevice* device); private: OpenSearchEngine* read(); QString m_searchXml; }; #endif // OPENSEARCHREADER_H diff --git a/src/lib/opensearch/searchenginesdialog.cpp b/src/lib/opensearch/searchenginesdialog.cpp index ec1c88df..ba13ae7a 100644 --- a/src/lib/opensearch/searchenginesdialog.cpp +++ b/src/lib/opensearch/searchenginesdialog.cpp @@ -1,283 +1,283 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "searchenginesdialog.h" #include "ui_searchenginesdialog.h" #include "editsearchengine.h" #include "mainapplication.h" #include "removeitemfocusdelegate.h" #include SearchEnginesDialog::SearchEnginesDialog(QWidget* parent) : QDialog(parent) , ui(new Ui::SearchEnginesDialog) , m_manager(mApp->searchEnginesManager()) { setAttribute(Qt::WA_DeleteOnClose); ui->setupUi(this); connect(ui->add, SIGNAL(clicked()), this, SLOT(addEngine())); connect(ui->remove, SIGNAL(clicked()), this, SLOT(removeEngine())); connect(ui->edit, SIGNAL(clicked()), this, SLOT(editEngine())); connect(ui->setAsDefault, SIGNAL(clicked()), this, SLOT(setDefaultEngine())); connect(ui->defaults, SIGNAL(clicked()), this, SLOT(defaults())); connect(ui->moveUp, SIGNAL(clicked()), this, SLOT(moveUp())); connect(ui->moveDown, SIGNAL(clicked()), this, SLOT(moveDown())); connect(ui->treeWidget, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)), this, SLOT(editEngine())); ui->treeWidget->setItemDelegate(new RemoveItemFocusDelegate(ui->treeWidget)); ui->treeWidget->sortByColumn(-1); reloadEngines(); } void SearchEnginesDialog::addEngine() { EditSearchEngine dialog(tr("Add Search Engine"), this); dialog.hideIconLabels(); if (dialog.exec() != QDialog::Accepted) { return; } SearchEngine engine; engine.name = dialog.name(); engine.url = dialog.url(); engine.postData = dialog.postData().toUtf8(); engine.shortcut = dialog.shortcut(); engine.icon = SearchEnginesManager::iconForSearchEngine(QUrl::fromEncoded(dialog.url().toUtf8())); if (engine.name.isEmpty() || engine.url.isEmpty()) { return; } QTreeWidgetItem* item = new QTreeWidgetItem(); setEngine(item, engine); changeItemToDefault(item, false); item->setIcon(0, engine.icon); item->setText(1, engine.shortcut); ui->treeWidget->addTopLevelItem(item); } void SearchEnginesDialog::removeEngine() { QTreeWidgetItem* item = ui->treeWidget->currentItem(); if (!item || ui->treeWidget->topLevelItemCount() == 1) { return; } if (isDefaultEngine(item)) { SearchEngine en = getEngine(item); QMessageBox::warning(this, tr("Remove Engine"), tr("You can't remove the default search engine.
" "Set a different engine as default before removing %1.").arg(en.name)); } else { delete item; } } void SearchEnginesDialog::editEngine() { QTreeWidgetItem* item = ui->treeWidget->currentItem(); if (!item) { return; } SearchEngine engine = getEngine(item); EditSearchEngine dialog(tr("Edit Search Engine"), this); dialog.setName(engine.name); dialog.setUrl(engine.url); dialog.setPostData(engine.postData); dialog.setShortcut(engine.shortcut); dialog.setIcon(engine.icon); if (dialog.exec() != QDialog::Accepted) { return; } engine.name = dialog.name(); engine.url = dialog.url(); engine.postData = dialog.postData().toUtf8(); engine.shortcut = dialog.shortcut(); engine.icon = dialog.icon(); if (engine.name.isEmpty() || engine.url.isEmpty()) { return; } setEngine(item, engine); changeItemToDefault(item, isDefaultEngine(item)); item->setIcon(0, engine.icon); item->setText(1, engine.shortcut); } void SearchEnginesDialog::setDefaultEngine() { QTreeWidgetItem* item = ui->treeWidget->currentItem(); if (!item) { return; } for (int j = 0; j < ui->treeWidget->topLevelItemCount(); ++j) { QTreeWidgetItem* i = ui->treeWidget->topLevelItem(j); if (isDefaultEngine(i)) { if (i == item) { return; } changeItemToDefault(i, false); break; } } changeItemToDefault(item, true); } void SearchEnginesDialog::defaults() { m_manager->restoreDefaults(); reloadEngines(); } bool SearchEnginesDialog::isDefaultEngine(QTreeWidgetItem* item) { return item->data(0, DefaultRole).toBool(); } SearchEngine SearchEnginesDialog::getEngine(QTreeWidgetItem* item) { return item->data(0, EngineRole).value(); } void SearchEnginesDialog::setEngine(QTreeWidgetItem* item, SearchEngine engine) { QVariant v; v.setValue(engine); item->setData(0, EngineRole, v); item->setText(0, engine.name); } void SearchEnginesDialog::changeItemToDefault(QTreeWidgetItem* item, bool isDefault) { QFont font = item->font(0); font.setBold(isDefault); item->setFont(0, font); item->setFont(1, font); item->setData(0, DefaultRole, isDefault); } void SearchEnginesDialog::moveUp() { QTreeWidgetItem* currentItem = ui->treeWidget->currentItem(); int index = ui->treeWidget->indexOfTopLevelItem(currentItem); if (!currentItem || index == 0) { return; } ui->treeWidget->takeTopLevelItem(index); ui->treeWidget->insertTopLevelItem(index - 1, currentItem); ui->treeWidget->setCurrentItem(currentItem); } void SearchEnginesDialog::moveDown() { QTreeWidgetItem* currentItem = ui->treeWidget->currentItem(); int index = ui->treeWidget->indexOfTopLevelItem(currentItem); if (!currentItem || !ui->treeWidget->itemBelow(currentItem)) { return; } ui->treeWidget->takeTopLevelItem(index); ui->treeWidget->insertTopLevelItem(index + 1, currentItem); ui->treeWidget->setCurrentItem(currentItem); } void SearchEnginesDialog::reloadEngines() { ui->treeWidget->clear(); const SearchEngine defaultEngine = mApp->searchEnginesManager()->defaultEngine(); foreach (const SearchEngine &en, m_manager->allEngines()) { QTreeWidgetItem* item = new QTreeWidgetItem(); setEngine(item, en); changeItemToDefault(item, en == defaultEngine); item->setIcon(0, en.icon); item->setText(1, en.shortcut); ui->treeWidget->addTopLevelItem(item); } } void SearchEnginesDialog::showEvent(QShowEvent *e) { QDialog::showEvent(e); resizeViewHeader(); } void SearchEnginesDialog::resizeEvent(QResizeEvent *e) { QDialog::resizeEvent(e); resizeViewHeader(); } void SearchEnginesDialog::resizeViewHeader() { const int headerWidth = ui->treeWidget->header()->width(); ui->treeWidget->header()->resizeSection(0, headerWidth - headerWidth / 4); } void SearchEnginesDialog::accept() { if (ui->treeWidget->topLevelItemCount() < 1) { return; } QVector allEngines; for (int i = 0; i < ui->treeWidget->topLevelItemCount(); i++) { QTreeWidgetItem* item = ui->treeWidget->topLevelItem(i); if (!item) { continue; } SearchEngine engine = getEngine(item); allEngines.append(engine); if (isDefaultEngine(item)) { m_manager->setDefaultEngine(engine); } } m_manager->setAllEngines(allEngines); QDialog::accept(); } SearchEnginesDialog::~SearchEnginesDialog() { delete ui; } diff --git a/src/lib/opensearch/searchenginesdialog.h b/src/lib/opensearch/searchenginesdialog.h index 413dc822..4bb82bcf 100644 --- a/src/lib/opensearch/searchenginesdialog.h +++ b/src/lib/opensearch/searchenginesdialog.h @@ -1,74 +1,74 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef SEARCHENGINESDIALOG_H #define SEARCHENGINESDIALOG_H #include "qzcommon.h" #include "searchenginesmanager.h" #include class QTreeWidgetItem; namespace Ui { class SearchEnginesDialog; } -class QUPZILLA_EXPORT SearchEnginesDialog : public QDialog +class FALKON_EXPORT SearchEnginesDialog : public QDialog { Q_OBJECT public: explicit SearchEnginesDialog(QWidget* parent = 0); ~SearchEnginesDialog(); public slots: void accept(); private slots: void addEngine(); void removeEngine(); void editEngine(); void setDefaultEngine(); void moveUp(); void moveDown(); void defaults(); private: enum TreeRole { EngineRole = Qt::UserRole, DefaultRole = Qt::UserRole + 1 }; bool isDefaultEngine(QTreeWidgetItem* item); SearchEngine getEngine(QTreeWidgetItem* item); void setEngine(QTreeWidgetItem* item, SearchEngine engine); void changeItemToDefault(QTreeWidgetItem* item, bool isDefault); void reloadEngines(); void showEvent(QShowEvent *e) override; void resizeEvent(QResizeEvent *e) override; void resizeViewHeader(); Ui::SearchEnginesDialog* ui; SearchEnginesManager* m_manager; }; #endif // SEARCHENGINESDIALOG_H diff --git a/src/lib/opensearch/searchenginesmanager.cpp b/src/lib/opensearch/searchenginesmanager.cpp index de833eec..94b86e2f 100644 --- a/src/lib/opensearch/searchenginesmanager.cpp +++ b/src/lib/opensearch/searchenginesmanager.cpp @@ -1,511 +1,511 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "searchenginesmanager.h" #include "searchenginesdialog.h" #include "editsearchengine.h" #include "networkmanager.h" #include "iconprovider.h" #include "mainapplication.h" #include "opensearchreader.h" #include "opensearchengine.h" #include "settings.h" #include "qzsettings.h" #include "webview.h" #include #include #include #include #include #define ENSURE_LOADED if (!m_settingsLoaded) loadSettings(); static QIcon iconFromBase64(const QByteArray &data) { QIcon image; QByteArray bArray = QByteArray::fromBase64(data); QBuffer buffer(&bArray); buffer.open(QIODevice::ReadOnly); QDataStream in(&buffer); in >> image; buffer.close(); if (!image.isNull()) { return image; } return IconProvider::emptyWebIcon(); } static QByteArray iconToBase64(const QIcon &icon) { QByteArray bArray; QBuffer buffer(&bArray); buffer.open(QIODevice::WriteOnly); QDataStream out(&buffer); out << icon; buffer.close(); return bArray.toBase64(); } SearchEnginesManager::SearchEnginesManager(QObject* parent) : QObject(parent) , m_settingsLoaded(false) , m_saveScheduled(false) { Settings settings; settings.beginGroup("SearchEngines"); m_startingEngineName = settings.value("activeEngine", "DuckDuckGo").toString(); m_defaultEngineName = settings.value("DefaultEngine", "DuckDuckGo").toString(); settings.endGroup(); connect(this, SIGNAL(enginesChanged()), this, SLOT(scheduleSave())); } void SearchEnginesManager::loadSettings() { m_settingsLoaded = true; QSqlQuery query; query.exec("SELECT name, icon, url, shortcut, suggestionsUrl, suggestionsParameters, postData FROM search_engines"); while (query.next()) { Engine en; en.name = query.value(0).toString(); en.icon = iconFromBase64(query.value(1).toByteArray()); en.url = query.value(2).toString(); en.shortcut = query.value(3).toString(); en.suggestionsUrl = query.value(4).toString(); en.suggestionsParameters = query.value(5).toByteArray(); en.postData = query.value(6).toByteArray(); m_allEngines.append(en); if (en.name == m_defaultEngineName) { m_defaultEngine = en; } } if (m_allEngines.isEmpty()) { restoreDefaults(); } if (m_defaultEngine.name.isEmpty()) { m_defaultEngine = m_allEngines[0]; } } SearchEngine SearchEnginesManager::engineForShortcut(const QString &shortcut) { Engine returnEngine; if (shortcut.isEmpty()) { return returnEngine; } foreach (const Engine &en, m_allEngines) { if (en.shortcut == shortcut) { returnEngine = en; break; } } return returnEngine; } LoadRequest SearchEnginesManager::searchResult(const Engine &engine, const QString &string) { ENSURE_LOADED; // GET search engine if (engine.postData.isEmpty()) { QByteArray url = engine.url.toUtf8(); url.replace(QLatin1String("%s"), QUrl::toPercentEncoding(string)); return LoadRequest(QUrl::fromEncoded(url)); } // POST search engine QByteArray data = engine.postData; data.replace("%s", QUrl::toPercentEncoding(string)); return LoadRequest(QUrl::fromEncoded(engine.url.toUtf8()), LoadRequest::PostOperation, data); } LoadRequest SearchEnginesManager::searchResult(const QString &string) { ENSURE_LOADED; const Engine en = qzSettings->searchWithDefaultEngine ? m_defaultEngine : m_activeEngine; return searchResult(en, string); } void SearchEnginesManager::restoreDefaults() { Engine duck; duck.name = "DuckDuckGo"; duck.icon = QIcon(":/icons/sites/duck.png"); - duck.url = "https://duckduckgo.com/?q=%s&t=qupzilla"; + duck.url = "https://duckduckgo.com/?q=%s&t=falkon"; duck.shortcut = "d"; duck.suggestionsUrl = "https://ac.duckduckgo.com/ac/?q=%s&type=list"; Engine sp; sp.name = "StartPage"; sp.icon = QIcon(":/icons/sites/startpage.png"); sp.url = "https://startpage.com/do/search"; sp.postData = "query=%s&cat=web&language=english"; sp.shortcut = "sp"; sp.suggestionsUrl = "https://startpage.com/cgi-bin/csuggest?output=json&lang=english&query=%s"; Engine wiki; wiki.name = "Wikipedia (en)"; wiki.icon = QIcon(":/icons/sites/wikipedia.png"); wiki.url = "https://en.wikipedia.org/wiki/Special:Search?search=%s&fulltext=Search"; wiki.shortcut = "w"; wiki.suggestionsUrl = "https://en.wikipedia.org/w/api.php?action=opensearch&search=%s&namespace=0"; Engine google; google.name = "Google"; google.icon = QIcon(":icons/sites/google.png"); - google.url = "https://www.google.com/search?client=qupzilla&q=%s"; + google.url = "https://www.google.com/search?client=falkon&q=%s"; google.shortcut = "g"; google.suggestionsUrl = "https://suggestqueries.google.com/complete/search?output=firefox&q=%s"; addEngine(duck); addEngine(sp); addEngine(wiki); addEngine(google); m_defaultEngine = duck; emit enginesChanged(); } // static QIcon SearchEnginesManager::iconForSearchEngine(const QUrl &url) { QIcon ic = IconProvider::iconForDomain(url); if (ic.isNull()) { ic = QIcon::fromTheme(QSL("edit-find"), QIcon(QSL(":icons/menu/search-icon.svg"))); } return ic; } void SearchEnginesManager::engineChangedImage() { OpenSearchEngine* engine = qobject_cast(sender()); if (!engine) { return; } foreach (Engine e, m_allEngines) { if (e.name == engine->name() && e.url.contains(engine->searchUrl("%s").toString()) && !engine->image().isNull() ) { int index = m_allEngines.indexOf(e); if (index != -1) { m_allEngines[index].icon = QIcon(QPixmap::fromImage(engine->image())); emit enginesChanged(); delete engine; break; } } } } void SearchEnginesManager::editEngine(const Engine &before, const Engine &after) { removeEngine(before); addEngine(after); } void SearchEnginesManager::addEngine(const Engine &engine) { ENSURE_LOADED; if (m_allEngines.contains(engine)) { return; } m_allEngines.append(engine); emit enginesChanged(); } void SearchEnginesManager::addEngineFromForm(const QVariantMap &formData, WebView *view) { if (formData.isEmpty()) return; const QString method = formData.value(QSL("method")).toString(); bool isPost = method == QL1S("post"); QUrl actionUrl = formData.value(QSL("action")).toUrl(); if (actionUrl.isRelative()) { actionUrl = view->url().resolved(actionUrl); } QUrl parameterUrl = actionUrl; if (isPost) { parameterUrl = QUrl("http://foo.bar"); } const QString &inputName = formData.value(QSL("inputName")).toString(); QUrlQuery query(parameterUrl); query.addQueryItem(inputName, QSL("SEARCH")); const QVariantList &inputs = formData.value(QSL("inputs")).toList(); foreach (const QVariant &pair, inputs) { const QVariantList &list = pair.toList(); if (list.size() != 2) continue; const QString &name = list.at(0).toString(); const QString &value = list.at(1).toString(); if (name == inputName || name.isEmpty() || value.isEmpty()) continue; query.addQueryItem(name, value); } parameterUrl.setQuery(query); if (!isPost) { actionUrl = parameterUrl; } SearchEngine engine; engine.name = view->title(); engine.icon = view->icon(); engine.url = actionUrl.toEncoded(); if (isPost) { QByteArray data = parameterUrl.toEncoded(QUrl::RemoveScheme); engine.postData = data.contains('?') ? data.mid(data.lastIndexOf('?') + 1) : QByteArray(); engine.postData.replace((inputName + QL1S("=SEARCH")).toUtf8(), (inputName + QL1S("=%s")).toUtf8()); } else { engine.url.replace(inputName + QL1S("=SEARCH"), inputName + QL1S("=%s")); } EditSearchEngine dialog(SearchEnginesDialog::tr("Add Search Engine"), view); dialog.setName(engine.name); dialog.setIcon(engine.icon); dialog.setUrl(engine.url); dialog.setPostData(engine.postData); if (dialog.exec() != QDialog::Accepted) { return; } engine.name = dialog.name(); engine.icon = dialog.icon(); engine.url = dialog.url(); engine.shortcut = dialog.shortcut(); engine.postData = dialog.postData().toUtf8(); if (engine.name.isEmpty() || engine.url.isEmpty()) { return; } addEngine(engine); } void SearchEnginesManager::addEngine(OpenSearchEngine* engine) { ENSURE_LOADED; Engine en; en.name = engine->name(); en.url = engine->searchUrl("searchstring").toString().replace(QLatin1String("searchstring"), QLatin1String("%s")); if (engine->image().isNull()) { en.icon = iconForSearchEngine(engine->searchUrl(QString())); } else { en.icon = QIcon(QPixmap::fromImage(engine->image())); } en.suggestionsUrl = engine->getSuggestionsUrl(); en.suggestionsParameters = engine->getSuggestionsParameters(); en.postData = engine->getPostData("searchstring").replace("searchstring", "%s"); addEngine(en); connect(engine, SIGNAL(imageChanged()), this, SLOT(engineChangedImage())); } void SearchEnginesManager::addEngine(const QUrl &url) { ENSURE_LOADED; if (!url.isValid()) { return; } qApp->setOverrideCursor(Qt::WaitCursor); QNetworkReply* reply = mApp->networkManager()->get(QNetworkRequest(url)); reply->setParent(this); connect(reply, SIGNAL(finished()), this, SLOT(replyFinished())); } void SearchEnginesManager::replyFinished() { qApp->restoreOverrideCursor(); QNetworkReply* reply = qobject_cast(sender()); if (!reply) { return; } if (reply->error() != QNetworkReply::NoError) { reply->close(); reply->deleteLater(); return; } OpenSearchReader reader; OpenSearchEngine* engine = reader.read(reply); engine->setNetworkAccessManager(mApp->networkManager()); reply->close(); reply->deleteLater(); if (checkEngine(engine)) { addEngine(engine); QMessageBox::information(0, tr("Search Engine Added"), tr("Search Engine \"%1\" has been successfully added.").arg(engine->name())); } } bool SearchEnginesManager::checkEngine(OpenSearchEngine* engine) { if (!engine->isValid()) { QString errorString = tr("Search Engine is not valid!"); QMessageBox::warning(0, tr("Error"), tr("Error while adding Search Engine
Error Message: %1").arg(errorString)); return false; } return true; } void SearchEnginesManager::setActiveEngine(const Engine &engine) { ENSURE_LOADED; if (!m_allEngines.contains(engine)) { return; } m_activeEngine = engine; emit activeEngineChanged(); } void SearchEnginesManager::setDefaultEngine(const SearchEnginesManager::Engine &engine) { ENSURE_LOADED; if (!m_allEngines.contains(engine)) { return; } m_defaultEngine = engine; emit defaultEngineChanged(); } void SearchEnginesManager::removeEngine(const Engine &engine) { ENSURE_LOADED; int index = m_allEngines.indexOf(engine); if (index < 0) { return; } QSqlQuery query; query.prepare("DELETE FROM search_engines WHERE name=? AND url=?"); query.bindValue(0, engine.name); query.bindValue(1, engine.url); query.exec(); m_allEngines.remove(index); emit enginesChanged(); } void SearchEnginesManager::setAllEngines(const QVector &engines) { ENSURE_LOADED; m_allEngines = engines; emit enginesChanged(); } QVector SearchEnginesManager::allEngines() { ENSURE_LOADED; return m_allEngines; } void SearchEnginesManager::saveSettings() { Settings settings; settings.beginGroup("SearchEngines"); settings.setValue("activeEngine", m_activeEngine.name); settings.setValue("DefaultEngine", m_defaultEngine.name); settings.endGroup(); if (!m_saveScheduled) { return; } // Well, this is not the best implementation to do as this is taking some time. // Actually, it is delaying the quit of app for about a 1 sec on my machine with only // 5 engines. Another problem is that deleting rows without VACUUM isn't actually freeing // space in database. // // But as long as user is not playing with search engines every run it is acceptable. QSqlQuery query; query.exec("DELETE FROM search_engines"); foreach (const Engine &en, m_allEngines) { query.prepare("INSERT INTO search_engines (name, icon, url, shortcut, suggestionsUrl, suggestionsParameters, postData) VALUES (?, ?, ?, ?, ?, ?, ?)"); query.addBindValue(en.name); query.addBindValue(iconToBase64(en.icon)); query.addBindValue(en.url); query.addBindValue(en.shortcut); query.addBindValue(en.suggestionsUrl); query.addBindValue(en.suggestionsParameters); query.addBindValue(en.postData); query.exec(); } } diff --git a/src/lib/opensearch/searchenginesmanager.h b/src/lib/opensearch/searchenginesmanager.h index 123037d1..90286729 100644 --- a/src/lib/opensearch/searchenginesmanager.h +++ b/src/lib/opensearch/searchenginesmanager.h @@ -1,124 +1,124 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef SEARCHENGINESMANAGER_H #define SEARCHENGINESMANAGER_H #include #include #include #include #include "qzcommon.h" #include "opensearchengine.h" class QWebElement; class WebView; class LoadRequest; -class QUPZILLA_EXPORT SearchEnginesManager : public QObject +class FALKON_EXPORT SearchEnginesManager : public QObject { Q_OBJECT public: explicit SearchEnginesManager(QObject* parent = 0); struct Engine { QString name; QIcon icon; QString url; QString shortcut; QString suggestionsUrl; QByteArray suggestionsParameters; QByteArray postData; bool operator==(const Engine &other) const { return (this->name == other.name && this->url == other.url && this->suggestionsUrl == other.suggestionsUrl && this->shortcut == other.shortcut); } }; LoadRequest searchResult(const Engine &engine, const QString &string); LoadRequest searchResult(const QString &string); void addEngine(const QUrl &url); void addEngine(OpenSearchEngine* engine); void addEngine(const Engine &engine); void addEngineFromForm(const QVariantMap &formData, WebView *view); void removeEngine(const Engine &engine); void setActiveEngine(const Engine &engine); Engine activeEngine() const { return m_activeEngine; } void setDefaultEngine(const Engine &engine); Engine defaultEngine() const { return m_defaultEngine; } void editEngine(const Engine &before, const Engine &after); Engine engineForShortcut(const QString &shortcut); void setAllEngines(const QVector &engines); QVector allEngines(); QString startingEngineName() { return m_startingEngineName; } void saveSettings(); void restoreDefaults(); static QIcon iconForSearchEngine(const QUrl &url); signals: void enginesChanged(); void activeEngineChanged(); void defaultEngineChanged(); public slots: private slots: void engineChangedImage(); void replyFinished(); void scheduleSave() { m_saveScheduled = true; } private: bool checkEngine(OpenSearchEngine* engine); void loadSettings(); bool m_settingsLoaded; bool m_saveScheduled; QString m_startingEngineName; QString m_defaultEngineName; QVector m_allEngines; Engine m_activeEngine; Engine m_defaultEngine; }; typedef SearchEnginesManager::Engine SearchEngine; // Hint to QVector to use std::realloc on item moving Q_DECLARE_TYPEINFO(SearchEngine, Q_MOVABLE_TYPE); Q_DECLARE_METATYPE(SearchEngine) #endif // SEARCHENGINESMANAGER_H diff --git a/src/lib/other/aboutdialog.cpp b/src/lib/other/aboutdialog.cpp index 747b85e9..81324924 100644 --- a/src/lib/other/aboutdialog.cpp +++ b/src/lib/other/aboutdialog.cpp @@ -1,155 +1,155 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "aboutdialog.h" #include "ui_aboutdialog.h" #include "browserwindow.h" #include "mainapplication.h" #include "tabbedwebview.h" #include "webpage.h" #include "useragentmanager.h" #include #include #ifdef Q_OS_WIN #include #endif AboutDialog::AboutDialog(QWidget* parent) : QDialog(parent) , ui(new Ui::AboutDialog) , m_showingAuthors(false) { setAttribute(Qt::WA_DeleteOnClose); ui->setupUi(this); ui->label->setPixmap(QIcon(QSL(":icons/other/about.png")).pixmap(300, 130)); #ifdef Q_OS_WIN if (QtWin::isCompositionEnabled()) { QtWin::extendFrameIntoClientArea(this, -1, -1, -1, -1); ui->verticalLayout->setContentsMargins(0, 0, 0, 0); } #endif connect(ui->buttonBox, SIGNAL(clicked(QAbstractButton*)), this, SLOT(close())); connect(ui->authorsButton, SIGNAL(clicked()), this, SLOT(buttonClicked())); showAbout(); #ifdef Q_OS_WIN resize(300, height()); #endif } void AboutDialog::buttonClicked() { if (m_showingAuthors) showAbout(); else showAuthors(); } void AboutDialog::showAbout() { m_showingAuthors = false; ui->authorsButton->setText(tr("Authors and Contributors")); if (m_aboutHtml.isEmpty()) { m_aboutHtml += "
"; m_aboutHtml += tr("

Application version %1
").arg( #ifdef GIT_REVISION QString("%1 (%2)").arg(Qz::VERSION, GIT_REVISION) #else Qz::VERSION #endif ); m_aboutHtml += tr("QtWebEngine version %1

").arg(qVersion()); m_aboutHtml += QString("

© %1 %2
").arg(Qz::COPYRIGHT, Qz::AUTHOR); m_aboutHtml += QString("%1

").arg(Qz::WWWADDRESS); m_aboutHtml += "

" + mApp->userAgentManager()->defaultUserAgent() + "

"; m_aboutHtml += "
"; } ui->textBrowser->setHtml(m_aboutHtml); } void AboutDialog::showAuthors() { m_showingAuthors = true; - ui->authorsButton->setText(tr("< About QupZilla")); + ui->authorsButton->setText(tr("< About Falkon")); if (m_authorsHtml.isEmpty()) { m_authorsHtml += "
"; m_authorsHtml += tr("

Main developer:
%1 <%2>

").arg(Qz::AUTHOR, "nowrep@gmail.com"); m_authorsHtml += tr("

Contributors:
%1

").arg( QString::fromUtf8("Mladen Pejaković
" "Seyyed Razi Alavizadeh
" "Adrien Vigneron
" "Elio Qoshi
" "Alexander Samilov
" "Franz Fellner
" "Bryan M Dunsmore
" "Mariusz Fik
" "Daniele Cocca") ); m_authorsHtml += tr("

Translators:
%1

").arg( QString::fromUtf8("Heimen Stoffels
" "Peter Vacula
" "Jonathan Hooverman
" "Federico Fabiani
" "Francesco Marinucci
" "Jorge Sevilla
" "Ștefan Comănescu
" "Michał Szymanowski
" "Mariusz Fik
" "Jérôme Giry
" "Nicolas Ourceau
" "Vasilis Tsivikis
" "Rustam Salakhutdinov
" "Oleg Brezhnev
" "Sérgio Marques
" "Alexandre Carvalho
" "Mladen Pejaković
" "Unink-Lio
" "Wu Cheng-Hong
" "Widya Walesa
" "Beqa Arabuli
" "Daiki Noda
" "Gábor Oberle
" "Piccoro McKay Lenz
" "Stanislav Kuznietsov
" "Seyyed Razi Alavizadeh
" "Guillem Prats
" "Clara Villalba
" "Yu Hai
" "Muhammad Fawwaz Orabi
" "Lasso Kante
" "Kizito Birabwa
" "Juan Carlos Sánchez
" "Xabier Aramendi
" "Ferhat AYDIN") ); m_authorsHtml += "
"; } ui->textBrowser->setHtml(m_authorsHtml); } AboutDialog::~AboutDialog() { delete ui; } diff --git a/src/lib/other/aboutdialog.h b/src/lib/other/aboutdialog.h index acab69e6..6e4b8d5d 100644 --- a/src/lib/other/aboutdialog.h +++ b/src/lib/other/aboutdialog.h @@ -1,51 +1,51 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef ABOUTDIALOG_H #define ABOUTDIALOG_H #include #include "qzcommon.h" namespace Ui { class AboutDialog; } -class QUPZILLA_EXPORT AboutDialog : public QDialog +class FALKON_EXPORT AboutDialog : public QDialog { Q_OBJECT public: explicit AboutDialog(QWidget* parent = 0); ~AboutDialog(); private slots: void showAbout(); void showAuthors(); void buttonClicked(); private: Ui::AboutDialog* ui; QString m_aboutHtml; QString m_authorsHtml; bool m_showingAuthors; }; #endif // ABOUTDIALOG_H diff --git a/src/lib/other/aboutdialog.ui b/src/lib/other/aboutdialog.ui index e2520edd..b912bb97 100644 --- a/src/lib/other/aboutdialog.ui +++ b/src/lib/other/aboutdialog.ui @@ -1,107 +1,107 @@ AboutDialog 0 0 446 382 - About QupZilla + About Falkon 0 Qt::AlignCenter Qt::ScrollBarAlwaysOff true true 5 0 0 Authors Qt::Horizontal QDialogButtonBox::Close buttonBox accepted() AboutDialog accept() 248 254 157 274 buttonBox rejected() AboutDialog reject() 316 260 286 274 diff --git a/src/lib/other/browsinglibrary.cpp b/src/lib/other/browsinglibrary.cpp index 2c61ce7b..0ad6d971 100644 --- a/src/lib/other/browsinglibrary.cpp +++ b/src/lib/other/browsinglibrary.cpp @@ -1,136 +1,136 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "browsinglibrary.h" #include "ui_browsinglibrary.h" #include "bookmarksimport/bookmarksimportdialog.h" #include "bookmarksexport/bookmarksexportdialog.h" #include "historymanager.h" #include "bookmarksmanager.h" #include "mainapplication.h" #include "qztools.h" #include "settings.h" #include #include BrowsingLibrary::BrowsingLibrary(BrowserWindow* window, QWidget* parent) : QWidget(parent) , ui(new Ui::BrowsingLibrary) , m_historyManager(new HistoryManager(window)) , m_bookmarksManager(new BookmarksManager(window)) { ui->setupUi(this); Settings settings; settings.beginGroup("BrowsingLibrary"); resize(settings.value("size", QSize(760, 470)).toSize()); m_historyManager->restoreState(settings.value("historyState", QByteArray()).toByteArray()); settings.endGroup(); QzTools::centerWidgetOnScreen(this); QIcon historyIcon; historyIcon.addFile(QSL(":/icons/other/bighistory.svg"), QSize(), QIcon::Normal); historyIcon.addFile(QSL(":/icons/other/bighistory-selected.svg"), QSize(), QIcon::Selected); QIcon bookmarksIcon; bookmarksIcon.addFile(QSL(":/icons/other/bigstar.svg"), QSize(), QIcon::Normal); bookmarksIcon.addFile(QSL(":/icons/other/bigstar-selected.svg"), QSize(), QIcon::Selected); ui->tabs->AddTab(m_historyManager, historyIcon, tr("History")); ui->tabs->AddTab(m_bookmarksManager, bookmarksIcon, tr("Bookmarks")); ui->tabs->SetMode(FancyTabWidget::Mode_LargeSidebar); ui->tabs->setFocus(); QMenu* m = new QMenu(this); m->addAction(tr("Import Bookmarks..."), this, SLOT(importBookmarks())); m->addAction(tr("Export Bookmarks..."), this, SLOT(exportBookmarks())); ui->importExport->setMenu(m); connect(ui->tabs, &FancyTabWidget::CurrentChanged, ui->searchLine, &QLineEdit::clear); connect(ui->searchLine, SIGNAL(textChanged(QString)), this, SLOT(search())); QzTools::setWmClass("Browsing Library", this); } void BrowsingLibrary::search() { if (ui->tabs->current_index() == 0) { m_historyManager->search(ui->searchLine->text()); } else { m_bookmarksManager->search(ui->searchLine->text()); } } void BrowsingLibrary::importBookmarks() { BookmarksImportDialog* d = new BookmarksImportDialog(this); d->open(); } void BrowsingLibrary::exportBookmarks() { BookmarksExportDialog* d = new BookmarksExportDialog(this); d->open(); } void BrowsingLibrary::showHistory(BrowserWindow* window) { ui->tabs->SetCurrentIndex(0); show(); m_historyManager->setMainWindow(window); raise(); activateWindow(); } void BrowsingLibrary::showBookmarks(BrowserWindow* window) { ui->tabs->SetCurrentIndex(1); show(); m_bookmarksManager->setMainWindow(window); raise(); activateWindow(); } void BrowsingLibrary::closeEvent(QCloseEvent* e) { Settings settings; settings.beginGroup("BrowsingLibrary"); settings.setValue("size", size()); settings.setValue("historyState", m_historyManager->saveState()); settings.endGroup(); e->accept(); } void BrowsingLibrary::keyPressEvent(QKeyEvent* e) { if (e->key() == Qt::Key_Escape || (e->key() == Qt::Key_W && e->modifiers() == Qt::ControlModifier)) { close(); } QWidget::keyPressEvent(e); } BrowsingLibrary::~BrowsingLibrary() { delete ui; } diff --git a/src/lib/other/browsinglibrary.h b/src/lib/other/browsinglibrary.h index 65aa4795..8ced5bc9 100644 --- a/src/lib/other/browsinglibrary.h +++ b/src/lib/other/browsinglibrary.h @@ -1,64 +1,64 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef LIBRARY_H #define LIBRARY_H #include #include "qzcommon.h" namespace Ui { class BrowsingLibrary; } class HistoryManager; class BookmarksManager; class BrowserWindow; -class QUPZILLA_EXPORT BrowsingLibrary : public QWidget +class FALKON_EXPORT BrowsingLibrary : public QWidget { Q_OBJECT public: explicit BrowsingLibrary(BrowserWindow* window, QWidget* parent = 0); ~BrowsingLibrary(); void showHistory(BrowserWindow* window); void showBookmarks(BrowserWindow* window); void optimizeDatabase(); HistoryManager* historyManager() { return m_historyManager; } BookmarksManager* bookmarksManager() { return m_bookmarksManager; } private slots: void search(); void importBookmarks(); void exportBookmarks(); private: void closeEvent(QCloseEvent* e); void keyPressEvent(QKeyEvent* e); Ui::BrowsingLibrary* ui; HistoryManager* m_historyManager; BookmarksManager* m_bookmarksManager; }; #endif // LIBRARY_H diff --git a/src/lib/other/checkboxdialog.cpp b/src/lib/other/checkboxdialog.cpp index 4ccf8b06..3479aa0a 100644 --- a/src/lib/other/checkboxdialog.cpp +++ b/src/lib/other/checkboxdialog.cpp @@ -1,44 +1,44 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * Copyright (C) 2017 Razi Alavizadeh * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "checkboxdialog.h" #include CheckBoxDialog::CheckBoxDialog(const QMessageBox::StandardButtons &buttons, QWidget* parent) : QMessageBox(parent) , m_checkBox(new QCheckBox) { setCheckBox(m_checkBox); setStandardButtons(buttons); setWindowFlags(windowFlags() | Qt::MSWindowsFixedSizeDialogHint | Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint); } void CheckBoxDialog::setCheckBoxText(const QString &text) { m_checkBox->setText(text); } bool CheckBoxDialog::isChecked() const { return m_checkBox->isChecked(); } void CheckBoxDialog::setDefaultCheckState(Qt::CheckState state) { m_checkBox->setChecked(state == Qt::Checked); } diff --git a/src/lib/other/checkboxdialog.h b/src/lib/other/checkboxdialog.h index fb0ad097..9f2f3fc2 100644 --- a/src/lib/other/checkboxdialog.h +++ b/src/lib/other/checkboxdialog.h @@ -1,42 +1,42 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * Copyright (C) 2017 Razi Alavizadeh * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef CHECKBOXDIALOG_H #define CHECKBOXDIALOG_H #include #include "qzcommon.h" -class QUPZILLA_EXPORT CheckBoxDialog : public QMessageBox +class FALKON_EXPORT CheckBoxDialog : public QMessageBox { Q_OBJECT public: explicit CheckBoxDialog(const QMessageBox::StandardButtons &buttons, QWidget* parent = 0); void setCheckBoxText(const QString &text); bool isChecked() const; void setDefaultCheckState(Qt::CheckState state); private: QCheckBox* m_checkBox; }; #endif // CHECKBOXDIALOG_H diff --git a/src/lib/other/clearprivatedata.cpp b/src/lib/other/clearprivatedata.cpp index 4fd9ba00..c3031221 100644 --- a/src/lib/other/clearprivatedata.cpp +++ b/src/lib/other/clearprivatedata.cpp @@ -1,244 +1,244 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2015 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "clearprivatedata.h" #include "browserwindow.h" #include "tabwidget.h" #include "cookiejar.h" #include "history.h" #include "settings.h" #include "datapaths.h" #include "mainapplication.h" #include "networkmanager.h" #include "ui_clearprivatedata.h" #include "iconprovider.h" #include "qztools.h" #include "cookiemanager.h" #include "desktopnotificationsfactory.h" #include #include #include #include #include #include #include #include #include ClearPrivateData::ClearPrivateData(QWidget* parent) : QDialog(parent) , ui(new Ui::ClearPrivateData) { setAttribute(Qt::WA_DeleteOnClose); ui->setupUi(this); ui->buttonBox->setFocus(); connect(ui->history, SIGNAL(clicked(bool)), this, SLOT(historyClicked(bool))); connect(ui->clear, SIGNAL(clicked(bool)), this, SLOT(dialogAccepted())); connect(ui->optimizeDb, SIGNAL(clicked(bool)), this, SLOT(optimizeDb())); connect(ui->editCookies, SIGNAL(clicked()), this, SLOT(showCookieManager())); Settings settings; settings.beginGroup("ClearPrivateData"); restoreState(settings.value("state", QByteArray()).toByteArray()); settings.endGroup(); } void ClearPrivateData::historyClicked(bool state) { ui->historyLength->setEnabled(state); } void ClearPrivateData::clearLocalStorage() { const QString profile = DataPaths::currentProfilePath(); QzTools::removeDir(profile + "/LocalStorage"); } void ClearPrivateData::clearWebDatabases() { const QString profile = DataPaths::currentProfilePath(); QzTools::removeDir(profile + "/IndexedDB"); QzTools::removeDir(profile + "/databases"); } void ClearPrivateData::clearCache() { const QString profile = DataPaths::currentProfilePath(); QzTools::removeDir(profile + "/GPUCache"); mApp->webProfile()->clearHttpCache(); } void ClearPrivateData::closeEvent(QCloseEvent* e) { Settings settings; settings.beginGroup("ClearPrivateData"); settings.setValue("state", saveState()); settings.endGroup(); e->accept(); } void ClearPrivateData::dialogAccepted() { QApplication::setOverrideCursor(Qt::WaitCursor); if (ui->history->isChecked()) { qint64 start = QDateTime::currentMSecsSinceEpoch(); qint64 end = 0; const QDate today = QDate::currentDate(); const QDate week = today.addDays(1 - today.dayOfWeek()); const QDate month = QDate(today.year(), today.month(), 1); switch (ui->historyLength->currentIndex()) { case 0: //Later Today end = QDateTime(today).toMSecsSinceEpoch(); break; case 1: //Week end = QDateTime(week).toMSecsSinceEpoch(); break; case 2: //Month end = QDateTime(month).toMSecsSinceEpoch(); break; case 3: //All break; } if (end == 0) { mApp->history()->clearHistory(); } else { const QList &indexes = mApp->history()->indexesFromTimeRange(start, end); mApp->history()->deleteHistoryEntry(indexes); } } if (ui->cookies->isChecked()) { mApp->cookieJar()->deleteAllCookies(); } if (ui->cache->isChecked()) { clearCache(); } if (ui->databases->isChecked()) { clearWebDatabases(); } if (ui->localStorage->isChecked()) { clearLocalStorage(); } QApplication::restoreOverrideCursor(); ui->clear->setEnabled(false); ui->clear->setText(tr("Done")); QTimer::singleShot(1000, this, SLOT(close())); } void ClearPrivateData::optimizeDb() { mApp->setOverrideCursor(Qt::WaitCursor); const QString profilePath = DataPaths::currentProfilePath(); QString sizeBefore = QzTools::fileSizeToString(QFileInfo(profilePath + "/browsedata.db").size()); IconProvider::instance()->clearOldIconsInDatabase(); QString sizeAfter = QzTools::fileSizeToString(QFileInfo(profilePath + "/browsedata.db").size()); mApp->restoreOverrideCursor(); QMessageBox::information(this, tr("Database Optimized"), tr("Database successfully optimized.

Database Size Before: %1
Database Size After: %2").arg(sizeBefore, sizeAfter)); } void ClearPrivateData::showCookieManager() { CookieManager* dialog = new CookieManager(); dialog->show(); } static const int stateDataVersion = 0x0001; void ClearPrivateData::restoreState(const QByteArray &state) { QDataStream stream(state); if (stream.atEnd()) { return; } int version = -1; int historyIndex = -1; bool databases = false; bool localStorage = false; bool cache = false; bool cookies = false; bool icons = false; stream >> version; if (version != stateDataVersion) { return; } stream >> historyIndex; stream >> databases; stream >> localStorage; stream >> cache; stream >> cookies; stream >> icons; if (historyIndex != -1) { ui->history->setChecked(true); ui->historyLength->setEnabled(true); ui->historyLength->setCurrentIndex(historyIndex); } ui->databases->setChecked(databases); ui->localStorage->setChecked(localStorage); ui->cache->setChecked(cache); ui->cookies->setChecked(cookies); } QByteArray ClearPrivateData::saveState() { // history - web database - local storage - cache - cookies - icons QByteArray data; QDataStream stream(&data, QIODevice::WriteOnly); stream << stateDataVersion; if (!ui->history->isChecked()) { stream << -1; } else { stream << ui->historyLength->currentIndex(); } stream << ui->databases->isChecked(); stream << ui->localStorage->isChecked(); stream << ui->cache->isChecked(); stream << ui->cookies->isChecked(); return data; } diff --git a/src/lib/other/clearprivatedata.h b/src/lib/other/clearprivatedata.h index eaed5eca..daf2cb73 100644 --- a/src/lib/other/clearprivatedata.h +++ b/src/lib/other/clearprivatedata.h @@ -1,56 +1,56 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef CLEARPRIVATEDATA_H #define CLEARPRIVATEDATA_H #include #include "qzcommon.h" namespace Ui { class ClearPrivateData; } -class QUPZILLA_EXPORT ClearPrivateData : public QDialog +class FALKON_EXPORT ClearPrivateData : public QDialog { Q_OBJECT public: explicit ClearPrivateData(QWidget* parent = 0); static void clearLocalStorage(); static void clearWebDatabases(); static void clearCache(); private slots: void historyClicked(bool state); void dialogAccepted(); void optimizeDb(); void showCookieManager(); private: void closeEvent(QCloseEvent* e); void restoreState(const QByteArray &state); QByteArray saveState(); Ui::ClearPrivateData* ui; }; #endif // CLEARPRIVATEDATA_H diff --git a/src/lib/other/iconchooser.cpp b/src/lib/other/iconchooser.cpp index 46f8aae3..ea7099e3 100644 --- a/src/lib/other/iconchooser.cpp +++ b/src/lib/other/iconchooser.cpp @@ -1,135 +1,135 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2016 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "iconchooser.h" #include "ui_iconchooser.h" #include "mainapplication.h" #include "proxystyle.h" #include "qztools.h" #include #include IconChooser::IconChooser(QWidget* parent) : QDialog(parent), ui(new Ui::IconChooser) { ui->setupUi(this); ui->iconList->setItemDelegate(new IconChooserDelegate(ui->iconList)); connect(ui->chooseFile, SIGNAL(clicked()), this, SLOT(chooseFile())); connect(ui->siteUrl, SIGNAL(textChanged(QString)), this, SLOT(searchIcon(QString))); } void IconChooser::chooseFile() { const QString fileTypes = QString("%3(*.png *.jpg *.jpeg *.gif)").arg(tr("Image files")); const QString path = QzTools::getOpenFileName("IconChooser-ChangeIcon", this, tr("Choose icon..."), QDir::homePath(), fileTypes); if (path.isEmpty()) { return; } ui->iconList->clear(); QIcon icon(path); if (!icon.isNull()) { QListWidgetItem* item = new QListWidgetItem(ui->iconList); item->setIcon(icon); ui->iconList->setCurrentItem(item); } } void IconChooser::searchIcon(const QString &string) { if (string.size() < 4) { return; } ui->iconList->clear(); QSqlQuery query; query.prepare(QSL("SELECT icon FROM icons WHERE url GLOB ? LIMIT 20")); query.addBindValue(QString(QL1S("*%1*")).arg(QzTools::escapeSqlGlobString(string))); query.exec(); while (query.next()) { QImage image = QImage::fromData(query.value(0).toByteArray()); if (!image.isNull()) { QListWidgetItem* item = new QListWidgetItem(ui->iconList); item->setIcon(QPixmap::fromImage(image)); } } } QIcon IconChooser::getIcon() { QIcon icon; int status = QDialog::exec(); if (status == QDialog::Accepted) { QList selectedItems = ui->iconList->selectedItems(); if (!selectedItems.isEmpty()) { icon = selectedItems.at(0)->icon(); } } // Ensure we are returning 16×16px icon if (!icon.isNull()) { icon = icon.pixmap(16); } return icon; } IconChooser::~IconChooser() { delete ui; } IconChooserDelegate::IconChooserDelegate(QWidget* parent) : QStyledItemDelegate(parent) { } void IconChooserDelegate::paint(QPainter* painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { QStyleOptionViewItem opt = option; initStyleOption(&opt, index); const QWidget* w = opt.widget; const QStyle* style = w ? w->style() : QApplication::style(); // Draw background opt.showDecorationSelected = true; style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, w); // Draw icon const int padding = opt.rect.width() / 4; const QIcon icon = index.data(Qt::DecorationRole).value(); icon.paint(painter, opt.rect.adjusted(padding, padding, -padding, -padding)); } QSize IconChooserDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const { Q_UNUSED(option) Q_UNUSED(index) return QSize(48, 48); } diff --git a/src/lib/other/iconchooser.h b/src/lib/other/iconchooser.h index aee42393..463f5d39 100644 --- a/src/lib/other/iconchooser.h +++ b/src/lib/other/iconchooser.h @@ -1,60 +1,60 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef ICONCHOOSER_H #define ICONCHOOSER_H #include #include #include "qzcommon.h" class QIcon; namespace Ui { class IconChooser; } -class QUPZILLA_EXPORT IconChooser : public QDialog +class FALKON_EXPORT IconChooser : public QDialog { Q_OBJECT public: explicit IconChooser(QWidget* parent = 0); ~IconChooser(); QIcon getIcon(); private slots: void chooseFile(); void searchIcon(const QString &string); private: Ui::IconChooser* ui; }; -class QUPZILLA_EXPORT IconChooserDelegate : public QStyledItemDelegate +class FALKON_EXPORT IconChooserDelegate : public QStyledItemDelegate { public: explicit IconChooserDelegate(QWidget* parent = 0); void paint(QPainter* painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const; }; #endif // ICONCHOOSER_H diff --git a/src/lib/other/licenseviewer.cpp b/src/lib/other/licenseviewer.cpp index 1f0cca7e..b4915289 100644 --- a/src/lib/other/licenseviewer.cpp +++ b/src/lib/other/licenseviewer.cpp @@ -1,61 +1,61 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "licenseviewer.h" #include "qztools.h" #include #include #include #include LicenseViewer::LicenseViewer(QWidget* parent) : QWidget() { setAttribute(Qt::WA_DeleteOnClose); setWindowTitle(tr("License Viewer")); m_textBrowser = new QTextBrowser(this); QFont serifFont = m_textBrowser->font(); serifFont.setFamily("Courier"); m_textBrowser->setFont(serifFont); QDialogButtonBox* buttonBox = new QDialogButtonBox(this); buttonBox->setStandardButtons(QDialogButtonBox::Close); connect(buttonBox, SIGNAL(rejected()), this, SLOT(close())); QVBoxLayout* l = new QVBoxLayout(this); l->addWidget(m_textBrowser); l->addWidget(buttonBox); setLayout(l); resize(600, 500); QzTools::centerWidgetToParent(this, parent); } void LicenseViewer::setLicenseFile(const QString &fileName) { m_textBrowser->setText(QzTools::readAllFileContents(fileName)); } void LicenseViewer::setText(const QString &text) { m_textBrowser->setText(text); } diff --git a/src/lib/other/licenseviewer.h b/src/lib/other/licenseviewer.h index 5d2dd3a4..2ccb4777 100644 --- a/src/lib/other/licenseviewer.h +++ b/src/lib/other/licenseviewer.h @@ -1,41 +1,41 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef LICENSEVIEWER_H #define LICENSEVIEWER_H #include #include "qzcommon.h" class QTextBrowser; -class QUPZILLA_EXPORT LicenseViewer : public QWidget +class FALKON_EXPORT LicenseViewer : public QWidget { Q_OBJECT public: explicit LicenseViewer(QWidget* parent = 0); void setLicenseFile(const QString &fileName); void setText(const QString &text); private: QTextBrowser* m_textBrowser; }; #endif // LICENSEVIEWER_H diff --git a/src/lib/other/pagescreen.cpp b/src/lib/other/pagescreen.cpp index 6af8f8e5..eef08bd6 100644 --- a/src/lib/other/pagescreen.cpp +++ b/src/lib/other/pagescreen.cpp @@ -1,277 +1,277 @@ /* ============================================================ * QupZilla - WebKit based browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "pagescreen.h" #include "ui_pagescreen.h" #include "tabbedwebview.h" #include "webpage.h" #include "qztools.h" #include "browserwindow.h" #include "settings.h" #if QTWEBENGINE_DISABLED #include #include #include #include #include #include #include #include #include #include PageScreen::PageScreen(WebView* view, QWidget* parent) : QDialog(parent) , ui(new Ui::PageScreen) , m_view(view) , m_imageScaling(0) { setAttribute(Qt::WA_DeleteOnClose); ui->setupUi(this); m_formats.append(QSL("PNG")); m_formats.append(QSL("BMP")); m_formats.append(QSL("JPG")); m_formats.append(QSL("PPM")); m_formats.append(QSL("TIFF")); m_formats.append(QSL("PDF")); foreach (const QString &format, m_formats) { ui->formats->addItem(tr("Save as %1").arg(format)); } m_pageTitle = m_view->title(); Settings settings; const QString name = QzTools::filterCharsFromFilename(m_pageTitle).replace(QLatin1Char(' '), QLatin1Char('_')); const QString path = settings.value("FileDialogPaths/PageScreen-Location", QDir::homePath()).toString(); ui->location->setText(QString("%1/%2.png").arg(path, name)); QMovie* mov = new QMovie(":html/loading.gif"); ui->label->setMovie(mov); mov->start(); connect(ui->changeLocation, SIGNAL(clicked()), this, SLOT(changeLocation())); connect(ui->formats, SIGNAL(currentIndexChanged(int)), this, SLOT(formatChanged())); connect(ui->buttonBox->button(QDialogButtonBox::Save), SIGNAL(clicked()), this, SLOT(dialogAccepted())); connect(ui->buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), this, SLOT(close())); QTimer::singleShot(200, this, SLOT(createThumbnail())); } void PageScreen::formatChanged() { QString text = ui->location->text(); int pos = text.lastIndexOf(QLatin1Char('.')); if (pos > -1) { text = text.left(pos + 1) + m_formats.at(ui->formats->currentIndex()).toLower(); } else { text.append(QLatin1Char('.') + m_formats.at(ui->formats->currentIndex()).toLower()); } ui->location->setText(text); } void PageScreen::changeLocation() { const QString name = QzTools::filterCharsFromFilename(m_pageTitle).replace(QLatin1Char(' '), QLatin1Char('_')); const QString suggestedPath = QString("%1/%2.%3").arg(QDir::homePath(), name, m_formats.at(ui->formats->currentIndex()).toLower()); const QString path = QzTools::getSaveFileName("PageScreen-Location", this, tr("Choose location..."), suggestedPath); if (!path.isEmpty()) { ui->location->setText(path); } } void PageScreen::dialogAccepted() { if (!ui->location->text().isEmpty()) { if (QFile::exists(ui->location->text())) { const QString text = tr("File '%1' already exists. Do you want to overwrite it?").arg(ui->location->text()); QMessageBox::StandardButton button = QMessageBox::warning(this, tr("File already exists"), text, QMessageBox::Yes | QMessageBox::No, QMessageBox::No); if (button != QMessageBox::Yes) { return; } } QApplication::setOverrideCursor(Qt::WaitCursor); const QString format = m_formats.at(ui->formats->currentIndex()); if (format == QLatin1String("PDF")) { saveAsDocument(format); } else { saveAsImage(format); } QApplication::restoreOverrideCursor(); close(); } } void PageScreen::saveAsImage(const QString &format) { const QString suffix = QLatin1Char('.') + format.toLower(); QString pathWithoutSuffix = ui->location->text(); if (pathWithoutSuffix.endsWith(suffix, Qt::CaseInsensitive)) { pathWithoutSuffix = pathWithoutSuffix.mid(0, pathWithoutSuffix.length() - suffix.length()); } if (m_pageImages.count() == 1) { m_pageImages.first().save(pathWithoutSuffix + suffix, format.toUtf8()); } else { int part = 1; foreach (const QImage &image, m_pageImages) { const QString fileName = pathWithoutSuffix + ".part" + QString::number(part); image.save(fileName + suffix, format.toUtf8()); part++; } } } void PageScreen::saveAsDocument(const QString &format) { const QString suffix = QLatin1Char('.') + format.toLower(); QString pathWithoutSuffix = ui->location->text(); if (pathWithoutSuffix.endsWith(suffix, Qt::CaseInsensitive)) { pathWithoutSuffix = pathWithoutSuffix.mid(0, pathWithoutSuffix.length() - suffix.length()); } QPrinter printer; - printer.setCreator(BrowserWindow::tr("QupZilla %1 (%2)").arg(Qz::VERSION, Qz::WWWADDRESS)); + printer.setCreator(BrowserWindow::tr("Falkon %1 (%2)").arg(Qz::VERSION, Qz::WWWADDRESS)); printer.setOutputFileName(pathWithoutSuffix + suffix); printer.setOutputFormat(QPrinter::PdfFormat); printer.setPaperSize(m_pageImages.first().size(), QPrinter::DevicePixel); printer.setPageMargins(0, 0, 0, 0, QPrinter::DevicePixel); printer.setFullPage(true); QPainter painter; painter.begin(&printer); for (int i = 0; i < m_pageImages.size(); ++i) { const QImage image = m_pageImages.at(i); painter.drawImage(0, 0, image); if (i != m_pageImages.size() - 1) { printer.newPage(); } } painter.end(); } void PageScreen::createThumbnail() { QWebEnginePage* page = m_view->page(); const int heightLimit = 20000; const QPoint originalScrollPosition = page->mainFrame()->scrollPosition(); const QSize originalSize = page->viewportSize(); const QSize frameSize = page->mainFrame()->contentsSize(); const int verticalScrollbarSize = page->mainFrame()->scrollBarGeometry(Qt::Vertical).width(); const int horizontalScrollbarSize = page->mainFrame()->scrollBarGeometry(Qt::Horizontal).height(); int yPosition = 0; bool canScroll = frameSize.height() > heightLimit; // We will split rendering page into smaller parts to avoid infinite loops // or crashes. do { int remainingHeight = frameSize.height() - yPosition; if (remainingHeight <= 0) { break; } QSize size(frameSize.width(), remainingHeight > heightLimit ? heightLimit : remainingHeight); page->setViewportSize(size); page->mainFrame()->scroll(0, qMax(0, yPosition - horizontalScrollbarSize)); QImage image(page->viewportSize().width() - verticalScrollbarSize, page->viewportSize().height() - horizontalScrollbarSize, QImage::Format_ARGB32_Premultiplied); QPainter painter(&image); page->mainFrame()->render(&painter); painter.end(); m_pageImages.append(image); canScroll = remainingHeight > heightLimit; yPosition += size.height(); } while (canScroll); page->setViewportSize(originalSize); page->mainFrame()->setScrollBarValue(Qt::Vertical, originalScrollPosition.y()); page->mainFrame()->setScrollBarValue(Qt::Horizontal, originalScrollPosition.x()); m_imageScaling = new QFutureWatcher(this); m_imageScaling->setFuture(QtConcurrent::run(this, &PageScreen::scaleImage)); connect(m_imageScaling, SIGNAL(finished()), SLOT(showImage())); } QImage PageScreen::scaleImage() { QVector scaledImages; int sumHeight = 0; foreach (const QImage &image, m_pageImages) { QImage scaled = image.scaledToWidth(450, Qt::SmoothTransformation); scaledImages.append(scaled); sumHeight += scaled.height(); } QImage finalImage(QSize(450, sumHeight), QImage::Format_ARGB32_Premultiplied); QPainter painter(&finalImage); int offset = 0; foreach (const QImage &image, scaledImages) { painter.drawImage(0, offset, image); offset += image.height(); } return finalImage; } void PageScreen::showImage() { delete ui->label->movie(); ui->label->setPixmap(QPixmap::fromImage(m_imageScaling->result())); } PageScreen::~PageScreen() { delete ui; } #endif diff --git a/src/lib/other/pagescreen.h b/src/lib/other/pagescreen.h index 6c2b17ef..a867f1bc 100644 --- a/src/lib/other/pagescreen.h +++ b/src/lib/other/pagescreen.h @@ -1,70 +1,70 @@ /* ============================================================ * QupZilla - WebKit based browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef PAGESCREEN_H #define PAGESCREEN_H #include #include #include "qzcommon.h" #if QTWEBENGINE_DISABLED namespace Ui { class PageScreen; } class WebView; -class QUPZILLA_EXPORT PageScreen : public QDialog +class FALKON_EXPORT PageScreen : public QDialog { Q_OBJECT public: explicit PageScreen(WebView* view, QWidget* parent); ~PageScreen(); QImage scaleImage(); private slots: void createThumbnail(); void showImage(); void formatChanged(); void changeLocation(); void dialogAccepted(); private: void saveAsImage(const QString &format); void saveAsDocument(const QString &format); void createPixmap(); Ui::PageScreen* ui; WebView* m_view; QString m_pageTitle; QFutureWatcher* m_imageScaling; QVector m_pageImages; QStringList m_formats; }; #endif #endif // PAGESCREEN_H diff --git a/src/lib/other/qzsettings.cpp b/src/lib/other/qzsettings.cpp index 41f1124a..f43f8f4a 100644 --- a/src/lib/other/qzsettings.cpp +++ b/src/lib/other/qzsettings.cpp @@ -1,73 +1,73 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2016 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "qzsettings.h" #include "settings.h" #include "webview.h" QzSettings::QzSettings() { loadSettings(); } void QzSettings::loadSettings() { Settings settings; settings.beginGroup("AddressBar"); selectAllOnDoubleClick = settings.value("SelectAllTextOnDoubleClick", true).toBool(); selectAllOnClick = settings.value("SelectAllTextOnClick", false).toBool(); showLoadingProgress = settings.value("ShowLoadingProgress", false).toBool(); showLocationSuggestions = settings.value("showSuggestions", 0).toInt(); showSwitchTab = settings.value("showSwitchTab", true).toBool(); alwaysShowGoIcon = settings.value("alwaysShowGoIcon", false).toBool(); useInlineCompletion = settings.value("useInlineCompletion", true).toBool(); settings.endGroup(); settings.beginGroup("SearchEngines"); showSearchSuggestions = settings.value("showSuggestions", true).toBool(); searchOnEngineChange = settings.value("SearchOnEngineChange", true).toBool(); searchFromAddressBar = settings.value("SearchFromAddressBar", true).toBool(); searchWithDefaultEngine = settings.value("SearchWithDefaultEngine", false).toBool(); settings.endGroup(); settings.beginGroup("Web-Browser-Settings"); defaultZoomLevel = settings.value("DefaultZoomLevel", WebView::zoomLevels().indexOf(100)).toInt(); loadTabsOnActivation = settings.value("LoadTabsOnActivation", true).toBool(); autoOpenProtocols = settings.value("AutomaticallyOpenProtocols", QStringList()).toStringList(); blockedProtocols = settings.value("BlockOpeningProtocols", QStringList()).toStringList(); settings.endGroup(); settings.beginGroup("Browser-Tabs-Settings"); newTabPosition = settings.value("OpenNewTabsSelected", false).toBool() ? Qz::NT_CleanSelectedTab : Qz::NT_CleanNotSelectedTab; tabsOnTop = settings.value("TabsOnTop", true).toBool(); openPopupsInTabs = settings.value("OpenPopupsInTabs", false).toBool(); alwaysSwitchTabsWithWheel = settings.value("AlwaysSwitchTabsWithWheel", false).toBool(); settings.endGroup(); } void QzSettings::saveSettings() { Settings settings; settings.beginGroup("Web-Browser-Settings"); settings.setValue("AutomaticallyOpenProtocols", autoOpenProtocols); settings.setValue("BlockOpeningProtocols", blockedProtocols); settings.endGroup(); settings.beginGroup("Browser-Tabs-Settings"); settings.setValue("TabsOnTop", tabsOnTop); settings.endGroup(); } diff --git a/src/lib/other/qzsettings.h b/src/lib/other/qzsettings.h index 85e38933..cce79b8b 100644 --- a/src/lib/other/qzsettings.h +++ b/src/lib/other/qzsettings.h @@ -1,65 +1,65 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2016 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef QZSETTINGS_H #define QZSETTINGS_H #include "qzcommon.h" #include "settings.h" #include -class QUPZILLA_EXPORT QzSettings +class FALKON_EXPORT QzSettings { public: QzSettings(); void loadSettings(); void saveSettings(); // AddressBar bool selectAllOnDoubleClick; bool selectAllOnClick; bool showLoadingProgress; int showLocationSuggestions; bool showSwitchTab; bool alwaysShowGoIcon; bool useInlineCompletion; // SearchEngines bool showSearchSuggestions; bool searchOnEngineChange; bool searchFromAddressBar; bool searchWithDefaultEngine; // Web-Browser-Settings int defaultZoomLevel; bool loadTabsOnActivation; QStringList autoOpenProtocols; QStringList blockedProtocols; // Browser-Tabs-Settings Qz::NewTabPositionFlags newTabPosition; bool tabsOnTop; bool openPopupsInTabs; bool alwaysSwitchTabsWithWheel; }; #define qzSettings Settings::staticSettings() #endif // QZSETTINGS_H diff --git a/src/lib/other/registerqappassociation.cpp b/src/lib/other/registerqappassociation.cpp index 3903c12a..e061ed72 100644 --- a/src/lib/other/registerqappassociation.cpp +++ b/src/lib/other/registerqappassociation.cpp @@ -1,419 +1,419 @@ /* ============================================================ * Copyright (C) 2012-2017 S. Razi Alavizadeh -* This file is part of QupZilla - WebKit based browser 2010-2014 +* This file is part of Falkon - Qt web browser 2010-2014 * by David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "registerqappassociation.h" #include "mainapplication.h" #include "browserwindow.h" #include "ShlObj.h" #include #include #include #include RegisterQAppAssociation::RegisterQAppAssociation(QObject* parent) : QObject(parent) { setPerMachineRegisteration(false); } RegisterQAppAssociation::RegisterQAppAssociation(const QString &appRegisteredName, const QString &appPath, const QString &appIcon, const QString &appDesc, QObject* parent) : QObject(parent) { setPerMachineRegisteration(false); setAppInfo(appRegisteredName, appPath, appIcon, appDesc); } RegisterQAppAssociation::~RegisterQAppAssociation() { } void RegisterQAppAssociation::addCapability(const QString &assocName, const QString &progId, const QString &desc, const QString &iconPath, AssociationType type) { _assocDescHash.insert(progId, QPair(desc, QDir::toNativeSeparators(iconPath))); switch (type) { case FileAssociation: _fileAssocHash.insert(assocName, progId); break; case UrlAssociation: _urlAssocHash.insert(assocName, progId); break; default: break; } } void RegisterQAppAssociation::removeCapability(const QString &assocName) { _fileAssocHash.remove(assocName); _urlAssocHash.remove(assocName); } void RegisterQAppAssociation::setAppInfo(const QString &appRegisteredName, const QString &appPath, const QString &appIcon, const QString &appDesc) { _appRegisteredName = appRegisteredName; _appPath = QDir::toNativeSeparators(appPath); _appIcon = QDir::toNativeSeparators(appIcon); _appDesc = appDesc; } bool RegisterQAppAssociation::isPerMachineRegisteration() { return (_UserRootKey == "HKEY_LOCAL_MACHINE"); } void RegisterQAppAssociation::setPerMachineRegisteration(bool enable) { if (enable) { _UserRootKey = "HKEY_LOCAL_MACHINE"; } else { _UserRootKey = "HKEY_CURRENT_USER"; } } bool RegisterQAppAssociation::registerAppCapabilities() { if (!isVistaOrNewer()) { return true; } // Vista and newer QSettings regLocalMachine("HKEY_LOCAL_MACHINE", QSettings::NativeFormat); QString capabilitiesKey = regLocalMachine.value("Software/RegisteredApplications/" + _appRegisteredName).toString(); if (capabilitiesKey.isEmpty()) { regLocalMachine.setValue("Software/RegisteredApplications/" + _appRegisteredName, QString("Software\\" + _appRegisteredName + "\\Capabilities")); capabilitiesKey = regLocalMachine.value("Software/RegisteredApplications/" + _appRegisteredName).toString(); if (capabilitiesKey.isEmpty()) { QMessageBox::warning(mApp->getWindow(), tr("Warning!"), - tr("There are some problems. Please, reinstall QupZilla.\n" + tr("There are some problems. Please, reinstall Falkon.\n" "Maybe relaunch with administrator right do a magic for you! ;)")); return false; } } capabilitiesKey.replace("\\", "/"); QHash >::const_iterator it = _assocDescHash.constBegin(); while (it != _assocDescHash.constEnd()) { createProgId(it.key()); ++it; } regLocalMachine.setValue(capabilitiesKey + "/ApplicationDescription", _appDesc); regLocalMachine.setValue(capabilitiesKey + "/ApplicationIcon", _appIcon); regLocalMachine.setValue(capabilitiesKey + "/ApplicationName", _appRegisteredName); QHash::const_iterator i = _fileAssocHash.constBegin(); while (i != _fileAssocHash.constEnd()) { regLocalMachine.setValue(capabilitiesKey + "/FileAssociations/" + i.key(), i.value()); ++i; } i = _urlAssocHash.constBegin(); while (i != _urlAssocHash.constEnd()) { regLocalMachine.setValue(capabilitiesKey + "/URLAssociations/" + i.key(), i.value()); ++i; } regLocalMachine.setValue(capabilitiesKey + "/Startmenu/StartMenuInternet", _appPath); return true; } bool RegisterQAppAssociation::isVistaOrNewer() { return (QSysInfo::windowsVersion() >= QSysInfo::WV_VISTA && QSysInfo::windowsVersion() <= QSysInfo::WV_NT_based); } bool RegisterQAppAssociation::isWin10OrNewer() { return (QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS10 && QSysInfo::windowsVersion() <= QSysInfo::WV_NT_based); } void RegisterQAppAssociation::registerAssociation(const QString &assocName, AssociationType type) { if (isVistaOrNewer()) { // Vista and newer #ifndef __MINGW32__ IApplicationAssociationRegistration* pAAR; HRESULT hr = CoCreateInstance(CLSID_ApplicationAssociationRegistration, NULL, CLSCTX_INPROC, __uuidof(IApplicationAssociationRegistration), (void**)&pAAR); if (SUCCEEDED(hr)) { switch (type) { case FileAssociation: hr = pAAR->SetAppAsDefault(_appRegisteredName.toStdWString().c_str(), assocName.toStdWString().c_str(), AT_FILEEXTENSION); break; case UrlAssociation: { QSettings regCurrentUserRoot("HKEY_CURRENT_USER", QSettings::NativeFormat); QString currentUrlDefault = regCurrentUserRoot.value("Software/Microsoft/Windows/Shell/Associations/UrlAssociations/" + assocName + "/UserChoice/Progid").toString(); hr = pAAR->SetAppAsDefault(_appRegisteredName.toStdWString().c_str(), assocName.toStdWString().c_str(), AT_URLPROTOCOL); if (SUCCEEDED(hr) && !currentUrlDefault.isEmpty() && currentUrlDefault != _urlAssocHash.value(assocName) ) { regCurrentUserRoot.setValue("Software/Classes" + assocName + "/shell/open/command/backup_progid", currentUrlDefault); } } break; default: break; } pAAR->Release(); } #endif // #ifndef __MINGW32__ } else { // Older than Vista QSettings regUserRoot(_UserRootKey, QSettings::NativeFormat); regUserRoot.beginGroup("Software/Classes"); QSettings regClassesRoot("HKEY_CLASSES_ROOT", QSettings::NativeFormat); switch (type) { case FileAssociation: { QString progId = _fileAssocHash.value(assocName); createProgId(progId); QString currentDefault = regClassesRoot.value(assocName + "/Default").toString(); if (!currentDefault.isEmpty() && currentDefault != progId && regUserRoot.value(assocName + "/backup_val").toString() != progId ) { regUserRoot.setValue(assocName + "/backup_val", currentDefault); } regUserRoot.setValue(assocName + "/.", progId); } break; case UrlAssociation: { QString progId = _urlAssocHash.value(assocName); createProgId(progId); QString currentDefault = regClassesRoot.value(assocName + "/shell/open/command/Default").toString(); QString command = "\"" + _appPath + "\" \"%1\""; if (!currentDefault.isEmpty() && currentDefault != command && regUserRoot.value(assocName + "/shell/open/command/backup_val").toString() != command ) { regUserRoot.setValue(assocName + "/shell/open/command/backup_val", currentDefault); } regUserRoot.setValue(assocName + "/shell/open/command/.", command); regUserRoot.setValue(assocName + "/URL Protocol", ""); break; } default: break; } regUserRoot.endGroup(); } } void RegisterQAppAssociation::registerAllAssociation() { if (isVistaOrNewer() && !registerAppCapabilities()) { return; } QHash::const_iterator i = _fileAssocHash.constBegin(); while (i != _fileAssocHash.constEnd()) { registerAssociation(i.key(), FileAssociation); ++i; } i = _urlAssocHash.constBegin(); while (i != _urlAssocHash.constEnd()) { registerAssociation(i.key(), UrlAssociation); ++i; } if (!isVistaOrNewer()) { #ifndef __MINGW32__ // On Windows Vista or newer for updating icons 'pAAR->SetAppAsDefault()' // calls 'SHChangeNotify()'. Thus, we just need care about older Windows. SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_FLUSHNOWAIT, 0 , 0); #endif } } bool RegisterQAppAssociation::showNativeDefaultAppSettingsUi() { if (!isVistaOrNewer()) { return false; } if (isWin10OrNewer()) { IApplicationActivationManager* pActivator; HRESULT hr = CoCreateInstance(CLSID_ApplicationActivationManager, nullptr, CLSCTX_INPROC, IID_IApplicationActivationManager, (void**)&pActivator); if (!SUCCEEDED(hr)) { return false; } DWORD pid; hr = pActivator->ActivateApplication( L"windows.immersivecontrolpanel_cw5n1h2txyewy" // appUserModelId of "Settings" L"!microsoft.windows.immersivecontrolpanel", // in Windows Store L"page=SettingsPageAppsDefaults", AO_NONE, &pid); if (!SUCCEEDED(hr)) { return false; } // Do not check error because we could at least open // the "Default apps" setting. pActivator->ActivateApplication( L"windows.immersivecontrolpanel_cw5n1h2txyewy" L"!microsoft.windows.immersivecontrolpanel", L"page=SettingsPageAppsDefaults" L"&target=SystemSettings_DefaultApps_Browser", AO_NONE, &pid); pActivator->Release(); } else { IApplicationAssociationRegistrationUI* pAARUI = NULL; HRESULT hr = CoCreateInstance(CLSID_ApplicationAssociationRegistrationUI, NULL, CLSCTX_INPROC, __uuidof(IApplicationAssociationRegistrationUI), reinterpret_cast< void** > (&pAARUI)); if (!SUCCEEDED(hr)) { return false; } hr = pAARUI->LaunchAdvancedAssociationUI(reinterpret_cast(_appRegisteredName.utf16())); pAARUI->Release(); } return true; } void RegisterQAppAssociation::createProgId(const QString &progId) { QSettings regUserRoot(_UserRootKey, QSettings::NativeFormat); regUserRoot.beginGroup("Software/Classes"); QPair pair = _assocDescHash.value(progId); regUserRoot.setValue(progId + "/.", pair.first); regUserRoot.setValue(progId + "/shell/.", "open"); regUserRoot.setValue(progId + "/DefaultIcon/.", pair.second); regUserRoot.setValue(progId + "/shell/open/command/.", QString("\"" + _appPath + "\" \"%1\"")); regUserRoot.endGroup(); } bool RegisterQAppAssociation::isDefaultApp(const QString &assocName, AssociationType type) { if (isVistaOrNewer()) { QSettings regCurrentUserRoot("HKEY_CURRENT_USER", QSettings::NativeFormat); switch (type) { case FileAssociation: { regCurrentUserRoot.beginGroup("Software/Microsoft/Windows/CurrentVersion/Explorer/FileExts"); if (regCurrentUserRoot.childGroups().contains(assocName, Qt::CaseInsensitive)) { return (_fileAssocHash.value(assocName) == regCurrentUserRoot.value(assocName + "/UserChoice/Progid")); } else { regCurrentUserRoot.endGroup(); return false; } break; } case UrlAssociation: { regCurrentUserRoot.beginGroup("Software/Microsoft/Windows/Shell/Associations/UrlAssociations"); if (regCurrentUserRoot.childGroups().contains(assocName, Qt::CaseInsensitive)) { return (_urlAssocHash.value(assocName) == regCurrentUserRoot.value(assocName + "/UserChoice/Progid")); } else { regCurrentUserRoot.endGroup(); return false; } } break; default: break; } } else { QSettings regClassesRoot("HKEY_CLASSES_ROOT", QSettings::NativeFormat); { if (!regClassesRoot.childGroups().contains(assocName, Qt::CaseInsensitive)) { return false; } } switch (type) { case FileAssociation: { return (_fileAssocHash.value(assocName) == regClassesRoot.value(assocName + "/Default")); } break; case UrlAssociation: { QString currentDefault = regClassesRoot.value(assocName + "/shell/open/command/Default").toString(); currentDefault.remove("\""); currentDefault.remove("%1"); currentDefault = currentDefault.trimmed(); return (_appPath == currentDefault); } break; default: break; } } return false; } bool RegisterQAppAssociation::isDefaultForAllCapabilities() { bool result = true; QHash::const_iterator i = _fileAssocHash.constBegin(); while (i != _fileAssocHash.constEnd()) { bool res = isDefaultApp(i.key(), FileAssociation); result &= res; ++i; } i = _urlAssocHash.constBegin(); while (i != _urlAssocHash.constEnd()) { bool res = isDefaultApp(i.key(), UrlAssociation); result &= res; ++i; } return result; } diff --git a/src/lib/other/registerqappassociation.h b/src/lib/other/registerqappassociation.h index cf1d6dc5..16933750 100644 --- a/src/lib/other/registerqappassociation.h +++ b/src/lib/other/registerqappassociation.h @@ -1,75 +1,75 @@ /* ============================================================ * Copyright (C) 2012-2017 S. Razi Alavizadeh -* This file is part of QupZilla - WebKit based browser 2010-2014 +* This file is part of Falkon - Qt web browser 2010-2014 * by David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef REGISTERQAPPASSOCIATION_H #define REGISTERQAPPASSOCIATION_H #include #include #include #include "qzcommon.h" -class QUPZILLA_EXPORT RegisterQAppAssociation : public QObject +class FALKON_EXPORT RegisterQAppAssociation : public QObject { Q_OBJECT public: explicit RegisterQAppAssociation(QObject* parent = 0); explicit RegisterQAppAssociation(const QString &appRegisteredName, const QString &appPath, const QString &appIcon = QString(), const QString &appDesc = QString(), QObject* parent = 0); ~RegisterQAppAssociation(); enum AssociationType { FileAssociation, UrlAssociation }; void addCapability(const QString &assocName, const QString &progId, const QString &desc, const QString &iconPath, AssociationType type); void removeCapability(const QString &assocName); void setAppInfo(const QString &appRegisteredName, const QString &appPath, const QString &appIcon = QString(), const QString &appDesc = QString()); bool isPerMachineRegisteration(); void setPerMachineRegisteration(bool enable); bool registerAppCapabilities(); bool isVistaOrNewer(); bool isWin10OrNewer(); void registerAssociation(const QString &assocName, AssociationType type); void createProgId(const QString &progId); bool isDefaultApp(const QString &assocName, AssociationType type); bool isDefaultForAllCapabilities(); void registerAllAssociation(); bool showNativeDefaultAppSettingsUi(); private: QString _appRegisteredName; QString _appPath; QString _appIcon; QString _appDesc; QString _UserRootKey; QHash _fileAssocHash; // (extention, progId) QHash _urlAssocHash; // (protocol, progId) QHash > _assocDescHash; // (progId, (desc, icon)) }; #endif // REGISTERQAPPASSOCIATION_H diff --git a/src/lib/other/siteinfo.cpp b/src/lib/other/siteinfo.cpp index bc02730f..18794628 100644 --- a/src/lib/other/siteinfo.cpp +++ b/src/lib/other/siteinfo.cpp @@ -1,282 +1,282 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2016 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "siteinfo.h" #include "ui_siteinfo.h" #include "listitemdelegate.h" #include "webview.h" #include "webpage.h" #include "mainapplication.h" #include "downloaditem.h" #include "certificateinfowidget.h" #include "qztools.h" #include "iconprovider.h" #include "scripts.h" #include "networkmanager.h" #include "locationbar.h" #include #include #include #include #include #include #include SiteInfo::SiteInfo(WebView* view) : QWidget() , ui(new Ui::SiteInfo) , m_certWidget(0) , m_view(view) , m_imageReply(Q_NULLPTR) , m_baseUrl(view->url()) { setAttribute(Qt::WA_DeleteOnClose); ui->setupUi(this); ui->treeTags->setLayoutDirection(Qt::LeftToRight); QzTools::centerWidgetOnScreen(this); ListItemDelegate* delegate = new ListItemDelegate(24, ui->listWidget); delegate->setUpdateParentHeight(true); delegate->setUniformItemSizes(true); ui->listWidget->setItemDelegate(delegate); ui->listWidget->item(0)->setIcon(QIcon::fromTheme("document-properties", QIcon(":/icons/preferences/document-properties.png"))); ui->listWidget->item(1)->setIcon(QIcon::fromTheme("applications-graphics", QIcon(":/icons/preferences/applications-graphics.png"))); ui->listWidget->item(0)->setSelected(true); // General ui->heading->setText(QString("%1:").arg(m_view->title())); ui->siteAddress->setText(m_view->url().toString()); if (m_view->url().scheme() == QL1S("https")) ui->securityLabel->setText(tr("Connection is Encrypted.")); else ui->securityLabel->setText(tr("Connection Not Encrypted.")); m_view->page()->runJavaScript(QSL("document.charset"), WebPage::SafeJsWorld, [this](const QVariant &res) { ui->encodingLabel->setText(res.toString()); }); // Meta m_view->page()->runJavaScript(Scripts::getAllMetaAttributes(), WebPage::SafeJsWorld, [this](const QVariant &res) { const QVariantList &list = res.toList(); Q_FOREACH (const QVariant &val, list) { const QVariantMap &meta = val.toMap(); QString content = meta.value(QSL("content")).toString(); QString name = meta.value(QSL("name")).toString(); if (name.isEmpty()) name = meta.value(QSL("httpequiv")).toString(); if (content.isEmpty() || name.isEmpty()) continue; QTreeWidgetItem* item = new QTreeWidgetItem(ui->treeTags); item->setText(0, name); item->setText(1, content); ui->treeTags->addTopLevelItem(item); } }); // Images m_view->page()->runJavaScript(Scripts::getAllImages(), WebPage::SafeJsWorld, [this](const QVariant &res) { const QVariantList &list = res.toList(); Q_FOREACH (const QVariant &val, list) { const QVariantMap &img = val.toMap(); QString src = img.value(QSL("src")).toString(); QString alt = img.value(QSL("alt")).toString(); if (alt.isEmpty()) { if (src.indexOf(QLatin1Char('/')) == -1) { alt = src; } else { int pos = src.lastIndexOf(QLatin1Char('/')); alt = src.mid(pos); alt.remove(QLatin1Char('/')); } } if (src.isEmpty() || alt.isEmpty()) continue; QTreeWidgetItem* item = new QTreeWidgetItem(ui->treeImages); item->setText(0, alt); item->setText(1, src); ui->treeImages->addTopLevelItem(item); } }); connect(ui->saveButton, SIGNAL(clicked(QAbstractButton*)), this, SLOT(saveImage())); connect(ui->listWidget, SIGNAL(currentRowChanged(int)), ui->stackedWidget, SLOT(setCurrentIndex(int))); connect(ui->treeImages, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(showImagePreview(QTreeWidgetItem*))); connect(ui->treeImages, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(imagesCustomContextMenuRequested(QPoint))); ui->treeImages->setContextMenuPolicy(Qt::CustomContextMenu); ui->treeImages->sortByColumn(-1); ui->treeTags->sortByColumn(-1); QzTools::setWmClass("Site Info", this); } bool SiteInfo::canShowSiteInfo(const QUrl &url) { if (LocationBar::convertUrlToText(url).isEmpty()) return false; - if (url.scheme() == QL1S("qupzilla") || url.scheme() == QL1S("view-source")) + if (url.scheme() == QL1S("falkon") || url.scheme() == QL1S("view-source")) return false; return true; } void SiteInfo::imagesCustomContextMenuRequested(const QPoint &p) { QTreeWidgetItem* item = ui->treeImages->itemAt(p); if (!item) { return; } QMenu menu; menu.addAction(QIcon::fromTheme("edit-copy"), tr("Copy Image Location"), this, SLOT(copyActionData()))->setData(item->text(1)); menu.addAction(tr("Copy Image Name"), this, SLOT(copyActionData()))->setData(item->text(0)); menu.addSeparator(); menu.addAction(QIcon::fromTheme("document-save"), tr("Save Image to Disk"), this, SLOT(saveImage())); menu.exec(ui->treeImages->viewport()->mapToGlobal(p)); } void SiteInfo::copyActionData() { if (QAction* action = qobject_cast(sender())) { qApp->clipboard()->setText(action->data().toString()); } } void SiteInfo::saveImage() { QTreeWidgetItem* item = ui->treeImages->currentItem(); if (!item) { return; } if (!ui->mediaPreview->scene() || ui->mediaPreview->scene()->items().isEmpty()) return; QGraphicsItem *graphicsItem = ui->mediaPreview->scene()->items().at(0); QGraphicsPixmapItem *pixmapItem = static_cast(graphicsItem); if (graphicsItem->type() != QGraphicsPixmapItem::Type || !pixmapItem) return; if (!pixmapItem || pixmapItem->pixmap().isNull()) { QMessageBox::warning(this, tr("Error!"), tr("This preview is not available!")); return; } QString imageFileName = QzTools::getFileNameFromUrl(QUrl(item->text(1))); int index = imageFileName.lastIndexOf(QLatin1Char('.')); if (index != -1) { imageFileName = imageFileName.left(index); imageFileName.append(QL1S(".png")); } QString filePath = QzTools::getSaveFileName("SiteInfo-DownloadImage", this, tr("Save image..."), QDir::homePath() + QDir::separator() + imageFileName, QSL("*.png")); if (filePath.isEmpty()) { return; } if (!pixmapItem->pixmap().save(filePath, "PNG")) { QMessageBox::critical(this, tr("Error!"), tr("Cannot write to file!")); return; } } void SiteInfo::showLoadingText() { delete ui->mediaPreview->scene(); QGraphicsScene* scene = new QGraphicsScene(ui->mediaPreview); scene->addText(tr("Loading...")); ui->mediaPreview->setScene(scene); } void SiteInfo::showPixmap(QPixmap pixmap) { pixmap.setDevicePixelRatio(devicePixelRatioF()); delete ui->mediaPreview->scene(); QGraphicsScene* scene = new QGraphicsScene(ui->mediaPreview); if (pixmap.isNull()) scene->addText(tr("Preview not available")); else scene->addPixmap(pixmap); ui->mediaPreview->setScene(scene); } void SiteInfo::showImagePreview(QTreeWidgetItem *item) { if (!item) { return; } QUrl imageUrl = QUrl::fromEncoded(item->text(1).toUtf8()); if (imageUrl.isRelative()) { imageUrl = m_baseUrl.resolved(imageUrl); } QPixmap pixmap; bool loading = false; if (imageUrl.scheme() == QLatin1String("data")) { QByteArray encodedUrl = item->text(1).toUtf8(); QByteArray imageData = encodedUrl.mid(encodedUrl.indexOf(',') + 1); pixmap = QzTools::pixmapFromByteArray(imageData); } else if (imageUrl.scheme() == QLatin1String("file")) { pixmap = QPixmap(imageUrl.toLocalFile()); } else if (imageUrl.scheme() == QLatin1String("qrc")) { pixmap = QPixmap(imageUrl.toString().mid(3)); // Remove qrc from url } else { delete m_imageReply; m_imageReply = mApp->networkManager()->get(QNetworkRequest(imageUrl)); connect(m_imageReply, &QNetworkReply::finished, this, [this]() { if (m_imageReply->error() != QNetworkReply::NoError) return; const QByteArray &data = m_imageReply->readAll(); showPixmap(QPixmap::fromImage(QImage::fromData(data))); }); loading = true; showLoadingText(); } if (!loading) showPixmap(pixmap); } SiteInfo::~SiteInfo() { delete ui; delete m_certWidget; } diff --git a/src/lib/other/siteinfo.h b/src/lib/other/siteinfo.h index c7835b51..ee80537c 100644 --- a/src/lib/other/siteinfo.h +++ b/src/lib/other/siteinfo.h @@ -1,65 +1,65 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef SITEINFO_H #define SITEINFO_H #include "qzcommon.h" #include #include namespace Ui { class SiteInfo; } class QNetworkReply; class QTreeWidgetItem; class WebView; class CertificateInfoWidget; -class QUPZILLA_EXPORT SiteInfo : public QWidget +class FALKON_EXPORT SiteInfo : public QWidget { Q_OBJECT public: explicit SiteInfo(WebView* view); ~SiteInfo(); static bool canShowSiteInfo(const QUrl &url); private slots: void showImagePreview(QTreeWidgetItem *item); void imagesCustomContextMenuRequested(const QPoint &p); void copyActionData(); void saveImage(); private: void showLoadingText(); void showPixmap(QPixmap pixmap); Ui::SiteInfo* ui; CertificateInfoWidget* m_certWidget; WebView* m_view; QNetworkReply *m_imageReply; QUrl m_baseUrl; }; #endif // SITEINFO_H diff --git a/src/lib/other/siteinfowidget.cpp b/src/lib/other/siteinfowidget.cpp index d3858d33..5ae26b01 100644 --- a/src/lib/other/siteinfowidget.cpp +++ b/src/lib/other/siteinfowidget.cpp @@ -1,90 +1,90 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "qztools.h" #include "siteinfowidget.h" #include "ui_siteinfowidget.h" #include "browserwindow.h" #include "mainapplication.h" #include "webpage.h" #include "tabbedwebview.h" #include #include SiteInfoWidget::SiteInfoWidget(BrowserWindow* window, QWidget* parent) : LocationBarPopup(parent) , ui(new Ui::SiteInfoWidget) , m_window(window) { this->setAttribute(Qt::WA_DeleteOnClose); ui->setupUi(this); setPopupAlignment(Qt::AlignLeft); WebView* view = m_window->weView(); if (view->url().scheme() == QL1S("https")) { ui->secureLabel->setText(tr("Your connection to this site is secured.")); ui->secureIcon->setPixmap(QPixmap(":/icons/locationbar/safe.png")); } else { ui->secureLabel->setText(tr("Your connection to this site is unsecured.")); ui->secureIcon->setPixmap(QPixmap(":/icons/locationbar/unsafe.png")); } QString scheme = view->url().scheme(); QSqlQuery query; QString host = view->url().host(); query.prepare("SELECT sum(count) FROM history WHERE url LIKE ?"); query.addBindValue(QString("%1://%2%").arg(scheme, host)); query.exec(); if (query.next()) { int count = query.value(0).toInt(); if (count > 3) { ui->historyLabel->setText(tr("This is your %1 visit of this site.").arg(QString::number(count) + ".")); ui->historyIcon->setPixmap(QPixmap(":/icons/locationbar/visit3.png")); } else if (count == 0) { ui->historyLabel->setText(tr("You have never visited this site before.")); ui->historyIcon->setPixmap(QPixmap(":/icons/locationbar/visit1.png")); } else { ui->historyIcon->setPixmap(QPixmap(":/icons/locationbar/visit2.png")); QString text; if (count == 1) { text = tr("first"); } else if (count == 2) { text = tr("second"); } else if (count == 3) { text = tr("third"); } ui->historyLabel->setText(tr("This is your %1 visit of this site.").arg(text)); } } connect(ui->pushButton, SIGNAL(clicked()), m_window->action(QSL("Tools/SiteInfo")), SLOT(trigger())); } SiteInfoWidget::~SiteInfoWidget() { delete ui; } diff --git a/src/lib/other/siteinfowidget.h b/src/lib/other/siteinfowidget.h index 24672530..416df5c7 100644 --- a/src/lib/other/siteinfowidget.h +++ b/src/lib/other/siteinfowidget.h @@ -1,45 +1,45 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef SITEINFOWIDGET_H #define SITEINFOWIDGET_H #include #include "qzcommon.h" #include namespace Ui { class SiteInfoWidget; } class BrowserWindow; -class QUPZILLA_EXPORT SiteInfoWidget : public LocationBarPopup +class FALKON_EXPORT SiteInfoWidget : public LocationBarPopup { Q_OBJECT public: explicit SiteInfoWidget(BrowserWindow* window, QWidget* parent = 0); ~SiteInfoWidget(); private: Ui::SiteInfoWidget* ui; BrowserWindow* m_window; }; #endif // SITEINFOWIDGET_H diff --git a/src/lib/other/statusbarmessage.cpp b/src/lib/other/statusbarmessage.cpp index 09b87df2..6cdcf20d 100644 --- a/src/lib/other/statusbarmessage.cpp +++ b/src/lib/other/statusbarmessage.cpp @@ -1,152 +1,152 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "statusbarmessage.h" #include "browserwindow.h" #include "tabwidget.h" #include "tabbedwebview.h" #include "squeezelabelv1.h" #include "mainapplication.h" #include "webpage.h" #include "proxystyle.h" #include "qztools.h" #include #include #include #include #include TipLabel::TipLabel(QWidget* parent) : SqueezeLabelV1(parent) { setWindowFlags(Qt::ToolTip); setForegroundRole(QPalette::ToolTipText); setBackgroundRole(QPalette::ToolTipBase); setPalette(QToolTip::palette()); ensurePolished(); setFrameStyle(QFrame::NoFrame); setMargin(3); m_timer = new QTimer(this); m_timer->setSingleShot(true); m_timer->setInterval(500); connect(m_timer, SIGNAL(timeout()), this, SLOT(hide())); } void TipLabel::show(QWidget* widget) { m_timer->stop(); widget->installEventFilter(this); SqueezeLabelV1::show(); } void TipLabel::hideDelayed() { m_timer->start(); } void TipLabel::resizeEvent(QResizeEvent* ev) { SqueezeLabelV1::resizeEvent(ev); // Oxygen is setting rounded corners only for top-level tooltips if (mApp->styleName() == QLatin1String("oxygen")) { setMask(QzTools::roundedRect(rect(), 4)); } } void TipLabel::paintEvent(QPaintEvent* ev) { QStylePainter p(this); QStyleOptionFrame opt; opt.init(this); p.drawPrimitive(QStyle::PE_PanelTipLabel, opt); p.end(); SqueezeLabelV1::paintEvent(ev); } bool TipLabel::eventFilter(QObject* o, QEvent* e) { Q_UNUSED(o); switch (e->type()) { case QEvent::Leave: case QEvent::WindowDeactivate: case QEvent::Wheel: hide(); break; case QEvent::MouseMove: case QEvent::MouseButtonPress: case QEvent::MouseButtonRelease: if (o == this) hide(); break; default: break; } return false; } StatusBarMessage::StatusBarMessage(BrowserWindow* window) : m_window(window) , m_statusBarText(new TipLabel(window)) { } void StatusBarMessage::showMessage(const QString &message) { if (m_window->statusBar()->isVisible()) { const static QChar LRE(0x202a); m_window->statusBar()->showMessage(message.isRightToLeft() ? message : (LRE + message)); } else if (mApp->activeWindow() == m_window) { WebView* view = m_window->weView(); const int verticalScrollSize = view->scrollBarGeometry(Qt::Vertical).width();; const int horizontalScrollSize = view->scrollBarGeometry(Qt::Horizontal).height(); m_statusBarText->setText(message); m_statusBarText->setMaximumWidth(view->width() - verticalScrollSize); m_statusBarText->resize(m_statusBarText->sizeHint()); QPoint position(0, view->height() - horizontalScrollSize - m_statusBarText->height()); const QRect statusRect = QRect(view->mapToGlobal(QPoint(0, position.y())), m_statusBarText->size()); if (statusRect.contains(QCursor::pos())) { position.setY(position.y() - m_statusBarText->height()); } m_statusBarText->move(view->mapToGlobal(position)); m_statusBarText->show(view); } } void StatusBarMessage::clearMessage() { if (m_window->statusBar()->isVisible()) { m_window->statusBar()->showMessage(QString()); } else { m_statusBarText->hideDelayed(); } } diff --git a/src/lib/other/statusbarmessage.h b/src/lib/other/statusbarmessage.h index 12fd57b9..bed1f304 100644 --- a/src/lib/other/statusbarmessage.h +++ b/src/lib/other/statusbarmessage.h @@ -1,61 +1,61 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef STATUSBARMESSAGE_H #define STATUSBARMESSAGE_H #include #include "qzcommon.h" #include "squeezelabelv1.h" #include "animatedwidget.h" class QTimer; class BrowserWindow; -class QUPZILLA_EXPORT TipLabel : public SqueezeLabelV1 +class FALKON_EXPORT TipLabel : public SqueezeLabelV1 { public: explicit TipLabel(QWidget* parent); void show(QWidget* widget); void hideDelayed(); bool eventFilter(QObject* o, QEvent* e); private: void resizeEvent(QResizeEvent* ev); void paintEvent(QPaintEvent* ev); QTimer* m_timer; }; -class QUPZILLA_EXPORT StatusBarMessage +class FALKON_EXPORT StatusBarMessage { public: explicit StatusBarMessage(BrowserWindow* window); void showMessage(const QString &message); void clearMessage(); private: BrowserWindow* m_window; TipLabel* m_statusBarText; }; #endif // STATUSBARMESSAGE_H diff --git a/src/lib/other/updater.cpp b/src/lib/other/updater.cpp index 85eef5ed..05dca110 100644 --- a/src/lib/other/updater.cpp +++ b/src/lib/other/updater.cpp @@ -1,161 +1,161 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "updater.h" #include "browserwindow.h" #include "qztools.h" #include "mainapplication.h" #include "tabwidget.h" #include "desktopnotificationsfactory.h" #include "networkmanager.h" #include #include #include Updater::Version::Version(const QString &s) : isValid(false) , majorVersion(-1) , minorVersion(-1) , revisionNumber(-1) { isValid = false; QStringList v = s.split(QLatin1Char('.')); if (v.count() != 3) { return; } bool ok; majorVersion = v.at(0).toInt(&ok); if (!ok) { return; } minorVersion = v.at(1).toInt(&ok); if (!ok) { return; } revisionNumber = v.at(2).toInt(&ok); if (!ok) { return; } isValid = majorVersion >= 0 && minorVersion >= 0 && revisionNumber >= 0; } bool Updater::Version::operator <(const Updater::Version &other) const { if (this->majorVersion != other.majorVersion) { return this->majorVersion < other.majorVersion; } if (this->minorVersion != other.minorVersion) { return this->minorVersion < other.minorVersion; } if (this->revisionNumber != other.revisionNumber) { return this->revisionNumber < other.revisionNumber; } return false; } bool Updater::Version::operator >(const Updater::Version &other) const { if (*this == other) { return false; } return !operator<(other); } bool Updater::Version::operator ==(const Updater::Version &other) const { return (this->majorVersion == other.majorVersion && this->minorVersion == other.minorVersion && this->revisionNumber == other.revisionNumber); } bool Updater::Version::operator >=(const Updater::Version &other) const { if (*this == other) { return true; } return *this > other; } bool Updater::Version::operator <=(const Updater::Version &other) const { if (*this == other) { return true; } return *this < other; } QString Updater::Version::versionString() const { return QString("%1.%2.%3").arg(majorVersion, minorVersion, revisionNumber); } Updater::Updater(BrowserWindow* window, QObject* parent) : QObject(parent) , m_window(window) { QTimer::singleShot(60 * 1000, this, SLOT(start())); // Start checking after 1 minute } void Updater::start() { QUrl url = QUrl(QString("%1/update.php?v=%2&os=%3").arg(Qz::WWWADDRESS, Qz::VERSION, QzTools::operatingSystem())); startDownloadingUpdateInfo(url); } void Updater::startDownloadingUpdateInfo(const QUrl &url) { QNetworkReply *reply = mApp->networkManager()->get(QNetworkRequest(QUrl(url))); connect(reply, SIGNAL(finished()), this, SLOT(downCompleted())); } void Updater::downCompleted() { QNetworkReply* reply = qobject_cast(sender()); if (!reply) return; QString html = reply->readAll(); if (html.startsWith(QLatin1String("Version:"))) { html.remove(QLatin1String("Version:")); Version current(Qz::VERSION); Version updated(html); if (current.isValid && updated.isValid && current < updated) { - mApp->desktopNotifications()->showNotification(QPixmap(":icons/qupzilla.png"), tr("Update available"), tr("New version of QupZilla is ready to download.")); + mApp->desktopNotifications()->showNotification(QPixmap(":icons/qupzilla.png"), tr("Update available"), tr("New version of Falkon is ready to download.")); } } reply->deleteLater(); } void Updater::downloadNewVersion() { m_window->tabWidget()->addView(QUrl::fromEncoded(QByteArray(Qz::WWWADDRESS) + QByteArray("/download")), tr("Update"), Qz::NT_NotSelectedTab); } diff --git a/src/lib/other/updater.h b/src/lib/other/updater.h index 0a23b07e..0e7a05cc 100644 --- a/src/lib/other/updater.h +++ b/src/lib/other/updater.h @@ -1,65 +1,65 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef UPDATER_H #define UPDATER_H #include #include "qzcommon.h" class QNetworkReply; class QUrl; class BrowserWindow; -class QUPZILLA_EXPORT Updater : public QObject +class FALKON_EXPORT Updater : public QObject { Q_OBJECT public: explicit Updater(BrowserWindow* window, QObject* parent = 0); - struct QUPZILLA_EXPORT Version { + struct FALKON_EXPORT Version { bool isValid; int majorVersion; int minorVersion; int revisionNumber; Version(const QString &s); bool operator<(const Version &other) const; bool operator>(const Version &other) const; bool operator==(const Version &other) const; bool operator>=(const Version &other) const; bool operator<=(const Version &other) const; QString versionString() const; }; private slots: void downCompleted(); void start(); void downloadNewVersion(); private: void startDownloadingUpdateInfo(const QUrl &url); BrowserWindow* m_window; }; #endif // UPDATER_H diff --git a/src/lib/other/useragentmanager.cpp b/src/lib/other/useragentmanager.cpp index ab5e1e79..52778b1a 100644 --- a/src/lib/other/useragentmanager.cpp +++ b/src/lib/other/useragentmanager.cpp @@ -1,97 +1,97 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "useragentmanager.h" #include "browserwindow.h" #include "qztools.h" #include "settings.h" #include #include UserAgentManager::UserAgentManager(QObject* parent) : QObject(parent) , m_usePerDomainUserAgent(false) { m_defaultUserAgent = QWebEngineProfile::defaultProfile()->httpUserAgent(); - m_defaultUserAgent.replace(QRegularExpression(QSL("QtWebEngine/[^\\s]+")), QSL("QupZilla/%1").arg(Qz::VERSION)); + m_defaultUserAgent.replace(QRegularExpression(QSL("QtWebEngine/[^\\s]+")), QSL("Falkon/%1").arg(Qz::VERSION)); } void UserAgentManager::loadSettings() { Settings settings; settings.beginGroup("Web-Browser-Settings"); m_globalUserAgent = settings.value("UserAgent", QString()).toString(); settings.endGroup(); settings.beginGroup("User-Agent-Settings"); m_usePerDomainUserAgent = settings.value("UsePerDomainUA", false).toBool(); QStringList domainList = settings.value("DomainList", QStringList()).toStringList(); QStringList userAgentsList = settings.value("UserAgentsList", QStringList()).toStringList(); settings.endGroup(); m_usePerDomainUserAgent = (m_usePerDomainUserAgent && domainList.count() == userAgentsList.count()); if (m_usePerDomainUserAgent) { for (int i = 0; i < domainList.count(); ++i) { m_userAgentsList[domainList.at(i)] = userAgentsList.at(i); } } const QString userAgent = m_globalUserAgent.isEmpty() ? m_defaultUserAgent : m_globalUserAgent; QWebEngineProfile::defaultProfile()->setHttpUserAgent(userAgent); } QString UserAgentManager::userAgentForUrl(const QUrl &url) const { const QString host = url.host(); if (m_usePerDomainUserAgent) { if (m_userAgentsList.contains(host)) { return m_userAgentsList.value(host); } QHashIterator i(m_userAgentsList); while (i.hasNext()) { i.next(); if (host.endsWith(i.key())) { return i.value(); } } } return QWebEngineProfile::defaultProfile()->httpUserAgent(); } QString UserAgentManager::globalUserAgent() const { return m_globalUserAgent; } QString UserAgentManager::defaultUserAgent() const { return m_defaultUserAgent; } bool UserAgentManager::usePerDomainUserAgents() const { return m_usePerDomainUserAgent; } QHash UserAgentManager::perDomainUserAgentsList() const { return m_userAgentsList; } diff --git a/src/lib/other/useragentmanager.h b/src/lib/other/useragentmanager.h index b8a94f0c..45477847 100644 --- a/src/lib/other/useragentmanager.h +++ b/src/lib/other/useragentmanager.h @@ -1,53 +1,53 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2015 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef USERAGENTMANAGER_H #define USERAGENTMANAGER_H #include #include #include "qzcommon.h" class QUrl; -class QUPZILLA_EXPORT UserAgentManager : QObject +class FALKON_EXPORT UserAgentManager : QObject { Q_OBJECT public: explicit UserAgentManager(QObject* parent = 0); void loadSettings(); QString userAgentForUrl(const QUrl &url) const; QString globalUserAgent() const; QString defaultUserAgent() const; bool usePerDomainUserAgents() const; QHash perDomainUserAgentsList() const; private: QString m_globalUserAgent; QString m_defaultUserAgent; bool m_usePerDomainUserAgent; QHash m_userAgentsList; }; #endif // USERAGENTMANAGER_H diff --git a/src/lib/plugins/plugininterface.h b/src/lib/plugins/plugininterface.h index 7378b7bc..b72a0a83 100644 --- a/src/lib/plugins/plugininterface.h +++ b/src/lib/plugins/plugininterface.h @@ -1,91 +1,91 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2016 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef PLUGININTERFACE_H #define PLUGININTERFACE_H #include #include #include #include "qzcommon.h" #include "webhittestresult.h" struct PluginSpec { QString name; QString info; QString description; QString author; QString version; QPixmap icon; bool hasSettings; PluginSpec() { hasSettings = false; } bool operator==(const PluginSpec &other) const { return (this->name == other.name && this->info == other.info && this->description == other.description && this->author == other.author && this->version == other.version); } }; class QTranslator; class QMenu; class QMouseEvent; class QKeyEvent; class QWheelEvent; class WebView; class WebPage; class PluginInterface { public: enum InitState { StartupInitState, LateInitState }; virtual PluginSpec pluginSpec() = 0; virtual void init(InitState state, const QString &settingsPath) = 0; virtual void unload() = 0; virtual bool testPlugin() = 0; virtual ~PluginInterface() { } virtual QTranslator* getTranslator(const QString &locale) { Q_UNUSED(locale) return 0; } virtual void showSettings(QWidget* parent = 0) { Q_UNUSED(parent) } virtual void populateWebViewMenu(QMenu* menu, WebView* view, const WebHitTestResult &r) { Q_UNUSED(menu) Q_UNUSED(view) Q_UNUSED(r) } virtual void populateExtensionsMenu(QMenu *menu) { Q_UNUSED(menu) } virtual bool mouseDoubleClick(const Qz::ObjectName &type, QObject* obj, QMouseEvent* event) { Q_UNUSED(type) Q_UNUSED(obj) Q_UNUSED(event) return false; } virtual bool mousePress(const Qz::ObjectName &type, QObject* obj, QMouseEvent* event) { Q_UNUSED(type) Q_UNUSED(obj) Q_UNUSED(event) return false; } virtual bool mouseRelease(const Qz::ObjectName &type, QObject* obj, QMouseEvent* event) { Q_UNUSED(type) Q_UNUSED(obj) Q_UNUSED(event) return false; } virtual bool mouseMove(const Qz::ObjectName &type, QObject* obj, QMouseEvent* event) { Q_UNUSED(type) Q_UNUSED(obj) Q_UNUSED(event) return false; } virtual bool wheelEvent(const Qz::ObjectName &type, QObject* obj, QWheelEvent* event) { Q_UNUSED(type) Q_UNUSED(obj) Q_UNUSED(event) return false; } virtual bool keyPress(const Qz::ObjectName &type, QObject* obj, QKeyEvent* event) { Q_UNUSED(type) Q_UNUSED(obj) Q_UNUSED(event) return false; } virtual bool keyRelease(const Qz::ObjectName &type, QObject* obj, QKeyEvent* event) { Q_UNUSED(type) Q_UNUSED(obj) Q_UNUSED(event) return false; } virtual bool acceptNavigationRequest(WebPage *page, const QUrl &url, QWebEnginePage::NavigationType type, bool isMainFrame) { Q_UNUSED(page); Q_UNUSED(url); Q_UNUSED(type); Q_UNUSED(isMainFrame); return true; } }; -Q_DECLARE_INTERFACE(PluginInterface, "QupZilla.Browser.PluginInterface/2.0") +Q_DECLARE_INTERFACE(PluginInterface, "Falkon.Browser.PluginInterface/2.0") #endif // PLUGININTERFACE_H diff --git a/src/lib/plugins/pluginproxy.cpp b/src/lib/plugins/pluginproxy.cpp index b536259a..014d896f 100644 --- a/src/lib/plugins/pluginproxy.cpp +++ b/src/lib/plugins/pluginproxy.cpp @@ -1,238 +1,238 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2016 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "pluginproxy.h" #include "plugininterface.h" #include "mainapplication.h" #include "settings.h" #include PluginProxy::PluginProxy() : Plugins() { connect(this, SIGNAL(pluginUnloaded(PluginInterface*)), this, SLOT(pluginUnloaded(PluginInterface*))); } void PluginProxy::registerAppEventHandler(const PluginProxy::EventHandlerType &type, PluginInterface* obj) { switch (type) { case MouseDoubleClickHandler: if (!m_mouseDoubleClickHandlers.contains(obj)) { m_mouseDoubleClickHandlers.append(obj); } break; case MousePressHandler: if (!m_mousePressHandlers.contains(obj)) { m_mousePressHandlers.append(obj); } break; case MouseReleaseHandler: if (!m_mouseReleaseHandlers.contains(obj)) { m_mouseReleaseHandlers.append(obj); } break; case MouseMoveHandler: if (!m_mouseMoveHandlers.contains(obj)) { m_mouseMoveHandlers.append(obj); } break; case KeyPressHandler: if (!m_keyPressHandlers.contains(obj)) { m_keyPressHandlers.append(obj); } break; case KeyReleaseHandler: if (!m_keyReleaseHandlers.contains(obj)) { m_keyReleaseHandlers.append(obj); } break; case WheelEventHandler: if (!m_wheelEventHandlers.contains(obj)) { m_wheelEventHandlers.append(obj); } break; default: qWarning("PluginProxy::registerAppEventHandler registering unknown event handler type"); break; } } void PluginProxy::pluginUnloaded(PluginInterface* plugin) { m_mousePressHandlers.removeOne(plugin); m_mouseReleaseHandlers.removeOne(plugin); m_mouseMoveHandlers.removeOne(plugin); m_wheelEventHandlers.removeOne(plugin); m_keyPressHandlers.removeOne(plugin); m_keyReleaseHandlers.removeOne(plugin); } void PluginProxy::populateWebViewMenu(QMenu* menu, WebView* view, const WebHitTestResult &r) { if (!menu || !view) { return; } foreach (PluginInterface* iPlugin, m_loadedPlugins) { iPlugin->populateWebViewMenu(menu, view, r); } } void PluginProxy::populateExtensionsMenu(QMenu *menu) { if (!menu) { return; } foreach (PluginInterface* iPlugin, m_loadedPlugins) { iPlugin->populateExtensionsMenu(menu); } } bool PluginProxy::processMouseDoubleClick(const Qz::ObjectName &type, QObject* obj, QMouseEvent* event) { bool accepted = false; foreach (PluginInterface* iPlugin, m_mouseDoubleClickHandlers) { if (iPlugin->mouseDoubleClick(type, obj, event)) { accepted = true; } } return accepted; } bool PluginProxy::processMousePress(const Qz::ObjectName &type, QObject* obj, QMouseEvent* event) { bool accepted = false; foreach (PluginInterface* iPlugin, m_mousePressHandlers) { if (iPlugin->mousePress(type, obj, event)) { accepted = true; } } return accepted; } bool PluginProxy::processMouseRelease(const Qz::ObjectName &type, QObject* obj, QMouseEvent* event) { bool accepted = false; foreach (PluginInterface* iPlugin, m_mouseReleaseHandlers) { if (iPlugin->mouseRelease(type, obj, event)) { accepted = true; } } return accepted; } bool PluginProxy::processMouseMove(const Qz::ObjectName &type, QObject* obj, QMouseEvent* event) { bool accepted = false; foreach (PluginInterface* iPlugin, m_mouseMoveHandlers) { if (iPlugin->mouseMove(type, obj, event)) { accepted = true; } } return accepted; } bool PluginProxy::processWheelEvent(const Qz::ObjectName &type, QObject* obj, QWheelEvent* event) { bool accepted = false; foreach (PluginInterface* iPlugin, m_wheelEventHandlers) { if (iPlugin->wheelEvent(type, obj, event)) { accepted = true; } } return accepted; } bool PluginProxy::processKeyPress(const Qz::ObjectName &type, QObject* obj, QKeyEvent* event) { bool accepted = false; foreach (PluginInterface* iPlugin, m_keyPressHandlers) { if (iPlugin->keyPress(type, obj, event)) { accepted = true; } } return accepted; } bool PluginProxy::processKeyRelease(const Qz::ObjectName &type, QObject* obj, QKeyEvent* event) { bool accepted = false; foreach (PluginInterface* iPlugin, m_keyReleaseHandlers) { if (iPlugin->keyRelease(type, obj, event)) { accepted = true; } } return accepted; } bool PluginProxy::acceptNavigationRequest(WebPage *page, const QUrl &url, QWebEnginePage::NavigationType type, bool isMainFrame) { bool accepted = true; foreach (PluginInterface* iPlugin, m_loadedPlugins) { if (!iPlugin->acceptNavigationRequest(page, url, type, isMainFrame)) { accepted = false; } } return accepted; } void PluginProxy::emitWebPageCreated(WebPage* page) { emit webPageCreated(page); } void PluginProxy::emitWebPageDeleted(WebPage* page) { emit webPageDeleted(page); } void PluginProxy::emitMainWindowCreated(BrowserWindow* window) { emit mainWindowCreated(window); } void PluginProxy::emitMainWindowDeleted(BrowserWindow* window) { emit mainWindowDeleted(window); } diff --git a/src/lib/plugins/pluginproxy.h b/src/lib/plugins/pluginproxy.h index da593fb6..3f82756c 100644 --- a/src/lib/plugins/pluginproxy.h +++ b/src/lib/plugins/pluginproxy.h @@ -1,103 +1,103 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef PLUGINPROXY_H #define PLUGINPROXY_H #include "plugins.h" #include "qzcommon.h" #include class WebPage; class BrowserWindow; -class QUPZILLA_EXPORT PluginProxy : public Plugins +class FALKON_EXPORT PluginProxy : public Plugins { Q_OBJECT public: enum EventHandlerType { MouseDoubleClickHandler, MousePressHandler, MouseReleaseHandler, MouseMoveHandler, KeyPressHandler, KeyReleaseHandler, WheelEventHandler }; explicit PluginProxy(); void registerAppEventHandler(const EventHandlerType &type, PluginInterface* obj); void populateWebViewMenu(QMenu* menu, WebView* view, const WebHitTestResult &r); void populateExtensionsMenu(QMenu *menu); bool processMouseDoubleClick(const Qz::ObjectName &type, QObject* obj, QMouseEvent* event); bool processMousePress(const Qz::ObjectName &type, QObject* obj, QMouseEvent* event); bool processMouseRelease(const Qz::ObjectName &type, QObject* obj, QMouseEvent* event); bool processMouseMove(const Qz::ObjectName &type, QObject* obj, QMouseEvent* event); bool processWheelEvent(const Qz::ObjectName &type, QObject* obj, QWheelEvent* event); bool processKeyPress(const Qz::ObjectName &type, QObject* obj, QKeyEvent* event); bool processKeyRelease(const Qz::ObjectName &type, QObject* obj, QKeyEvent* event); bool acceptNavigationRequest(WebPage *page, const QUrl &url, QWebEnginePage::NavigationType type, bool isMainFrame); void emitWebPageCreated(WebPage* page); void emitWebPageDeleted(WebPage* page); void emitMainWindowCreated(BrowserWindow* window); void emitMainWindowDeleted(BrowserWindow* window); signals: void webPageCreated(WebPage* page); void webPageDeleted(WebPage* page); void mainWindowCreated(BrowserWindow* window); void mainWindowDeleted(BrowserWindow* window); private slots: void pluginUnloaded(PluginInterface* plugin); private: QList m_mouseDoubleClickHandlers; QList m_mousePressHandlers; QList m_mouseReleaseHandlers; QList m_mouseMoveHandlers; QList m_wheelEventHandlers; QList m_keyPressHandlers; QList m_keyReleaseHandlers; }; #include "mainapplication.h" #include "networkmanager.h" #include "autofill.h" #include "passwordmanager.h" #define QZ_REGISTER_EVENT_HANDLER(Type) \ mApp->plugins()->registerAppEventHandler(Type, this); #define QZ_REGISTER_SCHEME_HANDLER(Scheme, Object) \ mApp->networkManager()->registerSchemeHandler(Scheme, Object); #define QZ_UNREGISTER_SCHEME_HANDLER(Scheme, Object) \ mApp->networkManager()->unregisterSchemeHandler(Scheme, Object); #define QZ_REGISTER_PASSWORD_BACKEND(Name, Object) \ mApp->autoFill()->passwordManager()->registerBackend(Name, Object); #define QZ_UNREGISTER_PASSWORD_BACKEND(Object) \ mApp->autoFill()->passwordManager()->unregisterBackend(Object); #endif // PLUGINPROXY_H diff --git a/src/lib/plugins/plugins.cpp b/src/lib/plugins/plugins.cpp index dc530449..32e84fb0 100644 --- a/src/lib/plugins/plugins.cpp +++ b/src/lib/plugins/plugins.cpp @@ -1,257 +1,257 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "pluginproxy.h" #include "plugininterface.h" #include "mainapplication.h" #include "speeddial.h" #include "settings.h" #include "datapaths.h" #include #include #include Plugins::Plugins(QObject* parent) : QObject(parent) , m_pluginsLoaded(false) , m_speedDial(new SpeedDial(this)) { loadSettings(); } QList Plugins::getAvailablePlugins() { loadAvailablePlugins(); return m_availablePlugins; } bool Plugins::loadPlugin(Plugins::Plugin* plugin) { if (plugin->isLoaded()) { return true; } plugin->pluginLoader->setFileName(plugin->fullPath); PluginInterface* iPlugin = qobject_cast(plugin->pluginLoader->instance()); if (!iPlugin) { return false; } m_availablePlugins.removeOne(*plugin); plugin->instance = initPlugin(PluginInterface::LateInitState, iPlugin, plugin->pluginLoader); m_availablePlugins.prepend(*plugin); refreshLoadedPlugins(); return plugin->isLoaded(); } void Plugins::unloadPlugin(Plugins::Plugin* plugin) { if (!plugin->isLoaded()) { return; } plugin->instance->unload(); plugin->pluginLoader->unload(); emit pluginUnloaded(plugin->instance); m_availablePlugins.removeOne(*plugin); plugin->instance = 0; m_availablePlugins.append(*plugin); refreshLoadedPlugins(); } void Plugins::loadSettings() { Settings settings; settings.beginGroup("Plugin-Settings"); m_pluginsEnabled = settings.value("EnablePlugins", !mApp->isPortable()).toBool(); m_allowedPlugins = settings.value("AllowedPlugins", QStringList()).toStringList(); settings.endGroup(); // Plugins are saved with relative path in portable mode #ifdef NO_SYSTEM_DATAPATH if (true) { #else if (mApp->isPortable()) { #endif QDir dir(DataPaths::path(DataPaths::Plugins)); for (int i = 0; i < m_allowedPlugins.count(); ++i) m_allowedPlugins[i] = dir.absoluteFilePath(QFileInfo(m_allowedPlugins[i]).fileName()); } c2f_loadSettings(); } void Plugins::shutdown() { c2f_saveSettings(); foreach (PluginInterface* iPlugin, m_loadedPlugins) { iPlugin->unload(); } } void Plugins::c2f_loadSettings() { Settings settings; settings.beginGroup("ClickToFlash"); c2f_whitelist = settings.value("whitelist", QStringList()).toStringList(); c2f_enabled = settings.value("Enabled", true).toBool(); settings.endGroup(); } void Plugins::c2f_saveSettings() { Settings settings; settings.beginGroup("ClickToFlash"); settings.setValue("whitelist", c2f_whitelist); settings.setValue("Enabled", c2f_enabled); settings.endGroup(); } void Plugins::loadPlugins() { if (!m_pluginsEnabled) { return; } QDir settingsDir(DataPaths::currentProfilePath() + "/extensions/"); if (!settingsDir.exists()) { settingsDir.mkdir(settingsDir.absolutePath()); } foreach (const QString &fullPath, m_allowedPlugins) { QPluginLoader* loader = new QPluginLoader(fullPath); PluginInterface* iPlugin = qobject_cast(loader->instance()); if (!iPlugin) { qWarning() << "Plugins::loadPlugins Loading" << fullPath << "failed:" << loader->errorString(); continue; } Plugin plugin; plugin.fileName = QFileInfo(fullPath).fileName(); plugin.fullPath = fullPath; plugin.pluginLoader = loader; plugin.instance = initPlugin(PluginInterface::StartupInitState, iPlugin, loader); if (plugin.isLoaded()) { plugin.pluginSpec = iPlugin->pluginSpec(); m_loadedPlugins.append(plugin.instance); m_availablePlugins.append(plugin); } } refreshLoadedPlugins(); - std::cout << "QupZilla: " << m_loadedPlugins.count() << " extensions loaded" << std::endl; + std::cout << "Falkon: " << m_loadedPlugins.count() << " extensions loaded" << std::endl; } void Plugins::loadAvailablePlugins() { if (m_pluginsLoaded) { return; } m_pluginsLoaded = true; QStringList dirs = DataPaths::allPaths(DataPaths::Plugins); // Portable build: Load only plugins from DATADIR/plugins/ directory. #ifndef NO_SYSTEM_DATAPATH if (mApp->isPortable()) #endif dirs = QStringList(DataPaths::path(DataPaths::Plugins)); foreach (const QString &dir, dirs) { QDir pluginsDir = QDir(dir); foreach (const QString &fileName, pluginsDir.entryList(QDir::Files)) { const QString absolutePath = pluginsDir.absoluteFilePath(fileName); QPluginLoader* loader = new QPluginLoader(absolutePath); PluginInterface* iPlugin = qobject_cast(loader->instance()); if (!iPlugin) { qWarning() << "Plugins::loadAvailablePlugins" << loader->errorString(); continue; } Plugin plugin; plugin.fileName = fileName; plugin.fullPath = absolutePath; plugin.pluginSpec = iPlugin->pluginSpec(); plugin.pluginLoader = loader; plugin.instance = 0; loader->unload(); if (!alreadySpecInAvailable(plugin.pluginSpec)) { m_availablePlugins.append(plugin); } } } } PluginInterface* Plugins::initPlugin(PluginInterface::InitState state, PluginInterface* pluginInterface, QPluginLoader* loader) { if (!pluginInterface) { return 0; } pluginInterface->init(state, DataPaths::currentProfilePath() + QL1S("/extensions")); if (!pluginInterface->testPlugin()) { pluginInterface->unload(); loader->unload(); emit pluginUnloaded(pluginInterface); return 0; } qApp->installTranslator(pluginInterface->getTranslator(mApp->currentLanguageFile())); return pluginInterface; } void Plugins::refreshLoadedPlugins() { m_loadedPlugins.clear(); foreach (const Plugin &plugin, m_availablePlugins) { if (plugin.isLoaded()) { m_loadedPlugins.append(plugin.instance); } } } bool Plugins::alreadySpecInAvailable(const PluginSpec &spec) { foreach (const Plugin &plugin, m_availablePlugins) { if (plugin.pluginSpec == spec) { return true; } } return false; } diff --git a/src/lib/plugins/plugins.h b/src/lib/plugins/plugins.h index 2d767cfb..6e90d905 100644 --- a/src/lib/plugins/plugins.h +++ b/src/lib/plugins/plugins.h @@ -1,112 +1,112 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef PLUGINLOADER_H #define PLUGINLOADER_H #include #include #include #include "qzcommon.h" #include "plugininterface.h" class QPluginLoader; class SpeedDial; -class QUPZILLA_EXPORT Plugins : public QObject +class FALKON_EXPORT Plugins : public QObject { Q_OBJECT public: struct Plugin { QString fileName; QString fullPath; PluginSpec pluginSpec; QPluginLoader* pluginLoader; PluginInterface* instance; Plugin() { pluginLoader = 0; instance = 0; } bool isLoaded() const { return instance; } bool operator==(const Plugin &other) const { return (this->fileName == other.fileName && this->fullPath == other.fullPath && this->pluginSpec == other.pluginSpec && this->instance == other.instance); } }; explicit Plugins(QObject* parent = 0); QList getAvailablePlugins(); bool loadPlugin(Plugin* plugin); void unloadPlugin(Plugin* plugin); void shutdown(); // CLick2Flash void c2f_loadSettings(); void c2f_saveSettings(); void c2f_addWhitelist(QString page) { c2f_whitelist.append(page); } void c2f_removeWhitelist(QString page) { c2f_whitelist.removeOne(page); } void c2f_setEnabled(bool en) { c2f_enabled = en; } bool c2f_isEnabled() { return c2f_enabled; } QStringList c2f_getWhiteList() { return c2f_whitelist; } // SpeedDial SpeedDial* speedDial() { return m_speedDial; } public slots: void loadSettings(); void loadPlugins(); protected: QList m_loadedPlugins; signals: void pluginUnloaded(PluginInterface* plugin); private: bool alreadySpecInAvailable(const PluginSpec &spec); PluginInterface* initPlugin(PluginInterface::InitState state , PluginInterface* pluginInterface, QPluginLoader* loader); void refreshLoadedPlugins(); void loadAvailablePlugins(); QList m_availablePlugins; QStringList m_allowedPlugins; bool m_pluginsEnabled; bool m_pluginsLoaded; SpeedDial* m_speedDial; QStringList c2f_whitelist; bool c2f_enabled; }; Q_DECLARE_METATYPE(Plugins::Plugin) #endif // PLUGINLOADER_H diff --git a/src/lib/plugins/speeddial.cpp b/src/lib/plugins/speeddial.cpp index 8db3e7a3..afa67ef3 100644 --- a/src/lib/plugins/speeddial.cpp +++ b/src/lib/plugins/speeddial.cpp @@ -1,384 +1,384 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "speeddial.h" #include "pagethumbnailer.h" #include "settings.h" #include "datapaths.h" #include "qztools.h" #include "autosaver.h" #include #include #include #include #include #define ENSURE_LOADED if (!m_loaded) loadSettings(); SpeedDial::SpeedDial(QObject* parent) : QObject(parent) , m_maxPagesInRow(4) , m_sizeOfSpeedDials(231) , m_sdcentered(false) , m_loaded(false) , m_regenerateScript(true) { m_autoSaver = new AutoSaver(this); connect(m_autoSaver, SIGNAL(save()), this, SLOT(saveSettings())); connect(this, SIGNAL(pagesChanged()), m_autoSaver, SLOT(changeOccurred())); } SpeedDial::~SpeedDial() { m_autoSaver->saveIfNecessary(); } void SpeedDial::loadSettings() { m_loaded = true; Settings settings; settings.beginGroup("SpeedDial"); QString allPages = settings.value("pages", QString()).toString(); setBackgroundImage(settings.value("background", QString()).toString()); m_backgroundImageSize = settings.value("backsize", "auto").toString(); m_maxPagesInRow = settings.value("pagesrow", 4).toInt(); m_sizeOfSpeedDials = settings.value("sdsize", 231).toInt(); m_sdcentered = settings.value("sdcenter", false).toBool(); settings.endGroup(); if (allPages.isEmpty()) { allPages = "url:\"https://www.qupzilla.com\"|title:\"QupZilla\";" "url:\"http://blog.qupzilla.com\"|title:\"QupZilla Blog\";" "url:\"https://github.com/QupZilla/qupzilla\"|title:\"QupZilla GitHub\";" "url:\"https://duckduckgo.com\"|title:\"DuckDuckGo\";"; } changed(allPages); m_thumbnailsDir = DataPaths::currentProfilePath() + "/thumbnails/"; // If needed, create thumbnails directory if (!QDir(m_thumbnailsDir).exists()) { QDir(DataPaths::currentProfilePath()).mkdir("thumbnails"); } } void SpeedDial::saveSettings() { ENSURE_LOADED; if (m_pages.isEmpty()) { return; } Settings settings; settings.beginGroup("SpeedDial"); settings.setValue("pages", generateAllPages()); settings.setValue("background", m_backgroundImageUrl); settings.setValue("backsize", m_backgroundImageSize); settings.setValue("pagesrow", m_maxPagesInRow); settings.setValue("sdsize", m_sizeOfSpeedDials); settings.setValue("sdcenter", m_sdcentered); settings.endGroup(); } SpeedDial::Page SpeedDial::pageForUrl(const QUrl &url) { ENSURE_LOADED; QString urlString = url.toString(); if (urlString.endsWith(QL1C('/'))) urlString = urlString.left(urlString.size() - 1); foreach (const Page &page, m_pages) { if (page.url == urlString) { return page; } } return Page(); } QUrl SpeedDial::urlForShortcut(int key) { ENSURE_LOADED; if (key < 0 || m_pages.count() <= key) { return QUrl(); } return QUrl::fromEncoded(m_pages.at(key).url.toUtf8()); } void SpeedDial::addPage(const QUrl &url, const QString &title) { ENSURE_LOADED; if (url.isEmpty()) { return; } Page page; page.title = escapeTitle(title); page.url = escapeUrl(url.toString()); m_pages.append(page); m_regenerateScript = true; emit pagesChanged(); } void SpeedDial::removePage(const Page &page) { ENSURE_LOADED; if (!page.isValid()) { return; } removeImageForUrl(page.url); m_pages.removeAll(page); m_regenerateScript = true; emit pagesChanged(); } int SpeedDial::pagesInRow() { ENSURE_LOADED; return m_maxPagesInRow; } int SpeedDial::sdSize() { ENSURE_LOADED; return m_sizeOfSpeedDials; } bool SpeedDial::sdCenter() { ENSURE_LOADED; return m_sdcentered; } QString SpeedDial::backgroundImage() { ENSURE_LOADED; return m_backgroundImage; } QString SpeedDial::backgroundImageUrl() { return m_backgroundImageUrl; } QString SpeedDial::backgroundImageSize() { ENSURE_LOADED; return m_backgroundImageSize; } QString SpeedDial::initialScript() { ENSURE_LOADED; if (!m_regenerateScript) { return m_initialScript; } m_regenerateScript = false; m_initialScript.clear(); foreach (const Page &page, m_pages) { QString imgSource = m_thumbnailsDir + QCryptographicHash::hash(page.url.toUtf8(), QCryptographicHash::Md4).toHex() + ".png"; if (!QFile(imgSource).exists()) { imgSource = "qrc:html/loading.gif"; if (!page.isValid()) { imgSource.clear(); } } else { imgSource = QzTools::pixmapToDataUrl(QPixmap(imgSource)).toString(); } m_initialScript.append(QString("addBox('%1', '%2', '%3');\n").arg(page.url, page.title, imgSource)); } return m_initialScript; } void SpeedDial::changed(const QString &allPages) { if (allPages.isEmpty()) { return; } const QStringList entries = allPages.split(QLatin1String("\";"), QString::SkipEmptyParts); m_pages.clear(); foreach (const QString &entry, entries) { if (entry.isEmpty()) { continue; } const QStringList tmp = entry.split(QLatin1String("\"|"), QString::SkipEmptyParts); if (tmp.count() != 2) { continue; } Page page; page.url = tmp.at(0).mid(5); page.title = tmp.at(1).mid(7); if (page.url.endsWith(QL1C('/'))) page.url = page.url.left(page.url.size() - 1); m_pages.append(page); } m_regenerateScript = true; emit pagesChanged(); } void SpeedDial::loadThumbnail(const QString &url, bool loadTitle) { PageThumbnailer* thumbnailer = new PageThumbnailer(this); thumbnailer->setUrl(QUrl::fromEncoded(url.toUtf8())); thumbnailer->setLoadTitle(loadTitle); connect(thumbnailer, SIGNAL(thumbnailCreated(QPixmap)), this, SLOT(thumbnailCreated(QPixmap))); thumbnailer->start(); } void SpeedDial::removeImageForUrl(const QString &url) { QString fileName = m_thumbnailsDir + QCryptographicHash::hash(url.toUtf8(), QCryptographicHash::Md4).toHex() + ".png"; if (QFile(fileName).exists()) { QFile(fileName).remove(); } } QStringList SpeedDial::getOpenFileName() { const QString fileTypes = QString("%3(*.png *.jpg *.jpeg *.bmp *.gif *.svg *.tiff)").arg(tr("Image files")); const QString image = QzTools::getOpenFileName("SpeedDial-GetOpenFileName", 0, tr("Select image..."), QDir::homePath(), fileTypes); if (image.isEmpty()) return QStringList(); return {QzTools::pixmapToDataUrl(QPixmap(image)).toString(), QUrl::fromLocalFile(image).toEncoded()}; } QString SpeedDial::urlFromUserInput(const QString &url) { return QUrl::fromUserInput(url).toString(); } void SpeedDial::setBackgroundImage(const QString &image) { m_backgroundImage = QzTools::pixmapToDataUrl(QPixmap(QUrl(image).toLocalFile())).toString(); m_backgroundImageUrl = image; } void SpeedDial::setBackgroundImageSize(const QString &size) { m_backgroundImageSize = size; } void SpeedDial::setPagesInRow(int count) { m_maxPagesInRow = count; } void SpeedDial::setSdSize(int count) { m_sizeOfSpeedDials = count; } void SpeedDial::setSdCentered(bool centered) { m_sdcentered = centered; m_autoSaver->changeOccurred(); } void SpeedDial::thumbnailCreated(const QPixmap &pixmap) { PageThumbnailer* thumbnailer = qobject_cast(sender()); if (!thumbnailer) { return; } bool loadTitle = thumbnailer->loadTitle(); QString title = thumbnailer->title(); QString url = thumbnailer->url().toString(); QString fileName = m_thumbnailsDir + QCryptographicHash::hash(url.toUtf8(), QCryptographicHash::Md4).toHex() + ".png"; if (pixmap.isNull()) { fileName = ":/html/broken-page.png"; title = tr("Unable to load"); } else { if (!pixmap.save(fileName, "PNG")) { qWarning() << "SpeedDial::thumbnailCreated Cannot save thumbnail to " << fileName; } //fileName = QUrl::fromLocalFile(fileName).toString(); } m_regenerateScript = true; thumbnailer->deleteLater(); if (loadTitle) emit pageTitleLoaded(url, title); emit thumbnailLoaded(url, QzTools::pixmapToDataUrl(QPixmap(fileName)).toString()); } QString SpeedDial::escapeTitle(QString title) const { title.replace(QLatin1Char('"'), QLatin1String(""")); title.replace(QLatin1Char('\''), QLatin1String("'")); return title; } QString SpeedDial::escapeUrl(QString url) const { url.remove(QLatin1Char('"')); url.remove(QLatin1Char('\'')); return url; } QString SpeedDial::generateAllPages() { QString allPages; foreach (const Page &page, m_pages) { const QString string = QString("url:\"%1\"|title:\"%2\";").arg(page.url, page.title); allPages.append(string); } return allPages; } diff --git a/src/lib/plugins/speeddial.h b/src/lib/plugins/speeddial.h index 494b0f9c..95fc2e12 100644 --- a/src/lib/plugins/speeddial.h +++ b/src/lib/plugins/speeddial.h @@ -1,115 +1,115 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef SPEEDDIAL_H #define SPEEDDIAL_H #include #include #include #include "qzcommon.h" class QUrl; class QPixmap; class AutoSaver; class PageThumbnailer; -class QUPZILLA_EXPORT SpeedDial : public QObject +class FALKON_EXPORT SpeedDial : public QObject { Q_OBJECT public: struct Page { QString title; QString url; bool isValid() const { return !url.isEmpty(); } bool operator==(const Page &other) { return (this->title == other.title && this->url == other.url); } }; explicit SpeedDial(QObject* parent = 0); ~SpeedDial(); void loadSettings(); Page pageForUrl(const QUrl &url); QUrl urlForShortcut(int key); void addPage(const QUrl &url, const QString &title); void removePage(const Page &page); int pagesInRow(); int sdSize(); bool sdCenter(); QString backgroundImage(); QString backgroundImageUrl(); QString backgroundImageSize(); QString initialScript(); signals: void pagesChanged(); void thumbnailLoaded(const QString &url, const QString &src); void pageTitleLoaded(const QString &url, const QString &title); public slots: void changed(const QString &allPages); void loadThumbnail(const QString &url, bool loadTitle); void removeImageForUrl(const QString &url); QStringList getOpenFileName(); QString urlFromUserInput(const QString &url); void setBackgroundImage(const QString &image); void setBackgroundImageSize(const QString &size); void setPagesInRow(int count); void setSdSize(int count); void setSdCentered(bool centered); private slots: void thumbnailCreated(const QPixmap &pixmap); void saveSettings(); private: QString escapeTitle(QString string) const; QString escapeUrl(QString url) const; QString generateAllPages(); QString m_initialScript; QString m_thumbnailsDir; QString m_backgroundImage; QString m_backgroundImageUrl; QString m_backgroundImageSize; int m_maxPagesInRow; int m_sizeOfSpeedDials; bool m_sdcentered; QList m_pages; AutoSaver* m_autoSaver; bool m_loaded; bool m_regenerateScript; }; #endif // SPEEDDIAL_H diff --git a/src/lib/popupwindow/popuplocationbar.cpp b/src/lib/popupwindow/popuplocationbar.cpp index 5fbf4a13..3c83b320 100644 --- a/src/lib/popupwindow/popuplocationbar.cpp +++ b/src/lib/popupwindow/popuplocationbar.cpp @@ -1,110 +1,110 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2016 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "popuplocationbar.h" #include "popupwebview.h" #include "toolbutton.h" #include "qztools.h" #include "iconprovider.h" #include "bookmarksicon.h" #include "autofillicon.h" #include "webpage.h" -class QUPZILLA_EXPORT PopupSiteIcon : public QWidget +class FALKON_EXPORT PopupSiteIcon : public QWidget { public: explicit PopupSiteIcon(QWidget* parent = 0) : QWidget(parent) { } void setIcon(const QIcon &icon) { m_icon = QIcon(icon.pixmap(16)); update(); } private: QIcon m_icon; void paintEvent(QPaintEvent*) { QPainter p(this); m_icon.paint(&p, rect()); } }; PopupLocationBar::PopupLocationBar(QWidget* parent) : LineEdit(parent) , m_view(0) { m_siteIcon = new PopupSiteIcon(this); m_siteIcon->setIcon(IconProvider::emptyWebIcon()); m_siteIcon->setFixedSize(26, 26); m_bookmarkIcon = new BookmarksIcon(this); m_autofillIcon = new AutoFillIcon(this); QWidget* rightSpacer = new QWidget(this); rightSpacer->setFixedWidth(3); addWidget(m_siteIcon, LineEdit::LeftSide); addWidget(m_autofillIcon, LineEdit::RightSide); addWidget(m_bookmarkIcon, LineEdit::RightSide); addWidget(rightSpacer, LineEdit::RightSide); setLeftMargin(24); setFixedHeight(26); setReadOnly(true); // Hide icons by default m_autofillIcon->hide(); } void PopupLocationBar::setView(PopupWebView* view) { m_view = view; m_bookmarkIcon->setWebView(m_view); m_autofillIcon->setWebView(m_view); } void PopupLocationBar::startLoading() { m_autofillIcon->hide(); updateTextMargins(); } void PopupLocationBar::stopLoading() { m_bookmarkIcon->checkBookmark(m_view->url()); WebPage* page = qobject_cast(m_view->page()); if (page && page->hasMultipleUsernames()) { m_autofillIcon->setFormData(page->autoFillData()); m_autofillIcon->show(); } updateTextMargins(); } void PopupLocationBar::showUrl(const QUrl &url) { setText(QzTools::urlEncodeQueryString(url)); setCursorPosition(0); } void PopupLocationBar::showSiteIcon() { m_siteIcon->setIcon(m_view->icon()); } diff --git a/src/lib/popupwindow/popuplocationbar.h b/src/lib/popupwindow/popuplocationbar.h index 1ef7ded1..1f122fe8 100644 --- a/src/lib/popupwindow/popuplocationbar.h +++ b/src/lib/popupwindow/popuplocationbar.h @@ -1,58 +1,58 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2016 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef POPUPLOCATIONBAR_H #define POPUPLOCATIONBAR_H #include "qzcommon.h" #include "lineedit.h" class QUrl; class PopupSiteIcon; class PopupWebView; class AutoFillIcon; class BookmarksIcon; -class QUPZILLA_EXPORT PopupLocationBar : public LineEdit +class FALKON_EXPORT PopupLocationBar : public LineEdit { Q_OBJECT Q_PROPERTY(QSize fixedsize READ size WRITE setFixedSize) Q_PROPERTY(int fixedwidth READ width WRITE setFixedWidth) Q_PROPERTY(int fixedheight READ height WRITE setFixedHeight) public: explicit PopupLocationBar(QWidget* parent = 0); void setView(PopupWebView* view); void startLoading(); void stopLoading(); public slots: void showUrl(const QUrl &url); void showSiteIcon(); private: PopupWebView* m_view; PopupSiteIcon* m_siteIcon; AutoFillIcon* m_autofillIcon; BookmarksIcon* m_bookmarkIcon; }; #endif // POPUPLOCATIONBAR_H diff --git a/src/lib/popupwindow/popupstatusbarmessage.cpp b/src/lib/popupwindow/popupstatusbarmessage.cpp index 129fde2a..ef011482 100644 --- a/src/lib/popupwindow/popupstatusbarmessage.cpp +++ b/src/lib/popupwindow/popupstatusbarmessage.cpp @@ -1,72 +1,72 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "popupstatusbarmessage.h" #include "popupwindow.h" #include "popupwebview.h" #include "webpage.h" #include "statusbarmessage.h" #include "mainapplication.h" #include #include PopupStatusBarMessage::PopupStatusBarMessage(PopupWindow* window) : m_popupWindow(window) , m_statusBarText(new TipLabel(window)) { } void PopupStatusBarMessage::showMessage(const QString &message) { if (m_popupWindow->statusBar()->isVisible()) { m_popupWindow->statusBar()->showMessage(message); } #ifdef Q_OS_WIN else if (mApp->activeWindow() == m_popupWindow) { #else else { #endif PopupWebView* view = m_popupWindow->webView(); m_statusBarText->setText(message); m_statusBarText->setMaximumWidth(view->width()); m_statusBarText->resize(m_statusBarText->sizeHint()); QPoint position; position.setY(view->height() - m_statusBarText->height()); QRect statusRect = QRect(view->mapToGlobal(QPoint(0, position.y())), m_statusBarText->size()); if (statusRect.contains(QCursor::pos())) { position.setY(position.y() - m_statusBarText->height()); } m_statusBarText->move(view->mapToGlobal(position)); m_statusBarText->show(view); } } void PopupStatusBarMessage::clearMessage() { if (m_popupWindow->statusBar()->isVisible()) { m_popupWindow->statusBar()->showMessage(QString()); } else { m_statusBarText->hideDelayed(); } } diff --git a/src/lib/popupwindow/popupstatusbarmessage.h b/src/lib/popupwindow/popupstatusbarmessage.h index 808ad2a1..05cc947f 100644 --- a/src/lib/popupwindow/popupstatusbarmessage.h +++ b/src/lib/popupwindow/popupstatusbarmessage.h @@ -1,39 +1,39 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef POPUPSTATUSBARMESSAGE_H #define POPUPSTATUSBARMESSAGE_H #include "qzcommon.h" class PopupWindow; class TipLabel; -class QUPZILLA_EXPORT PopupStatusBarMessage +class FALKON_EXPORT PopupStatusBarMessage { public: explicit PopupStatusBarMessage(PopupWindow* window); void showMessage(const QString &message); void clearMessage(); private: PopupWindow* m_popupWindow; TipLabel* m_statusBarText; }; #endif // POPUPSTATUSBARMESSAGE_H diff --git a/src/lib/popupwindow/popupwebview.cpp b/src/lib/popupwindow/popupwebview.cpp index 3ca7d77a..4a053a00 100644 --- a/src/lib/popupwindow/popupwebview.cpp +++ b/src/lib/popupwindow/popupwebview.cpp @@ -1,113 +1,113 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "popupwebview.h" #include "mainapplication.h" #include "browserwindow.h" #include "tabwidget.h" #include "tabbedwebview.h" #include "iconprovider.h" #include "enhancedmenu.h" #include "loadrequest.h" #include "webpage.h" #include "webhittestresult.h" #include "webinspector.h" #include PopupWebView::PopupWebView(QWidget* parent) : WebView(parent) , m_menu(new Menu(this)) { m_menu->setCloseOnMiddleClick(true); } QWidget* PopupWebView::overlayWidget() { return parentWidget(); } void PopupWebView::loadInNewTab(const LoadRequest &req, Qz::NewTabPositionFlags position) { Q_UNUSED(position) BrowserWindow* window = mApp->getWindow(); if (window) { int index = window->tabWidget()->addView(QUrl(), Qz::NT_SelectedTab); window->weView(index)->load(req); window->raise(); } } void PopupWebView::closeView() { window()->close(); } bool PopupWebView::isFullScreen() { return parentWidget()->isFullScreen(); } void PopupWebView::requestFullScreen(bool enable) { if (enable) parentWidget()->showFullScreen(); else parentWidget()->showNormal(); } void PopupWebView::inspectElement() { if (!WebInspector::isEnabled()) return; if (m_inspector) { triggerPageAction(QWebEnginePage::InspectElement); return; } m_inspector = new WebInspector; m_inspector->setView(this); m_inspector->inspectElement(); m_inspector->show(); } void PopupWebView::_contextMenuEvent(QContextMenuEvent *event) { m_menu->clear(); WebHitTestResult hitTest = page()->hitTestContent(event->pos()); createContextMenu(m_menu, hitTest); if (WebInspector::isEnabled()) { m_menu->addSeparator(); m_menu->addAction(tr("Inspect Element"), this, SLOT(inspectElement())); } if (!m_menu->isEmpty()) { // Prevent choosing first option with double rightclick const QPoint pos = event->globalPos(); QPoint p(pos.x(), pos.y() + 1); m_menu->popup(p); return; } WebView::_contextMenuEvent(event); } diff --git a/src/lib/popupwindow/popupwebview.h b/src/lib/popupwindow/popupwebview.h index 788f8be6..f70f61c5 100644 --- a/src/lib/popupwindow/popupwebview.h +++ b/src/lib/popupwindow/popupwebview.h @@ -1,53 +1,53 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2015 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef POPUPWEBVIEW_H #define POPUPWEBVIEW_H #include #include "qzcommon.h" #include "webview.h" class Menu; class LoadRequest; class WebInspector; -class QUPZILLA_EXPORT PopupWebView : public WebView +class FALKON_EXPORT PopupWebView : public WebView { Q_OBJECT public: explicit PopupWebView(QWidget* parent = 0); QWidget* overlayWidget() Q_DECL_OVERRIDE; void loadInNewTab(const LoadRequest &req, Qz::NewTabPositionFlags position) Q_DECL_OVERRIDE; void closeView() Q_DECL_OVERRIDE; bool isFullScreen() Q_DECL_OVERRIDE; void requestFullScreen(bool enable) Q_DECL_OVERRIDE; public slots: void inspectElement(); private: void _contextMenuEvent(QContextMenuEvent *event) Q_DECL_OVERRIDE; Menu* m_menu; QPointer m_inspector; }; #endif // POPUPWEBVIEW_H diff --git a/src/lib/popupwindow/popupwindow.cpp b/src/lib/popupwindow/popupwindow.cpp index b786208a..cd963b15 100644 --- a/src/lib/popupwindow/popupwindow.cpp +++ b/src/lib/popupwindow/popupwindow.cpp @@ -1,278 +1,278 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "popupwindow.h" #include "popupwebview.h" #include "webpage.h" #include "popupstatusbarmessage.h" #include "progressbar.h" #include "searchtoolbar.h" #include "qzsettings.h" #include "popuplocationbar.h" #include "qztools.h" #include "mainapplication.h" #include "browserwindow.h" #include #include #include #include PopupWindow::PopupWindow(PopupWebView* view) : QWidget() , m_view(view) , m_search(0) { m_layout = new QVBoxLayout(this); m_layout->setContentsMargins(0, 0, 0, 0); m_layout->setSpacing(2); m_locationBar = new PopupLocationBar(this); m_locationBar->setView(m_view); m_statusBar = new QStatusBar(this); m_statusBar->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum); m_progressBar = new ProgressBar(m_statusBar); m_statusBar->addPermanentWidget(m_progressBar); m_progressBar->hide(); m_view->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); m_statusBarMessage = new PopupStatusBarMessage(this); m_notificationWidget = new QWidget(this); m_notificationWidget->setAutoFillBackground(true); QPalette pal = m_notificationWidget->palette(); pal.setColor(QPalette::Background, pal.window().color().darker(110)); m_notificationWidget->setPalette(pal); QVBoxLayout *nlayout = new QVBoxLayout(m_notificationWidget); nlayout->setSizeConstraint(QLayout::SetMinAndMaxSize); nlayout->setContentsMargins(0, 0, 0, 0); nlayout->setSpacing(1); m_menuBar = new QMenuBar(this); QMenu* menuFile = new QMenu(tr("File")); menuFile->addAction(QIcon::fromTheme("mail-message-new"), tr("Send Link..."), m_view, SLOT(sendPageByMail())); menuFile->addAction(QIcon::fromTheme("document-print"), tr("&Print..."), m_view, SLOT(printPage()))->setShortcut(QKeySequence("Ctrl+P")); menuFile->addSeparator(); menuFile->addAction(QIcon::fromTheme("window-close"), tr("Close"), this, SLOT(close()))->setShortcut(QKeySequence("Ctrl+W")); m_menuBar->addMenu(menuFile); m_menuEdit = new QMenu(tr("Edit")); m_menuEdit->addAction(m_view->pageAction(QWebEnginePage::Undo)); m_menuEdit->addAction(m_view->pageAction(QWebEnginePage::Redo)); m_menuEdit->addSeparator(); m_menuEdit->addAction(m_view->pageAction(QWebEnginePage::Cut)); m_menuEdit->addAction(m_view->pageAction(QWebEnginePage::Copy)); m_menuEdit->addAction(m_view->pageAction(QWebEnginePage::Paste)); m_menuEdit->addSeparator(); m_menuEdit->addAction(m_view->pageAction(QWebEnginePage::SelectAll)); m_menuEdit->addAction(QIcon::fromTheme("edit-find"), tr("Find"), this, SLOT(searchOnPage()))->setShortcut(QKeySequence("Ctrl+F")); m_menuBar->addMenu(m_menuEdit); m_menuView = new QMenu(tr("View")); m_actionStop = m_menuView->addAction(QIcon::fromTheme(QSL("process-stop")), tr("&Stop"), m_view, SLOT(stop())); m_actionStop->setShortcut(QKeySequence("Esc")); m_actionReload = m_menuView->addAction(QIcon::fromTheme(QSL("view-refresh")), tr("&Reload"), m_view, SLOT(reload())); m_actionReload->setShortcut(QKeySequence("F5")); m_menuView->addSeparator(); m_menuView->addAction(QIcon::fromTheme("zoom-in"), tr("Zoom &In"), m_view, SLOT(zoomIn()))->setShortcut(QKeySequence("Ctrl++")); m_menuView->addAction(QIcon::fromTheme("zoom-out"), tr("Zoom &Out"), m_view, SLOT(zoomOut()))->setShortcut(QKeySequence("Ctrl+-")); m_menuView->addAction(QIcon::fromTheme("zoom-original"), tr("Reset"), m_view, SLOT(zoomReset()))->setShortcut(QKeySequence("Ctrl+0")); m_menuView->addSeparator(); m_menuView->addAction(QIcon::fromTheme("text-html"), tr("&Page Source"), m_view, SLOT(showSource()))->setShortcut(QKeySequence("Ctrl+U")); m_menuBar->addMenu(m_menuView); // Make shortcuts available even with hidden menubar QList actions = m_menuBar->actions(); foreach (QAction* action, actions) { if (action->menu()) { actions += action->menu()->actions(); } addAction(action); } QVBoxLayout *l = new QVBoxLayout(); l->setContentsMargins(0, 0, 0, 0); l->setSpacing(0); l->addWidget(m_view); QWidget *viewWidget = new QWidget(this); viewWidget->setLayout(l); m_layout->insertWidget(0, m_menuBar); m_layout->addWidget(m_locationBar); m_layout->addWidget(viewWidget); m_layout->addWidget(m_statusBar); setLayout(m_layout); connect(m_view, &WebView::showNotification, this, &PopupWindow::showNotification); connect(m_view, &WebView::titleChanged, this, &PopupWindow::titleChanged); connect(m_view, &WebView::urlChanged, m_locationBar, &PopupLocationBar::showUrl); connect(m_view, &WebView::iconChanged, m_locationBar, &PopupLocationBar::showSiteIcon); connect(m_view, &WebView::loadStarted, this, &PopupWindow::loadStarted); connect(m_view, &WebView::loadProgress, this, &PopupWindow::loadProgress); connect(m_view, &WebView::loadFinished, this, &PopupWindow::loadFinished); connect(m_view->page(), &WebPage::linkHovered, this, &PopupWindow::showStatusBarMessage); connect(m_view->page(), &WebPage::geometryChangeRequested, this, &PopupWindow::setWindowGeometry); m_view->setFocus(); titleChanged(); QUrl urlToShow = m_view->url(); if (urlToShow.isEmpty()) { urlToShow = m_view->page()->requestedUrl(); } m_locationBar->showUrl(urlToShow); if (mApp->getWindow()) { m_statusBar->setVisible(mApp->getWindow()->statusBar()->isVisible()); m_menuBar->setVisible(mApp->getWindow()->menuBar()->isVisible()); if (m_menuBar->isHidden()) m_layout->setContentsMargins(0, 2, 0, 0); } // Ensuring correct sizes for widgets in layout are calculated even // before calling QWidget::show() m_layout->invalidate(); m_layout->activate(); } QStatusBar* PopupWindow::statusBar() { return m_statusBar; } PopupWebView* PopupWindow::webView() { return m_view; } void PopupWindow::showNotification(QWidget* notif) { m_notificationWidget->setParent(nullptr); m_notificationWidget->setParent(m_view->overlayWidget()); m_notificationWidget->setFixedWidth(m_view->width()); m_notificationWidget->layout()->addWidget(notif); m_notificationWidget->show(); notif->show(); } void PopupWindow::showStatusBarMessage(const QString &message) { if (message.isEmpty()) { m_statusBarMessage->clearMessage(); } else { m_statusBarMessage->showMessage(message); } } void PopupWindow::loadStarted() { m_progressBar->setValue(0); m_progressBar->show(); m_locationBar->startLoading(); if (m_actionStop) { m_actionStop->setEnabled(true); m_actionReload->setEnabled(false); } } void PopupWindow::loadProgress(int value) { m_progressBar->setValue(value); } void PopupWindow::loadFinished() { m_progressBar->hide(); m_locationBar->stopLoading(); if (m_actionStop) { m_actionStop->setEnabled(false); m_actionReload->setEnabled(true); } } void PopupWindow::closeEvent(QCloseEvent* event) { if (m_view->page()->isRunningLoop()) { event->ignore(); return; } m_view->deleteLater(); event->accept(); } void PopupWindow::resizeEvent(QResizeEvent *event) { QWidget::resizeEvent(event); m_notificationWidget->setFixedWidth(m_view->width()); } void PopupWindow::searchOnPage() { if (!m_search) { m_search = new SearchToolBar(m_view, this); m_search.data()->showMinimalInPopupWindow(); m_layout->insertWidget(m_layout->count() - 1, m_search); } m_search->focusSearchLine(); } void PopupWindow::titleChanged() { - setWindowTitle(tr("%1 - QupZilla").arg(m_view->title())); + setWindowTitle(tr("%1 - Falkon").arg(m_view->title())); } void PopupWindow::setWindowGeometry(QRect newRect) { if (!Settings().value("allowJavaScriptGeometryChange", true).toBool()) return; // left/top was set while width/height not if (!newRect.topLeft().isNull() && newRect.size().isNull()) { newRect.setSize(QSize(550, 585)); } if (newRect.isValid()) { QRect oldRect = rect(); move(newRect.topLeft()); QSize newSize = newRect.size(); int additionalHeight = height() - m_view->height(); newSize.setHeight(newSize.height() + additionalHeight); resize(newSize); if (newRect.topLeft() == QPoint(0, 0) && oldRect.topLeft() == QPoint(0, 0)) { QzTools::centerWidgetOnScreen(this); } } } diff --git a/src/lib/popupwindow/popupwindow.h b/src/lib/popupwindow/popupwindow.h index 16059682..85b4bb70 100644 --- a/src/lib/popupwindow/popupwindow.h +++ b/src/lib/popupwindow/popupwindow.h @@ -1,81 +1,81 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef POPUPWINDOW_H #define POPUPWINDOW_H #include #include #include "qzcommon.h" class QVBoxLayout; class QStatusBar; class QMenuBar; class QMenu; class WebPage; class PopupWebView; class PopupStatusBarMessage; class PopupLocationBar; class ProgressBar; class SearchToolBar; -class QUPZILLA_EXPORT PopupWindow : public QWidget +class FALKON_EXPORT PopupWindow : public QWidget { Q_OBJECT public: explicit PopupWindow(PopupWebView* view); QStatusBar* statusBar(); PopupWebView* webView(); public slots: void setWindowGeometry(QRect newRect); private slots: void titleChanged(); void showNotification(QWidget* notif); void showStatusBarMessage(const QString &message); void loadStarted(); void loadProgress(int value); void loadFinished(); void searchOnPage(); private: void closeEvent(QCloseEvent* event); void resizeEvent(QResizeEvent *event) override; PopupWebView* m_view; PopupLocationBar* m_locationBar; PopupStatusBarMessage* m_statusBarMessage; ProgressBar* m_progressBar; QVBoxLayout* m_layout; QStatusBar* m_statusBar; QMenuBar* m_menuBar; QMenu* m_menuEdit; QMenu* m_menuView; QAction* m_actionReload; QAction* m_actionStop; QPointer m_search; QWidget *m_notificationWidget; }; #endif // POPUPWINDOW_H diff --git a/src/lib/preferences/acceptlanguage.cpp b/src/lib/preferences/acceptlanguage.cpp index fa02a5c6..da698651 100644 --- a/src/lib/preferences/acceptlanguage.cpp +++ b/src/lib/preferences/acceptlanguage.cpp @@ -1,228 +1,228 @@ /* * Copyright 2009 Benjamin C. Meyer * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA */ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "acceptlanguage.h" #include "ui_acceptlanguage.h" #include "ui_addacceptlanguage.h" #include "mainapplication.h" #include "networkmanager.h" #include "settings.h" QStringList AcceptLanguage::defaultLanguage() { QString longCode = QLocale::system().name().replace(QLatin1Char('_'), QLatin1Char('-')); if (longCode.size() == 5) { QStringList ret; ret << longCode << longCode.left(2); return ret; } return QStringList(longCode); } QByteArray AcceptLanguage::generateHeader(const QStringList &langs) { if (langs.count() == 0) { return QByteArray(); } QByteArray header; header.append(langs.at(0)); int counter = 8; for (int i = 1; i < langs.count(); i++) { QString s = "," + langs.at(i) + ";q=0."; s.append(QString::number(counter)); if (counter != 2) { counter -= 2; } header.append(s); } return header; } AcceptLanguage::AcceptLanguage(QWidget* parent) : QDialog(parent) , ui(new Ui::AcceptLanguage) { setAttribute(Qt::WA_DeleteOnClose); ui->setupUi(this); ui->listWidget->setLayoutDirection(Qt::LeftToRight); Settings settings; settings.beginGroup("Language"); QStringList langs = settings.value("acceptLanguage", defaultLanguage()).toStringList(); settings.endGroup(); foreach (const QString &code, langs) { QString code_ = code; QLocale loc = QLocale(code_.replace(QLatin1Char('-'), QLatin1Char('_'))); QString label; if (loc.language() == QLocale::C) { label = tr("Personal [%1]").arg(code); } else { label = QString("%1/%2 [%3]").arg(loc.languageToString(loc.language()), loc.countryToString(loc.country()), code); } ui->listWidget->addItem(label); } connect(ui->add, SIGNAL(clicked()), this, SLOT(addLanguage())); connect(ui->remove, SIGNAL(clicked()), this, SLOT(removeLanguage())); connect(ui->up, SIGNAL(clicked()), this, SLOT(upLanguage())); connect(ui->down, SIGNAL(clicked()), this, SLOT(downLanguage())); } QStringList AcceptLanguage::expand(const QLocale::Language &language) { QStringList allLanguages; QList countries = QLocale::countriesForLanguage(language); for (int j = 0; j < countries.size(); ++j) { QString languageString; if (countries.count() == 1) { languageString = QString(QLatin1String("%1 [%2]")) .arg(QLocale::languageToString(language)) .arg(QLocale(language).name().split(QLatin1Char('_')).at(0)); } else { languageString = QString(QLatin1String("%1/%2 [%3]")) .arg(QLocale::languageToString(language)) .arg(QLocale::countryToString(countries.at(j))) .arg(QLocale(language, countries.at(j)).name().split(QLatin1Char('_')).join(QLatin1String("-")).toLower()); } if (!allLanguages.contains(languageString)) { allLanguages.append(languageString); } } return allLanguages; } void AcceptLanguage::addLanguage() { Ui_AddAcceptLanguage acceptLangUi; QDialog dialog(this); acceptLangUi.setupUi(&dialog); acceptLangUi.listWidget->setLayoutDirection(Qt::LeftToRight); QStringList allLanguages; for (int i = 1 + (int)QLocale::C; i <= (int)QLocale::LastLanguage; ++i) { allLanguages += expand(QLocale::Language(i)); } acceptLangUi.listWidget->addItems(allLanguages); connect(acceptLangUi.listWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), &dialog, SLOT(accept())); if (dialog.exec() == QDialog::Rejected) { return; } if (!acceptLangUi.ownDefinition->text().isEmpty()) { QString title = tr("Personal [%1]").arg(acceptLangUi.ownDefinition->text()); ui->listWidget->addItem(title); } else { QListWidgetItem* c = acceptLangUi.listWidget->currentItem(); if (!c) { return; } ui->listWidget->addItem(c->text()); } } void AcceptLanguage::removeLanguage() { delete ui->listWidget->currentItem(); } void AcceptLanguage::upLanguage() { int index = ui->listWidget->currentRow(); QListWidgetItem* currentItem = ui->listWidget->currentItem(); if (!currentItem || index == 0) { return; } ui->listWidget->takeItem(index); ui->listWidget->insertItem(index - 1, currentItem); ui->listWidget->setCurrentItem(currentItem); } void AcceptLanguage::downLanguage() { int index = ui->listWidget->currentRow(); QListWidgetItem* currentItem = ui->listWidget->currentItem(); if (!currentItem || index == ui->listWidget->count() - 1) { return; } ui->listWidget->takeItem(index); ui->listWidget->insertItem(index + 1, currentItem); ui->listWidget->setCurrentItem(currentItem); } void AcceptLanguage::accept() { QStringList langs; for (int i = 0; i < ui->listWidget->count(); i++) { QString t = ui->listWidget->item(i)->text(); QString code = t.mid(t.indexOf(QLatin1Char('[')) + 1); code.remove(QLatin1Char(']')); langs.append(code); } Settings settings; settings.beginGroup("Language"); settings.setValue("acceptLanguage", langs); mApp->networkManager()->loadSettings(); QDialog::close(); } AcceptLanguage::~AcceptLanguage() { delete ui; } diff --git a/src/lib/preferences/acceptlanguage.h b/src/lib/preferences/acceptlanguage.h index 94d3151b..16182e0a 100644 --- a/src/lib/preferences/acceptlanguage.h +++ b/src/lib/preferences/acceptlanguage.h @@ -1,57 +1,57 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef ACCEPTLANGUAGE_H #define ACCEPTLANGUAGE_H #include #include #include "qzcommon.h" namespace Ui { class AcceptLanguage; } -class QUPZILLA_EXPORT AcceptLanguage : public QDialog +class FALKON_EXPORT AcceptLanguage : public QDialog { Q_OBJECT public: explicit AcceptLanguage(QWidget* parent = 0); ~AcceptLanguage(); static QStringList defaultLanguage(); static QByteArray generateHeader(const QStringList &langs); public slots: void accept(); private slots: void addLanguage(); void removeLanguage(); void upLanguage(); void downLanguage(); private: QStringList expand(const QLocale::Language &language); Ui::AcceptLanguage* ui; }; #endif // ACCEPTLANGUAGE_H diff --git a/src/lib/preferences/autofillmanager.cpp b/src/lib/preferences/autofillmanager.cpp index bde705ba..d3f76666 100644 --- a/src/lib/preferences/autofillmanager.cpp +++ b/src/lib/preferences/autofillmanager.cpp @@ -1,382 +1,382 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2016 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "autofillmanager.h" #include "ui_autofillmanager.h" #include "autofill.h" #include "passwordmanager.h" #include "passwordbackends/passwordbackend.h" #include "mainapplication.h" #include "settings.h" #include "qztools.h" #include #include #include #include #include #include #include #include AutoFillManager::AutoFillManager(QWidget* parent) : QWidget(parent) , ui(new Ui::AutoFillManager) , m_passwordManager(mApp->autoFill()->passwordManager()) , m_passwordsShown(false) { ui->setupUi(this); if (isRightToLeft()) { ui->treePass->headerItem()->setTextAlignment(0, Qt::AlignRight | Qt::AlignVCenter); ui->treePass->headerItem()->setTextAlignment(1, Qt::AlignRight | Qt::AlignVCenter); ui->treePass->headerItem()->setTextAlignment(2, Qt::AlignRight | Qt::AlignVCenter); ui->treePass->setLayoutDirection(Qt::LeftToRight); ui->treeExcept->setLayoutDirection(Qt::LeftToRight); } connect(ui->removePass, SIGNAL(clicked()), this, SLOT(removePass())); connect(ui->removeAllPass, SIGNAL(clicked()), this, SLOT(removeAllPass())); connect(ui->editPass, SIGNAL(clicked()), this, SLOT(editPass())); connect(ui->showPasswords, SIGNAL(clicked()), this, SLOT(showPasswords())); connect(ui->search, SIGNAL(textChanged(QString)), ui->treePass, SLOT(filterString(QString))); connect(ui->changeBackend, SIGNAL(clicked()), this, SLOT(changePasswordBackend())); connect(ui->backendOptions, SIGNAL(clicked()), this, SLOT(showBackendOptions())); connect(m_passwordManager, SIGNAL(passwordBackendChanged()), this, SLOT(currentPasswordBackendChanged())); connect(ui->removeExcept, SIGNAL(clicked()), this, SLOT(removeExcept())); connect(ui->removeAllExcept, SIGNAL(clicked()), this, SLOT(removeAllExcept())); ui->treePass->setContextMenuPolicy(Qt::CustomContextMenu); connect(ui->treePass, &TreeWidget::customContextMenuRequested, this, &AutoFillManager::passwordContextMenu); QMenu* menu = new QMenu(this); menu->addAction(tr("Import Passwords from File..."), this, SLOT(importPasswords())); menu->addAction(tr("Export Passwords to File..."), this, SLOT(exportPasswords())); ui->importExport->setMenu(menu); ui->search->setPlaceholderText(tr("Search")); // Password backends ui->currentBackend->setText(QString("%1").arg(m_passwordManager->activeBackend()->name())); ui->backendOptions->setVisible(m_passwordManager->activeBackend()->hasSettings()); // Load passwords QTimer::singleShot(0, this, SLOT(loadPasswords())); } void AutoFillManager::loadPasswords() { ui->showPasswords->setText(tr("Show Passwords")); m_passwordsShown = false; QVector allEntries = mApp->autoFill()->getAllFormData(); ui->treePass->clear(); foreach (const PasswordEntry &entry, allEntries) { QTreeWidgetItem* item = new QTreeWidgetItem(ui->treePass); item->setText(0, entry.host); item->setText(1, entry.username); item->setText(2, "*****"); QVariant v; v.setValue(entry); item->setData(0, Qt::UserRole + 10, v); ui->treePass->addTopLevelItem(item); } QSqlQuery query; query.exec("SELECT server, id FROM autofill_exceptions"); ui->treeExcept->clear(); while (query.next()) { QTreeWidgetItem* item = new QTreeWidgetItem(ui->treeExcept); item->setText(0, query.value(0).toString()); item->setData(0, Qt::UserRole + 10, query.value(1).toString()); ui->treeExcept->addTopLevelItem(item); } ui->treePass->sortByColumn(-1); ui->treeExcept->sortByColumn(-1); } void AutoFillManager::changePasswordBackend() { QHash backends = m_passwordManager->availableBackends(); QStringList items; int current = 0; QHashIterator i(backends); while (i.hasNext()) { i.next(); if (i.value() == m_passwordManager->activeBackend()) { current = items.size(); } items << i.value()->name(); } QString item = QInputDialog::getItem(this, tr("Change backend..."), tr("Change backend:"), items, current, false); // Switch backends if (!item.isEmpty()) { PasswordBackend* backend = 0; QHashIterator i(backends); while (i.hasNext()) { i.next(); if (i.value()->name() == item) { backend = i.value(); break; } } if (backend) { m_passwordManager->switchBackend(backends.key(backend)); } } } void AutoFillManager::showBackendOptions() { PasswordBackend* backend = m_passwordManager->activeBackend(); if (backend->hasSettings()) { backend->showSettings(this); } } void AutoFillManager::showPasswords() { if (m_passwordsShown) { for (int i = 0; i < ui->treePass->topLevelItemCount(); i++) { QTreeWidgetItem* item = ui->treePass->topLevelItem(i); if (!item) { continue; } item->setText(2, "*****"); } ui->showPasswords->setText(tr("Show Passwords")); m_passwordsShown = false; return; } m_passwordsShown = true; int result = QMessageBox::question(this, tr("Show Passwords"), tr("Are you sure that you want to show all passwords?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No); if (result != QMessageBox::Yes) { return; } for (int i = 0; i < ui->treePass->topLevelItemCount(); i++) { QTreeWidgetItem* item = ui->treePass->topLevelItem(i); if (!item) { continue; } item->setText(2, item->data(0, Qt::UserRole + 10).value().password); } ui->showPasswords->setText(tr("Hide Passwords")); } void AutoFillManager::copyPassword() { QTreeWidgetItem* curItem = ui->treePass->currentItem(); if (!curItem) return; PasswordEntry entry = curItem->data(0, Qt::UserRole + 10).value(); QApplication::clipboard()->setText(entry.password); } void AutoFillManager::copyUsername() { QTreeWidgetItem* curItem = ui->treePass->currentItem(); if (!curItem) return; PasswordEntry entry = curItem->data(0, Qt::UserRole + 10).value(); QApplication::clipboard()->setText(entry.username); } void AutoFillManager::removePass() { QTreeWidgetItem* curItem = ui->treePass->currentItem(); if (!curItem) { return; } PasswordEntry entry = curItem->data(0, Qt::UserRole + 10).value(); mApp->autoFill()->removeEntry(entry); delete curItem; } void AutoFillManager::removeAllPass() { QMessageBox::StandardButton button = QMessageBox::warning(this, tr("Confirmation"), tr("Are you sure you want to delete all passwords on your computer?"), QMessageBox::Yes | QMessageBox::No); if (button != QMessageBox::Yes) { return; } mApp->autoFill()->removeAllEntries(); ui->treePass->clear(); } void AutoFillManager::editPass() { QTreeWidgetItem* curItem = ui->treePass->currentItem(); if (!curItem) { return; } PasswordEntry entry = curItem->data(0, Qt::UserRole + 10).value(); bool ok; QString text = QInputDialog::getText(this, tr("Edit password"), tr("Change password:"), QLineEdit::Normal, entry.password, &ok); if (ok && !text.isEmpty() && text != entry.password) { QByteArray oldPass = "=" + PasswordManager::urlEncodePassword(entry.password); entry.data.replace(oldPass, "=" + PasswordManager::urlEncodePassword(text)); entry.password = text; if (mApp->autoFill()->updateEntry(entry)) { QVariant v; v.setValue(entry); curItem->setData(0, Qt::UserRole + 10, v); if (m_passwordsShown) { curItem->setText(2, text); } } } } void AutoFillManager::removeExcept() { QTreeWidgetItem* curItem = ui->treeExcept->currentItem(); if (!curItem) { return; } QString id = curItem->data(0, Qt::UserRole + 10).toString(); QSqlQuery query; query.prepare("DELETE FROM autofill_exceptions WHERE id=?"); query.addBindValue(id); query.exec(); delete curItem; } void AutoFillManager::removeAllExcept() { QSqlQuery query; query.exec("DELETE FROM autofill_exceptions"); ui->treeExcept->clear(); } void AutoFillManager::showExceptions() { ui->tabWidget->setCurrentIndex(1); } void AutoFillManager::importPasswords() { m_fileName = QzTools::getOpenFileName("AutoFill-ImportPasswords", this, tr("Choose file..."), QDir::homePath() + "/passwords.xml", "*.xml"); if (m_fileName.isEmpty()) { return; } QTimer::singleShot(0, this, SLOT(slotImportPasswords())); } void AutoFillManager::exportPasswords() { m_fileName = QzTools::getSaveFileName("AutoFill-ExportPasswords", this, tr("Choose file..."), QDir::homePath() + "/passwords.xml", "*.xml"); if (m_fileName.isEmpty()) { return; } QTimer::singleShot(0, this, SLOT(slotExportPasswords())); } void AutoFillManager::slotImportPasswords() { QFile file(m_fileName); if (!file.open(QFile::ReadOnly)) { ui->importExportLabel->setText(tr("Cannot read file!")); return; } QApplication::setOverrideCursor(Qt::WaitCursor); bool status = mApp->autoFill()->importPasswords(file.readAll()); file.close(); ui->importExportLabel->setText(status ? tr("Successfully imported") : tr("Error while importing!")); loadPasswords(); QApplication::restoreOverrideCursor(); } void AutoFillManager::slotExportPasswords() { QFile file(m_fileName); if (!file.open(QFile::WriteOnly)) { ui->importExportLabel->setText(tr("Cannot write to file!")); return; } QApplication::setOverrideCursor(Qt::WaitCursor); file.write(mApp->autoFill()->exportPasswords()); file.close(); ui->importExportLabel->setText(tr("Successfully exported")); QApplication::restoreOverrideCursor(); } void AutoFillManager::currentPasswordBackendChanged() { ui->currentBackend->setText(QString("%1").arg(m_passwordManager->activeBackend()->name())); ui->backendOptions->setVisible(m_passwordManager->activeBackend()->hasSettings()); QTimer::singleShot(0, this, SLOT(loadPasswords())); } void AutoFillManager::passwordContextMenu(const QPoint &pos) { QMenu *menu = new QMenu; menu->setAttribute(Qt::WA_DeleteOnClose); menu->addAction(tr("Copy Username"), this, &AutoFillManager::copyUsername); menu->addAction(tr("Copy Password"), this, &AutoFillManager::copyPassword); menu->addSeparator(); menu->addAction(tr("Edit Password"), this, &AutoFillManager::editPass); menu->popup(ui->treePass->viewport()->mapToGlobal(pos)); } AutoFillManager::~AutoFillManager() { delete ui; } diff --git a/src/lib/preferences/autofillmanager.h b/src/lib/preferences/autofillmanager.h index 4a7289aa..3516a114 100644 --- a/src/lib/preferences/autofillmanager.h +++ b/src/lib/preferences/autofillmanager.h @@ -1,75 +1,75 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2016 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef AUTOFILLMANAGER_H #define AUTOFILLMANAGER_H #include #include "qzcommon.h" class PasswordManager; namespace Ui { class AutoFillManager; } -class QUPZILLA_EXPORT AutoFillManager : public QWidget +class FALKON_EXPORT AutoFillManager : public QWidget { Q_OBJECT public: explicit AutoFillManager(QWidget* parent = 0); ~AutoFillManager(); void showExceptions(); private slots: void loadPasswords(); void changePasswordBackend(); void showBackendOptions(); void removePass(); void removeAllPass(); void editPass(); void showPasswords(); void copyPassword(); void copyUsername(); void removeExcept(); void removeAllExcept(); void importPasswords(); void exportPasswords(); void slotImportPasswords(); void slotExportPasswords(); void currentPasswordBackendChanged(); void passwordContextMenu(const QPoint &pos); private: Ui::AutoFillManager* ui; PasswordManager* m_passwordManager; QString m_fileName; bool m_passwordsShown; }; #endif // AUTOFILLMANAGER_H diff --git a/src/lib/preferences/jsoptions.cpp b/src/lib/preferences/jsoptions.cpp index f5cd925c..bf1f113d 100644 --- a/src/lib/preferences/jsoptions.cpp +++ b/src/lib/preferences/jsoptions.cpp @@ -1,55 +1,55 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2013-2014 David Rosca 2013-2014 Mladen Pejaković * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "jsoptions.h" #include "ui_jsoptions.h" #include "mainapplication.h" #include "settings.h" JsOptions::JsOptions(QWidget* parent) : QDialog(parent) , ui(new Ui::JsOptions) { setAttribute(Qt::WA_DeleteOnClose); ui->setupUi(this); Settings settings; settings.beginGroup("Web-Browser-Settings"); ui->jscanOpenWindow->setChecked(settings.value("allowJavaScriptOpenWindow", false).toBool()); ui->jscanChangeSize->setChecked(settings.value("allowJavaScriptGeometryChange", true).toBool()); ui->jscanAccessClipboard->setChecked(settings.value("allowJavaScriptAccessClipboard", false).toBool()); settings.endGroup(); } void JsOptions::accept() { Settings settings; settings.beginGroup("Web-Browser-Settings"); settings.setValue("allowJavaScriptOpenWindow", ui->jscanOpenWindow->isChecked()); settings.setValue("allowJavaScriptGeometryChange", ui->jscanChangeSize->isChecked()); settings.setValue("allowJavaScriptAccessClipboard", ui->jscanAccessClipboard->isChecked()); settings.endGroup(); QDialog::close(); } JsOptions::~JsOptions() { delete ui; } diff --git a/src/lib/preferences/jsoptions.h b/src/lib/preferences/jsoptions.h index cbcdc007..bf0618c4 100644 --- a/src/lib/preferences/jsoptions.h +++ b/src/lib/preferences/jsoptions.h @@ -1,46 +1,46 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2013-2014 David Rosca 2013-2014 Mladen Pejaković * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef JSOPTIONS_H #define JSOPTIONS_H #include #include "qzcommon.h" namespace Ui { class JsOptions; } -class QUPZILLA_EXPORT JsOptions : public QDialog +class FALKON_EXPORT JsOptions : public QDialog { Q_OBJECT public: explicit JsOptions(QWidget* parent = 0); ~JsOptions(); public slots: void accept(); private: Ui::JsOptions* ui; }; #endif // JSOPTIONS_H diff --git a/src/lib/preferences/pluginlistdelegate.cpp b/src/lib/preferences/pluginlistdelegate.cpp index 2a5cbc7c..f1b7a6e3 100644 --- a/src/lib/preferences/pluginlistdelegate.cpp +++ b/src/lib/preferences/pluginlistdelegate.cpp @@ -1,143 +1,143 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "pluginlistdelegate.h" #include #include #include PluginListDelegate::PluginListDelegate(QListWidget* parent) : QStyledItemDelegate(parent) , m_rowHeight(0) , m_padding(0) { } void PluginListDelegate::paint(QPainter* painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { QStyleOptionViewItem opt = option; initStyleOption(&opt, index); const QWidget* w = opt.widget; const QStyle* style = w ? w->style() : QApplication::style(); const int height = opt.rect.height(); const int center = height / 2 + opt.rect.top(); painter->setLayoutDirection(Qt::LeftToRight); // Prepare title font QFont titleFont = opt.font; titleFont.setBold(true); titleFont.setPointSize(titleFont.pointSize() + 1); const QFontMetrics titleMetrics(titleFont); const QPalette::ColorRole colorRole = opt.state & QStyle::State_Selected ? QPalette::HighlightedText : QPalette::Text; QPalette::ColorGroup cg = opt.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled; if (cg == QPalette::Normal && !(opt.state & QStyle::State_Active)) { cg = QPalette::Inactive; } #ifdef Q_OS_WIN opt.palette.setColor(QPalette::All, QPalette::HighlightedText, opt.palette.color(QPalette::Active, QPalette::Text)); opt.palette.setColor(QPalette::All, QPalette::Highlight, opt.palette.base().color().darker(108)); #endif QPalette textPalette = opt.palette; textPalette.setCurrentColorGroup(cg); int leftPosition = m_padding; int rightPosition = opt.rect.right() - m_padding; // Draw background style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, w); // Draw checkbox const int checkboxSize = 18; const int checkboxYPos = center - (checkboxSize / 2); QStyleOptionViewItem opt2 = opt; opt2.checkState == Qt::Checked ? opt2.state |= QStyle::State_On : opt2.state |= QStyle::State_Off; QRect styleCheckBoxRect = style->subElementRect(QStyle::SE_ViewItemCheckIndicator, &opt2, w); opt2.rect = QRect(leftPosition, checkboxYPos, styleCheckBoxRect.width(), styleCheckBoxRect.height()); style->drawPrimitive(QStyle::PE_IndicatorViewItemCheck, &opt2, painter, w); leftPosition = opt2.rect.right() + m_padding; // Draw icon const int iconSize = 32; const int iconYPos = center - (iconSize / 2); QRect iconRect(leftPosition, iconYPos, iconSize, iconSize); QPixmap pixmap = index.data(Qt::DecorationRole).value().pixmap(iconSize); painter->drawPixmap(iconRect, pixmap); leftPosition = iconRect.right() + m_padding; // Draw plugin name const QString name = index.data(Qt::DisplayRole).toString(); const int leftTitleEdge = leftPosition + 2; const int rightTitleEdge = rightPosition - m_padding; const int leftPosForVersion = titleMetrics.width(name) + m_padding; QRect nameRect(leftTitleEdge, opt.rect.top() + m_padding, rightTitleEdge - leftTitleEdge, titleMetrics.height()); painter->setFont(titleFont); style->drawItemText(painter, nameRect, Qt::AlignLeft, textPalette, true, name, colorRole); // Draw version const QString version = index.data(Qt::UserRole).toString(); QRect versionRect(nameRect.x() + leftPosForVersion, nameRect.y(), rightTitleEdge - leftPosForVersion, titleMetrics.height()); QFont versionFont = titleFont; versionFont.setBold(false); painter->setFont(versionFont); style->drawItemText(painter, versionRect, Qt::AlignLeft, textPalette, true, version, colorRole); // Draw info const int infoYPos = nameRect.bottom() + opt.fontMetrics.leading(); QRect infoRect(nameRect.x(), infoYPos, nameRect.width(), opt.fontMetrics.height()); const QString info = opt.fontMetrics.elidedText(index.data(Qt::UserRole + 1).toString(), Qt::ElideRight, infoRect.width()); painter->setFont(opt.font); style->drawItemText(painter, infoRect, Qt::TextSingleLine | Qt::AlignLeft, textPalette, true, info, colorRole); // Draw description const int descriptionYPos = infoRect.bottom() + opt.fontMetrics.leading(); QRect descriptionRect(infoRect.x(), descriptionYPos, infoRect.width(), opt.fontMetrics.height()); const QString description = opt.fontMetrics.elidedText(index.data(Qt::UserRole + 2).toString(), Qt::ElideRight, descriptionRect.width()); style->drawItemText(painter, descriptionRect, Qt::TextSingleLine | Qt::AlignLeft, textPalette, true, description, colorRole); } QSize PluginListDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const { Q_UNUSED(index) if (!m_rowHeight) { QStyleOptionViewItem opt(option); initStyleOption(&opt, index); const QWidget* w = opt.widget; const QStyle* style = w ? w->style() : QApplication::style(); const int padding = style->pixelMetric(QStyle::PM_FocusFrameHMargin, 0) + 1; QFont titleFont = opt.font; titleFont.setBold(true); titleFont.setPointSize(titleFont.pointSize() + 1); m_padding = padding > 5 ? padding : 5; const QFontMetrics titleMetrics(titleFont); m_rowHeight = 2 * m_padding + 2 * opt.fontMetrics.leading() + 2 * opt.fontMetrics.height() + titleMetrics.height(); } return QSize(200, m_rowHeight); } diff --git a/src/lib/preferences/pluginlistdelegate.h b/src/lib/preferences/pluginlistdelegate.h index 07790962..f5d37a04 100644 --- a/src/lib/preferences/pluginlistdelegate.h +++ b/src/lib/preferences/pluginlistdelegate.h @@ -1,40 +1,40 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef PLUGINLISTDELEGATE_H #define PLUGINLISTDELEGATE_H #include #include "qzcommon.h" class QListWidget; -class QUPZILLA_EXPORT PluginListDelegate : public QStyledItemDelegate +class FALKON_EXPORT PluginListDelegate : public QStyledItemDelegate { public: explicit PluginListDelegate(QListWidget* parent); void paint(QPainter* painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const; private: mutable int m_rowHeight; mutable int m_padding; }; #endif // PLUGINLISTDELEGATE_H diff --git a/src/lib/preferences/pluginsmanager.cpp b/src/lib/preferences/pluginsmanager.cpp index 1f2ca6a4..da1eed66 100644 --- a/src/lib/preferences/pluginsmanager.cpp +++ b/src/lib/preferences/pluginsmanager.cpp @@ -1,250 +1,250 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "pluginsmanager.h" #include "ui_pluginslist.h" #include "pluginproxy.h" #include "mainapplication.h" #include "plugininterface.h" #include "pluginlistdelegate.h" #include "qztools.h" #include "settings.h" #include "iconprovider.h" #include #include #include PluginsManager::PluginsManager(QWidget* parent) : QWidget(parent) , ui(new Ui::PluginsList) , m_loaded(false) { ui->setupUi(this); ui->list->setLayoutDirection(Qt::LeftToRight); ui->butSettings->setIcon(IconProvider::settingsIcon()); //Application Extensions Settings settings; settings.beginGroup("Plugin-Settings"); bool appPluginsEnabled = settings.value("EnablePlugins", !mApp->isPortable()).toBool(); settings.endGroup(); ui->allowAppPlugins->setChecked(appPluginsEnabled); ui->list->setEnabled(appPluginsEnabled); connect(ui->butSettings, SIGNAL(clicked()), this, SLOT(settingsClicked())); connect(ui->list, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), this, SLOT(currentChanged(QListWidgetItem*))); connect(ui->list, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(itemChanged(QListWidgetItem*))); connect(ui->allowAppPlugins, SIGNAL(clicked(bool)), this, SLOT(allowAppPluginsChanged(bool))); ui->list->setItemDelegate(new PluginListDelegate(ui->list)); } void PluginsManager::load() { if (!m_loaded) { refresh(); m_loaded = true; } } void PluginsManager::save() { if (!m_loaded) { return; } QStringList allowedPlugins; for (int i = 0; i < ui->list->count(); i++) { QListWidgetItem* item = ui->list->item(i); if (item->checkState() == Qt::Checked) { const Plugins::Plugin plugin = item->data(Qt::UserRole + 10).value(); // Save plugins with relative path in portable mode #ifdef NO_SYSTEM_DATAPATH if (true) #else if (mApp->isPortable()) #endif allowedPlugins.append(plugin.fileName); else allowedPlugins.append(plugin.fullPath); } } Settings settings; settings.beginGroup("Plugin-Settings"); settings.setValue("EnablePlugins", ui->allowAppPlugins->isChecked()); settings.setValue("AllowedPlugins", allowedPlugins); settings.endGroup(); } void PluginsManager::allowAppPluginsChanged(bool state) { ui->list->setEnabled(state); if (!state) { for (int i = 0; i < ui->list->count(); i++) { QListWidgetItem* item = ui->list->item(i); if (item->checkState() == Qt::Checked) { item->setCheckState(Qt::Unchecked); } } } refresh(); } void PluginsManager::refresh() { if (!ui->allowAppPlugins->isChecked()) { return; } ui->list->clear(); ui->butSettings->setEnabled(false); disconnect(ui->list, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(itemChanged(QListWidgetItem*))); const QList &allPlugins = mApp->plugins()->getAvailablePlugins(); foreach (const Plugins::Plugin &plugin, allPlugins) { PluginSpec spec = plugin.pluginSpec; QListWidgetItem* item = new QListWidgetItem(ui->list); QIcon icon = QIcon(spec.icon); if (icon.isNull()) { icon = QIcon(QSL(":/icons/preferences/extensions.svg")); } item->setIcon(icon); QString pluginInfo = QString("%1 %2
%3
%4").arg(spec.name, spec.version, spec.author.toHtmlEscaped(), spec.info); item->setToolTip(pluginInfo); item->setText(spec.name); item->setData(Qt::UserRole, spec.version); item->setData(Qt::UserRole + 1, spec.info); item->setData(Qt::UserRole + 2, spec.description); item->setFlags(item->flags() | Qt::ItemIsUserCheckable); item->setCheckState(plugin.isLoaded() ? Qt::Checked : Qt::Unchecked); item->setData(Qt::UserRole + 10, QVariant::fromValue(plugin)); ui->list->addItem(item); } sortItems(); connect(ui->list, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(itemChanged(QListWidgetItem*))); } void PluginsManager::sortItems() { ui->list->sortItems(); bool itemMoved; do { itemMoved = false; for (int i = 0; i < ui->list->count(); ++i) { QListWidgetItem* topItem = ui->list->item(i); QListWidgetItem* bottomItem = ui->list->item(i + 1); if (!topItem || !bottomItem) { continue; } if (topItem->checkState() == Qt::Unchecked && bottomItem->checkState() == Qt::Checked) { QListWidgetItem* item = ui->list->takeItem(i + 1); ui->list->insertItem(i, item); itemMoved = true; } } } while (itemMoved); } void PluginsManager::currentChanged(QListWidgetItem* item) { if (!item) { return; } const Plugins::Plugin plugin = item->data(Qt::UserRole + 10).value(); bool showSettings = plugin.pluginSpec.hasSettings; if (!plugin.isLoaded()) { showSettings = false; } ui->butSettings->setEnabled(showSettings); } void PluginsManager::itemChanged(QListWidgetItem* item) { if (!item) { return; } Plugins::Plugin plugin = item->data(Qt::UserRole + 10).value(); if (item->checkState() == Qt::Checked) { mApp->plugins()->loadPlugin(&plugin); } else { mApp->plugins()->unloadPlugin(&plugin); } disconnect(ui->list, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(itemChanged(QListWidgetItem*))); if (item->checkState() == Qt::Checked && !plugin.isLoaded()) { item->setCheckState(Qt::Unchecked); QMessageBox::critical(this, tr("Error!"), tr("Cannot load extension!")); } item->setData(Qt::UserRole + 10, QVariant::fromValue(plugin)); connect(ui->list, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(itemChanged(QListWidgetItem*))); currentChanged(ui->list->currentItem()); } void PluginsManager::settingsClicked() { QListWidgetItem* item = ui->list->currentItem(); if (!item || item->checkState() == Qt::Unchecked) { return; } Plugins::Plugin plugin = item->data(Qt::UserRole + 10).value(); if (!plugin.isLoaded()) { mApp->plugins()->loadPlugin(&plugin); item->setData(Qt::UserRole + 10, QVariant::fromValue(plugin)); } if (plugin.isLoaded() && plugin.pluginSpec.hasSettings) { plugin.instance->showSettings(this); } } PluginsManager::~PluginsManager() { delete ui; } diff --git a/src/lib/preferences/pluginsmanager.h b/src/lib/preferences/pluginsmanager.h index 521a7874..904f6ed3 100644 --- a/src/lib/preferences/pluginsmanager.h +++ b/src/lib/preferences/pluginsmanager.h @@ -1,58 +1,58 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef PLUGINSMANAGER_H #define PLUGINSMANAGER_H #include #include "qzcommon.h" namespace Ui { class PluginsList; } class QListWidgetItem; -class QUPZILLA_EXPORT PluginsManager : public QWidget +class FALKON_EXPORT PluginsManager : public QWidget { Q_OBJECT public: explicit PluginsManager(QWidget* parent = 0); ~PluginsManager(); void load(); void save(); private slots: void settingsClicked(); void currentChanged(QListWidgetItem* item); void itemChanged(QListWidgetItem* item); void allowAppPluginsChanged(bool state); void refresh(); private: void sortItems(); Ui::PluginsList* ui; bool m_loaded; }; #endif // PLUGINSMANAGER_H diff --git a/src/lib/preferences/preferences.cpp b/src/lib/preferences/preferences.cpp index bfcfe204..90f43f21 100644 --- a/src/lib/preferences/preferences.cpp +++ b/src/lib/preferences/preferences.cpp @@ -1,1111 +1,1111 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "preferences.h" #include "ui_preferences.h" #include "browserwindow.h" #include "bookmarkstoolbar.h" #include "history.h" #include "tabwidget.h" #include "cookiejar.h" #include "locationbar.h" #include "autofillmanager.h" #include "mainapplication.h" #include "cookiemanager.h" #include "pluginproxy.h" #include "pluginsmanager.h" #include "jsoptions.h" #include "networkproxyfactory.h" #include "networkmanager.h" #include "desktopnotificationsfactory.h" #include "desktopnotification.h" #include "navigationbar.h" #include "thememanager.h" #include "acceptlanguage.h" #include "qztools.h" #include "autofill.h" #include "settings.h" #include "datapaths.h" #include "tabbedwebview.h" #include "clearprivatedata.h" #include "useragentdialog.h" #include "registerqappassociation.h" #include "profilemanager.h" #include "html5permissions/html5permissionsdialog.h" #include "searchenginesdialog.h" #include "webscrollbarmanager.h" #include #include #include #include #include #include #include #include #include #include static QString createLanguageItem(const QString &lang) { QLocale locale(lang); if (locale.language() == QLocale::C) { return lang; } QString country = QLocale::countryToString(locale.country()); QString language = QLocale::languageToString(locale.language()); if (lang == QLatin1String("es_ES")) { return QString::fromUtf8("Castellano"); } if (lang == QLatin1String("nqo")) { return QString("N'ko (nqo)"); } if (lang == QLatin1String("sr")) { return QString::fromUtf8("српски екавски"); } if (lang == QLatin1String("sr@ijekavian")) { return QString::fromUtf8("српски ијекавски"); } if (lang == QLatin1String("sr@latin")) { return QString::fromUtf8("srpski ekavski"); } if (lang == QLatin1String("sr@ijekavianlatin")) { return QString::fromUtf8("srpski ijekavski"); } return QString("%1, %2 (%3)").arg(language, country, lang); } Preferences::Preferences(BrowserWindow* window) : QWidget() , ui(new Ui::Preferences) , m_window(window) , m_autoFillManager(0) , m_pluginsList(0) , m_autoFillEnabled(false) { setAttribute(Qt::WA_DeleteOnClose); ui->setupUi(this); ui->languages->setLayoutDirection(Qt::LeftToRight); QzTools::centerWidgetOnScreen(this); m_themesManager = new ThemeManager(ui->themesWidget, this); m_pluginsList = new PluginsManager(this); ui->pluginsFrame->addWidget(m_pluginsList); #ifdef DISABLE_CHECK_UPDATES ui->checkUpdates->setVisible(false); #endif auto setCategoryIcon = [this](int index, const QIcon &icon) { ui->listWidget->item(index)->setIcon(QIcon(icon.pixmap(32))); }; setCategoryIcon(0, QIcon(":/icons/preferences/general.svg")); setCategoryIcon(1, QIcon(":/icons/preferences/appearance.svg")); setCategoryIcon(2, QIcon(":/icons/preferences/tabs.svg")); setCategoryIcon(3, QIcon(":/icons/preferences/browsing.svg")); setCategoryIcon(4, QIcon(":/icons/preferences/fonts.svg")); setCategoryIcon(5, QIcon(":/icons/preferences/shortcuts.svg")); setCategoryIcon(6, QIcon(":/icons/preferences/downloads.svg")); setCategoryIcon(7, QIcon(":/icons/preferences/passwords.svg")); setCategoryIcon(8, QIcon(":/icons/preferences/privacy.svg")); setCategoryIcon(9, QIcon(":/icons/preferences/notifications.svg")); setCategoryIcon(10, QIcon(":/icons/preferences/extensions.svg")); setCategoryIcon(11, QIcon(":/icons/preferences/spellcheck.svg")); setCategoryIcon(12, QIcon(":/icons/preferences/other.svg")); Settings settings; //GENERAL URLs settings.beginGroup("Web-URL-Settings"); - m_homepage = settings.value("homepage", QUrl(QSL("qupzilla:start"))).toUrl(); - m_newTabUrl = settings.value("newTabUrl", QUrl(QSL("qupzilla:speeddial"))).toUrl(); + m_homepage = settings.value("homepage", QUrl(QSL("falkon:start"))).toUrl(); + m_newTabUrl = settings.value("newTabUrl", QUrl(QSL("falkon:speeddial"))).toUrl(); ui->homepage->setText(m_homepage.toEncoded()); ui->newTabUrl->setText(m_newTabUrl.toEncoded()); settings.endGroup(); ui->afterLaunch->setCurrentIndex(mApp->afterLaunch()); ui->checkUpdates->setChecked(settings.value("Web-Browser-Settings/CheckUpdates", true).toBool()); ui->dontLoadTabsUntilSelected->setChecked(settings.value("Web-Browser-Settings/LoadTabsOnActivation", true).toBool()); #if defined(Q_OS_WIN) && !defined(Q_OS_OS2) ui->checkDefaultBrowser->setChecked(settings.value("Web-Browser-Settings/CheckDefaultBrowser", DEFAULT_CHECK_DEFAULTBROWSER).toBool()); if (mApp->associationManager()->isDefaultForAllCapabilities()) { ui->checkNowDefaultBrowser->setText(tr("Default")); ui->checkNowDefaultBrowser->setEnabled(false); } else { ui->checkNowDefaultBrowser->setText(tr("Set as default")); ui->checkNowDefaultBrowser->setEnabled(true); - connect(ui->checkNowDefaultBrowser, SIGNAL(clicked()), this, SLOT(makeQupZillaDefault())); + connect(ui->checkNowDefaultBrowser, SIGNAL(clicked()), this, SLOT(makeFalkonDefault())); } #else // No Default Browser settings on non-Windows platform ui->hSpacerDefaultBrowser->changeSize(0, 0, QSizePolicy::Fixed, QSizePolicy::Fixed); ui->hLayoutDefaultBrowser->invalidate(); delete ui->hLayoutDefaultBrowser; delete ui->checkDefaultBrowser; delete ui->checkNowDefaultBrowser; #endif ui->newTabFrame->setVisible(false); if (m_newTabUrl.isEmpty() || m_newTabUrl.toString() == QL1S("about:blank")) { ui->newTab->setCurrentIndex(0); } else if (m_newTabUrl == m_homepage) { ui->newTab->setCurrentIndex(1); } - else if (m_newTabUrl.toString() == QL1S("qupzilla:speeddial")) { + else if (m_newTabUrl.toString() == QL1S("falkon:speeddial")) { ui->newTab->setCurrentIndex(2); } else { ui->newTab->setCurrentIndex(3); ui->newTabFrame->setVisible(true); } afterLaunchChanged(ui->afterLaunch->currentIndex()); connect(ui->afterLaunch, SIGNAL(currentIndexChanged(int)), this, SLOT(afterLaunchChanged(int))); connect(ui->newTab, SIGNAL(currentIndexChanged(int)), this, SLOT(newTabChanged(int))); if (m_window) { connect(ui->useCurrentBut, SIGNAL(clicked()), this, SLOT(useActualHomepage())); connect(ui->newTabUseCurrent, SIGNAL(clicked()), this, SLOT(useActualNewTab())); } else { ui->useCurrentBut->setEnabled(false); ui->newTabUseCurrent->setEnabled(false); } // PROFILES QString startingProfile = ProfileManager::startingProfile(); ui->activeProfile->setText("" + ProfileManager::currentProfile() + ""); ui->startProfile->addItem(startingProfile); foreach (const QString &name, ProfileManager::availableProfiles()) { if (startingProfile != name) { ui->startProfile->addItem(name); } } connect(ui->createProfile, SIGNAL(clicked()), this, SLOT(createProfile())); connect(ui->deleteProfile, SIGNAL(clicked()), this, SLOT(deleteProfile())); connect(ui->startProfile, SIGNAL(currentIndexChanged(int)), this, SLOT(startProfileIndexChanged(int))); startProfileIndexChanged(ui->startProfile->currentIndex()); //APPEREANCE settings.beginGroup("Browser-View-Settings"); ui->showStatusbar->setChecked(settings.value("showStatusBar", false).toBool()); // NOTE: instantBookmarksToolbar and showBookmarksToolbar cannot be both enabled at the same time ui->instantBookmarksToolbar->setChecked(settings.value("instantBookmarksToolbar", false).toBool()); ui->showBookmarksToolbar->setChecked(settings.value("showBookmarksToolbar", true).toBool()); ui->instantBookmarksToolbar->setDisabled(settings.value("showBookmarksToolbar", true).toBool()); ui->showBookmarksToolbar->setDisabled(settings.value("instantBookmarksToolbar").toBool()); connect(ui->instantBookmarksToolbar, SIGNAL(toggled(bool)), ui->showBookmarksToolbar, SLOT(setDisabled(bool))); connect(ui->showBookmarksToolbar, SIGNAL(toggled(bool)), ui->instantBookmarksToolbar, SLOT(setDisabled(bool))); ui->showNavigationToolbar->setChecked(settings.value("showNavigationToolbar", true).toBool()); ui->showHome->setChecked(settings.value("showHomeButton", true).toBool()); ui->showBackForward->setChecked(settings.value("showBackForwardButtons", true).toBool()); ui->showAddTabButton->setChecked(settings.value("showAddTabButton", false).toBool()); ui->showReloadStopButtons->setChecked(settings.value("showReloadButton", true).toBool()); ui->showWebSearchBar->setChecked(settings.value("showWebSearchBar", true).toBool()); int currentSettingsPage = settings.value("settingsDialogPage", 0).toInt(0); settings.endGroup(); //TABS settings.beginGroup("Browser-Tabs-Settings"); ui->hideTabsOnTab->setChecked(settings.value("hideTabsWithOneTab", false).toBool()); ui->activateLastTab->setChecked(settings.value("ActivateLastTabWhenClosingActual", false).toBool()); ui->openNewTabAfterActive->setChecked(settings.value("newTabAfterActive", true).toBool()); ui->openNewEmptyTabAfterActive->setChecked(settings.value("newEmptyTabAfterActive", false).toBool()); ui->openPopupsInTabs->setChecked(settings.value("OpenPopupsInTabs", false).toBool()); ui->alwaysSwitchTabsWithWheel->setChecked(settings.value("AlwaysSwitchTabsWithWheel", false).toBool()); ui->switchToNewTabs->setChecked(settings.value("OpenNewTabsSelected", false).toBool()); ui->dontCloseOnLastTab->setChecked(settings.value("dontCloseWithOneTab", false).toBool()); ui->askWhenClosingMultipleTabs->setChecked(settings.value("AskOnClosing", false).toBool()); ui->showClosedTabsButton->setChecked(settings.value("showClosedTabsButton", false).toBool()); ui->showCloseOnInactive->setCurrentIndex(settings.value("showCloseOnInactiveTabs", 0).toInt()); settings.endGroup(); //AddressBar settings.beginGroup("AddressBar"); ui->addressbarCompletion->setCurrentIndex(settings.value("showSuggestions", 0).toInt()); ui->useInlineCompletion->setChecked(settings.value("useInlineCompletion", true).toBool()); ui->completionShowSwitchTab->setChecked(settings.value("showSwitchTab", true).toBool()); ui->alwaysShowGoIcon->setChecked(settings.value("alwaysShowGoIcon", false).toBool()); ui->selectAllOnFocus->setChecked(settings.value("SelectAllTextOnDoubleClick", true).toBool()); ui->selectAllOnClick->setChecked(settings.value("SelectAllTextOnClick", false).toBool()); bool showPBinAB = settings.value("ShowLoadingProgress", false).toBool(); ui->showLoadingInAddressBar->setChecked(showPBinAB); ui->adressProgressSettings->setEnabled(showPBinAB); ui->progressStyleSelector->setCurrentIndex(settings.value("ProgressStyle", 0).toInt()); bool pbInABuseCC = settings.value("UseCustomProgressColor", false).toBool(); ui->checkBoxCustomProgressColor->setChecked(pbInABuseCC); ui->progressBarColorSelector->setEnabled(pbInABuseCC); QColor pbColor = settings.value("CustomProgressColor", palette().color(QPalette::Highlight)).value(); setProgressBarColorIcon(pbColor); connect(ui->customColorToolButton, SIGNAL(clicked(bool)), SLOT(selectCustomProgressBarColor())); connect(ui->resetProgressBarcolor, SIGNAL(clicked()), SLOT(setProgressBarColorIcon())); settings.endGroup(); settings.beginGroup("SearchEngines"); bool searchFromAB = settings.value("SearchFromAddressBar", true).toBool(); ui->searchFromAddressBar->setChecked(searchFromAB); ui->searchWithDefaultEngine->setEnabled(searchFromAB); ui->searchWithDefaultEngine->setChecked(settings.value("SearchWithDefaultEngine", false).toBool()); connect(ui->searchFromAddressBar, SIGNAL(toggled(bool)), this, SLOT(searchFromAddressBarChanged(bool))); settings.endGroup(); // BROWSING settings.beginGroup("Web-Browser-Settings"); ui->allowPlugins->setChecked(settings.value("allowPlugins", true).toBool()); ui->allowJavaScript->setChecked(settings.value("allowJavaScript", true).toBool()); ui->linksInFocusChain->setChecked(settings.value("IncludeLinkInFocusChain", false).toBool()); ui->spatialNavigation->setChecked(settings.value("SpatialNavigation", false).toBool()); ui->animateScrolling->setChecked(settings.value("AnimateScrolling", true).toBool()); ui->wheelScroll->setValue(settings.value("wheelScrollLines", qApp->wheelScrollLines()).toInt()); ui->xssAuditing->setChecked(settings.value("XSSAuditing", false).toBool()); ui->printEBackground->setChecked(settings.value("PrintElementBackground", true).toBool()); ui->useNativeScrollbars->setChecked(settings.value("UseNativeScrollbars", false).toBool()); foreach (int level, WebView::zoomLevels()) { ui->defaultZoomLevel->addItem(QString("%1%").arg(level)); } ui->defaultZoomLevel->setCurrentIndex(settings.value("DefaultZoomLevel", WebView::zoomLevels().indexOf(100)).toInt()); ui->closeAppWithCtrlQ->setChecked(settings.value("closeAppWithCtrlQ", true).toBool()); //Cache ui->allowCache->setChecked(settings.value("AllowLocalCache", true).toBool()); ui->removeCache->setChecked(settings.value("deleteCacheOnClose", false).toBool()); ui->cacheMB->setValue(settings.value("LocalCacheSize", 50).toInt()); ui->cachePath->setText(settings.value("CachePath", QWebEngineProfile::defaultProfile()->cachePath()).toString()); connect(ui->allowCache, SIGNAL(clicked(bool)), this, SLOT(allowCacheChanged(bool))); connect(ui->changeCachePath, SIGNAL(clicked()), this, SLOT(changeCachePathClicked())); allowCacheChanged(ui->allowCache->isChecked()); //PASSWORD MANAGER ui->allowPassManager->setChecked(settings.value("SavePasswordsOnSites", true).toBool()); connect(ui->allowPassManager, SIGNAL(toggled(bool)), this, SLOT(showPassManager(bool))); showPassManager(ui->allowPassManager->isChecked()); //PRIVACY //Web storage ui->saveHistory->setChecked(settings.value("allowHistory", true).toBool()); ui->deleteHistoryOnClose->setChecked(settings.value("deleteHistoryOnClose", false).toBool()); if (!ui->saveHistory->isChecked()) { ui->deleteHistoryOnClose->setEnabled(false); } connect(ui->saveHistory, SIGNAL(toggled(bool)), this, SLOT(saveHistoryChanged(bool))); // Html5Storage ui->html5storage->setChecked(settings.value("HTML5StorageEnabled", true).toBool()); ui->deleteHtml5storageOnClose->setChecked(settings.value("deleteHTML5StorageOnClose", false).toBool()); connect(ui->html5storage, SIGNAL(toggled(bool)), this, SLOT(allowHtml5storageChanged(bool))); // Other ui->doNotTrack->setChecked(settings.value("DoNotTrack", false).toBool()); //CSS Style ui->userStyleSheet->setText(settings.value("userStyleSheet", "").toString()); connect(ui->chooseUserStylesheet, SIGNAL(clicked()), this, SLOT(chooseUserStyleClicked())); settings.endGroup(); //DOWNLOADS settings.beginGroup("DownloadManager"); ui->downLoc->setText(settings.value("defaultDownloadPath", "").toString()); ui->closeDownManOnFinish->setChecked(settings.value("CloseManagerOnFinish", false).toBool()); if (ui->downLoc->text().isEmpty()) { ui->askEverytime->setChecked(true); } else { ui->useDefined->setChecked(true); } ui->useExternalDownManager->setChecked(settings.value("UseExternalManager", false).toBool()); ui->externalDownExecutable->setText(settings.value("ExternalManagerExecutable", "").toString()); ui->externalDownArguments->setText(settings.value("ExternalManagerArguments", "").toString()); connect(ui->useExternalDownManager, SIGNAL(toggled(bool)), this, SLOT(useExternalDownManagerChanged(bool))); connect(ui->useDefined, SIGNAL(toggled(bool)), this, SLOT(downLocChanged(bool))); connect(ui->downButt, SIGNAL(clicked()), this, SLOT(chooseDownPath())); connect(ui->chooseExternalDown, SIGNAL(clicked()), this, SLOT(chooseExternalDownloadManager())); downLocChanged(ui->useDefined->isChecked()); useExternalDownManagerChanged(ui->useExternalDownManager->isChecked()); settings.endGroup(); //FONTS settings.beginGroup("Browser-Fonts"); QWebEngineSettings* webSettings = QWebEngineSettings::defaultSettings(); auto defaultFont = [&](QWebEngineSettings::FontFamily font) -> const QString { const QString family = webSettings->fontFamily(font); if (!family.isEmpty()) return family; switch (font) { case QWebEngineSettings::FixedFont: return QFontDatabase::systemFont(QFontDatabase::FixedFont).family(); case QWebEngineSettings::SerifFont: // TODO default: return QFontDatabase::systemFont(QFontDatabase::GeneralFont).family(); } }; ui->fontStandard->setCurrentFont(QFont(settings.value("StandardFont", defaultFont(QWebEngineSettings::StandardFont)).toString())); ui->fontCursive->setCurrentFont(QFont(settings.value("CursiveFont", defaultFont(QWebEngineSettings::CursiveFont)).toString())); ui->fontFantasy->setCurrentFont(QFont(settings.value("FantasyFont", defaultFont(QWebEngineSettings::FantasyFont)).toString())); ui->fontFixed->setCurrentFont(QFont(settings.value("FixedFont", defaultFont(QWebEngineSettings::FixedFont)).toString())); ui->fontSansSerif->setCurrentFont(QFont(settings.value("SansSerifFont", defaultFont(QWebEngineSettings::SansSerifFont)).toString())); ui->fontSerif->setCurrentFont(QFont(settings.value("SerifFont", defaultFont(QWebEngineSettings::SerifFont)).toString())); ui->sizeDefault->setValue(settings.value("DefaultFontSize", webSettings->fontSize(QWebEngineSettings::DefaultFontSize)).toInt()); ui->sizeFixed->setValue(settings.value("FixedFontSize", webSettings->fontSize(QWebEngineSettings::DefaultFixedFontSize)).toInt()); ui->sizeMinimum->setValue(settings.value("MinimumFontSize", webSettings->fontSize(QWebEngineSettings::MinimumFontSize)).toInt()); ui->sizeMinimumLogical->setValue(settings.value("MinimumLogicalFontSize", webSettings->fontSize(QWebEngineSettings::MinimumLogicalFontSize)).toInt()); settings.endGroup(); //KEYBOARD SHORTCUTS settings.beginGroup("Shortcuts"); ui->switchTabsAlt->setChecked(settings.value("useTabNumberShortcuts", true).toBool()); ui->loadSpeedDialsCtrl->setChecked(settings.value("useSpeedDialNumberShortcuts", true).toBool()); ui->singleKeyShortcuts->setChecked(settings.value("useSingleKeyShortcuts", false).toBool()); settings.endGroup(); //NOTIFICATIONS ui->useNativeSystemNotifications->setEnabled(mApp->desktopNotifications()->supportsNativeNotifications()); DesktopNotificationsFactory::Type notifyType; settings.beginGroup("Notifications"); ui->notificationTimeout->setValue(settings.value("Timeout", 6000).toInt() / 1000); #if defined(Q_OS_UNIX) && !defined(DISABLE_DBUS) notifyType = settings.value("UseNativeDesktop", true).toBool() ? DesktopNotificationsFactory::DesktopNative : DesktopNotificationsFactory::PopupWidget; #else notifyType = DesktopNotificationsFactory::PopupWidget; #endif if (ui->useNativeSystemNotifications->isEnabled() && notifyType == DesktopNotificationsFactory::DesktopNative) { ui->useNativeSystemNotifications->setChecked(true); } else { ui->useOSDNotifications->setChecked(true); } connect(ui->notificationPreview, &QPushButton::clicked, this, &Preferences::showNotificationPreview); ui->doNotUseNotifications->setChecked(!settings.value("Enabled", true).toBool()); m_notifPosition = settings.value("Position", QPoint(10, 10)).toPoint(); settings.endGroup(); //SPELLCHECK settings.beginGroup(QSL("SpellCheck")); ui->spellcheckEnabled->setChecked(settings.value(QSL("Enabled"), false).toBool()); const QStringList spellcheckLanguages = settings.value(QSL("Languages")).toStringList(); settings.endGroup(); auto updateSpellCheckEnabled = [this]() { ui->spellcheckLanguages->setEnabled(ui->spellcheckEnabled->isChecked()); ui->spellcheckNoLanguages->setEnabled(ui->spellcheckEnabled->isChecked()); }; updateSpellCheckEnabled(); connect(ui->spellcheckEnabled, &QCheckBox::toggled, this, updateSpellCheckEnabled); QStringList dictionariesDirs = { #ifdef Q_OS_OSX QDir::cleanPath(QCoreApplication::applicationDirPath() + QL1S("/../Resources/qtwebengine_dictionaries")), QDir::cleanPath(QCoreApplication::applicationDirPath() + QL1S("/../Frameworks/QtWebEngineCore.framework/Resources/qtwebengine_dictionaries")) #else QDir::cleanPath(QCoreApplication::applicationDirPath() + QL1S("/qtwebengine_dictionaries")), QDir::cleanPath(QLibraryInfo::location(QLibraryInfo::DataPath) + QL1S("/qtwebengine_dictionaries")) #endif }; dictionariesDirs.removeDuplicates(); ui->spellcheckDirectories->setText(dictionariesDirs.join(QL1C('\n'))); for (const QString &path : dictionariesDirs) { QDir dir(path); const QStringList files = dir.entryList({QSL("*.bdic")}); for (const QString &file : files) { const QString lang = file.left(file.size() - 5); const QString langName = createLanguageItem(lang); if (!ui->spellcheckLanguages->findItems(langName, Qt::MatchExactly).isEmpty()) { continue; } QListWidgetItem *item = new QListWidgetItem; item->setText(langName); item->setData(Qt::UserRole, lang); ui->spellcheckLanguages->addItem(item); } } int topIndex = 0; for (const QString &lang : spellcheckLanguages) { const auto items = ui->spellcheckLanguages->findItems(createLanguageItem(lang), Qt::MatchExactly); if (items.isEmpty()) { continue; } QListWidgetItem *item = items.at(0); ui->spellcheckLanguages->takeItem(ui->spellcheckLanguages->row(item)); ui->spellcheckLanguages->insertItem(topIndex++, item); ui->spellcheckLanguages->setCurrentItem(item, QItemSelectionModel::Select); } if (ui->spellcheckLanguages->count() == 0) { ui->spellcheckLanguages->hide(); } else { ui->spellcheckNoLanguages->hide(); } //OTHER //Languages QString activeLanguage = mApp->currentLanguage(); if (!activeLanguage.isEmpty() && activeLanguage != QLatin1String("en_US")) { ui->languages->addItem(createLanguageItem(activeLanguage), activeLanguage); } ui->languages->addItem("English (en_US)"); const QStringList translationPaths = DataPaths::allPaths(DataPaths::Translations); foreach (const QString &path, translationPaths) { QDir lanDir(path); QStringList list = lanDir.entryList(QStringList("*.qm")); foreach (const QString &name, list) { if (name.startsWith(QLatin1String("qt_"))) { continue; } QString loc = name; loc.remove(QLatin1String(".qm")); if (loc == activeLanguage) { continue; } ui->languages->addItem(createLanguageItem(loc), loc); } } // Proxy Configuration settings.beginGroup("Web-Proxy"); QNetworkProxy::ProxyType proxyType = QNetworkProxy::ProxyType(settings.value("ProxyType", QNetworkProxy::NoProxy).toInt()); ui->systemProxy->setChecked(proxyType == QNetworkProxy::NoProxy); ui->manualProxy->setChecked(proxyType != QNetworkProxy::NoProxy); if (proxyType == QNetworkProxy::Socks5Proxy) { ui->proxyType->setCurrentIndex(1); } else { ui->proxyType->setCurrentIndex(0); } ui->proxyServer->setText(settings.value("HostName", "").toString()); ui->proxyPort->setText(settings.value("Port", 8080).toString()); ui->proxyUsername->setText(settings.value("Username", "").toString()); ui->proxyPassword->setText(settings.value("Password", "").toString()); settings.endGroup(); setManualProxyConfigurationEnabled(proxyType != QNetworkProxy::NoProxy); connect(ui->manualProxy, SIGNAL(toggled(bool)), this, SLOT(setManualProxyConfigurationEnabled(bool))); //CONNECTS connect(ui->buttonBox, SIGNAL(clicked(QAbstractButton*)), this, SLOT(buttonClicked(QAbstractButton*))); connect(ui->cookieManagerBut, SIGNAL(clicked()), this, SLOT(showCookieManager())); connect(ui->html5permissions, SIGNAL(clicked()), this, SLOT(showHtml5Permissions())); connect(ui->preferredLanguages, SIGNAL(clicked()), this, SLOT(showAcceptLanguage())); connect(ui->deleteHtml5storage, SIGNAL(clicked()), this, SLOT(deleteHtml5storage())); connect(ui->uaManager, SIGNAL(clicked()), this, SLOT(openUserAgentManager())); connect(ui->jsOptionsButton, SIGNAL(clicked()), this, SLOT(openJsOptions())); connect(ui->searchEngines, SIGNAL(clicked()), this, SLOT(openSearchEnginesManager())); connect(ui->listWidget, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), this, SLOT(showStackedPage(QListWidgetItem*))); ui->listWidget->setItemSelected(ui->listWidget->itemAt(5, 5), true); ui->listWidget->setCurrentRow(currentSettingsPage); QDesktopWidget* desktop = QApplication::desktop(); QSize s = size(); if (desktop->availableGeometry(this).size().width() < s.width()) { s.setWidth(desktop->availableGeometry(this).size().width() - 50); } if (desktop->availableGeometry(this).size().height() < s.height()) { s.setHeight(desktop->availableGeometry(this).size().height() - 50); } resize(s); settings.beginGroup(QSL("Preferences")); restoreGeometry(settings.value(QSL("Geometry")).toByteArray()); settings.endGroup(); QzTools::setWmClass("Preferences", this); } void Preferences::chooseExternalDownloadManager() { QString path = QzTools::getOpenFileName("Preferences-ExternalDownloadManager", this, tr("Choose executable location..."), QDir::homePath()); if (path.isEmpty()) { return; } ui->externalDownExecutable->setText(path); } void Preferences::showStackedPage(QListWidgetItem* item) { if (!item) { return; } int index = ui->listWidget->currentRow(); ui->caption->setText("" + item->text() + ""); ui->stackedWidget->setCurrentIndex(index); if (m_notification) { m_notifPosition = m_notification.data()->pos(); delete m_notification.data(); } if (index == 10) { m_pluginsList->load(); } if (index == 7 && !m_autoFillManager) { m_autoFillManager = new AutoFillManager(this); ui->autoFillFrame->addWidget(m_autoFillManager); m_autoFillManager->setVisible(m_autoFillEnabled); } } void Preferences::showNotificationPreview() { if (ui->useOSDNotifications->isChecked()) { if (m_notification) { m_notifPosition = m_notification.data()->pos(); delete m_notification.data(); } m_notification = new DesktopNotification(true); m_notification.data()->setHeading(tr("OSD Notification")); m_notification.data()->setText(tr("Drag it on the screen to place it where you want.")); m_notification.data()->move(m_notifPosition); m_notification.data()->show(); } else if (ui->useNativeSystemNotifications->isChecked()) { mApp->desktopNotifications()->nativeNotificationPreview(); } } -void Preferences::makeQupZillaDefault() +void Preferences::makeFalkonDefault() { #if defined(Q_OS_WIN) && !defined(Q_OS_OS2) - disconnect(ui->checkNowDefaultBrowser, SIGNAL(clicked()), this, SLOT(makeQupZillaDefault())); + disconnect(ui->checkNowDefaultBrowser, SIGNAL(clicked()), this, SLOT(makeFalkonDefault())); ui->checkNowDefaultBrowser->setText(tr("Default")); ui->checkNowDefaultBrowser->setEnabled(false); if (!mApp->associationManager()->showNativeDefaultAppSettingsUi()) mApp->associationManager()->registerAllAssociation(); #endif } void Preferences::allowCacheChanged(bool state) { ui->removeCache->setEnabled(state); ui->maxCacheLabel->setEnabled(state); ui->cacheMB->setEnabled(state); ui->storeCacheLabel->setEnabled(state); ui->cachePath->setEnabled(state); ui->changeCachePath->setEnabled(state); } void Preferences::useActualHomepage() { if (!m_window) return; ui->homepage->setText(m_window->weView()->url().toString()); } void Preferences::useActualNewTab() { if (!m_window) return; ui->newTabUrl->setText(m_window->weView()->url().toString()); } void Preferences::chooseDownPath() { QString userFileName = QzTools::getExistingDirectory("Preferences-ChooseDownPath", this, tr("Choose download location..."), QDir::homePath()); if (userFileName.isEmpty()) { return; } #ifdef Q_OS_WIN //QFileDialog::getExistingDirectory returns path with \ instead of / (??) userFileName.replace(QLatin1Char('\\'), QLatin1Char('/')); #endif userFileName += QLatin1Char('/'); ui->downLoc->setText(userFileName); } void Preferences::chooseUserStyleClicked() { QString file = QzTools::getOpenFileName("Preferences-UserStyle", this, tr("Choose stylesheet location..."), QDir::homePath(), "*.css"); if (file.isEmpty()) { return; } ui->userStyleSheet->setText(file); } void Preferences::deleteHtml5storage() { ClearPrivateData::clearLocalStorage(); ui->deleteHtml5storage->setText(tr("Deleted")); ui->deleteHtml5storage->setEnabled(false); } void Preferences::openUserAgentManager() { UserAgentDialog* dialog = new UserAgentDialog(this); dialog->open(); } void Preferences::downLocChanged(bool state) { ui->downButt->setEnabled(state); ui->downLoc->setEnabled(state); } void Preferences::setManualProxyConfigurationEnabled(bool state) { ui->proxyType->setEnabled(state); ui->proxyServer->setEnabled(state); ui->proxyPort->setEnabled(state); ui->proxyUsername->setEnabled(state); ui->proxyPassword->setEnabled(state); } void Preferences::searchFromAddressBarChanged(bool stat) { ui->searchWithDefaultEngine->setEnabled(stat); } void Preferences::saveHistoryChanged(bool stat) { ui->deleteHistoryOnClose->setEnabled(stat); } void Preferences::allowHtml5storageChanged(bool stat) { ui->deleteHtml5storageOnClose->setEnabled(stat); } void Preferences::showCookieManager() { CookieManager* dialog = new CookieManager(); dialog->show(); } void Preferences::showHtml5Permissions() { HTML5PermissionsDialog* dialog = new HTML5PermissionsDialog(this); dialog->open(); } void Preferences::openJsOptions() { JsOptions* dialog = new JsOptions(this); dialog->open(); } void Preferences::useExternalDownManagerChanged(bool state) { ui->externalDownExecutable->setEnabled(state); ui->externalDownArguments->setEnabled(state); ui->chooseExternalDown->setEnabled(state); } void Preferences::openSearchEnginesManager() { SearchEnginesDialog* dialog = new SearchEnginesDialog(this); dialog->open(); } void Preferences::showAcceptLanguage() { AcceptLanguage* dialog = new AcceptLanguage(this); dialog->open(); } void Preferences::newTabChanged(int value) { ui->newTabFrame->setVisible(value == 3); } void Preferences::afterLaunchChanged(int value) { ui->dontLoadTabsUntilSelected->setEnabled(value == 3); } void Preferences::changeCachePathClicked() { QString path = QzTools::getExistingDirectory("Preferences-CachePath", this, tr("Choose cache path..."), ui->cachePath->text()); if (path.isEmpty()) { return; } ui->cachePath->setText(path); } void Preferences::showPassManager(bool state) { if (m_autoFillManager) { m_autoFillManager->setVisible(state); } else { m_autoFillEnabled = state; } } void Preferences::buttonClicked(QAbstractButton* button) { switch (ui->buttonBox->buttonRole(button)) { case QDialogButtonBox::ApplyRole: saveSettings(); break; case QDialogButtonBox::RejectRole: close(); break; case QDialogButtonBox::AcceptRole: saveSettings(); close(); break; default: break; } } void Preferences::createProfile() { QString name = QInputDialog::getText(this, tr("New Profile"), tr("Enter the new profile's name:")); name = QzTools::filterCharsFromFilename(name); if (name.isEmpty()) { return; } int res = ProfileManager::createProfile(name); if (res == -1) { QMessageBox::warning(this, tr("Error!"), tr("This profile already exists!")); return; } if (res != 0) { QMessageBox::warning(this, tr("Error!"), tr("Cannot create profile directory!")); return; } ui->startProfile->addItem(name); ui->startProfile->setCurrentIndex(ui->startProfile->count() - 1); } void Preferences::deleteProfile() { QString name = ui->startProfile->currentText(); QMessageBox::StandardButton button = QMessageBox::warning(this, tr("Confirmation"), tr("Are you sure you want to permanently delete \"%1\" profile? This action cannot be undone!").arg(name), QMessageBox::Yes | QMessageBox::No); if (button != QMessageBox::Yes) { return; } ProfileManager::removeProfile(name); ui->startProfile->removeItem(ui->startProfile->currentIndex()); } void Preferences::startProfileIndexChanged(int index) { const bool current = ui->startProfile->itemText(index) == ProfileManager::currentProfile(); ui->deleteProfile->setEnabled(!current); ui->cannotDeleteActiveProfileLabel->setText(current ? tr("Note: You cannot delete active profile.") : QString()); } void Preferences::closeEvent(QCloseEvent* event) { Settings settings; settings.beginGroup("Browser-View-Settings"); settings.setValue("settingsDialogPage", ui->stackedWidget->currentIndex()); settings.endGroup(); event->accept(); } void Preferences::saveSettings() { Settings settings; //GENERAL URLs QUrl homepage = QUrl::fromUserInput(ui->homepage->text()); settings.beginGroup("Web-URL-Settings"); settings.setValue("homepage", homepage); settings.setValue("afterLaunch", ui->afterLaunch->currentIndex()); switch (ui->newTab->currentIndex()) { case 0: settings.setValue("newTabUrl", QUrl()); break; case 1: settings.setValue("newTabUrl", homepage); break; case 2: - settings.setValue("newTabUrl", QUrl(QSL("qupzilla:speeddial"))); + settings.setValue("newTabUrl", QUrl(QSL("falkon:speeddial"))); break; case 3: settings.setValue("newTabUrl", QUrl::fromUserInput(ui->newTabUrl->text())); break; default: break; } settings.endGroup(); //PROFILES /* * * * */ //WINDOW settings.beginGroup("Browser-View-Settings"); settings.setValue("showStatusBar", ui->showStatusbar->isChecked()); settings.setValue("instantBookmarksToolbar", ui->instantBookmarksToolbar->isChecked()); settings.setValue("showBookmarksToolbar", ui->showBookmarksToolbar->isChecked()); settings.setValue("showNavigationToolbar", ui->showNavigationToolbar->isChecked()); settings.setValue("showHomeButton", ui->showHome->isChecked()); settings.setValue("showBackForwardButtons", ui->showBackForward->isChecked()); settings.setValue("showWebSearchBar", ui->showWebSearchBar->isChecked()); settings.setValue("showAddTabButton", ui->showAddTabButton->isChecked()); settings.setValue("showReloadButton", ui->showReloadStopButtons->isChecked()); settings.endGroup(); //TABS settings.beginGroup("Browser-Tabs-Settings"); settings.setValue("hideTabsWithOneTab", ui->hideTabsOnTab->isChecked()); settings.setValue("ActivateLastTabWhenClosingActual", ui->activateLastTab->isChecked()); settings.setValue("newTabAfterActive", ui->openNewTabAfterActive->isChecked()); settings.setValue("newEmptyTabAfterActive", ui->openNewEmptyTabAfterActive->isChecked()); settings.setValue("OpenPopupsInTabs", ui->openPopupsInTabs->isChecked()); settings.setValue("AlwaysSwitchTabsWithWheel", ui->alwaysSwitchTabsWithWheel->isChecked()); settings.setValue("OpenNewTabsSelected", ui->switchToNewTabs->isChecked()); settings.setValue("dontCloseWithOneTab", ui->dontCloseOnLastTab->isChecked()); settings.setValue("AskOnClosing", ui->askWhenClosingMultipleTabs->isChecked()); settings.setValue("showClosedTabsButton", ui->showClosedTabsButton->isChecked()); settings.setValue("showCloseOnInactiveTabs", ui->showCloseOnInactive->currentIndex()); settings.endGroup(); //DOWNLOADS settings.beginGroup("DownloadManager"); if (ui->askEverytime->isChecked()) { settings.setValue("defaultDownloadPath", ""); } else { settings.setValue("defaultDownloadPath", ui->downLoc->text()); } settings.setValue("CloseManagerOnFinish", ui->closeDownManOnFinish->isChecked()); settings.setValue("UseExternalManager", ui->useExternalDownManager->isChecked()); settings.setValue("ExternalManagerExecutable", ui->externalDownExecutable->text()); settings.setValue("ExternalManagerArguments", ui->externalDownArguments->text()); settings.endGroup(); //FONTS settings.beginGroup("Browser-Fonts"); settings.setValue("StandardFont", ui->fontStandard->currentFont().family()); settings.setValue("CursiveFont", ui->fontCursive->currentFont().family()); settings.setValue("FantasyFont", ui->fontFantasy->currentFont().family()); settings.setValue("FixedFont", ui->fontFixed->currentFont().family()); settings.setValue("SansSerifFont", ui->fontSansSerif->currentFont().family()); settings.setValue("SerifFont", ui->fontSerif->currentFont().family()); settings.setValue("DefaultFontSize", ui->sizeDefault->value()); settings.setValue("FixedFontSize", ui->sizeFixed->value()); settings.setValue("MinimumFontSize", ui->sizeMinimum->value()); settings.setValue("MinimumLogicalFontSize", ui->sizeMinimumLogical->value()); settings.endGroup(); //KEYBOARD SHORTCUTS settings.beginGroup("Shortcuts"); settings.setValue("useTabNumberShortcuts", ui->switchTabsAlt->isChecked()); settings.setValue("useSpeedDialNumberShortcuts", ui->loadSpeedDialsCtrl->isChecked()); settings.setValue("useSingleKeyShortcuts", ui->singleKeyShortcuts->isChecked()); settings.endGroup(); //BROWSING settings.beginGroup("Web-Browser-Settings"); settings.setValue("allowPlugins", ui->allowPlugins->isChecked()); settings.setValue("allowJavaScript", ui->allowJavaScript->isChecked()); settings.setValue("IncludeLinkInFocusChain", ui->linksInFocusChain->isChecked()); settings.setValue("SpatialNavigation", ui->spatialNavigation->isChecked()); settings.setValue("AnimateScrolling", ui->animateScrolling->isChecked()); settings.setValue("wheelScrollLines", ui->wheelScroll->value()); settings.setValue("DoNotTrack", ui->doNotTrack->isChecked()); settings.setValue("CheckUpdates", ui->checkUpdates->isChecked()); settings.setValue("LoadTabsOnActivation", ui->dontLoadTabsUntilSelected->isChecked()); settings.setValue("DefaultZoomLevel", ui->defaultZoomLevel->currentIndex()); settings.setValue("XSSAuditing", ui->xssAuditing->isChecked()); settings.setValue("PrintElementBackground", ui->printEBackground->isChecked()); settings.setValue("closeAppWithCtrlQ", ui->closeAppWithCtrlQ->isChecked()); settings.setValue("UseNativeScrollbars", ui->useNativeScrollbars->isChecked()); #ifdef Q_OS_WIN settings.setValue("CheckDefaultBrowser", ui->checkDefaultBrowser->isChecked()); #endif //Cache settings.setValue("AllowLocalCache", ui->allowCache->isChecked()); settings.setValue("deleteCacheOnClose", ui->removeCache->isChecked()); settings.setValue("LocalCacheSize", ui->cacheMB->value()); settings.setValue("CachePath", ui->cachePath->text()); //CSS Style settings.setValue("userStyleSheet", ui->userStyleSheet->text()); //PASSWORD MANAGER settings.setValue("SavePasswordsOnSites", ui->allowPassManager->isChecked()); //PRIVACY //Web storage settings.setValue("allowHistory", ui->saveHistory->isChecked()); settings.setValue("deleteHistoryOnClose", ui->deleteHistoryOnClose->isChecked()); settings.setValue("HTML5StorageEnabled", ui->html5storage->isChecked()); settings.setValue("deleteHTML5StorageOnClose", ui->deleteHtml5storageOnClose->isChecked()); settings.endGroup(); //NOTIFICATIONS settings.beginGroup("Notifications"); settings.setValue("Timeout", ui->notificationTimeout->value() * 1000); settings.setValue("Enabled", !ui->doNotUseNotifications->isChecked()); settings.setValue("UseNativeDesktop", ui->useNativeSystemNotifications->isChecked()); settings.setValue("Position", m_notification.data() ? m_notification.data()->pos() : m_notifPosition); settings.endGroup(); //SPELLCHECK settings.beginGroup(QSL("SpellCheck")); settings.setValue("Enabled", ui->spellcheckEnabled->isChecked()); QStringList languages; for (int i = 0; i < ui->spellcheckLanguages->count(); ++i) { QListWidgetItem *item = ui->spellcheckLanguages->item(i); if (item->isSelected()) { languages.append(item->data(Qt::UserRole).toString()); } } settings.setValue("Languages", languages); settings.endGroup(); //OTHER //AddressBar settings.beginGroup("AddressBar"); settings.setValue("showSuggestions", ui->addressbarCompletion->currentIndex()); settings.setValue("useInlineCompletion", ui->useInlineCompletion->isChecked()); settings.setValue("alwaysShowGoIcon", ui->alwaysShowGoIcon->isChecked()); settings.setValue("showSwitchTab", ui->completionShowSwitchTab->isChecked()); settings.setValue("SelectAllTextOnDoubleClick", ui->selectAllOnFocus->isChecked()); settings.setValue("SelectAllTextOnClick", ui->selectAllOnClick->isChecked()); settings.setValue("ShowLoadingProgress", ui->showLoadingInAddressBar->isChecked()); settings.setValue("ProgressStyle", ui->progressStyleSelector->currentIndex()); settings.setValue("UseCustomProgressColor", ui->checkBoxCustomProgressColor->isChecked()); settings.setValue("CustomProgressColor", ui->customColorToolButton->property("ProgressColor").value()); settings.endGroup(); settings.beginGroup("SearchEngines"); settings.setValue("SearchFromAddressBar", ui->searchFromAddressBar->isChecked()); settings.setValue("SearchWithDefaultEngine", ui->searchWithDefaultEngine->isChecked()); settings.endGroup(); //Languages settings.beginGroup("Language"); settings.setValue("language", ui->languages->itemData(ui->languages->currentIndex()).toString()); settings.endGroup(); //Proxy Configuration QNetworkProxy::ProxyType proxyType; if (ui->systemProxy->isChecked()) { proxyType = QNetworkProxy::NoProxy; } else if (ui->proxyType->currentIndex() == 0) { proxyType = QNetworkProxy::HttpProxy; } else { proxyType = QNetworkProxy::Socks5Proxy; } settings.beginGroup("Web-Proxy"); settings.setValue("ProxyType", proxyType); settings.setValue("HostName", ui->proxyServer->text()); settings.setValue("Port", ui->proxyPort->text().toInt()); settings.setValue("Username", ui->proxyUsername->text()); settings.setValue("Password", ui->proxyPassword->text()); settings.endGroup(); ProfileManager::setStartingProfile(ui->startProfile->currentText()); m_pluginsList->save(); m_themesManager->save(); mApp->cookieJar()->loadSettings(); mApp->history()->loadSettings(); mApp->reloadSettings(); mApp->plugins()->c2f_saveSettings(); mApp->desktopNotifications()->loadSettings(); mApp->autoFill()->loadSettings(); mApp->networkManager()->loadSettings(); WebScrollBarManager::instance()->loadSettings(); } Preferences::~Preferences() { Settings().setValue(QSL("Preferences/Geometry"), saveGeometry()); delete ui; delete m_autoFillManager; delete m_pluginsList; delete m_notification.data(); } void Preferences::setProgressBarColorIcon(QColor color) { const int size = style()->pixelMetric(QStyle::PM_ToolBarIconSize); QPixmap pm(QSize(size, size)); if (!color.isValid()) { color = palette().color(QPalette::Highlight); } pm.fill(color); ui->customColorToolButton->setIcon(pm); ui->customColorToolButton->setProperty("ProgressColor", color); } void Preferences::selectCustomProgressBarColor() { QColor newColor = QColorDialog::getColor(ui->customColorToolButton->property("ProgressColor").value(), this, tr("Select Color")); if (newColor.isValid()) { setProgressBarColorIcon(newColor); } } diff --git a/src/lib/preferences/preferences.h b/src/lib/preferences/preferences.h index 2e3fe1a7..b0e0ef9c 100644 --- a/src/lib/preferences/preferences.h +++ b/src/lib/preferences/preferences.h @@ -1,111 +1,111 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef PREFERENCES_H #define PREFERENCES_H #include #include #include #include "qzcommon.h" namespace Ui { class Preferences; } class QAbstractButton; class QListWidgetItem; class AutoFillManager; class BrowserWindow; class PluginsManager; class DesktopNotification; class ThemeManager; -class QUPZILLA_EXPORT Preferences : public QWidget +class FALKON_EXPORT Preferences : public QWidget { Q_OBJECT public: explicit Preferences(BrowserWindow* window); ~Preferences(); private slots: void saveSettings(); void buttonClicked(QAbstractButton* button); void showStackedPage(QListWidgetItem* item); void chooseDownPath(); void showCookieManager(); void showHtml5Permissions(); void useActualHomepage(); void useActualNewTab(); void showAcceptLanguage(); void chooseUserStyleClicked(); void deleteHtml5storage(); void chooseExternalDownloadManager(); void openUserAgentManager(); void openJsOptions(); void openSearchEnginesManager(); void searchFromAddressBarChanged(bool state); void saveHistoryChanged(bool state); void allowHtml5storageChanged(bool state); void downLocChanged(bool state); void allowCacheChanged(bool state); void showPassManager(bool state); void setManualProxyConfigurationEnabled(bool state); void useExternalDownManagerChanged(bool state); void changeCachePathClicked(); void newTabChanged(int value); void afterLaunchChanged(int value); void createProfile(); void deleteProfile(); void startProfileIndexChanged(int index); void setProgressBarColorIcon(QColor col = QColor()); void selectCustomProgressBarColor(); void showNotificationPreview(); - void makeQupZillaDefault(); + void makeFalkonDefault(); private: void closeEvent(QCloseEvent* event); Ui::Preferences* ui; BrowserWindow* m_window; AutoFillManager* m_autoFillManager; PluginsManager* m_pluginsList; ThemeManager* m_themesManager; QPointer m_notification; QUrl m_homepage; QUrl m_newTabUrl; QString m_actProfileName; int m_afterLaunch; int m_onNewTab; QPoint m_notifPosition; bool m_autoFillEnabled; }; #endif // PREFERENCES_H diff --git a/src/lib/preferences/preferences.ui b/src/lib/preferences/preferences.ui index 19788e6c..cff521de 100644 --- a/src/lib/preferences/preferences.ui +++ b/src/lib/preferences/preferences.ui @@ -1,2791 +1,2791 @@ Preferences 0 0 840 550 Preferences 220 0 220 16777215 false 32 32 QAbstractItemView::ScrollPerPixel QListView::Static 2 true true false General Appearance Tabs Browsing Fonts Keyboard Shortcuts Downloads Password Manager Privacy Notifications Extensions Spell Check Other Qt::Horizontal QFrame::NoFrame true 0 0 582 489 0 0 0 0 Qt::NoFocus 0 0 0 0 0 Use current QFrame::NoFrame QFrame::Raised 0 0 20 0 Note: You cannot delete active profile. Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 0 0 Create New false 0 0 Delete Qt::Horizontal QSizePolicy::Fixed 20 10 <b>Launching</b> After launch: Open blank page Open homepage Open speed dial Restore session Select session Homepage: Use current On new tab: Open blank tab Open homepage Open speed dial Open other page... <b>Profiles</b> Startup profile: Check for updates on start Active profile: In order to change language, you must restart browser. <b>Language</b> 0 0 200 0 Available translations: Don't load tabs until selected Qt::Vertical 20 40 - Check to see if QupZilla is the default browser on startup + Check to see if Falkon is the default browser on startup false Check Now Qt::Horizontal 40 20 0 Themes 0 0 0 0 Advanced options <b>Browser Window</b> Qt::Horizontal QSizePolicy::Fixed 20 20 Qt::Horizontal 40 20 Show StatusBar on start Show Bookmarks ToolBar on start Show Navigation ToolBar on start Enable instant Bookmarks ToolBar <b>Navigation ToolBar</b> Show Home button Show Back / Forward buttons Qt::Vertical 20 40 Show Add Tab button Show web search bar Show Reload / Stop buttons 0 Tabs behaviour Hide tabs when there is only one tab Activate last tab when closing active tab Open new tabs after active tab Open new empty tabs after active tab Open popup windows in tabs Always switch between tabs with mouse wheel Automatically switch to newly opened tab Don't close window upon closing last tab Ask when closing multiple tabs Show closed tabs button Show close buttons on inactive tabs: Automatic Always Never Qt::Horizontal QSizePolicy::Expanding 40 20 Qt::Vertical 20 40 Address Bar behaviour Suggest when typing into address bar: 170 0 History and Bookmarks History Bookmarks Nothing Qt::Horizontal QSizePolicy::Expanding 40 20 Enable inline suggestions Press "Shift" to not switch the tab but load the url in the current tab Propose to switch tab if completed url is already loaded Always show go icon Select all text by double clicking in address bar Select all text by clicking in address bar Enable automatic searching from the address bar Search with Default Engine Qt::Vertical QSizePolicy::Fixed 20 10 Show loading progress in address bar 0 0 Qt::Horizontal QSizePolicy::Fixed 20 20 Fill Bottom Top Custom color: 0 0 Select color ... Reset Qt::Horizontal 40 20 Qt::Vertical 20 40 0 Web Configuration Allow Pepper Plugins (Flash plugin) Allow JavaScript Include links in focus chain Enable XSS Auditing Print element background Animated scrolling Enable spatial navigation Use native scrollbars 0 0 Mouse wheel scrolls 0 0 1 lines on page Default zoom on pages: Qt::Horizontal 40 20 Qt::Vertical 20 40 Local Storage Allow storing network cache on disk Qt::Horizontal QSizePolicy::Fixed 40 20 Delete cache on close Maximum: MB 1 999999999 50 Store cache in: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter ... Allow saving history Delete history on close Qt::Horizontal QSizePolicy::Fixed 40 20 Allow local storage of HTML5 web content Delete locally stored HTML5 web content on close Qt::Horizontal 40 20 0 0 Delete now Qt::Vertical 20 40 Qt::Vertical QSizePolicy::Fixed 20 10 Proxy Configuration Qt::Vertical 20 40 System proxy configuration Qt::Horizontal QSizePolicy::Fixed 40 20 Manual configuration HTTP SOCKS5 Port: 50 16777215 Username: Password: Qt::Horizontal 40 20 <b>Font Families</b> 0 0 Standard Fixed Serif Sans Serif Cursive Qt::Vertical 20 40 Qt::Horizontal QSizePolicy::Fixed 20 20 0 0 Fantasy <b>Font Sizes</b> Fixed Font Size Default Font Size 0 0 0 0 Minimum Font Size Minimum Logical Font Size 0 0 0 0 <b>Shortcuts</b> Switch to tabs with Alt + number of tab Load speed dials with Ctrl + number of speed dial Existing shortcuts:<br/><b>1</b> - previous tab<br/><b>2</b> - next tab<br/><b>/</b> - search on page Use single key shortcuts If unchecked, prevents accidental exit from the application if the Ctrl-W shortcut was intended. Close application with Ctrl-Q Qt::Vertical 20 40 <b>Download Location</b> Ask everytime for download location Use defined location: ... Qt::Horizontal 40 20 Qt::Horizontal QSizePolicy::Fixed 20 20 <b>Download Options</b> Close download manager when downloading finishes <b>External download manager</b> Use external download manager QFormLayout::AllNonFixedFieldsGrow Executable: Arguments: Leave blank if unsure ... <b>%d</b> will be replaced with URL to be downloaded Qt::Vertical 20 40 <b>AutoFill options</b> Allow saving passwords from sites Qt::Horizontal QSizePolicy::Fixed 20 20 Qt::Horizontal 40 20 0 0 QLayout::SetMinAndMaxSize <b>Cookies</b> <b>Other</b> Qt::Vertical 20 40 0 0 JavaScript options true <b>JavaScript</b> 0 0 Cookies Manager false Manage JavaScript privacy options Qt::Horizontal QSizePolicy::Fixed 20 20 Manage HTML5 permissions Manage Cookies Qt::Horizontal 40 20 <b>HTML5 Permissions</b> 0 0 HTML5 Permissions Send Do Not Track header to servers Qt::Horizontal 40 20 Expiration timeout: 0 0 seconds Qt::Horizontal 40 20 <b>Notifications</b> Qt::Vertical 20 40 false Use Native System Notifications (Linux only) Do not use Notifications Qt::Horizontal QSizePolicy::Fixed 20 20 <b>Note: </b>You can change position of OSD Notification by dragging it on the screen. true Qt::Vertical QSizePolicy::Fixed 0 20 Use OSD Notifications Preview Qt::Horizontal 40 20 0 0 0 0 0 0 Qt::Horizontal 40 20 For more information about Spell Check, please see <a href="https://github.com/QupZilla/qupzilla/wiki/Spell-Check">wiki</a>. Qt::AlignCenter true Qt::Vertical 20 40 Qt::Vertical QSizePolicy::Fixed 20 40 <b>Spell Check options</b> Enable Spell Check <b>Dictionary directories</b> 0 0 true 0 0 560 80 16777215 100 true QAbstractItemView::InternalMove QAbstractItemView::MultiSelection No languages found <b>Manage search engines</b> <b>User Style Sheet</b> Style Sheet automatically loaded with all websites: ... Qt::Vertical 20 40 <b>Preferred language for web sites</b> Qt::Horizontal 40 20 <b>Change browser identification</b> Qt::Horizontal QSizePolicy::Fixed 20 20 User Agent Manager Qt::Horizontal 40 20 Qt::Horizontal QSizePolicy::Fixed 20 20 Languages Qt::Horizontal 40 20 Qt::Horizontal QSizePolicy::Fixed 20 20 Search Engines Manager Qt::Horizontal 40 20 Qt::Horizontal QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok MacToolButton QToolButton
mactoolbutton.h
buttonBox afterLaunch homepage useCurrentBut newTab newTabUrl newTabUseCurrent checkUpdates startProfile createProfile deleteProfile tabWidget_2 hideTabsOnTab askWhenClosingMultipleTabs selectAllOnFocus selectAllOnClick tabWidget allowPlugins wheelScroll fontStandard fontFixed fontSerif fontSansSerif fontCursive fontFantasy askEverytime useDefined downLoc downButt closeDownManOnFinish allowPassManager useOSDNotifications useNativeSystemNotifications doNotUseNotifications notificationTimeout preferredLanguages userStyleSheet chooseUserStylesheet showBackForward allowCache cacheMB saveHistory deleteHistoryOnClose proxyServer proxyPort manualProxy systemProxy showStatusbar showNavigationToolbar showHome showBookmarksToolbar showLoadingInAddressBar toggled(bool) adressProgressSettings setEnabled(bool) 513 117 513 154 checkBoxCustomProgressColor toggled(bool) progressBarColorSelector setEnabled(bool) 405 152 567 157
diff --git a/src/lib/preferences/thememanager.cpp b/src/lib/preferences/thememanager.cpp index cc172384..156bf819 100644 --- a/src/lib/preferences/thememanager.cpp +++ b/src/lib/preferences/thememanager.cpp @@ -1,176 +1,176 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "thememanager.h" #include "ui_thememanager.h" #include "qztools.h" #include "settings.h" #include "datapaths.h" #include "licenseviewer.h" #include "preferences.h" #include "qzregexp.h" #include #include ThemeManager::ThemeManager(QWidget* parent, Preferences* preferences) : QWidget() , ui(new Ui::ThemeManager) , m_preferences(preferences) { ui->setupUi(parent); ui->listWidget->setLayoutDirection(Qt::LeftToRight); ui->license->hide(); Settings settings; settings.beginGroup("Themes"); m_activeTheme = settings.value("activeTheme", DEFAULT_THEME_NAME).toString(); settings.endGroup(); const QStringList themePaths = DataPaths::allPaths(DataPaths::Themes); foreach (const QString &path, themePaths) { QDir dir(path); QStringList list = dir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot); foreach (const QString &name, list) { Theme themeInfo = parseTheme(dir.absoluteFilePath(name) + QLatin1Char('/'), name); if (!themeInfo.isValid) { continue; } QListWidgetItem* item = new QListWidgetItem(ui->listWidget); item->setText(themeInfo.name + "\n" + themeInfo.shortDescription); item->setIcon(themeInfo.icon); item->setData(Qt::UserRole, name); if (m_activeTheme == name) { ui->listWidget->setCurrentItem(item); } ui->listWidget->addItem(item); } } connect(ui->listWidget, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), this, SLOT(currentChanged())); connect(ui->license, SIGNAL(clicked(QPoint)), this, SLOT(showLicense())); currentChanged(); } void ThemeManager::showLicense() { QListWidgetItem* currentItem = ui->listWidget->currentItem(); if (!currentItem) { return; } Theme currentTheme = m_themeHash[currentItem->data(Qt::UserRole).toString()]; LicenseViewer* v = new LicenseViewer(m_preferences); v->setText(currentTheme.license); v->show(); } void ThemeManager::currentChanged() { QListWidgetItem* currentItem = ui->listWidget->currentItem(); if (!currentItem) { return; } Theme currentTheme = m_themeHash[currentItem->data(Qt::UserRole).toString()]; ui->name->setText(currentTheme.name); ui->author->setText(currentTheme.author); ui->descirption->setText(currentTheme.longDescription); ui->license->setHidden(currentTheme.license.isEmpty()); } ThemeManager::Theme ThemeManager::parseTheme(const QString &path, const QString &name) { Theme info; info.isValid = false; if (!QFile(path + "main.css").exists() || !QFile(path + "theme.info").exists()) { info.isValid = false; return info; } if (QFile(path + "theme.png").exists()) { info.icon = QIcon(path + "theme.png"); } else { info.icon = QIcon(":icons/preferences/style-default.png"); } if (QFile(path + "theme.license").exists()) { info.license = QzTools::readAllFileContents(path + "theme.license"); } QString theme_info = QzTools::readAllFileContents(path + "theme.info"); QzRegExp rx("Name:(.*)\\n"); rx.setMinimal(true); rx.indexIn(theme_info); if (rx.captureCount() == 1) { info.name = rx.cap(1).trimmed(); } if (info.name.isEmpty() || m_themeHash.contains(info.name)) { return info; } rx.setPattern("Author:(.*)\\n"); rx.indexIn(theme_info); if (rx.captureCount() == 1) { info.author = rx.cap(1).trimmed(); } rx.setPattern("Short Description:(.*)\\n"); rx.indexIn(theme_info); if (rx.captureCount() == 1) { info.shortDescription = rx.cap(1).trimmed(); } rx.setPattern("Long Description:(.*)\\n"); rx.indexIn(theme_info); if (rx.captureCount() == 1) { info.longDescription = rx.cap(1).trimmed(); } info.isValid = true; m_themeHash.insert(name, info); return info; } void ThemeManager::save() { QListWidgetItem* currentItem = ui->listWidget->currentItem(); if (!currentItem) { return; } Settings settings; settings.beginGroup("Themes"); settings.setValue("activeTheme", currentItem->data(Qt::UserRole)); settings.endGroup(); } ThemeManager::~ThemeManager() { delete ui; } diff --git a/src/lib/preferences/thememanager.h b/src/lib/preferences/thememanager.h index 00e8f51d..e479f7b4 100644 --- a/src/lib/preferences/thememanager.h +++ b/src/lib/preferences/thememanager.h @@ -1,69 +1,69 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef THEMEMANAGER_H #define THEMEMANAGER_H #include #include #include #include "qzcommon.h" namespace Ui { class ThemeManager; } class Preferences; -class QUPZILLA_EXPORT ThemeManager : public QWidget +class FALKON_EXPORT ThemeManager : public QWidget { Q_OBJECT public: explicit ThemeManager(QWidget* parent, Preferences* preferences); ~ThemeManager(); void save(); private slots: void currentChanged(); void showLicense(); private: struct Theme { bool isValid; QIcon icon; QString name; QString author; QString shortDescription; QString longDescription; QString license; }; Theme parseTheme(const QString &path, const QString &name); Ui::ThemeManager* ui; Preferences* m_preferences; QString m_activeTheme; QHash m_themeHash; }; #endif // THEMEMANAGER_H diff --git a/src/lib/preferences/useragentdialog.cpp b/src/lib/preferences/useragentdialog.cpp index a3639217..af887c8c 100644 --- a/src/lib/preferences/useragentdialog.cpp +++ b/src/lib/preferences/useragentdialog.cpp @@ -1,238 +1,238 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "useragentdialog.h" #include "ui_useragentdialog.h" #include "useragentmanager.h" #include "qztools.h" #include "mainapplication.h" #include "settings.h" #include #include #include UserAgentDialog::UserAgentDialog(QWidget* parent) : QDialog(parent) , ui(new Ui::UserAgentDialog) , m_manager(mApp->userAgentManager()) { setAttribute(Qt::WA_DeleteOnClose); ui->setupUi(this); ui->globalComboBox->setLayoutDirection(Qt::LeftToRight); ui->table->setLayoutDirection(Qt::LeftToRight); QString os = QzTools::operatingSystemLong(); #ifdef Q_OS_UNIX if (QGuiApplication::platformName() == QL1S("xcb")) os.prepend(QL1S("X11; ")); else if (QGuiApplication::platformName().startsWith(QL1S("wayland"))) os.prepend(QL1S("Wayland; ")); #endif m_knownUserAgents << QString("Opera/9.80 (%1) Presto/2.12.388 Version/12.16").arg(os) << QString("Mozilla/5.0 (%1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36").arg(os) << QString("Mozilla/5.0 (%1) AppleWebKit/602.3.12 (KHTML, like Gecko) Version/10.0.2 Safari/602.3.12").arg(os) << QString("Mozilla/5.0 (%1; rv:50.0) Gecko/20100101 Firefox/50.0").arg(os); ui->globalComboBox->addItems(m_knownUserAgents); const QString globalUserAgent = m_manager->globalUserAgent(); ui->changeGlobal->setChecked(!globalUserAgent.isEmpty()); ui->globalComboBox->lineEdit()->setText(globalUserAgent); ui->globalComboBox->lineEdit()->setCursorPosition(0); ui->changePerSite->setChecked(m_manager->usePerDomainUserAgents()); QHashIterator i(m_manager->perDomainUserAgentsList()); while (i.hasNext()) { i.next(); QTableWidgetItem* siteItem = new QTableWidgetItem(i.key()); QTableWidgetItem* userAgentItem = new QTableWidgetItem(i.value()); int row = ui->table->rowCount(); ui->table->insertRow(row); ui->table->setItem(row, 0, siteItem); ui->table->setItem(row, 1, userAgentItem); } ui->table->sortByColumn(-1); connect(ui->add, SIGNAL(clicked()), this, SLOT(addSite())); connect(ui->remove, SIGNAL(clicked()), this, SLOT(removeSite())); connect(ui->edit, SIGNAL(clicked()), this, SLOT(editSite())); connect(ui->table, SIGNAL(itemDoubleClicked(QTableWidgetItem*)), this, SLOT(editSite())); connect(ui->changeGlobal, SIGNAL(clicked(bool)), this, SLOT(enableGlobalComboBox(bool))); connect(ui->changePerSite, SIGNAL(clicked(bool)), this, SLOT(enablePerSiteFrame(bool))); enableGlobalComboBox(ui->changeGlobal->isChecked()); enablePerSiteFrame(ui->changePerSite->isChecked()); } void UserAgentDialog::addSite() { QString site; QString userAgent; if (showEditDialog(tr("Add new site"), &site, &userAgent)) { QTableWidgetItem* siteItem = new QTableWidgetItem(site); QTableWidgetItem* userAgentItem = new QTableWidgetItem(userAgent); int row = ui->table->rowCount(); ui->table->insertRow(row); ui->table->setItem(row, 0, siteItem); ui->table->setItem(row, 1, userAgentItem); } } void UserAgentDialog::removeSite() { int row = ui->table->currentRow(); QTableWidgetItem* siteItem = ui->table->item(row, 0); QTableWidgetItem* userAgentItem = ui->table->item(row, 1); if (siteItem && userAgentItem) { delete siteItem; delete userAgentItem; ui->table->removeRow(row); } } void UserAgentDialog::editSite() { int row = ui->table->currentRow(); QTableWidgetItem* siteItem = ui->table->item(row, 0); QTableWidgetItem* userAgentItem = ui->table->item(row, 1); if (siteItem && userAgentItem) { QString site = siteItem->text(); QString userAgent = userAgentItem->text(); if (showEditDialog(tr("Edit site"), &site, &userAgent)) { siteItem->setText(site); userAgentItem->setText(userAgent); } } } void UserAgentDialog::accept() { QString globalUserAgent = ui->changeGlobal->isChecked() ? ui->globalComboBox->currentText() : QString(); QStringList domainList; QStringList userAgentsList; for (int i = 0; i < ui->table->rowCount(); ++i) { QTableWidgetItem* siteItem = ui->table->item(i, 0); QTableWidgetItem* userAgentItem = ui->table->item(i, 1); if (!siteItem || !userAgentItem) { continue; } QString domain = siteItem->text().trimmed(); QString userAgent = userAgentItem->text().trimmed(); if (domain.isEmpty() || userAgent.isEmpty()) { continue; } domainList.append(domain); userAgentsList.append(userAgent); } Settings settings; settings.beginGroup("Web-Browser-Settings"); settings.setValue("UserAgent", globalUserAgent); settings.endGroup(); settings.beginGroup("User-Agent-Settings"); settings.setValue("UsePerDomainUA", ui->changePerSite->isChecked()); settings.setValue("DomainList", domainList); settings.setValue("UserAgentsList", userAgentsList); settings.endGroup(); m_manager->loadSettings(); close(); } void UserAgentDialog::enableGlobalComboBox(bool enable) { ui->globalComboBox->setEnabled(enable); } void UserAgentDialog::enablePerSiteFrame(bool enable) { ui->perSiteFrame->setEnabled(enable); } bool UserAgentDialog::showEditDialog(const QString &title, QString* rSite, QString* rUserAgent) { if (!rSite || !rUserAgent) { return false; } QDialog* dialog = new QDialog(this); QFormLayout* layout = new QFormLayout(dialog); QLineEdit* editSite = new QLineEdit(dialog); QComboBox* editAgent = new QComboBox(dialog); editAgent->setLayoutDirection(Qt::LeftToRight); editAgent->setEditable(true); editAgent->addItems(m_knownUserAgents); QDialogButtonBox* box = new QDialogButtonBox(dialog); box->addButton(QDialogButtonBox::Ok); box->addButton(QDialogButtonBox::Cancel); connect(box, SIGNAL(rejected()), dialog, SLOT(reject())); connect(box, SIGNAL(accepted()), dialog, SLOT(accept())); layout->addRow(new QLabel(tr("Site domain: ")), editSite); layout->addRow(new QLabel(tr("User Agent: ")), editAgent); layout->addRow(box); editSite->setText(*rSite); editAgent->lineEdit()->setText(*rUserAgent); editSite->setFocus(); editAgent->lineEdit()->setCursorPosition(0); dialog->setWindowTitle(title); dialog->setMinimumSize(550, 100); dialog->setMaximumWidth(550); if (dialog->exec()) { *rSite = editSite->text(); *rUserAgent = editAgent->currentText(); return !rSite->isEmpty() && !rUserAgent->isEmpty(); } return false; } UserAgentDialog::~UserAgentDialog() { delete ui; } diff --git a/src/lib/preferences/useragentdialog.h b/src/lib/preferences/useragentdialog.h index 0e9b511f..aa0838a3 100644 --- a/src/lib/preferences/useragentdialog.h +++ b/src/lib/preferences/useragentdialog.h @@ -1,60 +1,60 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef USERAGENTDIALOG_H #define USERAGENTDIALOG_H #include #include #include "qzcommon.h" class UserAgentManager; namespace Ui { class UserAgentDialog; } -class QUPZILLA_EXPORT UserAgentDialog : public QDialog +class FALKON_EXPORT UserAgentDialog : public QDialog { Q_OBJECT public: explicit UserAgentDialog(QWidget* parent = 0); ~UserAgentDialog(); private slots: void addSite(); void removeSite(); void editSite(); void accept(); void enableGlobalComboBox(bool enable); void enablePerSiteFrame(bool enable); private: bool showEditDialog(const QString &title, QString* rSite, QString* rUserAgent); Ui::UserAgentDialog* ui; UserAgentManager* m_manager; QStringList m_knownUserAgents; }; #endif // USERAGENTDIALOG_H diff --git a/src/lib/session/recoveryjsobject.cpp b/src/lib/session/recoveryjsobject.cpp index 2bcb7693..02e81e1a 100644 --- a/src/lib/session/recoveryjsobject.cpp +++ b/src/lib/session/recoveryjsobject.cpp @@ -1,126 +1,126 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2015-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "recoveryjsobject.h" #include "mainapplication.h" #include "webpage.h" #include "tabbedwebview.h" #include "browserwindow.h" #include "qztools.h" #include "iconprovider.h" #include RecoveryJsObject::RecoveryJsObject(RestoreManager *manager) : QObject() , m_manager(manager) , m_page(Q_NULLPTR) { } void RecoveryJsObject::setPage(WebPage *page) { Q_ASSERT(page); m_page = page; } QJsonArray RecoveryJsObject::restoreData() const { QJsonArray out; int i = 0; Q_FOREACH (const RestoreManager::WindowData &w, m_manager->restoreData()) { int j = 0; QJsonArray tabs; Q_FOREACH (const WebTab::SavedTab &t, w.tabsState) { const QIcon icon = t.icon.isNull() ? IconProvider::emptyWebIcon() : t.icon; QJsonObject tab; tab[QSL("tab")] = j; tab[QSL("icon")] = QzTools::pixmapToDataUrl(icon.pixmap(16)).toString(); tab[QSL("title")] = t.title; tab[QSL("url")] = t.url.toString(); tab[QSL("pinned")] = t.isPinned; tab[QSL("current")] = w.currentTab == j; tabs.append(tab); j++; } QJsonObject window; window[QSL("window")] = i++; window[QSL("tabs")] = tabs; out.append(window); } return out; } void RecoveryJsObject::startNewSession() { BrowserWindow *window = getBrowserWindow(); if (!window) return; m_page->load(window->homepageUrl()); mApp->destroyRestoreManager(); } void RecoveryJsObject::restoreSession(const QStringList &excludeWin, const QStringList &excludeTab) { Q_ASSERT(excludeWin.size() == excludeTab.size()); // This assumes that excludeWin and excludeTab are sorted in descending order RestoreData data = m_manager->restoreData(); for (int i = 0; i < excludeWin.size(); ++i) { int win = excludeWin.at(i).toInt(); int tab = excludeTab.at(i).toInt(); if (!QzTools::containsIndex(data, win) || !QzTools::containsIndex(data.at(win).tabsState, tab)) continue; RestoreManager::WindowData &wd = data[win]; wd.tabsState.remove(tab); if (wd.currentTab >= tab) --wd.currentTab; if (wd.tabsState.isEmpty()) { data.remove(win); continue; } if (wd.currentTab < 0) wd.currentTab = wd.tabsState.size() - 1; } BrowserWindow *window = getBrowserWindow(); if (!window) return; if (!mApp->restoreSession(window , data)) startNewSession(); } BrowserWindow *RecoveryJsObject::getBrowserWindow() const { TabbedWebView *view = qobject_cast(m_page->view()); return view ? view->browserWindow() : Q_NULLPTR; } diff --git a/src/lib/session/recoveryjsobject.h b/src/lib/session/recoveryjsobject.h index 8b1c9268..208f8106 100644 --- a/src/lib/session/recoveryjsobject.h +++ b/src/lib/session/recoveryjsobject.h @@ -1,52 +1,52 @@ /* ============================================================ -* QupZilla - QtWebEngine based browser +* Falkon - Qt web browser * Copyright (C) 2015 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef RECOVERYJSOBJECT_H #define RECOVERYJSOBJECT_H #include #include class WebPage; class BrowserWindow; class RestoreManager; class RecoveryJsObject : public QObject { Q_OBJECT Q_PROPERTY(QJsonArray restoreData READ restoreData CONSTANT) public: explicit RecoveryJsObject(RestoreManager *manager); void setPage(WebPage *page); QJsonArray restoreData() const; public slots: void startNewSession(); void restoreSession(const QStringList &excludeWin, const QStringList &excludeTab); private: BrowserWindow *getBrowserWindow() const; RestoreManager *m_manager; WebPage *m_page; }; #endif // RECOVERYJSOBJECT_H diff --git a/src/lib/session/restoremanager.cpp b/src/lib/session/restoremanager.cpp index 90ee0a26..16d88334 100644 --- a/src/lib/session/restoremanager.cpp +++ b/src/lib/session/restoremanager.cpp @@ -1,111 +1,111 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 Franz Fellner * David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "restoremanager.h" #include "recoveryjsobject.h" #include "datapaths.h" #include RestoreManager::RestoreManager(const QString &file) : m_recoveryObject(new RecoveryJsObject(this)) { createFromFile(file); } RestoreManager::~RestoreManager() { delete m_recoveryObject; } RestoreData RestoreManager::restoreData() const { return m_data; } bool RestoreManager::isValid() const { return !m_data.isEmpty(); } QObject *RestoreManager::recoveryObject(WebPage *page) { m_recoveryObject->setPage(page); return m_recoveryObject; } void RestoreManager::createFromFile(const QString &file, QVector &data) { if (!QFile::exists(file)) { return; } QFile recoveryFile(file); recoveryFile.open(QIODevice::ReadOnly); QDataStream stream(&recoveryFile); int version; stream >> version; if (version != Qz::sessionVersion && version != Qz::sessionVersionQt5) { return; } int windowCount; stream >> windowCount; for (int win = 0; win < windowCount; ++win) { QByteArray tabState; QByteArray windowState; stream >> tabState; stream >> windowState; WindowData wd; wd.windowState = windowState; QDataStream tabStream(tabState); if (tabStream.atEnd()) { continue; } QVector tabs; int tabListCount = 0; tabStream >> tabListCount; for (int i = 0; i < tabListCount; ++i) { WebTab::SavedTab tab; tabStream >> tab; tabs.append(tab); } if (tabs.count() == 0) continue; wd.tabsState = tabs; int currentTab; tabStream >> currentTab; wd.currentTab = currentTab; data.append(wd); } } void RestoreManager::createFromFile(const QString &file) { createFromFile(file, m_data); } diff --git a/src/lib/session/restoremanager.h b/src/lib/session/restoremanager.h index 69b168c6..880a18cd 100644 --- a/src/lib/session/restoremanager.h +++ b/src/lib/session/restoremanager.h @@ -1,58 +1,58 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 Franz Fellner * David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef RESTOREMANAGER_H #define RESTOREMANAGER_H #include "webtab.h" #include "qzcommon.h" class WebPage; class RecoveryJsObject; -class QUPZILLA_EXPORT RestoreManager +class FALKON_EXPORT RestoreManager { public: struct WindowData { int currentTab; QByteArray windowState; QVector tabsState; }; explicit RestoreManager(const QString &file); virtual ~RestoreManager(); bool isValid() const; QVector restoreData() const; QObject *recoveryObject(WebPage *page); static void createFromFile(const QString &file, QVector &data); private: void createFromFile(const QString &file); RecoveryJsObject *m_recoveryObject; QVector m_data; }; typedef QVector RestoreData; // Hint to QVector to use std::realloc on item moving Q_DECLARE_TYPEINFO(RestoreManager::WindowData, Q_MOVABLE_TYPE); #endif // RESTOREMANAGER_H diff --git a/src/lib/session/sessionmanager.cpp b/src/lib/session/sessionmanager.cpp index e55e5753..920aa261 100644 --- a/src/lib/session/sessionmanager.cpp +++ b/src/lib/session/sessionmanager.cpp @@ -1,416 +1,416 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2017 Razi Alavizadeh * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "browserwindow.h" #include "datapaths.h" #include "mainapplication.h" #include "restoremanager.h" #include "sessionmanager.h" #include "sessionmanagerdialog.h" #include "settings.h" #include #include #include #include #include #include #include #include #include #include #include #include SessionManager::SessionManager(QObject* parent) : QObject(parent) , m_firstBackupSession(DataPaths::currentProfilePath() + QL1S("/session.dat.old")) , m_secondBackupSession(DataPaths::currentProfilePath() + QL1S("/session.dat.old1")) { QFileSystemWatcher* sessionFilesWatcher = new QFileSystemWatcher({DataPaths::path(DataPaths::Sessions)}, this); connect(sessionFilesWatcher, SIGNAL(directoryChanged(QString)), this, SLOT(sessionsDirectoryChanged())); connect(sessionFilesWatcher, &QFileSystemWatcher::directoryChanged, this, &SessionManager::sessionsMetaDataChanged); loadSettings(); } void SessionManager::aboutToShowSessionsMenu() { QMenu* menu = qobject_cast(sender()); menu->clear(); QActionGroup *group = new QActionGroup(menu); const auto sessions = sessionMetaData(/*withBackups*/ false); for (const SessionManager::SessionMetaData &metaData : sessions) { QAction* action = menu->addAction(metaData.name); action->setCheckable(true); action->setChecked(metaData.isActive); group->addAction(action); connect(action, &QAction::triggered, this, [=]() { switchToSession(metaData.filePath); }); } } void SessionManager::sessionsDirectoryChanged() { m_sessionsMetaDataList.clear(); } void SessionManager::openSession(QString sessionFilePath, SessionFlags flags) { if (sessionFilePath.isEmpty()) { QAction* action = qobject_cast(sender()); if (!action) return; sessionFilePath = action->data().toString(); } if (isActive(sessionFilePath)) { return; } QVector sessionData; RestoreManager::createFromFile(sessionFilePath, sessionData); if (sessionData.isEmpty()) return; BrowserWindow* window = mApp->getWindow(); if (flags.testFlag(SwitchSession)) { writeCurrentSession(m_lastActiveSessionPath); window = mApp->createWindow(Qz::BW_OtherRestoredWindow); for (BrowserWindow* win : mApp->windows()) { if (win != window) win->close(); } if (!flags.testFlag(ReplaceSession)) { m_lastActiveSessionPath = QFileInfo(sessionFilePath).canonicalFilePath(); m_sessionsMetaDataList.clear(); } } mApp->openSession(window, sessionData); } void SessionManager::renameSession(QString sessionFilePath, SessionFlags flags) { if (sessionFilePath.isEmpty()) { QAction* action = qobject_cast(sender()); if (!action) return; sessionFilePath = action->data().toString(); } bool ok; const QString suggestedName = QFileInfo(sessionFilePath).baseName() + (flags.testFlag(CloneSession) ? tr("_cloned") : tr("_renamed")); QString newName = QInputDialog::getText(mApp->activeWindow(), (flags.testFlag(CloneSession) ? tr("Clone Session") : tr("Rename Session")), tr("Please enter a new name:"), QLineEdit::Normal, suggestedName, &ok); if (!ok) return; const QString newSessionPath = QString("%1/%2.dat").arg(DataPaths::path(DataPaths::Sessions)).arg(newName); if (QFile::exists(newSessionPath)) { QMessageBox::information(mApp->activeWindow(), tr("Error!"), tr("The session file \"%1\" exists. Please enter another name.").arg(newName)); renameSession(sessionFilePath, flags); return; } if (flags.testFlag(CloneSession)) { if (!QFile::copy(sessionFilePath, newSessionPath)) { QMessageBox::information(mApp->activeWindow(), tr("Error!"), tr("An error occurred when cloning session file.")); return; } } else { if (!QFile::rename(sessionFilePath, newSessionPath)) { QMessageBox::information(mApp->activeWindow(), tr("Error!"), tr("An error occurred when renaming session file.")); return; } if (isActive(sessionFilePath)) { m_lastActiveSessionPath = newSessionPath; m_sessionsMetaDataList.clear(); } } } void SessionManager::saveSession() { bool ok; QString sessionName = QInputDialog::getText(mApp->activeWindow(), tr("Save Session"), tr("Please enter a name to save session:"), QLineEdit::Normal, tr("Saved Session (%1)").arg(QDateTime::currentDateTime().toString("dd MMM yyyy HH-mm-ss")), &ok); if (!ok) return; const QString filePath = QString("%1/%2.dat").arg(DataPaths::path(DataPaths::Sessions)).arg(sessionName); if (QFile::exists(filePath)) { QMessageBox::information(mApp->activeWindow(), tr("Error!"), tr("The session file \"%1\" exists. Please enter another name.").arg(sessionName)); saveSession(); return; } writeCurrentSession(filePath); } void SessionManager::replaceSession(const QString &filePath) { QMessageBox::StandardButton result = QMessageBox::information(mApp->activeWindow(), tr("Restore Backup"), tr("Are you sure you want to replace current session?"), QMessageBox::Yes | QMessageBox::No); if (result == QMessageBox::Yes) { openSession(filePath, ReplaceSession); } } void SessionManager::switchToSession(const QString &filePath) { openSession(filePath, SwitchSession); } void SessionManager::cloneSession(const QString &filePath) { renameSession(filePath, CloneSession); } void SessionManager::deleteSession(const QString &filePath) { QMessageBox::StandardButton result = QMessageBox::information(mApp->activeWindow(), tr("Delete Session"), tr("Are you sure you want to delete session '%1'?") .arg(QFileInfo(filePath).baseName()), QMessageBox::Yes | QMessageBox::No); if (result == QMessageBox::Yes) { QFile::remove(filePath); } } void SessionManager::newSession() { bool ok; QString sessionName = QInputDialog::getText(mApp->activeWindow(), tr("New Session"), tr("Please enter a name to create new session:"), QLineEdit::Normal, tr("New Session (%1)").arg(QDateTime::currentDateTime().toString("dd MMM yyyy HH-mm-ss")), &ok); if (!ok) return; const QString filePath = QString("%1/%2.dat").arg(DataPaths::path(DataPaths::Sessions)).arg(sessionName); if (QFile::exists(filePath)) { QMessageBox::information(mApp->activeWindow(), tr("Error!"), tr("The session file \"%1\" exists. Please enter another name.").arg(sessionName)); newSession(); return; } writeCurrentSession(m_lastActiveSessionPath); BrowserWindow* window = mApp->createWindow(Qz::BW_NewWindow); for (BrowserWindow* win : mApp->windows()) { if (win != window) win->close(); } m_lastActiveSessionPath = filePath; autoSaveLastSession(); } QList SessionManager::sessionMetaData(bool withBackups) { fillSessionsMetaDataListIfNeeded(); auto out = m_sessionsMetaDataList; if (withBackups && QFile::exists(m_firstBackupSession)) { SessionMetaData data; data.name = tr("Backup 1"); data.filePath = m_firstBackupSession; data.isBackup = true; out.append(data); } if (withBackups && QFile::exists(m_secondBackupSession)) { SessionMetaData data; data.name = tr("Backup 2"); data.filePath = m_secondBackupSession; data.isBackup = true; out.append(data); } return out; } bool SessionManager::isActive(const QString &filePath) const { return QFileInfo(filePath) == QFileInfo(m_lastActiveSessionPath); } bool SessionManager::isActive(const QFileInfo &fileInfo) const { return fileInfo == QFileInfo(m_lastActiveSessionPath); } void SessionManager::fillSessionsMetaDataListIfNeeded() { if (!m_sessionsMetaDataList.isEmpty()) return; QDir dir(DataPaths::path(DataPaths::Sessions)); const QFileInfoList sessionFiles = QFileInfoList() << QFileInfo(defaultSessionPath()) << dir.entryInfoList({QSL("*.*")}, QDir::Files, QDir::Time); QStringList fileNames; for (int i = 0; i < sessionFiles.size(); ++i) { const QFileInfo &fileInfo = sessionFiles.at(i); QVector data; RestoreManager::createFromFile(fileInfo.absoluteFilePath(), data); if (data.isEmpty()) continue; SessionMetaData metaData; metaData.name = fileInfo.baseName(); if (fileInfo == QFileInfo(defaultSessionPath())) { metaData.name = tr("Default Session"); metaData.isDefault = true; } else if (fileNames.contains(fileInfo.baseName())) { metaData.name = fileInfo.fileName(); } else { metaData.name = fileInfo.baseName(); } if (isActive(fileInfo)) { metaData.isActive = true; } fileNames << metaData.name; metaData.filePath = fileInfo.canonicalFilePath(); m_sessionsMetaDataList << metaData; } } void SessionManager::loadSettings() { Settings settings; settings.beginGroup("Web-Browser-Settings"); m_lastActiveSessionPath = settings.value("lastActiveSessionPath", defaultSessionPath()).toString(); settings.endGroup(); // fallback to default session if (!QFile::exists(m_lastActiveSessionPath)) m_lastActiveSessionPath = defaultSessionPath(); } void SessionManager::saveSettings() { Settings settings; settings.beginGroup("Web-Browser-Settings"); settings.setValue("lastActiveSessionPath", m_lastActiveSessionPath); settings.endGroup(); } QString SessionManager::defaultSessionPath() { return DataPaths::currentProfilePath() + QL1S("/session.dat"); } QString SessionManager::lastActiveSessionPath() const { return m_lastActiveSessionPath; } void SessionManager::backupSavedSessions() { if (!QFile::exists(m_lastActiveSessionPath)) { return; } if (QFile::exists(m_firstBackupSession)) { QFile::remove(m_secondBackupSession); QFile::copy(m_firstBackupSession, m_secondBackupSession); } QFile::remove(m_firstBackupSession); QFile::copy(m_lastActiveSessionPath, m_firstBackupSession); } void SessionManager::writeCurrentSession(const QString &filePath) { QSaveFile file(filePath); if (!file.open(QIODevice::WriteOnly) || file.write(mApp->saveState()) == -1) { qWarning() << "Error! can not write the current session file: " << filePath << file.errorString(); return; } file.commit(); } void SessionManager::openSessionManagerDialog() { SessionManagerDialog *dialog = new SessionManagerDialog(mApp->getWindow()); dialog->open(); } void SessionManager::autoSaveLastSession() { if (mApp->isPrivate() || mApp->isRestoring() || mApp->windowCount() == 0 || mApp->restoreManager()) { return; } saveSettings(); writeCurrentSession(m_lastActiveSessionPath); } QString SessionManager::askSessionFromUser() { fillSessionsMetaDataListIfNeeded(); QDialog dialog(mApp->getWindow(), Qt::WindowStaysOnTopHint); QLabel label(tr("Please select the startup session:"), &dialog); QComboBox comboBox(&dialog); QDialogButtonBox buttonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, &dialog); connect(&buttonBox, &QDialogButtonBox::accepted, &dialog, &QDialog::accept); connect(&buttonBox, &QDialogButtonBox::rejected, &dialog, &QDialog::reject); QVBoxLayout layout; layout.addWidget(&label); layout.addWidget(&comboBox); layout.addWidget(&buttonBox); dialog.setLayout(&layout); const QFileInfo lastActiveSessionFileInfo(m_lastActiveSessionPath); for (const SessionMetaData &metaData : m_sessionsMetaDataList) { if (QFileInfo(metaData.filePath) != lastActiveSessionFileInfo) { comboBox.addItem(metaData.name, metaData.filePath); } else { comboBox.insertItem(0, tr("%1 (last session)").arg(metaData.name), metaData.filePath); } } comboBox.setCurrentIndex(0); if (dialog.exec() == QDialog::Accepted) { m_lastActiveSessionPath = comboBox.currentData().toString(); } return m_lastActiveSessionPath; } diff --git a/src/lib/session/sessionmanager.h b/src/lib/session/sessionmanager.h index 0223c14f..bf6179c5 100644 --- a/src/lib/session/sessionmanager.h +++ b/src/lib/session/sessionmanager.h @@ -1,97 +1,97 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2017 Razi Alavizadeh * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef SESSIONMANAGER_H #define SESSIONMANAGER_H #include "qzcommon.h" class QAction; class QMenu; class QFileInfo; -class QUPZILLA_EXPORT SessionManager : public QObject +class FALKON_EXPORT SessionManager : public QObject { Q_OBJECT public: struct SessionMetaData { QString name; QString filePath; bool isActive = false; bool isDefault = false; bool isBackup = false; }; enum SessionFlag { SwitchSession = 1, CloneSession = 2, ReplaceSession = SwitchSession | 4 }; Q_DECLARE_FLAGS(SessionFlags, SessionFlag) explicit SessionManager(QObject* parent = 0); void loadSettings(); void saveSettings(); static QString defaultSessionPath(); QString lastActiveSessionPath() const; QString askSessionFromUser(); void backupSavedSessions(); void writeCurrentSession(const QString &filePath); signals: void sessionsMetaDataChanged(); public slots: void autoSaveLastSession(); void openSessionManagerDialog(); private slots: void aboutToShowSessionsMenu(); void sessionsDirectoryChanged(); void openSession(QString sessionFilePath = QString(), SessionFlags flags = nullptr); void renameSession(QString sessionFilePath = QString(), SessionFlags flags = nullptr); void saveSession(); void replaceSession(const QString &filePath); void switchToSession(const QString &filePath); void cloneSession(const QString &filePath); void deleteSession(const QString &filePath); void newSession(); QList sessionMetaData(bool withBackups = true); private: bool isActive(const QString &filePath) const; bool isActive(const QFileInfo &fileInfo) const; void fillSessionsMetaDataListIfNeeded(); QList m_sessionsMetaDataList; QString m_firstBackupSession; QString m_secondBackupSession; QString m_lastActiveSessionPath; friend class SessionManagerDialog; }; Q_DECLARE_OPERATORS_FOR_FLAGS(SessionManager::SessionFlags) #endif // SESSIONMANAGER_H diff --git a/src/lib/session/sessionmanagerdialog.cpp b/src/lib/session/sessionmanagerdialog.cpp index c756eb38..eeb391c6 100644 --- a/src/lib/session/sessionmanagerdialog.cpp +++ b/src/lib/session/sessionmanagerdialog.cpp @@ -1,186 +1,186 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "sessionmanagerdialog.h" #include "ui_sessionmanagerdialog.h" #include "mainapplication.h" #include "sessionmanager.h" #include "removeitemfocusdelegate.h" #include #include SessionManagerDialog::SessionManagerDialog(QWidget *parent) : QDialog(parent), ui(new Ui::SessionManagerDialog) { ui->setupUi(this); setAttribute(Qt::WA_DeleteOnClose); ui->treeWidget->setItemDelegate(new RemoveItemFocusDelegate(ui->treeWidget)); connect(ui->newButton, &QPushButton::clicked, this, &SessionManagerDialog::newSession); connect(ui->renameButton, &QPushButton::clicked, this, &SessionManagerDialog::renameSession); connect(ui->cloneButton, &QPushButton::clicked, this, &SessionManagerDialog::cloneSession); connect(ui->deleteButton, &QPushButton::clicked, this, &SessionManagerDialog::deleteSession); connect(ui->switchToButton, &QPushButton::clicked, this, &SessionManagerDialog::switchToSession); connect(ui->treeWidget, &QTreeWidget::currentItemChanged, this, &SessionManagerDialog::updateButtons); refresh(); connect(mApp->sessionManager(), &SessionManager::sessionsMetaDataChanged, this, &SessionManagerDialog::refresh); } SessionManagerDialog::~SessionManagerDialog() { delete ui; } void SessionManagerDialog::newSession() { mApp->sessionManager()->newSession(); } void SessionManagerDialog::renameSession() { QTreeWidgetItem *item = ui->treeWidget->currentItem(); if (!item) { return; } const QString filePath = item->data(0, SessionFileRole).toString(); if (!filePath.isEmpty()) { mApp->sessionManager()->renameSession(filePath); } } void SessionManagerDialog::cloneSession() { QTreeWidgetItem *item = ui->treeWidget->currentItem(); if (!item) { return; } const QString filePath = item->data(0, SessionFileRole).toString(); if (!filePath.isEmpty()) { mApp->sessionManager()->cloneSession(filePath); } } void SessionManagerDialog::deleteSession() { QTreeWidgetItem *item = ui->treeWidget->currentItem(); if (!item) { return; } const QString filePath = item->data(0, SessionFileRole).toString(); if (!filePath.isEmpty()) { mApp->sessionManager()->deleteSession(filePath); } } void SessionManagerDialog::switchToSession() { QTreeWidgetItem *item = ui->treeWidget->currentItem(); if (!item) { return; } const QString filePath = item->data(0, SessionFileRole).toString(); if (!filePath.isEmpty()) { if (item->data(0, IsBackupSessionRole).toBool()) { mApp->sessionManager()->replaceSession(filePath); } else { mApp->sessionManager()->switchToSession(filePath); } } } void SessionManagerDialog::refresh() { ui->treeWidget->clear(); const auto sessions = mApp->sessionManager()->sessionMetaData(); for (const auto &session : sessions) { QTreeWidgetItem *item = new QTreeWidgetItem; item->setText(0, session.name); item->setText(1, QFileInfo(session.filePath).lastModified().toString(Qt::DefaultLocaleShortDate)); item->setData(0, SessionFileRole, session.filePath); item->setData(0, IsBackupSessionRole, session.isBackup); item->setData(0, IsActiveSessionRole, session.isActive); item->setData(0, IsDefaultSessionRole, session.isDefault); updateItem(item); ui->treeWidget->addTopLevelItem(item); } updateButtons(); } void SessionManagerDialog::updateButtons() { QTreeWidgetItem *item = ui->treeWidget->currentItem(); const bool isBackup = item && item->data(0, IsBackupSessionRole).toBool(); const bool isActive = item && item->data(0, IsActiveSessionRole).toBool(); const bool isDefault = item && item->data(0, IsDefaultSessionRole).toBool(); ui->renameButton->setEnabled(item && !isDefault && !isBackup); ui->cloneButton->setEnabled(item && !isBackup); ui->deleteButton->setEnabled(item && !isBackup && !isDefault && !isActive); ui->switchToButton->setEnabled(item && !isActive); ui->switchToButton->setText(isBackup ? tr("Restore") : tr("Switch To")); } void SessionManagerDialog::updateItem(QTreeWidgetItem *item) { const bool isBackup = item->data(0, IsBackupSessionRole).toBool(); const bool isActive = item->data(0, IsActiveSessionRole).toBool(); const bool isDefault = item->data(0, IsDefaultSessionRole).toBool(); QFont font = item->font(0); if (isBackup) { const QColor color = palette().color(QPalette::Disabled, QPalette::WindowText); item->setForeground(0, color); item->setForeground(1, color); } if (isActive) { font.setBold(true); item->setFont(0, font); item->setFont(1, font); } if (isDefault) { font.setItalic(true); item->setFont(0, font); item->setFont(1, font); } } void SessionManagerDialog::showEvent(QShowEvent *e) { QDialog::showEvent(e); resizeViewHeader(); } void SessionManagerDialog::resizeEvent(QResizeEvent *e) { QDialog::resizeEvent(e); resizeViewHeader(); } void SessionManagerDialog::resizeViewHeader() { const int headerWidth = ui->treeWidget->header()->width(); ui->treeWidget->header()->resizeSection(0, headerWidth - headerWidth / 2.5); } diff --git a/src/lib/session/sessionmanagerdialog.h b/src/lib/session/sessionmanagerdialog.h index 21a2fb6c..69e151b3 100644 --- a/src/lib/session/sessionmanagerdialog.h +++ b/src/lib/session/sessionmanagerdialog.h @@ -1,62 +1,62 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef SESSIONMANAGERDIALOG_H #define SESSIONMANAGERDIALOG_H #include namespace Ui { class SessionManagerDialog; } class QTreeWidgetItem; class SessionManagerDialog : public QDialog { Q_OBJECT public: explicit SessionManagerDialog(QWidget *parent = 0); ~SessionManagerDialog(); private: enum Roles { SessionFileRole = Qt::UserRole + 10, IsBackupSessionRole, IsActiveSessionRole, IsDefaultSessionRole }; void newSession(); void renameSession(); void cloneSession(); void deleteSession(); void switchToSession(); void refresh(); void updateButtons(); void updateItem(QTreeWidgetItem *item); void showEvent(QShowEvent *e) override; void resizeEvent(QResizeEvent *e) override; void resizeViewHeader(); Ui::SessionManagerDialog *ui; }; #endif // SESSIONMANAGERDIALOG_H diff --git a/src/lib/sidebar/bookmarkssidebar.cpp b/src/lib/sidebar/bookmarkssidebar.cpp index f7650712..0df13dc9 100644 --- a/src/lib/sidebar/bookmarkssidebar.cpp +++ b/src/lib/sidebar/bookmarkssidebar.cpp @@ -1,136 +1,136 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "bookmarkssidebar.h" #include "ui_bookmarkssidebar.h" #include "bookmarkstools.h" #include "bookmarkitem.h" #include "bookmarks.h" #include "mainapplication.h" #include "iconprovider.h" #include BookmarksSidebar::BookmarksSidebar(BrowserWindow* window, QWidget* parent) : QWidget(parent) , ui(new Ui::BookmarksSideBar) , m_window(window) , m_bookmarks(mApp->bookmarks()) { ui->setupUi(this); ui->tree->setViewType(BookmarksTreeView::BookmarksSidebarViewType); connect(ui->tree, SIGNAL(bookmarkActivated(BookmarkItem*)), this, SLOT(bookmarkActivated(BookmarkItem*))); connect(ui->tree, SIGNAL(bookmarkCtrlActivated(BookmarkItem*)), this, SLOT(bookmarkCtrlActivated(BookmarkItem*))); connect(ui->tree, SIGNAL(bookmarkShiftActivated(BookmarkItem*)), this, SLOT(bookmarkShiftActivated(BookmarkItem*))); connect(ui->tree, SIGNAL(contextMenuRequested(QPoint)), this, SLOT(createContextMenu(QPoint))); connect(ui->search, SIGNAL(textChanged(QString)), ui->tree, SLOT(search(QString))); } BookmarksSidebar::~BookmarksSidebar() { delete ui; } void BookmarksSidebar::bookmarkActivated(BookmarkItem* item) { openBookmark(item); } void BookmarksSidebar::bookmarkCtrlActivated(BookmarkItem* item) { openBookmarkInNewTab(item); } void BookmarksSidebar::bookmarkShiftActivated(BookmarkItem* item) { openBookmarkInNewWindow(item); } void BookmarksSidebar::openBookmark(BookmarkItem* item) { item = item ? item : ui->tree->selectedBookmark(); BookmarksTools::openBookmark(m_window, item); } void BookmarksSidebar::openBookmarkInNewTab(BookmarkItem* item) { item = item ? item : ui->tree->selectedBookmark(); BookmarksTools::openBookmarkInNewTab(m_window, item); } void BookmarksSidebar::openBookmarkInNewWindow(BookmarkItem* item) { item = item ? item : ui->tree->selectedBookmark(); BookmarksTools::openBookmarkInNewWindow(item); } void BookmarksSidebar::openBookmarkInNewPrivateWindow(BookmarkItem* item) { item = item ? item : ui->tree->selectedBookmark(); BookmarksTools::openBookmarkInNewPrivateWindow(item); } void BookmarksSidebar::deleteBookmarks() { QList items = ui->tree->selectedBookmarks(); foreach (BookmarkItem* item, items) { if (m_bookmarks->canBeModified(item)) { m_bookmarks->removeBookmark(item); } } } void BookmarksSidebar::createContextMenu(const QPoint &pos) { QMenu menu; QAction* actNewTab = menu.addAction(IconProvider::newTabIcon(), tr("Open in new tab")); QAction* actNewWindow = menu.addAction(IconProvider::newWindowIcon(), tr("Open in new window")); QAction* actNewPrivateWindow = menu.addAction(IconProvider::privateBrowsingIcon(), tr("Open in new private window")); menu.addSeparator(); QAction* actDelete = menu.addAction(QIcon::fromTheme("edit-delete"), tr("Delete")); connect(actNewTab, SIGNAL(triggered()), this, SLOT(openBookmarkInNewTab())); connect(actNewWindow, SIGNAL(triggered()), this, SLOT(openBookmarkInNewWindow())); connect(actNewPrivateWindow, SIGNAL(triggered()), this, SLOT(openBookmarkInNewPrivateWindow())); connect(actDelete, SIGNAL(triggered()), this, SLOT(deleteBookmarks())); bool canBeDeleted = false; QList items = ui->tree->selectedBookmarks(); foreach (BookmarkItem* item, items) { if (m_bookmarks->canBeModified(item)) { canBeDeleted = true; break; } } if (!canBeDeleted) { actDelete->setDisabled(true); } if (!ui->tree->selectedBookmark() || !ui->tree->selectedBookmark()->isUrl()) { actNewTab->setDisabled(true); actNewWindow->setDisabled(true); actNewPrivateWindow->setDisabled(true); } menu.exec(pos); } diff --git a/src/lib/sidebar/bookmarkssidebar.h b/src/lib/sidebar/bookmarkssidebar.h index 70f3cadc..c4a6ed79 100644 --- a/src/lib/sidebar/bookmarkssidebar.h +++ b/src/lib/sidebar/bookmarkssidebar.h @@ -1,61 +1,61 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef BOOKMARKSSIDEBAR_H #define BOOKMARKSSIDEBAR_H #include #include "qzcommon.h" namespace Ui { class BookmarksSideBar; } class BrowserWindow; class Bookmarks; class BookmarkItem; -class QUPZILLA_EXPORT BookmarksSidebar : public QWidget +class FALKON_EXPORT BookmarksSidebar : public QWidget { Q_OBJECT public: explicit BookmarksSidebar(BrowserWindow* window, QWidget* parent = 0); ~BookmarksSidebar(); private slots: void bookmarkActivated(BookmarkItem* item); void bookmarkCtrlActivated(BookmarkItem* item); void bookmarkShiftActivated(BookmarkItem* item); void openBookmark(BookmarkItem* item = 0); void openBookmarkInNewTab(BookmarkItem* item = 0); void openBookmarkInNewWindow(BookmarkItem* item = 0); void openBookmarkInNewPrivateWindow(BookmarkItem* item = 0); void deleteBookmarks(); void createContextMenu(const QPoint &pos); private: Ui::BookmarksSideBar* ui; BrowserWindow* m_window; Bookmarks* m_bookmarks; }; #endif // BOOKMARKSSIDEBAR_H diff --git a/src/lib/sidebar/historysidebar.cpp b/src/lib/sidebar/historysidebar.cpp index b3cf7d37..e2316176 100644 --- a/src/lib/sidebar/historysidebar.cpp +++ b/src/lib/sidebar/historysidebar.cpp @@ -1,109 +1,109 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "historysidebar.h" #include "ui_historysidebar.h" #include "browserwindow.h" #include "tabwidget.h" #include "tabbedwebview.h" #include "mainapplication.h" #include "qzsettings.h" #include "iconprovider.h" HistorySideBar::HistorySideBar(BrowserWindow* window, QWidget* parent) : QWidget(parent) , ui(new Ui::HistorySideBar) , m_window(window) { ui->setupUi(this); ui->historyTree->setViewType(HistoryTreeView::HistorySidebarViewType); connect(ui->historyTree, SIGNAL(urlActivated(QUrl)), this, SLOT(urlActivated(QUrl))); connect(ui->historyTree, SIGNAL(urlCtrlActivated(QUrl)), this, SLOT(urlCtrlActivated(QUrl))); connect(ui->historyTree, SIGNAL(urlShiftActivated(QUrl)), this, SLOT(urlShiftActivated(QUrl))); connect(ui->historyTree, SIGNAL(contextMenuRequested(QPoint)), this, SLOT(createContextMenu(QPoint))); connect(ui->search, SIGNAL(textEdited(QString)), ui->historyTree, SLOT(search(QString))); } void HistorySideBar::urlActivated(const QUrl &url) { openUrl(url); } void HistorySideBar::urlCtrlActivated(const QUrl &url) { openUrlInNewTab(url); } void HistorySideBar::urlShiftActivated(const QUrl &url) { openUrlInNewWindow(url); } void HistorySideBar::openUrl(const QUrl &url) { const QUrl u = !url.isEmpty() ? url : ui->historyTree->selectedUrl(); m_window->weView()->load(u); } void HistorySideBar::openUrlInNewTab(const QUrl &url) { const QUrl u = !url.isEmpty() ? url : ui->historyTree->selectedUrl(); m_window->tabWidget()->addView(u, qzSettings->newTabPosition); } void HistorySideBar::openUrlInNewWindow(const QUrl &url) { const QUrl u = !url.isEmpty() ? url : ui->historyTree->selectedUrl(); mApp->createWindow(Qz::BW_NewWindow, u); } void HistorySideBar::openUrlInNewPrivateWindow(const QUrl &url) { const QUrl u = !url.isEmpty() ? url : ui->historyTree->selectedUrl(); mApp->startPrivateBrowsing(u); } void HistorySideBar::createContextMenu(const QPoint &pos) { QMenu menu; QAction* actNewTab = menu.addAction(IconProvider::newTabIcon(), tr("Open in new tab")); QAction* actNewWindow = menu.addAction(IconProvider::newWindowIcon(), tr("Open in new window")); QAction* actNewPrivateWindow = menu.addAction(IconProvider::privateBrowsingIcon(), tr("Open in new private window")); menu.addSeparator(); QAction* actDelete = menu.addAction(QIcon::fromTheme(QSL("edit-delete")), tr("Delete")); connect(actNewTab, SIGNAL(triggered()), this, SLOT(openUrlInNewTab())); connect(actNewWindow, SIGNAL(triggered()), this, SLOT(openUrlInNewWindow())); connect(actNewPrivateWindow, SIGNAL(triggered()), this, SLOT(openUrlInNewPrivateWindow())); connect(actDelete, SIGNAL(triggered()), ui->historyTree, SLOT(removeSelectedItems())); if (ui->historyTree->selectedUrl().isEmpty()) { actNewTab->setDisabled(true); actNewWindow->setDisabled(true); actNewPrivateWindow->setDisabled(true); } menu.exec(pos); } HistorySideBar::~HistorySideBar() { delete ui; } diff --git a/src/lib/sidebar/historysidebar.h b/src/lib/sidebar/historysidebar.h index 85b3f918..c6f63d28 100644 --- a/src/lib/sidebar/historysidebar.h +++ b/src/lib/sidebar/historysidebar.h @@ -1,58 +1,58 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef HISTORYSIDEBAR_H #define HISTORYSIDEBAR_H #include #include #include "qzcommon.h" namespace Ui { class HistorySideBar; } class BrowserWindow; -class QUPZILLA_EXPORT HistorySideBar : public QWidget +class FALKON_EXPORT HistorySideBar : public QWidget { Q_OBJECT public: explicit HistorySideBar(BrowserWindow* window, QWidget* parent = 0); ~HistorySideBar(); private slots: void urlActivated(const QUrl &url); void urlCtrlActivated(const QUrl &url); void urlShiftActivated(const QUrl &url); void openUrl(const QUrl &url = QUrl()); void openUrlInNewTab(const QUrl &url = QUrl()); void openUrlInNewWindow(const QUrl &url = QUrl()); void openUrlInNewPrivateWindow(const QUrl &url = QUrl()); void createContextMenu(const QPoint &pos); private: Ui::HistorySideBar* ui; BrowserWindow* m_window; }; #endif // HISTORYSIDEBAR_H diff --git a/src/lib/sidebar/sidebar.cpp b/src/lib/sidebar/sidebar.cpp index 147861f8..8c695732 100644 --- a/src/lib/sidebar/sidebar.cpp +++ b/src/lib/sidebar/sidebar.cpp @@ -1,210 +1,210 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "sidebar.h" #include "sidebarinterface.h" #include "docktitlebarwidget.h" #include "bookmarkssidebar.h" #include "historysidebar.h" #include "mainapplication.h" #include "browserwindow.h" #include "settings.h" #include QHash > SideBarManager::s_sidebars; SideBar::SideBar(SideBarManager* manager, BrowserWindow* window) : QWidget(window) , m_window(window) , m_manager(manager) { setObjectName("sidebar"); setAttribute(Qt::WA_DeleteOnClose); m_layout = new QVBoxLayout(this); m_layout->setContentsMargins(0, 0, 0, 0); m_layout->setSpacing(0); setLayout(m_layout); m_titleBar = new DockTitleBarWidget(QString(), this); m_layout->addWidget(m_titleBar); } void SideBar::setTitle(const QString &title) { m_titleBar->setTitle(title); } void SideBar::setWidget(QWidget* widget) { if (m_layout->count() == 2) { delete m_layout->itemAt(1)->widget(); } if (widget) m_layout->addWidget(widget); } void SideBar::showBookmarks() { m_titleBar->setTitle(tr("Bookmarks")); BookmarksSidebar* bar = new BookmarksSidebar(m_window); setWidget(bar); } void SideBar::showHistory() { m_titleBar->setTitle(tr("History")); HistorySideBar* bar = new HistorySideBar(m_window); setWidget(bar); } void SideBar::close() { m_manager->closeSideBar(); QWidget* p = parentWidget(); if (p) { p->setFocus(); } QWidget::close(); } SideBarManager::SideBarManager(BrowserWindow* parent) : QObject(parent) , m_window(parent) { } void SideBarManager::createMenu(QMenu* menu) { m_window->removeActions(menu->actions()); menu->clear(); QAction* act = menu->addAction(SideBar::tr("Bookmarks"), this, SLOT(slotShowSideBar())); act->setCheckable(true); act->setShortcut(QKeySequence("Ctrl+Shift+B")); act->setData("Bookmarks"); act->setChecked(m_activeBar == QL1S("Bookmarks")); act = menu->addAction(SideBar::tr("History"), this, SLOT(slotShowSideBar())); act->setCheckable(true); act->setShortcut(QKeySequence("Ctrl+H")); act->setData("History"); act->setChecked(m_activeBar == QL1S("History")); foreach (const QPointer &sidebar, s_sidebars) { if (sidebar) { QAction* act = sidebar.data()->createMenuAction(); act->setData(s_sidebars.key(sidebar)); act->setChecked(m_activeBar == s_sidebars.key(sidebar)); connect(act, SIGNAL(triggered()), this, SLOT(slotShowSideBar())); menu->addAction(act); } } m_window->addActions(menu->actions()); } void SideBarManager::addSidebar(const QString &id, SideBarInterface* interface) { s_sidebars[id] = interface; } void SideBarManager::removeSidebar(const QString &id) { s_sidebars.remove(id); foreach (BrowserWindow* window, mApp->windows()) { window->sideBarManager()->sideBarRemoved(id); } } void SideBarManager::slotShowSideBar() { if (QAction* act = qobject_cast(sender())) { showSideBar(act->data().toString()); } } void SideBarManager::showSideBar(const QString &id, bool toggle) { if (id == QLatin1String("None")) { return; } if (!m_sideBar) { m_sideBar = m_window->addSideBar(); } if (id == m_activeBar) { if (!toggle) { return; } m_sideBar.data()->close(); m_activeBar = "None"; Settings settings; settings.setValue("Browser-View-Settings/SideBar", m_activeBar); return; } if (id == QLatin1String("Bookmarks")) { m_sideBar.data()->showBookmarks(); } else if (id == QLatin1String("History")) { m_sideBar.data()->showHistory(); } else { SideBarInterface* sidebar = s_sidebars[id].data(); if (!sidebar) { m_sideBar.data()->close(); return; } m_sideBar.data()->setTitle(sidebar->title()); m_sideBar.data()->setWidget(sidebar->createSideBarWidget(m_window)); } m_activeBar = id; Settings settings; settings.setValue("Browser-View-Settings/SideBar", m_activeBar); } void SideBarManager::sideBarRemoved(const QString &id) { if (m_activeBar == id && m_sideBar) { m_sideBar.data()->setWidget(Q_NULLPTR); m_sideBar.data()->close(); } } void SideBarManager::closeSideBar() { if (mApp->isClosing()) { return; } m_activeBar = "None"; Settings settings; settings.setValue("Browser-View-Settings/SideBar", m_activeBar); m_window->saveSideBarWidth(); } diff --git a/src/lib/sidebar/sidebar.h b/src/lib/sidebar/sidebar.h index f34b3b8a..519b00be 100644 --- a/src/lib/sidebar/sidebar.h +++ b/src/lib/sidebar/sidebar.h @@ -1,84 +1,84 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef SIDEBAR_H #define SIDEBAR_H #include #include #include #include "qzcommon.h" class QVBoxLayout; class QMenu; class DockTitleBarWidget; class SideBarInterface; class SideBarManager; class BrowserWindow; -class QUPZILLA_EXPORT SideBar : public QWidget +class FALKON_EXPORT SideBar : public QWidget { Q_OBJECT public: explicit SideBar(SideBarManager* manager, BrowserWindow* window); void showBookmarks(); void showHistory(); void setTitle(const QString &title); void setWidget(QWidget* widget); public slots: void close(); private: BrowserWindow* m_window; QVBoxLayout* m_layout; DockTitleBarWidget* m_titleBar; SideBarManager* m_manager; }; -class QUPZILLA_EXPORT SideBarManager : public QObject +class FALKON_EXPORT SideBarManager : public QObject { Q_OBJECT public: explicit SideBarManager(BrowserWindow* parent); void createMenu(QMenu* menu); void showSideBar(const QString &id, bool toggle = true); void sideBarRemoved(const QString &id); void closeSideBar(); static QHash > s_sidebars; static void addSidebar(const QString &id, SideBarInterface* interface); static void removeSidebar(const QString &id); private slots: void slotShowSideBar(); private: BrowserWindow* m_window; QPointer m_sideBar; QMenu* m_menu; QString m_activeBar; }; #endif // SIDEBAR_H diff --git a/src/lib/sidebar/sidebarinterface.h b/src/lib/sidebar/sidebarinterface.h index 677963bc..bf63c111 100644 --- a/src/lib/sidebar/sidebarinterface.h +++ b/src/lib/sidebar/sidebarinterface.h @@ -1,40 +1,40 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef SIDEBARINTERFACE_H #define SIDEBARINTERFACE_H #include #include "qzcommon.h" class QAction; class BrowserWindow; -class QUPZILLA_EXPORT SideBarInterface : public QObject +class FALKON_EXPORT SideBarInterface : public QObject { public: explicit SideBarInterface(QObject* parent = 0) : QObject(parent) { } virtual QString title() const = 0; virtual QAction* createMenuAction() = 0; virtual QWidget* createSideBarWidget(BrowserWindow* mainWindow) = 0; }; #endif // SIDEBARINTERFACE_H diff --git a/src/lib/tabwidget/combotabbar.cpp b/src/lib/tabwidget/combotabbar.cpp index 1817f0fd..346b6a84 100644 --- a/src/lib/tabwidget/combotabbar.cpp +++ b/src/lib/tabwidget/combotabbar.cpp @@ -1,1665 +1,1665 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2013-2014 S. Razi Alavizadeh * Copyright (C) 2014-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "combotabbar.h" #include "toolbutton.h" #include "tabicon.h" #include "mainapplication.h" #include "proxystyle.h" #include "qzsettings.h" #include #include #include #include #include #include #include #include #include #include #include #include ComboTabBar::ComboTabBar(QWidget* parent) : QWidget(parent) , m_mainTabBar(0) , m_pinnedTabBar(0) , m_mainBarOverFlowed(false) , m_lastAppliedOverflow(false) , m_usesScrollButtons(false) , m_blockCurrentChangedSignal(false) { QObject::setObjectName(QSL("tabbarwidget")); m_mainTabBar = new TabBarHelper(/*isPinnedTabBar*/ false, this); m_pinnedTabBar = new TabBarHelper(/*isPinnedTabBar*/ true, this); m_mainTabBarWidget = new TabBarScrollWidget(m_mainTabBar, this); m_pinnedTabBarWidget = new TabBarScrollWidget(m_pinnedTabBar, this); m_mainTabBar->setScrollArea(m_mainTabBarWidget->scrollArea()); m_pinnedTabBar->setScrollArea(m_pinnedTabBarWidget->scrollArea()); connect(m_mainTabBarWidget->scrollBar(), SIGNAL(rangeChanged(int,int)), this, SLOT(setMinimumWidths())); connect(m_mainTabBarWidget->scrollBar(), SIGNAL(valueChanged(int)), this, SIGNAL(scrollBarValueChanged(int))); connect(m_pinnedTabBarWidget->scrollBar(), SIGNAL(rangeChanged(int,int)), this, SLOT(setMinimumWidths())); connect(m_pinnedTabBarWidget->scrollBar(), SIGNAL(valueChanged(int)), this, SIGNAL(scrollBarValueChanged(int))); connect(this, SIGNAL(overFlowChanged(bool)), m_mainTabBarWidget, SLOT(overFlowChanged(bool))); m_mainTabBar->setActiveTabBar(true); m_pinnedTabBar->setTabsClosable(false); m_leftLayout = new QHBoxLayout; m_leftLayout->setSpacing(0); m_leftLayout->setContentsMargins(0, 0, 0, 0); m_leftContainer = new QWidget(this); m_leftContainer->setLayout(m_leftLayout); m_rightLayout = new QHBoxLayout; m_rightLayout->setSpacing(0); m_rightLayout->setContentsMargins(0, 0, 0, 0); m_rightContainer = new QWidget(this); m_rightContainer->setLayout(m_rightLayout); m_mainLayout = new QHBoxLayout; m_mainLayout->setSpacing(0); m_mainLayout->setContentsMargins(0, 0, 0, 0); m_mainLayout->addWidget(m_leftContainer); m_mainLayout->addWidget(m_pinnedTabBarWidget); m_mainLayout->addWidget(m_mainTabBarWidget); m_mainLayout->addWidget(m_rightContainer); setLayout(m_mainLayout); connect(m_mainTabBar, SIGNAL(currentChanged(int)), this, SLOT(slotCurrentChanged(int))); connect(m_mainTabBar, SIGNAL(tabCloseRequested(int)), this, SLOT(slotTabCloseRequested(int))); connect(m_mainTabBar, SIGNAL(tabMoved(int,int)), this, SLOT(slotTabMoved(int,int))); connect(m_pinnedTabBar, SIGNAL(currentChanged(int)), this, SLOT(slotCurrentChanged(int))); connect(m_pinnedTabBar, SIGNAL(tabCloseRequested(int)), this, SLOT(slotTabCloseRequested(int))); connect(m_pinnedTabBar, SIGNAL(tabMoved(int,int)), this, SLOT(slotTabMoved(int,int))); setAutoFillBackground(false); m_mainTabBar->setAutoFillBackground(false); m_pinnedTabBar->setAutoFillBackground(false); m_mainTabBar->installEventFilter(this); m_pinnedTabBar->installEventFilter(this); m_leftContainer->installEventFilter(this); m_rightContainer->installEventFilter(this); m_mainTabBarWidget->installEventFilter(this); m_pinnedTabBarWidget->installEventFilter(this); } int ComboTabBar::addTab(const QString &text) { return insertTab(-1, text); } int ComboTabBar::addTab(const QIcon &icon, const QString &text) { return insertTab(-1, icon, text); } int ComboTabBar::insertTab(int index, const QString &text) { return insertTab(index, QIcon(), text); } int ComboTabBar::insertTab(int index, const QIcon &icon, const QString &text, bool pinned) { if (pinned) { index = m_pinnedTabBar->insertTab(index, icon, text); } else { index = m_mainTabBar->insertTab(index - pinnedTabsCount(), icon, text); if (tabsClosable()) { QWidget* closeButton = m_mainTabBar->tabButton(index, closeButtonPosition()); if ((closeButton && closeButton->objectName() != QLatin1String("combotabbar_tabs_close_button")) || !closeButton) { // insert our close button insertCloseButton(index + pinnedTabsCount()); if (closeButton) { closeButton->deleteLater(); } } } index += pinnedTabsCount(); } updatePinnedTabBarVisibility(); tabInserted(index); setMinimumWidths(); return index; } void ComboTabBar::removeTab(int index) { if (validIndex(index)) { setUpdatesEnabled(false); localTabBar(index)->removeTab(toLocalIndex(index)); updatePinnedTabBarVisibility(); tabRemoved(index); setMinimumWidths(); setUpdatesEnabled(true); updateTabBars(); } } void ComboTabBar::moveTab(int from, int to) { if (from >= pinnedTabsCount() && to >= pinnedTabsCount()) { m_mainTabBar->moveTab(from - pinnedTabsCount(), to - pinnedTabsCount()); } else if (from < pinnedTabsCount() && to < pinnedTabsCount()) { m_pinnedTabBar->moveTab(from, to); } } bool ComboTabBar::isTabEnabled(int index) const { return localTabBar(index)->isTabEnabled(toLocalIndex(index)); } void ComboTabBar::setTabEnabled(int index, bool enabled) { localTabBar(index)->setTabEnabled(toLocalIndex(index), enabled); } QColor ComboTabBar::tabTextColor(int index) const { return localTabBar(index)->tabTextColor(toLocalIndex(index)); } void ComboTabBar::setTabTextColor(int index, const QColor &color) { localTabBar(index)->setTabTextColor(toLocalIndex(index), color); } QRect ComboTabBar::tabRect(int index) const { QRect rect; if (index != -1) { bool mainTabBar = index >= pinnedTabsCount(); rect = localTabBar(index)->tabRect(toLocalIndex(index)); if (mainTabBar) { rect.moveLeft(rect.x() + mapFromGlobal(m_mainTabBar->mapToGlobal(QPoint(0, 0))).x()); QRect widgetRect = m_mainTabBarWidget->scrollArea()->viewport()->rect(); widgetRect.moveLeft(widgetRect.x() + mapFromGlobal(m_mainTabBarWidget->scrollArea()->viewport()->mapToGlobal(QPoint(0, 0))).x()); rect = rect.intersected(widgetRect); } else { rect.moveLeft(rect.x() + mapFromGlobal(m_pinnedTabBar->mapToGlobal(QPoint(0, 0))).x()); QRect widgetRect = m_pinnedTabBarWidget->scrollArea()->viewport()->rect(); widgetRect.moveLeft(widgetRect.x() + mapFromGlobal(m_pinnedTabBarWidget->scrollArea()->viewport()->mapToGlobal(QPoint(0, 0))).x()); rect = rect.intersected(widgetRect); } } return rect; } int ComboTabBar::tabAt(const QPoint &pos) const { QWidget* w = QApplication::widgetAt(mapToGlobal(pos)); if (!qobject_cast(w) && !qobject_cast(w)) return -1; int index = m_pinnedTabBarWidget->tabAt(m_pinnedTabBarWidget->mapFromParent(pos)); if (index != -1) return index; index = m_mainTabBarWidget->tabAt(m_mainTabBarWidget->mapFromParent(pos)); if (index != -1) index += pinnedTabsCount(); return index; } bool ComboTabBar::emptyArea(const QPoint &pos) const { if (tabAt(pos) != -1) return false; return qobject_cast(QApplication::widgetAt(mapToGlobal(pos))); } int ComboTabBar::mainTabBarCurrentIndex() const { return (m_mainTabBar->currentIndex() == -1 ? -1 : pinnedTabsCount() + m_mainTabBar->currentIndex()); } int ComboTabBar::currentIndex() const { if (m_pinnedTabBar->isActiveTabBar()) { return m_pinnedTabBar->currentIndex(); } else { return (m_mainTabBar->currentIndex() == -1 ? -1 : pinnedTabsCount() + m_mainTabBar->currentIndex()); } } void ComboTabBar::setCurrentIndex(int index) { return localTabBar(index)->setCurrentIndex(toLocalIndex(index)); } void ComboTabBar::slotCurrentChanged(int index) { if (m_blockCurrentChangedSignal) { return; } if (sender() == m_pinnedTabBar) { if (index == -1 && m_mainTabBar->count() > 0) { m_mainTabBar->setActiveTabBar(true); m_pinnedTabBar->setActiveTabBar(false); emit currentChanged(pinnedTabsCount()); } else { m_pinnedTabBar->setActiveTabBar(true); m_mainTabBar->setActiveTabBar(false); emit currentChanged(index); } } else { if (index == -1 && pinnedTabsCount() > 0) { m_pinnedTabBar->setActiveTabBar(true); m_mainTabBar->setActiveTabBar(false); emit currentChanged(pinnedTabsCount() - 1); } else { m_mainTabBar->setActiveTabBar(true); m_pinnedTabBar->setActiveTabBar(false); emit currentChanged(index + pinnedTabsCount()); } } } void ComboTabBar::slotTabCloseRequested(int index) { if (sender() == m_pinnedTabBar) { emit tabCloseRequested(index); } else { emit tabCloseRequested(index + pinnedTabsCount()); } } void ComboTabBar::slotTabMoved(int from, int to) { if (sender() == m_pinnedTabBar) { emit tabMoved(from, to); } else { emit tabMoved(from + pinnedTabsCount(), to + pinnedTabsCount()); } } void ComboTabBar::closeTabFromButton() { QWidget* button = qobject_cast(sender()); int tabToClose = -1; for (int i = 0; i < m_mainTabBar->count(); ++i) { if (m_mainTabBar->tabButton(i, closeButtonPosition()) == button) { tabToClose = i; break; } } if (tabToClose != -1) { emit tabCloseRequested(tabToClose + pinnedTabsCount()); } } void ComboTabBar::updateTabBars() { m_mainTabBar->update(); m_pinnedTabBar->update(); } void ComboTabBar::emitOverFlowChanged() { if (m_mainBarOverFlowed != m_lastAppliedOverflow) { emit overFlowChanged(m_mainBarOverFlowed); m_lastAppliedOverflow = m_mainBarOverFlowed; } } int ComboTabBar::count() const { return pinnedTabsCount() + m_mainTabBar->count(); } void ComboTabBar::setDrawBase(bool drawTheBase) { m_mainTabBar->setDrawBase(drawTheBase); m_pinnedTabBar->setDrawBase(drawTheBase); } bool ComboTabBar::drawBase() const { return m_mainTabBar->drawBase(); } Qt::TextElideMode ComboTabBar::elideMode() const { return m_mainTabBar->elideMode(); } void ComboTabBar::setElideMode(Qt::TextElideMode elide) { m_mainTabBar->setElideMode(elide); m_pinnedTabBar->setElideMode(elide); } QString ComboTabBar::tabText(int index) const { return localTabBar(index)->tabText(toLocalIndex(index)); } void ComboTabBar::setTabText(int index, const QString &text) { localTabBar(index)->setTabText(toLocalIndex(index), text); } void ComboTabBar::setTabToolTip(int index, const QString &tip) { localTabBar(index)->setTabToolTip(toLocalIndex(index), tip); } QString ComboTabBar::tabToolTip(int index) const { return localTabBar(index)->tabToolTip(toLocalIndex(index)); } bool ComboTabBar::tabsClosable() const { return m_mainTabBar->tabsClosable(); } void ComboTabBar::setTabsClosable(bool closable) { if (closable == tabsClosable()) { return; } if (closable) { // insert our close button for (int i = 0; i < m_mainTabBar->count(); ++i) { QWidget* closeButton = m_mainTabBar->tabButton(i, closeButtonPosition()); if (closeButton) { if (closeButton->objectName() == QLatin1String("combotabbar_tabs_close_button")) { continue; } } insertCloseButton(i + pinnedTabsCount()); if (closeButton) { closeButton->deleteLater(); } } } m_mainTabBar->setTabsClosable(closable); } void ComboTabBar::setTabButton(int index, QTabBar::ButtonPosition position, QWidget* widget) { if (widget) widget->setMinimumSize(closeButtonSize()); localTabBar(index)->setTabButton(toLocalIndex(index), position, widget); } QWidget* ComboTabBar::tabButton(int index, QTabBar::ButtonPosition position) const { return localTabBar(index)->tabButton(toLocalIndex(index), position); } QTabBar::SelectionBehavior ComboTabBar::selectionBehaviorOnRemove() const { return m_mainTabBar->selectionBehaviorOnRemove(); } void ComboTabBar::setSelectionBehaviorOnRemove(QTabBar::SelectionBehavior behavior) { m_mainTabBar->setSelectionBehaviorOnRemove(behavior); m_pinnedTabBar->setSelectionBehaviorOnRemove(behavior); } bool ComboTabBar::expanding() const { return m_mainTabBar->expanding(); } void ComboTabBar::setExpanding(bool enabled) { m_mainTabBar->setExpanding(enabled); m_pinnedTabBar->setExpanding(enabled); } bool ComboTabBar::isMovable() const { return m_mainTabBar->isMovable(); } void ComboTabBar::setMovable(bool movable) { m_mainTabBar->setMovable(movable); m_pinnedTabBar->setMovable(movable); } bool ComboTabBar::documentMode() const { return m_mainTabBar->documentMode(); } void ComboTabBar::setDocumentMode(bool set) { m_mainTabBar->setDocumentMode(set); m_pinnedTabBar->setDocumentMode(set); } int ComboTabBar::pinnedTabsCount() const { return m_pinnedTabBar->count(); } int ComboTabBar::normalTabsCount() const { return m_mainTabBar->count(); } bool ComboTabBar::isPinned(int index) const { return index >= 0 && index < pinnedTabsCount(); } void ComboTabBar::setFocusPolicy(Qt::FocusPolicy policy) { QWidget::setFocusPolicy(policy); m_mainTabBar->setFocusPolicy(policy); m_pinnedTabBar->setFocusPolicy(policy); } void ComboTabBar::setObjectName(const QString &name) { m_mainTabBar->setObjectName(name); m_pinnedTabBar->setObjectName(name); } void ComboTabBar::setMouseTracking(bool enable) { m_mainTabBarWidget->scrollArea()->setMouseTracking(enable); m_mainTabBarWidget->setMouseTracking(enable); m_mainTabBar->setMouseTracking(enable); m_pinnedTabBarWidget->scrollArea()->setMouseTracking(enable); m_pinnedTabBarWidget->setMouseTracking(enable); m_pinnedTabBar->setMouseTracking(enable); QWidget::setMouseTracking(enable); } void ComboTabBar::setUpLayout() { int height = qMax(m_mainTabBar->height(), m_pinnedTabBar->height()); // Workaround for Oxygen theme. For some reason, QTabBar::height() returns bigger // height than it actually should. if (mApp->styleName() == QLatin1String("oxygen")) { height -= 4; } // We need to setup heights even before m_mainTabBar->height() has correct value // So lets just set minimum 5px height height = qMax(5, height); setFixedHeight(height); m_pinnedTabBar->setFixedHeight(height); m_leftContainer->setFixedHeight(height); m_rightContainer->setFixedHeight(height); m_mainTabBarWidget->setUpLayout(); m_pinnedTabBarWidget->setUpLayout(); setMinimumWidths(); if (isVisible() && m_mainTabBar->count() > 0) { // ComboTabBar is now visible, we can sync heights of both tabbars m_pinnedTabBar->setFixedHeight(m_mainTabBar->sizeHint().height()); m_mainTabBar->setFixedHeight(m_mainTabBar->sizeHint().height()); } } void ComboTabBar::insertCloseButton(int index) { index -= pinnedTabsCount(); if (index < 0) { return; } QAbstractButton* closeButton = new CloseButton(this); closeButton->setFixedSize(closeButtonSize()); closeButton->setToolTip(m_closeButtonsToolTip); connect(closeButton, SIGNAL(clicked()), this, SLOT(closeTabFromButton())); m_mainTabBar->setTabButton(index, closeButtonPosition(), closeButton); } void ComboTabBar::setCloseButtonsToolTip(const QString &tip) { m_closeButtonsToolTip = tip; } int ComboTabBar::mainTabBarWidth() const { return m_mainTabBar->width(); } int ComboTabBar::pinTabBarWidth() const { return m_pinnedTabBarWidget->isHidden() ? 0 : m_pinnedTabBarWidget->width(); } bool ComboTabBar::event(QEvent *event) { const bool res = QWidget::event(event); switch (event->type()) { case QEvent::ToolTip: if (!isDragInProgress() && !isScrollInProgress()) { int index = tabAt(mapFromGlobal(QCursor::pos())); if (index >= 0) QToolTip::showText(QCursor::pos(), tabToolTip(index)); } break; case QEvent::Resize: ensureVisible(); break; case QEvent::Show: if (!event->spontaneous()) QTimer::singleShot(0, this, &ComboTabBar::setUpLayout); break; case QEvent::Enter: case QEvent::Leave: // Make sure tabs are painted with correct mouseover state QTimer::singleShot(100, this, &ComboTabBar::updateTabBars); break; default: break; } return res; } void ComboTabBar::wheelEvent(QWheelEvent* event) { event->accept(); if (qzSettings->alwaysSwitchTabsWithWheel || (!m_mainTabBarWidget->isOverflowed() && !m_pinnedTabBarWidget->isOverflowed())) { m_wheelHelper.processEvent(event); while (WheelHelper::Direction direction = m_wheelHelper.takeDirection()) { switch (direction) { case WheelHelper::WheelUp: case WheelHelper::WheelLeft: setCurrentNextEnabledIndex(-1); break; case WheelHelper::WheelDown: case WheelHelper::WheelRight: setCurrentNextEnabledIndex(1); break; default: break; } } return; } if (m_mainTabBarWidget->underMouse()) { if (m_mainTabBarWidget->isOverflowed()) { m_mainTabBarWidget->scrollByWheel(event); } else if (m_pinnedTabBarWidget->isOverflowed()) { m_pinnedTabBarWidget->scrollByWheel(event); } } else if (m_pinnedTabBarWidget->underMouse()) { if (m_pinnedTabBarWidget->isOverflowed()) { m_pinnedTabBarWidget->scrollByWheel(event); } else if (m_mainTabBarWidget->isOverflowed()) { m_mainTabBarWidget->scrollByWheel(event); } } } bool ComboTabBar::eventFilter(QObject* obj, QEvent* ev) { if (obj == m_mainTabBar && ev->type() == QEvent::Resize) { QResizeEvent* event = static_cast(ev); if (event->oldSize().height() != event->size().height()) { setUpLayout(); } } // Handle wheel events exclusively in ComboTabBar if (ev->type() == QEvent::Wheel) { wheelEvent(static_cast(ev)); return true; } return QWidget::eventFilter(obj, ev); } void ComboTabBar::paintEvent(QPaintEvent* ev) { Q_UNUSED(ev); // This is needed to apply style sheets QStyleOption option; option.init(this); QPainter p(this); style()->drawPrimitive(QStyle::PE_Widget, &option, &p, this); #ifndef Q_OS_MACOS // Draw tabbar base even on parts of ComboTabBar that are not directly QTabBar QStyleOptionTabBarBase opt; TabBarHelper::initStyleBaseOption(&opt, m_mainTabBar, size()); // Left container opt.rect.setX(m_leftContainer->x()); opt.rect.setWidth(m_leftContainer->width()); style()->drawPrimitive(QStyle::PE_FrameTabBarBase, &opt, &p); // Right container opt.rect.setX(m_rightContainer->x()); opt.rect.setWidth(m_rightContainer->width()); style()->drawPrimitive(QStyle::PE_FrameTabBarBase, &opt, &p); if (m_mainBarOverFlowed) { const int scrollButtonWidth = m_mainTabBarWidget->scrollButtonsWidth(); // Left scroll button opt.rect.setX(m_mainTabBarWidget->x()); opt.rect.setWidth(scrollButtonWidth); style()->drawPrimitive(QStyle::PE_FrameTabBarBase, &opt, &p); // Right scroll button opt.rect.setX(m_mainTabBarWidget->x() + m_mainTabBarWidget->width() - scrollButtonWidth); opt.rect.setWidth(scrollButtonWidth); style()->drawPrimitive(QStyle::PE_FrameTabBarBase, &opt, &p); } // Draw base even when main tabbar is empty if (normalTabsCount() == 0) { opt.rect.setX(m_mainTabBarWidget->x()); opt.rect.setWidth(m_mainTabBarWidget->width()); style()->drawPrimitive(QStyle::PE_FrameTabBarBase, &opt, &p); } #endif } int ComboTabBar::comboTabBarPixelMetric(ComboTabBar::SizeType sizeType) const { switch (sizeType) { case ExtraReservedWidth: return 0; case NormalTabMaximumWidth: return 150; case ActiveTabMinimumWidth: case NormalTabMinimumWidth: case OverflowedTabWidth: return 100; case PinnedTabWidth: return 30; default: break; } return -1; } QTabBar::ButtonPosition ComboTabBar::iconButtonPosition() const { return (closeButtonPosition() == QTabBar::RightSide ? QTabBar::LeftSide : QTabBar::RightSide); } QTabBar::ButtonPosition ComboTabBar::closeButtonPosition() const { return (QTabBar::ButtonPosition)style()->styleHint(QStyle::SH_TabBar_CloseButtonPosition, 0, this); } QSize ComboTabBar::iconButtonSize() const { QSize s = closeButtonSize(); s.setWidth(qMax(16, s.width())); s.setHeight(qMax(16, s.height())); return s; } QSize ComboTabBar::closeButtonSize() const { int width = style()->pixelMetric(QStyle::PM_TabCloseIndicatorWidth, 0, this); int height = style()->pixelMetric(QStyle::PM_TabCloseIndicatorHeight, 0, this); return QSize(width, height); } bool ComboTabBar::validIndex(int index) const { return (index >= 0 && index < count()); } void ComboTabBar::setCurrentNextEnabledIndex(int offset) { for (int index = currentIndex() + offset; validIndex(index); index += offset) { if (isTabEnabled(index)) { setCurrentIndex(index); break; } } } bool ComboTabBar::usesScrollButtons() const { return m_mainTabBarWidget->usesScrollButtons(); } void ComboTabBar::setUsesScrollButtons(bool useButtons) { m_mainTabBarWidget->setUsesScrollButtons(useButtons); } bool ComboTabBar::isDragInProgress() const { return m_mainTabBar->isDragInProgress() || m_pinnedTabBar->isDragInProgress(); } bool ComboTabBar::isScrollInProgress() const { return m_mainTabBarWidget->scrollBar()->isScrolling() || m_pinnedTabBarWidget->scrollBar()->isScrolling(); } bool ComboTabBar::isMainBarOverflowed() const { return m_mainBarOverFlowed; } int ComboTabBar::cornerWidth(Qt::Corner corner) const { if (corner == Qt::TopLeftCorner) { return m_leftContainer->width(); } else if (corner == Qt::TopRightCorner) { return m_rightContainer->width(); } qFatal("ComboTabBar::cornerWidth Only TopLeft and TopRight corners are implemented!"); return -1; } void ComboTabBar::addCornerWidget(QWidget* widget, Qt::Corner corner) { if (corner == Qt::TopLeftCorner) { m_leftLayout->addWidget(widget); } else if (corner == Qt::TopRightCorner) { m_rightLayout->addWidget(widget); } else { qFatal("ComboTabBar::addCornerWidget Only TopLeft and TopRight corners are implemented!"); } } // static int ComboTabBar::slideAnimationDuration() { // taken from qtabbar_p.h return 250; } void ComboTabBar::ensureVisible(int index, int xmargin) { if (index == -1) { index = currentIndex(); } if (index < pinnedTabsCount()) { if (xmargin == -1) { xmargin = qMax(20, comboTabBarPixelMetric(PinnedTabWidth)); } m_pinnedTabBarWidget->ensureVisible(index, xmargin); } else { if (xmargin == -1) { xmargin = comboTabBarPixelMetric(OverflowedTabWidth); } index -= pinnedTabsCount(); m_mainTabBarWidget->ensureVisible(index, xmargin); } } QSize ComboTabBar::tabSizeHint(int index, bool fast) const { Q_UNUSED(fast) return localTabBar(index)->baseClassTabSizeHint(toLocalIndex(index)); } void ComboTabBar::tabInserted(int index) { Q_UNUSED(index) } void ComboTabBar::tabRemoved(int index) { Q_UNUSED(index) } TabBarHelper* ComboTabBar::mainTabBar() const { return m_mainTabBar; } TabBarHelper* ComboTabBar::localTabBar(int index) const { if (index < 0 || index >= pinnedTabsCount()) { return m_mainTabBar; } else { return m_pinnedTabBar; } } int ComboTabBar::toLocalIndex(int globalIndex) const { if (globalIndex < 0) { return -1; } if (globalIndex >= pinnedTabsCount()) { return globalIndex - pinnedTabsCount(); } else { return globalIndex; } } void ComboTabBar::updatePinnedTabBarVisibility() { m_pinnedTabBarWidget->setVisible(pinnedTabsCount() > 0); } void ComboTabBar::setMinimumWidths() { if (!isVisible() || comboTabBarPixelMetric(PinnedTabWidth) < 0) { return; } const int tabBarsSpacing = 3; // To distinguish tabbars int pinnedTabBarWidth = pinnedTabsCount() * comboTabBarPixelMetric(PinnedTabWidth); m_pinnedTabBar->setMinimumWidth(pinnedTabBarWidth); m_pinnedTabBarWidget->setFixedWidth(pinnedTabBarWidth + tabBarsSpacing); // Width that is needed by main tabbar int mainTabBarWidth = comboTabBarPixelMetric(NormalTabMinimumWidth) * (m_mainTabBar->count() - 1) + comboTabBarPixelMetric(ActiveTabMinimumWidth) + comboTabBarPixelMetric(ExtraReservedWidth); // This is the full width that would be needed for the tabbar (including pinned tabbar and corner widgets) int realTabBarWidth = mainTabBarWidth + m_pinnedTabBarWidget->width() + cornerWidth(Qt::TopLeftCorner) + cornerWidth(Qt::TopRightCorner); // Does it fit in our widget? if (realTabBarWidth <= width()) { if (m_mainBarOverFlowed) { m_mainBarOverFlowed = false; QTimer::singleShot(0, this, SLOT(emitOverFlowChanged())); } m_mainTabBar->useFastTabSizeHint(false); m_mainTabBar->setMinimumWidth(mainTabBarWidth); } else { if (!m_mainBarOverFlowed) { m_mainBarOverFlowed = true; QTimer::singleShot(0, this, SLOT(emitOverFlowChanged())); } // All tabs have now same width, we can use fast tabSizeHint m_mainTabBar->useFastTabSizeHint(true); m_mainTabBar->setMinimumWidth(m_mainTabBar->count() * comboTabBarPixelMetric(OverflowedTabWidth)); } } TabBarHelper::TabBarHelper(bool isPinnedTabBar, ComboTabBar* comboTabBar) : QTabBar(comboTabBar) , m_comboTabBar(comboTabBar) , m_scrollArea(0) , m_pressedIndex(-1) , m_pressedGlobalX(-1) , m_dragInProgress(false) , m_activeTabBar(false) , m_isPinnedTabBar(isPinnedTabBar) , m_useFastTabSizeHint(false) { connect(this, SIGNAL(tabMoved(int,int)), this, SLOT(tabWasMoved(int,int))); } void TabBarHelper::setTabButton(int index, QTabBar::ButtonPosition position, QWidget* widget) { QTabBar::setTabButton(index, position, widget); } QSize TabBarHelper::tabSizeHint(int index) const { if (this == m_comboTabBar->mainTabBar()) { index += m_comboTabBar->pinnedTabsCount(); } return m_comboTabBar->tabSizeHint(index, m_useFastTabSizeHint); } QSize TabBarHelper::baseClassTabSizeHint(int index) const { return QTabBar::tabSizeHint(index); } bool TabBarHelper::isActiveTabBar() { return m_activeTabBar; } void TabBarHelper::setActiveTabBar(bool activate) { if (m_activeTabBar != activate) { m_activeTabBar = activate; // If the last tab in a tabbar is closed, the selection jumps to the other // tabbar. The stacked widget automatically selects the next tab, which is // either the last tab in pinned tabbar or the first one in main tabbar. if (!m_activeTabBar) { m_comboTabBar->m_blockCurrentChangedSignal = true; setCurrentIndex(m_isPinnedTabBar ? count() - 1 : 0); m_comboTabBar->m_blockCurrentChangedSignal = false; } update(); } } void TabBarHelper::removeTab(int index) { // Removing tab in inactive tabbar will change current index and thus // changing active tabbar, which is really not wanted. if (!m_activeTabBar) m_comboTabBar->m_blockCurrentChangedSignal = true; QTabBar::removeTab(index); m_comboTabBar->m_blockCurrentChangedSignal = false; } void TabBarHelper::setScrollArea(QScrollArea* scrollArea) { m_scrollArea = scrollArea; } void TabBarHelper::useFastTabSizeHint(bool enabled) { m_useFastTabSizeHint = enabled; } bool TabBarHelper::isDisplayedOnViewPort(int globalLeft, int globalRight) { bool isVisible = true; if (m_scrollArea) { if (globalRight < m_scrollArea->viewport()->mapToGlobal(QPoint(0, 0)).x() || globalLeft > m_scrollArea->viewport()->mapToGlobal(m_scrollArea->viewport()->rect().topRight()).x() ) { isVisible = false; } } return isVisible; } bool TabBarHelper::isDragInProgress() const { return m_dragInProgress; } void TabBarHelper::setCurrentIndex(int index) { if (index == currentIndex() && !m_activeTabBar) { emit currentChanged(currentIndex()); } QTabBar::setCurrentIndex(index); } bool TabBarHelper::event(QEvent* ev) { switch (ev->type()) { case QEvent::ToolTip: ev->ignore(); return false; default: break; } QTabBar::event(ev); ev->ignore(); return false; } // Taken from qtabbar.cpp void TabBarHelper::initStyleBaseOption(QStyleOptionTabBarBase *optTabBase, QTabBar* tabbar, QSize size) { QStyleOptionTab tabOverlap; tabOverlap.shape = tabbar->shape(); int overlap = tabbar->style()->pixelMetric(QStyle::PM_TabBarBaseOverlap, &tabOverlap, tabbar); QWidget* theParent = tabbar->parentWidget(); optTabBase->init(tabbar); optTabBase->shape = tabbar->shape(); optTabBase->documentMode = tabbar->documentMode(); if (theParent && overlap > 0) { QRect rect; switch (tabOverlap.shape) { case QTabBar::RoundedNorth: case QTabBar::TriangularNorth: rect.setRect(0, size.height() - overlap, size.width(), overlap); break; case QTabBar::RoundedSouth: case QTabBar::TriangularSouth: rect.setRect(0, 0, size.width(), overlap); break; case QTabBar::RoundedEast: case QTabBar::TriangularEast: rect.setRect(0, 0, overlap, size.height()); break; case QTabBar::RoundedWest: case QTabBar::TriangularWest: rect.setRect(size.width() - overlap, 0, overlap, size.height()); break; } optTabBase->rect = rect; } } // Adapted from qtabbar.cpp void TabBarHelper::paintEvent(QPaintEvent* event) { // Note: this code doesn't support vertical tabs if (m_dragInProgress) { QTabBar::paintEvent(event); return; } QStyleOptionTabBarBase optTabBase; initStyleBaseOption(&optTabBase, this, size()); QStylePainter p(this); int selected = currentIndex(); for (int i = 0; i < count(); ++i) { optTabBase.tabBarRect |= tabRect(i); } if (m_activeTabBar) { optTabBase.selectedTabRect = tabRect(selected); } if (drawBase()) { p.drawPrimitive(QStyle::PE_FrameTabBarBase, optTabBase); } const QPoint cursorPos = QCursor::pos(); int indexUnderMouse = isDisplayedOnViewPort(cursorPos.x(), cursorPos.x()) ? tabAt(mapFromGlobal(cursorPos)) : -1; for (int i = 0; i < count(); ++i) { QStyleOptionTab tab; initStyleOption(&tab, i); if (i == selected) { continue; } // Don't bother drawing a tab if the entire tab is outside of the visible tab bar. if (!isDisplayedOnViewPort(mapToGlobal(tab.rect.topLeft()).x(), mapToGlobal(tab.rect.topRight()).x())) { continue; } if (!m_activeTabBar) { tab.selectedPosition = QStyleOptionTab::NotAdjacent; } if (!(tab.state & QStyle::State_Enabled)) { tab.palette.setCurrentColorGroup(QPalette::Disabled); } // Update mouseover state when scrolling if (i == indexUnderMouse) { tab.state |= QStyle::State_MouseOver; } else { tab.state &= ~QStyle::State_MouseOver; } p.drawControl(QStyle::CE_TabBarTab, tab); } // Draw the selected tab last to get it "on top" if (selected >= 0) { QStyleOptionTab tab; initStyleOption(&tab, selected); // Update mouseover state when scrolling if (selected == indexUnderMouse) { tab.state |= QStyle::State_MouseOver; } else { tab.state &= ~QStyle::State_MouseOver; } if (!m_activeTabBar) { // If this is inactive tab, we still need to draw selected tab outside the tabbar // Some themes (eg. Oxygen) draws line under tabs with selected tab // Let's just move it outside rect(), it appears to work QStyleOptionTab tb = tab; tb.rect.moveRight((rect().x() + rect().width()) * 2); p.drawControl(QStyle::CE_TabBarTab, tb); // Draw the tab without selected state tab.state = tab.state & ~QStyle::State_Selected; } p.drawControl(QStyle::CE_TabBarTab, tab); } } void TabBarHelper::mousePressEvent(QMouseEvent* event) { event->ignore(); if (event->buttons() == Qt::LeftButton) { m_pressedIndex = tabAt(event->pos()); if (m_pressedIndex != -1) { m_pressedGlobalX = event->globalX(); m_dragInProgress = true; // virtualize selecting tab by click if (m_pressedIndex == currentIndex() && !m_activeTabBar) { emit currentChanged(currentIndex()); } } } QTabBar::mousePressEvent(event); } void TabBarHelper::mouseReleaseEvent(QMouseEvent* event) { event->ignore(); if (event->button() != Qt::LeftButton) { return; } QTabBar::mouseReleaseEvent(event); if (m_pressedIndex >= 0 && m_pressedIndex < count()) { QTimer::singleShot(ComboTabBar::slideAnimationDuration(), this, &TabBarHelper::resetDragState); m_pressedIndex = -1; m_pressedGlobalX = -1; } } void TabBarHelper::initStyleOption(QStyleOptionTab* option, int tabIndex) const { QTabBar::initStyleOption(option, tabIndex); // Bespin doesn't highlight current tab when there is only one tab in tabbar static int isBespin = -1; if (isBespin == -1) isBespin = mApp->styleName() == QL1S("bespin"); if (!isBespin) return; int index = m_isPinnedTabBar ? tabIndex : m_comboTabBar->pinnedTabsCount() + tabIndex; if (m_comboTabBar->count() > 1) { if (index == 0) option->position = QStyleOptionTab::Beginning; else if (index == m_comboTabBar->count() - 1) option->position = QStyleOptionTab::End; else option->position = QStyleOptionTab::Middle; } else { option->position = QStyleOptionTab::OnlyOneTab; } } void TabBarHelper::resetDragState() { if (m_pressedIndex == -1) { m_dragInProgress = false; update(); } } void TabBarHelper::tabWasMoved(int from, int to) { if (m_pressedIndex != -1) { if (m_pressedIndex == from) { m_pressedIndex = to; } else { const int start = qMin(from, to); const int end = qMax(from, to); if (m_pressedIndex >= start && m_pressedIndex <= end) { m_pressedIndex += (from < to) ? -1 : 1; } } } } void TabBarHelper::tabInserted(int index) { if (m_pressedIndex != -1 && index <= m_pressedIndex) { ++m_pressedIndex; } } void TabBarHelper::tabRemoved(int index) { if (m_pressedIndex != -1) { if (index < m_pressedIndex) { --m_pressedIndex; } else if (index == m_pressedIndex) { m_pressedIndex = -1; } } } TabScrollBar::TabScrollBar(QWidget* parent) : QScrollBar(Qt::Horizontal, parent) { m_animation = new QPropertyAnimation(this, "value", this); } TabScrollBar::~TabScrollBar() { } bool TabScrollBar::isScrolling() const { return m_animation->state() == QPropertyAnimation::Running; } void TabScrollBar::animateToValue(int to, QEasingCurve::Type type) { to = qBound(minimum(), to, maximum()); int lenght = qAbs(to - value()); int duration = qMin(1500, 200 + lenght / 2); m_animation->stop(); m_animation->setEasingCurve(type); m_animation->setDuration(duration); m_animation->setStartValue(value()); m_animation->setEndValue(to); m_animation->start(); } TabBarScrollWidget::TabBarScrollWidget(QTabBar* tabBar, QWidget* parent) : QWidget(parent) , m_tabBar(tabBar) , m_usesScrollButtons(false) , m_totalDeltas(0) { m_scrollArea = new QScrollArea(this); m_scrollArea->setFocusPolicy(Qt::NoFocus); m_scrollArea->setFrameStyle(QFrame::NoFrame); m_scrollArea->setWidgetResizable(true); m_scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); m_scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); m_scrollBar = new TabScrollBar(m_scrollArea); m_scrollArea->setHorizontalScrollBar(m_scrollBar); m_scrollArea->setWidget(m_tabBar); m_leftScrollButton = new ToolButton(this); m_leftScrollButton->setFocusPolicy(Qt::NoFocus); m_leftScrollButton->setAutoRaise(true); m_leftScrollButton->setObjectName("tabbar-button-left"); m_leftScrollButton->setAutoRepeat(true); m_leftScrollButton->setAutoRepeatDelay(200); m_leftScrollButton->setAutoRepeatInterval(200); connect(m_leftScrollButton, SIGNAL(pressed()), this, SLOT(scrollStart())); connect(m_leftScrollButton, SIGNAL(doubleClicked()), this, SLOT(scrollToLeftEdge())); connect(m_leftScrollButton, SIGNAL(middleMouseClicked()), this, SLOT(ensureVisible())); m_rightScrollButton = new ToolButton(this); m_rightScrollButton->setFocusPolicy(Qt::NoFocus); m_rightScrollButton->setAutoRaise(true); m_rightScrollButton->setObjectName("tabbar-button-right"); m_rightScrollButton->setAutoRepeat(true); m_rightScrollButton->setAutoRepeatDelay(200); m_rightScrollButton->setAutoRepeatInterval(200); connect(m_rightScrollButton, SIGNAL(pressed()), this, SLOT(scrollStart())); connect(m_rightScrollButton, SIGNAL(doubleClicked()), this, SLOT(scrollToRightEdge())); connect(m_rightScrollButton, SIGNAL(middleMouseClicked()), this, SLOT(ensureVisible())); QHBoxLayout* hLayout = new QHBoxLayout; hLayout->setSpacing(0); hLayout->setContentsMargins(0, 0, 0, 0); hLayout->addWidget(m_leftScrollButton); hLayout->addWidget(m_scrollArea); hLayout->addWidget(m_rightScrollButton); setLayout(hLayout); m_scrollArea->viewport()->setAutoFillBackground(false); connect(m_scrollBar, SIGNAL(valueChanged(int)), this, SLOT(updateScrollButtonsState())); updateScrollButtonsState(); overFlowChanged(false); } QTabBar* TabBarScrollWidget::tabBar() { return m_tabBar; } QScrollArea* TabBarScrollWidget::scrollArea() { return m_scrollArea; } TabScrollBar* TabBarScrollWidget::scrollBar() { return m_scrollBar; } void TabBarScrollWidget::ensureVisible(int index, int xmargin) { if (index == -1) { index = m_tabBar->currentIndex(); } if (index < 0 || index >= m_tabBar->count()) { return; } xmargin = qMin(xmargin, m_scrollArea->viewport()->width() / 2); // Qt Bug? the following lines were taken from QScrollArea::ensureVisible() and // then were fixed. The original version caculates wrong values in RTL layouts. const QRect logicalTabRect = QStyle::visualRect(m_tabBar->layoutDirection(), m_tabBar->rect(), m_tabBar->tabRect(index)); int logicalX = QStyle::visualPos(Qt::LeftToRight, m_scrollArea->viewport()->rect(), logicalTabRect.center()).x(); if (logicalX - xmargin < m_scrollBar->value()) { m_scrollBar->animateToValue(qMax(0, logicalX - xmargin)); } else if (logicalX > m_scrollBar->value() + m_scrollArea->viewport()->width() - xmargin) { m_scrollBar->animateToValue(qMin(logicalX - m_scrollArea->viewport()->width() + xmargin, m_scrollBar->maximum())); } } void TabBarScrollWidget::scrollToLeft(int n, QEasingCurve::Type type) { n = qMax(1, n); m_scrollBar->animateToValue(m_scrollBar->value() - n * m_scrollBar->singleStep(), type); } void TabBarScrollWidget::scrollToRight(int n, QEasingCurve::Type type) { n = qMax(1, n); m_scrollBar->animateToValue(m_scrollBar->value() + n * m_scrollBar->singleStep(), type); } void TabBarScrollWidget::scrollToLeftEdge() { m_scrollBar->animateToValue(m_scrollBar->minimum()); } void TabBarScrollWidget::scrollToRightEdge() { m_scrollBar->animateToValue(m_scrollBar->maximum()); } void TabBarScrollWidget::setUpLayout() { const int height = m_tabBar->height(); setFixedHeight(height); } void TabBarScrollWidget::updateScrollButtonsState() { m_leftScrollButton->setEnabled(m_scrollBar->value() != m_scrollBar->minimum()); m_rightScrollButton->setEnabled(m_scrollBar->value() != m_scrollBar->maximum()); } void TabBarScrollWidget::overFlowChanged(bool overflowed) { bool showScrollButtons = overflowed && m_usesScrollButtons; m_leftScrollButton->setVisible(showScrollButtons); m_rightScrollButton->setVisible(showScrollButtons); } void TabBarScrollWidget::scrollStart() { bool ctrlModifier = QApplication::keyboardModifiers() & Qt::ControlModifier; if (sender() == m_leftScrollButton) { if (ctrlModifier) { scrollToLeftEdge(); } else { scrollToLeft(5, QEasingCurve::Linear); } } else if (sender() == m_rightScrollButton) { if (ctrlModifier) { scrollToRightEdge(); } else { scrollToRight(5, QEasingCurve::Linear); } } } void TabBarScrollWidget::scrollByWheel(QWheelEvent* event) { event->accept(); // Check if direction has changed from last time if (m_totalDeltas * event->delta() < 0) { m_totalDeltas = 0; } m_totalDeltas += event->delta(); // Slower scrolling for horizontal wheel scrolling if (event->orientation() == Qt::Horizontal) { if (event->delta() > 0) { scrollToLeft(); } else if (event->delta() < 0) { scrollToRight(); } return; } // Faster scrolling with control modifier if (event->orientation() == Qt::Vertical && event->modifiers() == Qt::ControlModifier) { if (event->delta() > 0) { scrollToLeft(10); } else if (event->delta() < 0) { scrollToRight(10); } return; } // Fast scrolling with just wheel scroll int factor = qMax(qRound(m_scrollBar->pageStep() / 1.5), m_scrollBar->singleStep()); if ((event->modifiers() & Qt::ControlModifier) || (event->modifiers() & Qt::ShiftModifier)) { factor = m_scrollBar->pageStep(); } int offset = (m_totalDeltas / 120) * factor; if (offset != 0) { if (isRightToLeft()) { m_scrollBar->animateToValue(m_scrollBar->value() + offset); } else { m_scrollBar->animateToValue(m_scrollBar->value() - offset); } m_totalDeltas -= (offset / factor) * 120; } } int TabBarScrollWidget::scrollButtonsWidth() const { // Assumes both buttons have the same width return m_leftScrollButton->width(); } bool TabBarScrollWidget::usesScrollButtons() const { return m_usesScrollButtons; } void TabBarScrollWidget::setUsesScrollButtons(bool useButtons) { if (useButtons != m_usesScrollButtons) { m_usesScrollButtons = useButtons; updateScrollButtonsState(); m_tabBar->setElideMode(m_tabBar->elideMode()); } } bool TabBarScrollWidget::isOverflowed() const { return m_tabBar->count() > 0 && m_scrollBar->minimum() != m_scrollBar->maximum(); } int TabBarScrollWidget::tabAt(const QPoint &pos) const { if (m_leftScrollButton->isVisible() && (m_leftScrollButton->rect().contains(pos) || m_rightScrollButton->rect().contains(pos))) { return -1; } return m_tabBar->tabAt(m_tabBar->mapFromGlobal(mapToGlobal(pos))); } void TabBarScrollWidget::mouseMoveEvent(QMouseEvent* event) { event->ignore(); } void TabBarScrollWidget::resizeEvent(QResizeEvent* event) { QWidget::resizeEvent(event); updateScrollButtonsState(); } CloseButton::CloseButton(QWidget* parent) : QAbstractButton(parent) { setObjectName("combotabbar_tabs_close_button"); setFocusPolicy(Qt::NoFocus); setCursor(Qt::ArrowCursor); } void CloseButton::enterEvent(QEvent* event) { if (isEnabled()) { update(); } QAbstractButton::enterEvent(event); } void CloseButton::leaveEvent(QEvent* event) { if (isEnabled()) { update(); } QAbstractButton::leaveEvent(event); } void CloseButton::paintEvent(QPaintEvent*) { QPainter p(this); QStyleOption opt; opt.init(this); opt.state |= QStyle::State_AutoRaise; // update raised state on scrolling bool isUnderMouse = rect().contains(mapFromGlobal(QCursor::pos())); if (isEnabled() && isUnderMouse && !isChecked() && !isDown()) { opt.state |= QStyle::State_Raised; } if (isChecked()) { opt.state |= QStyle::State_On; } if (isDown()) { opt.state |= QStyle::State_Sunken; } if (TabBarHelper* tb = qobject_cast(parent())) { int index = tb->currentIndex(); QTabBar::ButtonPosition closeSide = (QTabBar::ButtonPosition)style()->styleHint(QStyle::SH_TabBar_CloseButtonPosition, 0, tb); if (tb->tabButton(index, closeSide) == this && tb->isActiveTabBar()) { opt.state |= QStyle::State_Selected; } } style()->drawPrimitive(QStyle::PE_IndicatorTabClose, &opt, &p, this); } diff --git a/src/lib/tabwidget/combotabbar.h b/src/lib/tabwidget/combotabbar.h index 84afe5c0..ce567c62 100644 --- a/src/lib/tabwidget/combotabbar.h +++ b/src/lib/tabwidget/combotabbar.h @@ -1,345 +1,345 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2013-2014 S. Razi Alavizadeh * Copyright (C) 2014-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef COMBOTABBAR_H #define COMBOTABBAR_H #include "qzcommon.h" #include "wheelhelper.h" #include #include #include #include #include class QScrollArea; class QPropertyAnimation; class QHBoxLayout; class TabBarScrollWidget; class TabBarHelper; class ToolButton; -class QUPZILLA_EXPORT ComboTabBar : public QWidget +class FALKON_EXPORT ComboTabBar : public QWidget { Q_OBJECT Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentChanged) Q_PROPERTY(int count READ count) public: enum SizeType { PinnedTabWidth, ActiveTabMinimumWidth, NormalTabMinimumWidth, NormalTabMaximumWidth, OverflowedTabWidth, ExtraReservedWidth }; explicit ComboTabBar(QWidget* parent = 0); int addTab(const QString &text); int addTab(const QIcon &icon, const QString &text); int insertTab(int index, const QString &text); int insertTab(int index, const QIcon &icon, const QString &text, bool pinned = false); void removeTab(int index); void moveTab(int from, int to); bool isTabEnabled(int index) const; void setTabEnabled(int index, bool enabled); QColor tabTextColor(int index) const; void setTabTextColor(int index, const QColor &color); QRect tabRect(int index) const; // Returns tab index at pos, or -1 int tabAt(const QPoint &pos) const; // Returns true if there is an empty area at pos // (returns false if there are buttons or other widgets on the pos) bool emptyArea(const QPoint &pos) const; int mainTabBarCurrentIndex() const; int currentIndex() const; int count() const; void setDrawBase(bool drawTheBase); bool drawBase() const; Qt::TextElideMode elideMode() const; void setElideMode(Qt::TextElideMode elide); QString tabText(int index) const; void setTabText(int index, const QString &text); void setTabToolTip(int index, const QString &tip); QString tabToolTip(int index) const; bool tabsClosable() const; void setTabsClosable(bool closable); void setTabButton(int index, QTabBar::ButtonPosition position, QWidget* widget); QWidget* tabButton(int index, QTabBar::ButtonPosition position) const; QTabBar::SelectionBehavior selectionBehaviorOnRemove() const; void setSelectionBehaviorOnRemove(QTabBar::SelectionBehavior behavior); bool expanding() const; void setExpanding(bool enabled); bool isMovable() const; void setMovable(bool movable); bool documentMode() const; void setDocumentMode(bool set); int pinnedTabsCount() const; int normalTabsCount() const; bool isPinned(int index) const; void setMaxVisiblePinnedTab(int max); void setFocusPolicy(Qt::FocusPolicy policy); void setObjectName(const QString &name); void setMouseTracking(bool enable); void insertCloseButton(int index); void setCloseButtonsToolTip(const QString &tip); QTabBar::ButtonPosition iconButtonPosition() const; QTabBar::ButtonPosition closeButtonPosition() const; QSize iconButtonSize() const; QSize closeButtonSize() const; bool validIndex(int index) const; void setCurrentNextEnabledIndex(int offset); bool usesScrollButtons() const; void setUsesScrollButtons(bool useButtons); bool isDragInProgress() const; bool isScrollInProgress() const; bool isMainBarOverflowed() const; // Width of all widgets in the corner int cornerWidth(Qt::Corner corner) const; // Add widget to the left/right corner void addCornerWidget(QWidget* widget, Qt::Corner corner); // Duration of tab slide animation when releasing dragged tab static int slideAnimationDuration(); public slots: void setUpLayout(); void ensureVisible(int index = -1, int xmargin = -1); void setCurrentIndex(int index); signals: void overFlowChanged(bool overFlow); void currentChanged(int index); void tabCloseRequested(int index); void tabMoved(int from, int to); void scrollBarValueChanged(int value); private slots: void setMinimumWidths(); void slotCurrentChanged(int index); void slotTabCloseRequested(int index); void slotTabMoved(int from, int to); void closeTabFromButton(); void updateTabBars(); void emitOverFlowChanged(); protected: int mainTabBarWidth() const; int pinTabBarWidth() const; bool event(QEvent *event); void wheelEvent(QWheelEvent* event); bool eventFilter(QObject* obj, QEvent* ev); void paintEvent(QPaintEvent* ev); virtual int comboTabBarPixelMetric(SizeType sizeType) const; virtual QSize tabSizeHint(int index, bool fast = false) const; virtual void tabInserted(int index); virtual void tabRemoved(int index); private: TabBarHelper* mainTabBar() const; TabBarHelper* localTabBar(int index = -1) const; int toLocalIndex(int globalIndex) const; void updatePinnedTabBarVisibility(); QHBoxLayout* m_mainLayout; QHBoxLayout* m_leftLayout; QHBoxLayout* m_rightLayout; QWidget* m_leftContainer; QWidget* m_rightContainer; TabBarHelper* m_mainTabBar; TabBarHelper* m_pinnedTabBar; TabBarScrollWidget* m_mainTabBarWidget; TabBarScrollWidget* m_pinnedTabBarWidget; QString m_closeButtonsToolTip; bool m_mainBarOverFlowed; bool m_lastAppliedOverflow; bool m_usesScrollButtons; bool m_blockCurrentChangedSignal; WheelHelper m_wheelHelper; friend class TabBarHelper; friend class TabStackedWidget; }; -class QUPZILLA_EXPORT TabBarHelper : public QTabBar +class FALKON_EXPORT TabBarHelper : public QTabBar { Q_OBJECT public: explicit TabBarHelper(bool isPinnedTabBar, ComboTabBar* comboTabBar); void setTabButton(int index, QTabBar::ButtonPosition position, QWidget* widget); QSize tabSizeHint(int index) const; QSize baseClassTabSizeHint(int index) const; bool isActiveTabBar(); void setActiveTabBar(bool activate); void removeTab(int index); void setScrollArea(QScrollArea* scrollArea); void useFastTabSizeHint(bool enabled); bool isDisplayedOnViewPort(int globalLeft, int globalRight); bool isDragInProgress() const; static void initStyleBaseOption(QStyleOptionTabBarBase* optTabBase, QTabBar* tabbar, QSize size); public slots: void setCurrentIndex(int index); private slots: void resetDragState(); void tabWasMoved(int from, int to); private: bool event(QEvent* ev); void paintEvent(QPaintEvent* event); void mousePressEvent(QMouseEvent* event); void mouseReleaseEvent(QMouseEvent* event); void initStyleOption(QStyleOptionTab* option, int tabIndex) const; void tabInserted(int index); void tabRemoved(int index); ComboTabBar* m_comboTabBar; QScrollArea* m_scrollArea; int m_pressedIndex; int m_pressedGlobalX; bool m_dragInProgress; bool m_activeTabBar; bool m_isPinnedTabBar; bool m_useFastTabSizeHint; }; -class QUPZILLA_EXPORT TabScrollBar : public QScrollBar +class FALKON_EXPORT TabScrollBar : public QScrollBar { Q_OBJECT public: explicit TabScrollBar(QWidget* parent = 0); ~TabScrollBar(); bool isScrolling() const; void animateToValue(int to, QEasingCurve::Type type = QEasingCurve::OutQuad); private: QPropertyAnimation* m_animation; }; -class QUPZILLA_EXPORT TabBarScrollWidget : public QWidget +class FALKON_EXPORT TabBarScrollWidget : public QWidget { Q_OBJECT public: explicit TabBarScrollWidget(QTabBar* tabBar, QWidget* parent = 0); QTabBar* tabBar(); QScrollArea* scrollArea(); TabScrollBar* scrollBar(); void scrollByWheel(QWheelEvent* event); int scrollButtonsWidth() const; bool usesScrollButtons() const; void setUsesScrollButtons(bool useButtons); bool isOverflowed() const; int tabAt(const QPoint &pos) const; public slots: void ensureVisible(int index = -1, int xmargin = 132); void scrollToLeft(int n = 5, QEasingCurve::Type type = QEasingCurve::OutQuad); void scrollToRight(int n = 5, QEasingCurve::Type type = QEasingCurve::OutQuad); void scrollToLeftEdge(); void scrollToRightEdge(); void setUpLayout(); private slots: void overFlowChanged(bool overflowed); void scrollStart(); void updateScrollButtonsState(); private: void mouseMoveEvent(QMouseEvent* event); void resizeEvent(QResizeEvent* event); QTabBar* m_tabBar; QScrollArea* m_scrollArea; TabScrollBar* m_scrollBar; ToolButton* m_rightScrollButton; ToolButton* m_leftScrollButton; bool m_usesScrollButtons; int m_totalDeltas; }; // Class for close button on tabs // * taken from qtabbar.cpp class CloseButton : public QAbstractButton { Q_OBJECT public: CloseButton(QWidget* parent = 0); void enterEvent(QEvent* event); void leaveEvent(QEvent* event); void paintEvent(QPaintEvent* event); }; #endif // COMBOTABBAR_H diff --git a/src/lib/tabwidget/tabbar.cpp b/src/lib/tabwidget/tabbar.cpp index 8cf8deed..df225e06 100644 --- a/src/lib/tabwidget/tabbar.cpp +++ b/src/lib/tabwidget/tabbar.cpp @@ -1,668 +1,668 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "tabbar.h" #include "tabwidget.h" #include "browserwindow.h" #include "webtab.h" #include "toolbutton.h" #include "settings.h" #include "tabbedwebview.h" #include "mainapplication.h" #include "pluginproxy.h" #include "iconprovider.h" #include "checkboxdialog.h" #include #include #include #include #include #include #include #include #include #include TabBar::TabBar(BrowserWindow* window, TabWidget* tabWidget) : ComboTabBar() , m_window(window) , m_tabWidget(tabWidget) , m_hideTabBarWithOneTab(false) , m_showCloseOnInactive(0) , m_clickedTab(0) , m_normalTabWidth(0) , m_activeTabWidth(0) , m_forceHidden(false) { setObjectName("tabbar"); setElideMode(Qt::ElideRight); setFocusPolicy(Qt::NoFocus); setTabsClosable(false); setMouseTracking(true); setDocumentMode(true); setAcceptDrops(true); setDrawBase(false); setMovable(true); connect(this, SIGNAL(currentChanged(int)), this, SLOT(currentTabChanged(int))); // ComboTabBar features setUsesScrollButtons(true); setCloseButtonsToolTip(BrowserWindow::tr("Close Tab")); connect(this, SIGNAL(overFlowChanged(bool)), this, SLOT(overflowChanged(bool))); if (mApp->isPrivate()) { QLabel* privateBrowsing = new QLabel(this); privateBrowsing->setObjectName(QSL("private-browsing-icon")); privateBrowsing->setPixmap(IconProvider::privateBrowsingIcon().pixmap(16)); privateBrowsing->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); privateBrowsing->setFixedWidth(30); addCornerWidget(privateBrowsing, Qt::TopLeftCorner); } } void TabBar::loadSettings() { Settings settings; settings.beginGroup("Browser-Tabs-Settings"); m_hideTabBarWithOneTab = settings.value("hideTabsWithOneTab", false).toBool(); bool activateLastTab = settings.value("ActivateLastTabWhenClosingActual", false).toBool(); m_showCloseOnInactive = settings.value("showCloseOnInactiveTabs", 0).toInt(0); settings.endGroup(); setSelectionBehaviorOnRemove(activateLastTab ? QTabBar::SelectPreviousTab : QTabBar::SelectRightTab); setVisible(!(count() == 1 && m_hideTabBarWithOneTab)); setUpLayout(); } TabWidget* TabBar::tabWidget() const { return m_tabWidget; } void TabBar::setVisible(bool visible) { if (m_forceHidden) { ComboTabBar::setVisible(false); return; } // Make sure to honor user preference if (visible) { visible = !(count() == 1 && m_hideTabBarWithOneTab); } ComboTabBar::setVisible(visible); } void TabBar::setForceHidden(bool hidden) { m_forceHidden = hidden; setVisible(!m_forceHidden); } void TabBar::overflowChanged(bool overflowed) { // Make sure close buttons on inactive tabs are hidden // This is needed for when leaving fullscreen from non-overflowed to overflowed state if (overflowed && m_showCloseOnInactive != 1) { setTabsClosable(false); showCloseButton(currentIndex()); } } static bool canCloseTabs(const QString &settingsKey, const QString &title, const QString &description) { Settings settings; bool ask = settings.value("Browser-Tabs-Settings/" + settingsKey, true).toBool(); if (ask) { CheckBoxDialog dialog(QMessageBox::Yes | QMessageBox::No, mApp->activeWindow()); dialog.setDefaultButton(QMessageBox::No); dialog.setWindowTitle(title); dialog.setText(description); dialog.setCheckBoxText(TabBar::tr("Don't ask again")); dialog.setIcon(QMessageBox::Question); if (dialog.exec() != QMessageBox::Yes) { return false; } if (dialog.isChecked()) { settings.setValue("Browser-Tabs-Settings/" + settingsKey, false); } } return true; } void TabBar::closeAllButCurrent() { if (canCloseTabs(QLatin1String("AskOnClosingAllButCurrent"), tr("Close Tabs"), tr("Do you really want to close other tabs?"))) { emit closeAllButCurrent(m_clickedTab); } } void TabBar::closeToRight() { if (canCloseTabs(QLatin1String("AskOnClosingToRight"), tr("Close Tabs"), tr("Do you really want to close all tabs to the right?"))) { emit closeToRight(m_clickedTab); } } void TabBar::closeToLeft() { if (canCloseTabs(QLatin1String("AskOnClosingToLeft"), tr("Close Tabs"), tr("Do you really want to close all tabs to the left?"))) { emit closeToLeft(m_clickedTab); } } QSize TabBar::tabSizeHint(int index, bool fast) const { if (!m_window->isVisible()) { // Don't calculate it when window is not visible // It produces invalid size anyway return QSize(-1, -1); } const int pinnedTabWidth = comboTabBarPixelMetric(ComboTabBar::PinnedTabWidth); const int minTabWidth = comboTabBarPixelMetric(ComboTabBar::NormalTabMinimumWidth); QSize size = ComboTabBar::tabSizeHint(index); // The overflowed tabs have same size and we can use this fast method if (fast) { size.setWidth(index >= pinnedTabsCount() ? minTabWidth : pinnedTabWidth); return size; } WebTab* webTab = qobject_cast(m_tabWidget->widget(index)); TabBar* tabBar = const_cast (this); if (webTab && webTab->isPinned()) { size.setWidth(pinnedTabWidth); } else { int availableWidth = mainTabBarWidth() - comboTabBarPixelMetric(ExtraReservedWidth); if (availableWidth < 0) { return QSize(-1, -1); } const int normalTabsCount = ComboTabBar::normalTabsCount(); const int maxTabWidth = comboTabBarPixelMetric(ComboTabBar::NormalTabMaximumWidth); if (availableWidth >= maxTabWidth * normalTabsCount) { m_normalTabWidth = maxTabWidth; size.setWidth(m_normalTabWidth); } else if (normalTabsCount > 0) { const int minActiveTabWidth = comboTabBarPixelMetric(ComboTabBar::ActiveTabMinimumWidth); int maxWidthForTab = availableWidth / normalTabsCount; int realTabWidth = maxWidthForTab; bool adjustingActiveTab = false; if (realTabWidth < minActiveTabWidth) { maxWidthForTab = normalTabsCount > 1 ? (availableWidth - minActiveTabWidth) / (normalTabsCount - 1) : 0; realTabWidth = minActiveTabWidth; adjustingActiveTab = true; } bool tryAdjusting = availableWidth >= minTabWidth * normalTabsCount; if (m_showCloseOnInactive != 1 && tabsClosable() && availableWidth < (minTabWidth + 25) * normalTabsCount) { // Hiding close buttons to save some space tabBar->setTabsClosable(false); tabBar->showCloseButton(currentIndex()); } if (m_showCloseOnInactive == 1) { // Always showing close buttons tabBar->setTabsClosable(true); tabBar->showCloseButton(currentIndex()); } if (tryAdjusting) { m_normalTabWidth = maxWidthForTab; // Fill any empty space (we've got from rounding) with active tab if (index == mainTabBarCurrentIndex()) { if (adjustingActiveTab) { m_activeTabWidth = (availableWidth - minActiveTabWidth - maxWidthForTab * (normalTabsCount - 1)) + realTabWidth; } else { m_activeTabWidth = (availableWidth - maxWidthForTab * normalTabsCount) + maxWidthForTab; } size.setWidth(m_activeTabWidth); } else { size.setWidth(m_normalTabWidth); } } } // Restore close buttons according to preferences if (m_showCloseOnInactive != 2 && !tabsClosable() && availableWidth >= (minTabWidth + 25) * normalTabsCount) { tabBar->setTabsClosable(true); // Hide close buttons on pinned tabs for (int i = 0; i < count(); ++i) { tabBar->updatePinnedTabCloseButton(i); } } } if (index == count() - 1) { WebTab* lastMainActiveTab = qobject_cast(m_tabWidget->widget(mainTabBarCurrentIndex())); int xForAddTabButton = cornerWidth(Qt::TopLeftCorner) + pinTabBarWidth() + normalTabsCount() * m_normalTabWidth; if (lastMainActiveTab && m_activeTabWidth > m_normalTabWidth) { xForAddTabButton += m_activeTabWidth - m_normalTabWidth; } if (QApplication::layoutDirection() == Qt::RightToLeft) { xForAddTabButton = width() - xForAddTabButton; } emit tabBar->moveAddTabButton(xForAddTabButton); } return size; } int TabBar::comboTabBarPixelMetric(ComboTabBar::SizeType sizeType) const { switch (sizeType) { case ComboTabBar::PinnedTabWidth: return iconButtonSize().width() + style()->pixelMetric(QStyle::PM_TabBarTabHSpace, 0, this); case ComboTabBar::ActiveTabMinimumWidth: case ComboTabBar::NormalTabMinimumWidth: case ComboTabBar::OverflowedTabWidth: return 100; case ComboTabBar::NormalTabMaximumWidth: return 250; case ComboTabBar::ExtraReservedWidth: return m_tabWidget->extraReservedWidth(); default: break; } return -1; } WebTab* TabBar::webTab(int index) const { if (index == -1) { return qobject_cast(m_tabWidget->widget(currentIndex())); } return qobject_cast(m_tabWidget->widget(index)); } void TabBar::showCloseButton(int index) { if (!validIndex(index)) { return; } WebTab* webTab = qobject_cast(m_tabWidget->widget(index)); QAbstractButton* button = qobject_cast(tabButton(index, closeButtonPosition())); if (button || (webTab && webTab->isPinned())) { return; } insertCloseButton(index); } void TabBar::contextMenuEvent(QContextMenuEvent* event) { int index = tabAt(event->pos()); m_clickedTab = index; QMenu menu; if (index != -1) { WebTab* webTab = qobject_cast(m_tabWidget->widget(m_clickedTab)); if (!webTab) { return; } if (m_window->weView(m_clickedTab)->isLoading()) { menu.addAction(QIcon::fromTheme(QSL("process-stop")), tr("&Stop Tab"), this, SLOT(stopTab())); } else { menu.addAction(QIcon::fromTheme(QSL("view-refresh")), tr("&Reload Tab"), this, SLOT(reloadTab())); } menu.addAction(QIcon::fromTheme("tab-duplicate"), tr("&Duplicate Tab"), this, SLOT(duplicateTab())); if (count() > 1 && !webTab->isPinned()) { menu.addAction(QIcon::fromTheme("tab-detach"), tr("D&etach Tab"), this, SLOT(detachTab())); } menu.addAction(webTab->isPinned() ? tr("Un&pin Tab") : tr("&Pin Tab"), this, SLOT(pinTab())); menu.addAction(webTab->isMuted() ? tr("Un&mute Tab") : tr("&Mute Tab"), this, SLOT(muteTab())); menu.addSeparator(); menu.addAction(tr("Re&load All Tabs"), m_tabWidget, SLOT(reloadAllTabs())); menu.addAction(tr("Bookmark &All Tabs"), m_window, SLOT(bookmarkAllTabs())); menu.addSeparator(); menu.addAction(tr("Close Ot&her Tabs"), this, SLOT(closeAllButCurrent())); menu.addAction(tr("Close Tabs To The Right"), this, SLOT(closeToRight())); menu.addAction(tr("Close Tabs To The Left"), this, SLOT(closeToLeft())); menu.addSeparator(); menu.addAction(m_window->action(QSL("Other/RestoreClosedTab"))); menu.addAction(QIcon::fromTheme("window-close"), tr("Cl&ose Tab"), this, SLOT(closeTab())); } else { menu.addAction(IconProvider::newTabIcon(), tr("&New tab"), m_window, SLOT(addTab())); menu.addSeparator(); menu.addAction(tr("Reloa&d All Tabs"), m_tabWidget, SLOT(reloadAllTabs())); menu.addAction(tr("Bookmark &All Tabs"), m_window, SLOT(bookmarkAllTabs())); menu.addSeparator(); menu.addAction(m_window->action(QSL("Other/RestoreClosedTab"))); } m_window->action(QSL("Other/RestoreClosedTab"))->setEnabled(m_tabWidget->canRestoreTab()); // Prevent choosing first option with double rightclick const QPoint pos = event->globalPos(); QPoint p(pos.x(), pos.y() + 1); menu.exec(p); m_window->action(QSL("Other/RestoreClosedTab"))->setEnabled(true); } void TabBar::hideCloseButton(int index) { if (!validIndex(index) || tabsClosable()) { return; } CloseButton* button = qobject_cast(tabButton(index, closeButtonPosition())); if (!button) { return; } setTabButton(index, closeButtonPosition(), 0); button->deleteLater(); } void TabBar::updatePinnedTabCloseButton(int index) { if (!validIndex(index)) { return; } WebTab* webTab = qobject_cast(m_tabWidget->widget(index)); QAbstractButton* button = qobject_cast(tabButton(index, closeButtonPosition())); bool pinned = webTab && webTab->isPinned(); if (pinned) { if (button) { button->hide(); } } else { if (button) { button->show(); } else { showCloseButton(index); } } } void TabBar::closeCurrentTab() { m_tabWidget->requestCloseTab(currentIndex()); } void TabBar::closeTabFromButton() { QWidget* button = qobject_cast(sender()); int tabToClose = -1; for (int i = 0; i < count(); ++i) { if (tabButton(i, closeButtonPosition()) == button) { tabToClose = i; break; } } if (tabToClose != -1) { m_tabWidget->requestCloseTab(tabToClose); } } void TabBar::currentTabChanged(int index) { if (!validIndex(index)) { return; } // Don't hide close buttons when dragging tabs if (m_dragStartPosition.isNull()) { showCloseButton(index); hideCloseButton(m_tabWidget->lastTabIndex()); QTimer::singleShot(100, this, [this]() { ensureVisible(); }); } m_tabWidget->currentTabChanged(index); } void TabBar::pinTab() { WebTab* webTab = qobject_cast(m_tabWidget->widget(m_clickedTab)); if (webTab) { webTab->togglePinned(); } } void TabBar::muteTab() { WebTab* webTab = qobject_cast(m_tabWidget->widget(m_clickedTab)); if (webTab) { webTab->toggleMuted(); } } void TabBar::overrideTabTextColor(int index, QColor color) { if (!m_originalTabTextColor.isValid()) { m_originalTabTextColor = tabTextColor(index); } setTabTextColor(index, color); } void TabBar::restoreTabTextColor(int index) { setTabTextColor(index, m_originalTabTextColor); } void TabBar::setTabText(int index, const QString &text) { QString tabText = text; // Avoid Alt+letter shortcuts tabText.replace(QLatin1Char('&'), QLatin1String("&&")); if (WebTab* tab = webTab(index)) { if (tab->isPinned()) { tabText.clear(); } } setTabToolTip(index, text); ComboTabBar::setTabText(index, tabText); } void TabBar::tabInserted(int index) { Q_UNUSED(index) setVisible(!(count() == 1 && m_hideTabBarWithOneTab)); } void TabBar::tabRemoved(int index) { Q_UNUSED(index) showCloseButton(currentIndex()); setVisible(!(count() == 1 && m_hideTabBarWithOneTab)); // Make sure to move add tab button to correct position when there are no normal tabs if (normalTabsCount() == 0) { int xForAddTabButton = cornerWidth(Qt::TopLeftCorner) + pinTabBarWidth(); if (QApplication::layoutDirection() == Qt::RightToLeft) xForAddTabButton = width() - xForAddTabButton; emit moveAddTabButton(xForAddTabButton); } } void TabBar::mouseDoubleClickEvent(QMouseEvent* event) { if (mApp->plugins()->processMouseDoubleClick(Qz::ON_TabBar, this, event)) { return; } if (event->buttons() == Qt::LeftButton && emptyArea(event->pos())) { m_tabWidget->addView(QUrl(), Qz::NT_SelectedTabAtTheEnd, true); return; } ComboTabBar::mouseDoubleClickEvent(event); } void TabBar::mousePressEvent(QMouseEvent* event) { if (mApp->plugins()->processMousePress(Qz::ON_TabBar, this, event)) { return; } if (event->buttons() == Qt::LeftButton && !emptyArea(event->pos())) { m_dragStartPosition = mapFromGlobal(event->globalPos()); } else { m_dragStartPosition = QPoint(); } ComboTabBar::mousePressEvent(event); } void TabBar::mouseMoveEvent(QMouseEvent* event) { if (mApp->plugins()->processMouseMove(Qz::ON_TabBar, this, event)) { return; } if (!m_dragStartPosition.isNull() && m_tabWidget->buttonAddTab()->isVisible()) { int manhattanLength = (event->pos() - m_dragStartPosition).manhattanLength(); if (manhattanLength > QApplication::startDragDistance()) { m_tabWidget->buttonAddTab()->hide(); } } ComboTabBar::mouseMoveEvent(event); } void TabBar::mouseReleaseEvent(QMouseEvent* event) { m_dragStartPosition = QPoint(); if (mApp->plugins()->processMouseRelease(Qz::ON_TabBar, this, event)) { return; } if (m_tabWidget->buttonAddTab()->isHidden() && !isMainBarOverflowed()) { QTimer::singleShot(ComboTabBar::slideAnimationDuration(), m_tabWidget->buttonAddTab(), &AddTabButton::show); } if (!rect().contains(event->pos())) { ComboTabBar::mouseReleaseEvent(event); return; } if (event->button() == Qt::MiddleButton) { if (emptyArea(event->pos())) { m_tabWidget->addView(QUrl(), Qz::NT_SelectedTabAtTheEnd, true); return; } int id = tabAt(event->pos()); if (id != -1) { m_tabWidget->requestCloseTab(id); return; } } ComboTabBar::mouseReleaseEvent(event); } void TabBar::wheelEvent(QWheelEvent* event) { if (mApp->plugins()->processWheelEvent(Qz::ON_TabBar, this, event)) { return; } ComboTabBar::wheelEvent(event); } void TabBar::dragEnterEvent(QDragEnterEvent* event) { const QMimeData* mime = event->mimeData(); if (mime->hasUrls()) { event->acceptProposedAction(); return; } ComboTabBar::dragEnterEvent(event); } void TabBar::dropEvent(QDropEvent* event) { const QMimeData* mime = event->mimeData(); if (!mime->hasUrls()) { ComboTabBar::dropEvent(event); return; } int index = tabAt(event->pos()); if (index == -1) { foreach (const QUrl &url, mime->urls()) { m_tabWidget->addView(url, Qz::NT_SelectedTabAtTheEnd); } } else { WebTab* tab = m_window->weView(index)->webTab(); if (tab->isRestored()) { tab->webView()->load(mime->urls().at(0)); } } } diff --git a/src/lib/tabwidget/tabbar.h b/src/lib/tabwidget/tabbar.h index 086da1f3..6897ae27 100644 --- a/src/lib/tabwidget/tabbar.h +++ b/src/lib/tabwidget/tabbar.h @@ -1,120 +1,120 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2016 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef TABBAR_H #define TABBAR_H #include "combotabbar.h" #include #include "qzcommon.h" class BrowserWindow; class TabWidget; class WebTab; -class QUPZILLA_EXPORT TabBar : public ComboTabBar +class FALKON_EXPORT TabBar : public ComboTabBar { Q_OBJECT public: explicit TabBar(BrowserWindow* window, TabWidget* tabWidget); void loadSettings(); TabWidget* tabWidget() const; void setVisible(bool visible); void setForceHidden(bool hidden); void overrideTabTextColor(int index, QColor color); void restoreTabTextColor(int index); void setTabText(int index, const QString &text); void updatePinnedTabCloseButton(int index); void wheelEvent(QWheelEvent* event); signals: void reloadTab(int index); void stopTab(int index); void closeAllButCurrent(int index); void closeToRight(int index); void closeToLeft(int index); void duplicateTab(int index); void detachTab(int index); void moveAddTabButton(int posX); private slots: void currentTabChanged(int index); void overflowChanged(bool overflowed); void reloadTab() { emit reloadTab(m_clickedTab); } void stopTab() { emit stopTab(m_clickedTab); } void closeTab() { emit tabCloseRequested(m_clickedTab); } void duplicateTab() { emit duplicateTab(m_clickedTab); } void detachTab() { emit detachTab(m_clickedTab); } void pinTab(); void muteTab(); void closeCurrentTab(); void closeAllButCurrent(); void closeToRight(); void closeToLeft(); void closeTabFromButton(); private: inline bool validIndex(int index) const { return index >= 0 && index < count(); } void tabInserted(int index); void tabRemoved(int index); void hideCloseButton(int index); void showCloseButton(int index); void contextMenuEvent(QContextMenuEvent* event); void mouseDoubleClickEvent(QMouseEvent* event); void mousePressEvent(QMouseEvent* event); void mouseMoveEvent(QMouseEvent* event); void mouseReleaseEvent(QMouseEvent* event); void dragEnterEvent(QDragEnterEvent* event); void dropEvent(QDropEvent* event); QSize tabSizeHint(int index, bool fast) const; int comboTabBarPixelMetric(ComboTabBar::SizeType sizeType) const; WebTab* webTab(int index = -1) const; BrowserWindow* m_window; TabWidget* m_tabWidget; bool m_hideTabBarWithOneTab; int m_showCloseOnInactive; int m_clickedTab; mutable int m_normalTabWidth; mutable int m_activeTabWidth; QColor m_originalTabTextColor; QPoint m_dragStartPosition; bool m_forceHidden; }; #endif // TABBAR_H diff --git a/src/lib/tabwidget/tabicon.cpp b/src/lib/tabwidget/tabicon.cpp index 33d8b3bb..94c0002d 100644 --- a/src/lib/tabwidget/tabicon.cpp +++ b/src/lib/tabwidget/tabicon.cpp @@ -1,247 +1,247 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2014-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "tabicon.h" #include "webtab.h" #include "webpage.h" #include "iconprovider.h" #include "tabbedwebview.h" #include #include #include #define ANIMATION_INTERVAL 70 TabIcon::Data *TabIcon::s_data = Q_NULLPTR; TabIcon::TabIcon(QWidget* parent) : QWidget(parent) , m_tab(0) , m_currentFrame(0) , m_animationRunning(false) , m_audioIconDisplayed(false) { setObjectName(QSL("tab-icon")); if (!s_data) { s_data = new TabIcon::Data; s_data->animationPixmap = QIcon(QSL(":icons/other/loading.png")).pixmap(288, 16); s_data->framesCount = s_data->animationPixmap.width() / s_data->animationPixmap.height(); s_data->audioPlayingPixmap = QIcon::fromTheme(QSL("audio-volume-high"), QIcon(QSL(":icons/other/audioplaying.svg"))).pixmap(16); s_data->audioMutedPixmap = QIcon::fromTheme(QSL("audio-volume-muted"), QIcon(QSL(":icons/other/audiomuted.svg"))).pixmap(16); } m_updateTimer = new QTimer(this); m_updateTimer->setInterval(ANIMATION_INTERVAL); connect(m_updateTimer, SIGNAL(timeout()), this, SLOT(updateAnimationFrame())); m_hideTimer = new QTimer(this); m_hideTimer->setInterval(250); connect(m_hideTimer, &QTimer::timeout, this, &TabIcon::hide); resize(16, 16); } void TabIcon::setWebTab(WebTab* tab) { m_tab = tab; connect(m_tab->webView(), SIGNAL(loadStarted()), this, SLOT(showLoadingAnimation())); connect(m_tab->webView(), SIGNAL(loadFinished(bool)), this, SLOT(hideLoadingAnimation())); connect(m_tab->webView(), &WebView::iconChanged, this, &TabIcon::updateIcon); connect(m_tab->webView(), &WebView::backgroundActivityChanged, this, [this]() { update(); }); connect(m_tab->webView()->page(), &QWebEnginePage::recentlyAudibleChanged, this, &TabIcon::updateAudioIcon); updateIcon(); } void TabIcon::showLoadingAnimation() { m_currentFrame = 0; updateAnimationFrame(); show(); } void TabIcon::hideLoadingAnimation() { m_animationRunning = false; m_updateTimer->stop(); updateIcon(); } void TabIcon::updateIcon() { m_sitePixmap = m_tab->icon(/*allowNull*/ true).pixmap(16); if (m_sitePixmap.isNull()) { - if (m_tab->url().isEmpty() || m_tab->url().scheme() == QL1S("qupzilla")) { + if (m_tab->url().isEmpty() || m_tab->url().scheme() == QL1S("falkon")) { hide(); } else { m_hideTimer->start(); } } else { show(); } update(); } void TabIcon::updateAnimationFrame() { if (!m_animationRunning) { m_updateTimer->start(); m_animationRunning = true; } update(); m_currentFrame = (m_currentFrame + 1) % s_data->framesCount; } void TabIcon::show() { if (!shouldBeVisible()) { return; } m_hideTimer->stop(); if (isVisible()) { return; } setFixedSize(16, 16); emit resized(); QWidget::show(); } void TabIcon::hide() { if (shouldBeVisible() || isHidden()) { return; } emit resized(); setFixedSize(0, 0); QWidget::hide(); } bool TabIcon::shouldBeVisible() const { if (m_tab && m_tab->isPinned()) { return true; } return !m_sitePixmap.isNull() || m_animationRunning || m_audioIconDisplayed || (m_tab && m_tab->isPinned()); } bool TabIcon::event(QEvent *event) { if (event->type() == QEvent::ToolTip) { QHelpEvent *e = static_cast(event); if (m_audioIconDisplayed && m_audioIconRect.contains(e->pos())) { QToolTip::showText(e->globalPos(), m_tab->isMuted() ? tr("Unmute Tab") : tr("Mute Tab"), this); event->accept(); return true; } } return QWidget::event(event); } void TabIcon::updateAudioIcon(bool recentlyAudible) { if (m_tab->isMuted() || (!m_tab->isMuted() && recentlyAudible)) { m_audioIconDisplayed = true; show(); } else { m_audioIconDisplayed = false; hide(); } update(); } void TabIcon::paintEvent(QPaintEvent* event) { Q_UNUSED(event); QPainter p(this); p.setRenderHint(QPainter::Antialiasing); const int size = 16; const int pixmapSize = qRound(size * s_data->animationPixmap.devicePixelRatioF()); // Center the pixmap in rect QRect r = rect(); r.setX((r.width() - size) / 2); r.setY((r.height() - size) / 2); r.setWidth(size); r.setHeight(size); if (m_animationRunning) { p.drawPixmap(r, s_data->animationPixmap, QRect(m_currentFrame * pixmapSize, 0, pixmapSize, pixmapSize)); } else if (m_audioIconDisplayed && !m_tab->isPinned()) { m_audioIconRect = r; p.drawPixmap(r, m_tab->isMuted() ? s_data->audioMutedPixmap : s_data->audioPlayingPixmap); } else if (!m_sitePixmap.isNull()) { p.drawPixmap(r, m_sitePixmap); } else if (m_tab && m_tab->isPinned()) { p.drawPixmap(r, IconProvider::emptyWebIcon().pixmap(size)); } // Draw audio icon on top of site icon for pinned tabs if (!m_animationRunning && m_audioIconDisplayed && m_tab->isPinned()) { const int s = size - 4; const QRect r(width() - s, 0, s, s); m_audioIconRect = r; QColor c = palette().color(QPalette::Window); c.setAlpha(180); p.setPen(c); p.setBrush(c); p.drawEllipse(r); p.drawPixmap(r, m_tab->isMuted() ? s_data->audioMutedPixmap : s_data->audioPlayingPixmap); } // Draw background activity indicator if (m_tab && m_tab->isPinned() && m_tab->webView()->backgroundActivity()) { const int s = 5; // Background const QRect r1(width() - s - 2, height() - s - 2, s + 2, s + 2); QColor c1 = palette().color(QPalette::Window); c1.setAlpha(180); p.setPen(Qt::transparent); p.setBrush(c1); p.drawEllipse(r1); // Foreground const QRect r2(width() - s - 1, height() - s - 1, s, s); QColor c2 = palette().color(QPalette::Text); p.setPen(Qt::transparent); p.setBrush(c2); p.drawEllipse(r2); } } void TabIcon::mousePressEvent(QMouseEvent *event) { // If audio icon is clicked - we don't propagate mouse press to the tab if (m_audioIconDisplayed && event->button() == Qt::LeftButton && m_audioIconRect.contains(event->pos())) { m_tab->toggleMuted(); return; } QWidget::mousePressEvent(event); } diff --git a/src/lib/tabwidget/tabicon.h b/src/lib/tabwidget/tabicon.h index ce085485..7d601c8d 100644 --- a/src/lib/tabwidget/tabicon.h +++ b/src/lib/tabwidget/tabicon.h @@ -1,77 +1,77 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2014-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef TABICON_H #define TABICON_H #include #include #include "qzcommon.h" class QTimer; class WebTab; -class QUPZILLA_EXPORT TabIcon : public QWidget +class FALKON_EXPORT TabIcon : public QWidget { Q_OBJECT public: explicit TabIcon(QWidget* parent = 0); void setWebTab(WebTab* tab); void updateIcon(); signals: void resized(); private slots: void showLoadingAnimation(); void hideLoadingAnimation(); void updateAudioIcon(bool recentlyAudible); void updateAnimationFrame(); private: void show(); void hide(); bool shouldBeVisible() const; bool event(QEvent *event) override; void paintEvent(QPaintEvent* event) override; void mousePressEvent(QMouseEvent* event) override; WebTab* m_tab; QTimer* m_updateTimer; QTimer* m_hideTimer; QPixmap m_sitePixmap; int m_currentFrame; bool m_animationRunning; bool m_audioIconDisplayed; QRect m_audioIconRect; struct Data { int framesCount; QPixmap animationPixmap; QPixmap audioPlayingPixmap; QPixmap audioMutedPixmap; }; static Data *s_data; }; #endif // TABICON_H diff --git a/src/lib/tabwidget/tabstackedwidget.cpp b/src/lib/tabwidget/tabstackedwidget.cpp index 171a088d..e8499149 100644 --- a/src/lib/tabwidget/tabstackedwidget.cpp +++ b/src/lib/tabwidget/tabstackedwidget.cpp @@ -1,364 +1,364 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2013-2014 S. Razi Alavizadeh * * Some code was taken from qtabwidget.cpp * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "tabstackedwidget.h" #include "combotabbar.h" #include #include #include #include #include // Note: just some of QTabWidget's methods were implemented TabStackedWidget::TabStackedWidget(QWidget* parent) : QWidget(parent) , m_stack(0) , m_tabBar(0) , m_currentIndex(-1) , m_previousIndex(-1) { m_stack = new QStackedWidget(this); m_mainLayout = new QVBoxLayout; m_mainLayout->setSpacing(0); m_mainLayout->setContentsMargins(0, 0, 0, 0); m_mainLayout->addWidget(m_stack); setLayout(m_mainLayout); connect(m_stack, SIGNAL(widgetRemoved(int)), this, SLOT(tabWasRemoved(int))); } TabStackedWidget::~TabStackedWidget() { } ComboTabBar* TabStackedWidget::tabBar() { return m_tabBar; } void TabStackedWidget::setTabBar(ComboTabBar* tb) { Q_ASSERT(tb); if (tb->parentWidget() != this) { tb->setParent(this); tb->show(); } delete m_tabBar; m_dirtyTabBar = true; m_tabBar = tb; setFocusProxy(m_tabBar); connect(m_tabBar, SIGNAL(currentChanged(int)), this, SLOT(showTab(int))); connect(m_tabBar, SIGNAL(tabMoved(int,int)), this, SLOT(tabWasMoved(int,int))); connect(m_tabBar, SIGNAL(overFlowChanged(bool)), this, SLOT(setUpLayout())); if (m_tabBar->tabsClosable()) { connect(m_tabBar, SIGNAL(tabCloseRequested(int)), this, SIGNAL(tabCloseRequested(int))); } setDocumentMode(m_tabBar->documentMode()); m_tabBar->installEventFilter(this); setUpLayout(); } void TabStackedWidget::tabWasMoved(int from, int to) { m_stack->blockSignals(true); QWidget* w = m_stack->widget(from); m_stack->removeWidget(w); m_stack->insertWidget(to, w); m_stack->blockSignals(false); } void TabStackedWidget::tabWasRemoved(int index) { if (m_previousIndex == index) m_previousIndex = -1; else if (m_previousIndex > index) --m_previousIndex; if (m_currentIndex == index) m_currentIndex = -1; else if (m_currentIndex > index) --m_currentIndex; m_tabBar->removeTab(index); } void TabStackedWidget::setUpLayout() { if (!m_tabBar->isVisible()) { m_dirtyTabBar = true; return; } m_tabBar->setElideMode(m_tabBar->elideMode()); m_dirtyTabBar = false; } bool TabStackedWidget::eventFilter(QObject* obj, QEvent* event) { if (m_dirtyTabBar && obj == m_tabBar && event->type() == QEvent::Show) { setUpLayout(); } return false; } void TabStackedWidget::keyPressEvent(QKeyEvent* event) { if (((event->key() == Qt::Key_Tab || event->key() == Qt::Key_Backtab) && count() > 1 && event->modifiers() & Qt::ControlModifier) #ifdef QT_KEYPAD_NAVIGATION || QApplication::keypadNavigationEnabled() && (event->key() == Qt::Key_Left || event->key() == Qt::Key_Right) && count() > 1 #endif ) { int pageCount = count(); int page = currentIndex(); int dx = (event->key() == Qt::Key_Backtab || event->modifiers() & Qt::ShiftModifier) ? -1 : 1; #ifdef QT_KEYPAD_NAVIGATION if (QApplication::keypadNavigationEnabled() && (event->key() == Qt::Key_Left || event->key() == Qt::Key_Right)) { dx = event->key() == (isRightToLeft() ? Qt::Key_Right : Qt::Key_Left) ? -1 : 1; } #endif for (int pass = 0; pass < pageCount; ++pass) { page += dx; if (page < 0 #ifdef QT_KEYPAD_NAVIGATION && !event->isAutoRepeat() #endif ) { page = count() - 1; } else if (page >= pageCount #ifdef QT_KEYPAD_NAVIGATION && !event->isAutoRepeat() #endif ) { page = 0; } if (m_tabBar->isTabEnabled(page)) { setCurrentIndex(page); break; } } if (!QApplication::focusWidget()) { m_tabBar->setFocus(); } } else { event->ignore(); } } void TabStackedWidget::showTab(int index) { if (validIndex(index)) { m_stack->setCurrentIndex(index); } m_previousIndex = m_currentIndex; m_currentIndex = index; // This is slot connected to ComboTabBar::currentChanged // We must send the signal even with invalid index (-1) emit currentChanged(index); } bool TabStackedWidget::documentMode() const { return m_tabBar->documentMode(); } void TabStackedWidget::setDocumentMode(bool enabled) { m_tabBar->setDocumentMode(enabled); m_tabBar->setExpanding(!enabled); m_tabBar->setDrawBase(enabled); } int TabStackedWidget::addTab(QWidget* widget, const QString &label, bool pinned) { return insertTab(-1, widget, label, pinned); } int TabStackedWidget::insertTab(int index, QWidget* w, const QString &label, bool pinned) { if (!w) { return -1; } if (pinned) { index = index < 0 ? m_tabBar->pinnedTabsCount() : qMin(index, m_tabBar->pinnedTabsCount()); index = m_stack->insertWidget(index, w); m_tabBar->insertTab(index, QIcon(), label, true); } else { index = index < 0 ? -1 : qMax(index, m_tabBar->pinnedTabsCount()); index = m_stack->insertWidget(index, w); m_tabBar->insertTab(index, QIcon(), label, false); } if (m_previousIndex >= index) ++m_previousIndex; if (m_currentIndex >= index) ++m_currentIndex; QTimer::singleShot(0, this, SLOT(setUpLayout())); return index; } QString TabStackedWidget::tabText(int index) const { return m_tabBar->tabText(index); } void TabStackedWidget::setTabText(int index, const QString &label) { m_tabBar->setTabText(index, label); } QString TabStackedWidget::tabToolTip(int index) const { return m_tabBar->tabToolTip(index); } void TabStackedWidget::setTabToolTip(int index, const QString &tip) { m_tabBar->setTabToolTip(index, tip); } int TabStackedWidget::pinUnPinTab(int index, const QString &title) { QWidget* widget = m_stack->widget(index); QWidget* currentWidget = m_stack->currentWidget(); if (!widget || !currentWidget) return -1; bool makePinned = index >= m_tabBar->pinnedTabsCount(); QWidget* button = m_tabBar->tabButton(index, m_tabBar->iconButtonPosition()); m_tabBar->m_blockCurrentChangedSignal = true; m_tabBar->setTabButton(index, m_tabBar->iconButtonPosition(), 0); m_stack->removeWidget(widget); int newIndex = insertTab(makePinned ? 0 : m_tabBar->pinnedTabsCount(), widget, title, makePinned); m_tabBar->setTabButton(newIndex, m_tabBar->iconButtonPosition(), button); m_tabBar->m_blockCurrentChangedSignal = false; // Restore current widget setCurrentWidget(currentWidget); emit pinStateChanged(newIndex, makePinned); return newIndex; } void TabStackedWidget::removeTab(int index) { if (QWidget* w = m_stack->widget(index)) { // Select another current tab before remove, so it won't be handled by QTabBar if (index == currentIndex() && count() > 1) selectTabOnRemove(); m_stack->removeWidget(w); } } int TabStackedWidget::currentIndex() const { return m_tabBar->currentIndex(); } void TabStackedWidget::setCurrentIndex(int index) { m_tabBar->setCurrentIndex(index); } QWidget* TabStackedWidget::currentWidget() const { return m_stack->currentWidget(); } void TabStackedWidget::setCurrentWidget(QWidget* widget) { m_tabBar->setCurrentIndex(indexOf(widget)); } QWidget* TabStackedWidget::widget(int index) const { return m_stack->widget(index); } int TabStackedWidget::indexOf(QWidget* widget) const { return m_stack->indexOf(widget); } int TabStackedWidget::count() const { return m_tabBar->count(); } bool TabStackedWidget::validIndex(int index) const { return (index < m_stack->count() && index >= 0); } void TabStackedWidget::selectTabOnRemove() { Q_ASSERT(count() > 1); int index = -1; switch (m_tabBar->selectionBehaviorOnRemove()) { case QTabBar::SelectPreviousTab: if (validIndex(m_previousIndex)) { index = m_previousIndex; break; } // fallthrough case QTabBar::SelectLeftTab: index = currentIndex() - 1; if (!validIndex(index)) index = 1; break; case QTabBar::SelectRightTab: index = currentIndex() + 1; if (!validIndex(index)) index = currentIndex() - 1; break; default: break; } Q_ASSERT(validIndex(index)); setCurrentIndex(index); } diff --git a/src/lib/tabwidget/tabstackedwidget.h b/src/lib/tabwidget/tabstackedwidget.h index 1e1037cc..2c3b4763 100644 --- a/src/lib/tabwidget/tabstackedwidget.h +++ b/src/lib/tabwidget/tabstackedwidget.h @@ -1,95 +1,95 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2013-2014 S. Razi Alavizadeh * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef TABSTACKEDWIDGET_H #define TABSTACKEDWIDGET_H #include "qzcommon.h" #include class ComboTabBar; class QStackedWidget; class QVBoxLayout; -class QUPZILLA_EXPORT TabStackedWidget : public QWidget +class FALKON_EXPORT TabStackedWidget : public QWidget { Q_OBJECT public: explicit TabStackedWidget(QWidget* parent = 0); ~TabStackedWidget(); ComboTabBar* tabBar(); void setTabBar(ComboTabBar* tb); bool documentMode() const; void setDocumentMode(bool enabled); int addTab(QWidget* widget, const QString &label, bool pinned = false); int insertTab(int index, QWidget* widget, const QString &label, bool pinned = false); QString tabText(int index) const; void setTabText(int index, const QString &label); QString tabToolTip(int index) const; void setTabToolTip(int index, const QString &tip); int pinUnPinTab(int index, const QString &title = QString()); void removeTab(int index); int currentIndex() const; QWidget* currentWidget() const; QWidget* widget(int index) const; int indexOf(QWidget* widget) const; int count() const; signals: void currentChanged(int index); void tabCloseRequested(int index); void pinStateChanged(int index, bool pinned); public slots: void setCurrentIndex(int index); void setCurrentWidget(QWidget* widget); void setUpLayout(); private slots: void showTab(int index); void tabWasMoved(int from, int to); void tabWasRemoved(int index); protected: bool eventFilter(QObject* obj, QEvent* event); void keyPressEvent(QKeyEvent* event); private: bool validIndex(int index) const; void selectTabOnRemove(); QStackedWidget* m_stack; ComboTabBar* m_tabBar; QVBoxLayout* m_mainLayout; bool m_dirtyTabBar; int m_currentIndex; int m_previousIndex; }; #endif // TABSTACKEDWIDGET_H diff --git a/src/lib/tabwidget/tabwidget.cpp b/src/lib/tabwidget/tabwidget.cpp index aaa612c4..09cdeb41 100644 --- a/src/lib/tabwidget/tabwidget.cpp +++ b/src/lib/tabwidget/tabwidget.cpp @@ -1,849 +1,849 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "tabwidget.h" #include "tabbar.h" #include "tabbedwebview.h" #include "webpage.h" #include "browserwindow.h" #include "mainapplication.h" #include "webtab.h" #include "clickablelabel.h" #include "closedtabsmanager.h" #include "locationbar.h" #include "settings.h" #include "datapaths.h" #include "qzsettings.h" #include "qztools.h" #include "tabicon.h" #include #include #include #include #include #include #include AddTabButton::AddTabButton(TabWidget* tabWidget, TabBar* tabBar) : ToolButton(tabBar) , m_tabBar(tabBar) , m_tabWidget(tabWidget) { setObjectName("tabwidget-button-addtab"); setAutoRaise(true); setFocusPolicy(Qt::NoFocus); setAcceptDrops(true); setToolTip(TabWidget::tr("New Tab")); } void AddTabButton::wheelEvent(QWheelEvent* event) { m_tabBar->wheelEvent(event); } void AddTabButton::mouseReleaseEvent(QMouseEvent* event) { if (event->button() == Qt::MiddleButton && rect().contains(event->pos())) { m_tabWidget->addTabFromClipboard(); } ToolButton::mouseReleaseEvent(event); } void AddTabButton::dragEnterEvent(QDragEnterEvent* event) { const QMimeData* mime = event->mimeData(); if (mime->hasUrls()) { event->acceptProposedAction(); return; } ToolButton::dragEnterEvent(event); } void AddTabButton::dropEvent(QDropEvent* event) { const QMimeData* mime = event->mimeData(); if (!mime->hasUrls()) { ToolButton::dropEvent(event); return; } foreach (const QUrl &url, mime->urls()) { m_tabWidget->addView(url, Qz::NT_SelectedNewEmptyTab); } } void MenuTabs::mouseReleaseEvent(QMouseEvent* event) { if (event->button() == Qt::MiddleButton) { QAction* action = actionAt(event->pos()); if (action && action->isEnabled()) { WebTab* tab = qobject_cast(qvariant_cast(action->data())); if (tab) { emit closeTab(tab->tabIndex()); action->setEnabled(false); event->accept(); } } } QMenu::mouseReleaseEvent(event); } TabWidget::TabWidget(BrowserWindow* window, QWidget* parent) : TabStackedWidget(parent) , m_window(window) , m_locationBars(new QStackedWidget) , m_closedTabsManager(new ClosedTabsManager) , m_lastTabIndex(-1) , m_lastBackgroundTabIndex(-1) { setObjectName(QSL("tabwidget")); m_tabBar = new TabBar(m_window, this); setTabBar(m_tabBar); connect(this, SIGNAL(currentChanged(int)), m_window, SLOT(refreshHistory())); connect(this, &TabWidget::changed, mApp, &MainApplication::changeOccurred); connect(this, &TabStackedWidget::pinStateChanged, this, &TabWidget::changed); connect(m_tabBar, SIGNAL(tabCloseRequested(int)), this, SLOT(requestCloseTab(int))); connect(m_tabBar, SIGNAL(reloadTab(int)), this, SLOT(reloadTab(int))); connect(m_tabBar, SIGNAL(stopTab(int)), this, SLOT(stopTab(int))); connect(m_tabBar, SIGNAL(closeAllButCurrent(int)), this, SLOT(closeAllButCurrent(int))); connect(m_tabBar, SIGNAL(closeToRight(int)), this, SLOT(closeToRight(int))); connect(m_tabBar, SIGNAL(closeToLeft(int)), this, SLOT(closeToLeft(int))); connect(m_tabBar, SIGNAL(duplicateTab(int)), this, SLOT(duplicateTab(int))); connect(m_tabBar, SIGNAL(detachTab(int)), this, SLOT(detachTab(int))); connect(m_tabBar, SIGNAL(tabMoved(int,int)), this, SLOT(tabMoved(int,int))); connect(m_tabBar, SIGNAL(moveAddTabButton(int)), this, SLOT(moveAddTabButton(int))); connect(mApp, SIGNAL(settingsReloaded()), this, SLOT(loadSettings())); m_menuTabs = new MenuTabs(this); connect(m_menuTabs, SIGNAL(closeTab(int)), this, SLOT(requestCloseTab(int))); m_menuClosedTabs = new QMenu(this); // AddTab button displayed next to last tab m_buttonAddTab = new AddTabButton(this, m_tabBar); connect(m_buttonAddTab, SIGNAL(clicked()), m_window, SLOT(addTab())); // AddTab button displayed outside tabbar (as corner widget) m_buttonAddTab2 = new AddTabButton(this, m_tabBar); m_buttonAddTab2->setProperty("outside-tabbar", true); m_buttonAddTab2->hide(); connect(m_buttonAddTab2, SIGNAL(clicked()), m_window, SLOT(addTab())); // ClosedTabs button displayed as a permanent corner widget m_buttonClosedTabs = new ToolButton(m_tabBar); m_buttonClosedTabs->setObjectName("tabwidget-button-closedtabs"); m_buttonClosedTabs->setMenu(m_menuClosedTabs); m_buttonClosedTabs->setPopupMode(QToolButton::InstantPopup); m_buttonClosedTabs->setToolTip(tr("Closed tabs")); m_buttonClosedTabs->setAutoRaise(true); m_buttonClosedTabs->setFocusPolicy(Qt::NoFocus); m_buttonClosedTabs->setShowMenuInside(true); connect(m_buttonClosedTabs, SIGNAL(aboutToShowMenu()), this, SLOT(aboutToShowClosedTabsMenu())); // ListTabs button is showed only when tabbar overflows m_buttonListTabs = new ToolButton(m_tabBar); m_buttonListTabs->setObjectName("tabwidget-button-opentabs"); m_buttonListTabs->setMenu(m_menuTabs); m_buttonListTabs->setPopupMode(QToolButton::InstantPopup); m_buttonListTabs->setToolTip(tr("List of tabs")); m_buttonListTabs->setAutoRaise(true); m_buttonListTabs->setFocusPolicy(Qt::NoFocus); m_buttonListTabs->setShowMenuInside(true); m_buttonListTabs->hide(); connect(m_buttonListTabs, SIGNAL(aboutToShowMenu()), this, SLOT(aboutToShowTabsMenu())); m_tabBar->addCornerWidget(m_buttonAddTab2, Qt::TopRightCorner); m_tabBar->addCornerWidget(m_buttonClosedTabs, Qt::TopRightCorner); m_tabBar->addCornerWidget(m_buttonListTabs, Qt::TopRightCorner); connect(m_tabBar, SIGNAL(overFlowChanged(bool)), this, SLOT(tabBarOverFlowChanged(bool))); loadSettings(); } void TabWidget::loadSettings() { Settings settings; settings.beginGroup("Browser-Tabs-Settings"); m_dontCloseWithOneTab = settings.value("dontCloseWithOneTab", false).toBool(); m_showClosedTabsButton = settings.value("showClosedTabsButton", false).toBool(); m_newTabAfterActive = settings.value("newTabAfterActive", true).toBool(); m_newEmptyTabAfterActive = settings.value("newEmptyTabAfterActive", false).toBool(); settings.endGroup(); settings.beginGroup("Web-URL-Settings"); - m_urlOnNewTab = settings.value("newTabUrl", "qupzilla:speeddial").toUrl(); + m_urlOnNewTab = settings.value("newTabUrl", "falkon:speeddial").toUrl(); settings.endGroup(); m_tabBar->loadSettings(); updateClosedTabsButton(); } WebTab* TabWidget::weTab() { return weTab(currentIndex()); } WebTab* TabWidget::weTab(int index) { return qobject_cast(widget(index)); } TabIcon* TabWidget::tabIcon(int index) { return weTab(index)->tabIcon(); } bool TabWidget::validIndex(int index) const { return index >= 0 && index < count(); } void TabWidget::updateClosedTabsButton() { if (!m_showClosedTabsButton) { m_buttonClosedTabs->hide(); } m_buttonClosedTabs->setEnabled(canRestoreTab()); } bool TabWidget::isCurrentTabFresh() const { return m_currentTabFresh; } void TabWidget::setCurrentTabFresh(bool currentTabFresh) { m_currentTabFresh = currentTabFresh; } void TabWidget::tabBarOverFlowChanged(bool overflowed) { // Show buttons inside tabbar m_buttonAddTab->setVisible(!overflowed); // Show buttons displayed outside tabbar (corner widgets) m_buttonAddTab2->setVisible(overflowed); m_buttonListTabs->setVisible(overflowed); m_buttonClosedTabs->setVisible(m_showClosedTabsButton); } void TabWidget::moveAddTabButton(int posX) { int posY = (m_tabBar->height() - m_buttonAddTab->height()) / 2; if (QApplication::layoutDirection() == Qt::RightToLeft) { posX = qMax(posX - m_buttonAddTab->width(), 0); } else { posX = qMin(posX, m_tabBar->width() - m_buttonAddTab->width()); } m_buttonAddTab->move(posX, posY); } void TabWidget::aboutToShowTabsMenu() { m_menuTabs->clear(); for (int i = 0; i < count(); i++) { WebTab* tab = weTab(i); if (!tab || tab->isPinned()) { continue; } QAction* action = new QAction(this); action->setIcon(tab->icon()); if (i == currentIndex()) { QFont f = action->font(); f.setBold(true); action->setFont(f); } QString title = tab->title(); title.replace(QLatin1Char('&'), QLatin1String("&&")); action->setText(QzTools::truncatedText(title, 40)); action->setData(QVariant::fromValue(qobject_cast(tab))); connect(action, SIGNAL(triggered()), this, SLOT(actionChangeIndex())); m_menuTabs->addAction(action); } } void TabWidget::aboutToShowClosedTabsMenu() { m_menuClosedTabs->clear(); int i = 0; const QLinkedList closedTabs = closedTabsManager()->allClosedTabs(); foreach (const ClosedTabsManager::Tab &tab, closedTabs) { const QString title = QzTools::truncatedText(tab.title, 40); QAction* act = m_menuClosedTabs->addAction(tab.icon, title, this, SLOT(restoreClosedTab())); act->setData(i++); } if (m_menuClosedTabs->isEmpty()) { m_menuClosedTabs->addAction(tr("Empty"))->setEnabled(false); } else { m_menuClosedTabs->addSeparator(); m_menuClosedTabs->addAction(tr("Restore All Closed Tabs"), this, SLOT(restoreAllClosedTabs())); m_menuClosedTabs->addAction(tr("Clear list"), this, SLOT(clearClosedTabsList())); } } void TabWidget::actionChangeIndex() { if (QAction* action = qobject_cast(sender())) { WebTab* tab = qobject_cast(qvariant_cast(action->data())); if (tab) { m_tabBar->ensureVisible(tab->tabIndex()); setCurrentIndex(tab->tabIndex()); } } } int TabWidget::addView(const LoadRequest &req, const Qz::NewTabPositionFlags &openFlags, bool selectLine, bool pinned) { return addView(req, QString(), openFlags, selectLine, -1, pinned); } int TabWidget::addView(const LoadRequest &req, const QString &title, const Qz::NewTabPositionFlags &openFlags, bool selectLine, int position, bool pinned) { QUrl url = req.url(); m_lastTabIndex = currentIndex(); m_currentTabFresh = false; if (url.isEmpty() && !(openFlags & Qz::NT_CleanTab)) { url = m_urlOnNewTab; } bool openAfterActive = m_newTabAfterActive && !(openFlags & Qz::NT_TabAtTheEnd); if (openFlags == Qz::NT_SelectedNewEmptyTab && m_newEmptyTabAfterActive) { openAfterActive = true; } if (openAfterActive && position == -1) { // If we are opening newBgTab from pinned tab, make sure it won't be // opened between other pinned tabs if (openFlags & Qz::NT_NotSelectedTab && m_lastBackgroundTabIndex != -1) { position = m_lastBackgroundTabIndex + 1; } else { position = qMax(currentIndex() + 1, m_tabBar->pinnedTabsCount()); } } WebTab* webTab = new WebTab(m_window); webTab->locationBar()->showUrl(url); m_locationBars->addWidget(webTab->locationBar()); int index = insertTab(position == -1 ? count() : position, webTab, QString(), pinned); webTab->attach(m_window); if (!title.isEmpty()) { m_tabBar->setTabText(index, title); } if (openFlags & Qz::NT_SelectedTab) { setCurrentIndex(index); } else { m_lastBackgroundTabIndex = index; } connect(webTab->webView(), SIGNAL(wantsCloseTab(int)), this, SLOT(closeTab(int))); connect(webTab->webView(), SIGNAL(urlChanged(QUrl)), this, SIGNAL(changed())); connect(webTab->webView(), SIGNAL(ipChanged(QString)), m_window->ipLabel(), SLOT(setText(QString))); connect(webTab->webView(), &WebView::urlChanged, this, [this](const QUrl &url) { if (url != m_urlOnNewTab) m_currentTabFresh = false; }); if (url.isValid() && url != req.url()) { LoadRequest r(req); r.setUrl(url); webTab->webView()->load(r); } else if (req.url().isValid()) { webTab->webView()->load(req); } if (selectLine && m_window->locationBar()->text().isEmpty()) { m_window->locationBar()->setFocus(); } // Make sure user notice opening new background tabs if (!(openFlags & Qz::NT_SelectedTab)) { m_tabBar->ensureVisible(index); } emit changed(); return index; } int TabWidget::addView(WebTab* tab) { m_locationBars->addWidget(tab->locationBar()); int index = addTab(tab, QString()); tab->attach(m_window); connect(tab->webView(), SIGNAL(wantsCloseTab(int)), this, SLOT(closeTab(int))); connect(tab->webView(), SIGNAL(urlChanged(QUrl)), this, SIGNAL(changed())); connect(tab->webView(), SIGNAL(ipChanged(QString)), m_window->ipLabel(), SLOT(setText(QString))); return index; } void TabWidget::addTabFromClipboard() { QString selectionClipboard = QApplication::clipboard()->text(QClipboard::Selection); QUrl guessedUrl = QUrl::fromUserInput(selectionClipboard); if (!guessedUrl.isEmpty()) { addView(guessedUrl, Qz::NT_SelectedNewEmptyTab); } } void TabWidget::closeTab(int index) { if (index == -1) index = currentIndex(); WebTab *webTab = weTab(index); if (!webTab || !validIndex(index)) return; TabbedWebView *webView = webTab->webView(); // Save tab url and history - if (webView->url().toString() != QL1S("qupzilla:restore")) + if (webView->url().toString() != QL1S("falkon:restore")) m_closedTabsManager->saveTab(webTab, index); m_locationBars->removeWidget(webView->webTab()->locationBar()); disconnect(webView, SIGNAL(wantsCloseTab(int)), this, SLOT(closeTab(int))); disconnect(webView, SIGNAL(urlChanged(QUrl)), this, SIGNAL(changed())); disconnect(webView, SIGNAL(ipChanged(QString)), m_window->ipLabel(), SLOT(setText(QString))); m_lastBackgroundTabIndex = -1; if (m_menuTabs->isVisible()) { QAction* labelAction = m_menuTabs->actions().last(); labelAction->setText(tr("Currently you have %n opened tab(s)", "", count() - 1)); } removeTab(index); webTab->deleteLater(); updateClosedTabsButton(); emit changed(); } void TabWidget::requestCloseTab(int index) { if (index == -1) index = currentIndex(); WebTab *webTab = weTab(index); if (!webTab || !validIndex(index)) return; TabbedWebView *webView = webTab->webView(); // Don't close restore page! - if (webView->url().toString() == QL1S("qupzilla:restore") && mApp->restoreManager()) + if (webView->url().toString() == QL1S("falkon:restore") && mApp->restoreManager()) return; // This would close last tab, so we close the window instead if (count() == 1) { // If we are not closing window upon closing last tab, let's just load new-tab-url if (m_dontCloseWithOneTab) { if (webView->url() == m_urlOnNewTab) { // We don't want to accumulate more than one closed tab, if user tries // to close the last tab multiple times m_closedTabsManager->takeLastClosedTab(); } webView->load(m_urlOnNewTab); return; } m_window->close(); return; } webView->triggerPageAction(QWebEnginePage::RequestClose); } void TabWidget::currentTabChanged(int index) { if (!validIndex(index)) return; m_lastBackgroundTabIndex = -1; m_lastTabIndex = index; m_currentTabFresh = false; WebTab* webTab = weTab(index); LocationBar* locBar = webTab->locationBar(); if (locBar && m_locationBars->indexOf(locBar) != -1) { m_locationBars->setCurrentWidget(locBar); } m_window->currentTabChanged(); emit changed(); } void TabWidget::tabMoved(int before, int after) { Q_UNUSED(before) Q_UNUSED(after) m_lastBackgroundTabIndex = -1; m_lastTabIndex = before; emit changed(); } void TabWidget::setCurrentIndex(int index) { m_lastTabIndex = currentIndex(); TabStackedWidget::setCurrentIndex(index); } void TabWidget::nextTab() { QKeyEvent fakeEvent(QKeyEvent::KeyPress, Qt::Key_Tab, Qt::ControlModifier); keyPressEvent(&fakeEvent); } void TabWidget::previousTab() { QKeyEvent fakeEvent(QKeyEvent::KeyPress, Qt::Key_Backtab, QFlags(Qt::ControlModifier + Qt::ShiftModifier)); keyPressEvent(&fakeEvent); } int TabWidget::normalTabsCount() const { return m_tabBar->normalTabsCount(); } int TabWidget::pinnedTabsCount() const { return m_tabBar->pinnedTabsCount(); } void TabWidget::reloadTab(int index) { if (!validIndex(index)) { return; } weTab(index)->reload(); } int TabWidget::lastTabIndex() const { return m_lastTabIndex; } int TabWidget::extraReservedWidth() const { return m_buttonAddTab->width(); } TabBar* TabWidget::tabBar() const { return m_tabBar; } ClosedTabsManager* TabWidget::closedTabsManager() const { return m_closedTabsManager; } void TabWidget::reloadAllTabs() { for (int i = 0; i < count(); i++) { reloadTab(i); } } void TabWidget::stopTab(int index) { if (!validIndex(index)) { return; } weTab(index)->stop(); } void TabWidget::closeAllButCurrent(int index) { if (!validIndex(index)) { return; } WebTab* akt = weTab(index); foreach (WebTab* tab, allTabs(false)) { int tabIndex = tab->tabIndex(); if (akt == widget(tabIndex)) { continue; } requestCloseTab(tabIndex); } } void TabWidget::closeToRight(int index) { if (!validIndex(index)) { return; } foreach (WebTab* tab, allTabs(false)) { int tabIndex = tab->tabIndex(); if (index >= tabIndex) { continue; } requestCloseTab(tabIndex); } } void TabWidget::closeToLeft(int index) { if (!validIndex(index)) { return; } foreach (WebTab* tab, allTabs(false)) { int tabIndex = tab->tabIndex(); if (index <= tabIndex) { continue; } requestCloseTab(tabIndex); } } void TabWidget::detachTab(int index) { WebTab* tab = weTab(index); if (tab->isPinned() || count() == 1) { return; } m_locationBars->removeWidget(tab->locationBar()); disconnect(tab->webView(), SIGNAL(wantsCloseTab(int)), this, SLOT(closeTab(int))); disconnect(tab->webView(), SIGNAL(urlChanged(QUrl)), this, SIGNAL(changed())); disconnect(tab->webView(), SIGNAL(ipChanged(QString)), m_window->ipLabel(), SLOT(setText(QString))); tab->detach(); BrowserWindow* window = mApp->createWindow(Qz::BW_NewWindow); window->setStartTab(tab); } int TabWidget::duplicateTab(int index) { if (!validIndex(index)) { return -1; } WebTab* webTab = weTab(index); int id = addView(QUrl(), webTab->title(), Qz::NT_CleanNotSelectedTab); weTab(id)->p_restoreTab(webTab->url(), webTab->historyData(), webTab->zoomLevel()); return id; } void TabWidget::restoreClosedTab(QObject* obj) { if (!obj) { obj = sender(); } if (!m_closedTabsManager->isClosedTabAvailable()) { return; } ClosedTabsManager::Tab tab; QAction* action = qobject_cast(obj); if (action && action->data().toInt() != 0) { tab = m_closedTabsManager->takeTabAt(action->data().toInt()); } else { tab = m_closedTabsManager->takeLastClosedTab(); } if (tab.position < 0) { return; } int index = addView(QUrl(), tab.title, Qz::NT_CleanSelectedTab, false, tab.position); WebTab* webTab = weTab(index); webTab->p_restoreTab(tab.url, tab.history, tab.zoomLevel); updateClosedTabsButton(); } void TabWidget::restoreAllClosedTabs() { if (!m_closedTabsManager->isClosedTabAvailable()) { return; } const QLinkedList &closedTabs = m_closedTabsManager->allClosedTabs(); foreach (const ClosedTabsManager::Tab &tab, closedTabs) { int index = addView(QUrl(), tab.title, Qz::NT_CleanSelectedTab); WebTab* webTab = weTab(index); webTab->p_restoreTab(tab.url, tab.history, tab.zoomLevel); } clearClosedTabsList(); } void TabWidget::clearClosedTabsList() { m_closedTabsManager->clearList(); updateClosedTabsButton(); } bool TabWidget::canRestoreTab() const { return m_closedTabsManager->isClosedTabAvailable(); } QStackedWidget* TabWidget::locationBars() const { return m_locationBars; } ToolButton* TabWidget::buttonClosedTabs() const { return m_buttonClosedTabs; } AddTabButton* TabWidget::buttonAddTab() const { return m_buttonAddTab; } QList TabWidget::allTabs(bool withPinned) { QList allTabs; for (int i = 0; i < count(); i++) { WebTab* tab = weTab(i); if (!tab || (!withPinned && tab->isPinned())) { continue; } allTabs.append(tab); } return allTabs; } QByteArray TabWidget::saveState() { int currentTabIndex = 0; QVector tabList; for (int i = 0; i < count(); ++i) { WebTab* webTab = weTab(i); if (!webTab) continue; WebTab::SavedTab tab(webTab); if (!tab.isValid()) continue; tabList.append(tab); if (webTab->isCurrentTab()) currentTabIndex = tabList.size() - 1; } QByteArray data; QDataStream stream(&data, QIODevice::WriteOnly); stream << tabList.count(); foreach (const WebTab::SavedTab &tab, tabList) { stream << tab; } stream << currentTabIndex; return data; } bool TabWidget::restoreState(const QVector &tabs, int currentTab) { for (int i = 0; i < tabs.size(); ++i) { WebTab::SavedTab tab = tabs.at(i); int index = addView(QUrl(), Qz::NT_CleanSelectedTab, false, tab.isPinned); weTab(index)->restoreTab(tab); if (tab.isPinned) m_tabBar->updatePinnedTabCloseButton(index); } setCurrentIndex(currentTab); QTimer::singleShot(0, m_tabBar, SLOT(ensureVisible(int,int))); // WebTab is restoring state on showEvent weTab()->hide(); weTab()->show(); return true; } void TabWidget::closeRecoveryTab() { foreach (WebTab* tab, allTabs(false)) { - if (tab->url().toString() == QLatin1String("qupzilla:restore")) { + if (tab->url().toString() == QLatin1String("falkon:restore")) { closeTab(tab->tabIndex()); } } } TabWidget::~TabWidget() { delete m_closedTabsManager; } diff --git a/src/lib/tabwidget/tabwidget.h b/src/lib/tabwidget/tabwidget.h index ea4f02dc..f5c267a8 100644 --- a/src/lib/tabwidget/tabwidget.h +++ b/src/lib/tabwidget/tabwidget.h @@ -1,172 +1,172 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef TABWIDGET_H #define TABWIDGET_H #include #include #include "tabstackedwidget.h" #include "toolbutton.h" #include "loadrequest.h" #include "webtab.h" #include "qzcommon.h" class QMenu; class TabBar; class TabIcon; class TabWidget; class BrowserWindow; class TabbedWebView; class ClosedTabsManager; -class QUPZILLA_EXPORT AddTabButton : public ToolButton +class FALKON_EXPORT AddTabButton : public ToolButton { public: explicit AddTabButton(TabWidget* tabWidget, TabBar* tabBar); private: void wheelEvent(QWheelEvent* event); void mouseReleaseEvent(QMouseEvent* event); void dragEnterEvent(QDragEnterEvent* event); void dropEvent(QDropEvent* event); TabBar* m_tabBar; TabWidget* m_tabWidget; }; -class QUPZILLA_EXPORT MenuTabs : public QMenu +class FALKON_EXPORT MenuTabs : public QMenu { Q_OBJECT public: explicit MenuTabs(QWidget* parent = 0) : QMenu(parent) {} signals: void closeTab(int); private: void mouseReleaseEvent(QMouseEvent* event); }; -class QUPZILLA_EXPORT TabWidget : public TabStackedWidget +class FALKON_EXPORT TabWidget : public TabStackedWidget { Q_OBJECT public: explicit TabWidget(BrowserWindow* mainclass, QWidget* parent = 0); ~TabWidget(); QByteArray saveState(); bool restoreState(const QVector &tabs, int currentTab); void closeRecoveryTab(); void setCurrentIndex(int index); void nextTab(); void previousTab(); void currentTabChanged(int index); int normalTabsCount() const; int pinnedTabsCount() const; int lastTabIndex() const; int extraReservedWidth() const; TabBar* tabBar() const; ClosedTabsManager* closedTabsManager() const; QList allTabs(bool withPinned = true); bool canRestoreTab() const; bool isCurrentTabFresh() const; void setCurrentTabFresh(bool currentTabFresh); QStackedWidget* locationBars() const; ToolButton* buttonClosedTabs() const; AddTabButton* buttonAddTab() const; public slots: int addView(const LoadRequest &req, const Qz::NewTabPositionFlags &openFlags, bool selectLine = false, bool pinned = false); int addView(const LoadRequest &req, const QString &title = tr("New tab"), const Qz::NewTabPositionFlags &openFlags = Qz::NT_SelectedTab, bool selectLine = false, int position = -1, bool pinned = false); int addView(WebTab* tab); void addTabFromClipboard(); int duplicateTab(int index); // Force close tab void closeTab(int index = -1); // Request close tab (may be rejected) void requestCloseTab(int index = -1); void reloadTab(int index); void reloadAllTabs(); void stopTab(int index); void closeAllButCurrent(int index); void closeToRight(int index); void closeToLeft(int index); void detachTab(int index); void restoreClosedTab(QObject* obj = 0); void restoreAllClosedTabs(); void clearClosedTabsList(); void moveAddTabButton(int posX); void tabBarOverFlowChanged(bool overflowed); signals: void changed(); private slots: void loadSettings(); void aboutToShowTabsMenu(); void aboutToShowClosedTabsMenu(); void actionChangeIndex(); void tabMoved(int before, int after); private: WebTab* weTab(); WebTab* weTab(int index); TabIcon* tabIcon(int index); bool validIndex(int index) const; void updateClosedTabsButton(); BrowserWindow* m_window; TabBar* m_tabBar; QStackedWidget* m_locationBars; ClosedTabsManager* m_closedTabsManager; MenuTabs* m_menuTabs; ToolButton* m_buttonListTabs; QMenu* m_menuClosedTabs; ToolButton* m_buttonClosedTabs; AddTabButton* m_buttonAddTab; AddTabButton* m_buttonAddTab2; int m_lastTabIndex; int m_lastBackgroundTabIndex; bool m_dontCloseWithOneTab; bool m_showClosedTabsButton; bool m_newTabAfterActive; bool m_newEmptyTabAfterActive; QUrl m_urlOnNewTab; bool m_currentTabFresh; }; #endif // TABWIDGET_H diff --git a/src/lib/tools/aesinterface.cpp b/src/lib/tools/aesinterface.cpp index 51dc4d5e..6d4a8523 100644 --- a/src/lib/tools/aesinterface.cpp +++ b/src/lib/tools/aesinterface.cpp @@ -1,209 +1,209 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2013-2014 S. Razi Alavizadeh * Copyright (C) 2013-2017 David Rosca * * This is based on a work by Saju Pillai * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "aesinterface.h" #include #include #include #include #include #include ////////////////////////////////////////////// /// Version 1: /// init(): n=5, EVP_CIPHER=EVP_aes_256_cbc(), EVP_MD=EVP_sha256(), Random IV /// Encrypted data structure: Version$InitializationVector_base64$EncryptedData_base64 const int AesInterface::VERSION = 1; AesInterface::AesInterface(QObject* parent) : QObject(parent) , m_ok(false) { m_encodeCTX = EVP_CIPHER_CTX_new(); m_decodeCTX = EVP_CIPHER_CTX_new(); EVP_CIPHER_CTX_init(m_encodeCTX); EVP_CIPHER_CTX_init(m_decodeCTX); } AesInterface::~AesInterface() { EVP_CIPHER_CTX_cleanup(m_encodeCTX); EVP_CIPHER_CTX_cleanup(m_decodeCTX); EVP_CIPHER_CTX_free(m_encodeCTX); EVP_CIPHER_CTX_free(m_decodeCTX); } bool AesInterface::isOk() { return m_ok; } // Create an 256 bit 'key' using the supplied password, and creates a random 'iv'. // saltArray is an array of 8 bytes can be added for taste. // Fills in the encryption and decryption ctx objects and returns true on success bool AesInterface::init(int evpMode, const QByteArray &password, const QByteArray &iVector) { m_iVector.clear(); int i; const int nrounds = 5; uchar key[EVP_MAX_KEY_LENGTH]; // Gen "key" for AES 256 CBC mode. A SHA1 digest is used to hash the supplied // key material. nrounds is the number of times that we hash the material. // More rounds are more secure but slower. i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha256(), 0, (uchar*)password.data(), password.size(), nrounds, key, 0); if (i != 32) { qWarning("Key size is %d bits - should be 256 bits", i * 8); return false; } int result = 0; if (evpMode == EVP_PKEY_MO_ENCRYPT) { m_iVector = createRandomData(EVP_MAX_IV_LENGTH); result = EVP_EncryptInit_ex(m_encodeCTX, EVP_aes_256_cbc(), NULL, key, (uchar*)m_iVector.constData()); } else if (evpMode == EVP_PKEY_MO_DECRYPT) { result = EVP_DecryptInit_ex(m_decodeCTX, EVP_aes_256_cbc(), NULL, key, (uchar*)iVector.constData()); } if (result == 0) { qWarning("EVP is not initialized!"); return false; } return true; } QByteArray AesInterface::encrypt(const QByteArray &plainData, const QByteArray &password) { if (!init(EVP_PKEY_MO_ENCRYPT, password)) { m_ok = false; return plainData; } // max ciphertext len for a n bytes of plaintext is n + AES_BLOCK_SIZE -1 bytes int dataLength = plainData.size(); int cipherlength = dataLength + AES_BLOCK_SIZE; int finalLength = 0; uchar* ciphertext = (uchar*)malloc(cipherlength); // allows reusing of 'm_encodeCTX' for multiple encryption cycles EVP_EncryptInit_ex(m_encodeCTX, NULL, NULL, NULL, NULL); // update ciphertext, c_len is filled with the length of ciphertext generated, // dataLength is the size of plaintext in bytes EVP_EncryptUpdate(m_encodeCTX, ciphertext, &cipherlength, (uchar*)plainData.data(), dataLength); // update ciphertext with the final remaining bytes EVP_EncryptFinal_ex(m_encodeCTX, ciphertext + cipherlength, &finalLength); dataLength = cipherlength + finalLength; QByteArray out((char*)ciphertext, dataLength); out = QByteArray::number(AesInterface::VERSION) + '$' + m_iVector.toBase64() + '$' + out.toBase64(); free(ciphertext); m_ok = true; return out; } QByteArray AesInterface::decrypt(const QByteArray &cipherData, const QByteArray &password) { m_ok = false; if (cipherData.isEmpty()) { m_ok = true; return QByteArray(); } QList cipherSections(cipherData.split('$')); if (cipherSections.size() != 3) { qWarning() << "Decrypt error: It seems data is corrupted"; return QByteArray(); } if (cipherSections.at(0).toInt() > AesInterface::VERSION) { - QMessageBox::information(0, tr("Warning!"), tr("Data has been encrypted with a newer version of QupZilla." - "\nPlease install latest version of QupZilla.")); + QMessageBox::information(0, tr("Warning!"), tr("Data has been encrypted with a newer version of Falkon." + "\nPlease install latest version of Falkon.")); return QByteArray(); } if (cipherSections.at(0).toInt() != 1) { qWarning() << Q_FUNC_INFO << "There is just version 1 of decoder, yet ;-)"; return QByteArray(); } if (!init(EVP_PKEY_MO_DECRYPT, password, QByteArray::fromBase64(cipherSections.at(1)))) { return QByteArray(); } QByteArray cipherArray = QByteArray::fromBase64(cipherSections.at(2)); int cipherLength = cipherArray.size(); int plainTextLength = cipherLength; int finalLength = 0; uchar* cipherText = (uchar*)cipherArray.data(); // because we have padding ON, we must allocate an extra cipher block size of memory uchar* plainText = (uchar*)malloc(plainTextLength + AES_BLOCK_SIZE); EVP_DecryptInit_ex(m_decodeCTX, NULL, NULL, NULL, NULL); EVP_DecryptUpdate(m_decodeCTX, plainText, &plainTextLength, cipherText, cipherLength); int success = EVP_DecryptFinal_ex(m_decodeCTX, plainText + plainTextLength, &finalLength); cipherLength = plainTextLength + finalLength; QByteArray result((char*)plainText, cipherLength); free(plainText); if (success != 1) { return QByteArray(); } m_ok = true; return result; } QByteArray AesInterface::passwordToHash(const QString &masterPassword) { if (!masterPassword.isEmpty()) { QByteArray result = masterPassword.toUtf8(); result = QCryptographicHash::hash(result, QCryptographicHash::Sha1) + result; result = QCryptographicHash::hash(result, QCryptographicHash::Sha1); return result.toBase64(); } else { return QByteArray(); } } QByteArray AesInterface::createRandomData(int length) { uchar* randomData = (uchar*)malloc(length); RAND_bytes(randomData, length); QByteArray data((char*)randomData, length); free(randomData); return data; } diff --git a/src/lib/tools/aesinterface.h b/src/lib/tools/aesinterface.h index c3c940c2..8ca2e578 100644 --- a/src/lib/tools/aesinterface.h +++ b/src/lib/tools/aesinterface.h @@ -1,59 +1,59 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2013-2014 S. Razi Alavizadeh * Copyright (C) 2013-2014 David Rosca * * This is based on a work by Saju Pillai * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef AESINTERFACE_H #define AESINTERFACE_H #include "qzcommon.h" #include #include #include #include -class QUPZILLA_EXPORT AesInterface : public QObject +class FALKON_EXPORT AesInterface : public QObject { Q_OBJECT public: static const int VERSION; explicit AesInterface(QObject* parent = 0); ~AesInterface(); bool isOk(); QByteArray encrypt(const QByteArray &plainData, const QByteArray &password); QByteArray decrypt(const QByteArray &cipherData, const QByteArray &password); static QByteArray passwordToHash(const QString &masterPassword); static QByteArray createRandomData(int length); private: bool init(int evpMode, const QByteArray &password, const QByteArray &iVector = QByteArray()); EVP_CIPHER_CTX* m_encodeCTX; EVP_CIPHER_CTX* m_decodeCTX; bool m_ok; QByteArray m_iVector; }; #endif //AESINTERFACE_H diff --git a/src/lib/tools/animatedwidget.cpp b/src/lib/tools/animatedwidget.cpp index a4017eba..cdae42f3 100644 --- a/src/lib/tools/animatedwidget.cpp +++ b/src/lib/tools/animatedwidget.cpp @@ -1,91 +1,91 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "animatedwidget.h" #include AnimatedWidget::AnimatedWidget(const Direction &direction, int duration, QWidget* parent) : QWidget(parent) , m_direction(direction) , m_stepHeight(0) , m_stepY(0) , m_startY(0) , m_widget(new QWidget(this)) { m_timeLine.setDuration(duration); m_timeLine.setFrameRange(0, 100); connect(&m_timeLine, SIGNAL(frameChanged(int)), this, SLOT(animateFrame(int))); setMaximumHeight(0); } void AnimatedWidget::startAnimation() { if (m_timeLine.state() == QTimeLine::Running) { return; } int shown = 0; int hidden = 0; if (m_direction == Down) { shown = 0; hidden = -m_widget->height(); } m_widget->move(QPoint(m_widget->pos().x(), hidden)); m_stepY = (hidden - shown) / 100.0; m_startY = hidden; m_stepHeight = m_widget->height() / 100.0; m_timeLine.setDirection(QTimeLine::Forward); m_timeLine.start(); } void AnimatedWidget::animateFrame(int frame) { setFixedHeight(frame * m_stepHeight); m_widget->move(pos().x(), m_startY - frame * m_stepY); } void AnimatedWidget::hide() { if (m_timeLine.state() == QTimeLine::Running) { return; } m_timeLine.setDirection(QTimeLine::Backward); m_timeLine.start(); connect(&m_timeLine, SIGNAL(finished()), this, SLOT(close())); QWidget* p = parentWidget(); if (p) { p->setFocus(); } } void AnimatedWidget::resizeEvent(QResizeEvent* event) { if (event->size().width() != m_widget->width()) { m_widget->resize(event->size().width(), m_widget->height()); } QWidget::resizeEvent(event); } diff --git a/src/lib/tools/animatedwidget.h b/src/lib/tools/animatedwidget.h index edb07017..dfab5c9e 100644 --- a/src/lib/tools/animatedwidget.h +++ b/src/lib/tools/animatedwidget.h @@ -1,56 +1,56 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef NOTIFICATION_H #define NOTIFICATION_H #include #include #include "qzcommon.h" -class QUPZILLA_EXPORT AnimatedWidget : public QWidget +class FALKON_EXPORT AnimatedWidget : public QWidget { Q_OBJECT public: enum Direction { Down, Up }; explicit AnimatedWidget(const Direction &direction = Down, int duration = 300, QWidget* parent = 0); QWidget* widget() { return m_widget; } public slots: void hide(); void startAnimation(); private slots: void animateFrame(int frame); private: void resizeEvent(QResizeEvent* e); Direction m_direction; QTimeLine m_timeLine; qreal m_stepHeight; qreal m_stepY; int m_startY; QWidget* m_widget; }; #endif // NOTIFICATION_H diff --git a/src/lib/tools/buttonbox.cpp b/src/lib/tools/buttonbox.cpp index db754f8f..8a675c57 100644 --- a/src/lib/tools/buttonbox.cpp +++ b/src/lib/tools/buttonbox.cpp @@ -1,35 +1,35 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "buttonbox.h" ButtonBox::ButtonBox(QWidget* parent) : QDialogButtonBox(parent) , m_clickedButton(QDialogButtonBox::RejectRole) { connect(this, SIGNAL(clicked(QAbstractButton*)), this, SLOT(buttonClicked(QAbstractButton*))); } void ButtonBox::buttonClicked(QAbstractButton* button) { m_clickedButton = buttonRole(button); } QDialogButtonBox::ButtonRole ButtonBox::clickedButtonRole() { return m_clickedButton; } diff --git a/src/lib/tools/buttonbox.h b/src/lib/tools/buttonbox.h index 9f78991f..ffe53a3f 100644 --- a/src/lib/tools/buttonbox.h +++ b/src/lib/tools/buttonbox.h @@ -1,46 +1,46 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef BUTTONBOX_H #define BUTTONBOX_H #include #include "qzcommon.h" class QAbstractButton; -class QUPZILLA_EXPORT ButtonBox : public QDialogButtonBox +class FALKON_EXPORT ButtonBox : public QDialogButtonBox { Q_OBJECT public: explicit ButtonBox(QWidget* parent = 0); ButtonRole clickedButtonRole(); signals: public slots: private slots: void buttonClicked(QAbstractButton* button); private: QDialogButtonBox::ButtonRole m_clickedButton; }; #endif // BUTTONBOX_H diff --git a/src/lib/tools/buttonwithmenu.cpp b/src/lib/tools/buttonwithmenu.cpp index cfddb9b1..2e6349dd 100644 --- a/src/lib/tools/buttonwithmenu.cpp +++ b/src/lib/tools/buttonwithmenu.cpp @@ -1,179 +1,179 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "buttonwithmenu.h" #include #include ButtonWithMenu::ButtonWithMenu(QWidget* parent) : ToolButton(parent) , m_menu(new QMenu(this)) { setCursor(Qt::ArrowCursor); setFocusPolicy(Qt::ClickFocus); connect(this, SIGNAL(aboutToShowMenu()), this, SLOT(generateMenu())); } void ButtonWithMenu::setCurrentItem() { if (QAction* action = qobject_cast(sender())) { setCurrentItem(action->data().value()); } } void ButtonWithMenu::clearItems() { m_menu->clear(); m_items.clear(); } void ButtonWithMenu::selectNextItem() { int index = m_items.indexOf(m_currentItem) + 1; if (index < m_items.size()) { setCurrentIndex(index); } } void ButtonWithMenu::selectPreviousItem() { int index = m_items.indexOf(m_currentItem) - 1; if (index >= 0) { setCurrentIndex(index); } } void ButtonWithMenu::addItem(const Item &item) { m_items.append(item); if (m_items.count() == 1) { setCurrentItem(item); } emit itemAdded(item); } void ButtonWithMenu::addItems(const QVector &items) { foreach (const Item &item, items) { addItem(item); } } void ButtonWithMenu::removeItem(const Item &item) { int index = m_items.indexOf(item); if (index < 0) { return; } m_items.remove(index); if (m_items.count() == 0) { setIcon(QIcon()); return; } if (m_currentItem == item) { setCurrentItem(m_items.at(0)); } } void ButtonWithMenu::setCurrentItem(const Item &item, bool emitSignal) { int index = m_items.indexOf(item); if (index < 0 || m_currentItem == item) { return; } m_currentItem = item; setIcon(m_currentItem.icon); setToolTip(m_currentItem.text); if (emitSignal) { emit activeItemChanged(m_currentItem); } } void ButtonWithMenu::setCurrentIndex(int index, bool emitSignal) { setCurrentItem(m_items.at(index), emitSignal); } void ButtonWithMenu::wheelEvent(QWheelEvent* event) { m_wheelHelper.processEvent(event); while (WheelHelper::Direction direction = m_wheelHelper.takeDirection()) { switch (direction) { case WheelHelper::WheelUp: case WheelHelper::WheelLeft: selectPreviousItem(); break; case WheelHelper::WheelDown: case WheelHelper::WheelRight: selectNextItem(); break; default: break; } } event->accept(); } ButtonWithMenu::Item ButtonWithMenu::currentItem() { return m_currentItem; } QMenu* ButtonWithMenu::menu() const { return m_menu; } void ButtonWithMenu::generateMenu() { m_menu->clear(); foreach (const Item &item, m_items) { QVariant variant; variant.setValue(item); m_menu->addAction(item.icon, item.text, this, SLOT(setCurrentItem()))->setData(variant); } } void ButtonWithMenu::mousePressEvent(QMouseEvent *event) { if (parentWidget() && parentWidget()->parentWidget()) { emit aboutToShowMenu(); QWidget *w = parentWidget()->parentWidget(); m_menu->popup(w->mapToGlobal(w->rect().bottomLeft())); } ToolButton::mousePressEvent(event); } ButtonWithMenu::~ButtonWithMenu() { } diff --git a/src/lib/tools/buttonwithmenu.h b/src/lib/tools/buttonwithmenu.h index 9d1025b6..612cbf2c 100644 --- a/src/lib/tools/buttonwithmenu.h +++ b/src/lib/tools/buttonwithmenu.h @@ -1,99 +1,99 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef BUTTONWITHMENU_H #define BUTTONWITHMENU_H #include #include "toolbutton.h" #include "wheelhelper.h" // Only to be used in WebSearchBar class ButtonWithMenu : public ToolButton { Q_OBJECT public: struct Item { QString text; QIcon icon; QVariant userData; Item(const QString &a = QString(), const QIcon &b = QIcon()) { text = a; icon = b; } bool operator==(const Item &a) { return (a.text == text) && (a.icon.pixmap(16).toImage() == icon.pixmap(16).toImage()); } bool isEmpty() { return (text.isEmpty() && icon.isNull()); } void clear() { text = QString(); icon = QIcon(); userData = QVariant(); } }; explicit ButtonWithMenu(QWidget* parent = 0); ~ButtonWithMenu(); void addItem(const Item &item); void addItems(const QVector &items); void removeItem(const Item &item); void setCurrentItem(const Item &item, bool emitSignal = true); void setCurrentIndex(int index, bool emitSignal = true); Item currentItem(); QVector allItems() { return m_items; } QMenu* menu() const; signals: void activeItemChanged(const ButtonWithMenu::Item &item); void itemAdded(const ButtonWithMenu::Item &item); void itemRemoved(const ButtonWithMenu::Item &item); public slots: void clearItems(); void selectNextItem(); void selectPreviousItem(); private slots: void setCurrentItem(); void generateMenu(); private: void mousePressEvent(QMouseEvent *event); void wheelEvent(QWheelEvent* event); QMenu* m_menu; QVector m_items; Item m_currentItem; WheelHelper m_wheelHelper; }; // Hint to QVector to use std::realloc on item moving Q_DECLARE_TYPEINFO(ButtonWithMenu::Item, Q_MOVABLE_TYPE); Q_DECLARE_METATYPE(ButtonWithMenu::Item) #endif // BUTTONWITHMENU_H diff --git a/src/lib/tools/certificateinfowidget.cpp b/src/lib/tools/certificateinfowidget.cpp index 6ed0b487..cb0a92db 100644 --- a/src/lib/tools/certificateinfowidget.cpp +++ b/src/lib/tools/certificateinfowidget.cpp @@ -1,340 +1,340 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "certificateinfowidget.h" #include "ui_certificateinfowidget.h" #include "mainapplication.h" #include "qztools.h" #include #include QString CertificateInfoWidget::certificateItemText(const QSslCertificate &cert) { QString commonName = cert.subjectInfo(QSslCertificate::CommonName).isEmpty() ? QString() : cert.subjectInfo(QSslCertificate::CommonName).at(0); QString organization = cert.subjectInfo(QSslCertificate::Organization).isEmpty() ? QString() : cert.subjectInfo(QSslCertificate::Organization).at(0); if (commonName.isEmpty()) { return clearCertSpecialSymbols(organization); } return clearCertSpecialSymbols(commonName); } QString CertificateInfoWidget::clearCertSpecialSymbols(const QString &string) { QString n = string.toHtmlEscaped(); if (!n.contains(QLatin1String("\\"))) { return n; } // Credits to http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/176679?help-en n.replace(QLatin1String("\\xC3\\x80"), QLatin1String("A")); n.replace(QLatin1String("\\xC3\\x81"), QLatin1String("A")); n.replace(QLatin1String("\\xC3\\x82"), QLatin1String("A")); n.replace(QLatin1String("\\xC3\\x83"), QLatin1String("A")); n.replace(QLatin1String("\\xC3\\x84"), QLatin1String("A")); n.replace(QLatin1String("\\xC3\\x85"), QLatin1String("A")); n.replace(QLatin1String("\\xC3\\x86"), QLatin1String("AE")); n.replace(QLatin1String("\\xC3\\x87"), QLatin1String("C")); n.replace(QLatin1String("\\xC3\\x88"), QLatin1String("E")); n.replace(QLatin1String("\\xC3\\x89"), QLatin1String("E")); n.replace(QLatin1String("\\xC3\\x8A"), QLatin1String("E")); n.replace(QLatin1String("\\xC3\\x8B"), QLatin1String("E")); n.replace(QLatin1String("\\xC3\\x8C"), QLatin1String("I")); n.replace(QLatin1String("\\xC3\\x8D"), QLatin1String("I")); n.replace(QLatin1String("\\xC3\\x8E"), QLatin1String("I")); n.replace(QLatin1String("\\xC3\\x8F"), QLatin1String("I")); n.replace(QLatin1String("\\xC3\\x90"), QLatin1String("D")); n.replace(QLatin1String("\\xC3\\x91"), QLatin1String("N")); n.replace(QLatin1String("\\xC3\\x92"), QLatin1String("O")); n.replace(QLatin1String("\\xC3\\x93"), QLatin1String("O")); n.replace(QLatin1String("\\xC3\\x94"), QLatin1String("O")); n.replace(QLatin1String("\\xC3\\x95"), QLatin1String("O")); n.replace(QLatin1String("\\xC3\\x96"), QLatin1String("O")); n.replace(QLatin1String("\\xC3\\x98"), QLatin1String("O")); n.replace(QLatin1String("\\xC3\\x99"), QLatin1String("U")); n.replace(QLatin1String("\\xC3\\x9A"), QLatin1String("U")); n.replace(QLatin1String("\\xC3\\x9B"), QLatin1String("U")); n.replace(QLatin1String("\\xC3\\x9C"), QLatin1String("U")); n.replace(QLatin1String("\\xC3\\x9D"), QLatin1String("Y")); n.replace(QLatin1String("\\xC3\\x9E"), QLatin1String("P")); n.replace(QLatin1String("\\xC3\\x9F"), QLatin1String("ss")); n.replace(QLatin1String("\\xC9\\x99"), QLatin1String("e")); n.replace(QLatin1String("\\xC3\\xA0"), QLatin1String("a")); n.replace(QLatin1String("\\xC3\\xA1"), QLatin1String("a")); n.replace(QLatin1String("\\xC3\\xA2"), QLatin1String("a")); n.replace(QLatin1String("\\xC3\\xA3"), QLatin1String("a")); n.replace(QLatin1String("\\xC3\\xA4"), QLatin1String("a")); n.replace(QLatin1String("\\xC3\\xA5"), QLatin1String("a")); n.replace(QLatin1String("\\xC3\\xA6"), QLatin1String("ae")); n.replace(QLatin1String("\\xC3\\xA7"), QLatin1String("c")); n.replace(QLatin1String("\\xC3\\xA8"), QLatin1String("e")); n.replace(QLatin1String("\\xC3\\xA9"), QLatin1String("e")); n.replace(QLatin1String("\\xC3\\xAA"), QLatin1String("e")); n.replace(QLatin1String("\\xC3\\xAB"), QLatin1String("e")); n.replace(QLatin1String("\\xC3\\xAC"), QLatin1String("i")); n.replace(QLatin1String("\\xC3\\xAD"), QLatin1String("i")); n.replace(QLatin1String("\\xC3\\xAE"), QLatin1String("i")); n.replace(QLatin1String("\\xC3\\xAF"), QLatin1String("i")); n.replace(QLatin1String("\\xC3\\xB0"), QLatin1String("o")); n.replace(QLatin1String("\\xC3\\xB1"), QLatin1String("n")); n.replace(QLatin1String("\\xC3\\xB2"), QLatin1String("o")); n.replace(QLatin1String("\\xC3\\xB3"), QLatin1String("o")); n.replace(QLatin1String("\\xC3\\xB4"), QLatin1String("o")); n.replace(QLatin1String("\\xC3\\xB5"), QLatin1String("o")); n.replace(QLatin1String("\\xC3\\xB6"), QLatin1String("o")); n.replace(QLatin1String("\\xC3\\xB8"), QLatin1String("o")); n.replace(QLatin1String("\\xC3\\xB9"), QLatin1String("u")); n.replace(QLatin1String("\\xC3\\xBA"), QLatin1String("u")); n.replace(QLatin1String("\\xC3\\xBB"), QLatin1String("u")); n.replace(QLatin1String("\\xC3\\xBC"), QLatin1String("u")); n.replace(QLatin1String("\\xC3\\xBD"), QLatin1String("y")); n.replace(QLatin1String("\\xC3\\xBE"), QLatin1String("p")); n.replace(QLatin1String("\\xC3\\xBF"), QLatin1String("y")); n.replace(QLatin1String("\\xC7\\xBF"), QLatin1String("o")); n.replace(QLatin1String("\\xC4\\x80"), QLatin1String("A")); n.replace(QLatin1String("\\xC4\\x81"), QLatin1String("a")); n.replace(QLatin1String("\\xC4\\x82"), QLatin1String("A")); n.replace(QLatin1String("\\xC4\\x83"), QLatin1String("a")); n.replace(QLatin1String("\\xC4\\x84"), QLatin1String("A")); n.replace(QLatin1String("\\xC4\\x85"), QLatin1String("a")); n.replace(QLatin1String("\\xC4\\x86"), QLatin1String("C")); n.replace(QLatin1String("\\xC4\\x87"), QLatin1String("c")); n.replace(QLatin1String("\\xC4\\x88"), QLatin1String("C")); n.replace(QLatin1String("\\xC4\\x89"), QLatin1String("c")); n.replace(QLatin1String("\\xC4\\x8A"), QLatin1String("C")); n.replace(QLatin1String("\\xC4\\x8B"), QLatin1String("c")); n.replace(QLatin1String("\\xC4\\x8C"), QLatin1String("C")); n.replace(QLatin1String("\\xC4\\x8D"), QLatin1String("c")); n.replace(QLatin1String("\\xC4\\x8E"), QLatin1String("D")); n.replace(QLatin1String("\\xC4\\x8F"), QLatin1String("d")); n.replace(QLatin1String("\\xC4\\x90"), QLatin1String("D")); n.replace(QLatin1String("\\xC4\\x91"), QLatin1String("d")); n.replace(QLatin1String("\\xC4\\x92"), QLatin1String("E")); n.replace(QLatin1String("\\xC4\\x93"), QLatin1String("e")); n.replace(QLatin1String("\\xC4\\x94"), QLatin1String("E")); n.replace(QLatin1String("\\xC4\\x95"), QLatin1String("e")); n.replace(QLatin1String("\\xC4\\x96"), QLatin1String("E")); n.replace(QLatin1String("\\xC4\\x97"), QLatin1String("e")); n.replace(QLatin1String("\\xC4\\x98"), QLatin1String("E")); n.replace(QLatin1String("\\xC4\\x99"), QLatin1String("e")); n.replace(QLatin1String("\\xC4\\x9A"), QLatin1String("E")); n.replace(QLatin1String("\\xC4\\x9B"), QLatin1String("e")); n.replace(QLatin1String("\\xC4\\x9C"), QLatin1String("G")); n.replace(QLatin1String("\\xC4\\x9D"), QLatin1String("g")); n.replace(QLatin1String("\\xC4\\x9E"), QLatin1String("G")); n.replace(QLatin1String("\\xC4\\x9F"), QLatin1String("g")); n.replace(QLatin1String("\\xC4\\xA0"), QLatin1String("G")); n.replace(QLatin1String("\\xC4\\xA1"), QLatin1String("g")); n.replace(QLatin1String("\\xC4\\xA2"), QLatin1String("G")); n.replace(QLatin1String("\\xC4\\xA3"), QLatin1String("g")); n.replace(QLatin1String("\\xC4\\xA4"), QLatin1String("H")); n.replace(QLatin1String("\\xC4\\xA5"), QLatin1String("h")); n.replace(QLatin1String("\\xC4\\xA6"), QLatin1String("H")); n.replace(QLatin1String("\\xC4\\xA7"), QLatin1String("h")); n.replace(QLatin1String("\\xC4\\xA8"), QLatin1String("I")); n.replace(QLatin1String("\\xC4\\xA9"), QLatin1String("i")); n.replace(QLatin1String("\\xC4\\xAA"), QLatin1String("I")); n.replace(QLatin1String("\\xC4\\xAB"), QLatin1String("i")); n.replace(QLatin1String("\\xC4\\xAC"), QLatin1String("I")); n.replace(QLatin1String("\\xC4\\xAD"), QLatin1String("i")); n.replace(QLatin1String("\\xC4\\xAE"), QLatin1String("I")); n.replace(QLatin1String("\\xC4\\xAF"), QLatin1String("i")); n.replace(QLatin1String("\\xC4\\xB0"), QLatin1String("I")); n.replace(QLatin1String("\\xC4\\xB1"), QLatin1String("i")); n.replace(QLatin1String("\\xC4\\xB2"), QLatin1String("IJ")); n.replace(QLatin1String("\\xC4\\xB3"), QLatin1String("ij")); n.replace(QLatin1String("\\xC4\\xB4"), QLatin1String("J")); n.replace(QLatin1String("\\xC4\\xB5"), QLatin1String("j")); n.replace(QLatin1String("\\xC4\\xB6"), QLatin1String("K")); n.replace(QLatin1String("\\xC4\\xB7"), QLatin1String("k")); n.replace(QLatin1String("\\xC4\\xB8"), QLatin1String("k")); n.replace(QLatin1String("\\xC4\\xB9"), QLatin1String("L")); n.replace(QLatin1String("\\xC4\\xBA"), QLatin1String("l")); n.replace(QLatin1String("\\xC4\\xBB"), QLatin1String("L")); n.replace(QLatin1String("\\xC4\\xBC"), QLatin1String("l")); n.replace(QLatin1String("\\xC4\\xBD"), QLatin1String("L")); n.replace(QLatin1String("\\xC4\\xBE"), QLatin1String("l")); n.replace(QLatin1String("\\xC4\\xBF"), QLatin1String("L")); n.replace(QLatin1String("\\xC5\\x80"), QLatin1String("l")); n.replace(QLatin1String("\\xC5\\x81"), QLatin1String("L")); n.replace(QLatin1String("\\xC5\\x82"), QLatin1String("l")); n.replace(QLatin1String("\\xC5\\x83"), QLatin1String("N")); n.replace(QLatin1String("\\xC5\\x84"), QLatin1String("n")); n.replace(QLatin1String("\\xC5\\x85"), QLatin1String("N")); n.replace(QLatin1String("\\xC5\\x86"), QLatin1String("n")); n.replace(QLatin1String("\\xC5\\x87"), QLatin1String("N")); n.replace(QLatin1String("\\xC5\\x88"), QLatin1String("n")); n.replace(QLatin1String("\\xC5\\x89"), QLatin1String("n")); n.replace(QLatin1String("\\xC5\\x8A"), QLatin1String("N")); n.replace(QLatin1String("\\xC5\\x8B"), QLatin1String("n")); n.replace(QLatin1String("\\xC5\\x8C"), QLatin1String("O")); n.replace(QLatin1String("\\xC5\\x8D"), QLatin1String("o")); n.replace(QLatin1String("\\xC5\\x8E"), QLatin1String("O")); n.replace(QLatin1String("\\xC5\\x8F"), QLatin1String("o")); n.replace(QLatin1String("\\xC5\\x90"), QLatin1String("O")); n.replace(QLatin1String("\\xC5\\x91"), QLatin1String("o")); n.replace(QLatin1String("\\xC5\\x92"), QLatin1String("CE")); n.replace(QLatin1String("\\xC5\\x93"), QLatin1String("ce")); n.replace(QLatin1String("\\xC5\\x94"), QLatin1String("R")); n.replace(QLatin1String("\\xC5\\x95"), QLatin1String("r")); n.replace(QLatin1String("\\xC5\\x96"), QLatin1String("R")); n.replace(QLatin1String("\\xC5\\x97"), QLatin1String("r")); n.replace(QLatin1String("\\xC5\\x98"), QLatin1String("R")); n.replace(QLatin1String("\\xC5\\x99"), QLatin1String("r")); n.replace(QLatin1String("\\xC5\\x9A"), QLatin1String("S")); n.replace(QLatin1String("\\xC5\\x9B"), QLatin1String("s")); n.replace(QLatin1String("\\xC5\\x9C"), QLatin1String("S")); n.replace(QLatin1String("\\xC5\\x9D"), QLatin1String("s")); n.replace(QLatin1String("\\xC5\\x9E"), QLatin1String("S")); n.replace(QLatin1String("\\xC5\\x9F"), QLatin1String("s")); n.replace(QLatin1String("\\xC5\\xA0"), QLatin1String("S")); n.replace(QLatin1String("\\xC5\\xA1"), QLatin1String("s")); n.replace(QLatin1String("\\xC5\\xA2"), QLatin1String("T")); n.replace(QLatin1String("\\xC5\\xA3"), QLatin1String("t")); n.replace(QLatin1String("\\xC5\\xA4"), QLatin1String("T")); n.replace(QLatin1String("\\xC5\\xA5"), QLatin1String("t")); n.replace(QLatin1String("\\xC5\\xA6"), QLatin1String("T")); n.replace(QLatin1String("\\xC5\\xA7"), QLatin1String("t")); n.replace(QLatin1String("\\xC5\\xA8"), QLatin1String("U")); n.replace(QLatin1String("\\xC5\\xA9"), QLatin1String("u")); n.replace(QLatin1String("\\xC5\\xAA"), QLatin1String("U")); n.replace(QLatin1String("\\xC5\\xAB"), QLatin1String("u")); n.replace(QLatin1String("\\xC5\\xAC"), QLatin1String("U")); n.replace(QLatin1String("\\xC5\\xAD"), QLatin1String("u")); n.replace(QLatin1String("\\xC5\\xAE"), QLatin1String("U")); n.replace(QLatin1String("\\xC5\\xAF"), QLatin1String("u")); n.replace(QLatin1String("\\xC5\\xB0"), QLatin1String("U")); n.replace(QLatin1String("\\xC5\\xB1"), QLatin1String("u")); n.replace(QLatin1String("\\xC5\\xB2"), QLatin1String("U")); n.replace(QLatin1String("\\xC5\\xB3"), QLatin1String("u")); n.replace(QLatin1String("\\xC5\\xB4"), QLatin1String("W")); n.replace(QLatin1String("\\xC5\\xB5"), QLatin1String("w")); n.replace(QLatin1String("\\xC5\\xB6"), QLatin1String("Y")); n.replace(QLatin1String("\\xC5\\xB7"), QLatin1String("y")); n.replace(QLatin1String("\\xC5\\xB8"), QLatin1String("Y")); n.replace(QLatin1String("\\xC5\\xB9"), QLatin1String("Z")); n.replace(QLatin1String("\\xC5\\xBA"), QLatin1String("z")); n.replace(QLatin1String("\\xC5\\xBB"), QLatin1String("Z")); n.replace(QLatin1String("\\xC5\\xBC"), QLatin1String("z")); n.replace(QLatin1String("\\xC5\\xBD"), QLatin1String("Z")); n.replace(QLatin1String("\\xC5\\xBE"), QLatin1String("z")); n.replace(QLatin1String("\\xC6\\x8F"), QLatin1String("E")); n.replace(QLatin1String("\\xC6\\xA0"), QLatin1String("O")); n.replace(QLatin1String("\\xC6\\xA1"), QLatin1String("o")); n.replace(QLatin1String("\\xC6\\xAF"), QLatin1String("U")); n.replace(QLatin1String("\\xC6\\xB0"), QLatin1String("u")); n.replace(QLatin1String("\\xC7\\x8D"), QLatin1String("A")); n.replace(QLatin1String("\\xC7\\x8E"), QLatin1String("a")); n.replace(QLatin1String("\\xC7\\x8F"), QLatin1String("I")); n.replace(QLatin1String("\\xC7\\x93"), QLatin1String("U")); n.replace(QLatin1String("\\xC7\\x90"), QLatin1String("i")); n.replace(QLatin1String("\\xC7\\x91"), QLatin1String("O")); n.replace(QLatin1String("\\xC7\\x92"), QLatin1String("o")); n.replace(QLatin1String("\\xC7\\x97"), QLatin1String("U")); n.replace(QLatin1String("\\xC7\\x94"), QLatin1String("u")); n.replace(QLatin1String("\\xC7\\x95"), QLatin1String("U")); n.replace(QLatin1String("\\xC7\\x96"), QLatin1String("u")); n.replace(QLatin1String("\\xC7\\x9B"), QLatin1String("U")); n.replace(QLatin1String("\\xC7\\x98"), QLatin1String("u")); n.replace(QLatin1String("\\xC7\\x99"), QLatin1String("U")); n.replace(QLatin1String("\\xC7\\x9A"), QLatin1String("u")); n.replace(QLatin1String("\\xC7\\xBD"), QLatin1String("ae")); n.replace(QLatin1String("\\xC7\\x9C"), QLatin1String("u")); n.replace(QLatin1String("\\xC7\\xBB"), QLatin1String("a")); n.replace(QLatin1String("\\xC7\\xBC"), QLatin1String("AE")); n.replace(QLatin1String("\\xC7\\xBE"), QLatin1String("O")); n.replace(QLatin1String("\\xC7\\xBA"), QLatin1String("A")); n.replace(QLatin1String("\\xC2\\x82"), QLatin1String(",")); // High code comma n.replace(QLatin1String("\\xC2\\x84"), QLatin1String(",,")); // High code double comma n.replace(QLatin1String("\\xC2\\x85"), QLatin1String("...")); // Tripple dot n.replace(QLatin1String("\\xC2\\x88"), QLatin1String("^")); // High carat n.replace(QLatin1String("\\xC2\\x91"), QLatin1String("\\x27")); // Forward single quote n.replace(QLatin1String("\\xC2\\x92"), QLatin1String("\\x27")); // Reverse single quote n.replace(QLatin1String("\\xC2\\x93"), QLatin1String("\\x22")); // Forward double quote n.replace(QLatin1String("\\xC2\\x94"), QLatin1String("\\x22")); // Reverse double quote n.replace(QLatin1String("\\xC2\\x96"), QLatin1String("-")); // High hyphen n.replace(QLatin1String("\\xC2\\x97"), QLatin1String("--")); // Double hyphen n.replace(QLatin1String("\\xC2\\xA6"), QLatin1String("|")); // Split vertical bar n.replace(QLatin1String("\\xC2\\xAB"), QLatin1String("<<")); // Double less than n.replace(QLatin1String("\\xC2\\xBB"), QLatin1String(">>")); // Double greater than n.replace(QLatin1String("\\xC2\\xBC"), QLatin1String("1/4")); // one quarter n.replace(QLatin1String("\\xC2\\xBD"), QLatin1String("1/2")); // one half n.replace(QLatin1String("\\xC2\\xBE"), QLatin1String("3/4")); // three quarters n.replace(QLatin1String("\\xCA\\xBF"), QLatin1String("\\x27")); // c-single quote n.replace(QLatin1String("\\xCC\\xA8"), QString()); // modifier - under curve n.replace(QLatin1String("\\xCC\\xB1"), QString()); // modifier - under line return n; } QString CertificateInfoWidget::clearCertSpecialSymbols(const QStringList &stringList) { if (stringList.isEmpty()) { return QString(); } return clearCertSpecialSymbols(stringList.at(0)); } QString CertificateInfoWidget::showCertInfo(const QString &string) { if (string.isEmpty()) { return QObject::tr(""); } else { return clearCertSpecialSymbols(string); } } QString CertificateInfoWidget::showCertInfo(const QStringList &stringList) { if (stringList.isEmpty()) { return QString(); } return showCertInfo(stringList.at(0)); } CertificateInfoWidget::CertificateInfoWidget(const QSslCertificate &cert, QWidget* parent) : QWidget(parent) , ui(new Ui::CertificateInfoWidget) { ui->setupUi(this); //Issued to ui->issuedToCN->setText(showCertInfo(cert.subjectInfo(QSslCertificate::CommonName))); ui->issuedToO->setText(showCertInfo(cert.subjectInfo(QSslCertificate::Organization))); ui->issuedToOU->setText(showCertInfo(cert.subjectInfo(QSslCertificate::OrganizationalUnitName))); ui->issuedToSN->setText(showCertInfo(cert.serialNumber())); //Issued By ui->issuedByCN->setText(showCertInfo(cert.issuerInfo(QSslCertificate::CommonName))); ui->issuedByO->setText(showCertInfo(cert.issuerInfo(QSslCertificate::Organization))); ui->issuedByOU->setText(showCertInfo(cert.issuerInfo(QSslCertificate::OrganizationalUnitName))); //Validity QLocale locale = QLocale(mApp->currentLanguageFile()); ui->validityIssuedOn->setText(locale.toString(cert.effectiveDate(), "dddd d. MMMM yyyy")); ui->validityExpiresOn->setText(locale.toString(cert.expiryDate(), "dddd d. MMMM yyyy")); } CertificateInfoWidget::~CertificateInfoWidget() { delete ui; } diff --git a/src/lib/tools/certificateinfowidget.h b/src/lib/tools/certificateinfowidget.h index 9e5fd668..a0c78d5b 100644 --- a/src/lib/tools/certificateinfowidget.h +++ b/src/lib/tools/certificateinfowidget.h @@ -1,54 +1,54 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef CERTIFICATEINFOWIDGET_H #define CERTIFICATEINFOWIDGET_H #include #include "qzcommon.h" namespace Ui { class CertificateInfoWidget; } class QSslCertificate; -class QUPZILLA_EXPORT CertificateInfoWidget : public QWidget +class FALKON_EXPORT CertificateInfoWidget : public QWidget { public: explicit CertificateInfoWidget(const QSslCertificate &cert, QWidget* parent = 0); ~CertificateInfoWidget(); // Qt5 compatibility // QSslCertificate::subjectInfo returns: // QString in Qt 4 // QStringList in Qt 5 // static QString showCertInfo(const QString &string); static QString showCertInfo(const QStringList &stringList); static QString clearCertSpecialSymbols(const QString &string); static QString clearCertSpecialSymbols(const QStringList &stringList); static QString certificateItemText(const QSslCertificate &cert); private: Ui::CertificateInfoWidget* ui; }; #endif // CERTIFICATEINFOWIDGET_H diff --git a/src/lib/tools/clickablelabel.cpp b/src/lib/tools/clickablelabel.cpp index 3a1aaa10..56b4fbae 100644 --- a/src/lib/tools/clickablelabel.cpp +++ b/src/lib/tools/clickablelabel.cpp @@ -1,85 +1,85 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "clickablelabel.h" #include ClickableLabel::ClickableLabel(QWidget* parent) : QLabel(parent) { } QString ClickableLabel::themeIcon() const { return m_themeIcon; } void ClickableLabel::setThemeIcon(const QString &name) { m_themeIcon = name; updateIcon(); } QIcon ClickableLabel::fallbackIcon() const { return m_fallbackIcon; } void ClickableLabel::setFallbackIcon(const QIcon &fallbackIcon) { m_fallbackIcon = fallbackIcon; updateIcon(); } void ClickableLabel::updateIcon() { if (!m_themeIcon.isEmpty()) { const QIcon icon = QIcon::fromTheme(m_themeIcon); if (!icon.isNull()) { setPixmap(icon.pixmap(size())); return; } } if (!m_fallbackIcon.isNull()) setPixmap(m_fallbackIcon.pixmap(size())); } void ClickableLabel::resizeEvent(QResizeEvent *ev) { QLabel::resizeEvent(ev); updateIcon(); } void ClickableLabel::mouseReleaseEvent(QMouseEvent* ev) { if (ev->button() == Qt::LeftButton && rect().contains(ev->pos())) { if (ev->modifiers() == Qt::ControlModifier) { emit middleClicked(ev->globalPos()); } else { emit clicked(ev->globalPos()); } } else if (ev->button() == Qt::MiddleButton && rect().contains(ev->pos())) { emit middleClicked(ev->globalPos()); } else { QLabel::mouseReleaseEvent(ev); } } diff --git a/src/lib/tools/clickablelabel.h b/src/lib/tools/clickablelabel.h index 1051f10b..97e48031 100644 --- a/src/lib/tools/clickablelabel.h +++ b/src/lib/tools/clickablelabel.h @@ -1,61 +1,61 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef CLICKABLELABEL_H #define CLICKABLELABEL_H #include #include #include "qzcommon.h" class QMouseEvent; -class QUPZILLA_EXPORT ClickableLabel : public QLabel +class FALKON_EXPORT ClickableLabel : public QLabel { Q_OBJECT Q_PROPERTY(QSize fixedsize READ size WRITE setFixedSize) Q_PROPERTY(int fixedwidth READ width WRITE setFixedWidth) Q_PROPERTY(int fixedheight READ height WRITE setFixedHeight) Q_PROPERTY(QString themeIcon READ themeIcon WRITE setThemeIcon) Q_PROPERTY(QIcon fallbackIcon READ fallbackIcon WRITE setFallbackIcon) public: explicit ClickableLabel(QWidget* parent = 0); QString themeIcon() const; void setThemeIcon(const QString &name); QIcon fallbackIcon() const; void setFallbackIcon(const QIcon &fallbackIcon); signals: void clicked(QPoint); void middleClicked(QPoint); private: void updateIcon(); void resizeEvent(QResizeEvent *ev); void mouseReleaseEvent(QMouseEvent* ev); QString m_themeIcon; QIcon m_fallbackIcon; }; #endif // CLICKABLELABEL_H diff --git a/src/lib/tools/closedtabsmanager.cpp b/src/lib/tools/closedtabsmanager.cpp index ea432a18..323910c5 100644 --- a/src/lib/tools/closedtabsmanager.cpp +++ b/src/lib/tools/closedtabsmanager.cpp @@ -1,96 +1,96 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "closedtabsmanager.h" #include "webtab.h" #include "qztools.h" #include "mainapplication.h" #include #include ClosedTabsManager::ClosedTabsManager() { } void ClosedTabsManager::saveTab(WebTab* tab, int position) { if (mApp->isPrivate()) { return; } // Don't save empty tab if (tab->url().isEmpty() && tab->history()->items().count() == 0) { return; } Tab closedTab; closedTab.url = tab->url(); closedTab.title = tab->title(); closedTab.icon = tab->icon(); closedTab.position = position; closedTab.history = tab->historyData(); closedTab.zoomLevel = tab->zoomLevel(); m_closedTabs.prepend(closedTab); } bool ClosedTabsManager::isClosedTabAvailable() { return !m_closedTabs.isEmpty(); } ClosedTabsManager::Tab ClosedTabsManager::takeLastClosedTab() { Tab tab; tab.position = -1; if (m_closedTabs.count() > 0) { tab = m_closedTabs.takeFirst(); } return tab; } ClosedTabsManager::Tab ClosedTabsManager::takeTabAt(int index) { Tab tab; tab.position = -1; QLinkedList::iterator it; int i = 0; for (it = m_closedTabs.begin(); it != m_closedTabs.end(); ++it, ++i) { if (i == index) { tab = *it; m_closedTabs.erase(it); break; } } return tab; } QLinkedList ClosedTabsManager::allClosedTabs() { return m_closedTabs; } void ClosedTabsManager::clearList() { m_closedTabs.clear(); } diff --git a/src/lib/tools/closedtabsmanager.h b/src/lib/tools/closedtabsmanager.h index 5c26b66e..cceb4a01 100644 --- a/src/lib/tools/closedtabsmanager.h +++ b/src/lib/tools/closedtabsmanager.h @@ -1,68 +1,68 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef CLOSEDTABSMANAGER_H #define CLOSEDTABSMANAGER_H #include #include #include #include "qzcommon.h" class WebTab; -class QUPZILLA_EXPORT ClosedTabsManager +class FALKON_EXPORT ClosedTabsManager { public: struct Tab { QUrl url; QString title; QIcon icon; QByteArray history; int position; int zoomLevel; bool operator==(const Tab &a) const { return (a.url == url && a.history == history && a.position == position); } }; explicit ClosedTabsManager(); void saveTab(WebTab* tab, int position); bool isClosedTabAvailable(); // Takes tab that was most recently closed Tab takeLastClosedTab(); // Takes tab at given index Tab takeTabAt(int index); QLinkedList allClosedTabs(); void clearList(); private: QLinkedList m_closedTabs; }; // Hint to Qt to use std::realloc on item moving Q_DECLARE_TYPEINFO(ClosedTabsManager::Tab, Q_MOVABLE_TYPE); #endif // CLOSEDTABSMANAGER_H diff --git a/src/lib/tools/delayedfilewatcher.cpp b/src/lib/tools/delayedfilewatcher.cpp index c969c8b8..d351c8bc 100644 --- a/src/lib/tools/delayedfilewatcher.cpp +++ b/src/lib/tools/delayedfilewatcher.cpp @@ -1,60 +1,60 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2013-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "delayedfilewatcher.h" #include DelayedFileWatcher::DelayedFileWatcher(QObject* parent) : QFileSystemWatcher(parent) { init(); } DelayedFileWatcher::DelayedFileWatcher(const QStringList &paths, QObject* parent) : QFileSystemWatcher(paths, parent) { init(); } void DelayedFileWatcher::init() { connect(this, SIGNAL(directoryChanged(QString)), this, SLOT(slotDirectoryChanged(QString))); connect(this, SIGNAL(fileChanged(QString)), this, SLOT(slotFileChanged(QString))); } void DelayedFileWatcher::slotDirectoryChanged(const QString &path) { m_dirQueue.enqueue(path); QTimer::singleShot(500, this, SLOT(dequeueDirectory())); } void DelayedFileWatcher::slotFileChanged(const QString &path) { m_fileQueue.enqueue(path); QTimer::singleShot(500, this, SLOT(dequeueFile())); } void DelayedFileWatcher::dequeueDirectory() { emit delayedDirectoryChanged(m_dirQueue.dequeue()); } void DelayedFileWatcher::dequeueFile() { emit delayedFileChanged(m_fileQueue.dequeue()); } diff --git a/src/lib/tools/delayedfilewatcher.h b/src/lib/tools/delayedfilewatcher.h index 062ef0d2..499fba42 100644 --- a/src/lib/tools/delayedfilewatcher.h +++ b/src/lib/tools/delayedfilewatcher.h @@ -1,53 +1,53 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2013-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef DELAYEDFILEWATCHER_H #define DELAYEDFILEWATCHER_H #include #include #include #include "qzcommon.h" -class QUPZILLA_EXPORT DelayedFileWatcher : public QFileSystemWatcher +class FALKON_EXPORT DelayedFileWatcher : public QFileSystemWatcher { Q_OBJECT public: explicit DelayedFileWatcher(QObject* parent = 0); explicit DelayedFileWatcher(const QStringList &paths, QObject* parent = 0); signals: void delayedDirectoryChanged(const QString &path); void delayedFileChanged(const QString &path); private slots: void slotDirectoryChanged(const QString &path); void slotFileChanged(const QString &path); void dequeueDirectory(); void dequeueFile(); private: void init(); QQueue m_dirQueue; QQueue m_fileQueue; }; #endif // DELAYEDFILEWATCHER_H diff --git a/src/lib/tools/docktitlebarwidget.cpp b/src/lib/tools/docktitlebarwidget.cpp index cba0eb71..975dfd4a 100644 --- a/src/lib/tools/docktitlebarwidget.cpp +++ b/src/lib/tools/docktitlebarwidget.cpp @@ -1,39 +1,39 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "docktitlebarwidget.h" #include "iconprovider.h" DockTitleBarWidget::DockTitleBarWidget(const QString &title, QWidget* parent) : QWidget(parent) { setupUi(this); closeButton->setIcon(QIcon(IconProvider::standardIcon(QStyle::SP_DialogCloseButton).pixmap(16))); label->setText(title); connect(closeButton, SIGNAL(clicked()), parent, SLOT(close())); setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); } void DockTitleBarWidget::setTitle(const QString &title) { label->setText(title); } DockTitleBarWidget::~DockTitleBarWidget() { } diff --git a/src/lib/tools/docktitlebarwidget.h b/src/lib/tools/docktitlebarwidget.h index dd415e4f..4a6f0260 100644 --- a/src/lib/tools/docktitlebarwidget.h +++ b/src/lib/tools/docktitlebarwidget.h @@ -1,37 +1,37 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef DOCKTITLEBARWIDGET_H #define DOCKTITLEBARWIDGET_H #include #include "qzcommon.h" #include "ui_docktitlebarwidget.h" -class QUPZILLA_EXPORT DockTitleBarWidget : public QWidget, public Ui_DockTitleBarWidget +class FALKON_EXPORT DockTitleBarWidget : public QWidget, public Ui_DockTitleBarWidget { public: explicit DockTitleBarWidget(const QString &title, QWidget* parent = 0); ~DockTitleBarWidget(); void setTitle(const QString &title); private: }; #endif // DOCKTITLEBARWIDGET_H diff --git a/src/lib/tools/emptynetworkreply.cpp b/src/lib/tools/emptynetworkreply.cpp index bfe16818..2be8c94c 100644 --- a/src/lib/tools/emptynetworkreply.cpp +++ b/src/lib/tools/emptynetworkreply.cpp @@ -1,43 +1,43 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "emptynetworkreply.h" #include EmptyNetworkReply::EmptyNetworkReply(QObject* parent) : QNetworkReply(parent) { setOperation(QNetworkAccessManager::GetOperation); - setError(QNetworkReply::OperationCanceledError, QSL("QupZilla:No Error")); + setError(QNetworkReply::OperationCanceledError, QSL("Falkon:No Error")); open(QIODevice::ReadOnly); QTimer::singleShot(0, this, SLOT(delayedFinish())); } void EmptyNetworkReply::delayedFinish() { emit finished(); } qint64 EmptyNetworkReply::readData(char* data, qint64 maxSize) { Q_UNUSED(data) Q_UNUSED(maxSize) return 0; } diff --git a/src/lib/tools/emptynetworkreply.h b/src/lib/tools/emptynetworkreply.h index ad486484..923e1e29 100644 --- a/src/lib/tools/emptynetworkreply.h +++ b/src/lib/tools/emptynetworkreply.h @@ -1,39 +1,39 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef EMPTYNETWORKREPLY_H #define EMPTYNETWORKREPLY_H #include #include "qzcommon.h" -class QUPZILLA_EXPORT EmptyNetworkReply : public QNetworkReply +class FALKON_EXPORT EmptyNetworkReply : public QNetworkReply { Q_OBJECT public: explicit EmptyNetworkReply(QObject* parent = 0); private slots: void delayedFinish(); protected: qint64 readData(char* data, qint64 maxSize); void abort() { } }; #endif // EMPTYNETWORKREPLY_H diff --git a/src/lib/tools/enhancedmenu.cpp b/src/lib/tools/enhancedmenu.cpp index 6b00ba59..a06b5d65 100644 --- a/src/lib/tools/enhancedmenu.cpp +++ b/src/lib/tools/enhancedmenu.cpp @@ -1,152 +1,152 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "enhancedmenu.h" #include #include Menu::Menu(QWidget* parent) : QMenu(parent) , m_closeOnMiddleClick(false) { } Menu::Menu(const QString &title, QWidget* parent) : QMenu(title, parent) , m_closeOnMiddleClick(false) { } bool Menu::closeOnMiddleClick() const { return m_closeOnMiddleClick; } void Menu::setCloseOnMiddleClick(bool close) { m_closeOnMiddleClick = close; } void Menu::mouseReleaseEvent(QMouseEvent* e) { QAction* qact = activeAction(); Action* act = qobject_cast (qact); if (qact && qact->menu()) { Menu* m = qobject_cast (qact->menu()); if (!m) { QMenu::mouseReleaseEvent(e); return; } if (e->button() == Qt::MiddleButton || (e->button() == Qt::LeftButton && e->modifiers() == Qt::ControlModifier)) { closeAllMenus(); emit menuMiddleClicked(m); } } if (!act) { QMenu::mouseReleaseEvent(e); return; } if ((e->button() == Qt::LeftButton || e->button() == Qt::RightButton) && e->modifiers() == Qt::NoModifier) { closeAllMenus(); act->trigger(); e->accept(); } else if (e->button() == Qt::MiddleButton || (e->button() == Qt::LeftButton && e->modifiers() == Qt::ControlModifier)) { if ((e->button() == Qt::MiddleButton && m_closeOnMiddleClick) || e->button() != Qt::MiddleButton) { closeAllMenus(); } act->emitCtrlTriggered(); e->accept(); } else if (e->button() == Qt::LeftButton && e->modifiers() == Qt::ShiftModifier) { closeAllMenus(); act->emitShiftTriggered(); e->accept(); } } void Menu::keyPressEvent(QKeyEvent* e) { if (e->key() != Qt::Key_Enter && e->key() != Qt::Key_Return) { QMenu::keyPressEvent(e); return; } QAction* qact = activeAction(); Action* act = qobject_cast (qact); if (!act) { QMenu::keyPressEvent(e); return; } if (e->modifiers() == Qt::NoModifier || e->modifiers() == Qt::KeypadModifier) { closeAllMenus(); act->trigger(); e->accept(); } else if (e->modifiers() == Qt::ControlModifier) { closeAllMenus(); act->emitCtrlTriggered(); e->accept(); } else if (e->modifiers() == Qt::ShiftModifier) { closeAllMenus(); act->emitShiftTriggered(); e->accept(); } } void Menu::closeAllMenus() { QMenu* menu = this; while (menu) { menu->close(); menu = qobject_cast(QApplication::activePopupWidget()); } } Action::Action(QObject* parent) : QAction(parent) { } Action::Action(const QString &text, QObject* parent) : QAction(text, parent) { } Action::Action(const QIcon &icon, const QString &text, QObject* parent) : QAction(icon, text, parent) { } void Action::emitCtrlTriggered() { emit ctrlTriggered(); } void Action::emitShiftTriggered() { emit shiftTriggered(); } diff --git a/src/lib/tools/enhancedmenu.h b/src/lib/tools/enhancedmenu.h index b7827a15..c4556650 100644 --- a/src/lib/tools/enhancedmenu.h +++ b/src/lib/tools/enhancedmenu.h @@ -1,71 +1,71 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef ENHANCEDMENU_H #define ENHANCEDMENU_H #include #include "qzcommon.h" class Action; -class QUPZILLA_EXPORT Menu : public QMenu +class FALKON_EXPORT Menu : public QMenu { Q_OBJECT public: explicit Menu(QWidget* parent = 0); explicit Menu(const QString &title, QWidget* parent = 0); // Default is false, menu will NOT be closed on middle click bool closeOnMiddleClick() const; void setCloseOnMiddleClick(bool close); signals: void menuMiddleClicked(Menu*); public slots: private: void mouseReleaseEvent(QMouseEvent* e); void keyPressEvent(QKeyEvent* e); void closeAllMenus(); bool m_closeOnMiddleClick; }; -class QUPZILLA_EXPORT Action : public QAction +class FALKON_EXPORT Action : public QAction { Q_OBJECT public: explicit Action(QObject* parent = 0); explicit Action(const QString &text, QObject* parent = 0); explicit Action(const QIcon &icon, const QString &text, QObject* parent = 0); signals: void ctrlTriggered(); void shiftTriggered(); public slots: void emitCtrlTriggered(); void emitShiftTriggered(); }; #endif // ENHANCEDMENU_H diff --git a/src/lib/tools/focusselectlineedit.cpp b/src/lib/tools/focusselectlineedit.cpp index 0c68887a..30f7728c 100644 --- a/src/lib/tools/focusselectlineedit.cpp +++ b/src/lib/tools/focusselectlineedit.cpp @@ -1,51 +1,51 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "focusselectlineedit.h" #include FocusSelectLineEdit::FocusSelectLineEdit(QWidget* parent) : QLineEdit(parent) , m_mouseFocusReason(false) { } void FocusSelectLineEdit::setFocus() { selectAll(); QLineEdit::setFocus(); } void FocusSelectLineEdit::focusInEvent(QFocusEvent* event) { m_mouseFocusReason = event->reason() == Qt::MouseFocusReason; selectAll(); QLineEdit::focusInEvent(event); } void FocusSelectLineEdit::mousePressEvent(QMouseEvent* event) { if (m_mouseFocusReason) { m_mouseFocusReason = false; return; } QLineEdit::mousePressEvent(event); } diff --git a/src/lib/tools/focusselectlineedit.h b/src/lib/tools/focusselectlineedit.h index 92b26f12..f50abe32 100644 --- a/src/lib/tools/focusselectlineedit.h +++ b/src/lib/tools/focusselectlineedit.h @@ -1,42 +1,42 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef FOCUSSELECTLINEEDIT_H #define FOCUSSELECTLINEEDIT_H #include #include "qzcommon.h" -class QUPZILLA_EXPORT FocusSelectLineEdit : public QLineEdit +class FALKON_EXPORT FocusSelectLineEdit : public QLineEdit { Q_OBJECT public: explicit FocusSelectLineEdit(QWidget* parent = 0); public slots: void setFocus(); protected: void focusInEvent(QFocusEvent* event); void mousePressEvent(QMouseEvent* event); bool m_mouseFocusReason; }; #endif // FOCUSSELECTLINEEDIT_H diff --git a/src/lib/tools/frame.cpp b/src/lib/tools/frame.cpp index 95af2794..c9a2383d 100644 --- a/src/lib/tools/frame.cpp +++ b/src/lib/tools/frame.cpp @@ -1,33 +1,33 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "frame.h" #include Frame::Frame(QWidget* parent) : QFrame(parent) { } void Frame::mousePressEvent(QMouseEvent* event) { //If we proccess mouse events, then menu from bookmarkswidget //is going to close() with clicking in free space Q_UNUSED(event) event->accept(); } diff --git a/src/lib/tools/frame.h b/src/lib/tools/frame.h index f6bf1860..1a0d9be3 100644 --- a/src/lib/tools/frame.h +++ b/src/lib/tools/frame.h @@ -1,35 +1,35 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef FRAME_H #define FRAME_H #include #include "qzcommon.h" -class QUPZILLA_EXPORT Frame : public QFrame +class FALKON_EXPORT Frame : public QFrame { public: explicit Frame(QWidget* parent = 0); private: void mousePressEvent(QMouseEvent* event); }; #endif // FRAME_H diff --git a/src/lib/tools/headerview.cpp b/src/lib/tools/headerview.cpp index 73bb49c4..5ace75c2 100644 --- a/src/lib/tools/headerview.cpp +++ b/src/lib/tools/headerview.cpp @@ -1,95 +1,95 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "headerview.h" #include #include HeaderView::HeaderView(QAbstractItemView* parent) : QHeaderView(Qt::Horizontal, parent) , m_parent(parent) , m_menu(0) , m_resizeOnShow(false) { setSectionsMovable(true); setStretchLastSection(true); setDefaultAlignment(Qt::AlignLeft); setMinimumSectionSize(60); } void HeaderView::setDefaultSectionSizes(const QList &sizes) { m_sectionSizes = sizes; } QList HeaderView::defaultSectionSizes() const { return m_sectionSizes; } bool HeaderView::restoreState(const QByteArray &state) { m_resizeOnShow = !QHeaderView::restoreState(state); return !m_resizeOnShow; } void HeaderView::showEvent(QShowEvent* event) { if (m_resizeOnShow) { for (int i = 0; i < m_sectionSizes.count(); ++i) { int size = m_parent->width() * m_sectionSizes.at(i); resizeSection(i, size); } } QHeaderView::showEvent(event); } void HeaderView::contextMenuEvent(QContextMenuEvent* event) { if (!m_menu) { m_menu = new QMenu(this); for (int i = 0; i < count(); ++i) { QAction* act = new QAction(model()->headerData(i, Qt::Horizontal).toString(), m_menu); act->setCheckable(true); act->setData(i); connect(act, SIGNAL(triggered()), this, SLOT(toggleSectionVisibility())); m_menu->addAction(act); } } for (int i = 0; i < m_menu->actions().count(); ++i) { QAction* act = m_menu->actions().at(i); act->setEnabled(i > 0); act->setChecked(!isSectionHidden(i)); } m_menu->popup(event->globalPos()); } void HeaderView::toggleSectionVisibility() { if (QAction* act = qobject_cast(sender())) { int index = act->data().toInt(); setSectionHidden(index, !isSectionHidden(index)); } } diff --git a/src/lib/tools/headerview.h b/src/lib/tools/headerview.h index 9290957b..691a19df 100644 --- a/src/lib/tools/headerview.h +++ b/src/lib/tools/headerview.h @@ -1,53 +1,53 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef HEADERVIEW_H #define HEADERVIEW_H #include class QContextMenuEvent; #include "qzcommon.h" -class QUPZILLA_EXPORT HeaderView : public QHeaderView +class FALKON_EXPORT HeaderView : public QHeaderView { Q_OBJECT public: explicit HeaderView(QAbstractItemView* parent); void setDefaultSectionSizes(const QList &sizes); QList defaultSectionSizes() const; bool restoreState(const QByteArray &state); private slots: void toggleSectionVisibility(); private: void showEvent(QShowEvent* event); void contextMenuEvent(QContextMenuEvent* event); QAbstractItemView* m_parent; QMenu* m_menu; bool m_resizeOnShow; QList m_sectionSizes; QByteArray m_restoreData; }; #endif // HEADERVIEW_H diff --git a/src/lib/tools/horizontallistwidget.cpp b/src/lib/tools/horizontallistwidget.cpp index 9dec53c5..8a2c440b 100644 --- a/src/lib/tools/horizontallistwidget.cpp +++ b/src/lib/tools/horizontallistwidget.cpp @@ -1,61 +1,61 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2013-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "horizontallistwidget.h" #include HorizontalListWidget::HorizontalListWidget(QWidget* parent) : QListWidget(parent) , m_mouseDown(false) { setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setMovement(QListView::Static); setResizeMode(QListView::Adjust); setViewMode(QListView::IconMode); setSelectionRectVisible(false); } void HorizontalListWidget::mousePressEvent(QMouseEvent* event) { m_mouseDown = true; QListWidget::mousePressEvent(event); } void HorizontalListWidget::mouseMoveEvent(QMouseEvent* event) { if (!itemAt(event->pos())) { // Don't unselect item so it ends up with no item selected return; } QListWidget::mouseMoveEvent(event); } void HorizontalListWidget::mouseReleaseEvent(QMouseEvent* event) { m_mouseDown = false; QListWidget::mouseReleaseEvent(event); } void HorizontalListWidget::wheelEvent(QWheelEvent* event) { // As this is just Horizontal ListWidget, disable wheel scrolling completely Q_UNUSED(event) } diff --git a/src/lib/tools/horizontallistwidget.h b/src/lib/tools/horizontallistwidget.h index 92b9ebb3..ddf2089d 100644 --- a/src/lib/tools/horizontallistwidget.h +++ b/src/lib/tools/horizontallistwidget.h @@ -1,37 +1,37 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2013-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef HORIZONTALLISTWIDGET_H #define HORIZONTALLISTWIDGET_H #include class HorizontalListWidget : public QListWidget { public: explicit HorizontalListWidget(QWidget* parent = 0); private: void mousePressEvent(QMouseEvent* event); void mouseMoveEvent(QMouseEvent* event); void mouseReleaseEvent(QMouseEvent* event); void wheelEvent(QWheelEvent* event); bool m_mouseDown; }; #endif // HORIZONTALLISTWIDGET_H diff --git a/src/lib/tools/html5permissions/html5permissionsdialog.cpp b/src/lib/tools/html5permissions/html5permissionsdialog.cpp index b80cf6e9..f79ec974 100644 --- a/src/lib/tools/html5permissions/html5permissionsdialog.cpp +++ b/src/lib/tools/html5permissions/html5permissionsdialog.cpp @@ -1,169 +1,169 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2013-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "html5permissionsdialog.h" #include "ui_html5permissionsdialog.h" #include "settings.h" #include "mainapplication.h" #include "html5permissionsmanager.h" HTML5PermissionsDialog::HTML5PermissionsDialog(QWidget* parent) : QDialog(parent) , ui(new Ui::HTML5PermissionsDialog) { setAttribute(Qt::WA_DeleteOnClose); ui->setupUi(this); loadSettings(); ui->treeWidget->header()->resizeSection(0, 220); connect(ui->remove, &QPushButton::clicked, this, &HTML5PermissionsDialog::removeEntry); connect(ui->feature, SIGNAL(currentIndexChanged(int)), this, SLOT(featureIndexChanged())); connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &HTML5PermissionsDialog::saveSettings); showFeaturePermissions(currentFeature()); } HTML5PermissionsDialog::~HTML5PermissionsDialog() { delete ui; } void HTML5PermissionsDialog::showFeaturePermissions(QWebEnginePage::Feature feature) { if (!m_granted.contains(feature) || !m_denied.contains(feature)) { return; } ui->treeWidget->clear(); foreach (const QString &site, m_granted.value(feature)) { QTreeWidgetItem* item = new QTreeWidgetItem(ui->treeWidget); item->setText(0, site); item->setText(1, tr("Allow")); item->setData(0, Qt::UserRole + 10, Allow); ui->treeWidget->addTopLevelItem(item); } foreach (const QString &site, m_denied.value(feature)) { QTreeWidgetItem* item = new QTreeWidgetItem(ui->treeWidget); item->setText(0, site); item->setText(1, tr("Deny")); item->setData(0, Qt::UserRole + 10, Deny); ui->treeWidget->addTopLevelItem(item); } } void HTML5PermissionsDialog::featureIndexChanged() { showFeaturePermissions(currentFeature()); } void HTML5PermissionsDialog::removeEntry() { QTreeWidgetItem* item = ui->treeWidget->currentItem(); if (!item) { return; } Role role = static_cast(item->data(0, Qt::UserRole + 10).toInt()); const QString origin = item->text(0); if (role == Allow) m_granted[currentFeature()].removeOne(origin); else m_denied[currentFeature()].removeOne(origin); delete item; } QWebEnginePage::Feature HTML5PermissionsDialog::currentFeature() const { switch (ui->feature->currentIndex()) { case 0: return QWebEnginePage::Notifications; case 1: return QWebEnginePage::Geolocation; case 2: return QWebEnginePage::MediaAudioCapture; case 3: return QWebEnginePage::MediaVideoCapture; case 4: return QWebEnginePage::MediaAudioVideoCapture; case 5: return QWebEnginePage::MouseLock; default: Q_UNREACHABLE(); return QWebEnginePage::Notifications; } } void HTML5PermissionsDialog::loadSettings() { Settings settings; settings.beginGroup("HTML5Notifications"); m_granted[QWebEnginePage::Notifications] = settings.value("NotificationsGranted", QStringList()).toStringList(); m_denied[QWebEnginePage::Notifications] = settings.value("NotificationsDenied", QStringList()).toStringList(); m_granted[QWebEnginePage::Geolocation] = settings.value("GeolocationGranted", QStringList()).toStringList(); m_denied[QWebEnginePage::Geolocation] = settings.value("GeolocationDenied", QStringList()).toStringList(); m_granted[QWebEnginePage::MediaAudioCapture] = settings.value("MediaAudioCaptureGranted", QStringList()).toStringList(); m_denied[QWebEnginePage::MediaAudioCapture] = settings.value("MediaAudioCaptureDenied", QStringList()).toStringList(); m_granted[QWebEnginePage::MediaVideoCapture] = settings.value("MediaVideoCaptureGranted", QStringList()).toStringList(); m_denied[QWebEnginePage::MediaVideoCapture] = settings.value("MediaVideoCaptureDenied", QStringList()).toStringList(); m_granted[QWebEnginePage::MediaAudioVideoCapture] = settings.value("MediaAudioVideoCaptureGranted", QStringList()).toStringList(); m_denied[QWebEnginePage::MediaAudioVideoCapture] = settings.value("MediaAudioVideoCaptureDenied", QStringList()).toStringList(); m_granted[QWebEnginePage::MouseLock] = settings.value("MouseLockGranted", QStringList()).toStringList(); m_denied[QWebEnginePage::MouseLock] = settings.value("MouseLockDenied", QStringList()).toStringList(); settings.endGroup(); } void HTML5PermissionsDialog::saveSettings() { Settings settings; settings.beginGroup("HTML5Notifications"); settings.setValue("NotificationsGranted", m_granted[QWebEnginePage::Notifications]); settings.setValue("NotificationsDenied", m_denied[QWebEnginePage::Notifications]); settings.setValue("GeolocationGranted", m_granted[QWebEnginePage::Geolocation]); settings.setValue("GeolocationDenied", m_denied[QWebEnginePage::Geolocation]); settings.setValue("MediaAudioCaptureGranted", m_granted[QWebEnginePage::MediaAudioCapture]); settings.setValue("MediaAudioCaptureDenied", m_denied[QWebEnginePage::MediaAudioCapture]); settings.setValue("MediaVideoCaptureGranted", m_granted[QWebEnginePage::MediaVideoCapture]); settings.setValue("MediaVideoCaptureDenied", m_denied[QWebEnginePage::MediaVideoCapture]); settings.setValue("MediaAudioVideoCaptureGranted", m_granted[QWebEnginePage::MediaAudioVideoCapture]); settings.setValue("MediaAudioVideoCaptureDenied", m_denied[QWebEnginePage::MediaAudioVideoCapture]); settings.setValue("MouseLockGranted", m_granted[QWebEnginePage::MouseLock]); settings.setValue("MouseLockDenied", m_denied[QWebEnginePage::MouseLock]); settings.endGroup(); mApp->html5PermissionsManager()->loadSettings(); } diff --git a/src/lib/tools/html5permissions/html5permissionsdialog.h b/src/lib/tools/html5permissions/html5permissionsdialog.h index 89b66542..82bae0c7 100644 --- a/src/lib/tools/html5permissions/html5permissionsdialog.h +++ b/src/lib/tools/html5permissions/html5permissionsdialog.h @@ -1,58 +1,58 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2013-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef HTML5PERMISSIONSDIALOG_H #define HTML5PERMISSIONSDIALOG_H #include #include #include namespace Ui { class HTML5PermissionsDialog; } class HTML5PermissionsDialog : public QDialog { Q_OBJECT public: explicit HTML5PermissionsDialog(QWidget* parent = 0); ~HTML5PermissionsDialog(); void showFeaturePermissions(QWebEnginePage::Feature feature); private slots: void removeEntry(); void featureIndexChanged(); void saveSettings(); private: enum Role { Allow, Deny }; void loadSettings(); QWebEnginePage::Feature currentFeature() const; Ui::HTML5PermissionsDialog* ui; QHash m_granted; QHash m_denied; }; #endif // HTML5PERMISSIONSDIALOG_H diff --git a/src/lib/tools/html5permissions/html5permissionsmanager.cpp b/src/lib/tools/html5permissions/html5permissionsmanager.cpp index 5f0a0980..fc3bec16 100644 --- a/src/lib/tools/html5permissions/html5permissionsmanager.cpp +++ b/src/lib/tools/html5permissions/html5permissionsmanager.cpp @@ -1,125 +1,125 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2013-2015 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "html5permissionsmanager.h" #include "html5permissionsnotification.h" #include "settings.h" #include "webview.h" HTML5PermissionsManager::HTML5PermissionsManager(QObject* parent) : QObject(parent) { loadSettings(); } void HTML5PermissionsManager::requestPermissions(WebPage* page, const QUrl &origin, const QWebEnginePage::Feature &feature) { if (!page) { return; } if (!m_granted.contains(feature) || !m_denied.contains(feature)) { qWarning() << "HTML5PermissionsManager: Unknown feature" << feature; return; } // Permission granted if (m_granted.value(feature).contains(origin.toString())) { page->setFeaturePermission(origin, feature, QWebEnginePage::PermissionGrantedByUser); return; } // Permission denied if (m_denied.value(feature).contains(origin.toString())) { page->setFeaturePermission(origin, feature, QWebEnginePage::PermissionDeniedByUser); return; } // Ask user for permission HTML5PermissionsNotification* notif = new HTML5PermissionsNotification(origin, page, feature); page->view()->addNotification(notif); } void HTML5PermissionsManager::rememberPermissions(const QUrl &origin, const QWebEnginePage::Feature &feature, const QWebEnginePage::PermissionPolicy &policy) { if (origin.isEmpty()) { return; } if (policy == QWebEnginePage::PermissionGrantedByUser) { m_granted[feature].append(origin.toString()); } else { m_denied[feature].append(origin.toString()); } saveSettings(); } void HTML5PermissionsManager::loadSettings() { Settings settings; settings.beginGroup("HTML5Notifications"); m_granted[QWebEnginePage::Notifications] = settings.value("NotificationsGranted", QStringList()).toStringList(); m_denied[QWebEnginePage::Notifications] = settings.value("NotificationsDenied", QStringList()).toStringList(); m_granted[QWebEnginePage::Geolocation] = settings.value("GeolocationGranted", QStringList()).toStringList(); m_denied[QWebEnginePage::Geolocation] = settings.value("GeolocationDenied", QStringList()).toStringList(); m_granted[QWebEnginePage::MediaAudioCapture] = settings.value("MediaAudioCaptureGranted", QStringList()).toStringList(); m_denied[QWebEnginePage::MediaAudioCapture] = settings.value("MediaAudioCaptureDenied", QStringList()).toStringList(); m_granted[QWebEnginePage::MediaVideoCapture] = settings.value("MediaVideoCaptureGranted", QStringList()).toStringList(); m_denied[QWebEnginePage::MediaVideoCapture] = settings.value("MediaVideoCaptureDenied", QStringList()).toStringList(); m_granted[QWebEnginePage::MediaAudioVideoCapture] = settings.value("MediaAudioVideoCaptureGranted", QStringList()).toStringList(); m_denied[QWebEnginePage::MediaAudioVideoCapture] = settings.value("MediaAudioVideoCaptureDenied", QStringList()).toStringList(); m_granted[QWebEnginePage::MouseLock] = settings.value("MouseLockGranted", QStringList()).toStringList(); m_denied[QWebEnginePage::MouseLock] = settings.value("MouseLockDenied", QStringList()).toStringList(); settings.endGroup(); } void HTML5PermissionsManager::saveSettings() { Settings settings; settings.beginGroup("HTML5Notifications"); settings.setValue("NotificationsGranted", m_granted[QWebEnginePage::Notifications]); settings.setValue("NotificationsDenied", m_denied[QWebEnginePage::Notifications]); settings.setValue("GeolocationGranted", m_granted[QWebEnginePage::Geolocation]); settings.setValue("GeolocationDenied", m_denied[QWebEnginePage::Geolocation]); settings.setValue("MediaAudioCaptureGranted", m_granted[QWebEnginePage::MediaAudioCapture]); settings.setValue("MediaAudioCaptureDenied", m_denied[QWebEnginePage::MediaAudioCapture]); settings.setValue("MediaVideoCaptureGranted", m_granted[QWebEnginePage::MediaVideoCapture]); settings.setValue("MediaVideoCaptureDenied", m_denied[QWebEnginePage::MediaVideoCapture]); settings.setValue("MediaAudioVideoCaptureGranted", m_granted[QWebEnginePage::MediaAudioVideoCapture]); settings.setValue("MediaAudioVideoCaptureDenied", m_denied[QWebEnginePage::MediaAudioVideoCapture]); settings.setValue("MouseLockGranted", m_granted[QWebEnginePage::MouseLock]); settings.setValue("MouseLockDenied", m_denied[QWebEnginePage::MouseLock]); settings.endGroup(); } diff --git a/src/lib/tools/html5permissions/html5permissionsmanager.h b/src/lib/tools/html5permissions/html5permissionsmanager.h index 1854a187..417f297c 100644 --- a/src/lib/tools/html5permissions/html5permissionsmanager.h +++ b/src/lib/tools/html5permissions/html5permissionsmanager.h @@ -1,48 +1,48 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2013-2015 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef HTML5PERMISSIONSMANAGER_H #define HTML5PERMISSIONSMANAGER_H #include #include #include "qzcommon.h" #include "webpage.h" class QUrl; class WebPage; -class QUPZILLA_EXPORT HTML5PermissionsManager : public QObject +class FALKON_EXPORT HTML5PermissionsManager : public QObject { public: explicit HTML5PermissionsManager(QObject* parent); void requestPermissions(WebPage* page, const QUrl &origin, const QWebEnginePage::Feature &feature); void rememberPermissions(const QUrl &origin, const QWebEnginePage::Feature &feature, const QWebEnginePage::PermissionPolicy &policy); void loadSettings(); private: void saveSettings(); QHash m_granted; QHash m_denied; }; #endif // HTML5PERMISSIONSMANAGER_H diff --git a/src/lib/tools/html5permissions/html5permissionsnotification.cpp b/src/lib/tools/html5permissions/html5permissionsnotification.cpp index 7ccb90e7..ee08b8d0 100644 --- a/src/lib/tools/html5permissions/html5permissionsnotification.cpp +++ b/src/lib/tools/html5permissions/html5permissionsnotification.cpp @@ -1,126 +1,126 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2013-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "ui_html5permissionsnotification.h" #include "html5permissionsnotification.h" #include "html5permissionsmanager.h" #include "mainapplication.h" #include "iconprovider.h" #include #include HTML5PermissionsNotification::HTML5PermissionsNotification(const QUrl &origin, QWebEnginePage* page, const QWebEnginePage::Feature &feature) : AnimatedWidget(AnimatedWidget::Down, 300, 0) , ui(new Ui::HTML5PermissionsNotification) , m_origin(origin) , m_page(page) , m_feature(feature) { setAutoFillBackground(true); ui->setupUi(widget()); ui->close->setIcon(IconProvider::standardIcon(QStyle::SP_DialogCloseButton)); const QString site = m_origin.host().isEmpty() ? tr("this site") : QString("%1").arg(m_origin.host()); switch (feature) { case QWebEnginePage::Notifications: ui->textLabel->setText(tr("Allow %1 to show desktop notifications?").arg(site)); break; case QWebEnginePage::Geolocation: ui->textLabel->setText(tr("Allow %1 to locate your position?").arg(site)); break; case QWebEnginePage::MediaAudioCapture: ui->textLabel->setText(tr("Allow %1 to use your microphone?").arg(site)); break; case QWebEnginePage::MediaVideoCapture: ui->textLabel->setText(tr("Allow %1 to use your camera?").arg(site)); break; case QWebEnginePage::MediaAudioVideoCapture: ui->textLabel->setText(tr("Allow %1 to use your microphone and camera?").arg(site)); break; case QWebEnginePage::MouseLock: ui->textLabel->setText(tr("Allow %1 to hide your pointer?").arg(site)); break; default: qWarning() << "Unknown feature" << feature; break; } connect(ui->allow, SIGNAL(clicked()), this, SLOT(grantPermissions())); connect(ui->deny, SIGNAL(clicked()), this, SLOT(denyPermissions())); connect(ui->close, SIGNAL(clicked()), this, SLOT(denyPermissions())); connect(m_page, &QWebEnginePage::loadStarted, this, &QObject::deleteLater); connect(m_page, &QWebEnginePage::featurePermissionRequestCanceled, this, [this](const QUrl &origin, QWebEnginePage::Feature feature) { if (origin == m_origin && feature == m_feature) { deleteLater(); } }); startAnimation(); } void HTML5PermissionsNotification::grantPermissions() { if (!m_page) { return; } QTimer::singleShot(0, this, [this]() { // We need to have cursor inside view to correctly grab mouse if (m_feature == QWebEnginePage::MouseLock) { QWidget *view = m_page->view(); QCursor::setPos(view->mapToGlobal(view->rect().center())); } m_page->setFeaturePermission(m_origin, m_feature, QWebEnginePage::PermissionGrantedByUser); }); if (ui->remember->isChecked()) { mApp->html5PermissionsManager()->rememberPermissions(m_origin, m_feature, QWebEnginePage::PermissionGrantedByUser); } hide(); } void HTML5PermissionsNotification::denyPermissions() { if (!m_page) { return; } m_page->setFeaturePermission(m_origin, m_feature, QWebEnginePage::PermissionDeniedByUser); if (ui->remember->isChecked()) { mApp->html5PermissionsManager()->rememberPermissions(m_origin, m_feature, QWebEnginePage::PermissionDeniedByUser); } hide(); } HTML5PermissionsNotification::~HTML5PermissionsNotification() { delete ui; } diff --git a/src/lib/tools/html5permissions/html5permissionsnotification.h b/src/lib/tools/html5permissions/html5permissionsnotification.h index 2bf1b81a..bc6ab075 100644 --- a/src/lib/tools/html5permissions/html5permissionsnotification.h +++ b/src/lib/tools/html5permissions/html5permissionsnotification.h @@ -1,51 +1,51 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2013-2015 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef HTML5PERMISSIONSNOTIFICATION_H #define HTML5PERMISSIONSNOTIFICATION_H #include #include "animatedwidget.h" #include "webpage.h" namespace Ui { class HTML5PermissionsNotification; } class HTML5PermissionsNotification : public AnimatedWidget { Q_OBJECT public: explicit HTML5PermissionsNotification(const QUrl &origin, QWebEnginePage* page, const QWebEnginePage::Feature &feature); ~HTML5PermissionsNotification(); private slots: void grantPermissions(); void denyPermissions(); private: Ui::HTML5PermissionsNotification* ui; QUrl m_origin; QWebEnginePage* m_page; QWebEnginePage::Feature m_feature; }; #endif // HTML5PERMISSIONSNOTIFICATION_H diff --git a/src/lib/tools/iconprovider.cpp b/src/lib/tools/iconprovider.cpp index 27b5c865..94d480c6 100644 --- a/src/lib/tools/iconprovider.cpp +++ b/src/lib/tools/iconprovider.cpp @@ -1,287 +1,287 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2016 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "iconprovider.h" #include "mainapplication.h" #include "networkmanager.h" #include "sqldatabase.h" #include "autosaver.h" #include "webview.h" #include "qztools.h" #include #include #include #include Q_GLOBAL_STATIC(IconProvider, qz_icon_provider) static QByteArray encodeUrl(const QUrl &url) { return url.toEncoded(QUrl::RemoveFragment | QUrl::StripTrailingSlash); } IconProvider::IconProvider() : QWidget() { m_autoSaver = new AutoSaver(this); connect(m_autoSaver, SIGNAL(save()), this, SLOT(saveIconsToDatabase())); } void IconProvider::saveIcon(WebView* view) { // Don't save icons in private mode. if (mApp->isPrivate()) { return; } const QIcon icon = view->icon(true); if (icon.isNull()) { return; } const QStringList ignoredSchemes = { - QStringLiteral("qupzilla"), + QStringLiteral("falkon"), QStringLiteral("ftp"), QStringLiteral("file"), QStringLiteral("view-source"), QStringLiteral("data"), QStringLiteral("about") }; if (ignoredSchemes.contains(view->url().scheme())) { return; } BufferedIcon item; item.first = view->url(); item.second = icon.pixmap(16).toImage(); if (m_iconBuffer.contains(item)) { return; } m_autoSaver->changeOccurred(); m_iconBuffer.append(item); } QIcon IconProvider::bookmarkIcon() const { return QIcon::fromTheme(QSL("bookmarks"), m_bookmarkIcon); } void IconProvider::setBookmarkIcon(const QIcon &icon) { m_bookmarkIcon = icon; } QIcon IconProvider::standardIcon(QStyle::StandardPixmap icon) { switch (icon) { case QStyle::SP_MessageBoxCritical: return QIcon::fromTheme(QSL("dialog-error"), QApplication::style()->standardIcon(icon)); case QStyle::SP_MessageBoxInformation: return QIcon::fromTheme(QSL("dialog-information"), QApplication::style()->standardIcon(icon)); case QStyle::SP_MessageBoxQuestion: return QIcon::fromTheme(QSL("dialog-question"), QApplication::style()->standardIcon(icon)); case QStyle::SP_MessageBoxWarning: return QIcon::fromTheme(QSL("dialog-warning"), QApplication::style()->standardIcon(icon)); case QStyle::SP_DialogCloseButton: return QIcon::fromTheme(QSL("dialog-close"), QApplication::style()->standardIcon(icon)); case QStyle::SP_BrowserStop: return QIcon::fromTheme(QSL("process-stop"), QApplication::style()->standardIcon(icon)); case QStyle::SP_BrowserReload: return QIcon::fromTheme(QSL("view-refresh"), QApplication::style()->standardIcon(icon)); case QStyle::SP_FileDialogToParent: return QIcon::fromTheme(QSL("go-up"), QApplication::style()->standardIcon(icon)); case QStyle::SP_ArrowUp: return QIcon::fromTheme(QSL("go-up"), QApplication::style()->standardIcon(icon)); case QStyle::SP_ArrowDown: return QIcon::fromTheme(QSL("go-down"), QApplication::style()->standardIcon(icon)); case QStyle::SP_ArrowForward: if (QApplication::layoutDirection() == Qt::RightToLeft) { return QIcon::fromTheme(QSL("go-previous"), QApplication::style()->standardIcon(icon)); } return QIcon::fromTheme(QSL("go-next"), QApplication::style()->standardIcon(icon)); case QStyle::SP_ArrowBack: if (QApplication::layoutDirection() == Qt::RightToLeft) { return QIcon::fromTheme(QSL("go-next"), QApplication::style()->standardIcon(icon)); } return QIcon::fromTheme(QSL("go-previous"), QApplication::style()->standardIcon(icon)); default: return QApplication::style()->standardIcon(icon); } } QIcon IconProvider::newTabIcon() { return QIcon::fromTheme(QSL("tab-new"), QIcon(QSL(":/icons/menu/tab-new.svg"))); } QIcon IconProvider::newWindowIcon() { return QIcon::fromTheme(QSL("window-new"), QIcon(QSL(":/icons/menu/window-new.svg"))); } QIcon IconProvider::privateBrowsingIcon() { return QIcon(QSL(":/icons/menu/privatebrowsing.png")); } QIcon IconProvider::settingsIcon() { return QIcon::fromTheme(QSL("configure"), QIcon(QSL(":/icons/menu/settings.svg"))); } QIcon IconProvider::emptyWebIcon() { return QPixmap::fromImage(instance()->emptyWebImage()); } QImage IconProvider::emptyWebImage() { if (instance()->m_emptyWebImage.isNull()) { instance()->m_emptyWebImage = QIcon(QSL(":icons/other/webpage.svg")).pixmap(16).toImage(); } return instance()->m_emptyWebImage; } QIcon IconProvider::iconForUrl(const QUrl &url, bool allowNull) { return instance()->iconFromImage(imageForUrl(url, allowNull)); } QImage IconProvider::imageForUrl(const QUrl &url, bool allowNull) { if (url.path().isEmpty()) { return allowNull ? QImage() : IconProvider::emptyWebImage(); } const QByteArray encodedUrl = encodeUrl(url); foreach (const BufferedIcon &ic, instance()->m_iconBuffer) { if (encodeUrl(ic.first) == encodedUrl) { return ic.second; } } QSqlQuery query; query.prepare(QSL("SELECT icon FROM icons WHERE url GLOB ? LIMIT 1")); query.addBindValue(QString("%1*").arg(QzTools::escapeSqlGlobString(QString::fromUtf8(encodedUrl)))); SqlDatabase::instance()->exec(query); if (query.next()) { return QImage::fromData(query.value(0).toByteArray()); } return allowNull ? QImage() : IconProvider::emptyWebImage(); } QIcon IconProvider::iconForDomain(const QUrl &url, bool allowNull) { return instance()->iconFromImage(imageForDomain(url, allowNull)); } QImage IconProvider::imageForDomain(const QUrl &url, bool allowNull) { if (url.host().isEmpty()) { return allowNull ? QImage() : IconProvider::emptyWebImage(); } foreach (const BufferedIcon &ic, instance()->m_iconBuffer) { if (ic.first.host() == url.host()) { return ic.second; } } QSqlQuery query; query.prepare(QSL("SELECT icon FROM icons WHERE url GLOB ? LIMIT 1")); query.addBindValue(QString("*%1*").arg(QzTools::escapeSqlGlobString(url.host()))); query.exec(); if (query.next()) { return QImage::fromData(query.value(0).toByteArray()); } return allowNull ? QImage() : IconProvider::emptyWebImage(); } IconProvider* IconProvider::instance() { return qz_icon_provider(); } void IconProvider::saveIconsToDatabase() { foreach (const BufferedIcon &ic, m_iconBuffer) { QSqlQuery query; query.prepare("SELECT id FROM icons WHERE url = ?"); query.bindValue(0, ic.first.toEncoded(QUrl::RemoveFragment)); query.exec(); if (query.next()) { query.prepare("UPDATE icons SET icon = ? WHERE url = ?"); } else { query.prepare("INSERT INTO icons (icon, url) VALUES (?,?)"); } QByteArray ba; QBuffer buffer(&ba); buffer.open(QIODevice::WriteOnly); ic.second.save(&buffer, "PNG"); query.bindValue(0, buffer.data()); query.bindValue(1, encodeUrl(ic.first)); SqlDatabase::instance()->execAsync(query); } m_iconBuffer.clear(); } void IconProvider::clearOldIconsInDatabase() { // Delete icons for entries older than 6 months const QDateTime date = QDateTime::currentDateTime().addMonths(-6); QSqlQuery query; query.prepare(QSL("DELETE FROM icons WHERE url IN (SELECT url FROM history WHERE date < ?)")); query.addBindValue(date.toMSecsSinceEpoch()); query.exec(); query.clear(); query.exec(QSL("VACUUM")); } QIcon IconProvider::iconFromImage(const QImage &image) { return QIcon(QPixmap::fromImage(image)); } diff --git a/src/lib/tools/iconprovider.h b/src/lib/tools/iconprovider.h index 0532dc38..aa1a47f7 100644 --- a/src/lib/tools/iconprovider.h +++ b/src/lib/tools/iconprovider.h @@ -1,87 +1,87 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef ICONPROVIDER_H #define ICONPROVIDER_H #include #include #include #include #include #include "qzcommon.h" class QIcon; class WebView; class AutoSaver; // Needs to be QWidget subclass, otherwise qproperty- setting won't work -class QUPZILLA_EXPORT IconProvider : public QWidget +class FALKON_EXPORT IconProvider : public QWidget { Q_OBJECT Q_PROPERTY(QIcon bookmarkIcon READ bookmarkIcon WRITE setBookmarkIcon) public: explicit IconProvider(); void saveIcon(WebView* view); QIcon bookmarkIcon() const; void setBookmarkIcon(const QIcon &icon); // QStyle equivalent static QIcon standardIcon(QStyle::StandardPixmap icon); static QIcon newTabIcon(); static QIcon newWindowIcon(); static QIcon privateBrowsingIcon(); static QIcon settingsIcon(); // Icon for empty page static QIcon emptyWebIcon(); static QImage emptyWebImage(); // Icon for url (only available for urls in history) static QIcon iconForUrl(const QUrl &url, bool allowNull = false); static QImage imageForUrl(const QUrl &url, bool allowNull = false); // Icon for domain (only available for urls in history) static QIcon iconForDomain(const QUrl &url, bool allowNull = false); static QImage imageForDomain(const QUrl &url, bool allowNull = false); static IconProvider* instance(); public slots: void saveIconsToDatabase(); void clearOldIconsInDatabase(); private: typedef QPair BufferedIcon; QIcon iconFromImage(const QImage &image); QImage m_emptyWebImage; QIcon m_bookmarkIcon; QVector m_iconBuffer; AutoSaver* m_autoSaver; }; #endif // ICONPROVIDER_H diff --git a/src/lib/tools/listitemdelegate.cpp b/src/lib/tools/listitemdelegate.cpp index 79819fae..94dbd6f4 100644 --- a/src/lib/tools/listitemdelegate.cpp +++ b/src/lib/tools/listitemdelegate.cpp @@ -1,131 +1,131 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "listitemdelegate.h" #include "mainapplication.h" #include "proxystyle.h" #include #include ListItemDelegate::ListItemDelegate(int iconSize, QWidget* parent) : QStyledItemDelegate(parent) , m_iconSize(iconSize) , m_updateParentHeight(false) , m_uniformItemSizes(false) , m_itemHeight(0) , m_itemWidth(0) , m_padding(0) { } void ListItemDelegate::setUpdateParentHeight(bool update) { m_updateParentHeight = update; } void ListItemDelegate::setUniformItemSizes(bool uniform) { m_uniformItemSizes = uniform; } int ListItemDelegate::itemHeight() const { return m_itemHeight; } void ListItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { QStyleOptionViewItem opt = option; initStyleOption(&opt, index); const QWidget* w = opt.widget; const QStyle* style = w ? w->style() : QApplication::style(); const Qt::LayoutDirection direction = w ? w->layoutDirection() : QApplication::layoutDirection(); const QPalette::ColorRole colorRole = opt.state & QStyle::State_Selected ? QPalette::HighlightedText : QPalette::Text; QPalette::ColorGroup cg = opt.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled; if (cg == QPalette::Normal && !(opt.state & QStyle::State_Active)) { cg = QPalette::Inactive; } #ifdef Q_OS_WIN opt.palette.setColor(QPalette::All, QPalette::HighlightedText, opt.palette.color(QPalette::Active, QPalette::Text)); opt.palette.setColor(QPalette::All, QPalette::Highlight, opt.palette.base().color().darker(108)); #endif QPalette textPalette = opt.palette; textPalette.setCurrentColorGroup(cg); int topPosition = opt.rect.top() + m_padding; // Draw background opt.showDecorationSelected = true; style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, w); // Draw icon QRect iconRect(opt.rect.left() + (opt.rect.width() - m_iconSize) / 2, topPosition, m_iconSize, m_iconSize); QRect visualIconRect = style->visualRect(direction, opt.rect, iconRect); QPixmap pixmap = index.data(Qt::DecorationRole).value().pixmap(m_iconSize); painter->drawPixmap(visualIconRect, pixmap); topPosition += m_iconSize + m_padding; // Draw title const QString title = index.data(Qt::DisplayRole).toString(); const int leftTitleEdge = opt.rect.left() + m_padding; QRect titleRect(leftTitleEdge, topPosition, opt.rect.width() - 2 * m_padding, opt.fontMetrics.height()); QRect visualTitleRect = style->visualRect(direction, opt.rect, titleRect); style->drawItemText(painter, visualTitleRect, Qt::AlignCenter, textPalette, true, title, colorRole); } QSize ListItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const { if (!m_itemHeight) { QStyleOptionViewItem opt(option); initStyleOption(&opt, index); const QWidget* w = opt.widget; const QStyle* style = w ? w->style() : QApplication::style(); const int padding = style->pixelMetric(QStyle::PM_FocusFrameHMargin, 0) + 1; m_padding = padding > 5 ? padding : 5; m_itemHeight = 3 * m_padding + opt.fontMetrics.height() + m_iconSize; // Update height of parent widget QWidget* p = qobject_cast(parent()); if (p && m_updateParentHeight) { int frameWidth = p->style()->pixelMetric(QStyle::PM_DefaultFrameWidth, 0, p); p->setFixedHeight(m_itemHeight + 2 * frameWidth); } } int width = 2 * m_padding + option.fontMetrics.width(index.data(Qt::DisplayRole).toString()); width = width > (m_iconSize + 2 * m_padding) ? width : m_iconSize + 2 * m_padding; if (m_uniformItemSizes) { if (width > m_itemWidth) { m_itemWidth = width; } else { width = m_itemWidth; } } return QSize(width, m_itemHeight); } diff --git a/src/lib/tools/listitemdelegate.h b/src/lib/tools/listitemdelegate.h index f033c72b..393c62ec 100644 --- a/src/lib/tools/listitemdelegate.h +++ b/src/lib/tools/listitemdelegate.h @@ -1,48 +1,48 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef LISTITEMDELEGATE_H #define LISTITEMDELEGATE_H #include #include "qzcommon.h" -class QUPZILLA_EXPORT ListItemDelegate : public QStyledItemDelegate +class FALKON_EXPORT ListItemDelegate : public QStyledItemDelegate { public: explicit ListItemDelegate(int iconSize, QWidget* parent); void setUpdateParentHeight(bool update); void setUniformItemSizes(bool uniform); int itemHeight() const; void paint(QPainter* painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const; private: int m_iconSize; bool m_updateParentHeight; bool m_uniformItemSizes; mutable int m_itemHeight; mutable int m_itemWidth; mutable int m_padding; }; #endif // LISTITEMDELEGATE_H diff --git a/src/lib/tools/mactoolbutton.cpp b/src/lib/tools/mactoolbutton.cpp index 7e2e2c9a..f230bfbd 100644 --- a/src/lib/tools/mactoolbutton.cpp +++ b/src/lib/tools/mactoolbutton.cpp @@ -1,53 +1,53 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2013-2017 David Rosca * Copyright (C) 2013-2014 S. Razi Alavizadeh * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "mactoolbutton.h" #ifdef Q_OS_MACOS MacToolButton::MacToolButton(QWidget* parent) : QPushButton(parent) , m_autoRise(false) , m_buttonFixedSize(18, 18) { } void MacToolButton::setIconSize(const QSize &size) { QPushButton::setIconSize(size); m_buttonFixedSize = QSize(size.width() + 2, size.height() + 2); } void MacToolButton::setAutoRaise(bool enable) { m_autoRise = enable; setFlat(enable); if (enable) { setFixedSize(m_buttonFixedSize); } } bool MacToolButton::autoRaise() const { return m_autoRise; } #else MacToolButton::MacToolButton(QWidget* parent) : QToolButton(parent) { } #endif diff --git a/src/lib/tools/mactoolbutton.h b/src/lib/tools/mactoolbutton.h index a318bf32..9ac797c1 100644 --- a/src/lib/tools/mactoolbutton.h +++ b/src/lib/tools/mactoolbutton.h @@ -1,55 +1,55 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2013-2017 David Rosca * Copyright (C) 2013-2014 S. Razi Alavizadeh * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef MACTOOLBUTTON_H #define MACTOOLBUTTON_H #include "qzcommon.h" #ifdef Q_OS_MACOS #include -class QUPZILLA_EXPORT MacToolButton : public QPushButton +class FALKON_EXPORT MacToolButton : public QPushButton { Q_OBJECT Q_PROPERTY(bool autoRaise READ autoRaise WRITE setAutoRaise) public: explicit MacToolButton(QWidget* parent = 0); void setIconSize(const QSize &size); void setAutoRaise(bool enable); bool autoRaise() const; private: bool m_autoRise; QSize m_buttonFixedSize; }; #else #include -class QUPZILLA_EXPORT MacToolButton : public QToolButton +class FALKON_EXPORT MacToolButton : public QToolButton { Q_OBJECT public: explicit MacToolButton(QWidget* parent = 0); }; #endif #endif // MACTOOLBUTTON_H diff --git a/src/lib/tools/menubar.cpp b/src/lib/tools/menubar.cpp index dc4c7fd9..b129181d 100644 --- a/src/lib/tools/menubar.cpp +++ b/src/lib/tools/menubar.cpp @@ -1,40 +1,40 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2013-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "menubar.h" #include "browserwindow.h" MenuBar::MenuBar(BrowserWindow* parent) : QMenuBar(parent) , m_window(parent) { setObjectName("mainwindow-menubar"); setCursor(Qt::ArrowCursor); setContextMenuPolicy(Qt::CustomContextMenu); connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextMenuRequested(QPoint))); } void MenuBar::contextMenuRequested(const QPoint &pos) { if (!actionAt(pos)) { QMenu menu; m_window->createToolbarsMenu(&menu); menu.exec(mapToGlobal(pos)); } } diff --git a/src/lib/tools/menubar.h b/src/lib/tools/menubar.h index 93480f19..aa86d38c 100644 --- a/src/lib/tools/menubar.h +++ b/src/lib/tools/menubar.h @@ -1,41 +1,41 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2013-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef MENUBAR_H #define MENUBAR_H #include "qzcommon.h" #include class BrowserWindow; -class QUPZILLA_EXPORT MenuBar : public QMenuBar +class FALKON_EXPORT MenuBar : public QMenuBar { Q_OBJECT public: explicit MenuBar(BrowserWindow* parent); private slots: void contextMenuRequested(const QPoint &pos); private: BrowserWindow* m_window; }; #endif // MENUBAR_H diff --git a/src/lib/tools/pagethumbnailer.cpp b/src/lib/tools/pagethumbnailer.cpp index ba8d0bd1..9e0e0e99 100644 --- a/src/lib/tools/pagethumbnailer.cpp +++ b/src/lib/tools/pagethumbnailer.cpp @@ -1,111 +1,111 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "pagethumbnailer.h" #include "scripts.h" #include "webview.h" #include #include #include #include #include PageThumbnailer::PageThumbnailer(QObject* parent) : QObject(parent) , m_view(new QQuickWidget()) , m_size(QSize(450, 253) * qApp->devicePixelRatio()) , m_loadTitle(false) { m_view->setAttribute(Qt::WA_DontShowOnScreen); m_view->setSource(QUrl(QSL("qrc:data/thumbnailer.qml"))); m_view->rootContext()->setContextProperty(QSL("thumbnailer"), this); m_view->show(); } void PageThumbnailer::setSize(const QSize &size) { if (size.isValid()) { m_size = size; } } void PageThumbnailer::setUrl(const QUrl &url) { if (url.isValid()) { m_url = url; } } QUrl PageThumbnailer::url() { return m_url; } bool PageThumbnailer::loadTitle() { return m_loadTitle; } void PageThumbnailer::setLoadTitle(bool load) { m_loadTitle = load; } QString PageThumbnailer::title() { QString title = m_title.isEmpty() ? m_url.host() : m_title; if (title.isEmpty()) { title = m_url.toString(); } return title; } void PageThumbnailer::start() { if (m_view->rootObject() && WebView::isUrlValid(m_url)) { m_view->rootObject()->setProperty("url", m_url); } else { QTimer::singleShot(500, this, [this]() { emit thumbnailCreated(QPixmap()); }); } } QString PageThumbnailer::afterLoadScript() const { return Scripts::setCss(QSL("::-webkit-scrollbar{display:none;}")); } void PageThumbnailer::createThumbnail(bool status) { if (!status) { emit thumbnailCreated(QPixmap()); return; } QTimer::singleShot(1000, this, [this]() { m_title = m_view->rootObject()->property("title").toString().trimmed(); emit thumbnailCreated(QPixmap::fromImage(m_view->grabFramebuffer().scaled(m_size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation))); }); } PageThumbnailer::~PageThumbnailer() { m_view->deleteLater(); } diff --git a/src/lib/tools/pagethumbnailer.h b/src/lib/tools/pagethumbnailer.h index ffaa1b3d..ed7eaf51 100644 --- a/src/lib/tools/pagethumbnailer.h +++ b/src/lib/tools/pagethumbnailer.h @@ -1,65 +1,65 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef PAGETHUMBNAILER_H #define PAGETHUMBNAILER_H #include #include #include #include "qzcommon.h" class QQuickWidget; class QPixmap; -class QUPZILLA_EXPORT PageThumbnailer : public QObject +class FALKON_EXPORT PageThumbnailer : public QObject { Q_OBJECT public: explicit PageThumbnailer(QObject* parent = 0); ~PageThumbnailer(); void setSize(const QSize &size); void setUrl(const QUrl &url); QUrl url(); bool loadTitle(); void setLoadTitle(bool load); QString title(); void start(); signals: void thumbnailCreated(const QPixmap &); public slots: QString afterLoadScript() const; void createThumbnail(bool status); private: QQuickWidget *m_view; QSize m_size; QUrl m_url; QString m_title; bool m_loadTitle; }; #endif // PAGETHUMBNAILER_H diff --git a/src/lib/tools/progressbar.cpp b/src/lib/tools/progressbar.cpp index dc04ea70..a51ba087 100644 --- a/src/lib/tools/progressbar.cpp +++ b/src/lib/tools/progressbar.cpp @@ -1,64 +1,64 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2016 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "progressbar.h" #include #include ProgressBar::ProgressBar(QWidget* parent) : QWidget(parent) , m_value(0) , m_lastPaintedValue(-1) { setMinimumSize(130, 16); setMaximumSize(150, 16); } void ProgressBar::setValue(int value) { m_value = value; if (m_lastPaintedValue != m_value) { update(); } } void ProgressBar::initStyleOption(QStyleOptionProgressBar* option) { if (!option) { return; } option->initFrom(this); option->minimum = 0; option->maximum = 100; option->progress = m_value; option->textAlignment = Qt::AlignLeft; option->textVisible = false; } void ProgressBar::paintEvent(QPaintEvent*) { QStylePainter paint(this); QStyleOptionProgressBar opt; initStyleOption(&opt); paint.drawControl(QStyle::CE_ProgressBar, opt); m_lastPaintedValue = m_value; } diff --git a/src/lib/tools/progressbar.h b/src/lib/tools/progressbar.h index 0823ded3..e8260a43 100644 --- a/src/lib/tools/progressbar.h +++ b/src/lib/tools/progressbar.h @@ -1,47 +1,47 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef PROGRESSBAR_H #define PROGRESSBAR_H #include #include "qzcommon.h" class QStyleOptionProgressBar; -class QUPZILLA_EXPORT ProgressBar : public QWidget +class FALKON_EXPORT ProgressBar : public QWidget { Q_OBJECT public: explicit ProgressBar(QWidget* parent = 0); signals: public slots: void setValue(int value); protected: void paintEvent(QPaintEvent* e); void initStyleOption(QStyleOptionProgressBar* option); private: int m_value; int m_lastPaintedValue; }; #endif // PROGRESSBAR_H diff --git a/src/lib/tools/qzregexp.cpp b/src/lib/tools/qzregexp.cpp index 40adcc5c..473ea225 100644 --- a/src/lib/tools/qzregexp.cpp +++ b/src/lib/tools/qzregexp.cpp @@ -1,85 +1,85 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2013-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "qzregexp.h" #include "qztools.h" QzRegExp::QzRegExp() : QRegularExpression(QString(), QRegularExpression::DotMatchesEverythingOption) , m_matchedLength(-1) { } QzRegExp::QzRegExp(const QString &pattern, Qt::CaseSensitivity cs) : QRegularExpression(pattern, QRegularExpression::DotMatchesEverythingOption) , m_matchedLength(-1) { if (cs == Qt::CaseInsensitive) { setPatternOptions(patternOptions() | QRegularExpression::CaseInsensitiveOption); } } QzRegExp::QzRegExp(const QzRegExp &re) : QRegularExpression(re) , m_matchedLength(-1) { } void QzRegExp::setMinimal(bool minimal) { QRegularExpression::PatternOptions opt; if (minimal) { opt = patternOptions() | QRegularExpression::InvertedGreedinessOption; } else { opt = patternOptions() & ~QRegularExpression::InvertedGreedinessOption; } setPatternOptions(opt); } int QzRegExp::indexIn(const QString &str, int offset) const { QzRegExp* that = const_cast(this); QRegularExpressionMatch m = match(str, offset); if (!m.hasMatch()) { that->m_matchedLength = -1; that->m_capturedTexts.clear(); return -1; } that->m_matchedLength = m.capturedLength(); that->m_capturedTexts = m.capturedTexts(); return m.capturedStart(); } int QzRegExp::matchedLength() const { return m_matchedLength; } QString QzRegExp::cap(int nth) const { if (!QzTools::containsIndex(m_capturedTexts, nth)) { return QString(); } return m_capturedTexts.at(nth); } diff --git a/src/lib/tools/qzregexp.h b/src/lib/tools/qzregexp.h index 8c276d5d..3f84b513 100644 --- a/src/lib/tools/qzregexp.h +++ b/src/lib/tools/qzregexp.h @@ -1,44 +1,44 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2013-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef QZREGEXP_H #define QZREGEXP_H #include #include #include "qzcommon.h" -class QUPZILLA_EXPORT QzRegExp : public QRegularExpression +class FALKON_EXPORT QzRegExp : public QRegularExpression { public: QzRegExp(); QzRegExp(const QString &pattern, Qt::CaseSensitivity cs = Qt::CaseSensitive); QzRegExp(const QzRegExp &re); void setMinimal(bool minimal); int indexIn(const QString &str, int offset = 0) const; int matchedLength() const; QString cap(int nth = 0) const; private: QStringList m_capturedTexts; int m_matchedLength; }; #endif // QZREGEXP_H diff --git a/src/lib/tools/qztools.cpp b/src/lib/tools/qztools.cpp index 9571b392..ea64f3d8 100644 --- a/src/lib/tools/qztools.cpp +++ b/src/lib/tools/qztools.cpp @@ -1,969 +1,969 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "qztools.h" #include "datapaths.h" #include "settings.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef QZ_WS_X11 #include #include #endif #ifdef Q_OS_WIN #include #endif #ifdef Q_OS_MACOS #include #endif QByteArray QzTools::pixmapToByteArray(const QPixmap &pix) { QByteArray bytes; QBuffer buffer(&bytes); buffer.open(QIODevice::WriteOnly); if (pix.save(&buffer, "PNG")) { return buffer.buffer().toBase64(); } return QByteArray(); } QPixmap QzTools::pixmapFromByteArray(const QByteArray &data) { QPixmap image; QByteArray bArray = QByteArray::fromBase64(data); image.loadFromData(bArray); return image; } QUrl QzTools::pixmapToDataUrl(const QPixmap &pix) { const QString data(pixmapToByteArray(pix)); return data.isEmpty() ? QUrl() : QUrl(QSL("data:image/png;base64,") + data); } QPixmap QzTools::dpiAwarePixmap(const QString &path) { const QIcon icon(path); if (icon.availableSizes().isEmpty()) { return QPixmap(path); } return icon.pixmap(icon.availableSizes().at(0)); } QString QzTools::readAllFileContents(const QString &filename) { return QString::fromUtf8(readAllFileByteContents(filename)); } QByteArray QzTools::readAllFileByteContents(const QString &filename) { QFile file(filename); if (!filename.isEmpty() && file.open(QFile::ReadOnly)) { const QByteArray a = file.readAll(); file.close(); return a; } return QByteArray(); } void QzTools::centerWidgetOnScreen(QWidget* w) { const QRect screen = QApplication::desktop()->screenGeometry(); const QRect size = w->geometry(); w->move((screen.width() - size.width()) / 2, (screen.height() - size.height()) / 2); } // Very, very, very simplified QDialog::adjustPosition from qdialog.cpp void QzTools::centerWidgetToParent(QWidget* w, QWidget* parent) { if (!parent || !w) { return; } QPoint p; parent = parent->window(); QPoint pp = parent->mapToGlobal(QPoint(0, 0)); p = QPoint(pp.x() + parent->width() / 2, pp.y() + parent->height() / 2); p = QPoint(p.x() - w->width() / 2, p.y() - w->height() / 2 - 20); w->move(p); } bool QzTools::removeFile(const QString &fullFileName) { QFile f(fullFileName); if (f.exists()) { return f.remove(); } else { return false; } } void QzTools::removeDir(const QString &d) { QDir dir(d); if (dir.exists()) { const QFileInfoList list = dir.entryInfoList(); QFileInfo fi; for (int l = 0; l < list.size(); l++) { fi = list.at(l); if (fi.isDir() && fi.fileName() != QLatin1String(".") && fi.fileName() != QLatin1String("..")) { QzTools::removeDir(fi.absoluteFilePath()); } else if (fi.isFile()) { QzTools::removeFile(fi.absoluteFilePath()); } } dir.rmdir(d); } } /* Finds same part of @one in @other from the beginning */ QString QzTools::samePartOfStrings(const QString &one, const QString &other) { int maxSize = qMin(one.size(), other.size()); if (maxSize <= 0) { return QString(); } int i = 0; while (one.at(i) == other.at(i)) { i++; if (i == maxSize) { break; } } return one.left(i); } QString QzTools::urlEncodeQueryString(const QUrl &url) { QString returnString = url.toString(QUrl::RemoveQuery | QUrl::RemoveFragment); if (url.hasQuery()) { returnString += QLatin1Char('?') + url.query(QUrl::FullyEncoded); } if (url.hasFragment()) { returnString += QLatin1Char('#') + url.fragment(QUrl::FullyEncoded); } returnString.replace(QLatin1Char(' '), QLatin1String("%20")); return returnString; } QString QzTools::fromPunycode(const QString &str) { if (!str.startsWith(QL1S("xn--"))) return str; // QUrl::fromAce will only decode domains from idn whitelist const QString decoded = QUrl::fromAce(str.toUtf8() + QByteArray(".org")); return decoded.left(decoded.size() - 4); } QString QzTools::escapeSqlGlobString(QString urlString) { urlString.replace(QL1C('['), QStringLiteral("[[")); urlString.replace(QL1C(']'), QStringLiteral("[]]")); urlString.replace(QStringLiteral("[["), QStringLiteral("[[]")); urlString.replace(QL1C('*'), QStringLiteral("[*]")); urlString.replace(QL1C('?'), QStringLiteral("[?]")); return urlString; } QString QzTools::ensureUniqueFilename(const QString &name, const QString &appendFormat) { Q_ASSERT(appendFormat.contains(QL1S("%1"))); QFileInfo info(name); if (!info.exists()) return name; const QDir dir = info.absoluteDir(); const QString fileName = info.fileName(); int i = 1; while (info.exists()) { QString file = fileName; int index = file.lastIndexOf(QL1C('.')); const QString appendString = appendFormat.arg(i); if (index == -1) file.append(appendString); else file = file.left(index) + appendString + file.mid(index); info.setFile(dir, file); i++; } return info.absoluteFilePath(); } QString QzTools::getFileNameFromUrl(const QUrl &url) { QString fileName = url.toString(QUrl::RemoveFragment | QUrl::RemoveQuery | QUrl::RemoveScheme | QUrl::RemovePort); if (fileName.endsWith(QLatin1Char('/'))) { fileName = fileName.mid(0, fileName.length() - 1); } if (fileName.indexOf(QLatin1Char('/')) != -1) { int pos = fileName.lastIndexOf(QLatin1Char('/')); fileName = fileName.mid(pos); fileName.remove(QLatin1Char('/')); } fileName = filterCharsFromFilename(fileName); if (fileName.isEmpty()) { fileName = filterCharsFromFilename(url.host()); } return fileName; } QString QzTools::filterCharsFromFilename(const QString &name) { QString value = name; value.replace(QLatin1Char('/'), QLatin1Char('-')); value.remove(QLatin1Char('\\')); value.remove(QLatin1Char(':')); value.remove(QLatin1Char('*')); value.remove(QLatin1Char('?')); value.remove(QLatin1Char('"')); value.remove(QLatin1Char('<')); value.remove(QLatin1Char('>')); value.remove(QLatin1Char('|')); return value; } QString QzTools::lastPathForFileDialog(const QString &dialogName, const QString &fallbackPath) { Settings settings; settings.beginGroup("LastFileDialogsPaths"); QString path = settings.value("FileDialogs/" + dialogName).toString(); settings.endGroup(); return path.isEmpty() ? fallbackPath : path; } void QzTools::saveLastPathForFileDialog(const QString &dialogName, const QString &path) { if (path.isEmpty()) { return; } Settings settings; settings.beginGroup("LastFileDialogsPaths"); settings.setValue(dialogName, path); settings.endGroup(); } QString QzTools::alignTextToWidth(const QString &string, const QString &text, const QFontMetrics &metrics, int width) { int pos = 0; QString returnString; while (pos <= string.size()) { QString part = string.mid(pos); QString elidedLine = metrics.elidedText(part, Qt::ElideRight, width); if (elidedLine.isEmpty()) { break; } if (elidedLine.size() != part.size()) { elidedLine = elidedLine.left(elidedLine.size() - 3); } if (!returnString.isEmpty()) { returnString += text; } returnString += elidedLine; pos += elidedLine.size(); } return returnString; } QString QzTools::fileSizeToString(qint64 size) { if (size < 0) { return QObject::tr("Unknown size"); } double _size = size / 1024.0; // KB if (_size < 1000) { return QString::number(_size > 1 ? _size : 1, 'f', 0) + " " + QObject::tr("KB"); } _size /= 1024; // MB if (_size < 1000) { return QString::number(_size, 'f', 1) + " " + QObject::tr("MB"); } _size /= 1024; // GB return QString::number(_size, 'f', 2) + " " + QObject::tr("GB"); } QPixmap QzTools::createPixmapForSite(const QIcon &icon, const QString &title, const QString &url) { const QFontMetrics fontMetrics = QApplication::fontMetrics(); const int padding = 4; const int maxWidth = fontMetrics.width(title.length() > url.length() ? title : url) + 3 * padding + 16; const int width = qMin(maxWidth, 150); const int height = fontMetrics.height() * 2 + fontMetrics.leading() + 2 * padding; QPixmap pixmap(width * qApp->devicePixelRatio(), height * qApp->devicePixelRatio()); pixmap.setDevicePixelRatio(qApp->devicePixelRatio()); QPainter painter(&pixmap); painter.setRenderHint(QPainter::Antialiasing); // Draw background QPen pen(Qt::black); pen.setWidth(1); painter.setPen(pen); QPainterPath path; path.addRect(QRect(0, 0, width, height)); painter.fillPath(path, Qt::white); painter.drawPath(path); // Draw icon QRect iconRect(padding, 0, 16, height); icon.paint(&painter, iconRect); // Draw title QRect titleRect(iconRect.right() + padding, padding, width - padding - iconRect.right(), fontMetrics.height()); painter.drawText(titleRect, fontMetrics.elidedText(title, Qt::ElideRight, titleRect.width())); // Draw url QRect urlRect(titleRect.x(), titleRect.bottom() + fontMetrics.leading(), titleRect.width(), titleRect.height()); painter.setPen(QApplication::palette().color(QPalette::Link)); painter.drawText(urlRect, fontMetrics.elidedText(url, Qt::ElideRight, urlRect.width())); return pixmap; } QString QzTools::applyDirectionToPage(QString &pageContents) { QString direction = QLatin1String("ltr"); QString right_str = QLatin1String("right"); QString left_str = QLatin1String("left"); if (QApplication::isRightToLeft()) { direction = QLatin1String("rtl"); right_str = QLatin1String("left"); left_str = QLatin1String("right"); } pageContents.replace(QLatin1String("%DIRECTION%"), direction); pageContents.replace(QLatin1String("%RIGHT_STR%"), right_str); pageContents.replace(QLatin1String("%LEFT_STR%"), left_str); return pageContents; } QString QzTools::truncatedText(const QString &text, int size) { if (text.length() > size) { return text.left(size) + QL1S(".."); } return text; } // Thanks to http://www.qtcentre.org/threads/3205-Toplevel-widget-with-rounded-corners?p=17492#post17492 QRegion QzTools::roundedRect(const QRect &rect, int radius) { QRegion region; // middle and borders region += rect.adjusted(radius, 0, -radius, 0); region += rect.adjusted(0, radius, 0, -radius); // top left QRect corner(rect.topLeft(), QSize(radius * 2, radius * 2)); region += QRegion(corner, QRegion::Ellipse); // top right corner.moveTopRight(rect.topRight()); region += QRegion(corner, QRegion::Ellipse); // bottom left corner.moveBottomLeft(rect.bottomLeft()); region += QRegion(corner, QRegion::Ellipse); // bottom right corner.moveBottomRight(rect.bottomRight()); region += QRegion(corner, QRegion::Ellipse); return region; } QIcon QzTools::iconFromFileName(const QString &fileName) { static QHash iconCache; QFileInfo tempInfo(fileName); if (iconCache.contains(tempInfo.suffix())) { return iconCache.value(tempInfo.suffix()); } QFileIconProvider iconProvider; QTemporaryFile tempFile(DataPaths::path(DataPaths::Temp) + "/XXXXXX." + tempInfo.suffix()); tempFile.open(); tempInfo.setFile(tempFile.fileName()); QIcon icon(iconProvider.icon(tempInfo)); iconCache.insert(tempInfo.suffix(), icon); return icon; } QString QzTools::resolveFromPath(const QString &name) { const QString path = qgetenv("PATH").trimmed(); if (path.isEmpty()) { return QString(); } QStringList dirs = path.split(QLatin1Char(':'), QString::SkipEmptyParts); foreach (const QString &dir, dirs) { QDir d(dir); if (d.exists(name)) { return d.absoluteFilePath(name); } } return QString(); } // http://stackoverflow.com/questions/1031645/how-to-detect-utf-8-in-plain-c bool QzTools::isUtf8(const char* string) { if (!string) { return 0; } const unsigned char* bytes = (const unsigned char*)string; while (*bytes) { if ((// ASCII bytes[0] == 0x09 || bytes[0] == 0x0A || bytes[0] == 0x0D || (0x20 <= bytes[0] && bytes[0] <= 0x7F) ) ) { bytes += 1; continue; } if ((// non-overlong 2-byte (0xC2 <= bytes[0] && bytes[0] <= 0xDF) && (0x80 <= bytes[1] && bytes[1] <= 0xBF) ) ) { bytes += 2; continue; } if ((// excluding overlongs bytes[0] == 0xE0 && (0xA0 <= bytes[1] && bytes[1] <= 0xBF) && (0x80 <= bytes[2] && bytes[2] <= 0xBF) ) || (// straight 3-byte ((0xE1 <= bytes[0] && bytes[0] <= 0xEC) || bytes[0] == 0xEE || bytes[0] == 0xEF) && (0x80 <= bytes[1] && bytes[1] <= 0xBF) && (0x80 <= bytes[2] && bytes[2] <= 0xBF) ) || (// excluding surrogates bytes[0] == 0xED && (0x80 <= bytes[1] && bytes[1] <= 0x9F) && (0x80 <= bytes[2] && bytes[2] <= 0xBF) ) ) { bytes += 3; continue; } if ((// planes 1-3 bytes[0] == 0xF0 && (0x90 <= bytes[1] && bytes[1] <= 0xBF) && (0x80 <= bytes[2] && bytes[2] <= 0xBF) && (0x80 <= bytes[3] && bytes[3] <= 0xBF) ) || (// planes 4-15 (0xF1 <= bytes[0] && bytes[0] <= 0xF3) && (0x80 <= bytes[1] && bytes[1] <= 0xBF) && (0x80 <= bytes[2] && bytes[2] <= 0xBF) && (0x80 <= bytes[3] && bytes[3] <= 0xBF) ) || (// plane 16 bytes[0] == 0xF4 && (0x80 <= bytes[1] && bytes[1] <= 0x8F) && (0x80 <= bytes[2] && bytes[2] <= 0xBF) && (0x80 <= bytes[3] && bytes[3] <= 0xBF) ) ) { bytes += 4; continue; } return false; } return true; } bool QzTools::containsSpace(const QString &str) { Q_FOREACH (const QChar &c, str) { if (c.isSpace()) return true; } return false; } QString QzTools::getExistingDirectory(const QString &name, QWidget* parent, const QString &caption, const QString &dir, QFileDialog::Options options) { Settings settings; settings.beginGroup("FileDialogPaths"); QString lastDir = settings.value(name, dir).toString(); QString path = QFileDialog::getExistingDirectory(parent, caption, lastDir, options); if (!path.isEmpty()) { settings.setValue(name, QFileInfo(path).absolutePath()); } settings.endGroup(); return path; } static QString getFilename(const QString &path) { QFileInfo info(path); if (info.isFile()) { return info.fileName(); } if (info.isDir()) { return QString(); } if (info.dir().exists()) { return info.fileName(); } return QString(); } QString QzTools::getOpenFileName(const QString &name, QWidget* parent, const QString &caption, const QString &dir, const QString &filter, QString* selectedFilter, QFileDialog::Options options) { Settings settings; settings.beginGroup("FileDialogPaths"); QString lastDir = settings.value(name, QString()).toString(); QString fileName = getFilename(dir); if (lastDir.isEmpty()) { lastDir = dir; } else { lastDir.append(QDir::separator() + fileName); } QString path = QFileDialog::getOpenFileName(parent, caption, lastDir, filter, selectedFilter, options); if (!path.isEmpty()) { settings.setValue(name, QFileInfo(path).absolutePath()); } settings.endGroup(); return path; } QStringList QzTools::getOpenFileNames(const QString &name, QWidget* parent, const QString &caption, const QString &dir, const QString &filter, QString* selectedFilter, QFileDialog::Options options) { Settings settings; settings.beginGroup("FileDialogPaths"); QString lastDir = settings.value(name, QString()).toString(); QString fileName = getFilename(dir); if (lastDir.isEmpty()) { lastDir = dir; } else { lastDir.append(QDir::separator() + fileName); } QStringList paths = QFileDialog::getOpenFileNames(parent, caption, lastDir, filter, selectedFilter, options); if (!paths.isEmpty()) { settings.setValue(name, QFileInfo(paths.at(0)).absolutePath()); } settings.endGroup(); return paths; } QString QzTools::getSaveFileName(const QString &name, QWidget* parent, const QString &caption, const QString &dir, const QString &filter, QString* selectedFilter, QFileDialog::Options options) { Settings settings; settings.beginGroup("FileDialogPaths"); QString lastDir = settings.value(name, QString()).toString(); QString fileName = getFilename(dir); if (lastDir.isEmpty()) { lastDir = dir; } else { lastDir.append(QDir::separator() + fileName); } QString path = QFileDialog::getSaveFileName(parent, caption, lastDir, filter, selectedFilter, options); if (!path.isEmpty()) { settings.setValue(name, QFileInfo(path).absolutePath()); } settings.endGroup(); return path; } // Matches domain (assumes both pattern and domain not starting with dot) // pattern = domain to be matched // domain = site domain bool QzTools::matchDomain(const QString &pattern, const QString &domain) { if (pattern == domain) { return true; } if (!domain.endsWith(pattern)) { return false; } int index = domain.indexOf(pattern); return index > 0 && domain[index - 1] == QLatin1Char('.'); } QKeySequence QzTools::actionShortcut(QKeySequence shortcut, QKeySequence fallBack, QKeySequence shortcutRtl, QKeySequence fallbackRtl) { if (QApplication::isRightToLeft() && (!shortcutRtl.isEmpty() || !fallbackRtl.isEmpty())) return shortcutRtl.isEmpty() ? fallbackRtl : shortcutRtl; return shortcut.isEmpty() ? fallBack : shortcut; } static inline bool isQuote(const QChar &c) { return (c == QLatin1Char('"') || c == QLatin1Char('\'')); } // Function splits command line into arguments // eg. /usr/bin/foo -o test -b "bar bar" -s="sed sed" // => '/usr/bin/foo' '-o' 'test' '-b' 'bar bar' '-s=sed sed' QStringList QzTools::splitCommandArguments(const QString &command) { QString line = command.trimmed(); if (line.isEmpty()) { return QStringList(); } QChar SPACE(' '); QChar EQUAL('='); QChar BSLASH('\\'); QChar QUOTE('"'); QStringList r; int equalPos = -1; // Position of = in opt="value" int startPos = isQuote(line.at(0)) ? 1 : 0; bool inWord = !isQuote(line.at(0)); bool inQuote = !inWord; if (inQuote) { QUOTE = line.at(0); } const int strlen = line.length(); for (int i = 0; i < strlen; ++i) { const QChar c = line.at(i); if (inQuote && c == QUOTE && i > 0 && line.at(i - 1) != BSLASH) { QString str = line.mid(startPos, i - startPos); if (equalPos > -1) { str.remove(equalPos - startPos + 1, 1); } inQuote = false; if (!str.isEmpty()) { r.append(str); } continue; } else if (!inQuote && isQuote(c)) { inQuote = true; QUOTE = c; if (!inWord) { startPos = i + 1; } else if (i > 0 && line.at(i - 1) == EQUAL) { equalPos = i - 1; } } if (inQuote) { continue; } if (inWord && (c == SPACE || i == strlen - 1)) { int len = (i == strlen - 1) ? -1 : i - startPos; const QString str = line.mid(startPos, len); inWord = false; if (!str.isEmpty()) { r.append(str); } } else if (!inWord && c != SPACE) { inWord = true; startPos = i; } } // Unmatched quote if (inQuote) { return QStringList(); } return r; } bool QzTools::startExternalProcess(const QString &executable, const QString &args) { const QStringList arguments = splitCommandArguments(args); bool success = QProcess::startDetached(executable, arguments); if (!success) { QString info = "
  • %1%2
  • %3%4
"; info = info.arg(QObject::tr("Executable: "), executable, QObject::tr("Arguments: "), arguments.join(QLatin1String(" "))); QMessageBox::critical(0, QObject::tr("Cannot start external program"), QObject::tr("Cannot start external program! %1").arg(info)); } return success; } void QzTools::setWmClass(const QString &name, const QWidget* widget) { #ifdef QZ_WS_X11 if (QGuiApplication::platformName() != QL1S("xcb")) return; const QByteArray &nameData = name.toUtf8(); - const QByteArray &classData = QByteArrayLiteral("QupZilla"); + const QByteArray &classData = QByteArrayLiteral("Falkon"); uint32_t class_len = nameData.length() + 1 + classData.length() + 1; char *class_hint = (char*) malloc(class_len); qstrcpy(class_hint, nameData.constData()); qstrcpy(class_hint + nameData.length() + 1, classData.constData()); xcb_change_property(QX11Info::connection(), XCB_PROP_MODE_REPLACE, widget->winId(), XCB_ATOM_WM_CLASS, XCB_ATOM_STRING, 8, class_len, class_hint); free(class_hint); #else Q_UNUSED(name) Q_UNUSED(widget) #endif } QString QzTools::operatingSystem() { #ifdef Q_OS_MACOS QString str = "Mac OS X"; SInt32 majorVersion; SInt32 minorVersion; if (Gestalt(gestaltSystemVersionMajor, &majorVersion) == noErr && Gestalt(gestaltSystemVersionMinor, &minorVersion) == noErr) { str.append(QString(" %1.%2").arg(majorVersion).arg(minorVersion)); } return str; #endif #ifdef Q_OS_LINUX return "Linux"; #endif #ifdef Q_OS_BSD4 return "BSD 4.4"; #endif #ifdef Q_OS_BSDI return "BSD/OS"; #endif #ifdef Q_OS_FREEBSD return "FreeBSD"; #endif #ifdef Q_OS_HPUX return "HP-UX"; #endif #ifdef Q_OS_HURD return "GNU Hurd"; #endif #ifdef Q_OS_LYNX return "LynxOS"; #endif #ifdef Q_OS_NETBSD return "NetBSD"; #endif #ifdef Q_OS_OS2 return "OS/2"; #endif #ifdef Q_OS_OPENBSD return "OpenBSD"; #endif #ifdef Q_OS_OSF return "HP Tru64 UNIX"; #endif #ifdef Q_OS_SOLARIS return "Sun Solaris"; #endif #ifdef Q_OS_UNIXWARE return "UnixWare 7 / Open UNIX 8"; #endif #ifdef Q_OS_UNIX return "Unix"; #endif #ifdef Q_OS_HAIKU return "Haiku"; #endif #ifdef Q_OS_WIN32 QString str = "Windows"; switch (QSysInfo::windowsVersion()) { case QSysInfo::WV_NT: str.append(" NT"); break; case QSysInfo::WV_2000: str.append(" 2000"); break; case QSysInfo::WV_XP: str.append(" XP"); break; case QSysInfo::WV_2003: str.append(" XP Pro x64"); break; case QSysInfo::WV_VISTA: str.append(" Vista"); break; case QSysInfo::WV_WINDOWS7: str.append(" 7"); break; case QSysInfo::WV_WINDOWS8: str.append(" 8"); break; case QSysInfo::WV_WINDOWS8_1: str.append(" 8.1"); break; case QSysInfo::WV_WINDOWS10: str.append(" 10"); break; default: break; } return str; #endif } QString QzTools::cpuArchitecture() { return QSysInfo::currentCpuArchitecture(); } QString QzTools::operatingSystemLong() { const QString arch = cpuArchitecture(); if (arch.isEmpty()) return QzTools::operatingSystem(); return QzTools::operatingSystem() + QSL(" ") + arch; } diff --git a/src/lib/tools/qztools.h b/src/lib/tools/qztools.h index 33d5b508..59de3042 100644 --- a/src/lib/tools/qztools.h +++ b/src/lib/tools/qztools.h @@ -1,100 +1,100 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2016 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef QZTOOLS_H #define QZTOOLS_H #include #include "qzcommon.h" class QSslCertificate; class QFontMetrics; class QPixmap; class QIcon; class QWidget; class QUrl; -class QUPZILLA_EXPORT QzTools +class FALKON_EXPORT QzTools { public: static QByteArray pixmapToByteArray(const QPixmap &pix); static QPixmap pixmapFromByteArray(const QByteArray &data); static QUrl pixmapToDataUrl(const QPixmap &pix); static QPixmap dpiAwarePixmap(const QString &path); static QString readAllFileContents(const QString &filename); static QByteArray readAllFileByteContents(const QString &filename); static void centerWidgetOnScreen(QWidget* w); static void centerWidgetToParent(QWidget* w, QWidget* parent); static bool removeFile(const QString &fullFileName); static void removeDir(const QString &d); static QString samePartOfStrings(const QString &one, const QString &other); static QString urlEncodeQueryString(const QUrl &url); static QString fromPunycode(const QString &str); static QString escapeSqlGlobString(QString urlString); static QString ensureUniqueFilename(const QString &name, const QString &appendFormat = QString("(%1)")); static QString getFileNameFromUrl(const QUrl &url); static QString filterCharsFromFilename(const QString &name); static QString lastPathForFileDialog(const QString &dialogName, const QString &fallbackPath); static void saveLastPathForFileDialog(const QString &dialogName, const QString &path); static QString alignTextToWidth(const QString &string, const QString &text, const QFontMetrics &metrics, int width); static QString fileSizeToString(qint64 size); static QPixmap createPixmapForSite(const QIcon &icon, const QString &title, const QString &url); static QString applyDirectionToPage(QString &pageContents); static QString truncatedText(const QString &text, int size); static QString resolveFromPath(const QString &name); static QStringList splitCommandArguments(const QString &command); static bool startExternalProcess(const QString &executable, const QString &args); static QRegion roundedRect(const QRect &rect, int radius); static QIcon iconFromFileName(const QString &fileName); static bool isUtf8(const char* string); static bool containsSpace(const QString &str); // QFileDialog static functions that remembers last used directory static QString getExistingDirectory(const QString &name, QWidget* parent = 0, const QString &caption = QString(), const QString &dir = QString(), QFileDialog::Options options = QFileDialog::ShowDirsOnly); static QString getOpenFileName(const QString &name, QWidget* parent = 0, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString* selectedFilter = 0, QFileDialog::Options options = 0); static QStringList getOpenFileNames(const QString &name, QWidget* parent = 0, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString* selectedFilter = 0, QFileDialog::Options options = 0); static QString getSaveFileName(const QString &name, QWidget* parent = 0, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString* selectedFilter = 0, QFileDialog::Options options = 0); static bool matchDomain(const QString &pattern, const QString &domain); static QKeySequence actionShortcut(QKeySequence shortcut, QKeySequence fallBack, QKeySequence shortcutRtl = QKeySequence(), QKeySequence fallbackRtl = QKeySequence()); static QString operatingSystem(); static QString cpuArchitecture(); static QString operatingSystemLong(); static void setWmClass(const QString &name, const QWidget* widget); template static bool containsIndex(const T &container, int index) { return (index >= 0 && container.count() > index); } }; #endif // QZTOOLS_H diff --git a/src/lib/tools/removeitemfocusdelegate.cpp b/src/lib/tools/removeitemfocusdelegate.cpp index e2117ac9..491f3f7c 100644 --- a/src/lib/tools/removeitemfocusdelegate.cpp +++ b/src/lib/tools/removeitemfocusdelegate.cpp @@ -1,30 +1,30 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "removeitemfocusdelegate.h" RemoveItemFocusDelegate::RemoveItemFocusDelegate(QObject *parent) : QStyledItemDelegate(parent) { } void RemoveItemFocusDelegate::paint(QPainter* painter, const QStyleOptionViewItem & option, const QModelIndex &index) const { QStyleOptionViewItem opt = option; opt.state &= ~QStyle::State_HasFocus; QStyledItemDelegate::paint(painter, opt, index); } diff --git a/src/lib/tools/removeitemfocusdelegate.h b/src/lib/tools/removeitemfocusdelegate.h index 6700d2f6..4f91c7c3 100644 --- a/src/lib/tools/removeitemfocusdelegate.h +++ b/src/lib/tools/removeitemfocusdelegate.h @@ -1,32 +1,32 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef REMOVEITEMFOCUSDELEGATE_H #define REMOVEITEMFOCUSDELEGATE_H #include class RemoveItemFocusDelegate : public QStyledItemDelegate { public: explicit RemoveItemFocusDelegate(QObject *parent = nullptr); private: void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override; }; #endif // REMOVEITEMFOCUSDELEGATE_H diff --git a/src/lib/tools/scripts.cpp b/src/lib/tools/scripts.cpp index 42f5fb9d..6d51f1be 100644 --- a/src/lib/tools/scripts.cpp +++ b/src/lib/tools/scripts.cpp @@ -1,292 +1,292 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2015-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "scripts.h" #include "qztools.h" #include QString Scripts::setupWebChannel() { QString source = QL1S("(function() {" "%1" "" "function registerExternal(e) {" " window.external = e;" " if (window.external) {" " var event = document.createEvent('Event');" - " event.initEvent('_qupzilla_external_created', true, true);" + " event.initEvent('_falkon_external_created', true, true);" " document.dispatchEvent(event);" " }" "}" "" "if (self !== top) {" " if (top.external)" " registerExternal(top.external);" " else" - " top.document.addEventListener('_qupzilla_external_created', function() {" + " top.document.addEventListener('_falkon_external_created', function() {" " registerExternal(top.external);" " });" " return;" "}" "" "function registerWebChannel() {" " try {" " new QWebChannel(qt.webChannelTransport, function(channel) {" " registerExternal(channel.objects.qz_object);" " });" " } catch (e) {" " setTimeout(registerWebChannel, 100);" " }" "}" "registerWebChannel();" "" "})()"); return source.arg(QzTools::readAllFileContents(QSL(":/qtwebchannel/qwebchannel.js"))); } QString Scripts::setupFormObserver() { QString source = QL1S("(function() {" "function findUsername(inputs) {" " var usernameNames = ['user', 'name', 'login'];" " for (var i = 0; i < usernameNames.length; ++i) {" " for (var j = 0; j < inputs.length; ++j)" " if (inputs[j].type == 'text' && inputs[j].value.length && inputs[j].name.indexOf(usernameNames[i]) != -1)" " return inputs[j].value;" " }" " for (var i = 0; i < inputs.length; ++i)" " if (inputs[i].type == 'text' && inputs[i].value.length)" " return inputs[i].value;" " for (var i = 0; i < inputs.length; ++i)" " if (inputs[i].type == 'email' && inputs[i].value.length)" " return inputs[i].value;" " return '';" "}" "" "function registerForm(form) {" " form.addEventListener('submit', function() {" " var form = this;" " var data = '';" " var password = '';" " var inputs = form.getElementsByTagName('input');" " for (var i = 0; i < inputs.length; ++i) {" " var input = inputs[i];" " var type = input.type.toLowerCase();" " if (type != 'text' && type != 'password' && type != 'email')" " continue;" " if (!password && type == 'password')" " password = input.value;" " data += encodeURIComponent(input.name);" " data += '=';" " data += encodeURIComponent(input.value);" " data += '&';" " }" " if (!password)" " return;" " data = data.substring(0, data.length - 1);" " var url = window.location.href;" " var username = findUsername(inputs);" " external.autoFill.formSubmitted(url, username, password, data);" " }, true);" "}" "" "if (!document.documentElement) return;" "" "for (var i = 0; i < document.forms.length; ++i)" " registerForm(document.forms[i]);" "" "var observer = new MutationObserver(function(mutations) {" " for (var i = 0; i < mutations.length; ++i)" " for (var j = 0; j < mutations[i].addedNodes.length; ++j)" " if (mutations[i].addedNodes[j].tagName == 'FORM')" " registerForm(mutations[i].addedNodes[j]);" "});" "observer.observe(document.documentElement, { childList: true, subtree: true });" "" "})()"); return source; } QString Scripts::setCss(const QString &css) { QString source = QL1S("(function() {" "var head = document.getElementsByTagName('head')[0];" "if (!head) return;" "var css = document.createElement('style');" "css.setAttribute('type', 'text/css');" "css.appendChild(document.createTextNode('%1'));" "head.appendChild(css);" "})()"); QString style = css; style.replace(QL1S("'"), QL1S("\\'")); style.replace(QL1S("\n"), QL1S("\\n")); return source.arg(style); } QString Scripts::sendPostData(const QUrl &url, const QByteArray &data) { QString source = QL1S("(function() {" "var form = document.createElement('form');" "form.setAttribute('method', 'POST');" "form.setAttribute('action', '%1');" "var val;" "%2" "form.submit();" "})()"); QString valueSource = QL1S("val = document.createElement('input');" "val.setAttribute('type', 'hidden');" "val.setAttribute('name', '%1');" "val.setAttribute('value', '%2');" "form.appendChild(val);"); QString values; QUrlQuery query(data); const auto &queryItems = query.queryItems(QUrl::FullyDecoded); for (int i = 0; i < queryItems.size(); ++i) { const auto &pair = queryItems[i]; QString value = pair.first; QString key = pair.second; value.replace(QL1S("'"), QL1S("\\'")); key.replace(QL1S("'"), QL1S("\\'")); values.append(valueSource.arg(value, key)); } return source.arg(url.toString(), values); } QString Scripts::completeFormData(const QByteArray &data) { QString source = QL1S("(function() {" "var data = '%1'.split('&');" "var inputs = document.getElementsByTagName('input');" "" "for (var i = 0; i < data.length; ++i) {" " var pair = data[i].split('=');" " if (pair.length != 2)" " continue;" " var key = decodeURIComponent(pair[0]);" " var val = decodeURIComponent(pair[1]);" " for (var j = 0; j < inputs.length; ++j) {" " var input = inputs[j];" " var type = input.type.toLowerCase();" " if (type != 'text' && type != 'password' && type != 'email')" " continue;" " if (input.name == key)" " input.value = val;" " }" "}" "" "})()"); QString d = data; d.replace(QL1S("'"), QL1S("\\'")); return source.arg(d); } QString Scripts::getOpenSearchLinks() { QString source = QL1S("(function() {" "var out = [];" "var links = document.getElementsByTagName('link');" "for (var i = 0; i < links.length; ++i) {" " var e = links[i];" " if (e.type == 'application/opensearchdescription+xml') {" " out.push({" " url: e.href," " title: e.title" " });" " }" "}" "return out;" "})()"); return source; } QString Scripts::getAllImages() { QString source = QL1S("(function() {" "var out = [];" "var imgs = document.getElementsByTagName('img');" "for (var i = 0; i < imgs.length; ++i) {" " var e = imgs[i];" " out.push({" " src: e.src," " alt: e.alt" " });" "}" "return out;" "})()"); return source; } QString Scripts::getAllMetaAttributes() { QString source = QL1S("(function() {" "var out = [];" "var meta = document.getElementsByTagName('meta');" "for (var i = 0; i < meta.length; ++i) {" " var e = meta[i];" " out.push({" " name: e.getAttribute('name')," " content: e.getAttribute('content')," " httpequiv: e.getAttribute('http-equiv')" " });" "}" "return out;" "})()"); return source; } QString Scripts::getFormData(const QPointF &pos) { QString source = QL1S("(function() {" "var e = document.elementFromPoint(%1, %2);" "if (!e || e.tagName != 'INPUT')" " return;" "var fe = e.parentElement;" "while (fe) {" " if (fe.tagName == 'FORM')" " break;" " fe = fe.parentElement;" "}" "if (!fe)" " return;" "var res = {" " method: fe.method.toLowerCase()," " action: fe.action," " inputName: e.name," " inputs: []," "};" "for (var i = 0; i < fe.length; ++i) {" " var input = fe.elements[i];" " res.inputs.push([input.name, input.value]);" "}" "return res;" "})()"); return source.arg(pos.x()).arg(pos.y()); } diff --git a/src/lib/tools/scripts.h b/src/lib/tools/scripts.h index b751bab4..04f6e46d 100644 --- a/src/lib/tools/scripts.h +++ b/src/lib/tools/scripts.h @@ -1,43 +1,43 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2015-2016 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef SCRIPTS_H #define SCRIPTS_H #include #include "qzcommon.h" class QWebEngineView; -class QUPZILLA_EXPORT Scripts +class FALKON_EXPORT Scripts { public: static QString setupWebChannel(); static QString setupFormObserver(); static QString setCss(const QString &css); static QString sendPostData(const QUrl &url, const QByteArray &data); static QString completeFormData(const QByteArray &data); static QString getOpenSearchLinks(); static QString getAllImages(); static QString getAllMetaAttributes(); static QString getFormData(const QPointF &pos); }; #endif // SCRIPTS_H diff --git a/src/lib/tools/sqldatabase.cpp b/src/lib/tools/sqldatabase.cpp index 5e5e8ecf..b0203c7a 100644 --- a/src/lib/tools/sqldatabase.cpp +++ b/src/lib/tools/sqldatabase.cpp @@ -1,87 +1,87 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "sqldatabase.h" #include #include #include #include Q_GLOBAL_STATIC(SqlDatabase, qz_sql_database) // SqlDatabase SqlDatabase::SqlDatabase(QObject* parent) : QObject(parent) { } SqlDatabase::~SqlDatabase() { QMutableHashIterator i(m_databases); while (i.hasNext()) { i.next(); i.value().close(); } } QSqlDatabase SqlDatabase::databaseForThread(QThread* thread) { QMutexLocker lock(&m_mutex); if (!m_databases.contains(thread)) { const QString threadStr = QString::number((quintptr) thread); - m_databases[thread] = QSqlDatabase::cloneDatabase(QSqlDatabase::database(), QL1S("QupZilla/") + threadStr); + m_databases[thread] = QSqlDatabase::cloneDatabase(QSqlDatabase::database(), QL1S("Falkon/") + threadStr); m_databases[thread].open(); } Q_ASSERT(m_databases[thread].isOpen()); return m_databases[thread]; } QSqlQuery SqlDatabase::exec(QSqlQuery &query) { if (QThread::currentThread() == qApp->thread()) { query.exec(); return query; } QSqlQuery out(databaseForThread(QThread::currentThread())); out.prepare(query.lastQuery()); const QList boundValues = query.boundValues().values(); foreach (const QVariant &variant, boundValues) { out.addBindValue(variant); } out.exec(); return query = out; } QFuture SqlDatabase::execAsync(const QSqlQuery &query) { return QtConcurrent::run(this, &SqlDatabase::exec, query); } // instance SqlDatabase* SqlDatabase::instance() { return qz_sql_database(); } diff --git a/src/lib/tools/sqldatabase.h b/src/lib/tools/sqldatabase.h index 98e7e5dd..3fa44304 100644 --- a/src/lib/tools/sqldatabase.h +++ b/src/lib/tools/sqldatabase.h @@ -1,54 +1,54 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef SQLDATABASE_H #define SQLDATABASE_H #include #include #include #include #include // Fix build with Qt 4.7 #include "qzcommon.h" -class QUPZILLA_EXPORT SqlDatabase : public QObject +class FALKON_EXPORT SqlDatabase : public QObject { Q_OBJECT public: explicit SqlDatabase(QObject* parent = 0); ~SqlDatabase(); // Returns database connection for thread, creates new connection if not exists QSqlDatabase databaseForThread(QThread* thread); // Executes query using correct database for current thread QSqlQuery exec(QSqlQuery &query); // Executes query asynchronously on one thread from QThreadPool QFuture execAsync(const QSqlQuery &query); static SqlDatabase* instance(); private: QHash m_databases; QMutex m_mutex; }; #endif // SQLDATABASE_H diff --git a/src/lib/tools/toolbutton.cpp b/src/lib/tools/toolbutton.cpp index 6079742e..7ae289c2 100644 --- a/src/lib/tools/toolbutton.cpp +++ b/src/lib/tools/toolbutton.cpp @@ -1,246 +1,246 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "toolbutton.h" #include #include #include #include #include #include ToolButton::ToolButton(QWidget* parent) : QToolButton(parent) , m_menu(0) { setMinimumWidth(16); QStyleOptionToolButton opt; initStyleOption(&opt); m_pressTimer.setSingleShot(true); m_pressTimer.setInterval(QApplication::style()->styleHint(QStyle::SH_ToolButton_PopupDelay, &opt, this)); connect(&m_pressTimer, SIGNAL(timeout()), this, SLOT(showMenu())); } QImage ToolButton::multiIcon() const { return m_multiIcon; } void ToolButton::setMultiIcon(const QImage &image) { m_options |= MultiIconOption; m_multiIcon = image; setFixedSize(m_multiIcon.width(), m_multiIcon.height() / 4); update(); } QString ToolButton::themeIcon() const { return m_themeIcon; } void ToolButton::setThemeIcon(const QString &icon) { m_themeIcon = icon; setIcon(QIcon::fromTheme(m_themeIcon)); } QIcon ToolButton::fallbackIcon() const { return icon(); } void ToolButton::setFallbackIcon(const QIcon &fallbackIcon) { if (icon().isNull()) setIcon(fallbackIcon); } QIcon ToolButton::icon() const { return QToolButton::icon(); } void ToolButton::setIcon(const QIcon &icon) { if (m_options & MultiIconOption) setFixedSize(sizeHint()); m_options &= ~MultiIconOption; QToolButton::setIcon(icon); } QMenu* ToolButton::menu() const { return m_menu; } void ToolButton::setMenu(QMenu* menu) { Q_ASSERT(menu); if (m_menu) disconnect(m_menu, SIGNAL(aboutToHide()), this, SLOT(menuAboutToHide())); m_menu = menu; connect(m_menu, SIGNAL(aboutToHide()), this, SLOT(menuAboutToHide())); } bool ToolButton::showMenuInside() const { return m_options & ShowMenuInsideOption; } void ToolButton::setShowMenuInside(bool enable) { if (enable) m_options |= ShowMenuInsideOption; else m_options &= ~ShowMenuInsideOption; } bool ToolButton::toolbarButtonLook() const { return m_options & ToolBarLookOption; } void ToolButton::setToolbarButtonLook(bool enable) { if (enable) { m_options |= ToolBarLookOption; QStyleOption opt; opt.initFrom(this); int size = style()->pixelMetric(QStyle::PM_ToolBarIconSize, &opt, this); setIconSize(QSize(size, size)); } else { m_options &= ~ToolBarLookOption; } setProperty("toolbar-look", QVariant(enable)); style()->unpolish(this); style()->polish(this); } void ToolButton::menuAboutToHide() { setDown(false); emit aboutToHideMenu(); } void ToolButton::showMenu() { if (!m_menu || m_menu->isVisible()) return; emit aboutToShowMenu(); QPoint pos; if (m_options & ShowMenuInsideOption) { pos = mapToGlobal(rect().bottomRight()); if (QApplication::layoutDirection() == Qt::RightToLeft) pos.setX(pos.x() - rect().width()); else pos.setX(pos.x() - m_menu->sizeHint().width()); } else { pos = mapToGlobal(rect().bottomLeft()); } m_menu->popup(pos); } void ToolButton::mousePressEvent(QMouseEvent* e) { if (popupMode() == QToolButton::DelayedPopup) m_pressTimer.start(); if (e->buttons() == Qt::LeftButton && menu() && popupMode() == QToolButton::InstantPopup) { setDown(true); showMenu(); } else if (e->buttons() == Qt::RightButton && menu()) { setDown(true); showMenu(); } else { QToolButton::mousePressEvent(e); } } void ToolButton::mouseReleaseEvent(QMouseEvent* e) { m_pressTimer.stop(); if (e->button() == Qt::MiddleButton && rect().contains(e->pos())) { emit middleMouseClicked(); setDown(false); } else if (e->button() == Qt::LeftButton && rect().contains(e->pos()) && e->modifiers() == Qt::ControlModifier) { emit controlClicked(); setDown(false); } else { QToolButton::mouseReleaseEvent(e); } } void ToolButton::mouseDoubleClickEvent(QMouseEvent* e) { QToolButton::mouseDoubleClickEvent(e); m_pressTimer.stop(); if (e->buttons() == Qt::LeftButton) { emit doubleClicked(); } } void ToolButton::contextMenuEvent(QContextMenuEvent *e) { // Block to prevent showing both context menu and button menu if (menu()) return; QToolButton::contextMenuEvent(e); } void ToolButton::paintEvent(QPaintEvent* e) { if (!(m_options & MultiIconOption)) { QToolButton::paintEvent(e); return; } QPainter p(this); const int w = m_multiIcon.width(); const int h4 = m_multiIcon.height() / 4; if (!isEnabled()) p.drawImage(0, 0, m_multiIcon, 0, h4 * 3, w, h4); else if (isDown()) p.drawImage(0, 0, m_multiIcon, 0, h4 * 2, w, h4); else if (underMouse()) p.drawImage(0, 0, m_multiIcon, 0, h4 * 1, w, h4); else p.drawImage(0, 0, m_multiIcon, 0, h4 * 0, w, h4); } diff --git a/src/lib/tools/toolbutton.h b/src/lib/tools/toolbutton.h index 813316a5..41613026 100644 --- a/src/lib/tools/toolbutton.h +++ b/src/lib/tools/toolbutton.h @@ -1,108 +1,108 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef TOOLBUTTON_H #define TOOLBUTTON_H #include #include #include "qzcommon.h" -class QUPZILLA_EXPORT ToolButton : public QToolButton +class FALKON_EXPORT ToolButton : public QToolButton { Q_OBJECT Q_PROPERTY(QSize fixedsize READ size WRITE setFixedSize) Q_PROPERTY(int fixedwidth READ width WRITE setFixedWidth) Q_PROPERTY(int fixedheight READ height WRITE setFixedHeight) Q_PROPERTY(QImage multiIcon READ multiIcon WRITE setMultiIcon) Q_PROPERTY(QIcon icon READ icon WRITE setIcon) Q_PROPERTY(QString themeIcon READ themeIcon WRITE setThemeIcon) Q_PROPERTY(QIcon fallbackIcon READ fallbackIcon WRITE setFallbackIcon) public: explicit ToolButton(QWidget* parent = 0); // MultiIcon - Image containing pixmaps for all button states QImage multiIcon() const; void setMultiIcon(const QImage &image); // ThemeIcon - Standard QToolButton with theme icon QString themeIcon() const; void setThemeIcon(const QString &icon); // FallbackIcon - In case theme doesn't contain ThemeIcon QIcon fallbackIcon() const; void setFallbackIcon(const QIcon &fallbackIcon); // Icon - Standard QToolButton with icon QIcon icon() const; void setIcon(const QIcon &icon); // Menu - Menu is handled in ToolButton and is not passed to QToolButton // There won't be menu indicator shown in the button // QToolButton::MenuButtonPopup is not supported QMenu* menu() const; void setMenu(QMenu* menu); // Align the right corner of menu to the right corner of button bool showMenuInside() const; void setShowMenuInside(bool enable); // Set the button to look as it was in toolbar // (it now only sets the correct icon size) bool toolbarButtonLook() const; void setToolbarButtonLook(bool enable); signals: void middleMouseClicked(); void controlClicked(); void doubleClicked(); // It is needed to use these signals with ShowMenuInside void aboutToShowMenu(); void aboutToHideMenu(); private slots: void menuAboutToHide(); void showMenu(); protected: void mousePressEvent(QMouseEvent* e); void mouseReleaseEvent(QMouseEvent* e); void mouseDoubleClickEvent(QMouseEvent* e); void contextMenuEvent(QContextMenuEvent *e); void paintEvent(QPaintEvent* e); private: QImage m_multiIcon; QString m_themeIcon; QTimer m_pressTimer; QMenu* m_menu; enum Options { MultiIconOption = 1, ShowMenuInsideOption = 2, ToolBarLookOption = 4 }; Q_DECLARE_FLAGS(OptionsFlags, Options) OptionsFlags m_options; }; #endif // TOOLBUTTON_H diff --git a/src/lib/tools/treewidget.cpp b/src/lib/tools/treewidget.cpp index bb0ad9e9..166578ec 100644 --- a/src/lib/tools/treewidget.cpp +++ b/src/lib/tools/treewidget.cpp @@ -1,213 +1,213 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "treewidget.h" #include TreeWidget::TreeWidget(QWidget* parent) : QTreeWidget(parent) , m_refreshAllItemsNeeded(true) , m_showMode(ItemsCollapsed) { connect(this, SIGNAL(itemChanged(QTreeWidgetItem*,int)), this, SLOT(sheduleRefresh())); } void TreeWidget::clear() { QTreeWidget::clear(); m_allTreeItems.clear(); } void TreeWidget::sheduleRefresh() { m_refreshAllItemsNeeded = true; } void TreeWidget::addTopLevelItem(QTreeWidgetItem* item) { m_allTreeItems.append(item); QTreeWidget::addTopLevelItem(item); } void TreeWidget::addTopLevelItems(const QList &items) { m_allTreeItems.append(items); QTreeWidget::addTopLevelItems(items); } void TreeWidget::insertTopLevelItem(int index, QTreeWidgetItem* item) { m_allTreeItems.append(item); QTreeWidget::insertTopLevelItem(index, item); } void TreeWidget::insertTopLevelItems(int index, const QList &items) { m_allTreeItems.append(items); QTreeWidget::insertTopLevelItems(index, items); } void TreeWidget::mousePressEvent(QMouseEvent* event) { if (event->modifiers() == Qt::ControlModifier) { emit itemControlClicked(itemAt(event->pos())); } if (event->buttons() == Qt::MiddleButton) { emit itemMiddleButtonClicked(itemAt(event->pos())); } QTreeWidget::mousePressEvent(event); } void TreeWidget::iterateAllItems(QTreeWidgetItem* parent) { int count = parent ? parent->childCount() : topLevelItemCount(); for (int i = 0; i < count; i++) { QTreeWidgetItem* item = parent ? parent->child(i) : topLevelItem(i); if (item->childCount() == 0) { m_allTreeItems.append(item); } iterateAllItems(item); } } QList TreeWidget::allItems() { if (m_refreshAllItemsNeeded) { m_allTreeItems.clear(); iterateAllItems(0); m_refreshAllItemsNeeded = false; } return m_allTreeItems; } void TreeWidget::filterString(const QString &string) { QList _allItems = allItems(); QList parents; bool stringIsEmpty = string.isEmpty(); foreach (QTreeWidgetItem* item, _allItems) { bool containsString = stringIsEmpty || item->text(0).contains(string, Qt::CaseInsensitive); if (containsString) { item->setHidden(false); if (item->parent()) { if (!parents.contains(item->parent())) { parents << item->parent(); } } } else { item->setHidden(true); if (item->parent()) { item->parent()->setHidden(true); } } } for (int i = 0; i < parents.size(); ++i) { QTreeWidgetItem* parentItem = parents.at(i); parentItem->setHidden(false); if (stringIsEmpty) { parentItem->setExpanded(m_showMode == ItemsExpanded); } else { parentItem->setExpanded(true); } if (parentItem->parent() && !parents.contains(parentItem->parent())) { parents << parentItem->parent(); } } } bool TreeWidget::appendToParentItem(const QString &parentText, QTreeWidgetItem* item) { QList list = findItems(parentText, Qt::MatchExactly); if (list.count() == 0) { return false; } QTreeWidgetItem* parentItem = list.at(0); if (!parentItem) { return false; } m_allTreeItems.append(item); parentItem->addChild(item); return true; } bool TreeWidget::appendToParentItem(QTreeWidgetItem* parent, QTreeWidgetItem* item) { if (!parent || parent->treeWidget() != this) { return false; } m_allTreeItems.append(item); parent->addChild(item); return true; } bool TreeWidget::prependToParentItem(const QString &parentText, QTreeWidgetItem* item) { QList list = findItems(parentText, Qt::MatchExactly); if (list.count() == 0) { return false; } QTreeWidgetItem* parentItem = list.at(0); if (!parentItem) { return false; } m_allTreeItems.append(item); parentItem->insertChild(0, item); return true; } bool TreeWidget::prependToParentItem(QTreeWidgetItem* parent, QTreeWidgetItem* item) { if (!parent || parent->treeWidget() != this) { return false; } m_allTreeItems.append(item); parent->insertChild(0, item); return true; } void TreeWidget::deleteItem(QTreeWidgetItem* item) { // if (m_allTreeItems.contains(item)) { // m_allTreeItems.removeOne(item); // } m_refreshAllItemsNeeded = true; delete item; } void TreeWidget::deleteItems(const QList &items) { m_refreshAllItemsNeeded = true; qDeleteAll(items); } diff --git a/src/lib/tools/treewidget.h b/src/lib/tools/treewidget.h index 3ff1bf56..f046a78d 100644 --- a/src/lib/tools/treewidget.h +++ b/src/lib/tools/treewidget.h @@ -1,68 +1,68 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef BOOKMARKSTREEWIDGET_H #define BOOKMARKSTREEWIDGET_H #include "qzcommon.h" #include -class QUPZILLA_EXPORT TreeWidget : public QTreeWidget +class FALKON_EXPORT TreeWidget : public QTreeWidget { Q_OBJECT public: explicit TreeWidget(QWidget* parent = 0); enum ItemShowMode { ItemsCollapsed = 0, ItemsExpanded = 1 }; ItemShowMode defaultItemShowMode() { return m_showMode; } void setDefaultItemShowMode(ItemShowMode mode) { m_showMode = mode; } QList allItems(); bool appendToParentItem(const QString &parentText, QTreeWidgetItem* item); bool appendToParentItem(QTreeWidgetItem* parent, QTreeWidgetItem* item); bool prependToParentItem(const QString &parentText, QTreeWidgetItem* item); bool prependToParentItem(QTreeWidgetItem* parent, QTreeWidgetItem* item); void addTopLevelItem(QTreeWidgetItem* item); void addTopLevelItems(const QList &items); void insertTopLevelItem(int index, QTreeWidgetItem* item); void insertTopLevelItems(int index, const QList &items); void deleteItem(QTreeWidgetItem* item); void deleteItems(const QList &items); signals: void itemControlClicked(QTreeWidgetItem* item); void itemMiddleButtonClicked(QTreeWidgetItem* item); public slots: void filterString(const QString &string); void clear(); private slots: void sheduleRefresh(); private: void mousePressEvent(QMouseEvent* event); void iterateAllItems(QTreeWidgetItem* parent); bool m_refreshAllItemsNeeded; QList m_allTreeItems; ItemShowMode m_showMode; }; #endif // BOOKMARKSTREEWIDGET_H diff --git a/src/lib/tools/wheelhelper.cpp b/src/lib/tools/wheelhelper.cpp index 9d9e919c..16b4c37a 100644 --- a/src/lib/tools/wheelhelper.cpp +++ b/src/lib/tools/wheelhelper.cpp @@ -1,78 +1,78 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "wheelhelper.h" #include WheelHelper::WheelHelper() { } void WheelHelper::reset() { m_wheelDelta = 0; m_directions.clear(); } void WheelHelper::processEvent(QWheelEvent *event) { int delta = event->angleDelta().x() ? event->angleDelta().x() : event->angleDelta().y(); bool directionY = delta == event->angleDelta().y(); // When scroll to both directions, prefer the major one if (event->angleDelta().x() && event->angleDelta().y()) { if (qAbs(event->angleDelta().y()) > qAbs(event->angleDelta().x())) { delta = event->angleDelta().y(); directionY = true; } else { delta = event->angleDelta().x(); directionY = false; } } // Reset when direction changes if ((delta < 0 && m_wheelDelta > 0) || (delta > 0 && m_wheelDelta < 0)) { m_wheelDelta = 0; } m_wheelDelta += delta; // Angle delta 120 for common "one click" // See: http://qt-project.org/doc/qt-5/qml-qtquick-wheelevent.html#angleDelta-prop while (m_wheelDelta >= 120) { m_wheelDelta -= 120; if (directionY) { m_directions.enqueue(WheelUp); } else { m_directions.enqueue(WheelLeft); } } while (m_wheelDelta <= -120) { m_wheelDelta += 120; if (directionY) { m_directions.enqueue(WheelDown); } else { m_directions.enqueue(WheelRight); } } } WheelHelper::Direction WheelHelper::takeDirection() { return m_directions.isEmpty() ? None : m_directions.dequeue(); } diff --git a/src/lib/tools/wheelhelper.h b/src/lib/tools/wheelhelper.h index a6c41370..4682bb67 100644 --- a/src/lib/tools/wheelhelper.h +++ b/src/lib/tools/wheelhelper.h @@ -1,49 +1,49 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef WHEELHELPER_H #define WHEELHELPER_H #include #include "qzcommon.h" class QWheelEvent; -class QUPZILLA_EXPORT WheelHelper +class FALKON_EXPORT WheelHelper { public: enum Direction { None = 0, WheelUp, WheelDown, WheelLeft, WheelRight }; explicit WheelHelper(); void reset(); void processEvent(QWheelEvent *event); Direction takeDirection(); private: int m_wheelDelta = 0; QQueue m_directions; }; #endif // WHEELHELPER_H diff --git a/src/lib/tools/widget.cpp b/src/lib/tools/widget.cpp index b2550e73..d1fb2902 100644 --- a/src/lib/tools/widget.cpp +++ b/src/lib/tools/widget.cpp @@ -1,44 +1,44 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "widget.h" /* * class Widget */ Widget::Widget(QWidget* parent) : QWidget(parent) { } void Widget::slotResize(const QSize &size) { resize(size); } /* * class ResizableFrame */ ResizableFrame::ResizableFrame(QWidget* parent) : QFrame(parent) { } void ResizableFrame::slotResize(const QSize &size) { resize(size); } diff --git a/src/lib/tools/widget.h b/src/lib/tools/widget.h index c88abd6f..4b65b0ef 100644 --- a/src/lib/tools/widget.h +++ b/src/lib/tools/widget.h @@ -1,51 +1,51 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef WIDGET_H #define WIDGET_H #include #include #include "qzcommon.h" -class QUPZILLA_EXPORT Widget : public QWidget +class FALKON_EXPORT Widget : public QWidget { Q_OBJECT public: explicit Widget(QWidget* parent = 0); signals: public slots: void slotResize(const QSize &size); }; -class QUPZILLA_EXPORT ResizableFrame : public QFrame +class FALKON_EXPORT ResizableFrame : public QFrame { Q_OBJECT public: explicit ResizableFrame(QWidget* parent = 0); signals: public slots: void slotResize(const QSize &size); }; #endif // WIDGET_H diff --git a/src/lib/webengine/javascript/autofilljsobject.cpp b/src/lib/webengine/javascript/autofilljsobject.cpp index ba23b296..804a7182 100644 --- a/src/lib/webengine/javascript/autofilljsobject.cpp +++ b/src/lib/webengine/javascript/autofilljsobject.cpp @@ -1,39 +1,39 @@ /* ============================================================ -* QupZilla - QtWebEngine based browser +* Falkon - Qt web browser * Copyright (C) 2015 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "autofilljsobject.h" #include "externaljsobject.h" #include "mainapplication.h" #include "autofill.h" #include "webpage.h" AutoFillJsObject::AutoFillJsObject(ExternalJsObject *parent) : QObject(parent) , m_jsObject(parent) { } void AutoFillJsObject::formSubmitted(const QString &frameUrl, const QString &username, const QString &password, const QByteArray &data) { PageFormData formData; formData.username = username; formData.password = password; formData.postData = data; mApp->autoFill()->saveForm(m_jsObject->page(), QUrl(frameUrl), formData); } diff --git a/src/lib/webengine/javascript/autofilljsobject.h b/src/lib/webengine/javascript/autofilljsobject.h index 924706ab..4143d3e0 100644 --- a/src/lib/webengine/javascript/autofilljsobject.h +++ b/src/lib/webengine/javascript/autofilljsobject.h @@ -1,39 +1,39 @@ /* ============================================================ -* QupZilla - QtWebEngine based browser +* Falkon - Qt web browser * Copyright (C) 2015 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef AUTOFILLJSOBJECT_H #define AUTOFILLJSOBJECT_H #include class ExternalJsObject; class AutoFillJsObject : public QObject { Q_OBJECT public: explicit AutoFillJsObject(ExternalJsObject *parent); public slots: void formSubmitted(const QString &frameUrl, const QString &username, const QString &password, const QByteArray &data); private: ExternalJsObject *m_jsObject; }; #endif // AUTOFILLJSOBJECT_H diff --git a/src/lib/webengine/javascript/externaljsobject.cpp b/src/lib/webengine/javascript/externaljsobject.cpp index 754eb075..52cda127 100644 --- a/src/lib/webengine/javascript/externaljsobject.cpp +++ b/src/lib/webengine/javascript/externaljsobject.cpp @@ -1,69 +1,69 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "externaljsobject.h" #include "mainapplication.h" #include "pluginproxy.h" #include "speeddial.h" #include "webpage.h" #include "searchenginesmanager.h" #include "autofilljsobject.h" #include "restoremanager.h" ExternalJsObject::ExternalJsObject(WebPage *page) : QObject(page) , m_page(page) , m_autoFill(new AutoFillJsObject(this)) { } WebPage *ExternalJsObject::page() const { return m_page; } void ExternalJsObject::AddSearchProvider(const QString &engineUrl) { mApp->searchEnginesManager()->addEngine(QUrl(engineUrl)); } int ExternalJsObject::IsSearchProviderInstalled(const QString &engineURL) { qDebug() << "NOT IMPLEMENTED: IsSearchProviderInstalled()" << engineURL; return 0; } QObject *ExternalJsObject::speedDial() const { - if (m_page->url().toString() != QL1S("qupzilla:speeddial")) + if (m_page->url().toString() != QL1S("falkon:speeddial")) return Q_NULLPTR; return mApp->plugins()->speedDial(); } QObject *ExternalJsObject::autoFill() const { return m_autoFill; } QObject *ExternalJsObject::recovery() const { - if (!mApp->restoreManager() || m_page->url().toString() != QL1S("qupzilla:restore")) + if (!mApp->restoreManager() || m_page->url().toString() != QL1S("falkon:restore")) return Q_NULLPTR; return mApp->restoreManager()->recoveryObject(m_page); } diff --git a/src/lib/webengine/javascript/externaljsobject.h b/src/lib/webengine/javascript/externaljsobject.h index 5d7934ed..9f01bc58 100644 --- a/src/lib/webengine/javascript/externaljsobject.h +++ b/src/lib/webengine/javascript/externaljsobject.h @@ -1,51 +1,51 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef EXTERNALJSOBJECT_H #define EXTERNALJSOBJECT_H #include class WebPage; class AutoFillJsObject; class ExternalJsObject : public QObject { Q_OBJECT Q_PROPERTY(QObject* speedDial READ speedDial CONSTANT) Q_PROPERTY(QObject* autoFill READ autoFill CONSTANT) Q_PROPERTY(QObject* recovery READ recovery CONSTANT) public: explicit ExternalJsObject(WebPage *page); WebPage *page() const; public slots: void AddSearchProvider(const QString &engineUrl); int IsSearchProviderInstalled(const QString &engineURL); private: QObject *speedDial() const; QObject *autoFill() const; QObject *recovery() const; WebPage *m_page; AutoFillJsObject *m_autoFill; }; #endif // EXTERNALJSOBJECT_H diff --git a/src/lib/webengine/loadrequest.cpp b/src/lib/webengine/loadrequest.cpp index 1d3b7209..9c490ae0 100644 --- a/src/lib/webengine/loadrequest.cpp +++ b/src/lib/webengine/loadrequest.cpp @@ -1,94 +1,94 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2014-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "loadrequest.h" LoadRequest::LoadRequest() : m_operation(GetOperation) { } LoadRequest::LoadRequest(const LoadRequest &other) : m_url(other.m_url) , m_operation(other.m_operation) , m_data(other.m_data) { } LoadRequest::LoadRequest(const QUrl &url, LoadRequest::Operation op, const QByteArray &data) : m_url(url) , m_operation(op) , m_data(data) { } LoadRequest &LoadRequest::operator=(const LoadRequest &other) { m_url = other.m_url; m_operation = other.m_operation; m_data = other.m_data; return *this; } bool LoadRequest::isEmpty() const { return m_url.isEmpty(); } QUrl LoadRequest::url() const { return m_url; } void LoadRequest::setUrl(const QUrl &url) { m_url = url; } QString LoadRequest::urlString() const { return QUrl::fromPercentEncoding(m_url.toEncoded()); } LoadRequest::Operation LoadRequest::operation() const { return m_operation; } void LoadRequest::setOperation(LoadRequest::Operation op) { m_operation = op; } QByteArray LoadRequest::data() const { return m_data; } void LoadRequest::setData(const QByteArray &data) { m_data = data; } #if QT_VERSION >= QT_VERSION_CHECK(5, 9, 0) QWebEngineHttpRequest LoadRequest::webRequest() const { QWebEngineHttpRequest req(m_url, m_operation == GetOperation ? QWebEngineHttpRequest::Get : QWebEngineHttpRequest::Post); req.setPostData(m_data); return req; } #endif diff --git a/src/lib/webengine/loadrequest.h b/src/lib/webengine/loadrequest.h index 3f71b07d..eecf23b7 100644 --- a/src/lib/webengine/loadrequest.h +++ b/src/lib/webengine/loadrequest.h @@ -1,66 +1,66 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2014-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef LOADREQUEST_H #define LOADREQUEST_H #include #if QT_VERSION >= QT_VERSION_CHECK(5, 9, 0) #include #endif #include "qzcommon.h" -class QUPZILLA_EXPORT LoadRequest +class FALKON_EXPORT LoadRequest { public: enum Operation { GetOperation = 0, PostOperation = 1 }; LoadRequest(); LoadRequest(const LoadRequest &other); LoadRequest(const QUrl &url, Operation op = GetOperation, const QByteArray &data = QByteArray()); LoadRequest &operator=(const LoadRequest &other); bool isEmpty() const; QUrl url() const; void setUrl(const QUrl &url); QString urlString() const; Operation operation() const; void setOperation(Operation op); QByteArray data() const; void setData(const QByteArray &data); #if QT_VERSION >= QT_VERSION_CHECK(5, 9, 0) QWebEngineHttpRequest webRequest() const; #endif private: QUrl m_url; Operation m_operation; QByteArray m_data; }; #endif // LOADREQUEST_H diff --git a/src/lib/webengine/webhittestresult.cpp b/src/lib/webengine/webhittestresult.cpp index 1d6d7902..a82def83 100644 --- a/src/lib/webengine/webhittestresult.cpp +++ b/src/lib/webengine/webhittestresult.cpp @@ -1,221 +1,221 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2015-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "webhittestresult.h" #include "webpage.h" #include WebHitTestResult::WebHitTestResult(const WebPage *page, const QPoint &pos) : m_isNull(true) , m_isContentEditable(false) , m_isContentSelected(false) , m_mediaPaused(false) , m_mediaMuted(false) , m_pos(pos) { QString source = QL1S("(function() {" "var e = document.elementFromPoint(%1, %2);" "if (!e)" " return;" "function isMediaElement(e) {" " return e.tagName == 'AUDIO' || e.tagName == 'VIDEO';" "}" "function isEditableElement(e) {" " if (e.isContentEditable)" " return true;" " if (e.tagName == 'INPUT' || e.tagName == 'TEXTAREA')" " return e.getAttribute('readonly') != 'readonly';" " return false;" "}" "function isSelected(e) {" " var selection = window.getSelection();" " if (selection.type != 'Range')" " return false;" " return window.getSelection().containsNode(e, true);" "}" "var res = {" " baseUrl: document.baseURI," " alternateText: e.getAttribute('alt')," " boundingRect: ''," " imageUrl: ''," " contentEditable: isEditableElement(e)," " contentSelected: isSelected(e)," " linkTitle: ''," " linkUrl: ''," " mediaUrl: ''," " tagName: e.tagName.toLowerCase()" "};" "var r = e.getBoundingClientRect();" "res.boundingRect = [r.top, r.left, r.width, r.height];" "if (e.tagName == 'IMG')" " res.imageUrl = e.getAttribute('src');" "if (e.tagName == 'A') {" " res.linkTitle = e.text;" " res.linkUrl = e.getAttribute('href');" "}" "while (e) {" " if (res.linkTitle == '' && e.tagName == 'A')" " res.linkTitle = e.text;" " if (res.linkUrl == '' && e.tagName == 'A')" " res.linkUrl = e.getAttribute('href');" " if (res.mediaUrl == '' && isMediaElement(e)) {" " res.mediaUrl = e.currentSrc;" " res.mediaPaused = e.paused;" " res.mediaMuted = e.muted;" " }" " e = e.parentElement;" "}" "return res;" "})()"); WebPage *p = const_cast(page); m_viewportPos = p->mapToViewport(m_pos); const QString &js = source.arg(m_viewportPos.x()).arg(m_viewportPos.y()); init(p->url(), p->execJavaScript(js, WebPage::SafeJsWorld).toMap()); } void WebHitTestResult::updateWithContextMenuData(const QWebEngineContextMenuData &data) { if (!data.isValid() || data.position() != m_pos) { return; } m_linkTitle = data.linkText(); m_linkUrl = data.linkUrl(); m_isContentEditable = data.isContentEditable(); m_isContentSelected = !data.selectedText().isEmpty(); switch (data.mediaType()) { case QWebEngineContextMenuData::MediaTypeImage: m_imageUrl = data.mediaUrl(); break; case QWebEngineContextMenuData::MediaTypeVideo: case QWebEngineContextMenuData::MediaTypeAudio: m_mediaUrl = data.mediaUrl(); break; default: break; } } QUrl WebHitTestResult::baseUrl() const { return m_baseUrl; } QString WebHitTestResult::alternateText() const { return m_alternateText; } QRect WebHitTestResult::boundingRect() const { return m_boundingRect; } QUrl WebHitTestResult::imageUrl() const { return m_imageUrl; } bool WebHitTestResult::isContentEditable() const { return m_isContentEditable; } bool WebHitTestResult::isContentSelected() const { return m_isContentSelected; } bool WebHitTestResult::isNull() const { return m_isNull; } QString WebHitTestResult::linkTitle() const { return m_linkTitle; } QUrl WebHitTestResult::linkUrl() const { return m_linkUrl; } QUrl WebHitTestResult::mediaUrl() const { return m_mediaUrl; } bool WebHitTestResult::mediaPaused() const { return m_mediaPaused; } bool WebHitTestResult::mediaMuted() const { return m_mediaMuted; } QPoint WebHitTestResult::pos() const { return m_pos; } QPointF WebHitTestResult::viewportPos() const { return m_viewportPos; } QString WebHitTestResult::tagName() const { return m_tagName; } void WebHitTestResult::init(const QUrl &url, const QVariantMap &map) { if (map.isEmpty()) return; m_isNull = false; m_baseUrl = map.value(QSL("baseUrl")).toUrl(); m_alternateText = map.value(QSL("alternateText")).toString(); m_imageUrl = map.value(QSL("imageUrl")).toUrl(); m_isContentEditable = map.value(QSL("contentEditable")).toBool(); m_isContentSelected = map.value(QSL("contentSelected")).toBool(); m_linkTitle = map.value(QSL("linkTitle")).toString(); m_linkUrl = map.value(QSL("linkUrl")).toUrl(); m_mediaUrl = map.value(QSL("mediaUrl")).toUrl(); m_mediaPaused = map.value(QSL("mediaPaused")).toBool(); m_mediaMuted = map.value(QSL("mediaMuted")).toBool(); m_tagName = map.value(QSL("tagName")).toString(); const QVariantList &rect = map.value(QSL("boundingRect")).toList(); if (rect.size() == 4) m_boundingRect = QRect(rect.at(0).toInt(), rect.at(1).toInt(), rect.at(2).toInt(), rect.at(3).toInt()); if (!m_imageUrl.isEmpty()) m_imageUrl = url.resolved(m_imageUrl); if (!m_linkUrl.isEmpty()) m_linkUrl = m_baseUrl.resolved(m_linkUrl); if (!m_mediaUrl.isEmpty()) m_mediaUrl = url.resolved(m_mediaUrl); } diff --git a/src/lib/webengine/webhittestresult.h b/src/lib/webengine/webhittestresult.h index 43d8be94..1493464d 100644 --- a/src/lib/webengine/webhittestresult.h +++ b/src/lib/webengine/webhittestresult.h @@ -1,75 +1,75 @@ /* ============================================================ * QupZilla - QtWebEngine based browser * Copyright (C) 2015-2016 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef WEBHITTESTRESULT_H #define WEBHITTESTRESULT_H #include #include #include #include #include "qzcommon.h" class QWebEngineContextMenuData; class WebPage; -class QUPZILLA_EXPORT WebHitTestResult +class FALKON_EXPORT WebHitTestResult { public: explicit WebHitTestResult(const WebPage *page, const QPoint &pos); void updateWithContextMenuData(const QWebEngineContextMenuData &data); QUrl baseUrl() const; QString alternateText() const; QRect boundingRect() const; QUrl imageUrl() const; bool isContentEditable() const; bool isContentSelected() const; bool isNull() const; QString linkTitle() const; QUrl linkUrl() const; QUrl mediaUrl() const; bool mediaPaused() const; bool mediaMuted() const; QPoint pos() const; QPointF viewportPos() const; QString tagName() const; private: void init(const QUrl &url, const QVariantMap &map); bool m_isNull; QUrl m_baseUrl; QString m_alternateText; QRect m_boundingRect; QUrl m_imageUrl; bool m_isContentEditable; bool m_isContentSelected; QString m_linkTitle; QUrl m_linkUrl; QUrl m_mediaUrl; bool m_mediaPaused; bool m_mediaMuted; QPoint m_pos; QPointF m_viewportPos; QString m_tagName; }; #endif // WEBHITTESTRESULT_H diff --git a/src/lib/webengine/webinspector.cpp b/src/lib/webengine/webinspector.cpp index 03e921d3..d9610911 100644 --- a/src/lib/webengine/webinspector.cpp +++ b/src/lib/webengine/webinspector.cpp @@ -1,152 +1,152 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "webinspector.h" #include "mainapplication.h" #include "networkmanager.h" #include "settings.h" #include #include #include #include QList WebInspector::s_views; WebInspector::WebInspector(QWidget *parent) : QWebEngineView(parent) , m_view(Q_NULLPTR) { setAttribute(Qt::WA_DeleteOnClose); setObjectName(QSL("web-inspector")); setMinimumHeight(80); m_height = Settings().value(QSL("Web-Inspector/height"), 80).toInt(); m_windowSize = Settings().value(QSL("Web-Inspector/windowSize"), QSize(640, 480)).toSize(); registerView(this); connect(page(), &QWebEnginePage::windowCloseRequested, this, &WebInspector::deleteLater); connect(page(), &QWebEnginePage::loadFinished, this, &WebInspector::loadFinished); } WebInspector::~WebInspector() { unregisterView(this); if (isWindow()) { Settings().setValue(QSL("Web-Inspector/windowSize"), size()); } else { Settings().setValue(QSL("Web-Inspector/height"), height()); } } void WebInspector::setView(QWebEngineView *view) { m_view = view; Q_ASSERT(isEnabled()); int port = qEnvironmentVariableIntValue("QTWEBENGINE_REMOTE_DEBUGGING"); QUrl inspectorUrl = QUrl(QSL("http://localhost:%1").arg(port)); int index = s_views.indexOf(m_view); QNetworkReply *reply = mApp->networkManager()->get(QNetworkRequest(inspectorUrl.resolved(QUrl("json/list")))); connect(reply, &QNetworkReply::finished, this, [=]() { QJsonArray clients = QJsonDocument::fromJson(reply->readAll()).array(); QUrl pageUrl; if (clients.size() > index) { QJsonObject object = clients.at(index).toObject(); pageUrl = inspectorUrl.resolved(QUrl(object.value(QSL("devtoolsFrontendUrl")).toString())); } load(pageUrl); pushView(this); show(); }); } void WebInspector::inspectElement() { m_inspectElement = true; } bool WebInspector::isEnabled() { return qEnvironmentVariableIsSet("QTWEBENGINE_REMOTE_DEBUGGING"); } void WebInspector::pushView(QWebEngineView *view) { s_views.removeOne(view); s_views.prepend(view); } void WebInspector::registerView(QWebEngineView *view) { s_views.prepend(view); } void WebInspector::unregisterView(QWebEngineView *view) { s_views.removeOne(view); } void WebInspector::loadFinished() { // Show close button only when docked if (!isWindow()) { page()->runJavaScript(QL1S("var toolbar = document.getElementsByClassName('inspector-view-toolbar')[1];" "var button = document.createElement('button');" "button.style.width = '22px';" "button.style.height = '22px';" "button.style.border = 'none';" "button.style.cursor = 'pointer';" "button.style.background = 'url(qrc:html/close.png) no-repeat';" "button.style.backgroundPosition = 'center center';" "button.addEventListener('click', function() {" " window.close();" "});" "toolbar.appendChild(button);")); } // Inspect element if (m_inspectElement) { m_view->triggerPageAction(QWebEnginePage::InspectElement); m_inspectElement = false; } } QSize WebInspector::sizeHint() const { if (isWindow()) { return m_windowSize; } QSize s = QWebEngineView::sizeHint(); s.setHeight(m_height); return s; } void WebInspector::keyPressEvent(QKeyEvent *event) { Q_UNUSED(event) // Stop propagation } void WebInspector::keyReleaseEvent(QKeyEvent *event) { Q_UNUSED(event) // Stop propagation } diff --git a/src/lib/webengine/webinspector.h b/src/lib/webengine/webinspector.h index 6c5a1c50..07e0ffb6 100644 --- a/src/lib/webengine/webinspector.h +++ b/src/lib/webengine/webinspector.h @@ -1,59 +1,59 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef WEBINSPECTORDOCKWIDGET_H #define WEBINSPECTORDOCKWIDGET_H #include #include "qzcommon.h" class ToolButton; -class QUPZILLA_EXPORT WebInspector : public QWebEngineView +class FALKON_EXPORT WebInspector : public QWebEngineView { Q_OBJECT public: explicit WebInspector(QWidget *parent = Q_NULLPTR); ~WebInspector(); void setView(QWebEngineView *view); void inspectElement(); static bool isEnabled(); static void pushView(QWebEngineView *view); static void registerView(QWebEngineView *view); static void unregisterView(QWebEngineView *view); private slots: void loadFinished(); private: QSize sizeHint() const override; void keyPressEvent(QKeyEvent *event) Q_DECL_OVERRIDE; void keyReleaseEvent(QKeyEvent *event) Q_DECL_OVERRIDE; static QList s_views; int m_height; QSize m_windowSize; bool m_inspectElement = false; QWebEngineView *m_view; }; #endif // WEBINSPECTORDOCKWIDGET_H diff --git a/src/lib/webengine/webpage.cpp b/src/lib/webengine/webpage.cpp index 12d8f947..798d9edd 100644 --- a/src/lib/webengine/webpage.cpp +++ b/src/lib/webengine/webpage.cpp @@ -1,636 +1,636 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "webpage.h" #include "tabbedwebview.h" #include "browserwindow.h" #include "pluginproxy.h" #include "downloadmanager.h" #include "mainapplication.h" #include "checkboxdialog.h" #include "widget.h" #include "qztools.h" #include "speeddial.h" #include "autofill.h" #include "popupwebview.h" #include "popupwindow.h" #include "adblockmanager.h" #include "iconprovider.h" #include "qzsettings.h" #include "useragentmanager.h" #include "delayedfilewatcher.h" #include "searchenginesmanager.h" #include "html5permissions/html5permissionsmanager.h" #include "javascript/externaljsobject.h" #include "tabwidget.h" #include "scripts.h" #include "networkmanager.h" #include "webhittestresult.h" #ifdef NONBLOCK_JS_DIALOGS #include "ui_jsconfirm.h" #include "ui_jsalert.h" #include "ui_jsprompt.h" #include #endif #include #include #include #include #include #include #include #include #include #include QString WebPage::s_lastUploadLocation = QDir::homePath(); QUrl WebPage::s_lastUnsupportedUrl; QTime WebPage::s_lastUnsupportedUrlTime; WebPage::WebPage(QObject* parent) : QWebEnginePage(mApp->webProfile(), parent) , m_fileWatcher(0) , m_runningLoop(0) , m_loadProgress(-1) , m_blockAlerts(false) , m_secureStatus(false) { QWebChannel *channel = new QWebChannel(this); channel->registerObject(QSL("qz_object"), new ExternalJsObject(this)); setWebChannel(channel); connect(this, &QWebEnginePage::loadProgress, this, &WebPage::progress); connect(this, &QWebEnginePage::loadFinished, this, &WebPage::finished); connect(this, &QWebEnginePage::urlChanged, this, &WebPage::urlChanged); connect(this, &QWebEnginePage::featurePermissionRequested, this, &WebPage::featurePermissionRequested); connect(this, &QWebEnginePage::windowCloseRequested, this, &WebPage::windowCloseRequested); connect(this, &QWebEnginePage::fullScreenRequested, this, &WebPage::fullScreenRequested); connect(this, &QWebEnginePage::renderProcessTerminated, this, &WebPage::renderProcessTerminated); connect(this, &QWebEnginePage::authenticationRequired, this, [this](const QUrl &url, QAuthenticator *auth) { mApp->networkManager()->authentication(url, auth, view()); }); connect(this, &QWebEnginePage::proxyAuthenticationRequired, this, [this](const QUrl &, QAuthenticator *auth, const QString &proxyHost) { mApp->networkManager()->proxyAuthentication(proxyHost, auth, view()); }); // Workaround QWebEnginePage not scrolling to anchors when opened in background tab m_contentsResizedConnection = connect(this, &QWebEnginePage::contentsSizeChanged, this, [this]() { const QString fragment = url().fragment(); if (!fragment.isEmpty()) { const QString src = QSL("var els = document.querySelectorAll(\"[name='%1']\"); if (els.length) els[0].scrollIntoView();"); runJavaScript(src.arg(fragment)); } disconnect(m_contentsResizedConnection); }); } WebPage::~WebPage() { mApp->plugins()->emitWebPageDeleted(this); if (m_runningLoop) { m_runningLoop->exit(1); m_runningLoop = 0; } } WebView *WebPage::view() const { return static_cast(QWebEnginePage::view()); } bool WebPage::execPrintPage(QPrinter *printer, int timeout) { QPointer loop = new QEventLoop; bool result = false; QTimer::singleShot(timeout, loop.data(), &QEventLoop::quit); print(printer, [loop, &result](bool res) { if (loop && loop->isRunning()) { result = res; loop->quit(); } }); loop->exec(); delete loop; return result; } QVariant WebPage::execJavaScript(const QString &scriptSource, quint32 worldId, int timeout) { QPointer loop = new QEventLoop; QVariant result; QTimer::singleShot(timeout, loop.data(), &QEventLoop::quit); runJavaScript(scriptSource, worldId, [loop, &result](const QVariant &res) { if (loop && loop->isRunning()) { result = res; loop->quit(); } }); loop->exec(QEventLoop::ExcludeUserInputEvents); delete loop; return result; } QPointF WebPage::mapToViewport(const QPointF &pos) const { return QPointF(pos.x() / zoomFactor(), pos.y() / zoomFactor()); } WebHitTestResult WebPage::hitTestContent(const QPoint &pos) const { return WebHitTestResult(this, pos); } void WebPage::scroll(int x, int y) { runJavaScript(QSL("window.scrollTo(window.scrollX + %1, window.scrollY + %2)").arg(x).arg(y), WebPage::SafeJsWorld); } void WebPage::setScrollPosition(const QPointF &pos) { const QPointF v = mapToViewport(pos.toPoint()); runJavaScript(QSL("window.scrollTo(%1, %2)").arg(v.x()).arg(v.y()), WebPage::SafeJsWorld); } bool WebPage::isRunningLoop() { return m_runningLoop; } bool WebPage::isLoading() const { return m_loadProgress < 100; } void WebPage::urlChanged(const QUrl &url) { Q_UNUSED(url) if (isLoading()) { m_blockAlerts = false; } } void WebPage::progress(int prog) { m_loadProgress = prog; bool secStatus = url().scheme() == QL1S("https"); if (secStatus != m_secureStatus) { m_secureStatus = secStatus; emit privacyChanged(secStatus); } } void WebPage::finished() { progress(100); // File scheme watcher if (url().scheme() == QLatin1String("file")) { QFileInfo info(url().toLocalFile()); if (info.isFile()) { if (!m_fileWatcher) { m_fileWatcher = new DelayedFileWatcher(this); connect(m_fileWatcher, SIGNAL(delayedFileChanged(QString)), this, SLOT(watchedFileChanged(QString))); } const QString filePath = url().toLocalFile(); if (QFile::exists(filePath) && !m_fileWatcher->files().contains(filePath)) { m_fileWatcher->addPath(filePath); } } } else if (m_fileWatcher && !m_fileWatcher->files().isEmpty()) { m_fileWatcher->removePaths(m_fileWatcher->files()); } // AdBlock cleanBlockedObjects(); // AutoFill m_passwordEntries = mApp->autoFill()->completePage(this, url()); } void WebPage::watchedFileChanged(const QString &file) { if (url().toLocalFile() == file) { triggerAction(QWebEnginePage::Reload); } } void WebPage::handleUnknownProtocol(const QUrl &url) { const QString protocol = url.scheme(); if (protocol == QLatin1String("mailto")) { desktopServicesOpen(url); return; } if (qzSettings->blockedProtocols.contains(protocol)) { qDebug() << "WebPage::handleUnknownProtocol Protocol" << protocol << "is blocked!"; return; } if (qzSettings->autoOpenProtocols.contains(protocol)) { desktopServicesOpen(url); return; } CheckBoxDialog dialog(QMessageBox::Yes | QMessageBox::No, view()); const QString wrappedUrl = QzTools::alignTextToWidth(url.toString(), "
", dialog.fontMetrics(), 450); - const QString text = tr("QupZilla cannot handle %1: links. The requested link " - "is
  • %2
Do you want QupZilla to try " + const QString text = tr("Falkon cannot handle %1: links. The requested link " + "is
  • %2
Do you want Falkon to try " "open this link in system application?").arg(protocol, wrappedUrl); dialog.setText(text); dialog.setCheckBoxText(tr("Remember my choice for this protocol")); dialog.setWindowTitle(tr("External Protocol Request")); dialog.setIcon(QMessageBox::Question); switch (dialog.exec()) { case QMessageBox::Yes: if (dialog.isChecked()) { qzSettings->autoOpenProtocols.append(protocol); qzSettings->saveSettings(); } QDesktopServices::openUrl(url); break; case QMessageBox::No: if (dialog.isChecked()) { qzSettings->blockedProtocols.append(protocol); qzSettings->saveSettings(); } break; default: break; } } void WebPage::desktopServicesOpen(const QUrl &url) { // Open same url only once in 2 secs const int sameUrlTimeout = 2 * 1000; if (s_lastUnsupportedUrl != url || s_lastUnsupportedUrlTime.isNull() || s_lastUnsupportedUrlTime.elapsed() > sameUrlTimeout) { s_lastUnsupportedUrl = url; s_lastUnsupportedUrlTime.restart(); QDesktopServices::openUrl(url); } else { qWarning() << "WebPage::desktopServicesOpen Url" << url << "has already been opened!\n" "Ignoring it to prevent infinite loop!"; } } void WebPage::windowCloseRequested() { if (!view()) return; view()->closeView(); } void WebPage::fullScreenRequested(QWebEngineFullScreenRequest fullScreenRequest) { view()->requestFullScreen(fullScreenRequest.toggleOn()); const bool accepted = fullScreenRequest.toggleOn() == view()->isFullScreen(); if (accepted) fullScreenRequest.accept(); else fullScreenRequest.reject(); } void WebPage::featurePermissionRequested(const QUrl &origin, const QWebEnginePage::Feature &feature) { if (feature == MouseLock && view()->isFullScreen()) setFeaturePermission(origin, feature, PermissionGrantedByUser); else mApp->html5PermissionsManager()->requestPermissions(this, origin, feature); } void WebPage::renderProcessTerminated(QWebEnginePage::RenderProcessTerminationStatus terminationStatus, int exitCode) { Q_UNUSED(exitCode) if (terminationStatus == NormalTerminationStatus) return; QTimer::singleShot(0, this, [this]() { QString page = QzTools::readAllFileContents(":html/tabcrash.html"); page.replace(QL1S("%IMAGE%"), QzTools::pixmapToDataUrl(IconProvider::standardIcon(QStyle::SP_MessageBoxWarning).pixmap(45)).toString()); page.replace(QL1S("%TITLE%"), tr("Failed loading page")); page.replace(QL1S("%HEADING%"), tr("Failed loading page")); page.replace(QL1S("%LI-1%"), tr("Something went wrong while loading this page.")); page.replace(QL1S("%LI-2%"), tr("Try reloading the page or closing some tabs to make more memory available.")); page.replace(QL1S("%RELOAD-PAGE%"), tr("Reload page")); page = QzTools::applyDirectionToPage(page); load(url()); // Workaround for QtWebEngine crash setHtml(page.toUtf8(), url()); }); } bool WebPage::acceptNavigationRequest(const QUrl &url, QWebEnginePage::NavigationType type, bool isMainFrame) { if (!mApp->plugins()->acceptNavigationRequest(this, url, type, isMainFrame)) return false; // AdBlock if (url.scheme() == QL1S("abp") && AdBlockManager::instance()->addSubscriptionFromUrl(url)) return false; return QWebEnginePage::acceptNavigationRequest(url, type, isMainFrame); } bool WebPage::certificateError(const QWebEngineCertificateError &error) { return mApp->networkManager()->certificateError(error, view()); } QStringList WebPage::chooseFiles(QWebEnginePage::FileSelectionMode mode, const QStringList &oldFiles, const QStringList &acceptedMimeTypes) { Q_UNUSED(acceptedMimeTypes); QStringList files; QString suggestedFileName = s_lastUploadLocation; if (!oldFiles.isEmpty()) suggestedFileName = oldFiles.at(0); switch (mode) { case FileSelectOpen: files = QStringList(QzTools::getOpenFileName("WebPage-ChooseFile", view(), tr("Choose file..."), suggestedFileName)); break; case FileSelectOpenMultiple: files = QzTools::getOpenFileNames("WebPage-ChooseFile", view(), tr("Choose files..."), suggestedFileName); break; default: files = QWebEnginePage::chooseFiles(mode, oldFiles, acceptedMimeTypes); break; } if (!files.isEmpty()) s_lastUploadLocation = files.at(0); return files; } bool WebPage::hasMultipleUsernames() const { return m_passwordEntries.count() > 1; } QVector WebPage::autoFillData() const { return m_passwordEntries; } void WebPage::cleanBlockedObjects() { AdBlockManager* manager = AdBlockManager::instance(); if (!manager->isEnabled()) { return; } // Apply global element hiding rules const QString elementHiding = manager->elementHidingRules(url()); if (!elementHiding.isEmpty()) runJavaScript(Scripts::setCss(elementHiding), WebPage::SafeJsWorld); // Apply domain-specific element hiding rules const QString siteElementHiding = manager->elementHidingRulesForDomain(url()); if (!siteElementHiding.isEmpty()) runJavaScript(Scripts::setCss(siteElementHiding), WebPage::SafeJsWorld); } bool WebPage::javaScriptPrompt(const QUrl &securityOrigin, const QString &msg, const QString &defaultValue, QString* result) { Q_UNUSED(securityOrigin) #ifndef NONBLOCK_JS_DIALOGS return QWebEnginePage::javaScriptPrompt(securityOrigin, msg, defaultValue, result); #else if (m_runningLoop) { return false; } ResizableFrame* widget = new ResizableFrame(view()->overlayWidget()); widget->setObjectName("jsFrame"); Ui_jsPrompt* ui = new Ui_jsPrompt(); ui->setupUi(widget); ui->message->setText(msg); ui->lineEdit->setText(defaultValue); ui->lineEdit->setFocus(); widget->resize(view()->size()); widget->show(); connect(view(), SIGNAL(viewportResized(QSize)), widget, SLOT(slotResize(QSize))); connect(ui->lineEdit, SIGNAL(returnPressed()), ui->buttonBox->button(QDialogButtonBox::Ok), SLOT(animateClick())); QEventLoop eLoop; m_runningLoop = &eLoop; connect(ui->buttonBox, SIGNAL(clicked(QAbstractButton*)), &eLoop, SLOT(quit())); if (eLoop.exec() == 1) { return result; } m_runningLoop = 0; QString x = ui->lineEdit->text(); bool _result = ui->buttonBox->clickedButtonRole() == QDialogButtonBox::AcceptRole; *result = x; delete widget; view()->setFocus(); return _result; #endif } bool WebPage::javaScriptConfirm(const QUrl &securityOrigin, const QString &msg) { Q_UNUSED(securityOrigin) #ifndef NONBLOCK_JS_DIALOGS return QWebEnginePage::javaScriptConfirm(securityOrigin, msg); #else if (m_runningLoop) { return false; } ResizableFrame* widget = new ResizableFrame(view()->overlayWidget()); widget->setObjectName("jsFrame"); Ui_jsConfirm* ui = new Ui_jsConfirm(); ui->setupUi(widget); ui->message->setText(msg); ui->buttonBox->button(QDialogButtonBox::Ok)->setFocus(); widget->resize(view()->size()); widget->show(); connect(view(), SIGNAL(viewportResized(QSize)), widget, SLOT(slotResize(QSize))); QEventLoop eLoop; m_runningLoop = &eLoop; connect(ui->buttonBox, SIGNAL(clicked(QAbstractButton*)), &eLoop, SLOT(quit())); if (eLoop.exec() == 1) { return false; } m_runningLoop = 0; bool result = ui->buttonBox->clickedButtonRole() == QDialogButtonBox::AcceptRole; delete widget; view()->setFocus(); return result; #endif } void WebPage::javaScriptAlert(const QUrl &securityOrigin, const QString &msg) { Q_UNUSED(securityOrigin) if (m_blockAlerts || m_runningLoop) { return; } #ifndef NONBLOCK_JS_DIALOGS QString title = tr("JavaScript alert"); if (!url().host().isEmpty()) { title.append(QString(" - %1").arg(url().host())); } CheckBoxDialog dialog(QMessageBox::Ok, view()); dialog.setWindowTitle(title); dialog.setText(msg); dialog.setCheckBoxText(tr("Prevent this page from creating additional dialogs")); dialog.setIcon(QMessageBox::Information); dialog.exec(); m_blockAlerts = dialog.isChecked(); #else ResizableFrame* widget = new ResizableFrame(view()->overlayWidget()); widget->setObjectName("jsFrame"); Ui_jsAlert* ui = new Ui_jsAlert(); ui->setupUi(widget); ui->message->setText(msg); ui->buttonBox->button(QDialogButtonBox::Ok)->setFocus(); widget->resize(view()->size()); widget->show(); connect(view(), SIGNAL(viewportResized(QSize)), widget, SLOT(slotResize(QSize))); QEventLoop eLoop; m_runningLoop = &eLoop; connect(ui->buttonBox, SIGNAL(clicked(QAbstractButton*)), &eLoop, SLOT(quit())); if (eLoop.exec() == 1) { return; } m_runningLoop = 0; m_blockAlerts = ui->preventAlerts->isChecked(); delete widget; view()->setFocus(); #endif } void WebPage::setJavaScriptEnabled(bool enabled) { settings()->setAttribute(QWebEngineSettings::JavascriptEnabled, enabled); } QWebEnginePage* WebPage::createWindow(QWebEnginePage::WebWindowType type) { TabbedWebView *tView = qobject_cast(view()); BrowserWindow *window = tView ? tView->browserWindow() : mApp->getWindow(); auto createTab = [=](Qz::NewTabPositionFlags pos) { int index = window->tabWidget()->addView(QUrl(), pos); TabbedWebView* view = window->weView(index); view->setPage(new WebPage); // Workaround focus issue when creating tab if (pos.testFlag(Qz::NT_SelectedTab)) { QPointer pview = view; QTimer::singleShot(0, this, [pview]() { if (pview && pview->webTab()->isCurrentTab()) { pview->setFocus(); } }); } return view->page(); }; switch (type) { case QWebEnginePage::WebBrowserWindow: { BrowserWindow *window = mApp->createWindow(Qz::BW_NewWindow); WebPage *page = new WebPage; window->setStartPage(page); return page; } case QWebEnginePage::WebDialog: if (!qzSettings->openPopupsInTabs) { PopupWebView* view = new PopupWebView; view->setPage(new WebPage); PopupWindow* popup = new PopupWindow(view); popup->show(); window->addDeleteOnCloseWidget(popup); return view->page(); } // else fallthrough case QWebEnginePage::WebBrowserTab: return createTab(Qz::NT_CleanSelectedTab); case QWebEnginePage::WebBrowserBackgroundTab: return createTab(Qz::NT_CleanNotSelectedTab); default: break; } return Q_NULLPTR; } diff --git a/src/lib/webengine/webpage.h b/src/lib/webengine/webpage.h index 147d8df5..ac05a6b7 100644 --- a/src/lib/webengine/webpage.h +++ b/src/lib/webengine/webpage.h @@ -1,113 +1,113 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef WEBPAGE_H #define WEBPAGE_H #include #include #include #include #include "qzcommon.h" #include "passwordmanager.h" class QEventLoop; class QWebEngineDownloadItem; class WebView; class WebHitTestResult; class DelayedFileWatcher; -class QUPZILLA_EXPORT WebPage : public QWebEnginePage +class FALKON_EXPORT WebPage : public QWebEnginePage { Q_OBJECT public: enum JsWorld { SafeJsWorld = QWebEngineScript::ApplicationWorld }; explicit WebPage(QObject* parent = 0); ~WebPage(); WebView *view() const; bool execPrintPage(QPrinter *printer, int timeout = 1000); QVariant execJavaScript(const QString &scriptSource, quint32 worldId = QWebEngineScript::MainWorld, int timeout = 500); QPointF mapToViewport(const QPointF &pos) const; WebHitTestResult hitTestContent(const QPoint &pos) const; void scroll(int x, int y); void setScrollPosition(const QPointF &pos); bool javaScriptPrompt(const QUrl &securityOrigin, const QString &msg, const QString &defaultValue, QString* result) Q_DECL_OVERRIDE; bool javaScriptConfirm(const QUrl &securityOrigin, const QString &msg) Q_DECL_OVERRIDE; void javaScriptAlert(const QUrl &securityOrigin, const QString &msg) Q_DECL_OVERRIDE; void setJavaScriptEnabled(bool enabled); bool hasMultipleUsernames() const; QVector autoFillData() const; bool isRunningLoop(); bool isLoading() const; signals: void privacyChanged(bool status); protected slots: void progress(int prog); void finished(); private slots: void cleanBlockedObjects(); void urlChanged(const QUrl &url); void watchedFileChanged(const QString &file); void windowCloseRequested(); void fullScreenRequested(QWebEngineFullScreenRequest fullScreenRequest); void featurePermissionRequested(const QUrl &origin, const QWebEnginePage::Feature &feature); void renderProcessTerminated(RenderProcessTerminationStatus terminationStatus, int exitCode); private: bool acceptNavigationRequest(const QUrl &url, NavigationType type, bool isMainFrame) Q_DECL_OVERRIDE; bool certificateError(const QWebEngineCertificateError &error) Q_DECL_OVERRIDE; QStringList chooseFiles(FileSelectionMode mode, const QStringList &oldFiles, const QStringList &acceptedMimeTypes) Q_DECL_OVERRIDE; QWebEnginePage* createWindow(QWebEnginePage::WebWindowType type) Q_DECL_OVERRIDE; void handleUnknownProtocol(const QUrl &url); void desktopServicesOpen(const QUrl &url); static QString s_lastUploadLocation; static QUrl s_lastUnsupportedUrl; static QTime s_lastUnsupportedUrlTime; DelayedFileWatcher* m_fileWatcher; QEventLoop* m_runningLoop; QVector m_passwordEntries; int m_loadProgress; bool m_blockAlerts; bool m_secureStatus; QMetaObject::Connection m_contentsResizedConnection; }; #endif // WEBPAGE_H diff --git a/src/lib/webengine/webscrollbar.cpp b/src/lib/webengine/webscrollbar.cpp index a4e4907d..36abd980 100644 --- a/src/lib/webengine/webscrollbar.cpp +++ b/src/lib/webengine/webscrollbar.cpp @@ -1,93 +1,93 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2016-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "webscrollbar.h" #include "webview.h" #include "webpage.h" #include WebScrollBar::WebScrollBar(Qt::Orientation orientation, WebView *view) : QScrollBar(orientation) , m_view(view) { setFocusProxy(m_view); resize(sizeHint()); connect(this, &QScrollBar::valueChanged, this, &WebScrollBar::performScroll); connect(view, &WebView::focusChanged, this, [this]() { update(); }); } int WebScrollBar::thickness() const { return orientation() == Qt::Vertical ? width() : height(); } void WebScrollBar::updateValues(const QSize &viewport) { setMinimum(0); setParent(m_view->overlayWidget()); int newValue; m_blockScrolling = true; if (orientation() == Qt::Vertical) { setFixedHeight(m_view->height() - (m_view->height() - viewport.height()) * devicePixelRatioF()); move(m_view->width() - width(), 0); setPageStep(viewport.height()); setMaximum(qMax(0, m_view->page()->contentsSize().toSize().height() - viewport.height())); newValue = m_view->page()->scrollPosition().toPoint().y(); } else { setFixedWidth(m_view->width() - (m_view->width() - viewport.width()) * devicePixelRatioF()); move(0, m_view->height() - height()); setPageStep(viewport.width()); setMaximum(qMax(0, m_view->page()->contentsSize().toSize().width() - viewport.width())); newValue = m_view->page()->scrollPosition().toPoint().x(); } if (!isSliderDown()) { setValue(newValue); } m_blockScrolling = false; } void WebScrollBar::performScroll() { if (m_blockScrolling) { return; } QPointF pos = m_view->page()->scrollPosition(); if (orientation() == Qt::Vertical) { pos.setY(value()); } else { pos.setX(value()); } m_view->page()->setScrollPosition(pos); } void WebScrollBar::paintEvent(QPaintEvent *ev) { QPainter painter(this); painter.fillRect(ev->rect(), palette().background()); QScrollBar::paintEvent(ev); } diff --git a/src/lib/webengine/webscrollbar.h b/src/lib/webengine/webscrollbar.h index d18b0c02..96e46c53 100644 --- a/src/lib/webengine/webscrollbar.h +++ b/src/lib/webengine/webscrollbar.h @@ -1,46 +1,46 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2016 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef WEBSCROLLBAR_H #define WEBSCROLLBAR_H #include #include "qzcommon.h" class WebView; class WebScrollBar : public QScrollBar { Q_OBJECT public: explicit WebScrollBar(Qt::Orientation orientation, WebView *view); int thickness() const; void updateValues(const QSize &viewport); private: void performScroll(); void paintEvent(QPaintEvent *ev) override; WebView *m_view; bool m_blockScrolling = false; }; #endif // WEBSCROLLBAR_H diff --git a/src/lib/webengine/webscrollbarmanager.cpp b/src/lib/webengine/webscrollbarmanager.cpp index ff7c9635..0ffb2fdb 100644 --- a/src/lib/webengine/webscrollbarmanager.cpp +++ b/src/lib/webengine/webscrollbarmanager.cpp @@ -1,258 +1,258 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2016-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "webscrollbarmanager.h" #include "webscrollbar.h" #include "webview.h" #include "webpage.h" #include "mainapplication.h" #include "scripts.h" #include "settings.h" #include #include #include #include #include #include Q_GLOBAL_STATIC(WebScrollBarManager, qz_web_scrollbar_manager) class WebScrollBarCornerWidget : public QWidget { public: explicit WebScrollBarCornerWidget(WebView *view) : QWidget() , m_view(view) { setAutoFillBackground(true); } void updateVisibility(bool visible, int thickness) { if (visible) { setParent(m_view->overlayWidget()); resize(thickness, thickness); move(m_view->width() - width(), m_view->height() - height()); show(); } else { hide(); } } private: void paintEvent(QPaintEvent *ev) override { Q_UNUSED(ev) QStyleOption option; option.initFrom(this); option.rect = rect(); QPainter p(this); if (mApp->styleName() == QL1S("breeze")) { p.fillRect(ev->rect(), option.palette.background()); } else { style()->drawPrimitive(QStyle::PE_PanelScrollAreaCorner, &option, &p, this); } } WebView *m_view; }; struct ScrollBarData { ~ScrollBarData() { delete vscrollbar; delete hscrollbar; delete corner; } WebScrollBar *vscrollbar; WebScrollBar *hscrollbar; bool vscrollbarVisible = false; bool hscrollbarVisible = false; WebScrollBarCornerWidget *corner; }; WebScrollBarManager::WebScrollBarManager(QObject *parent) : QObject(parent) { m_scrollbarJs = QL1S("(function() {" "var head = document.getElementsByTagName('head')[0];" "if (!head) return;" "var css = document.createElement('style');" "css.setAttribute('type', 'text/css');" "var size = %1 / window.devicePixelRatio + 'px';" "css.appendChild(document.createTextNode('" " body::-webkit-scrollbar{width:'+size+';height:'+size+';}" "'));" "head.appendChild(css);" "})()"); loadSettings(); } void WebScrollBarManager::loadSettings() { m_enabled = Settings().value(QSL("Web-Browser-Settings/UseNativeScrollbars"), false).toBool(); if (!m_enabled) { for (WebView *view : m_scrollbars.keys()) { removeWebView(view); } } } void WebScrollBarManager::addWebView(WebView *view) { if (!m_enabled) { return; } delete m_scrollbars.value(view); ScrollBarData *data = new ScrollBarData; data->vscrollbar = new WebScrollBar(Qt::Vertical, view); data->hscrollbar = new WebScrollBar(Qt::Horizontal, view); data->corner = new WebScrollBarCornerWidget(view); m_scrollbars[view] = data; const int thickness = data->vscrollbar->thickness(); auto updateValues = [=]() { const QSize viewport = viewportSize(view, thickness); data->vscrollbar->updateValues(viewport); data->vscrollbar->setVisible(data->vscrollbarVisible); data->hscrollbar->updateValues(viewport); data->hscrollbar->setVisible(data->hscrollbarVisible); data->corner->updateVisibility(data->vscrollbarVisible && data->hscrollbarVisible, thickness); }; connect(view, &WebView::viewportResized, data->vscrollbar, updateValues); connect(view->page(), &WebPage::scrollPositionChanged, data->vscrollbar, updateValues); connect(view->page(), &WebPage::contentsSizeChanged, data->vscrollbar, [=]() { const QString source = QL1S("var out = {" "vertical: document.documentElement && window.innerWidth > document.documentElement.clientWidth," "horizontal: document.documentElement && window.innerHeight > document.documentElement.clientHeight" "};out;"); QPointer p(view); view->page()->runJavaScript(source, WebPage::SafeJsWorld, [=](const QVariant &res) { if (!p || !m_scrollbars.contains(view)) { return; } const QVariantMap map = res.toMap(); data->vscrollbarVisible = map.value(QSL("vertical")).toBool(); data->hscrollbarVisible = map.value(QSL("horizontal")).toBool(); updateValues(); }); }); connect(view, &WebView::zoomLevelChanged, data->vscrollbar, [=]() { view->page()->runJavaScript(m_scrollbarJs.arg(thickness)); }); if (m_scrollbars.size() == 1) { createUserScript(thickness); } } void WebScrollBarManager::removeWebView(WebView *view) { if (!m_scrollbars.contains(view)) { return; } if (m_scrollbars.size() == 1) { removeUserScript(); } delete m_scrollbars.take(view); } QScrollBar *WebScrollBarManager::scrollBar(Qt::Orientation orientation, WebView *view) const { ScrollBarData *d = m_scrollbars.value(view); if (!d) { return nullptr; } return orientation == Qt::Vertical ? d->vscrollbar : d->hscrollbar; } WebScrollBarManager *WebScrollBarManager::instance() { return qz_web_scrollbar_manager(); } void WebScrollBarManager::createUserScript(int thickness) { QWebEngineScript script; - script.setName(QSL("_qupzilla_scrollbar")); + script.setName(QSL("_falkon_scrollbar")); script.setInjectionPoint(QWebEngineScript::DocumentReady); script.setWorldId(WebPage::SafeJsWorld); script.setSourceCode(m_scrollbarJs.arg(thickness)); mApp->webProfile()->scripts()->insert(script); } void WebScrollBarManager::removeUserScript() { - QWebEngineScript script = mApp->webProfile()->scripts()->findScript(QSL("_qupzilla_scrollbar")); + QWebEngineScript script = mApp->webProfile()->scripts()->findScript(QSL("_falkon_scrollbar")); mApp->webProfile()->scripts()->remove(script); } QSize WebScrollBarManager::viewportSize(WebView *view, int thickness) const { QSize viewport = view->size(); thickness /= view->devicePixelRatioF(); ScrollBarData *data = m_scrollbars.value(view); Q_ASSERT(data); if (data->vscrollbarVisible) { viewport.setWidth(viewport.width() - thickness); } if (data->hscrollbarVisible) { viewport.setHeight(viewport.height() - thickness); } #if 0 const QSize content = view->page()->contentsSize().toSize(); // Check both axis if (content.width() - viewport.width() > 0) { viewport.setHeight(viewport.height() - thickness); } if (content.height() - viewport.height() > 0) { viewport.setWidth(viewport.width() - thickness); } // Check again against adjusted size if (viewport.height() == view->height() && content.width() - viewport.width() > 0) { viewport.setHeight(viewport.height() - thickness); } if (viewport.width() == view->width() && content.height() - viewport.height() > 0) { viewport.setWidth(viewport.width() - thickness); } #endif return viewport; } diff --git a/src/lib/webengine/webscrollbarmanager.h b/src/lib/webengine/webscrollbarmanager.h index 3c907fe9..20e674b1 100644 --- a/src/lib/webengine/webscrollbarmanager.h +++ b/src/lib/webengine/webscrollbarmanager.h @@ -1,55 +1,55 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2016 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef WEBSCROLLBARMANAGER_H #define WEBSCROLLBARMANAGER_H #include #include class QScrollBar; class WebView; class WebScrollBarManager : public QObject { Q_OBJECT public: explicit WebScrollBarManager(QObject *parent = 0); void loadSettings(); void addWebView(WebView *view); void removeWebView(WebView *view); QScrollBar *scrollBar(Qt::Orientation orientation, WebView *view) const; static WebScrollBarManager *instance(); private: void createUserScript(int thickness); void removeUserScript(); QSize viewportSize(WebView *view, int thickness) const; bool m_enabled = true; QString m_scrollbarJs; QHash m_scrollbars; }; #endif // WEBSCROLLBARMANAGER_H diff --git a/src/lib/webengine/webview.cpp b/src/lib/webengine/webview.cpp index 332925c4..1d86a610 100644 --- a/src/lib/webengine/webview.cpp +++ b/src/lib/webengine/webview.cpp @@ -1,1355 +1,1355 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "webview.h" #include "webpage.h" #include "mainapplication.h" #include "qztools.h" #include "iconprovider.h" #include "history.h" #include "pluginproxy.h" #include "downloadmanager.h" #include "siteinfo.h" #include "searchenginesmanager.h" #include "browsinglibrary.h" #include "bookmarkstools.h" #include "settings.h" #include "qzsettings.h" #include "enhancedmenu.h" #include "locationbar.h" #include "webinspector.h" #include "scripts.h" #include "webhittestresult.h" #include "webscrollbarmanager.h" #include #include #include #include #include #include #include #include #include #include #include #include #include bool WebView::s_forceContextMenuOnMouseRelease = false; WebView::WebView(QWidget* parent) : QWebEngineView(parent) , m_progress(100) , m_backgroundActivity(false) , m_page(0) , m_firstLoad(false) { connect(this, &QWebEngineView::loadStarted, this, &WebView::slotLoadStarted); connect(this, &QWebEngineView::loadProgress, this, &WebView::slotLoadProgress); connect(this, &QWebEngineView::loadFinished, this, &WebView::slotLoadFinished); connect(this, &QWebEngineView::iconChanged, this, &WebView::slotIconChanged); connect(this, &QWebEngineView::urlChanged, this, &WebView::slotUrlChanged); connect(this, &QWebEngineView::titleChanged, this, &WebView::slotTitleChanged); m_currentZoomLevel = zoomLevels().indexOf(100); setAcceptDrops(true); installEventFilter(this); if (parentWidget()) { parentWidget()->installEventFilter(this); } WebInspector::registerView(this); // Hack to find widget that receives input events QStackedLayout *l = qobject_cast(layout()); connect(l, &QStackedLayout::currentChanged, this, [this]() { QTimer::singleShot(0, this, [this]() { m_rwhvqt = focusProxy(); if (!m_rwhvqt) { qCritical() << "Focus proxy is null!"; return; } m_rwhvqt->installEventFilter(this); }); }); } WebView::~WebView() { WebInspector::unregisterView(this); WebScrollBarManager::instance()->removeWebView(this); } QIcon WebView::icon(bool allowNull) const { if (!QWebEngineView::icon().isNull()) { return QWebEngineView::icon(); } if (url().scheme() == QLatin1String("ftp")) { return IconProvider::standardIcon(QStyle::SP_ComputerIcon); } if (url().scheme() == QLatin1String("file")) { return IconProvider::standardIcon(QStyle::SP_DriveHDIcon); } return IconProvider::iconForUrl(url(), allowNull); } QString WebView::title() const { QString title = QWebEngineView::title(); if (title.isEmpty()) { title = url().toString(QUrl::RemoveFragment); } if (title.isEmpty() || title == QLatin1String("about:blank")) { return tr("Empty Page"); } return title; } bool WebView::isTitleEmpty() const { return QWebEngineView::title().isEmpty(); } WebPage* WebView::page() const { return m_page; } void WebView::setPage(WebPage *page) { if (m_page == page) { return; } if (m_page) { m_page->setView(nullptr); m_page->deleteLater(); } m_page = page; m_page->setParent(this); QWebEngineView::setPage(m_page); connect(m_page, SIGNAL(privacyChanged(bool)), this, SIGNAL(privacyChanged(bool))); // Set default zoom level zoomReset(); // Actions needs to be initialized for every QWebEnginePage change initializeActions(); // Scrollbars must be added only after QWebEnginePage is set WebScrollBarManager::instance()->addWebView(this); mApp->plugins()->emitWebPageCreated(m_page); } void WebView::load(const QUrl &url) { QWebEngineView::load(url); if (!m_firstLoad) { m_firstLoad = true; WebInspector::pushView(this); } } void WebView::load(const LoadRequest &request) { const QUrl reqUrl = request.url(); if (reqUrl.isEmpty()) return; if (reqUrl.scheme() == QL1S("javascript")) { const QString scriptSource = reqUrl.toString().mid(11); // Is the javascript source percent encoded or not? // Looking for % character in source should work in most cases if (scriptSource.contains(QL1C('%'))) page()->runJavaScript(QUrl::fromPercentEncoding(scriptSource.toUtf8())); else page()->runJavaScript(scriptSource); return; } if (isUrlValid(reqUrl)) { loadRequest(request); return; } // Make sure to correctly load hosts like localhost (eg. without the dot) if (!reqUrl.isEmpty() && reqUrl.scheme().isEmpty() && !QzTools::containsSpace(reqUrl.path()) && // See #1622 !reqUrl.path().contains(QL1C('.')) ) { QUrl u(QSL("http://") + reqUrl.path()); if (u.isValid()) { // This is blocking... QHostInfo info = QHostInfo::fromName(u.path()); if (info.error() == QHostInfo::NoError) { LoadRequest req = request; req.setUrl(u); loadRequest(req); return; } } } if (qzSettings->searchFromAddressBar) { const LoadRequest searchRequest = mApp->searchEnginesManager()->searchResult(request.urlString()); loadRequest(searchRequest); } } bool WebView::isLoading() const { return m_progress < 100; } int WebView::loadingProgress() const { return m_progress; } bool WebView::backgroundActivity() const { return m_backgroundActivity; } int WebView::zoomLevel() const { return m_currentZoomLevel; } void WebView::setZoomLevel(int level) { m_currentZoomLevel = level; applyZoom(); } QPointF WebView::mapToViewport(const QPointF &pos) const { return page()->mapToViewport(pos); } QRect WebView::scrollBarGeometry(Qt::Orientation orientation) const { QScrollBar *s = WebScrollBarManager::instance()->scrollBar(orientation, const_cast(this)); return s && s->isVisible() ? s->geometry() : QRect(); } QWidget *WebView::inputWidget() const { return m_rwhvqt ? m_rwhvqt : const_cast(this); } // static bool WebView::isUrlValid(const QUrl &url) { // Valid url must have scheme and actually contains something (therefore scheme:// is invalid) return url.isValid() && !url.scheme().isEmpty() && (!url.host().isEmpty() || !url.path().isEmpty() || url.hasQuery()); } // static QList WebView::zoomLevels() { return QList() << 30 << 40 << 50 << 67 << 80 << 90 << 100 << 110 << 120 << 133 << 150 << 170 << 200 << 220 << 233 << 250 << 270 << 285 << 300; } // static bool WebView::forceContextMenuOnMouseRelease() { return s_forceContextMenuOnMouseRelease; } // static void WebView::setForceContextMenuOnMouseRelease(bool force) { s_forceContextMenuOnMouseRelease = force; } void WebView::addNotification(QWidget* notif) { emit showNotification(notif); } void WebView::applyZoom() { setZoomFactor(qreal(zoomLevels().at(m_currentZoomLevel)) / 100.0); emit zoomLevelChanged(m_currentZoomLevel); } void WebView::zoomIn() { if (m_currentZoomLevel < zoomLevels().count() - 1) { m_currentZoomLevel++; applyZoom(); } } void WebView::zoomOut() { if (m_currentZoomLevel > 0) { m_currentZoomLevel--; applyZoom(); } } void WebView::zoomReset() { if (m_currentZoomLevel != qzSettings->defaultZoomLevel) { m_currentZoomLevel = qzSettings->defaultZoomLevel; applyZoom(); } } void WebView::editUndo() { triggerPageAction(QWebEnginePage::Undo); } void WebView::editRedo() { triggerPageAction(QWebEnginePage::Redo); } void WebView::editCut() { triggerPageAction(QWebEnginePage::Cut); } void WebView::editCopy() { triggerPageAction(QWebEnginePage::Copy); } void WebView::editPaste() { triggerPageAction(QWebEnginePage::Paste); } void WebView::editSelectAll() { triggerPageAction(QWebEnginePage::SelectAll); } void WebView::editDelete() { QKeyEvent ev(QEvent::KeyPress, Qt::Key_Delete, Qt::NoModifier); QApplication::sendEvent(this, &ev); } void WebView::reloadBypassCache() { triggerPageAction(QWebEnginePage::ReloadAndBypassCache); } void WebView::back() { QWebEngineHistory* history = page()->history(); if (history->canGoBack()) { history->back(); emit urlChanged(url()); } } void WebView::forward() { QWebEngineHistory* history = page()->history(); if (history->canGoForward()) { history->forward(); emit urlChanged(url()); } } void WebView::printPage() { Q_ASSERT(m_page); QPrintPreviewDialog* dialog = new QPrintPreviewDialog(this); dialog->setAttribute(Qt::WA_DeleteOnClose); dialog->resize(800, 750); - dialog->printer()->setCreator(tr("QupZilla %1 (%2)").arg(Qz::VERSION, Qz::WWWADDRESS)); + dialog->printer()->setCreator(tr("Falkon %1 (%2)").arg(Qz::VERSION, Qz::WWWADDRESS)); dialog->printer()->setDocName(QzTools::getFileNameFromUrl(m_page->url())); connect(dialog, &QPrintPreviewDialog::paintRequested, this, [=](QPrinter *printer) { QApplication::setOverrideCursor(Qt::WaitCursor); m_page->execPrintPage(printer, 10 * 1000); QApplication::restoreOverrideCursor(); }); dialog->open(); } void WebView::slotLoadStarted() { m_progress = 0; } void WebView::slotLoadProgress(int progress) { if (m_progress < 100) { m_progress = progress; } // QtWebEngine sometimes forgets applied zoom factor if (!qFuzzyCompare(zoomFactor(), zoomLevels().at(m_currentZoomLevel) / 100.0)) { applyZoom(); } } void WebView::slotLoadFinished(bool ok) { m_progress = 100; if (ok) mApp->history()->addHistoryEntry(this); } void WebView::slotIconChanged() { IconProvider::instance()->saveIcon(this); } void WebView::slotUrlChanged(const QUrl &url) { Q_UNUSED(url) // Don't save blank page / speed dial in tab history if (!history()->canGoForward() && history()->backItems(1).size() == 1) { const QString s = LocationBar::convertUrlToText(history()->backItem().url()); if (s.isEmpty()) history()->clear(); } } void WebView::slotTitleChanged(const QString &title) { Q_UNUSED(title) if (!isVisible() && !isLoading() && !m_backgroundActivity) { m_backgroundActivity = true; emit backgroundActivityChanged(m_backgroundActivity); } } void WebView::openUrlInNewWindow() { if (QAction* action = qobject_cast(sender())) { mApp->createWindow(Qz::BW_NewWindow, action->data().toUrl()); } } void WebView::sendTextByMail() { if (QAction* action = qobject_cast(sender())) { const QUrl mailUrl = QUrl::fromEncoded("mailto:%20?body=" + QUrl::toPercentEncoding(action->data().toString())); QDesktopServices::openUrl(mailUrl); } } void WebView::sendPageByMail() { const QUrl mailUrl = QUrl::fromEncoded("mailto:%20?body=" + QUrl::toPercentEncoding(url().toEncoded()) + "&subject=" + QUrl::toPercentEncoding(title())); QDesktopServices::openUrl(mailUrl); } void WebView::copyLinkToClipboard() { if (QAction* action = qobject_cast(sender())) { QApplication::clipboard()->setText(action->data().toUrl().toEncoded()); } } void WebView::savePageAs() { triggerPageAction(QWebEnginePage::SavePage); } void WebView::copyImageToClipboard() { triggerPageAction(QWebEnginePage::CopyImageToClipboard); } void WebView::downloadLinkToDisk() { triggerPageAction(QWebEnginePage::DownloadLinkToDisk); } void WebView::downloadImageToDisk() { triggerPageAction(QWebEnginePage::DownloadImageToDisk); } void WebView::downloadMediaToDisk() { triggerPageAction(QWebEnginePage::DownloadMediaToDisk); } void WebView::openUrlInNewTab(const QUrl &url, Qz::NewTabPositionFlags position) { loadInNewTab(url, position); } void WebView::openActionUrl() { if (QAction* action = qobject_cast(sender())) { load(action->data().toUrl()); } } void WebView::showSource() { // view-source: doesn't work on itself and custom schemes - if (url().scheme() == QL1S("view-source") || url().scheme() == QL1S("qupzilla") || url().scheme() == QL1S("qrc")) { + if (url().scheme() == QL1S("view-source") || url().scheme() == QL1S("falkon") || url().scheme() == QL1S("qrc")) { page()->toHtml([](const QString &html) { std::cout << html.toLocal8Bit().constData() << std::endl; }); return; } triggerPageAction(QWebEnginePage::ViewSource); } void WebView::showSiteInfo() { SiteInfo* s = new SiteInfo(this); s->show(); } void WebView::searchSelectedText() { SearchEngine engine = mApp->searchEnginesManager()->activeEngine(); if (QAction* act = qobject_cast(sender())) { if (act->data().isValid()) { engine = act->data().value(); } } const LoadRequest req = mApp->searchEnginesManager()->searchResult(engine, selectedText()); loadInNewTab(req, Qz::NT_SelectedTab); } void WebView::searchSelectedTextInBackgroundTab() { SearchEngine engine = mApp->searchEnginesManager()->activeEngine(); if (QAction* act = qobject_cast(sender())) { if (act->data().isValid()) { engine = act->data().value(); } } const LoadRequest req = mApp->searchEnginesManager()->searchResult(engine, selectedText()); loadInNewTab(req, Qz::NT_NotSelectedTab); } void WebView::bookmarkLink() { if (QAction* action = qobject_cast(sender())) { if (action->data().isNull()) { BookmarksTools::addBookmarkDialog(this, url(), title()); } else { const QVariantList bData = action->data().value(); const QString bookmarkTitle = bData.at(1).toString().isEmpty() ? title() : bData.at(1).toString(); BookmarksTools::addBookmarkDialog(this, bData.at(0).toUrl(), bookmarkTitle); } } } void WebView::openUrlInSelectedTab() { if (QAction* action = qobject_cast(sender())) { openUrlInNewTab(action->data().toUrl(), Qz::NT_CleanSelectedTab); } } void WebView::openUrlInBackgroundTab() { if (QAction* action = qobject_cast(sender())) { openUrlInNewTab(action->data().toUrl(), Qz::NT_CleanNotSelectedTab); } } void WebView::userDefinedOpenUrlInNewTab(const QUrl &url, bool invert) { Qz::NewTabPositionFlags position = qzSettings->newTabPosition; if (invert) { if (position & Qz::NT_SelectedTab) { position &= ~Qz::NT_SelectedTab; position |= Qz::NT_NotSelectedTab; } else { position &= ~Qz::NT_NotSelectedTab; position |= Qz::NT_SelectedTab; } } QUrl actionUrl; if (!url.isEmpty()) { actionUrl = url; } else if (QAction* action = qobject_cast(sender())) { actionUrl = action->data().toUrl(); } openUrlInNewTab(actionUrl, position); } void WebView::userDefinedOpenUrlInBgTab(const QUrl &url) { QUrl actionUrl; if (!url.isEmpty()) { actionUrl = url; } else if (QAction* action = qobject_cast(sender())) { actionUrl = action->data().toUrl(); } userDefinedOpenUrlInNewTab(actionUrl, true); } void WebView::showEvent(QShowEvent *event) { QWebEngineView::showEvent(event); if (m_backgroundActivity) { m_backgroundActivity = false; emit backgroundActivityChanged(m_backgroundActivity); } } void WebView::createContextMenu(QMenu *menu, WebHitTestResult &hitTest) { // cppcheck-suppress variableScope int spellCheckActionCount = 0; const QWebEngineContextMenuData &contextMenuData = page()->contextMenuData(); hitTest.updateWithContextMenuData(contextMenuData); if (!contextMenuData.misspelledWord().isEmpty()) { QFont boldFont = menu->font(); boldFont.setBold(true); for (const QString &suggestion : contextMenuData.spellCheckerSuggestions()) { QAction *action = menu->addAction(suggestion); action->setFont(boldFont); connect(action, &QAction::triggered, this, [=]() { page()->replaceMisspelledWord(suggestion); }); } if (menu->actions().isEmpty()) { menu->addAction(tr("No suggestions"))->setEnabled(false); } menu->addSeparator(); spellCheckActionCount = menu->actions().count(); } if (!hitTest.linkUrl().isEmpty() && hitTest.linkUrl().scheme() != QL1S("javascript")) { createLinkContextMenu(menu, hitTest); } if (!hitTest.imageUrl().isEmpty()) { createImageContextMenu(menu, hitTest); } if (!hitTest.mediaUrl().isEmpty()) { createMediaContextMenu(menu, hitTest); } if (hitTest.isContentEditable()) { // This only checks if the menu is empty (only spellchecker actions added) if (menu->actions().count() == spellCheckActionCount) { menu->addAction(pageAction(QWebEnginePage::Undo)); menu->addAction(pageAction(QWebEnginePage::Redo)); menu->addSeparator(); menu->addAction(pageAction(QWebEnginePage::Cut)); menu->addAction(pageAction(QWebEnginePage::Copy)); menu->addAction(pageAction(QWebEnginePage::Paste)); } if (hitTest.tagName() == QL1S("input")) { QAction *act = menu->addAction(QString()); act->setVisible(false); checkForForm(act, hitTest.pos()); } } if (!selectedText().isEmpty()) { createSelectedTextContextMenu(menu, hitTest); } if (menu->isEmpty()) { createPageContextMenu(menu); } menu->addSeparator(); mApp->plugins()->populateWebViewMenu(menu, this, hitTest); } void WebView::createPageContextMenu(QMenu* menu) { QAction* action = menu->addAction(tr("&Back"), this, SLOT(back())); action->setIcon(IconProvider::standardIcon(QStyle::SP_ArrowBack)); action->setEnabled(history()->canGoBack()); action = menu->addAction(tr("&Forward"), this, SLOT(forward())); action->setIcon(IconProvider::standardIcon(QStyle::SP_ArrowForward)); action->setEnabled(history()->canGoForward()); // Special menu for Speed Dial page - if (url().toString() == QL1S("qupzilla:speeddial")) { + if (url().toString() == QL1S("falkon:speeddial")) { menu->addSeparator(); menu->addAction(QIcon::fromTheme("list-add"), tr("&Add New Page"), this, SLOT(addSpeedDial())); menu->addAction(IconProvider::settingsIcon(), tr("&Configure Speed Dial"), this, SLOT(configureSpeedDial())); menu->addSeparator(); menu->addAction(QIcon::fromTheme(QSL("view-refresh")), tr("Reload All Dials"), this, SLOT(reloadAllSpeedDials())); return; } QAction *reloadAction = pageAction(QWebEnginePage::Reload); action = menu->addAction(reloadAction->icon(), reloadAction->text(), reloadAction, &QAction::trigger); action->setVisible(reloadAction->isEnabled()); connect(reloadAction, &QAction::changed, action, [=]() { action->setVisible(reloadAction->isEnabled()); }); QAction *stopAction = pageAction(QWebEnginePage::Stop); action = menu->addAction(stopAction->icon(), stopAction->text(), stopAction, &QAction::trigger); action->setVisible(stopAction->isEnabled()); connect(stopAction, &QAction::changed, action, [=]() { action->setVisible(stopAction->isEnabled()); }); menu->addSeparator(); menu->addAction(QIcon::fromTheme("bookmark-new"), tr("Book&mark page"), this, SLOT(bookmarkLink())); menu->addAction(QIcon::fromTheme("document-save"), tr("&Save page as..."), this, SLOT(savePageAs())); menu->addAction(QIcon::fromTheme("edit-copy"), tr("&Copy page link"), this, SLOT(copyLinkToClipboard()))->setData(url()); menu->addAction(QIcon::fromTheme("mail-message-new"), tr("Send page link..."), this, SLOT(sendPageByMail())); menu->addSeparator(); menu->addAction(QIcon::fromTheme("edit-select-all"), tr("Select &all"), this, SLOT(editSelectAll())); menu->addSeparator(); if (url().scheme() == QLatin1String("http") || url().scheme() == QLatin1String("https")) { const QUrl w3url = QUrl::fromEncoded("http://validator.w3.org/check?uri=" + QUrl::toPercentEncoding(url().toEncoded())); menu->addAction(QIcon(":icons/sites/w3.png"), tr("Validate page"), this, SLOT(openUrlInSelectedTab()))->setData(w3url); QByteArray langCode = mApp->currentLanguage().left(2).toUtf8(); const QUrl gturl = QUrl::fromEncoded("http://translate.google.com/translate?sl=auto&tl=" + langCode + "&u=" + QUrl::toPercentEncoding(url().toEncoded())); menu->addAction(QIcon(":icons/sites/translate.png"), tr("Translate page"), this, SLOT(openUrlInSelectedTab()))->setData(gturl); } menu->addSeparator(); menu->addAction(QIcon::fromTheme("text-html"), tr("Show so&urce code"), this, SLOT(showSource())); if (SiteInfo::canShowSiteInfo(url())) menu->addAction(QIcon::fromTheme("dialog-information"), tr("Show info ab&out site"), this, SLOT(showSiteInfo())); } void WebView::createLinkContextMenu(QMenu* menu, const WebHitTestResult &hitTest) { menu->addSeparator(); Action* act = new Action(IconProvider::newTabIcon(), tr("Open link in new &tab")); act->setData(hitTest.linkUrl()); connect(act, SIGNAL(triggered()), this, SLOT(userDefinedOpenUrlInNewTab())); connect(act, SIGNAL(ctrlTriggered()), this, SLOT(userDefinedOpenUrlInBgTab())); menu->addAction(act); menu->addAction(IconProvider::newWindowIcon(), tr("Open link in new &window"), this, SLOT(openUrlInNewWindow()))->setData(hitTest.linkUrl()); menu->addAction(IconProvider::privateBrowsingIcon(), tr("Open link in &private window"), mApp, SLOT(startPrivateBrowsing()))->setData(hitTest.linkUrl()); menu->addSeparator(); QVariantList bData; bData << hitTest.linkUrl() << hitTest.linkTitle(); menu->addAction(QIcon::fromTheme("bookmark-new"), tr("B&ookmark link"), this, SLOT(bookmarkLink()))->setData(bData); menu->addAction(QIcon::fromTheme("document-save"), tr("&Save link as..."), this, SLOT(downloadLinkToDisk())); menu->addAction(QIcon::fromTheme("mail-message-new"), tr("Send link..."), this, SLOT(sendTextByMail()))->setData(hitTest.linkUrl().toEncoded()); menu->addAction(QIcon::fromTheme("edit-copy"), tr("&Copy link address"), this, SLOT(copyLinkToClipboard()))->setData(hitTest.linkUrl()); menu->addSeparator(); if (!selectedText().isEmpty()) { pageAction(QWebEnginePage::Copy)->setIcon(QIcon::fromTheme("edit-copy")); menu->addAction(pageAction(QWebEnginePage::Copy)); } } void WebView::createImageContextMenu(QMenu* menu, const WebHitTestResult &hitTest) { menu->addSeparator(); Action* act = new Action(tr("Show i&mage")); act->setData(hitTest.imageUrl()); connect(act, SIGNAL(triggered()), this, SLOT(openActionUrl())); connect(act, SIGNAL(ctrlTriggered()), this, SLOT(userDefinedOpenUrlInNewTab())); menu->addAction(act); menu->addAction(tr("Copy image"), this, SLOT(copyImageToClipboard())); menu->addAction(QIcon::fromTheme("edit-copy"), tr("Copy image ad&dress"), this, SLOT(copyLinkToClipboard()))->setData(hitTest.imageUrl()); menu->addSeparator(); menu->addAction(QIcon::fromTheme("document-save"), tr("&Save image as..."), this, SLOT(downloadImageToDisk())); menu->addAction(QIcon::fromTheme("mail-message-new"), tr("Send image..."), this, SLOT(sendTextByMail()))->setData(hitTest.imageUrl().toEncoded()); menu->addSeparator(); if (!selectedText().isEmpty()) { pageAction(QWebEnginePage::Copy)->setIcon(QIcon::fromTheme("edit-copy")); menu->addAction(pageAction(QWebEnginePage::Copy)); } } void WebView::createSelectedTextContextMenu(QMenu* menu, const WebHitTestResult &hitTest) { Q_UNUSED(hitTest) QString selectedText = page()->selectedText(); menu->addSeparator(); if (!menu->actions().contains(pageAction(QWebEnginePage::Copy))) { menu->addAction(pageAction(QWebEnginePage::Copy)); } menu->addAction(QIcon::fromTheme("mail-message-new"), tr("Send text..."), this, SLOT(sendTextByMail()))->setData(selectedText); menu->addSeparator(); QString langCode = mApp->currentLanguage().left(2).toUtf8(); QUrl googleTranslateUrl = QUrl(QString("https://translate.google.com/#auto/%1/%2").arg(langCode, selectedText)); Action* gtwact = new Action(QIcon(":icons/sites/translate.png"), tr("Google Translate")); gtwact->setData(googleTranslateUrl); connect(gtwact, SIGNAL(triggered()), this, SLOT(openUrlInSelectedTab())); connect(gtwact, SIGNAL(ctrlTriggered()), this, SLOT(openUrlInBackgroundTab())); menu->addAction(gtwact); Action* dictact = new Action(QIcon::fromTheme("accessories-dictionary"), tr("Dictionary")); dictact->setData(QUrl("http://" + (!langCode.isEmpty() ? langCode + "." : langCode) + "wiktionary.org/wiki/Special:Search?search=" + selectedText)); connect(dictact, SIGNAL(triggered()), this, SLOT(openUrlInSelectedTab())); connect(dictact, SIGNAL(ctrlTriggered()), this, SLOT(openUrlInBackgroundTab())); menu->addAction(dictact); // #379: Remove newlines QString selectedString = selectedText.trimmed().remove(QLatin1Char('\n')); if (!selectedString.contains(QLatin1Char('.'))) { // Try to add .com selectedString.append(QLatin1String(".com")); } QUrl guessedUrl = QUrl::fromUserInput(selectedString); if (isUrlValid(guessedUrl)) { Action* act = new Action(QIcon::fromTheme("document-open-remote"), tr("Go to &web address")); act->setData(guessedUrl); connect(act, SIGNAL(triggered()), this, SLOT(openActionUrl())); connect(act, SIGNAL(ctrlTriggered()), this, SLOT(userDefinedOpenUrlInNewTab())); menu->addAction(act); } menu->addSeparator(); selectedText.truncate(20); // KDE is displaying newlines in menu actions ... weird -,- selectedText.replace(QLatin1Char('\n'), QLatin1Char(' ')).replace(QLatin1Char('\t'), QLatin1Char(' ')); SearchEngine engine = mApp->searchEnginesManager()->activeEngine(); Action* act = new Action(engine.icon, tr("Search \"%1 ..\" with %2").arg(selectedText, engine.name)); connect(act, SIGNAL(triggered()), this, SLOT(searchSelectedText())); connect(act, SIGNAL(ctrlTriggered()), this, SLOT(searchSelectedTextInBackgroundTab())); menu->addAction(act); // Search with ... Menu* swMenu = new Menu(tr("Search with..."), menu); swMenu->setCloseOnMiddleClick(true); SearchEnginesManager* searchManager = mApp->searchEnginesManager(); foreach (const SearchEngine &en, searchManager->allEngines()) { Action* act = new Action(en.icon, en.name); act->setData(QVariant::fromValue(en)); connect(act, SIGNAL(triggered()), this, SLOT(searchSelectedText())); connect(act, SIGNAL(ctrlTriggered()), this, SLOT(searchSelectedTextInBackgroundTab())); swMenu->addAction(act); } menu->addMenu(swMenu); } void WebView::createMediaContextMenu(QMenu *menu, const WebHitTestResult &hitTest) { bool paused = hitTest.mediaPaused(); bool muted = hitTest.mediaMuted(); menu->addSeparator(); menu->addAction(paused ? tr("&Play") : tr("&Pause"), this, SLOT(toggleMediaPause()))->setIcon(QIcon::fromTheme(paused ? "media-playback-start" : "media-playback-pause")); menu->addAction(muted ? tr("Un&mute") : tr("&Mute"), this, SLOT(toggleMediaMute()))->setIcon(QIcon::fromTheme(muted ? "audio-volume-muted" : "audio-volume-high")); menu->addSeparator(); menu->addAction(QIcon::fromTheme("edit-copy"), tr("&Copy Media Address"), this, SLOT(copyLinkToClipboard()))->setData(hitTest.mediaUrl()); menu->addAction(QIcon::fromTheme("mail-message-new"), tr("&Send Media Address"), this, SLOT(sendTextByMail()))->setData(hitTest.mediaUrl().toEncoded()); menu->addAction(QIcon::fromTheme("document-save"), tr("Save Media To &Disk"), this, SLOT(downloadMediaToDisk())); } void WebView::checkForForm(QAction *action, const QPoint &pos) { m_clickedPos = mapToViewport(pos); QPointer act = action; page()->runJavaScript(Scripts::getFormData(m_clickedPos), WebPage::SafeJsWorld, [this, act](const QVariant &res) { const QVariantMap &map = res.toMap(); if (!act || map.isEmpty()) return; const QUrl url = map.value(QSL("action")).toUrl(); const QString method = map.value(QSL("method")).toString(); if (!url.isEmpty() && (method == QL1S("get") || method == QL1S("post"))) { act->setVisible(true); act->setIcon(QIcon::fromTheme(QSL("edit-find"), QIcon(QSL(":icons/menu/search-icon.svg")))); act->setText(tr("Create Search Engine")); connect(act.data(), &QAction::triggered, this, &WebView::createSearchEngine); } }); } void WebView::createSearchEngine() { page()->runJavaScript(Scripts::getFormData(m_clickedPos), WebPage::SafeJsWorld, [this](const QVariant &res) { mApp->searchEnginesManager()->addEngineFromForm(res.toMap(), this); }); } void WebView::addSpeedDial() { page()->runJavaScript("addSpeedDial()"); } void WebView::configureSpeedDial() { page()->runJavaScript("configureSpeedDial()"); } void WebView::reloadAllSpeedDials() { page()->runJavaScript("reloadAll()"); } void WebView::toggleMediaPause() { triggerPageAction(QWebEnginePage::ToggleMediaPlayPause); } void WebView::toggleMediaMute() { triggerPageAction(QWebEnginePage::ToggleMediaMute); } void WebView::initializeActions() { QAction* undoAction = pageAction(QWebEnginePage::Undo); undoAction->setText(tr("&Undo")); undoAction->setShortcut(QKeySequence("Ctrl+Z")); undoAction->setShortcutContext(Qt::WidgetWithChildrenShortcut); undoAction->setIcon(QIcon::fromTheme(QSL("edit-undo"))); QAction* redoAction = pageAction(QWebEnginePage::Redo); redoAction->setText(tr("&Redo")); redoAction->setShortcut(QKeySequence("Ctrl+Shift+Z")); redoAction->setShortcutContext(Qt::WidgetWithChildrenShortcut); redoAction->setIcon(QIcon::fromTheme(QSL("edit-redo"))); QAction* cutAction = pageAction(QWebEnginePage::Cut); cutAction->setText(tr("&Cut")); cutAction->setShortcut(QKeySequence("Ctrl+X")); cutAction->setShortcutContext(Qt::WidgetWithChildrenShortcut); cutAction->setIcon(QIcon::fromTheme(QSL("edit-cut"))); QAction* copyAction = pageAction(QWebEnginePage::Copy); copyAction->setText(tr("&Copy")); copyAction->setShortcut(QKeySequence("Ctrl+C")); copyAction->setShortcutContext(Qt::WidgetWithChildrenShortcut); copyAction->setIcon(QIcon::fromTheme(QSL("edit-copy"))); QAction* pasteAction = pageAction(QWebEnginePage::Paste); pasteAction->setText(tr("&Paste")); pasteAction->setShortcut(QKeySequence("Ctrl+V")); pasteAction->setShortcutContext(Qt::WidgetWithChildrenShortcut); pasteAction->setIcon(QIcon::fromTheme(QSL("edit-paste"))); QAction* selectAllAction = pageAction(QWebEnginePage::SelectAll); selectAllAction->setText(tr("Select All")); selectAllAction->setShortcut(QKeySequence("Ctrl+A")); selectAllAction->setShortcutContext(Qt::WidgetWithChildrenShortcut); selectAllAction->setIcon(QIcon::fromTheme(QSL("edit-select-all"))); QAction* reloadAction = pageAction(QWebEnginePage::Reload); reloadAction->setText(tr("&Reload")); reloadAction->setIcon(QIcon::fromTheme(QSL("view-refresh"))); QAction* stopAction = pageAction(QWebEnginePage::Stop); stopAction->setText(tr("S&top")); stopAction->setIcon(QIcon::fromTheme(QSL("process-stop"))); // Make action shortcuts available for webview addAction(undoAction); addAction(redoAction); addAction(cutAction); addAction(copyAction); addAction(pasteAction); addAction(selectAllAction); } void WebView::_wheelEvent(QWheelEvent *event) { if (mApp->plugins()->processWheelEvent(Qz::ON_WebView, this, event)) { event->accept(); return; } if (event->modifiers() & Qt::ControlModifier) { m_wheelHelper.processEvent(event); while (WheelHelper::Direction direction = m_wheelHelper.takeDirection()) { switch (direction) { case WheelHelper::WheelUp: case WheelHelper::WheelLeft: zoomIn(); break; case WheelHelper::WheelDown: case WheelHelper::WheelRight: zoomOut(); break; default: break; } } event->accept(); return; } m_wheelHelper.reset(); // QtWebEngine ignores QApplication::wheelScrollLines() and instead always scrolls 3 lines if (event->spontaneous()) { const qreal multiplier = QApplication::wheelScrollLines() / 3.0; if (multiplier != 1.0) { QWheelEvent e(event->pos(), event->globalPos(), event->pixelDelta(), event->angleDelta() * multiplier, 0, Qt::Horizontal, event->buttons(), event->modifiers(), event->phase(), event->source(), event->inverted()); QApplication::sendEvent(m_rwhvqt, &e); event->accept(); } } } void WebView::_mousePressEvent(QMouseEvent *event) { m_clickedUrl = QUrl(); m_clickedPos = QPointF(); if (mApp->plugins()->processMousePress(Qz::ON_WebView, this, event)) { event->accept(); return; } switch (event->button()) { case Qt::XButton1: back(); event->accept(); break; case Qt::XButton2: forward(); event->accept(); break; case Qt::MiddleButton: m_clickedUrl = page()->hitTestContent(event->pos()).linkUrl(); if (!m_clickedUrl.isEmpty()) event->accept(); break; case Qt::LeftButton: m_clickedUrl = page()->hitTestContent(event->pos()).linkUrl(); break; default: break; } } void WebView::_mouseReleaseEvent(QMouseEvent *event) { if (mApp->plugins()->processMouseRelease(Qz::ON_WebView, this, event)) { event->accept(); return; } switch (event->button()) { case Qt::MiddleButton: if (!m_clickedUrl.isEmpty()) { const QUrl link = page()->hitTestContent(event->pos()).linkUrl(); if (m_clickedUrl == link && isUrlValid(link)) { userDefinedOpenUrlInNewTab(link, event->modifiers() & Qt::ShiftModifier); event->accept(); } } break; case Qt::LeftButton: if (!m_clickedUrl.isEmpty()) { const QUrl link = page()->hitTestContent(event->pos()).linkUrl(); if (m_clickedUrl == link && isUrlValid(link)) { if (event->modifiers() & Qt::ControlModifier) { userDefinedOpenUrlInNewTab(link, event->modifiers() & Qt::ShiftModifier); event->accept(); } } } break; case Qt::RightButton: if (s_forceContextMenuOnMouseRelease) { QContextMenuEvent ev(QContextMenuEvent::Mouse, event->pos(), event->globalPos(), event->modifiers()); _contextMenuEvent(&ev); event->accept(); } break; default: break; } } void WebView::_mouseMoveEvent(QMouseEvent *event) { if (mApp->plugins()->processMouseMove(Qz::ON_WebView, this, event)) { event->accept(); } } void WebView::_keyPressEvent(QKeyEvent *event) { if (mApp->plugins()->processKeyPress(Qz::ON_WebView, this, event)) { event->accept(); return; } switch (event->key()) { case Qt::Key_ZoomIn: zoomIn(); event->accept(); break; case Qt::Key_ZoomOut: zoomOut(); event->accept(); break; case Qt::Key_Plus: if (event->modifiers() & Qt::ControlModifier) { zoomIn(); event->accept(); } break; case Qt::Key_Minus: if (event->modifiers() & Qt::ControlModifier) { zoomOut(); event->accept(); } break; case Qt::Key_0: if (event->modifiers() & Qt::ControlModifier) { zoomReset(); event->accept(); } break; case Qt::Key_M: if (event->modifiers() & Qt::ControlModifier) { page()->setAudioMuted(!page()->isAudioMuted()); event->accept(); } break; default: break; } } void WebView::_keyReleaseEvent(QKeyEvent *event) { if (mApp->plugins()->processKeyRelease(Qz::ON_WebView, this, event)) { event->accept(); } switch (event->key()) { case Qt::Key_Escape: if (isFullScreen()) { triggerPageAction(QWebEnginePage::ExitFullScreen); event->accept(); } break; default: break; } } void WebView::_contextMenuEvent(QContextMenuEvent *event) { Q_UNUSED(event) } void WebView::resizeEvent(QResizeEvent *event) { QWebEngineView::resizeEvent(event); emit viewportResized(size()); } void WebView::contextMenuEvent(QContextMenuEvent *event) { // Context menu is created in mouseReleaseEvent if (s_forceContextMenuOnMouseRelease) return; const QPoint pos = event->pos(); const QContextMenuEvent::Reason reason = event->reason(); QTimer::singleShot(0, this, [this, pos, reason]() { QContextMenuEvent ev(reason, pos); _contextMenuEvent(&ev); }); } void WebView::loadRequest(const LoadRequest &req) { #if QT_VERSION >= QT_VERSION_CHECK(5, 9, 0) QWebEngineView::load(req.webRequest()); #else if (req.operation() == LoadRequest::GetOperation) load(req.url()); else page()->runJavaScript(Scripts::sendPostData(req.url(), req.data()), WebPage::SafeJsWorld); #endif } bool WebView::eventFilter(QObject *obj, QEvent *event) { // Keyboard events are sent to parent widget if (obj == this && event->type() == QEvent::ParentChange && parentWidget()) { parentWidget()->installEventFilter(this); } // Forward events to WebView #define HANDLE_EVENT(f, t) \ { \ bool wasAccepted = event->isAccepted(); \ event->setAccepted(false); \ f(static_cast(event)); \ bool ret = event->isAccepted(); \ event->setAccepted(wasAccepted); \ return ret; \ } if (obj == m_rwhvqt) { switch (event->type()) { case QEvent::MouseButtonPress: HANDLE_EVENT(_mousePressEvent, QMouseEvent); case QEvent::MouseButtonRelease: HANDLE_EVENT(_mouseReleaseEvent, QMouseEvent); case QEvent::MouseMove: HANDLE_EVENT(_mouseMoveEvent, QMouseEvent); case QEvent::Wheel: HANDLE_EVENT(_wheelEvent, QWheelEvent); default: break; } } if (obj == parentWidget()) { switch (event->type()) { case QEvent::KeyPress: HANDLE_EVENT(_keyPressEvent, QKeyEvent); case QEvent::KeyRelease: HANDLE_EVENT(_keyReleaseEvent, QKeyEvent); default: break; } } #undef HANDLE_EVENT // Block already handled events if (obj == this) { switch (event->type()) { case QEvent::KeyPress: case QEvent::KeyRelease: case QEvent::MouseButtonPress: case QEvent::MouseButtonRelease: case QEvent::MouseMove: case QEvent::Wheel: return true; case QEvent::Hide: if (isFullScreen()) { triggerPageAction(QWebEnginePage::ExitFullScreen); } break; default: break; } } const bool res = QWebEngineView::eventFilter(obj, event); if (obj == m_rwhvqt) { switch (event->type()) { case QEvent::FocusIn: case QEvent::FocusOut: emit focusChanged(hasFocus()); break; default: break; } } return res; } diff --git a/src/lib/webengine/webview.h b/src/lib/webengine/webview.h index 0b1920f2..f352273b 100644 --- a/src/lib/webengine/webview.h +++ b/src/lib/webengine/webview.h @@ -1,197 +1,197 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef WEBVIEW_H #define WEBVIEW_H #include #include #include "qzcommon.h" #include "loadrequest.h" #include "wheelhelper.h" class WebPage; class LoadRequest; class WebHitTestResult; -class QUPZILLA_EXPORT WebView : public QWebEngineView +class FALKON_EXPORT WebView : public QWebEngineView { Q_OBJECT public: explicit WebView(QWidget* parent = 0); ~WebView(); QIcon icon(bool allowNull = false) const; QString title() const; bool isTitleEmpty() const; WebPage* page() const; void setPage(WebPage* page); void load(const QUrl &url); void load(const LoadRequest &request); bool isLoading() const; int loadingProgress() const; bool backgroundActivity() const; // Set zoom level (0 - 17) int zoomLevel() const; void setZoomLevel(int level); QPointF mapToViewport(const QPointF &pos) const; QRect scrollBarGeometry(Qt::Orientation orientation) const; void addNotification(QWidget* notif); bool eventFilter(QObject *obj, QEvent *event); QWidget *inputWidget() const; virtual QWidget *overlayWidget() = 0; static bool isUrlValid(const QUrl &url); static QList zoomLevels(); // Force context menu event to be sent on mouse release // This allows to override right mouse button events (eg. for mouse gestures) static bool forceContextMenuOnMouseRelease(); static void setForceContextMenuOnMouseRelease(bool force); signals: void focusChanged(bool); void viewportResized(QSize); void showNotification(QWidget*); void privacyChanged(bool); void zoomLevelChanged(int); void backgroundActivityChanged(bool); public slots: void zoomIn(); void zoomOut(); void zoomReset(); void editUndo(); void editRedo(); void editCut(); void editCopy(); void editPaste(); void editSelectAll(); void editDelete(); void reloadBypassCache(); void back(); void forward(); void printPage(); void showSource(); void sendPageByMail(); void openUrlInNewTab(const QUrl &url, Qz::NewTabPositionFlags position); virtual void closeView() = 0; virtual void loadInNewTab(const LoadRequest &req, Qz::NewTabPositionFlags position) = 0; virtual bool isFullScreen() = 0; virtual void requestFullScreen(bool enable) = 0; protected slots: void slotLoadStarted(); void slotLoadProgress(int progress); void slotLoadFinished(bool ok); void slotIconChanged(); void slotUrlChanged(const QUrl &url); void slotTitleChanged(const QString &title); // Context menu slots void openUrlInNewWindow(); void sendTextByMail(); void copyLinkToClipboard(); void savePageAs(); void copyImageToClipboard(); void downloadLinkToDisk(); void downloadImageToDisk(); void downloadMediaToDisk(); void openActionUrl(); void showSiteInfo(); void searchSelectedText(); void searchSelectedTextInBackgroundTab(); void bookmarkLink(); void openUrlInSelectedTab(); void openUrlInBackgroundTab(); // To support user's option whether to open in selected or background tab void userDefinedOpenUrlInNewTab(const QUrl &url = QUrl(), bool invert = false); void userDefinedOpenUrlInBgTab(const QUrl &url = QUrl()); protected: void showEvent(QShowEvent *event) override; void resizeEvent(QResizeEvent *event); void contextMenuEvent(QContextMenuEvent *event); virtual void _wheelEvent(QWheelEvent *event); virtual void _mousePressEvent(QMouseEvent *event); virtual void _mouseReleaseEvent(QMouseEvent *event); virtual void _mouseMoveEvent(QMouseEvent *event); virtual void _keyPressEvent(QKeyEvent *event); virtual void _keyReleaseEvent(QKeyEvent *event); virtual void _contextMenuEvent(QContextMenuEvent *event); void loadRequest(const LoadRequest &req); void applyZoom(); void createContextMenu(QMenu *menu, WebHitTestResult &hitTest); void createPageContextMenu(QMenu *menu); void createLinkContextMenu(QMenu *menu, const WebHitTestResult &hitTest); void createImageContextMenu(QMenu *menu, const WebHitTestResult &hitTest); void createSelectedTextContextMenu(QMenu *menu, const WebHitTestResult &hitTest); void createMediaContextMenu(QMenu *menu, const WebHitTestResult &hitTest); void checkForForm(QAction *action, const QPoint &pos); void createSearchEngine(); private slots: void addSpeedDial(); void configureSpeedDial(); void reloadAllSpeedDials(); void toggleMediaPause(); void toggleMediaMute(); private: void initializeActions(); int m_currentZoomLevel; int m_progress; bool m_backgroundActivity; QUrl m_clickedUrl; QPointF m_clickedPos; WebPage* m_page; bool m_firstLoad; QPointer m_rwhvqt; WheelHelper m_wheelHelper; static bool s_forceContextMenuOnMouseRelease; }; #endif // WEBVIEW_H diff --git a/src/lib/webtab/searchtoolbar.cpp b/src/lib/webtab/searchtoolbar.cpp index d233fc80..f5247874 100644 --- a/src/lib/webtab/searchtoolbar.cpp +++ b/src/lib/webtab/searchtoolbar.cpp @@ -1,152 +1,152 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "searchtoolbar.h" #include "tabbedwebview.h" #include "webpage.h" #include "lineedit.h" #include "ui_searchtoolbar.h" #include "iconprovider.h" #include #include SearchToolBar::SearchToolBar(WebView* view, QWidget* parent) : QWidget(parent) , ui(new Ui::SearchToolbar) , m_view(view) , m_findFlags(0) { setAttribute(Qt::WA_DeleteOnClose); ui->setupUi(this); ui->closeButton->setIcon(IconProvider::instance()->standardIcon(QStyle::SP_DialogCloseButton)); ui->next->setIcon(IconProvider::instance()->standardIcon(QStyle::SP_ArrowDown)); ui->previous->setIcon(IconProvider::instance()->standardIcon(QStyle::SP_ArrowUp)); connect(ui->closeButton, SIGNAL(clicked()), this, SLOT(close())); connect(ui->lineEdit, SIGNAL(textChanged(QString)), this, SLOT(findNext())); connect(ui->lineEdit, SIGNAL(returnPressed()), this, SLOT(findNext())); connect(ui->next, SIGNAL(clicked()), this, SLOT(findNext())); connect(ui->previous, SIGNAL(clicked()), this, SLOT(findPrevious())); connect(ui->caseSensitive, SIGNAL(clicked()), this, SLOT(caseSensitivityChanged())); QShortcut* findNextAction = new QShortcut(QKeySequence("F3"), this); connect(findNextAction, SIGNAL(activated()), this, SLOT(findNext())); QShortcut* findPreviousAction = new QShortcut(QKeySequence("Shift+F3"), this); connect(findPreviousAction, SIGNAL(activated()), this, SLOT(findPrevious())); parent->installEventFilter(this); } void SearchToolBar::showMinimalInPopupWindow() { // Show only essentials widget + set minimum width ui->caseSensitive->hide(); ui->results->hide(); ui->horizontalLayout->setSpacing(2); ui->horizontalLayout->setContentsMargins(2, 6, 2, 6); setMinimumWidth(260); } void SearchToolBar::focusSearchLine() { ui->lineEdit->setFocus(); } void SearchToolBar::close() { hide(); searchText(QString()); m_view->setFocus(); deleteLater(); } void SearchToolBar::findNext() { m_findFlags = 0; updateFindFlags(); searchText(ui->lineEdit->text()); } void SearchToolBar::findPrevious() { m_findFlags = QWebEnginePage::FindBackward; updateFindFlags(); searchText(ui->lineEdit->text()); } void SearchToolBar::updateFindFlags() { if (ui->caseSensitive->isChecked()) { m_findFlags = m_findFlags | QWebEnginePage::FindCaseSensitively; } else { m_findFlags = m_findFlags & ~QWebEnginePage::FindCaseSensitively; } } void SearchToolBar::caseSensitivityChanged() { updateFindFlags(); searchText(QString()); searchText(ui->lineEdit->text()); } void SearchToolBar::searchText(const QString &text) { QPointer guard = this; m_view->findText(text, m_findFlags, [=](bool found) { if (!guard) { return; } if (ui->lineEdit->text().isEmpty()) found = true; if (!found) ui->results->setText(tr("No results found.")); else ui->results->clear(); ui->lineEdit->setProperty("notfound", QVariant(!found)); ui->lineEdit->style()->unpolish(ui->lineEdit); ui->lineEdit->style()->polish(ui->lineEdit); // Clear selection m_view->page()->runJavaScript(QSL("window.getSelection().empty();")); }); } bool SearchToolBar::eventFilter(QObject* obj, QEvent* event) { Q_UNUSED(obj); if (event->type() == QEvent::KeyPress && static_cast(event)->key() == Qt::Key_Escape) { close(); } return false; } SearchToolBar::~SearchToolBar() { delete ui; } diff --git a/src/lib/webtab/searchtoolbar.h b/src/lib/webtab/searchtoolbar.h index 02eb02aa..b7cd9fbc 100644 --- a/src/lib/webtab/searchtoolbar.h +++ b/src/lib/webtab/searchtoolbar.h @@ -1,66 +1,66 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef SEARCHTOOLBAR_H #define SEARCHTOOLBAR_H #include #include "qzcommon.h" namespace Ui { class SearchToolbar; } class QLineEdit; class WebView; class LineEdit; -class QUPZILLA_EXPORT SearchToolBar : public QWidget +class FALKON_EXPORT SearchToolBar : public QWidget { Q_OBJECT public: explicit SearchToolBar(WebView* view, QWidget* parent = 0); ~SearchToolBar(); void showMinimalInPopupWindow(); void focusSearchLine(); bool eventFilter(QObject* obj, QEvent* event); signals: public slots: void searchText(const QString &text); void updateFindFlags(); void caseSensitivityChanged(); void findNext(); void findPrevious(); void close(); private: Ui::SearchToolbar* ui; WebView* m_view; QWebEnginePage::FindFlags m_findFlags; }; #endif // SEARCHTOOLBAR_H diff --git a/src/lib/webtab/tabbedwebview.cpp b/src/lib/webtab/tabbedwebview.cpp index 286f32a4..9b40d1a9 100644 --- a/src/lib/webtab/tabbedwebview.cpp +++ b/src/lib/webtab/tabbedwebview.cpp @@ -1,235 +1,235 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "tabbedwebview.h" #include "browserwindow.h" #include "webpage.h" #include "tabwidget.h" #include "mainapplication.h" #include "tabbar.h" #include "webtab.h" #include "statusbarmessage.h" #include "progressbar.h" #include "navigationbar.h" #include "iconprovider.h" #include "searchenginesmanager.h" #include "enhancedmenu.h" #include "adblockicon.h" #include "locationbar.h" #include "webhittestresult.h" #include "webinspector.h" #include #include TabbedWebView::TabbedWebView(WebTab* webTab) : WebView(webTab) , m_window(0) , m_webTab(webTab) , m_menu(new Menu(this)) { m_menu->setCloseOnMiddleClick(true); connect(this, SIGNAL(loadStarted()), this, SLOT(slotLoadStarted())); connect(this, SIGNAL(loadProgress(int)), this, SLOT(slotLoadProgress(int))); connect(this, SIGNAL(loadFinished(bool)), this, SLOT(slotLoadFinished())); connect(this, SIGNAL(urlChanged(QUrl)), this, SLOT(urlChanged(QUrl))); } void TabbedWebView::setWebPage(WebPage* page) { page->setParent(this); setPage(page); connect(page, &WebPage::linkHovered, this, &TabbedWebView::linkHovered); } BrowserWindow* TabbedWebView::browserWindow() const { return m_window; } void TabbedWebView::setBrowserWindow(BrowserWindow* window) { m_window = window; } void TabbedWebView::inspectElement() { if (m_webTab->haveInspector()) triggerPageAction(QWebEnginePage::InspectElement); else m_webTab->showWebInspector(true); } WebTab* TabbedWebView::webTab() const { return m_webTab; } QString TabbedWebView::getIp() const { return m_currentIp; } void TabbedWebView::urlChanged(const QUrl &url) { Q_UNUSED(url) if (m_webTab->isCurrentTab() && m_window) { m_window->navigationBar()->refreshHistory(); } } void TabbedWebView::slotLoadProgress(int prog) { Q_UNUSED(prog) if (m_webTab->isCurrentTab() && m_window) { m_window->updateLoadingActions(); } } void TabbedWebView::userLoadAction(const LoadRequest &req) { load(req); } void TabbedWebView::slotLoadStarted() { m_currentIp.clear(); } void TabbedWebView::slotLoadFinished() { QHostInfo::lookupHost(url().host(), this, SLOT(setIp(QHostInfo))); if (m_webTab->isCurrentTab() && m_window) { m_window->updateLoadingActions(); } } void TabbedWebView::setIp(const QHostInfo &info) { if (info.addresses().isEmpty()) { return; } m_currentIp = QString("%1 (%2)").arg(info.hostName(), info.addresses().at(0).toString()); if (m_webTab->isCurrentTab()) { emit ipChanged(m_currentIp); } } void TabbedWebView::linkHovered(const QString &link) { if (m_webTab->isCurrentTab() && m_window) { if (link.isEmpty()) { m_window->statusBarMessage()->clearMessage(); } else { m_window->statusBarMessage()->showMessage(link); } } } int TabbedWebView::tabIndex() const { return m_webTab->tabIndex(); } QWidget* TabbedWebView::overlayWidget() { return m_webTab; } void TabbedWebView::closeView() { emit wantsCloseTab(tabIndex()); } void TabbedWebView::loadInNewTab(const LoadRequest &req, Qz::NewTabPositionFlags position) { if (m_window) { int index = m_window->tabWidget()->addView(QUrl(), position); m_window->weView(index)->webTab()->locationBar()->showUrl(req.url()); m_window->weView(index)->load(req); } } bool TabbedWebView::isFullScreen() { return m_window && m_window->isFullScreen(); } void TabbedWebView::requestFullScreen(bool enable) { if (!m_window) return; m_window->toggleHtmlFullScreen(enable); } void TabbedWebView::setAsCurrentTab() { if (m_window) { m_window->tabWidget()->setCurrentWidget(m_webTab); } } void TabbedWebView::_contextMenuEvent(QContextMenuEvent *event) { m_menu->clear(); WebHitTestResult hitTest = page()->hitTestContent(event->pos()); createContextMenu(m_menu, hitTest); if (!hitTest.isContentEditable() && !hitTest.isContentSelected() && m_window) { m_menu->addAction(m_window->adBlockIcon()->menuAction()); } if (WebInspector::isEnabled()) { m_menu->addSeparator(); m_menu->addAction(tr("Inspect Element"), this, SLOT(inspectElement())); } if (!m_menu->isEmpty()) { // Prevent choosing first option with double rightclick const QPoint pos = event->globalPos(); QPoint p(pos.x(), pos.y() + 1); m_menu->popup(p); return; } WebView::_contextMenuEvent(event); } void TabbedWebView::_mouseMoveEvent(QMouseEvent *event) { if (m_window && m_window->isFullScreen()) { if (m_window->fullScreenNavigationVisible()) { m_window->hideNavigationWithFullScreen(); } else if (event->y() < 5) { m_window->showNavigationWithFullScreen(); } } WebView::_mouseMoveEvent(event); } diff --git a/src/lib/webtab/tabbedwebview.h b/src/lib/webtab/tabbedwebview.h index 0e5c2c6b..b30f1b11 100644 --- a/src/lib/webtab/tabbedwebview.h +++ b/src/lib/webtab/tabbedwebview.h @@ -1,86 +1,86 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2015 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef TABBEDWEBVIEW_H #define TABBEDWEBVIEW_H #include "qzcommon.h" #include "webview.h" class QLabel; class QHostInfo; class BrowserWindow; class TabWidget; class WebPage; class WebTab; class Menu; -class QUPZILLA_EXPORT TabbedWebView : public WebView +class FALKON_EXPORT TabbedWebView : public WebView { Q_OBJECT public: explicit TabbedWebView(WebTab* webTab); void setWebPage(WebPage* page); // BrowserWindow can be null! BrowserWindow* browserWindow() const; void setBrowserWindow(BrowserWindow* window); WebTab* webTab() const; QString getIp() const; int tabIndex() const; QWidget* overlayWidget() Q_DECL_OVERRIDE; void closeView() Q_DECL_OVERRIDE; void loadInNewTab(const LoadRequest &req, Qz::NewTabPositionFlags position) Q_DECL_OVERRIDE; bool isFullScreen() Q_DECL_OVERRIDE; void requestFullScreen(bool enable) Q_DECL_OVERRIDE; signals: void wantsCloseTab(int); void ipChanged(QString); public slots: void setAsCurrentTab(); void userLoadAction(const LoadRequest &req); private slots: void slotLoadStarted(); void slotLoadFinished(); void slotLoadProgress(int prog); void urlChanged(const QUrl &url); void linkHovered(const QString &link); void setIp(const QHostInfo &info); void inspectElement(); private: void _contextMenuEvent(QContextMenuEvent *event) Q_DECL_OVERRIDE; void _mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE; BrowserWindow* m_window; WebTab* m_webTab; Menu* m_menu; QString m_currentIp; }; #endif // TABBEDWEBVIEW_H diff --git a/src/lib/webtab/webtab.cpp b/src/lib/webtab/webtab.cpp index 3e63da4d..8cdaefd3 100644 --- a/src/lib/webtab/webtab.cpp +++ b/src/lib/webtab/webtab.cpp @@ -1,523 +1,523 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "webtab.h" #include "browserwindow.h" #include "tabbedwebview.h" #include "webinspector.h" #include "webpage.h" #include "tabbar.h" #include "tabicon.h" #include "tabwidget.h" #include "locationbar.h" #include "qztools.h" #include "qzsettings.h" #include "mainapplication.h" #include "iconprovider.h" #include "searchtoolbar.h" #include #include #include #include #include bool WebTab::s_pinningTab = false; static const int savedTabVersion = 3; WebTab::SavedTab::SavedTab() : isPinned(false) , zoomLevel(qzSettings->defaultZoomLevel) { } WebTab::SavedTab::SavedTab(WebTab* webTab) { - if (webTab->url().toString() == QL1S("qupzilla:restore")) { + if (webTab->url().toString() == QL1S("falkon:restore")) { return; } title = webTab->title(); url = webTab->url(); icon = webTab->icon(true); history = webTab->historyData(); isPinned = webTab->isPinned(); zoomLevel = webTab->zoomLevel(); } bool WebTab::SavedTab::isValid() const { return !url.isEmpty(); } void WebTab::SavedTab::clear() { title.clear(); url.clear(); icon = QIcon(); history.clear(); isPinned = false; zoomLevel = qzSettings->defaultZoomLevel; } QDataStream &operator <<(QDataStream &stream, const WebTab::SavedTab &tab) { stream << savedTabVersion; stream << tab.title; stream << tab.url; stream << tab.icon.pixmap(16); stream << tab.history; stream << tab.isPinned; stream << tab.zoomLevel; return stream; } QDataStream &operator >>(QDataStream &stream, WebTab::SavedTab &tab) { int version; stream >> version; if (version < 1) return stream; QPixmap pixmap; stream >> tab.title; stream >> tab.url; stream >> pixmap; stream >> tab.history; if (version >= 2) stream >> tab.isPinned; if (version >= 3) stream >> tab.zoomLevel; tab.icon = QIcon(pixmap); return stream; } WebTab::WebTab(BrowserWindow* window) : QWidget() , m_window(window) , m_tabBar(0) , m_isPinned(false) { setObjectName(QSL("webtab")); m_webView = new TabbedWebView(this); m_webView->setBrowserWindow(m_window); m_webView->setWebPage(new WebPage); m_webView->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding); m_locationBar = new LocationBar(m_window); m_locationBar->setWebView(m_webView); m_tabIcon = new TabIcon(this); m_tabIcon->setWebTab(this); m_layout = new QVBoxLayout(this); m_layout->setContentsMargins(0, 0, 0, 0); m_layout->setSpacing(0); m_layout->addWidget(m_webView); QWidget *viewWidget = new QWidget(this); viewWidget->setLayout(m_layout); m_splitter = new QSplitter(Qt::Vertical, this); m_splitter->setChildrenCollapsible(false); m_splitter->addWidget(viewWidget); QVBoxLayout *layout = new QVBoxLayout(this); layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(0); layout->addWidget(m_splitter); setLayout(layout); m_notificationWidget = new QWidget(this); m_notificationWidget->setAutoFillBackground(true); QPalette pal = m_notificationWidget->palette(); pal.setColor(QPalette::Background, pal.window().color().darker(110)); m_notificationWidget->setPalette(pal); QVBoxLayout *nlayout = new QVBoxLayout(m_notificationWidget); nlayout->setSizeConstraint(QLayout::SetMinAndMaxSize); nlayout->setContentsMargins(0, 0, 0, 0); nlayout->setSpacing(1); connect(m_webView, SIGNAL(showNotification(QWidget*)), this, SLOT(showNotification(QWidget*))); connect(m_webView, SIGNAL(loadStarted()), this, SLOT(loadStarted())); connect(m_webView, SIGNAL(loadFinished(bool)), this, SLOT(loadFinished())); connect(m_webView, SIGNAL(titleChanged(QString)), this, SLOT(titleChanged(QString))); // Workaround QTabBar not immediately noticing resizing of tab buttons connect(m_tabIcon, &TabIcon::resized, this, [this]() { if (m_tabBar) { m_tabBar->setTabButton(tabIndex(), m_tabBar->iconButtonPosition(), m_tabIcon); } }); } TabbedWebView* WebTab::webView() const { return m_webView; } bool WebTab::haveInspector() const { return m_splitter->count() > 1 && m_splitter->widget(1)->inherits("WebInspector"); } void WebTab::showWebInspector(bool inspectElement) { if (!WebInspector::isEnabled() || haveInspector()) return; WebInspector *inspector = new WebInspector(this); inspector->setView(m_webView); if (inspectElement) inspector->inspectElement(); m_splitter->addWidget(inspector); } void WebTab::toggleWebInspector() { if (!haveInspector()) showWebInspector(); else delete m_splitter->widget(1); } void WebTab::showSearchToolBar() { const int index = 1; SearchToolBar *toolBar = nullptr; if (m_layout->count() == 1) { toolBar = new SearchToolBar(m_webView, this); m_layout->insertWidget(index, toolBar); } else if (m_layout->count() == 2) { Q_ASSERT(qobject_cast(m_layout->itemAt(index)->widget())); toolBar = static_cast(m_layout->itemAt(index)->widget()); } Q_ASSERT(toolBar); toolBar->focusSearchLine(); } QUrl WebTab::url() const { if (isRestored()) { return m_webView->url(); } else { return m_savedTab.url; } } QString WebTab::title() const { if (isRestored()) { return m_webView->title(); } else { return m_savedTab.title; } } QIcon WebTab::icon(bool allowNull) const { if (isRestored()) { return m_webView->icon(allowNull); } if (allowNull || !m_savedTab.icon.isNull()) { return m_savedTab.icon; } return IconProvider::emptyWebIcon(); } QWebEngineHistory* WebTab::history() const { return m_webView->history(); } int WebTab::zoomLevel() const { return m_webView->zoomLevel(); } void WebTab::setZoomLevel(int level) { m_webView->setZoomLevel(level); } void WebTab::detach() { Q_ASSERT(m_tabBar); // Remove icon from tab m_tabBar->setTabButton(tabIndex(), m_tabBar->iconButtonPosition(), 0); // Remove the tab from tabbar setParent(0); // Remove the locationbar from window m_locationBar->setParent(this); // Detach TabbedWebView m_webView->setBrowserWindow(0); // WebTab is now standalone widget m_window = 0; m_tabBar = 0; } void WebTab::attach(BrowserWindow* window) { m_window = window; m_tabBar = m_window->tabWidget()->tabBar(); m_webView->setBrowserWindow(m_window); m_tabBar->setTabText(tabIndex(), title()); m_tabBar->setTabButton(tabIndex(), m_tabBar->iconButtonPosition(), m_tabIcon); m_tabIcon->updateIcon(); } QByteArray WebTab::historyData() const { if (isRestored()) { QByteArray historyArray; QDataStream historyStream(&historyArray, QIODevice::WriteOnly); historyStream << *m_webView->history(); return historyArray; } else { return m_savedTab.history; } } void WebTab::reload() { m_webView->reload(); } void WebTab::stop() { m_webView->stop(); } bool WebTab::isLoading() const { return m_webView->isLoading(); } bool WebTab::isPinned() const { return m_isPinned; } void WebTab::setPinned(bool state) { m_isPinned = state; } bool WebTab::isMuted() const { return m_webView->page()->isAudioMuted(); } void WebTab::setMuted(bool muted) { m_webView->page()->setAudioMuted(muted); } void WebTab::toggleMuted() { bool muted = isMuted(); setMuted(!muted); } LocationBar* WebTab::locationBar() const { return m_locationBar; } TabIcon* WebTab::tabIcon() const { return m_tabIcon; } bool WebTab::isRestored() const { return !m_savedTab.isValid(); } void WebTab::restoreTab(const WebTab::SavedTab &tab) { Q_ASSERT(m_tabBar); m_isPinned = tab.isPinned; if (!m_isPinned && qzSettings->loadTabsOnActivation) { m_savedTab = tab; int index = tabIndex(); m_tabBar->setTabText(index, tab.title); m_locationBar->showUrl(tab.url); m_tabIcon->updateIcon(); if (!tab.url.isEmpty()) { QColor col = m_tabBar->palette().text().color(); QColor newCol = col.lighter(250); // It won't work for black color because (V) = 0 // It won't also work for white, as white won't get any lighter if (col == Qt::black || col == Qt::white) { newCol = Qt::gray; } m_tabBar->overrideTabTextColor(index, newCol); } } else { // This is called only on restore session and restoring tabs immediately // crashes QtWebEngine, waiting after initialization is complete fixes it QTimer::singleShot(1000, this, [=]() { p_restoreTab(tab); }); } } void WebTab::p_restoreTab(const QUrl &url, const QByteArray &history, int zoomLevel) { m_webView->load(url); // Restoring history of internal pages crashes QtWebEngine 5.8 static const QStringList blacklistedSchemes = { QSL("view-source"), QSL("chrome") }; if (!blacklistedSchemes.contains(url.scheme())) { QDataStream stream(history); stream >> *m_webView->history(); } m_webView->setZoomLevel(zoomLevel); m_webView->setFocus(); } void WebTab::p_restoreTab(const WebTab::SavedTab &tab) { p_restoreTab(tab.url, tab.history, tab.zoomLevel); } void WebTab::showNotification(QWidget* notif) { m_notificationWidget->setParent(nullptr); m_notificationWidget->setParent(this); m_notificationWidget->setFixedWidth(width()); m_notificationWidget->layout()->addWidget(notif); m_notificationWidget->show(); notif->show(); } void WebTab::loadStarted() { if (m_tabBar && m_webView->isTitleEmpty()) { m_tabBar->setTabText(tabIndex(), tr("Loading...")); } } void WebTab::loadFinished() { titleChanged(m_webView->title()); } void WebTab::titleChanged(const QString &title) { if (!m_tabBar || !m_window || title.isEmpty()) { return; } if (isCurrentTab()) { - m_window->setWindowTitle(tr("%1 - QupZilla").arg(title)); + m_window->setWindowTitle(tr("%1 - Falkon").arg(title)); } m_tabBar->setTabText(tabIndex(), title); } void WebTab::slotRestore() { Q_ASSERT(m_tabBar); p_restoreTab(m_savedTab); m_savedTab.clear(); m_tabBar->restoreTabTextColor(tabIndex()); } void WebTab::showEvent(QShowEvent* event) { QWidget::showEvent(event); if (!isRestored() && !s_pinningTab) { // When session is being restored, restore the tab immediately if (mApp->isRestoring()) { slotRestore(); } else { QTimer::singleShot(0, this, SLOT(slotRestore())); } } } void WebTab::resizeEvent(QResizeEvent *event) { QWidget::resizeEvent(event); m_notificationWidget->setFixedWidth(width()); } bool WebTab::isCurrentTab() const { return m_tabBar && tabIndex() == m_tabBar->currentIndex(); } int WebTab::tabIndex() const { Q_ASSERT(m_tabBar); return m_tabBar->tabWidget()->indexOf(const_cast(this)); } void WebTab::togglePinned() { Q_ASSERT(m_tabBar); Q_ASSERT(m_window); m_isPinned = !m_isPinned; // Workaround bug in TabStackedWidget when pinning tab, other tabs may be accidentaly // shown and restored state even when they won't be switched to by user. s_pinningTab = true; m_window->tabWidget()->pinUnPinTab(tabIndex(), title()); s_pinningTab = false; } diff --git a/src/lib/webtab/webtab.h b/src/lib/webtab/webtab.h index b08dbc61..fee25eff 100644 --- a/src/lib/webtab/webtab.h +++ b/src/lib/webtab/webtab.h @@ -1,134 +1,134 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef WEBTAB_H #define WEBTAB_H #include #include #include #include "qzcommon.h" class QVBoxLayout; class QWebEngineHistory; class QSplitter; class BrowserWindow; class TabbedWebView; class WebInspector; class LocationBar; class TabIcon; class TabBar; -class QUPZILLA_EXPORT WebTab : public QWidget +class FALKON_EXPORT WebTab : public QWidget { Q_OBJECT public: struct SavedTab { QString title; QUrl url; QIcon icon; QByteArray history; bool isPinned; int zoomLevel; SavedTab(); SavedTab(WebTab* webTab); bool isValid() const; void clear(); - friend QUPZILLA_EXPORT QDataStream &operator<<(QDataStream &stream, const SavedTab &tab); - friend QUPZILLA_EXPORT QDataStream &operator>>(QDataStream &stream, SavedTab &tab); + friend FALKON_EXPORT QDataStream &operator<<(QDataStream &stream, const SavedTab &tab); + friend FALKON_EXPORT QDataStream &operator>>(QDataStream &stream, SavedTab &tab); }; explicit WebTab(BrowserWindow* window); TabbedWebView* webView() const; LocationBar* locationBar() const; TabIcon* tabIcon() const; QUrl url() const; QString title() const; QIcon icon(bool allowNull = false) const; QWebEngineHistory* history() const; int zoomLevel() const; void setZoomLevel(int level); void detach(); void attach(BrowserWindow* window); QByteArray historyData() const; void stop(); void reload(); bool isLoading() const; bool isPinned() const; void setPinned(bool state); void togglePinned(); bool isMuted() const; void setMuted(bool muted); void toggleMuted(); int tabIndex() const; bool isCurrentTab() const; bool haveInspector() const; void showWebInspector(bool inspectElement = false); void toggleWebInspector(); void showSearchToolBar(); bool isRestored() const; void restoreTab(const SavedTab &tab); void p_restoreTab(const SavedTab &tab); void p_restoreTab(const QUrl &url, const QByteArray &history, int zoomLevel); private slots: void showNotification(QWidget* notif); void loadStarted(); void loadFinished(); void titleChanged(const QString &title); void slotRestore(); private: void showEvent(QShowEvent* event); void resizeEvent(QResizeEvent *event) override; BrowserWindow* m_window; QVBoxLayout* m_layout; QSplitter* m_splitter; TabbedWebView* m_webView; WebInspector* m_inspector; LocationBar* m_locationBar; TabIcon* m_tabIcon; TabBar* m_tabBar; QWidget *m_notificationWidget; SavedTab m_savedTab; bool m_isPinned; static bool s_pinningTab; }; #endif // WEBTAB_H diff --git a/src/main/Info.plist b/src/main/Info.plist index e75d29a1..62533275 100644 --- a/src/main/Info.plist +++ b/src/main/Info.plist @@ -1,73 +1,73 @@ CFBundleIconFile @ICON@ CFBundlePackageType APPL CFBundleGetInfoString 2.1.2 CFBundleVersion 2.1.2 CFBundleSignature @TYPEINFO@ CFBundleExecutable @EXECUTABLE@ CFBundleIdentifier - com.qupzilla.QupZilla + org.kde.Falkon CFBundleURLTypes CFBundleURLIconFile @ICON@ CFBundleURLName http URL CFBundleURLSchemes http https CFBundleDocumentTypes CFBundleTypeExtensions html htm shtml xhtml CFBundleTypeIconFile @ICON@ CFBundleTypeName HTML Document CFBundleTypeOSTypes HTML CFBundleTypeRole Viewer CFBundleDevelopmentRegion English CFBundleName - QupZilla + Falkon CFBundleDisplayName - QupZilla + Falkon LSApplicationCategoryType public.app-category.productivity NSPrincipalClass NSApplication NSHighResolutionCapable diff --git a/src/main/appicon.rc b/src/main/appicon.rc index 154dbcb1..1d24ee83 100644 --- a/src/main/appicon.rc +++ b/src/main/appicon.rc @@ -1,33 +1,33 @@ -#include "winver.h" - -IDI_ICON1 ICON DISCARDABLE "..\lib\data\icons\exeicons\qupzilla.ico" -IDI_ICON2 ICON DISCARDABLE "..\lib\data\icons\exeicons\page.ico" - -VS_VERSION_INFO VERSIONINFO - FILEVERSION 2,1,2,0 - PRODUCTVERSION 2,1,2,0 - FILEFLAGS 0x0L - FILEFLAGSMASK 0x3fL - FILEOS 0x00040004L - FILETYPE 0x1L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "000004b0" - BEGIN - VALUE "CompanyName", "QupZilla Team" - VALUE "FileDescription", "QupZilla Web Browser" - VALUE "FileVersion", "2.1.2" - VALUE "LegalCopyright", "Copyright (C) 2010-2017 David Rosca" - VALUE "InternalName", "qupzilla" - VALUE "OriginalFilename", "qupzilla.exe" - VALUE "ProductName", "QupZilla" - VALUE "ProductVersion", "2.1.2" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x0, 1200 - END -END +#include "winver.h" + +IDI_ICON1 ICON DISCARDABLE "..\lib\data\icons\exeicons\qupzilla.ico" +IDI_ICON2 ICON DISCARDABLE "..\lib\data\icons\exeicons\page.ico" + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 2,1,2,0 + PRODUCTVERSION 2,1,2,0 + FILEFLAGS 0x0L + FILEFLAGSMASK 0x3fL + FILEOS 0x00040004L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "000004b0" + BEGIN + VALUE "CompanyName", "Falkon Team" + VALUE "FileDescription", "Falkon Web Browser" + VALUE "FileVersion", "2.1.2" + VALUE "LegalCopyright", "Copyright (C) 2010-2017 David Rosca" + VALUE "InternalName", "falkon" + VALUE "OriginalFilename", "falkon.exe" + VALUE "ProductName", "Falkon" + VALUE "ProductVersion", "2.1.2" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0, 1200 + END +END diff --git a/src/main/main.cpp b/src/main/main.cpp index 9c10a22d..c1af1b6f 100644 --- a/src/main/main.cpp +++ b/src/main/main.cpp @@ -1,156 +1,156 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "mainapplication.h" #include "proxystyle.h" #include "datapaths.h" #include // For QT_REQUIRE_VERSION #include #if defined(Q_OS_LINUX) || defined(__GLIBC__) || defined(__FreeBSD__) || defined(__HAIKU__) #include #include #include #include #include #include -void qupzilla_signal_handler(int s) +void falkon_signal_handler(int s) { if (s != SIGSEGV) { return; } static bool sigSegvServed = false; if (sigSegvServed) { abort(); } sigSegvServed = true; - std::cout << "QupZilla: Crashed :( Saving backtrace in " << qPrintable(DataPaths::path(DataPaths::Config)) << "/crashlog ..." << std::endl; + std::cout << "Falkon: Crashed :( Saving backtrace in " << qPrintable(DataPaths::path(DataPaths::Config)) << "/crashlog ..." << std::endl; void* array[100]; int size = backtrace(array, 100); char** strings = backtrace_symbols(array, size); if (size < 0 || !strings) { std::cout << "Cannot get backtrace!" << std::endl; abort(); } QDir dir(DataPaths::path(DataPaths::Config)); if (!dir.exists()) { std::cout << qPrintable(DataPaths::path(DataPaths::Config)) << " does not exist" << std::endl; abort(); } if (!dir.cd("crashlog")) { if (!dir.mkdir("crashlog")) { std::cout << "Cannot create " << qPrintable(DataPaths::path(DataPaths::Config)) << "crashlog directory!" << std::endl; abort(); } dir.cd("crashlog"); } const QDateTime currentDateTime = QDateTime::currentDateTime(); QFile file(dir.absoluteFilePath("Crash-" + currentDateTime.toString(Qt::ISODate) + ".txt")); if (!file.open(QFile::WriteOnly | QFile::Truncate)) { std::cout << "Cannot open file " << qPrintable(file.fileName()) << " for writing!" << std::endl; abort(); } QTextStream stream(&file); stream << "Time: " << currentDateTime.toString() << endl; stream << "Qt version: " << qVersion() << " (compiled with " << QT_VERSION_STR << ")" << endl; - stream << "QupZilla version: " << Qz::VERSION << endl; + stream << "Falkon version: " << Qz::VERSION << endl; stream << "Rendering engine: QtWebEngine" << endl; stream << endl; stream << "============== BACKTRACE ==============" << endl; for (int i = 0; i < size; ++i) { stream << "#" << i << ": " << strings[i] << endl; } file.close(); std::cout << "Backtrace successfully saved in " << qPrintable(dir.absoluteFilePath(file.fileName())) << std::endl; } #endif // defined(Q_OS_LINUX) || defined(__GLIBC__) || defined(__FreeBSD__) #ifndef Q_OS_WIN void msgHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg) { if (msg.startsWith(QL1S("QSslSocket: cannot resolve SSL"))) return; if (msg.startsWith(QL1S("Remote debugging server started successfully."))) return; switch (type) { case QtDebugMsg: case QtInfoMsg: case QtWarningMsg: case QtCriticalMsg: std::cerr << qPrintable(qFormatLogMessage(type, context, msg)) << std::endl; break; case QtFatalMsg: std::cerr << "Fatal: " << qPrintable(qFormatLogMessage(type, context, msg)) << std::endl; abort(); default: break; } } #endif int main(int argc, char* argv[]) { QT_REQUIRE_VERSION(argc, argv, "5.8.0"); #ifndef Q_OS_WIN qInstallMessageHandler(&msgHandler); #endif #if defined(Q_OS_LINUX) || defined(__GLIBC__) || defined(__FreeBSD__) - signal(SIGSEGV, qupzilla_signal_handler); + signal(SIGSEGV, falkon_signal_handler); #endif // Hack to fix QT_STYLE_OVERRIDE with QProxyStyle const QByteArray style = qgetenv("QT_STYLE_OVERRIDE"); if (!style.isEmpty()) { char** args = (char**) malloc(sizeof(char*) * (argc + 1)); for (int i = 0; i < argc; ++i) args[i] = argv[i]; QString stylecmd = QL1S("-style=") + style; args[argc++] = qstrdup(stylecmd.toUtf8().constData()); argv = args; } MainApplication app(argc, argv); if (app.isClosing()) return 0; app.setProxyStyle(new ProxyStyle); return app.exec(); } diff --git a/src/main/main.pro b/src/main/main.pro index 5dfe1dc3..ee9ae20b 100644 --- a/src/main/main.pro +++ b/src/main/main.pro @@ -1,49 +1,49 @@ include(../defines.pri) QT += webenginecore webenginewidgets network widgets sql -TARGET = qupzilla -mac: TARGET = QupZilla +TARGET = falkon +mac: TARGET = Falkon TEMPLATE = app compile_libtool { -LIBS += $$QZ_DESTDIR/libQupZilla.la +LIBS += $$QZ_DESTDIR/libFalkon.la } else { -!unix|mac: LIBS += -L$$QZ_DESTDIR -lQupZilla -!mac:unix: LIBS += $$QZ_DESTDIR/libQupZilla.so +!unix|mac: LIBS += -L$$QZ_DESTDIR -lFalkon +!mac:unix: LIBS += $$QZ_DESTDIR/libFalkon.so } unix:!contains(DEFINES, "DISABLE_DBUS") QT += dbus INCLUDEPATH += ../lib/3rdparty \ ../lib/app \ ../lib/session \ ../lib/webengine \ ../lib/webtab \ DEPENDPATH += $$INCLUDEPATH SOURCES = main.cpp OTHER_FILES += appicon.rc \ appicon_os2.rc \ Info.plist \ os2:RC_FILE = appicon_os2.rc win32:RC_FILE = appicon.rc openbsd-*|freebsd-*|haiku-* { LIBS += -lexecinfo } include(../install.pri) unix:contains(DEFINES, "NO_SYSTEM_DATAPATH") { # For running the app without installing it QMAKE_LFLAGS+=$${QMAKE_LFLAGS_RPATH}\\$\$ORIGIN # For running the app after installation QMAKE_LFLAGS+=$${QMAKE_LFLAGS_RPATH}$${library_folder} message(QMAKE_LFLAGS: $$QMAKE_LFLAGS) } diff --git a/src/plugins.pri b/src/plugins.pri index 27d7cc0e..92f6f362 100644 --- a/src/plugins.pri +++ b/src/plugins.pri @@ -1,58 +1,58 @@ include(defines.pri) INCLUDEPATH += $$PWD/lib/3rdparty \ $$PWD/lib/adblock \ $$PWD/lib/app \ $$PWD/lib/autofill \ $$PWD/lib/bookmarks \ $$PWD/lib/cookies \ $$PWD/lib/downloads \ $$PWD/lib/history \ $$PWD/lib/navigation \ $$PWD/lib/network \ $$PWD/lib/notifications \ $$PWD/lib/opensearch \ $$PWD/lib/other \ $$PWD/lib/plugins \ $$PWD/lib/popupwindow \ $$PWD/lib/preferences \ $$PWD/lib/rss \ $$PWD/lib/session \ $$PWD/lib/sidebar \ $$PWD/lib/tabwidget \ $$PWD/lib/tools \ $$PWD/lib/webengine \ $$PWD/lib/webtab \ DEPENDPATH += $$INCLUDEPATH \ $$PWD/lib/data \ include(lib/3rdparty/qtsingleapplication/qtsingleapplication.pri) TEMPLATE = lib CONFIG += plugin DESTDIR = $$QZ_DESTDIR/plugins/ QT *= webenginecore webenginewidgets network CONFIG += c++11 OBJECTS_DIR = build MOC_DIR = build RCC_DIR = build UI_DIR = build -!unix|mac: LIBS += -L$$QZ_DESTDIR -lQupZilla -!mac:unix: LIBS += $$QZ_DESTDIR/libQupZilla.so +!unix|mac: LIBS += -L$$QZ_DESTDIR -lFalkon +!mac:unix: LIBS += $$QZ_DESTDIR/libFalkon.so !mac:unix { - target.path = $$library_folder/qupzilla + target.path = $$library_folder/falkon INSTALLS += target } updateqm.input = TRANSLATIONS updateqm.output = $$PLUGIN_DIR/locale/${QMAKE_FILE_BASE}.qm updateqm.commands = $$QMAKE_LRELEASE -silent ${QMAKE_FILE_IN} -qm $$PLUGIN_DIR/locale/${QMAKE_FILE_BASE}.qm updateqm.CONFIG += no_link target_predeps QMAKE_EXTRA_COMPILERS += updateqm diff --git a/src/plugins/AutoScroll/autoscroller.cpp b/src/plugins/AutoScroll/autoscroller.cpp index b70082e2..f6342691 100644 --- a/src/plugins/AutoScroll/autoscroller.cpp +++ b/src/plugins/AutoScroll/autoscroller.cpp @@ -1,290 +1,290 @@ /* ============================================================ -* AutoScroll - Autoscroll for QupZilla +* AutoScroll - Autoscroll for Falkon * Copyright (C) 2014-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "autoscroller.h" #include "framescroller.h" #include "webview.h" #include "webpage.h" #include "webhittestresult.h" #include #include #include #include #include ScrollIndicator::ScrollIndicator(QWidget *parent) : QLabel(parent) { resize(33, 33); setContentsMargins(0, 0, 0, 0); } Qt::Orientations ScrollIndicator::orientations() const { return m_orientations; } void ScrollIndicator::setOrientations(Qt::Orientations orientations) { m_orientations = orientations; if (m_orientations == Qt::Vertical) { setPixmap(QIcon(QSL(":/autoscroll/data/scroll_vertical.png")).pixmap(33)); } else if (m_orientations == Qt::Horizontal) { setPixmap(QIcon(QSL(":/autoscroll/data/scroll_horizontal.png")).pixmap(33)); } else { setPixmap(QIcon(QSL(":/autoscroll/data/scroll_all.png")).pixmap(33)); } update(); } void ScrollIndicator::paintEvent(QPaintEvent *event) { QPainter p(this); p.setRenderHint(QPainter::Antialiasing); QRectF r(rect()); r.adjust(1, 1, -1, -1); QColor c1(Qt::gray); c1.setAlpha(190); QColor c2(Qt::white); c2.setAlpha(190); QRadialGradient g(r.center(), r.height() / 2.0); g.setColorAt(1, c1); g.setColorAt(0.7, c2); p.setPen(Qt::NoPen); p.setBrush(g); p.drawEllipse(r); QLabel::paintEvent(event); } AutoScroller::AutoScroller(const QString &settingsFile, QObject* parent) : QObject(parent) , m_view(0) , m_settingsFile(settingsFile) { m_indicator = new ScrollIndicator; m_indicator->installEventFilter(this); QSettings settings(m_settingsFile, QSettings::IniFormat); settings.beginGroup("AutoScroll"); m_frameScroller = new FrameScroller(this); m_frameScroller->setScrollDivider(settings.value("ScrollDivider", 8.0).toDouble()); settings.endGroup(); } AutoScroller::~AutoScroller() { delete m_indicator; } bool AutoScroller::mouseMove(QObject* obj, QMouseEvent* event) { Q_UNUSED(obj) if (m_indicator->isVisible()) { QRect rect = indicatorGlobalRect(); int xlength = 0; int ylength = 0; if (rect.left() > event->globalPos().x()) { xlength = event->globalPos().x() - rect.left(); } else if (rect.right() < event->globalPos().x()) { xlength = event->globalPos().x() - rect.right(); } if (rect.top() > event->globalPos().y()) { ylength = event->globalPos().y() - rect.top(); } else if (rect.bottom() < event->globalPos().y()) { ylength = event->globalPos().y() - rect.bottom(); } if (!m_indicator->orientations().testFlag(Qt::Vertical)) { ylength = 0; } if (!m_indicator->orientations().testFlag(Qt::Horizontal)) { xlength = 0; } m_frameScroller->startScrolling(xlength, ylength); } return false; } bool AutoScroller::mousePress(QObject* obj, QMouseEvent* event) { bool middleButton = event->buttons() == Qt::MiddleButton; WebView* view = qobject_cast(obj); Q_ASSERT(view); // Start? if (m_view != view && middleButton) { return showIndicator(view, event->pos()); } else if (!m_indicator->isVisible() && middleButton) { return showIndicator(view, event->pos()); } // Stop if (m_indicator->isVisible()) { stopScrolling(); return true; } return false; } bool AutoScroller::mouseRelease(QObject* obj, QMouseEvent* event) { Q_UNUSED(obj) if (m_indicator->isVisible()) { if (!indicatorGlobalRect().contains(event->globalPos())) { stopScrolling(); } return true; } return false; } bool AutoScroller::wheel(QObject *obj, QWheelEvent *event) { Q_UNUSED(obj) Q_UNUSED(event); if (m_indicator->isVisible()) { stopScrolling(); return true; } return false; } double AutoScroller::scrollDivider() const { return m_frameScroller->scrollDivider(); } void AutoScroller::setScrollDivider(double divider) { QSettings settings(m_settingsFile, QSettings::IniFormat); settings.beginGroup("AutoScroll"); settings.setValue("ScrollDivider", divider); settings.endGroup(); m_frameScroller->setScrollDivider(divider); } bool AutoScroller::eventFilter(QObject* obj, QEvent* event) { if (obj == m_indicator) { switch (event->type()) { case QEvent::Enter: m_frameScroller->stopScrolling(); break; case QEvent::Wheel: case QEvent::Hide: case QEvent::MouseButtonPress: stopScrolling(); break; default: break; } } return false; } bool AutoScroller::showIndicator(WebView* view, const QPoint &pos) { const WebHitTestResult res = view->page()->hitTestContent(pos); if (res.isContentEditable() || !res.linkUrl().isEmpty() || res.tagName().endsWith(QL1S("frame"))) { return false; } QString source = QL1S("var out = {" " vertical: window.innerWidth > document.documentElement.clientWidth," " horizontal: window.innerHeight > document.documentElement.clientHeight" "};" "out;"); const QVariantMap &map = view->page()->execJavaScript(source, WebPage::SafeJsWorld).toMap(); bool vertical = map.value(QSL("vertical")).toBool(); bool horizontal = map.value(QSL("horizontal")).toBool(); if (!vertical && !horizontal) { return false; } Qt::Orientations orientations; if (vertical) { orientations |= Qt::Vertical; } if (horizontal) { orientations |= Qt::Horizontal; } m_indicator->setOrientations(orientations); m_view = view; QPoint p; p.setX(pos.x() - m_indicator->width() / 2); p.setY(pos.y() - m_indicator->height() / 2); m_indicator->setParent(m_view->overlayWidget()); m_indicator->move(m_view->mapTo(m_view->overlayWidget(), p)); m_indicator->show(); m_frameScroller->setPage(view->page()); m_view->inputWidget()->grabMouse(); QApplication::setOverrideCursor(Qt::ArrowCursor); return true; } void AutoScroller::stopScrolling() { m_view->inputWidget()->releaseMouse(); QApplication::restoreOverrideCursor(); m_indicator->hide(); m_indicator->setParent(0); m_frameScroller->stopScrolling(); } QRect AutoScroller::indicatorGlobalRect() const { QPoint pos = m_indicator->parentWidget()->mapToGlobal(m_indicator->geometry().topLeft()); return QRect(pos.x(), pos.y(), m_indicator->width(), m_indicator->height()); } diff --git a/src/plugins/AutoScroll/autoscroller.h b/src/plugins/AutoScroll/autoscroller.h index b3676d33..b6326227 100644 --- a/src/plugins/AutoScroll/autoscroller.h +++ b/src/plugins/AutoScroll/autoscroller.h @@ -1,74 +1,74 @@ /* ============================================================ -* AutoScroll - Autoscroll for QupZilla +* AutoScroll - Autoscroll for Falkon * Copyright (C) 2014-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef AUTOSCROLLER_H #define AUTOSCROLLER_H #include #include class QMouseEvent; class QWheelEvent; class QRect; class WebView; class FrameScroller; class ScrollIndicator : public QLabel { public: explicit ScrollIndicator(QWidget *parent = nullptr); Qt::Orientations orientations() const; void setOrientations(Qt::Orientations orientations); private: void paintEvent(QPaintEvent *event) override; Qt::Orientations m_orientations; }; class AutoScroller : public QObject { Q_OBJECT public: explicit AutoScroller(const QString &settingsFile, QObject* parent = 0); ~AutoScroller(); bool mouseMove(QObject* obj, QMouseEvent* event); bool mousePress(QObject* obj, QMouseEvent* event); bool mouseRelease(QObject* obj, QMouseEvent* event); bool wheel(QObject* obj, QWheelEvent *event); double scrollDivider() const; void setScrollDivider(double divider); private: bool eventFilter(QObject* obj, QEvent* event); bool showIndicator(WebView* view, const QPoint &pos); void stopScrolling(); QRect indicatorGlobalRect() const; WebView* m_view; ScrollIndicator* m_indicator; FrameScroller* m_frameScroller; QString m_settingsFile; }; #endif // AUTOSCROLLER_H diff --git a/src/plugins/AutoScroll/autoscrollplugin.cpp b/src/plugins/AutoScroll/autoscrollplugin.cpp index d4bc5519..dca80618 100644 --- a/src/plugins/AutoScroll/autoscrollplugin.cpp +++ b/src/plugins/AutoScroll/autoscrollplugin.cpp @@ -1,121 +1,121 @@ /* ============================================================ * AutoScroll - Autoscroll for QupZilla * Copyright (C) 2014-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "autoscrollplugin.h" #include "autoscrollsettings.h" #include "autoscroller.h" #include "browserwindow.h" #include "pluginproxy.h" #include "mainapplication.h" #include AutoScrollPlugin::AutoScrollPlugin() : QObject() , m_scroller(0) { } PluginSpec AutoScrollPlugin::pluginSpec() { PluginSpec spec; spec.name = "AutoScroll"; spec.info = "AutoScroll plugin"; spec.description = "Provides support for autoscroll with middle mouse button"; spec.version = "1.0.1"; spec.author = "David Rosca "; spec.icon = QIcon(QSL(":/autoscroll/data/scroll_all.png")).pixmap(32); spec.hasSettings = true; return spec; } void AutoScrollPlugin::init(InitState state, const QString &settingsPath) { Q_UNUSED(state) m_scroller = new AutoScroller(settingsPath + QL1S("/extensions.ini"), this); QZ_REGISTER_EVENT_HANDLER(PluginProxy::MouseMoveHandler); QZ_REGISTER_EVENT_HANDLER(PluginProxy::MousePressHandler); QZ_REGISTER_EVENT_HANDLER(PluginProxy::MouseReleaseHandler); QZ_REGISTER_EVENT_HANDLER(PluginProxy::WheelEventHandler); } void AutoScrollPlugin::unload() { m_scroller->deleteLater(); } bool AutoScrollPlugin::testPlugin() { // Require the version that the plugin was built with - return (Qz::VERSION == QLatin1String(QUPZILLA_VERSION)); + return (Qz::VERSION == QLatin1String(FALKON_VERSION)); } QTranslator* AutoScrollPlugin::getTranslator(const QString &locale) { QTranslator* translator = new QTranslator(this); translator->load(locale, ":/autoscroll/locale/"); return translator; } void AutoScrollPlugin::showSettings(QWidget* parent) { if (!m_settings) { m_settings = new AutoScrollSettings(m_scroller, parent); } m_settings.data()->show(); m_settings.data()->raise(); } bool AutoScrollPlugin::mouseMove(const Qz::ObjectName &type, QObject* obj, QMouseEvent* event) { if (type == Qz::ON_WebView) { return m_scroller->mouseMove(obj, event); } return false; } bool AutoScrollPlugin::mousePress(const Qz::ObjectName &type, QObject* obj, QMouseEvent* event) { if (type == Qz::ON_WebView) { return m_scroller->mousePress(obj, event); } return false; } bool AutoScrollPlugin::mouseRelease(const Qz::ObjectName &type, QObject* obj, QMouseEvent* event) { if (type == Qz::ON_WebView) { return m_scroller->mouseRelease(obj, event); } return false; } bool AutoScrollPlugin::wheelEvent(const Qz::ObjectName &type, QObject *obj, QWheelEvent *event) { if (type == Qz::ON_WebView) { return m_scroller->wheel(obj, event); } return false; } diff --git a/src/plugins/AutoScroll/autoscrollplugin.h b/src/plugins/AutoScroll/autoscrollplugin.h index 85b49488..603569d8 100644 --- a/src/plugins/AutoScroll/autoscrollplugin.h +++ b/src/plugins/AutoScroll/autoscrollplugin.h @@ -1,53 +1,53 @@ /* ============================================================ * AutoScroll - Autoscroll for QupZilla * Copyright (C) 2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef AUTOSCROLLPLUGIN_H #define AUTOSCROLLPLUGIN_H #include "plugininterface.h" class AutoScroller; class AutoScrollSettings; class AutoScrollPlugin : public QObject, public PluginInterface { Q_OBJECT Q_INTERFACES(PluginInterface) - Q_PLUGIN_METADATA(IID "QupZilla.Browser.plugin.TestPlugin") + Q_PLUGIN_METADATA(IID "Falkon.Browser.plugin.AutoScroll") public: explicit AutoScrollPlugin(); PluginSpec pluginSpec(); void init(InitState state, const QString &settingsPath); void unload(); bool testPlugin(); QTranslator* getTranslator(const QString &locale); void showSettings(QWidget* parent); bool mouseMove(const Qz::ObjectName &type, QObject* obj, QMouseEvent* event); bool mousePress(const Qz::ObjectName &type, QObject* obj, QMouseEvent* event); bool mouseRelease(const Qz::ObjectName &type, QObject* obj, QMouseEvent* event); bool wheelEvent(const Qz::ObjectName &type, QObject *obj, QWheelEvent *event); private: AutoScroller* m_scroller; QPointer m_settings; }; #endif // TESTPLUGIN_H diff --git a/src/plugins/AutoScroll/autoscrollsettings.cpp b/src/plugins/AutoScroll/autoscrollsettings.cpp index 45fd4516..696856c9 100644 --- a/src/plugins/AutoScroll/autoscrollsettings.cpp +++ b/src/plugins/AutoScroll/autoscrollsettings.cpp @@ -1,45 +1,45 @@ /* ============================================================ -* AutoScroll - Autoscroll for QupZilla +* AutoScroll - Autoscroll for Falkon * Copyright (C) 2014-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "autoscrollsettings.h" #include "ui_autoscrollsettings.h" #include "autoscroller.h" AutoScrollSettings::AutoScrollSettings(AutoScroller* scroller, QWidget* parent) : QDialog(parent) , ui(new Ui::AutoScrollSettings) , m_scroller(scroller) { setAttribute(Qt::WA_DeleteOnClose); ui->setupUi(this); ui->divider->setValue(m_scroller->scrollDivider()); ui->iconLabel->setPixmap(QIcon(QStringLiteral(":/autoscroll/data/scroll_all.png")).pixmap(32)); connect(ui->buttonBox, SIGNAL(accepted()), this, SLOT(accepted())); connect(ui->buttonBox, SIGNAL(rejected()), this, SLOT(close())); } AutoScrollSettings::~AutoScrollSettings() { delete ui; } void AutoScrollSettings::accepted() { m_scroller->setScrollDivider(ui->divider->value()); close(); } diff --git a/src/plugins/AutoScroll/autoscrollsettings.h b/src/plugins/AutoScroll/autoscrollsettings.h index c4bd2780..369d5462 100644 --- a/src/plugins/AutoScroll/autoscrollsettings.h +++ b/src/plugins/AutoScroll/autoscrollsettings.h @@ -1,46 +1,46 @@ /* ============================================================ -* AutoScroll - Autoscroll for QupZilla +* AutoScroll - Autoscroll for Falkon * Copyright (C) 2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef AUTOSCROLLSETTINGS_H #define AUTOSCROLLSETTINGS_H #include namespace Ui { class AutoScrollSettings; } class AutoScroller; class AutoScrollSettings : public QDialog { Q_OBJECT public: explicit AutoScrollSettings(AutoScroller* scroller, QWidget* parent = 0); ~AutoScrollSettings(); private slots: void accepted(); private: Ui::AutoScrollSettings* ui; AutoScroller* m_scroller; }; #endif // AUTOSCROLLSETTINGS_H diff --git a/src/plugins/AutoScroll/framescroller.cpp b/src/plugins/AutoScroll/framescroller.cpp index 4153b29e..9599c94b 100644 --- a/src/plugins/AutoScroll/framescroller.cpp +++ b/src/plugins/AutoScroll/framescroller.cpp @@ -1,72 +1,72 @@ /* ============================================================ -* AutoScroll - Autoscroll for QupZilla +* AutoScroll - Autoscroll for Falkon * Copyright (C) 2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "framescroller.h" #include "webpage.h" #include #include FrameScroller::FrameScroller(QObject* parent) : QObject(parent) , m_page(0) , m_lengthX(0) , m_lengthY(0) , m_divider(8.0) { m_timer = new QTimer(this); m_timer->setInterval(10); connect(m_timer, SIGNAL(timeout()), this, SLOT(scrollStep())); } void FrameScroller::setPage(WebPage *page) { m_page = page; } double FrameScroller::scrollDivider() const { return m_divider; } void FrameScroller::setScrollDivider(double divider) { m_divider = divider; } void FrameScroller::startScrolling(int lengthX, int lengthY) { m_lengthX = lengthX; m_lengthY = lengthY; if (m_lengthX == 0 && m_lengthY == 0) { m_timer->stop(); } else if (!m_timer->isActive()) { m_timer->start(); } } void FrameScroller::stopScrolling() { m_timer->stop(); } void FrameScroller::scrollStep() { m_page->scroll(qCeil(m_lengthX / m_divider), qCeil(m_lengthY / m_divider)); } diff --git a/src/plugins/AutoScroll/framescroller.h b/src/plugins/AutoScroll/framescroller.h index bb64244e..b06f7e61 100644 --- a/src/plugins/AutoScroll/framescroller.h +++ b/src/plugins/AutoScroll/framescroller.h @@ -1,54 +1,54 @@ /* ============================================================ -* AutoScroll - Autoscroll for QupZilla +* AutoScroll - Autoscroll for Falkon * Copyright (C) 2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef FRAMESCROLLER_H #define FRAMESCROLLER_H #include class QTimer; class WebPage; class FrameScroller : public QObject { Q_OBJECT public: explicit FrameScroller(QObject* parent = 0); void setPage(WebPage *page); double scrollDivider() const; void setScrollDivider(double divider); void startScrolling(int lengthX, int lengthY); void stopScrolling(); private slots: void scrollStep(); private: WebPage *m_page; QTimer* m_timer; int m_lengthX; int m_lengthY; double m_divider; }; #endif // FRAMESCROLLER_H diff --git a/src/plugins/FlashCookieManager/fcm_dialog.cpp b/src/plugins/FlashCookieManager/fcm_dialog.cpp index ed1c1238..4726d566 100644 --- a/src/plugins/FlashCookieManager/fcm_dialog.cpp +++ b/src/plugins/FlashCookieManager/fcm_dialog.cpp @@ -1,436 +1,436 @@ /* ============================================================ -* FlashCookieManager plugin for QupZilla +* FlashCookieManager plugin for Falkon * Copyright (C) 2014 S. Razi Alavizadeh * Copyright (C) 2010-2016 David Rosca * * some codes and ideas are taken from cookiemanager.cpp and cookiemanager.ui * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "fcm_dialog.h" #include "ui_fcm_dialog.h" #include "qztools.h" #include "iconprovider.h" #include "fcm_plugin.h" #include #include #include #include #include #include FCM_Dialog::FCM_Dialog(FCM_Plugin* manager, QWidget* parent) : QDialog(parent, Qt::WindowStaysOnTopHint) , ui(new Ui::FCM_Dialog) , m_manager(manager) { ui->setupUi(this); QzTools::centerWidgetOnScreen(this); ui->path->hide(); ui->labelPath->hide(); if (isRightToLeft()) { ui->flashCookieTree->headerItem()->setTextAlignment(0, Qt::AlignRight | Qt::AlignVCenter); ui->flashCookieTree->setLayoutDirection(Qt::LeftToRight); ui->whiteList->setLayoutDirection(Qt::LeftToRight); ui->blackList->setLayoutDirection(Qt::LeftToRight); } connect(ui->flashCookieTree, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*))); connect(ui->removeAll, SIGNAL(clicked()), this, SLOT(removeAll())); connect(ui->removeOne, SIGNAL(clicked()), this, SLOT(removeCookie())); connect(ui->close, SIGNAL(clicked(QAbstractButton*)), this, SLOT(close())); connect(ui->close2, SIGNAL(clicked(QAbstractButton*)), this, SLOT(close())); connect(ui->close3, SIGNAL(clicked(QAbstractButton*)), this, SLOT(close())); connect(ui->search, SIGNAL(textChanged(QString)), this, SLOT(filterString(QString))); connect(ui->reloadFromDisk, SIGNAL(clicked()), this, SLOT(reloadFromDisk())); connect(ui->whiteAdd, SIGNAL(clicked()), this, SLOT(addWhitelist())); connect(ui->whiteRemove, SIGNAL(clicked()), this, SLOT(removeWhitelist())); connect(ui->blackAdd, SIGNAL(clicked()), this, SLOT(addBlacklist())); connect(ui->blackRemove, SIGNAL(clicked()), this, SLOT(removeBlacklist())); connect(ui->autoMode, SIGNAL(toggled(bool)), ui->notification, SLOT(setEnabled(bool))); connect(ui->autoMode, SIGNAL(toggled(bool)), ui->labelNotification, SLOT(setEnabled(bool))); ui->autoMode->setChecked(m_manager->readSettings().value(QL1S("autoMode")).toBool()); ui->notification->setEnabled(m_manager->readSettings().value(QL1S("autoMode")).toBool()); ui->notification->setChecked(m_manager->readSettings().value(QL1S("notification")).toBool()); ui->deleteAllOnStartExit->setChecked(m_manager->readSettings().value(QL1S("deleteAllOnStartExit")).toBool()); ui->labelNotification->setEnabled(ui->autoMode->isChecked()); ui->search->setPlaceholderText(tr("Search")); ui->flashCookieTree->setDefaultItemShowMode(TreeWidget::ItemsCollapsed); ui->flashCookieTree->sortItems(0, Qt::AscendingOrder); ui->flashCookieTree->header()->setDefaultSectionSize(220); ui->flashCookieTree->setFocus(); ui->flashCookieTree->setContextMenuPolicy(Qt::CustomContextMenu); connect(ui->flashCookieTree, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(cookieTreeContextMenuRequested(QPoint))); QShortcut* removeShortcut = new QShortcut(QKeySequence("Del"), this); connect(removeShortcut, SIGNAL(activated()), this, SLOT(deletePressed())); QzTools::setWmClass("FlashCookies", this); } void FCM_Dialog::removeAll() { QMessageBox::StandardButton button = QMessageBox::warning(this, tr("Confirmation"), tr("Are you sure you want to delete all flash cookies on your computer?"), QMessageBox::Yes | QMessageBox::No); if (button != QMessageBox::Yes) { return; } const QList &flashCookies = m_manager->flashCookies(); foreach (const FlashCookie &flashCookie, flashCookies) { m_manager->removeCookie(flashCookie); } ui->flashCookieTree->clear(); m_manager->clearNewOrigins(); m_manager->clearCache(); } void FCM_Dialog::removeCookie() { QTreeWidgetItem* current = ui->flashCookieTree->currentItem(); if (!current) { return; } const QVariant data = current->data(0, Qt::UserRole + 10); if (data.isNull()) { //Remove whole cookie group const QString origin = current->text(0); const QList &flashCookies = m_manager->flashCookies(); foreach (const FlashCookie &flashCookie, flashCookies) { if (flashCookie.origin == origin) { m_manager->removeCookie(flashCookie); } } ui->flashCookieTree->deleteItem(current); } else { const FlashCookie flashCookie = qvariant_cast(data); m_manager->removeCookie(flashCookie); QTreeWidgetItem* parentItem = current->parent(); ui->flashCookieTree->deleteItem(current); if (parentItem->childCount() == 0) { ui->flashCookieTree->deleteItem(parentItem); } } } void FCM_Dialog::currentItemChanged(QTreeWidgetItem* current, QTreeWidgetItem* parent) { Q_UNUSED(parent); if (!current) { return; } ui->textEdit->clear(); const QVariant data = current->data(0, Qt::UserRole + 10); if (data.isNull()) { ui->name->setText(tr("")); ui->size->setText(tr("")); ui->server->setText(tr("")); ui->lastModified->setText(tr("")); ui->removeOne->setText(tr("Remove flash cookies")); ui->path->hide(); ui->labelPath->hide(); return; } const FlashCookie flashCookie = qvariant_cast(data); QString suffix; if (flashCookie.path.startsWith(m_manager->flashPlayerDataPath() + QL1S("/macromedia.com/support/flashplayer/sys"))) { suffix = tr(" (settings)"); } ui->name->setText(flashCookie.name + suffix); ui->size->setText(QString::number(flashCookie.size) + tr(" Byte")); ui->textEdit->setPlainText(flashCookie.contents); ui->server->setText(flashCookie.origin); ui->path->setText(QString("%2").arg(QUrl::fromLocalFile(flashCookie.path).toString()).arg(QDir::toNativeSeparators(flashCookie.path))); ui->lastModified->setText(flashCookie.lastModification.toString()); ui->removeOne->setText(tr("Remove flash cookie")); ui->labelPath->show(); ui->path->show(); } void FCM_Dialog::refreshView(bool forceReload) { disconnect(ui->search, SIGNAL(textChanged(QString)), this, SLOT(filterString(QString))); ui->search->clear(); ui->textEdit->clear(); connect(ui->search, SIGNAL(textChanged(QString)), this, SLOT(filterString(QString))); if (forceReload) { m_manager->clearCache(); m_manager->clearNewOrigins(); } QTimer::singleShot(0, this, SLOT(refreshFlashCookiesTree())); QTimer::singleShot(0, this, SLOT(refreshFilters())); } void FCM_Dialog::showPage(int index) { ui->tabWidget->setCurrentIndex(index); } void FCM_Dialog::refreshFlashCookiesTree() { const QList &flashCookies = m_manager->flashCookies(); QApplication::setOverrideCursor(Qt::WaitCursor); ui->flashCookieTree->clear(); int counter = 0; QPointer guard = this; QHash hash; for (int i = 0; i < flashCookies.count(); ++i) { const FlashCookie flashCookie = flashCookies.at(i); QTreeWidgetItem* item; QString cookieOrigin = flashCookie.origin; if (cookieOrigin.startsWith(QLatin1Char('.'))) { cookieOrigin = cookieOrigin.mid(1); } QTreeWidgetItem* findParent = hash.value(cookieOrigin); if (findParent) { item = new QTreeWidgetItem(findParent); } else { QTreeWidgetItem* newParent = new QTreeWidgetItem(ui->flashCookieTree); newParent->setText(0, cookieOrigin); newParent->setIcon(0, IconProvider::standardIcon(QStyle::SP_DirIcon)); ui->flashCookieTree->addTopLevelItem(newParent); hash[cookieOrigin] = newParent; item = new QTreeWidgetItem(newParent); } QString suffix; if (flashCookie.path.startsWith(m_manager->flashPlayerDataPath() + QL1S("/macromedia.com/support/flashplayer/sys"))) { suffix = tr(" (settings)"); } if (m_manager->newCookiesList().contains(flashCookie.path + QL1C('/') + flashCookie.name)) { suffix += tr(" [new]"); QFont font = item->font(0); font.setBold(true); item->setFont(0, font); item->parent()->setExpanded(true); } item->setText(0, flashCookie.name + suffix); item->setData(0, Qt::UserRole + 10, QVariant::fromValue(flashCookie)); ui->flashCookieTree->addTopLevelItem(item); ++counter; if (counter > 200) { QApplication::processEvents(); counter = 0; } if (!guard) { break; } } QApplication::restoreOverrideCursor(); } void FCM_Dialog::refreshFilters() { ui->whiteList->clear(); ui->blackList->clear(); ui->whiteList->addItems(m_manager->readSettings().value(QL1S("flashCookiesWhitelist")).toStringList()); ui->blackList->addItems(m_manager->readSettings().value(QL1S("flashCookiesBlacklist")).toStringList()); } void FCM_Dialog::addWhitelist() { const QString origin = QInputDialog::getText(this, tr("Add to whitelist"), tr("Origin:")); addWhitelist(origin); } void FCM_Dialog::addWhitelist(const QString &origin) { if (origin.isEmpty()) { return; } if (!ui->blackList->findItems(origin, Qt::MatchFixedString).isEmpty()) { QMessageBox::information(this, tr("Already whitelisted!"), tr("The server \"%1\" is already in blacklist, please remove it first.").arg(origin)); return; } if (ui->whiteList->findItems(origin, Qt::MatchFixedString).isEmpty()) { ui->whiteList->addItem(origin); } } void FCM_Dialog::removeWhitelist() { delete ui->whiteList->currentItem(); } void FCM_Dialog::addBlacklist() { const QString origin = QInputDialog::getText(this, tr("Add to blacklist"), tr("Origin:")); addBlacklist(origin); } void FCM_Dialog::addBlacklist(const QString &origin) { if (origin.isEmpty()) { return; } if (!ui->whiteList->findItems(origin, Qt::MatchFixedString).isEmpty()) { QMessageBox::information(this, tr("Already whitelisted!"), tr("The origin \"%1\" is already in whitelist, please remove it first.").arg(origin)); return; } if (ui->blackList->findItems(origin, Qt::MatchFixedString).isEmpty()) { ui->blackList->addItem(origin); } } void FCM_Dialog::removeBlacklist() { delete ui->blackList->currentItem(); } void FCM_Dialog::deletePressed() { if (ui->flashCookieTree->hasFocus()) { removeCookie(); } else if (ui->whiteList->hasFocus()) { removeWhitelist(); } else if (ui->blackList->hasFocus()) { removeBlacklist(); } } void FCM_Dialog::autoModeChanged(bool state) { ui->notification->setEnabled(state); } void FCM_Dialog::filterString(const QString &string) { if (string.isEmpty()) { for (int i = 0; i < ui->flashCookieTree->topLevelItemCount(); ++i) { ui->flashCookieTree->topLevelItem(i)->setHidden(false); ui->flashCookieTree->topLevelItem(i)->setExpanded(ui->flashCookieTree->defaultItemShowMode() == TreeWidget::ItemsExpanded); } } else { for (int i = 0; i < ui->flashCookieTree->topLevelItemCount(); ++i) { QString text = QL1C('.') + ui->flashCookieTree->topLevelItem(i)->text(0); ui->flashCookieTree->topLevelItem(i)->setHidden(!text.contains(string, Qt::CaseInsensitive)); ui->flashCookieTree->topLevelItem(i)->setExpanded(true); } } } void FCM_Dialog::reloadFromDisk() { refreshView(true); } void FCM_Dialog::cookieTreeContextMenuRequested(const QPoint &pos) { QMenu menu; QAction* actAddBlacklist = menu.addAction(tr("Add to blacklist")); QAction* actAddWhitelist = menu.addAction(tr("Add to whitelist")); QTreeWidgetItem* item = ui->flashCookieTree->itemAt(pos); if (!item) { return; } ui->flashCookieTree->setCurrentItem(item); QAction* activatedAction = menu.exec(ui->flashCookieTree->viewport()->mapToGlobal(pos)); const QString origin = item->childCount() > 0 ? item->text(0) : item->data(0, Qt::UserRole + 10).value().origin; if (activatedAction == actAddBlacklist) { addBlacklist(origin); } else if (activatedAction == actAddWhitelist) { addWhitelist(origin); } } void FCM_Dialog::closeEvent(QCloseEvent* e) { m_manager->clearNewOrigins(); QStringList flashWhitelist; QStringList flashBlacklist; for (int i = 0; i < ui->whiteList->count(); ++i) { flashWhitelist.append(ui->whiteList->item(i)->text()); } for (int i = 0; i < ui->blackList->count(); ++i) { flashBlacklist.append(ui->blackList->item(i)->text()); } QVariantHash settingsHash; settingsHash.insert(QL1S("autoMode"), QVariant(ui->autoMode->isChecked())); settingsHash.insert(QL1S("deleteAllOnStartExit"), QVariant(ui->deleteAllOnStartExit->isChecked())); settingsHash.insert(QL1S("notification"), QVariant(ui->notification->isChecked())); settingsHash.insert(QL1S("flashCookiesWhitelist"), flashWhitelist); settingsHash.insert(QL1S("flashCookiesBlacklist"), flashBlacklist); m_manager->writeSettings(settingsHash); e->accept(); } void FCM_Dialog::keyPressEvent(QKeyEvent* e) { if (e->key() == Qt::Key_Escape) { close(); } QWidget::keyPressEvent(e); } FCM_Dialog::~FCM_Dialog() { delete ui; } diff --git a/src/plugins/FlashCookieManager/fcm_dialog.h b/src/plugins/FlashCookieManager/fcm_dialog.h index 231b8b2b..03fa089f 100644 --- a/src/plugins/FlashCookieManager/fcm_dialog.h +++ b/src/plugins/FlashCookieManager/fcm_dialog.h @@ -1,80 +1,80 @@ /* ============================================================ -* FlashCookieManager plugin for QupZilla +* FlashCookieManager plugin for Falkon * Copyright (C) 2014 S. Razi Alavizadeh * Copyright (C) 2010-2014 David Rosca * * some codes and ideas are taken from cookiemanager.cpp and cookiemanager.ui * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef FCM_DIALOG_H #define FCM_DIALOG_H #include namespace Ui { class FCM_Dialog; } class QTreeWidgetItem; class BrowserWindow; class FCM_Plugin; class FCM_Dialog : public QDialog { Q_OBJECT public: explicit FCM_Dialog(FCM_Plugin* manager, QWidget* parent = 0); ~FCM_Dialog(); void refreshView(bool forceReload = false); void showPage(int index); private slots: void currentItemChanged(QTreeWidgetItem* current, QTreeWidgetItem* parent); void removeCookie(); void removeAll(); void refreshFlashCookiesTree(); void refreshFilters(); void addWhitelist(); void addWhitelist(const QString &origin); void removeWhitelist(); void addBlacklist(); void addBlacklist(const QString &origin); void removeBlacklist(); void deletePressed(); void autoModeChanged(bool state); void filterString(const QString &string); void reloadFromDisk(); void cookieTreeContextMenuRequested(const QPoint &pos); private: void closeEvent(QCloseEvent* e); void keyPressEvent(QKeyEvent* e); Ui::FCM_Dialog* ui; FCM_Plugin* m_manager; }; #endif // FCM_DIALOG_H diff --git a/src/plugins/FlashCookieManager/fcm_notification.cpp b/src/plugins/FlashCookieManager/fcm_notification.cpp index 228072a8..3f854552 100644 --- a/src/plugins/FlashCookieManager/fcm_notification.cpp +++ b/src/plugins/FlashCookieManager/fcm_notification.cpp @@ -1,49 +1,49 @@ /* ============================================================ -* FlashCookieManager plugin for QupZilla +* FlashCookieManager plugin for Falkon * Copyright (C) 2014 S. Razi Alavizadeh * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "fcm_notification.h" #include "ui_fcm_notification.h" #include "iconprovider.h" #include "fcm_plugin.h" FCM_Notification::FCM_Notification(FCM_Plugin* manager, int newOriginsCount) : AnimatedWidget(AnimatedWidget::Down, 300, 0) , ui(new Ui::FCM_Notification) , m_manager(manager) { setAutoFillBackground(true); ui->setupUi(widget()); ui->close->setIcon(IconProvider::standardIcon(QStyle::SP_DialogCloseButton)); if (newOriginsCount == 1) { ui->textLabel->setText(tr("A new flash cookie was detected")); } else { ui->textLabel->setText(tr("%1 new flash cookies were detected").arg(newOriginsCount)); } connect(ui->buttonView, SIGNAL(clicked()), m_manager, SLOT(showFlashCookieManager())); connect(ui->buttonView, SIGNAL(clicked()), this, SLOT(hide())); connect(ui->close, SIGNAL(clicked()), this, SLOT(hide())); startAnimation(); } FCM_Notification::~FCM_Notification() { delete ui; } diff --git a/src/plugins/FlashCookieManager/fcm_notification.h b/src/plugins/FlashCookieManager/fcm_notification.h index 8711d240..eb644227 100644 --- a/src/plugins/FlashCookieManager/fcm_notification.h +++ b/src/plugins/FlashCookieManager/fcm_notification.h @@ -1,44 +1,44 @@ /* ============================================================ -* FlashCookieManager plugin for QupZilla +* FlashCookieManager plugin for Falkon * Copyright (C) 2014 S. Razi Alavizadeh * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef FCM_Notification_H #define FCM_Notification_H #include "animatedwidget.h" namespace Ui { class FCM_Notification; } class FCM_Plugin; class FCM_Notification : public AnimatedWidget { Q_OBJECT public: FCM_Notification(FCM_Plugin* manager, int newOriginsCount); ~FCM_Notification(); private: Ui::FCM_Notification* ui; FCM_Plugin* m_manager; }; #endif // FCM_Notification_H diff --git a/src/plugins/FlashCookieManager/fcm_plugin.cpp b/src/plugins/FlashCookieManager/fcm_plugin.cpp index 94f31603..2a3060d9 100644 --- a/src/plugins/FlashCookieManager/fcm_plugin.cpp +++ b/src/plugins/FlashCookieManager/fcm_plugin.cpp @@ -1,459 +1,459 @@ /* ============================================================ * FlashCookieManager plugin for QupZilla * Copyright (C) 2014 S. Razi Alavizadeh * Copyright (C) 2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "fcm_plugin.h" #include "browserwindow.h" #include "pluginproxy.h" #include "mainapplication.h" #include "fcm_dialog.h" #include "clickablelabel.h" #include "tabbedwebview.h" #include "fcm_notification.h" #include "datapaths.h" #include #include #include #include #include #include #if defined(Q_OS_WIN) || defined(Q_OS_OS2) #include #endif const int refreshInterval = 60 * 1000; FCM_Plugin::FCM_Plugin() : QObject() { } PluginSpec FCM_Plugin::pluginSpec() { PluginSpec spec; spec.name = "Flash Cookie Manager"; spec.info = "A plugin to manage flash cookies."; spec.description = "You can easily view/delete flash cookies stored on your computer. This is a solution for having more privacy."; spec.version = "0.3.0"; spec.author = "Razi Alavizadeh "; spec.icon = QPixmap(":/flashcookiemanager/data/flash-cookie-manager.png"); spec.hasSettings = true; return spec; } void FCM_Plugin::init(InitState state, const QString &settingsPath) { m_settingsPath = settingsPath; connect(mApp->plugins(), SIGNAL(mainWindowCreated(BrowserWindow*)), this, SLOT(mainWindowCreated(BrowserWindow*))); connect(mApp->plugins(), SIGNAL(mainWindowDeleted(BrowserWindow*)), this, SLOT(mainWindowDeleted(BrowserWindow*))); m_timer = new QTimer(this); m_timer->setInterval(refreshInterval); connect(m_timer, SIGNAL(timeout()), this, SLOT(autoRefresh())); // start timer if needed startStopTimer(); if (state == StartupInitState && readSettings().value(QL1S("deleteAllOnStartExit")).toBool()) { loadFlashCookies(); removeAllButWhitelisted(); } if (state == LateInitState) { foreach (BrowserWindow* window, mApp->windows()) { mainWindowCreated(window); } } } void FCM_Plugin::unload() { if (m_fcmDialog) { m_fcmDialog->close(); } if (mApp->isClosing() && readSettings().value(QL1S("deleteAllOnStartExit")).toBool()) { removeAllButWhitelisted(); } foreach (BrowserWindow* window, mApp->windows()) { window->statusBar()->removeWidget(m_statusBarIcons.value(window)); delete m_statusBarIcons.value(window); m_statusBarIcons.remove(window); } delete m_fcmDialog; } bool FCM_Plugin::testPlugin() { - return (Qz::VERSION == QLatin1String(QUPZILLA_VERSION)); + return (Qz::VERSION == QLatin1String(FALKON_VERSION)); } QTranslator* FCM_Plugin::getTranslator(const QString &locale) { QTranslator* translator = new QTranslator(this); translator->load(locale, ":/flashcookiemanager/locale/"); return translator; } void FCM_Plugin::showSettings(QWidget* parent) { Q_UNUSED(parent) showFlashCookieManager(); m_fcmDialog->showPage(2); } void FCM_Plugin::populateExtensionsMenu(QMenu* menu) { QAction* showFCM = new QAction(QIcon(":/flashcookiemanager/data/flash-cookie-manager.png"), tr("Flash Cookie Manager"), menu); connect(showFCM, SIGNAL(triggered()), this, SLOT(showFlashCookieManager())); menu->addAction(showFCM); } void FCM_Plugin::setFlashCookies(const QList &flashCookies) { m_flashCookies = flashCookies; } QList FCM_Plugin::flashCookies() { if (m_flashCookies.isEmpty()) { loadFlashCookies(); } return m_flashCookies; } QStringList FCM_Plugin::newCookiesList() { return m_newCookiesList; } void FCM_Plugin::clearNewOrigins() { m_newCookiesList.clear(); } void FCM_Plugin::clearCache() { m_flashCookies.clear(); } bool FCM_Plugin::isBlacklisted(const FlashCookie &flashCookie) { return readSettings().value(QL1S("flashCookiesBlacklist")).toStringList().contains(flashCookie.origin); } bool FCM_Plugin::isWhitelisted(const FlashCookie &flashCookie) { return readSettings().value(QL1S("flashCookiesWhitelist")).toStringList().contains(flashCookie.origin); } void FCM_Plugin::removeAllButWhitelisted() { foreach (const FlashCookie &flashCookie, m_flashCookies) { if (isWhitelisted(flashCookie)) { continue; } removeCookie(flashCookie); } } QString FCM_Plugin::sharedObjectDirName() const { if (flashPlayerDataPath().contains(QL1S("macromedia"), Qt::CaseInsensitive) || !flashPlayerDataPath().contains(QL1S("/.gnash"), Qt::CaseInsensitive)) { return QLatin1String(QL1S("/#SharedObjects/")); } else { return QLatin1String(QL1S("/SharedObjects/")); } } QString FCM_Plugin::flashPlayerDataPath() const { return DataPaths::currentProfilePath() + QSL("/Pepper Data/Shockwave Flash/WritableRoot/"); } QVariantHash FCM_Plugin::readSettings() const { if (m_settingsHash.isEmpty()) { m_settingsHash.insert(QL1S("autoMode"), QVariant(false)); m_settingsHash.insert(QL1S("deleteAllOnStartExit"), QVariant(false)); m_settingsHash.insert(QL1S("notification"), QVariant(false)); m_settingsHash.insert(QL1S("flashCookiesWhitelist"), QVariant()); m_settingsHash.insert(QL1S("flashCookiesBlacklist"), QVariant()); QSettings settings(m_settingsPath + QL1S("/extensions.ini"), QSettings::IniFormat); settings.beginGroup(QL1S("FlashCookieManager")); QVariantHash::iterator i = m_settingsHash.begin(); while (i != m_settingsHash.end()) { *i = settings.value(i.key(), i.value()); ++i; } settings.endGroup(); } return m_settingsHash; } void FCM_Plugin::writeSettings(const QVariantHash &hashSettings) { m_settingsHash = hashSettings; QSettings settings(m_settingsPath + QL1S(QL1S("/extensions.ini")), QSettings::IniFormat); settings.beginGroup(QL1S("FlashCookieManager")); QVariantHash::const_iterator i = m_settingsHash.constBegin(); while (i != m_settingsHash.constEnd()) { settings.setValue(i.key(), i.value()); ++i; } settings.endGroup(); startStopTimer(); } void FCM_Plugin::removeCookie(const FlashCookie &flashCookie) { if (m_flashCookies.contains(flashCookie)) { m_flashCookies.removeOne(flashCookie); if (QFile(flashCookie.path + QL1C('/') + flashCookie.name).remove()) { QDir dir(flashCookie.path); dir.rmpath(flashCookie.path); } } } void FCM_Plugin::autoRefresh() { if (m_fcmDialog && m_fcmDialog->isVisible()) { return; } QList oldflashCookies = m_flashCookies; loadFlashCookies(); QStringList newCookieList; foreach (const FlashCookie &flashCookie, m_flashCookies) { if (isBlacklisted(flashCookie)) { removeCookie(flashCookie); continue; } if (isWhitelisted(flashCookie)) { continue; } bool newCookie = true; foreach (const FlashCookie &oldFlashCookie, oldflashCookies) { if (QString(oldFlashCookie.path + oldFlashCookie.name) == QString(flashCookie.path + flashCookie.name)) { newCookie = false; break; } } if (newCookie) { newCookieList << flashCookie.path + QL1C('/') + flashCookie.name; } } if (!newCookieList.isEmpty() && readSettings().value(QL1S("notification")).toBool()) { m_newCookiesList << newCookieList; BrowserWindow* window = mApp->getWindow(); if (!window) { return; } TabbedWebView* weView = window->weView(); if (!weView) { return; } FCM_Notification* notif = new FCM_Notification(this, newCookieList.size()); weView->addNotification(notif); } } void FCM_Plugin::showFlashCookieManager() { if (!m_fcmDialog) { m_fcmDialog = new FCM_Dialog(this); } m_fcmDialog->refreshView(); m_fcmDialog->showPage(0); m_fcmDialog->show(); m_fcmDialog->raise(); } void FCM_Plugin::mainWindowCreated(BrowserWindow *window) { window->statusBar()->addPermanentWidget(createStatusBarIcon(window)); } void FCM_Plugin::mainWindowDeleted(BrowserWindow *window) { if (!window) { return; } if (m_fcmDialog && m_fcmDialog->parent() == window) { m_fcmDialog->setParent(0); } window->statusBar()->removeWidget(m_statusBarIcons.value(window)); delete m_statusBarIcons.value(window); m_statusBarIcons.remove(window); } void FCM_Plugin::startStopTimer() { if (readSettings().value(QL1S("autoMode")).toBool()) { if (!m_timer->isActive()) { if (m_flashCookies.isEmpty()) { loadFlashCookies(); } m_timer->start(); } } else { m_timer->stop(); } } QWidget* FCM_Plugin::createStatusBarIcon(BrowserWindow* mainWindow) { if (m_statusBarIcons.contains(mainWindow)) { return m_statusBarIcons.value(mainWindow); } ClickableLabel* icon = new ClickableLabel(mainWindow); icon->setCursor(Qt::PointingHandCursor); icon->setPixmap(QIcon(QSL(":/flashcookiemanager/data/flash-cookie-manager.png")).pixmap(16)); icon->setToolTip(tr("Show Flash Cookie Manager")); connect(icon, SIGNAL(clicked(QPoint)), this, SLOT(showFlashCookieManager())); m_statusBarIcons.insert(mainWindow, icon); return icon; } void FCM_Plugin::loadFlashCookies() { m_flashCookies.clear(); loadFlashCookies(flashPlayerDataPath()); } void FCM_Plugin::loadFlashCookies(QString path) { QDir solDir(path); QStringList entryList = solDir.entryList(); entryList.removeAll(QL1S(".")); entryList.removeAll(QL1S("..")); foreach(QString entry, entryList) { if (path.endsWith(QL1S("#SharedObjects")) && entry == QL1S("#AppContainer")) { // specific to IE and Windows continue; } path.replace(QL1C('\\'), QL1C('/')); QFileInfo entryInfo(path + QL1C('/') + entry); if (entryInfo.isDir()) { loadFlashCookies(entryInfo.filePath()); } else if (entryInfo.isFile() && entryInfo.suffix() == QL1S("sol")) { insertFlashCookie(entryInfo.filePath()); } } } void FCM_Plugin::insertFlashCookie(QString path) { QFile solFile(path); if (!solFile.open(QFile::ReadOnly)) { return; } QByteArray file = solFile.readAll(); for (int i = 0; i < file.size(); ++i) { if (!((file.at(i) >= 'a' && file.at(i) <= 'z') || (file.at(i) >= 'A' && file.at(i) <= 'Z') || (file.at(i) >= '0' && file.at(i) <= '9'))) { file[i] = ' '; } } QString fileStr = QString(file); fileStr = fileStr.split(QL1C('.'), QString::SkipEmptyParts).join(QL1S("\n")); QFileInfo solFileInfo(solFile); FlashCookie flashCookie; flashCookie.contents = fileStr; flashCookie.name = solFileInfo.fileName(); flashCookie.path = solFileInfo.canonicalPath(); flashCookie.size = (int)solFile.size(); flashCookie.lastModification = solFileInfo.lastModified(); flashCookie.origin = extractOriginFrom(path); m_flashCookies << flashCookie; } QString FCM_Plugin::extractOriginFrom(const QString &path) { QString origin = path; if (path.startsWith(flashPlayerDataPath() + sharedObjectDirName())) { origin.remove(flashPlayerDataPath() + sharedObjectDirName()); if (origin.indexOf(QL1C('/')) != -1) { origin.remove(0, origin.indexOf(QL1C('/')) + 1); } } else if (path.startsWith(flashPlayerDataPath() + QL1S("/macromedia.com/support/flashplayer/sys/"))) { origin.remove(flashPlayerDataPath() + QL1S("/macromedia.com/support/flashplayer/sys/")); if (origin == QL1S("settings.sol")) { return tr("!default"); } else if (origin.startsWith(QL1C('#'))) { origin.remove(0, 1); } } else { origin.clear(); } int index = origin.indexOf(QL1C('/')); if (index == -1) { return tr("!other"); } origin = origin.remove(index, origin.size()); if (origin == QL1S("localhost") || origin == QL1S("local")) { origin = QL1S("!localhost"); } return origin; } diff --git a/src/plugins/FlashCookieManager/fcm_plugin.h b/src/plugins/FlashCookieManager/fcm_plugin.h index 41a74774..68aa54c2 100644 --- a/src/plugins/FlashCookieManager/fcm_plugin.h +++ b/src/plugins/FlashCookieManager/fcm_plugin.h @@ -1,109 +1,109 @@ /* ============================================================ * FlashCookieManager plugin for QupZilla * Copyright (C) 2014 S. Razi Alavizadeh * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef FLASHCOOKIEMANAGER_H #define FLASHCOOKIEMANAGER_H #include "plugininterface.h" #include #include class BrowserWindow; class FCM_Dialog; class QTimer; struct FlashCookie { QString name; QString origin; int size; QString path; QString contents; QDateTime lastModification; bool operator ==(const FlashCookie &other) { return (this->name == other.name && this->path == other.path); } }; class FCM_Plugin : public QObject, public PluginInterface { Q_OBJECT Q_INTERFACES(PluginInterface) - Q_PLUGIN_METADATA(IID "QupZilla.Browser.plugin.FlashCookieManager") + Q_PLUGIN_METADATA(IID "Falkon.Browser.plugin.FlashCookieManager") public: explicit FCM_Plugin(); PluginSpec pluginSpec(); void init(InitState state, const QString &settingsPath); void unload(); bool testPlugin(); QTranslator* getTranslator(const QString &locale); void showSettings(QWidget* parent = 0); void populateExtensionsMenu(QMenu* menu); void setFlashCookies(const QList &flashCookies); QList flashCookies(); QStringList newCookiesList(); void clearNewOrigins(); void clearCache(); QString flashPlayerDataPath() const; QVariantHash readSettings() const; void writeSettings(const QVariantHash &hashSettings); void removeCookie(const FlashCookie &flashCookie); private slots: void autoRefresh(); void showFlashCookieManager(); void mainWindowCreated(BrowserWindow* window); void mainWindowDeleted(BrowserWindow* window); void startStopTimer(); private: QWidget* createStatusBarIcon(BrowserWindow* mainWindow); void loadFlashCookies(); void loadFlashCookies(QString path); void insertFlashCookie(QString path); QString extractOriginFrom(const QString &path); bool isBlacklisted(const FlashCookie &flashCookie); bool isWhitelisted(const FlashCookie &flashCookie); void removeAllButWhitelisted(); QString sharedObjectDirName() const; QHash m_statusBarIcons; QPointer m_fcmDialog; QString m_settingsPath; QList m_flashCookies; QTimer* m_timer; mutable QVariantHash m_settingsHash; bool m_autoMode; bool m_deleteOnClose; bool m_enableNotification; QStringList m_blaklist; QStringList m_whitelist; QStringList m_newCookiesList; }; Q_DECLARE_METATYPE(FlashCookie); #endif // FLASHCOOKIEMANAGER_H diff --git a/src/plugins/GnomeKeyringPasswords/gnomekeyringpasswordbackend.cpp b/src/plugins/GnomeKeyringPasswords/gnomekeyringpasswordbackend.cpp index fc82974f..02bece6e 100644 --- a/src/plugins/GnomeKeyringPasswords/gnomekeyringpasswordbackend.cpp +++ b/src/plugins/GnomeKeyringPasswords/gnomekeyringpasswordbackend.cpp @@ -1,277 +1,277 @@ /* ============================================================ * GnomeKeyringPasswords - gnome-keyring support plugin for QupZilla * Copyright (C) 2013-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "gnomekeyringpasswordbackend.h" #include "gnomekeyringplugin.h" #include extern "C" { #include "gnome-keyring.h" } static PasswordEntry createEntry(GnomeKeyringFound* item) { PasswordEntry entry; entry.id = item->item_id; entry.password = QString::fromUtf8(item->secret); for (unsigned i = 0; i < item->attributes->len; ++i) { GnomeKeyringAttribute attr = g_array_index(item->attributes, GnomeKeyringAttribute, i); if (strcmp(attr.name, "host") == 0) { entry.host = QString::fromUtf8(attr.value.string); } else if (strcmp(attr.name, "username") == 0) { entry.username = QString::fromUtf8(attr.value.string); } else if (strcmp(attr.name, "data") == 0) { entry.data = attr.value.string; } else if (strcmp(attr.name, "updated") == 0) { entry.updated = attr.value.integer; } } entry.data.replace(QByteArray("___PASSWORD-VALUE___"), PasswordManager::urlEncodePassword(entry.password)); return entry; } static GnomeKeyringAttributeList* createAttributes(const PasswordEntry &entry) { GnomeKeyringAttributeList* attributes = gnome_keyring_attribute_list_new(); - gnome_keyring_attribute_list_append_string(attributes, "application", "QupZilla"); + gnome_keyring_attribute_list_append_string(attributes, "application", "Falkon"); QByteArray value = entry.username.toUtf8(); gnome_keyring_attribute_list_append_string(attributes, "username", value.constData()); value = entry.data; value.replace(PasswordManager::urlEncodePassword(entry.password), "___PASSWORD-VALUE___"); gnome_keyring_attribute_list_append_string(attributes, "data", value.constData()); value = entry.host.toUtf8(); gnome_keyring_attribute_list_append_string(attributes, "host", value.constData()); gnome_keyring_attribute_list_append_uint32(attributes, "updated", entry.updated); return attributes; } GnomeKeyringPasswordBackend::GnomeKeyringPasswordBackend() : PasswordBackend() , m_loaded(false) { } QString GnomeKeyringPasswordBackend::name() const { return GnomeKeyringPlugin::tr("Gnome Keyring"); } QVector GnomeKeyringPasswordBackend::getEntries(const QUrl &url) { initialize(); const QString host = PasswordManager::createHost(url); QVector list; foreach (const PasswordEntry &entry, m_allEntries) { if (entry.host == host) { list.append(entry); } } // Sort to prefer last updated entries std::sort(list.begin(), list.end()); return list; } QVector GnomeKeyringPasswordBackend::getAllEntries() { initialize(); return m_allEntries; } void GnomeKeyringPasswordBackend::addEntry(const PasswordEntry &entry) { initialize(); PasswordEntry stored = entry; stored.updated = QDateTime::currentDateTime().toTime_t(); guint32 itemId; GnomeKeyringAttributeList* attributes = createAttributes(stored); QByteArray pass = stored.password.toUtf8(); QByteArray host = stored.host.toUtf8(); GnomeKeyringResult result = gnome_keyring_item_create_sync(GNOME_KEYRING_DEFAULT, GNOME_KEYRING_ITEM_GENERIC_SECRET, host.constData(), attributes, pass.constData(), TRUE, // Update if exists &itemId); gnome_keyring_attribute_list_free(attributes); if (result != GNOME_KEYRING_RESULT_OK) { qWarning() << "GnomeKeyringPasswordBackend::addEntry Cannot add entry to keyring!"; } stored.id = itemId; m_allEntries.append(stored); } bool GnomeKeyringPasswordBackend::updateEntry(const PasswordEntry &entry) { initialize(); // Update item attributes GnomeKeyringAttributeList* attributes = createAttributes(entry); GnomeKeyringResult result = gnome_keyring_item_set_attributes_sync(GNOME_KEYRING_DEFAULT, entry.id.toUInt(), attributes); gnome_keyring_attribute_list_free(attributes); if (result != GNOME_KEYRING_RESULT_OK) { qWarning() << "GnomeKeyringPasswordBackend::updateEntry Cannot updated entry attributes in keyring!"; return false; } // Update secret GnomeKeyringItemInfo* info; result = gnome_keyring_item_get_info_full_sync(GNOME_KEYRING_DEFAULT, entry.id.toUInt(), GNOME_KEYRING_ITEM_INFO_SECRET, &info); if (result != GNOME_KEYRING_RESULT_OK) { qWarning() << "GnomeKeyringPasswordBackend::updateEntry Cannot get entry info from keyring!"; return false; } QByteArray pass = entry.password.toUtf8(); gnome_keyring_item_info_set_secret(info, pass.constData()); result = gnome_keyring_item_set_info_sync(GNOME_KEYRING_DEFAULT, entry.id.toUInt(), info); gnome_keyring_item_info_free(info); if (result != GNOME_KEYRING_RESULT_OK) { qWarning() << "GnomeKeyringPasswordBackend::updateEntry Cannot set entry info in keyring!"; return false; } int index = m_allEntries.indexOf(entry); if (index > -1) { m_allEntries[index] = entry; } return true; } void GnomeKeyringPasswordBackend::updateLastUsed(PasswordEntry &entry) { initialize(); entry.updated = QDateTime::currentDateTime().toTime_t(); GnomeKeyringAttributeList* attributes = createAttributes(entry); GnomeKeyringResult result = gnome_keyring_item_set_attributes_sync(GNOME_KEYRING_DEFAULT, entry.id.toUInt(), attributes); gnome_keyring_attribute_list_free(attributes); if (result != GNOME_KEYRING_RESULT_OK) { qWarning() << "GnomeKeyringPasswordBackend::updateLastUsed Cannot updated entry in keyring!"; return; } int index = m_allEntries.indexOf(entry); if (index > -1) { m_allEntries[index] = entry; } } void GnomeKeyringPasswordBackend::removeEntry(const PasswordEntry &entry) { initialize(); GnomeKeyringResult result = gnome_keyring_item_delete_sync(GNOME_KEYRING_DEFAULT, entry.id.toUInt()); if (result != GNOME_KEYRING_RESULT_OK) { qWarning() << "GnomeKeyringPasswordBackend::removeEntry Cannot remove entry from keyring!"; return; } int index = m_allEntries.indexOf(entry); if (index > -1) { m_allEntries.remove(index); } } void GnomeKeyringPasswordBackend::removeAll() { initialize(); foreach (const PasswordEntry &entry, m_allEntries) { removeEntry(entry); } m_allEntries.clear(); } void GnomeKeyringPasswordBackend::initialize() { if (m_loaded) { return; } GList* found; GnomeKeyringResult result = gnome_keyring_find_itemsv_sync(GNOME_KEYRING_ITEM_GENERIC_SECRET, &found, - "application", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, "QupZilla", + "application", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, "Falkon", NULL); if (result != GNOME_KEYRING_RESULT_OK && result != GNOME_KEYRING_RESULT_NO_MATCH) { qWarning() << "GnomeKeyringPasswordBackend::initialize Cannot read items from keyring!"; return; } GList* tmp = found; while (tmp) { GnomeKeyringFound* item = (GnomeKeyringFound*) tmp->data; m_allEntries.append(createEntry(item)); tmp = tmp->next; } gnome_keyring_found_list_free(found); m_loaded = true; } diff --git a/src/plugins/GnomeKeyringPasswords/gnomekeyringplugin.cpp b/src/plugins/GnomeKeyringPasswords/gnomekeyringplugin.cpp index d91eab34..34f26969 100644 --- a/src/plugins/GnomeKeyringPasswords/gnomekeyringplugin.cpp +++ b/src/plugins/GnomeKeyringPasswords/gnomekeyringplugin.cpp @@ -1,71 +1,71 @@ /* ============================================================ * GnomeKeyringPasswords - gnome-keyring support plugin for QupZilla * Copyright (C) 2013-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "gnomekeyringplugin.h" #include "gnomekeyringpasswordbackend.h" #include "pluginproxy.h" #include "browserwindow.h" #include GnomeKeyringPlugin::GnomeKeyringPlugin() : QObject() , m_backend(0) { } PluginSpec GnomeKeyringPlugin::pluginSpec() { PluginSpec spec; spec.name = "Gnome Keyring Passwords"; spec.info = "Gnome Keyring password backend"; spec.description = "Provides support for storing passwords in gnome-keyring"; spec.version = "0.1.0"; spec.author = "David Rosca "; spec.icon = QPixmap(":gkp/data/icon.png"); spec.hasSettings = false; return spec; } void GnomeKeyringPlugin::init(InitState state, const QString &settingsPath) { Q_UNUSED(state); Q_UNUSED(settingsPath); m_backend = new GnomeKeyringPasswordBackend; QZ_REGISTER_PASSWORD_BACKEND("GnomeKeyring", m_backend); } void GnomeKeyringPlugin::unload() { QZ_UNREGISTER_PASSWORD_BACKEND(m_backend); delete m_backend; } bool GnomeKeyringPlugin::testPlugin() { // Require the version that the plugin was built with - return (Qz::VERSION == QLatin1String(QUPZILLA_VERSION)); + return (Qz::VERSION == QLatin1String(FALKON_VERSION)); } QTranslator* GnomeKeyringPlugin::getTranslator(const QString &locale) { QTranslator* translator = new QTranslator(this); translator->load(locale, ":/gkp/locale/"); return translator; } diff --git a/src/plugins/GnomeKeyringPasswords/gnomekeyringplugin.h b/src/plugins/GnomeKeyringPasswords/gnomekeyringplugin.h index f80a594b..16e56b9a 100644 --- a/src/plugins/GnomeKeyringPasswords/gnomekeyringplugin.h +++ b/src/plugins/GnomeKeyringPasswords/gnomekeyringplugin.h @@ -1,46 +1,46 @@ /* ============================================================ * GnomeKeyringPasswords - gnome-keyring support plugin for QupZilla * Copyright (C) 2013-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef GNOMEKEYRINGPLUGIN_H #define GNOMEKEYRINGPLUGIN_H #include "plugininterface.h" class GnomeKeyringPasswordBackend; class GnomeKeyringPlugin : public QObject, public PluginInterface { Q_OBJECT Q_INTERFACES(PluginInterface) - Q_PLUGIN_METADATA(IID "QupZilla.Browser.plugin.GnomeKeyringPasswords") + Q_PLUGIN_METADATA(IID "Falkon.Browser.plugin.GnomeKeyringPasswords") public: explicit GnomeKeyringPlugin(); PluginSpec pluginSpec(); void init(InitState state, const QString &settingsPath); void unload(); bool testPlugin(); QTranslator* getTranslator(const QString &locale); private: GnomeKeyringPasswordBackend* m_backend; }; #endif // GNOMEKEYRINGPLUGIN_H diff --git a/src/plugins/GreaseMonkey/gm_addscriptdialog.cpp b/src/plugins/GreaseMonkey/gm_addscriptdialog.cpp index 5ce541d4..5f8e5e17 100644 --- a/src/plugins/GreaseMonkey/gm_addscriptdialog.cpp +++ b/src/plugins/GreaseMonkey/gm_addscriptdialog.cpp @@ -1,96 +1,96 @@ /* ============================================================ -* GreaseMonkey plugin for QupZilla +* GreaseMonkey plugin for Falkon * Copyright (C) 2012-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "gm_addscriptdialog.h" #include "ui_gm_addscriptdialog.h" #include "gm_script.h" #include "gm_manager.h" #include "gm_notification.h" #include "mainapplication.h" #include "browserwindow.h" #include "tabbedwebview.h" #include "tabwidget.h" #include "datapaths.h" #include "qztools.h" #include #include GM_AddScriptDialog::GM_AddScriptDialog(GM_Manager* manager, GM_Script* script, QWidget* parent) : QDialog(parent) , ui(new Ui::GM_AddScriptDialog) , m_manager(manager) , m_script(script) { ui->setupUi(this); ui->iconLabel->setPixmap(QIcon(QSL(":gm/data/icon.svg")).pixmap(32)); QString runsAt; QString dontRunsAt; const QStringList include = script->include(); const QStringList exclude = script->exclude(); if (!include.isEmpty()) { runsAt = tr("

runs at
%1

").arg(include.join("
")); } if (!exclude.isEmpty()) { dontRunsAt = tr("

does not run at
%1

").arg(exclude.join("
")); } QString scriptInfo = QString("%1 %2
%3 %4 %5").arg(script->name(), script->version(), script->description(), runsAt, dontRunsAt); ui->textBrowser->setText(scriptInfo); connect(ui->showSource, SIGNAL(clicked()), this, SLOT(showSource())); connect(this, SIGNAL(accepted()), this, SLOT(accepted())); } void GM_AddScriptDialog::showSource() { BrowserWindow* qz = mApp->getWindow(); if (!qz) { return; } const QString tmpFileName = QzTools::ensureUniqueFilename(DataPaths::path(DataPaths::Temp) + "/tmp-userscript.js"); if (QFile::copy(m_script->fileName(), tmpFileName)) { int index = qz->tabWidget()->addView(QUrl::fromLocalFile(tmpFileName), Qz::NT_SelectedTabAtTheEnd); TabbedWebView* view = qz->weView(index); view->addNotification(new GM_Notification(m_manager, tmpFileName, m_script->fileName())); } reject(); } void GM_AddScriptDialog::accepted() { QString message = tr("Cannot install script"); if (m_manager->addScript(m_script)) { message = tr("'%1' installed successfully").arg(m_script->name()); } m_manager->showNotification(message); } GM_AddScriptDialog::~GM_AddScriptDialog() { delete ui; } diff --git a/src/plugins/GreaseMonkey/gm_addscriptdialog.h b/src/plugins/GreaseMonkey/gm_addscriptdialog.h index 8f2a1b0d..0ad8c07a 100644 --- a/src/plugins/GreaseMonkey/gm_addscriptdialog.h +++ b/src/plugins/GreaseMonkey/gm_addscriptdialog.h @@ -1,51 +1,51 @@ /* ============================================================ -* GreaseMonkey plugin for QupZilla +* GreaseMonkey plugin for Falkon * Copyright (C) 2012-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef GM_ADDSCRIPTDIALOG_H #define GM_ADDSCRIPTDIALOG_H #include namespace Ui { class GM_AddScriptDialog; } class GM_Script; class GM_Manager; class GM_AddScriptDialog : public QDialog { Q_OBJECT public: explicit GM_AddScriptDialog(GM_Manager *manager, GM_Script *script, QWidget *parent = Q_NULLPTR); ~GM_AddScriptDialog(); private slots: void showSource(); void accepted(); private: Ui::GM_AddScriptDialog* ui; GM_Manager* m_manager; GM_Script* m_script; }; #endif // GM_ADDSCRIPTDIALOG_H diff --git a/src/plugins/GreaseMonkey/gm_downloader.cpp b/src/plugins/GreaseMonkey/gm_downloader.cpp index 9dee07e8..89348885 100644 --- a/src/plugins/GreaseMonkey/gm_downloader.cpp +++ b/src/plugins/GreaseMonkey/gm_downloader.cpp @@ -1,149 +1,149 @@ /* ============================================================ -* GreaseMonkey plugin for QupZilla +* GreaseMonkey plugin for Falkon * Copyright (C) 2012-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "gm_downloader.h" #include "gm_manager.h" #include "gm_script.h" #include "webpage.h" #include "mainapplication.h" #include "networkmanager.h" #include "qztools.h" #include "qzregexp.h" #include #include #include GM_Downloader::GM_Downloader(const QUrl &url, GM_Manager *manager, Mode mode) : QObject() , m_manager(manager) { m_reply = mApp->networkManager()->get(QNetworkRequest(url)); if (mode == DownloadMainScript) { connect(m_reply, &QNetworkReply::finished, this, &GM_Downloader::scriptDownloaded); } else { connect(m_reply, &QNetworkReply::finished, this, &GM_Downloader::requireDownloaded); } } void GM_Downloader::updateScript(const QString &fileName) { m_fileName = fileName; } void GM_Downloader::scriptDownloaded() { Q_ASSERT(m_reply == qobject_cast(sender())); deleteLater(); m_reply->deleteLater(); if (m_reply->error() != QNetworkReply::NoError) { qWarning() << "GreaseMonkey: Cannot download script" << m_reply->errorString(); emit error(); return; } const QByteArray response = QString::fromUtf8(m_reply->readAll()).toUtf8(); if (!response.contains(QByteArray("// ==UserScript=="))) { qWarning() << "GreaseMonkey: Script does not contain UserScript header" << m_reply->request().url(); emit error(); return; } if (m_fileName.isEmpty()) { const QString filePath = QString("%1/%2").arg(m_manager->scriptsDirectory(), QzTools::getFileNameFromUrl(m_reply->url())); m_fileName = QzTools::ensureUniqueFilename(filePath); } QFile file(m_fileName); if (!file.open(QFile::WriteOnly)) { qWarning() << "GreaseMonkey: Cannot open file for writing" << m_fileName; emit error(); return; } file.write(response); file.close(); emit finished(m_fileName); } void GM_Downloader::requireDownloaded() { Q_ASSERT(m_reply == qobject_cast(sender())); deleteLater(); m_reply->deleteLater(); if (m_reply != qobject_cast(sender())) { emit error(); return; } if (m_reply->error() != QNetworkReply::NoError) { qWarning() << "GreaseMonkey: Cannot download require script" << m_reply->errorString(); emit error(); return; } const QByteArray response = QString::fromUtf8(m_reply->readAll()).toUtf8(); if (response.isEmpty()) { qWarning() << "GreaseMonkey: Empty script downloaded" << m_reply->request().url(); emit error(); return; } QSettings settings(m_manager->settinsPath() + QL1S("/greasemonkey/requires/requires.ini"), QSettings::IniFormat); settings.beginGroup("Files"); if (m_fileName.isEmpty()) { m_fileName = settings.value(m_reply->request().url().toString()).toString(); if (m_fileName.isEmpty()) { QString name = QFileInfo(m_reply->request().url().path()).fileName(); if (name.isEmpty()) { name = QSL("require.js"); } else if (!name.endsWith(QL1S(".js"))) { name.append(QSL(".js")); } const QString filePath = m_manager->settinsPath() + QL1S("/greasemonkey/requires/") + name; m_fileName = QzTools::ensureUniqueFilename(filePath, "%1"); } if (!QFileInfo(m_fileName).isAbsolute()) { m_fileName.prepend(m_manager->settinsPath() + QL1S("/greasemonkey/requires/")); } } QFile file(m_fileName); if (!file.open(QFile::WriteOnly)) { qWarning() << "GreaseMonkey: Cannot open file for writing" << m_fileName; emit error(); return; } file.write(response); file.close(); settings.setValue(m_reply->request().url().toString(), QFileInfo(m_fileName).fileName()); emit finished(m_fileName); } diff --git a/src/plugins/GreaseMonkey/gm_downloader.h b/src/plugins/GreaseMonkey/gm_downloader.h index ca3e9e84..8a656e10 100644 --- a/src/plugins/GreaseMonkey/gm_downloader.h +++ b/src/plugins/GreaseMonkey/gm_downloader.h @@ -1,58 +1,58 @@ /* ============================================================ -* GreaseMonkey plugin for QupZilla +* GreaseMonkey plugin for Falkon * Copyright (C) 2012-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef GM_DOWNLOADER_H #define GM_DOWNLOADER_H #include #include #include class QNetworkReply; class GM_Manager; class GM_Downloader : public QObject { Q_OBJECT public: enum Mode { DownloadMainScript, DownloadRequireScript }; explicit GM_Downloader(const QUrl &url, GM_Manager *manager, Mode mode = DownloadMainScript); void updateScript(const QString& fileName); signals: void finished(const QString& fileName); void error(); private slots: void scriptDownloaded(); void requireDownloaded(); private: void downloadRequires(); GM_Manager* m_manager; QNetworkReply *m_reply; QString m_fileName; }; #endif // GM_DOWNLOADER_H diff --git a/src/plugins/GreaseMonkey/gm_icon.cpp b/src/plugins/GreaseMonkey/gm_icon.cpp index fd2e442a..0efc017f 100644 --- a/src/plugins/GreaseMonkey/gm_icon.cpp +++ b/src/plugins/GreaseMonkey/gm_icon.cpp @@ -1,37 +1,37 @@ /* ============================================================ -* GreaseMonkey plugin for QupZilla +* GreaseMonkey plugin for Falkon * Copyright (C) 2013-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "gm_icon.h" #include "gm_manager.h" #include "browserwindow.h" GM_Icon::GM_Icon(GM_Manager* manager, BrowserWindow* window) : ClickableLabel(window) , m_manager(manager) , m_window(window) { setCursor(Qt::PointingHandCursor); setPixmap(QIcon(":gm/data/icon.svg").pixmap(16)); setToolTip(tr("Open GreaseMonkey settings")); connect(this, SIGNAL(clicked(QPoint)), this, SLOT(openSettings())); } void GM_Icon::openSettings() { m_manager->showSettings(m_window); } diff --git a/src/plugins/GreaseMonkey/gm_icon.h b/src/plugins/GreaseMonkey/gm_icon.h index 4278c67c..823e486d 100644 --- a/src/plugins/GreaseMonkey/gm_icon.h +++ b/src/plugins/GreaseMonkey/gm_icon.h @@ -1,41 +1,41 @@ /* ============================================================ -* GreaseMonkey plugin for QupZilla +* GreaseMonkey plugin for Falkon * Copyright (C) 2013-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef GM_ICON_H #define GM_ICON_H #include "clickablelabel.h" class BrowserWindow; class GM_Manager; class GM_Icon : public ClickableLabel { Q_OBJECT public: explicit GM_Icon(GM_Manager* manager, BrowserWindow* window); private slots: void openSettings(); private: GM_Manager* m_manager; BrowserWindow* m_window; }; #endif // GM_ICON_H diff --git a/src/plugins/GreaseMonkey/gm_manager.cpp b/src/plugins/GreaseMonkey/gm_manager.cpp index 34178a9a..338fb4ff 100644 --- a/src/plugins/GreaseMonkey/gm_manager.cpp +++ b/src/plugins/GreaseMonkey/gm_manager.cpp @@ -1,296 +1,296 @@ /* ============================================================ -* GreaseMonkey plugin for QupZilla +* GreaseMonkey plugin for Falkon * Copyright (C) 2012-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "gm_manager.h" #include "gm_script.h" #include "gm_downloader.h" #include "gm_icon.h" #include "gm_addscriptdialog.h" #include "settings/gm_settings.h" #include "browserwindow.h" #include "webpage.h" #include "qztools.h" #include "mainapplication.h" #include "networkmanager.h" #include "desktopnotificationsfactory.h" #include #include #include #include #include #include GM_Manager::GM_Manager(const QString &sPath, QObject* parent) : QObject(parent) , m_settingsPath(sPath) { QTimer::singleShot(0, this, SLOT(load())); } void GM_Manager::showSettings(QWidget* parent) { if (!m_settings) { m_settings = new GM_Settings(this, parent); } m_settings.data()->show(); m_settings.data()->raise(); } void GM_Manager::downloadScript(const QUrl &url) { QMetaObject::invokeMethod(this, "doDownloadScript", Qt::QueuedConnection, Q_ARG(QUrl, url)); } QString GM_Manager::settinsPath() const { return m_settingsPath; } QString GM_Manager::scriptsDirectory() const { return m_settingsPath + QL1S("/greasemonkey"); } QString GM_Manager::requireScripts(const QStringList &urlList) const { QDir requiresDir(m_settingsPath + QL1S("/greasemonkey/requires")); if (!requiresDir.exists() || urlList.isEmpty()) { return QString(); } QSettings settings(m_settingsPath + QL1S("/greasemonkey/requires/requires.ini"), QSettings::IniFormat); settings.beginGroup("Files"); QString script; foreach (const QString &url, urlList) { if (settings.contains(url)) { QString fileName = settings.value(url).toString(); if (!QFileInfo(fileName).isAbsolute()) { fileName = m_settingsPath + QL1S("/greasemonkey/requires/") + fileName; } const QString data = QzTools::readAllFileContents(fileName).trimmed(); if (!data.isEmpty()) { script.append(data + QL1C('\n')); } } } return script; } QString GM_Manager::bootstrapScript() const { return m_bootstrapScript; } QString GM_Manager::valuesScript() const { return m_valuesScript; } void GM_Manager::unloadPlugin() { // Save settings QSettings settings(m_settingsPath + "/extensions.ini", QSettings::IniFormat); settings.beginGroup("GreaseMonkey"); settings.setValue("disabledScripts", m_disabledScripts); settings.endGroup(); delete m_settings.data(); // Remove icons from all windows QHashIterator it(m_windows); while (it.hasNext()) { it.next(); mainWindowDeleted(it.key()); } } QList GM_Manager::allScripts() const { return m_scripts; } bool GM_Manager::containsScript(const QString &fullName) const { foreach (GM_Script* script, m_scripts) { if (fullName == script->fullName()) { return true; } } return false; } void GM_Manager::enableScript(GM_Script* script) { script->setEnabled(true); m_disabledScripts.removeOne(script->fullName()); QWebEngineScriptCollection *collection = mApp->webProfile()->scripts(); collection->insert(script->webScript()); } void GM_Manager::disableScript(GM_Script* script) { script->setEnabled(false); m_disabledScripts.append(script->fullName()); QWebEngineScriptCollection *collection = mApp->webProfile()->scripts(); collection->remove(collection->findScript(script->fullName())); } bool GM_Manager::addScript(GM_Script* script) { if (!script || !script->isValid()) { return false; } m_scripts.append(script); connect(script, &GM_Script::scriptChanged, this, &GM_Manager::scriptChanged); QWebEngineScriptCollection *collection = mApp->webProfile()->scripts(); collection->insert(script->webScript()); emit scriptsChanged(); return true; } bool GM_Manager::removeScript(GM_Script* script, bool removeFile) { if (!script) { return false; } m_scripts.removeOne(script); QWebEngineScriptCollection *collection = mApp->webProfile()->scripts(); collection->remove(collection->findScript(script->fullName())); m_disabledScripts.removeOne(script->fullName()); if (removeFile) { QFile::remove(script->fileName()); delete script; } emit scriptsChanged(); return true; } void GM_Manager::showNotification(const QString &message, const QString &title) { QIcon icon(":gm/data/icon.svg"); mApp->desktopNotifications()->showNotification(icon.pixmap(48), title.isEmpty() ? tr("GreaseMonkey") : title, message); } void GM_Manager::load() { QDir gmDir(m_settingsPath + QL1S("/greasemonkey")); if (!gmDir.exists()) { gmDir.mkdir(m_settingsPath + QL1S("/greasemonkey")); } if (!gmDir.exists("requires")) { gmDir.mkdir("requires"); } m_bootstrapScript = QzTools::readAllFileContents(":gm/data/bootstrap.min.js"); m_valuesScript = QzTools::readAllFileContents(":gm/data/values.min.js"); QSettings settings(m_settingsPath + QL1S("/extensions.ini"), QSettings::IniFormat); settings.beginGroup("GreaseMonkey"); m_disabledScripts = settings.value("disabledScripts", QStringList()).toStringList(); foreach (const QString &fileName, gmDir.entryList(QStringList("*.js"), QDir::Files)) { const QString absolutePath = gmDir.absoluteFilePath(fileName); GM_Script* script = new GM_Script(this, absolutePath); if (!script->isValid()) { delete script; continue; } m_scripts.append(script); if (m_disabledScripts.contains(script->fullName())) { script->setEnabled(false); } else { mApp->webProfile()->scripts()->insert(script->webScript()); } } } void GM_Manager::scriptChanged() { GM_Script *script = qobject_cast(sender()); if (!script) return; QWebEngineScriptCollection *collection = mApp->webProfile()->scripts(); collection->remove(collection->findScript(script->fullName())); collection->insert(script->webScript()); } void GM_Manager::doDownloadScript(const QUrl &url) { GM_Downloader *downloader = new GM_Downloader(url, this); connect(downloader, &GM_Downloader::finished, this, [=](const QString &fileName) { bool deleteScript = true; GM_Script *script = new GM_Script(this, fileName); if (script->isValid()) { if (!containsScript(script->fullName())) { GM_AddScriptDialog dialog(this, script); deleteScript = dialog.exec() != QDialog::Accepted; } else { showNotification(tr("'%1' is already installed").arg(script->name())); } } if (deleteScript) { delete script; QFile(fileName).remove(); } }); } bool GM_Manager::canRunOnScheme(const QString &scheme) { return (scheme == QLatin1String("http") || scheme == QLatin1String("https") || scheme == QLatin1String("data") || scheme == QLatin1String("ftp")); } void GM_Manager::mainWindowCreated(BrowserWindow* window) { GM_Icon* icon = new GM_Icon(this, window); window->statusBar()->addPermanentWidget(icon); m_windows[window] = icon; } void GM_Manager::mainWindowDeleted(BrowserWindow* window) { window->statusBar()->removeWidget(m_windows[window]); delete m_windows[window]; m_windows.remove(window); } diff --git a/src/plugins/GreaseMonkey/gm_manager.h b/src/plugins/GreaseMonkey/gm_manager.h index e66bd650..bed11ae2 100644 --- a/src/plugins/GreaseMonkey/gm_manager.h +++ b/src/plugins/GreaseMonkey/gm_manager.h @@ -1,89 +1,89 @@ /* ============================================================ -* GreaseMonkey plugin for QupZilla +* GreaseMonkey plugin for Falkon * Copyright (C) 2013-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef GM_MANAGER_H #define GM_MANAGER_H #include #include #include #include class QUrl; class QWebFrame; class BrowserWindow; class GM_Script; class GM_Settings; class GM_Icon; class GM_Manager : public QObject { Q_OBJECT public: explicit GM_Manager(const QString &sPath, QObject* parent = 0); void showSettings(QWidget* parent); void downloadScript(const QUrl &url); QString settinsPath() const; QString scriptsDirectory() const; QString requireScripts(const QStringList &urlList) const; QString bootstrapScript() const; QString valuesScript() const; void unloadPlugin(); QList allScripts() const; bool containsScript(const QString &fullName) const; void enableScript(GM_Script* script); void disableScript(GM_Script* script); bool addScript(GM_Script* script); bool removeScript(GM_Script* script, bool removeFile = true); void showNotification(const QString &message, const QString &title = QString()); static bool canRunOnScheme(const QString &scheme); signals: void scriptsChanged(); public slots: void mainWindowCreated(BrowserWindow* window); void mainWindowDeleted(BrowserWindow* window); private slots: void load(); void scriptChanged(); void doDownloadScript(const QUrl &url); private: QString m_settingsPath; QString m_bootstrapScript; QString m_valuesScript; QPointer m_settings; QStringList m_disabledScripts; //GM_JSObject* m_jsObject; QList m_scripts; QHash m_windows; }; #endif // GM_MANAGER_H diff --git a/src/plugins/GreaseMonkey/gm_notification.cpp b/src/plugins/GreaseMonkey/gm_notification.cpp index ecad1be9..6d518b76 100644 --- a/src/plugins/GreaseMonkey/gm_notification.cpp +++ b/src/plugins/GreaseMonkey/gm_notification.cpp @@ -1,70 +1,70 @@ /* ============================================================ -* GreaseMonkey plugin for QupZilla +* GreaseMonkey plugin for Falkon * Copyright (C) 2012-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "gm_notification.h" #include "ui_gm_notification.h" #include "gm_manager.h" #include "gm_script.h" #include "iconprovider.h" #include GM_Notification::GM_Notification(GM_Manager* manager, const QString &tmpfileName, const QString &fileName) : AnimatedWidget(AnimatedWidget::Down, 300, 0) , ui(new Ui::GM_Notification) , m_manager(manager) , m_tmpFileName(tmpfileName) , m_fileName(fileName) { setAutoFillBackground(true); ui->setupUi(widget()); ui->iconLabel->setPixmap(QIcon(QSL(":gm/data/icon.svg")).pixmap(24)); ui->close->setIcon(IconProvider::standardIcon(QStyle::SP_DialogCloseButton)); connect(ui->install, SIGNAL(clicked()), this, SLOT(installScript())); connect(ui->close, SIGNAL(clicked()), this, SLOT(hide())); startAnimation(); } void GM_Notification::installScript() { bool success = false; GM_Script* script = 0; QString message = tr("Cannot install script"); if (QFile::copy(m_tmpFileName, m_fileName)) { script = new GM_Script(m_manager, m_fileName); success = m_manager->addScript(script); } if (success) { message = tr("'%1' installed successfully").arg(script->name()); } m_manager->showNotification(message); hide(); } GM_Notification::~GM_Notification() { delete ui; } diff --git a/src/plugins/GreaseMonkey/gm_notification.h b/src/plugins/GreaseMonkey/gm_notification.h index ca180720..c030e4a2 100644 --- a/src/plugins/GreaseMonkey/gm_notification.h +++ b/src/plugins/GreaseMonkey/gm_notification.h @@ -1,51 +1,51 @@ /* ============================================================ -* GreaseMonkey plugin for QupZilla +* GreaseMonkey plugin for Falkon * Copyright (C) 2012-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef GM_NOTIFICATION_H #define GM_NOTIFICATION_H #include "animatedwidget.h" namespace Ui { class GM_Notification; } class GM_Manager; class GM_Script; class GM_Notification : public AnimatedWidget { Q_OBJECT public: explicit GM_Notification(GM_Manager* manager, const QString &tmpfileName, const QString &fileName); ~GM_Notification(); private slots: void installScript(); private: Ui::GM_Notification* ui; GM_Manager* m_manager; QString m_tmpFileName; QString m_fileName; }; #endif // GM_NOTIFICATION_H diff --git a/src/plugins/GreaseMonkey/gm_plugin.cpp b/src/plugins/GreaseMonkey/gm_plugin.cpp index b211803c..88417630 100644 --- a/src/plugins/GreaseMonkey/gm_plugin.cpp +++ b/src/plugins/GreaseMonkey/gm_plugin.cpp @@ -1,100 +1,100 @@ /* ============================================================ * GreaseMonkey plugin for QupZilla * Copyright (C) 2012-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "gm_plugin.h" #include "gm_manager.h" #include "browserwindow.h" #include "webpage.h" #include "pluginproxy.h" #include "mainapplication.h" #include "emptynetworkreply.h" #include "tabwidget.h" #include "webtab.h" #include "tabbedwebview.h" #include GM_Plugin::GM_Plugin() : QObject() , m_manager(0) { } PluginSpec GM_Plugin::pluginSpec() { PluginSpec spec; spec.name = "GreaseMonkey"; - spec.info = "Userscripts for QupZilla"; + spec.info = "Userscripts for Falkon"; spec.description = "Provides support for userscripts"; spec.version = "0.8.0"; spec.author = "David Rosca "; spec.icon = QIcon(":gm/data/icon.svg").pixmap(32); spec.hasSettings = true; return spec; } void GM_Plugin::init(InitState state, const QString &settingsPath) { m_manager = new GM_Manager(settingsPath, this); connect(mApp->plugins(), SIGNAL(mainWindowCreated(BrowserWindow*)), m_manager, SLOT(mainWindowCreated(BrowserWindow*))); connect(mApp->plugins(), SIGNAL(mainWindowDeleted(BrowserWindow*)), m_manager, SLOT(mainWindowDeleted(BrowserWindow*))); // Make sure userscripts works also with already created WebPages if (state == LateInitState) { foreach (BrowserWindow *window, mApp->windows()) { m_manager->mainWindowCreated(window); } } } void GM_Plugin::unload() { m_manager->unloadPlugin(); delete m_manager; } bool GM_Plugin::testPlugin() { // Require the version that the plugin was built with - return (Qz::VERSION == QLatin1String(QUPZILLA_VERSION)); + return (Qz::VERSION == QLatin1String(FALKON_VERSION)); } QTranslator* GM_Plugin::getTranslator(const QString &locale) { QTranslator* translator = new QTranslator(this); translator->load(locale, ":/gm/locale/"); return translator; } void GM_Plugin::showSettings(QWidget* parent) { m_manager->showSettings(parent); } bool GM_Plugin::acceptNavigationRequest(WebPage *page, const QUrl &url, QWebEnginePage::NavigationType type, bool isMainFrame) { Q_UNUSED(page) Q_UNUSED(isMainFrame) if (type == QWebEnginePage::NavigationTypeLinkClicked && url.toString().endsWith(QLatin1String(".user.js"))) { m_manager->downloadScript(url); return false; } return true; } diff --git a/src/plugins/GreaseMonkey/gm_plugin.h b/src/plugins/GreaseMonkey/gm_plugin.h index 5a255be7..8f265acf 100644 --- a/src/plugins/GreaseMonkey/gm_plugin.h +++ b/src/plugins/GreaseMonkey/gm_plugin.h @@ -1,49 +1,49 @@ /* ============================================================ * GreaseMonkey plugin for QupZilla * Copyright (C) 2012-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef GM_PLUGIN_H #define GM_PLUGIN_H #include "plugininterface.h" class WebPage; class GM_Manager; class GM_Plugin : public QObject, public PluginInterface { Q_OBJECT Q_INTERFACES(PluginInterface) - Q_PLUGIN_METADATA(IID "QupZilla.Browser.plugin.GreaseMonkey") + Q_PLUGIN_METADATA(IID "Falkon.Browser.plugin.GreaseMonkey") public: explicit GM_Plugin(); PluginSpec pluginSpec(); void init(InitState state, const QString &settingsPath); void unload(); bool testPlugin(); QTranslator* getTranslator(const QString &locale); void showSettings(QWidget* parent = 0); bool acceptNavigationRequest(WebPage *page, const QUrl &url, QWebEnginePage::NavigationType type, bool isMainFrame) override; private: GM_Manager* m_manager; }; #endif // GM_PLUGIN_H diff --git a/src/plugins/GreaseMonkey/gm_script.cpp b/src/plugins/GreaseMonkey/gm_script.cpp index 1f6a520e..82ad0cd1 100644 --- a/src/plugins/GreaseMonkey/gm_script.cpp +++ b/src/plugins/GreaseMonkey/gm_script.cpp @@ -1,309 +1,309 @@ /* ============================================================ -* GreaseMonkey plugin for QupZilla +* GreaseMonkey plugin for Falkon * Copyright (C) 2012-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "gm_script.h" #include "gm_manager.h" #include "gm_downloader.h" #include "qzregexp.h" #include "delayedfilewatcher.h" #include "mainapplication.h" #include #include #include #include #include GM_Script::GM_Script(GM_Manager* manager, const QString &filePath) : QObject(manager) , m_manager(manager) , m_fileWatcher(new DelayedFileWatcher(this)) , m_namespace("GreaseMonkeyNS") , m_startAt(DocumentEnd) , m_noframes(false) , m_fileName(filePath) , m_enabled(true) , m_valid(false) , m_updating(false) { parseScript(); connect(m_fileWatcher, SIGNAL(delayedFileChanged(QString)), this, SLOT(watchedFileChanged(QString))); } bool GM_Script::isValid() const { return m_valid; } QString GM_Script::name() const { return m_name; } QString GM_Script::nameSpace() const { return m_namespace; } QString GM_Script::fullName() const { return QString("%1/%2").arg(m_namespace, m_name); } QString GM_Script::description() const { return m_description; } QString GM_Script::version() const { return m_version; } QUrl GM_Script::downloadUrl() const { return m_downloadUrl; } QUrl GM_Script::updateUrl() const { return m_updateUrl; } GM_Script::StartAt GM_Script::startAt() const { return m_startAt; } bool GM_Script::noFrames() const { return m_noframes; } bool GM_Script::isEnabled() const { return m_valid && m_enabled; } void GM_Script::setEnabled(bool enable) { m_enabled = enable; } QStringList GM_Script::include() const { return m_include; } QStringList GM_Script::exclude() const { return m_exclude; } QStringList GM_Script::require() const { return m_require; } QString GM_Script::fileName() const { return m_fileName; } QWebEngineScript GM_Script::webScript() const { QWebEngineScript script; script.setSourceCode(QSL("%1\n%2").arg(m_manager->bootstrapScript(), m_script)); script.setName(fullName()); script.setWorldId(QWebEngineScript::MainWorld); script.setRunsOnSubFrames(!m_noframes); return script; } bool GM_Script::isUpdating() { return m_updating; } void GM_Script::updateScript() { if (!m_downloadUrl.isValid() || m_updating) return; m_updating = true; emit updatingChanged(m_updating); GM_Downloader *downloader = new GM_Downloader(m_downloadUrl, m_manager); downloader->updateScript(m_fileName); connect(downloader, &GM_Downloader::finished, this, [this]() { m_updating = false; emit updatingChanged(m_updating); }); connect(downloader, &GM_Downloader::error, this, [this]() { m_updating = false; emit updatingChanged(m_updating); }); downloadRequires(); } void GM_Script::watchedFileChanged(const QString &file) { if (m_fileName == file) { reloadScript(); } } void GM_Script::parseScript() { m_name.clear(); m_namespace = QSL("GreaseMonkeyNS"); m_description.clear(); m_version.clear(); m_include.clear(); m_exclude.clear(); m_require.clear(); m_downloadUrl.clear(); m_updateUrl.clear(); m_startAt = DocumentEnd; m_noframes = false; m_script.clear(); m_enabled = true; m_valid = false; QFile file(m_fileName); if (!file.open(QFile::ReadOnly)) { qWarning() << "GreaseMonkey: Cannot open file for reading" << m_fileName; return; } if (!m_fileWatcher->files().contains(m_fileName)) { m_fileWatcher->addPath(m_fileName); } const QByteArray fileData = file.readAll(); bool inMetadata = false; QTextStream stream(fileData); QString line; while (stream.readLineInto(&line)) { if (line.startsWith(QL1S("// ==UserScript=="))) { inMetadata = true; } if (line.startsWith(QL1S("// ==/UserScript=="))) { break; } if (!inMetadata) { continue; } if (!line.startsWith(QLatin1String("// @"))) { continue; } line = line.mid(3).replace(QLatin1Char('\t'), QLatin1Char(' ')); int index = line.indexOf(QLatin1Char(' ')); if (index < 0) { continue; } const QString key = line.left(index).trimmed(); const QString value = line.mid(index + 1).trimmed(); if (key.isEmpty() || value.isEmpty()) { continue; } if (key == QLatin1String("@name")) { m_name = value; } else if (key == QLatin1String("@namespace")) { m_namespace = value; } else if (key == QLatin1String("@description")) { m_description = value; } else if (key == QLatin1String("@version")) { m_version = value; } else if (key == QLatin1String("@updateURL")) { m_updateUrl = QUrl(value); } else if (key == QLatin1String("@downloadURL")) { m_downloadUrl = QUrl(value); } else if (key == QLatin1String("@include") || key == QLatin1String("@match")) { m_include.append(value); } else if (key == QLatin1String("@exclude") || key == QLatin1String("@exclude_match")) { m_exclude.append(value); } else if (key == QLatin1String("@require")) { m_require.append(value); } else if (key == QLatin1String("@run-at")) { if (value == QLatin1String("document-end")) { m_startAt = DocumentEnd; } else if (value == QLatin1String("document-start")) { m_startAt = DocumentStart; } else if (value == QLatin1String("document-idle")) { m_startAt = DocumentIdle; } } } if (!inMetadata) { qWarning() << "GreaseMonkey: File does not contain metadata block" << m_fileName; return; } if (m_include.isEmpty()) { m_include.append(QSL("*")); } const QString nspace = QCryptographicHash::hash(fullName().toUtf8(), QCryptographicHash::Md4).toHex(); const QString gmValues = m_manager->valuesScript().arg(nspace); m_script = QSL("(function(){%1\n%2\n%3\n})();").arg(gmValues, m_manager->requireScripts(m_require), fileData); m_valid = true; downloadRequires(); } void GM_Script::reloadScript() { parseScript(); m_manager->removeScript(this, false); m_manager->addScript(this); emit scriptChanged(); } void GM_Script::downloadRequires() { for (const QString &url : qAsConst(m_require)) { if (m_manager->requireScripts({url}).isEmpty()) { GM_Downloader *downloader = new GM_Downloader(QUrl(url), m_manager, GM_Downloader::DownloadRequireScript); connect(downloader, &GM_Downloader::finished, this, &GM_Script::reloadScript); } } } diff --git a/src/plugins/GreaseMonkey/gm_script.h b/src/plugins/GreaseMonkey/gm_script.h index 013e9e90..28796209 100644 --- a/src/plugins/GreaseMonkey/gm_script.h +++ b/src/plugins/GreaseMonkey/gm_script.h @@ -1,104 +1,104 @@ /* ============================================================ -* GreaseMonkey plugin for QupZilla +* GreaseMonkey plugin for Falkon * Copyright (C) 2012-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef GM_SCRIPT_H #define GM_SCRIPT_H #include #include #include class QWebEngineScript; class GM_Manager; class DelayedFileWatcher; class GM_Script : public QObject { Q_OBJECT public: explicit GM_Script(GM_Manager* manager, const QString &filePath); enum StartAt { DocumentStart, DocumentEnd, DocumentIdle }; bool isValid() const; QString name() const; QString nameSpace() const; QString fullName() const; QString description() const; QString version() const; QUrl downloadUrl() const; QUrl updateUrl() const; StartAt startAt() const; bool noFrames() const; bool isEnabled() const; void setEnabled(bool enable); QStringList include() const; QStringList exclude() const; QStringList require() const; QString metaData() const; QString fileName() const; QWebEngineScript webScript() const; bool isUpdating(); void updateScript(); signals: void scriptChanged(); void updatingChanged(bool updating); private slots: void watchedFileChanged(const QString &file); private: void parseScript(); void reloadScript(); void downloadRequires(); GM_Manager* m_manager; DelayedFileWatcher* m_fileWatcher; QString m_name; QString m_namespace; QString m_description; QString m_version; QStringList m_include; QStringList m_exclude; QStringList m_require; QUrl m_downloadUrl; QUrl m_updateUrl; StartAt m_startAt; bool m_noframes; QString m_script; QString m_fileName; bool m_enabled; bool m_valid; bool m_updating; }; #endif // GM_SCRIPT_H diff --git a/src/plugins/GreaseMonkey/settings/gm_settings.cpp b/src/plugins/GreaseMonkey/settings/gm_settings.cpp index b46dbc23..bb0ec02f 100644 --- a/src/plugins/GreaseMonkey/settings/gm_settings.cpp +++ b/src/plugins/GreaseMonkey/settings/gm_settings.cpp @@ -1,206 +1,206 @@ /* ============================================================ * GreaseMonkey plugin for QupZilla * Copyright (C) 2012-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "gm_settings.h" #include "ui_gm_settings.h" #include "gm_settingsscriptinfo.h" #include "../gm_manager.h" #include "../gm_script.h" #include "qztools.h" #include "mainapplication.h" #include #include #include GM_Settings::GM_Settings(GM_Manager* manager, QWidget* parent) : QDialog(parent) , ui(new Ui::GM_Settings) , m_manager(manager) { setAttribute(Qt::WA_DeleteOnClose); ui->setupUi(this); ui->iconLabel->setPixmap(QIcon(QSL(":gm/data/icon.svg")).pixmap(32)); connect(ui->listWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(showItemInfo(QListWidgetItem*))); connect(ui->listWidget, SIGNAL(updateItemRequested(QListWidgetItem*)), this, SLOT(updateItem(QListWidgetItem*))); connect(ui->listWidget, SIGNAL(removeItemRequested(QListWidgetItem*)), this, SLOT(removeItem(QListWidgetItem*))); connect(ui->openDirectory, SIGNAL(clicked()), this, SLOT(openScriptsDirectory())); connect(ui->newScript, SIGNAL(clicked()), this, SLOT(newScript())); connect(ui->link, SIGNAL(clicked(QPoint)), this, SLOT(openUserJs())); connect(manager, SIGNAL(scriptsChanged()), this, SLOT(loadScripts())); loadScripts(); } void GM_Settings::openUserJs() { mApp->addNewTab(QUrl(QSL("http://openuserjs.org"))); close(); } void GM_Settings::showItemInfo(QListWidgetItem* item) { GM_Script* script = getScript(item); if (!script) { return; } GM_SettingsScriptInfo* dialog = new GM_SettingsScriptInfo(script, this); dialog->open(); } void GM_Settings::updateItem(QListWidgetItem* item) { GM_Script *script = getScript(item); if (!script) { return; } script->updateScript(); } void GM_Settings::removeItem(QListWidgetItem* item) { GM_Script* script = getScript(item); if (!script) { return; } QMessageBox::StandardButton button = QMessageBox::question(this, tr("Remove script"), tr("Are you sure you want to remove '%1'?").arg(script->name()), QMessageBox::Yes | QMessageBox::No); if (button == QMessageBox::Yes) { m_manager->removeScript(script); } } void GM_Settings::itemChanged(QListWidgetItem* item) { GM_Script* script = getScript(item); if (!script) { return; } if (item->checkState() == Qt::Checked) { m_manager->enableScript(script); } else { m_manager->disableScript(script); } } void GM_Settings::openScriptsDirectory() { QDesktopServices::openUrl(QUrl::fromLocalFile(m_manager->scriptsDirectory())); } void GM_Settings::newScript() { const QString name = QInputDialog::getText(this, tr("Add script"), tr("Choose name for script:")); if (name.isEmpty()) return; const QString script = QL1S("// ==UserScript== \n" "// @name %1 \n" - "// @namespace qupzilla.com \n" + "// @namespace kde.org \n" "// @description Script description \n" "// @include * \n" "// @version 1.0.0 \n" "// ==/UserScript==\n\n"); const QString fileName = QSL("%1/%2.user.js").arg(m_manager->scriptsDirectory(), QzTools::filterCharsFromFilename(name)); QFile file(QzTools::ensureUniqueFilename(fileName)); file.open(QFile::WriteOnly); file.write(script.arg(name).toUtf8()); file.close(); GM_Script *gmScript = new GM_Script(m_manager, file.fileName()); m_manager->addScript(gmScript); GM_SettingsScriptInfo* dialog = new GM_SettingsScriptInfo(gmScript, this); dialog->open(); } void GM_Settings::loadScripts() { disconnect(ui->listWidget, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(itemChanged(QListWidgetItem*))); ui->listWidget->clear(); foreach (GM_Script* script, m_manager->allScripts()) { QListWidgetItem* item = new QListWidgetItem(ui->listWidget); item->setText(script->name()); item->setFlags(item->flags() | Qt::ItemIsUserCheckable); item->setCheckState(script->isEnabled() ? Qt::Checked : Qt::Unchecked); item->setData(Qt::UserRole + 10, QVariant::fromValue((void*)script)); connect(script, &GM_Script::updatingChanged, this, [this]() { ui->listWidget->viewport()->update(); }); ui->listWidget->addItem(item); } ui->listWidget->sortItems(); bool itemMoved; do { itemMoved = false; for (int i = 0; i < ui->listWidget->count(); ++i) { QListWidgetItem* topItem = ui->listWidget->item(i); QListWidgetItem* bottomItem = ui->listWidget->item(i + 1); if (!topItem || !bottomItem) { continue; } if (topItem->checkState() == Qt::Unchecked && bottomItem->checkState() == Qt::Checked) { QListWidgetItem* item = ui->listWidget->takeItem(i + 1); ui->listWidget->insertItem(i, item); itemMoved = true; } } } while (itemMoved); connect(ui->listWidget, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(itemChanged(QListWidgetItem*))); } GM_Script* GM_Settings::getScript(QListWidgetItem* item) { if (!item) { return 0; } GM_Script* script = static_cast(item->data(Qt::UserRole + 10).value()); return script; } GM_Settings::~GM_Settings() { delete ui; } diff --git a/src/plugins/GreaseMonkey/settings/gm_settings.h b/src/plugins/GreaseMonkey/settings/gm_settings.h index 050ae5aa..e1078452 100644 --- a/src/plugins/GreaseMonkey/settings/gm_settings.h +++ b/src/plugins/GreaseMonkey/settings/gm_settings.h @@ -1,61 +1,61 @@ /* ============================================================ -* GreaseMonkey plugin for QupZilla +* GreaseMonkey plugin for Falkon * Copyright (C) 2012-2013 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef GM_SETTINGS_H #define GM_SETTINGS_H #include namespace Ui { class GM_Settings; } class QListWidgetItem; class GM_Manager; class GM_Script; class GM_Settings : public QDialog { Q_OBJECT public: explicit GM_Settings(GM_Manager* manager, QWidget* parent = 0); ~GM_Settings(); private slots: void showItemInfo(QListWidgetItem* item); void updateItem(QListWidgetItem* item); void removeItem(QListWidgetItem* item); void itemChanged(QListWidgetItem* item); void openScriptsDirectory(); void newScript(); void openUserJs(); void loadScripts(); private: inline GM_Script* getScript(QListWidgetItem* item); Ui::GM_Settings* ui; GM_Manager* m_manager; }; #endif // GM_SETTINGS_H diff --git a/src/plugins/GreaseMonkey/settings/gm_settingslistdelegate.cpp b/src/plugins/GreaseMonkey/settings/gm_settingslistdelegate.cpp index 74cc6926..a7decfda 100644 --- a/src/plugins/GreaseMonkey/settings/gm_settingslistdelegate.cpp +++ b/src/plugins/GreaseMonkey/settings/gm_settingslistdelegate.cpp @@ -1,173 +1,173 @@ /* ============================================================ -* GreaseMonkey plugin for QupZilla +* GreaseMonkey plugin for Falkon * Copyright (C) 2012-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "gm_settingslistdelegate.h" #include "gm_script.h" #include "iconprovider.h" #include #include #include GM_SettingsListDelegate::GM_SettingsListDelegate(QObject* parent) : QStyledItemDelegate(parent) , m_rowHeight(0) , m_padding(0) { m_removePixmap = IconProvider::standardIcon(QStyle::SP_DialogCloseButton).pixmap(16); m_updateIcon = IconProvider::standardIcon(QStyle::SP_BrowserReload); } int GM_SettingsListDelegate::padding() const { return m_padding; } void GM_SettingsListDelegate::paint(QPainter* painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { GM_Script *script = static_cast(index.data(Qt::UserRole + 10).value()); if (!script) return; QStyleOptionViewItem opt = option; initStyleOption(&opt, index); const QWidget* w = opt.widget; const QStyle* style = w ? w->style() : QApplication::style(); const int height = opt.rect.height(); const int center = height / 2 + opt.rect.top(); // forced to LTR, see issue#967 painter->setLayoutDirection(Qt::LeftToRight); // Prepare title font QFont titleFont = opt.font; titleFont.setBold(true); titleFont.setPointSize(titleFont.pointSize() + 1); const QFontMetrics titleMetrics(titleFont); const QPalette::ColorRole colorRole = opt.state & QStyle::State_Selected ? QPalette::HighlightedText : QPalette::Text; QPalette::ColorGroup cg = opt.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled; if (cg == QPalette::Normal && !(opt.state & QStyle::State_Active)) { cg = QPalette::Inactive; } #ifdef Q_OS_WIN opt.palette.setColor(QPalette::All, QPalette::HighlightedText, opt.palette.color(QPalette::Active, QPalette::Text)); opt.palette.setColor(QPalette::All, QPalette::Highlight, opt.palette.base().color().darker(108)); #endif QPalette textPalette = opt.palette; textPalette.setCurrentColorGroup(cg); int leftPosition = m_padding; int rightPosition = opt.rect.right() - m_padding - 16; // 16 for remove button if (!script->downloadUrl().isEmpty()) rightPosition -= m_padding + 16; // 16 for update button // Draw background style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, w); // Draw checkbox const int checkboxSize = 18; const int checkboxYPos = center - (checkboxSize / 2); QStyleOptionViewItem opt2 = opt; opt2.checkState == Qt::Checked ? opt2.state |= QStyle::State_On : opt2.state |= QStyle::State_Off; QRect styleCheckBoxRect = style->subElementRect(QStyle::SE_ViewItemCheckIndicator, &opt2, w); opt2.rect = QRect(leftPosition, checkboxYPos, styleCheckBoxRect.width(), styleCheckBoxRect.height()); style->drawPrimitive(QStyle::PE_IndicatorViewItemCheck, &opt2, painter, w); leftPosition = opt2.rect.right() + m_padding; // Draw icon const int iconSize = 32; const int iconYPos = center - (iconSize / 2); QRect iconRect(leftPosition, iconYPos, iconSize, iconSize); QPixmap pixmap = index.data(Qt::DecorationRole).value().pixmap(iconSize); if (!pixmap.isNull()) { painter->drawPixmap(iconRect, pixmap); leftPosition = iconRect.right() + m_padding; } else { leftPosition += m_padding; } // Draw script name const QString name = index.data(Qt::DisplayRole).toString(); const int leftTitleEdge = leftPosition + 2; const int rightTitleEdge = rightPosition - m_padding; const int leftPosForVersion = titleMetrics.width(name) + m_padding; QRect nameRect(leftTitleEdge, opt.rect.top() + m_padding, rightTitleEdge - leftTitleEdge, titleMetrics.height()); painter->setFont(titleFont); style->drawItemText(painter, nameRect, Qt::AlignLeft, textPalette, true, name, colorRole); // Draw version QRect versionRect(nameRect.x() + leftPosForVersion, nameRect.y(), rightTitleEdge - leftPosForVersion, titleMetrics.height()); QFont versionFont = titleFont; versionFont.setBold(false); painter->setFont(versionFont); style->drawItemText(painter, versionRect, Qt::AlignLeft, textPalette, true, script->version(), colorRole); // Draw description const int infoYPos = nameRect.bottom() + opt.fontMetrics.leading(); QRect infoRect(nameRect.x(), infoYPos, nameRect.width(), opt.fontMetrics.height()); const QString info = opt.fontMetrics.elidedText(script->description(), Qt::ElideRight, infoRect.width()); painter->setFont(opt.font); style->drawItemText(painter, infoRect, Qt::TextSingleLine | Qt::AlignLeft, textPalette, true, info, colorRole); // Draw update button if (!script->downloadUrl().isEmpty()) { const int updateIconSize = 16; const int updateIconYPos = center - (updateIconSize / 2); const QPixmap updatePixmap = m_updateIcon.pixmap(16, script->isUpdating() ? QIcon::Disabled : QIcon::Normal); QRect updateIconRect(rightPosition, updateIconYPos, updateIconSize, updateIconSize); painter->drawPixmap(updateIconRect, updatePixmap); rightPosition += m_padding + 16; } // Draw remove button const int removeIconSize = 16; const int removeIconYPos = center - (removeIconSize / 2); QRect removeIconRect(rightPosition, removeIconYPos, removeIconSize, removeIconSize); painter->drawPixmap(removeIconRect, m_removePixmap); } QSize GM_SettingsListDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const { Q_UNUSED(index) if (!m_rowHeight) { QStyleOptionViewItem opt(option); initStyleOption(&opt, index); const QWidget* w = opt.widget; const QStyle* style = w ? w->style() : QApplication::style(); const int padding = style->pixelMetric(QStyle::PM_FocusFrameHMargin, 0) + 1; QFont titleFont = opt.font; titleFont.setBold(true); titleFont.setPointSize(titleFont.pointSize() + 1); m_padding = padding > 5 ? padding : 5; const QFontMetrics titleMetrics(titleFont); m_rowHeight = 2 * m_padding + opt.fontMetrics.leading() + opt.fontMetrics.height() + titleMetrics.height(); } return QSize(200, m_rowHeight); } diff --git a/src/plugins/GreaseMonkey/settings/gm_settingslistdelegate.h b/src/plugins/GreaseMonkey/settings/gm_settingslistdelegate.h index 30668f40..c5a50ced 100644 --- a/src/plugins/GreaseMonkey/settings/gm_settingslistdelegate.h +++ b/src/plugins/GreaseMonkey/settings/gm_settingslistdelegate.h @@ -1,41 +1,41 @@ /* ============================================================ -* GreaseMonkey plugin for QupZilla +* GreaseMonkey plugin for Falkon * Copyright (C) 2012 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef GM_SETTINGSLISTDELEGATE_H #define GM_SETTINGSLISTDELEGATE_H #include class GM_SettingsListDelegate : public QStyledItemDelegate { public: explicit GM_SettingsListDelegate(QObject* parent = 0); int padding() const; void paint(QPainter* painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const; private: QPixmap m_removePixmap; QIcon m_updateIcon; mutable int m_rowHeight; mutable int m_padding; }; #endif // GM_SETTINGSLISTDELEGATE_H diff --git a/src/plugins/GreaseMonkey/settings/gm_settingslistwidget.cpp b/src/plugins/GreaseMonkey/settings/gm_settingslistwidget.cpp index a0b9dcb7..340aa70a 100644 --- a/src/plugins/GreaseMonkey/settings/gm_settingslistwidget.cpp +++ b/src/plugins/GreaseMonkey/settings/gm_settingslistwidget.cpp @@ -1,91 +1,91 @@ /* ============================================================ -* GreaseMonkey plugin for QupZilla +* GreaseMonkey plugin for Falkon * Copyright (C) 2012-2016 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "gm_settingslistwidget.h" #include "gm_settingslistdelegate.h" #include "gm_script.h" #include GM_SettingsListWidget::GM_SettingsListWidget(QWidget* parent) : QListWidget(parent) , m_delegate(new GM_SettingsListDelegate(this)) { // forced to LTR, see issue#967 setLayoutDirection(Qt::LeftToRight); setItemDelegate(m_delegate); } void GM_SettingsListWidget::mousePressEvent(QMouseEvent* event) { if (containsRemoveIcon(event->pos())) { emit removeItemRequested(itemAt(event->pos())); return; } if (containsUpdateIcon(event->pos())) { emit updateItemRequested(itemAt(event->pos())); return; } QListWidget::mousePressEvent(event); } void GM_SettingsListWidget::mouseDoubleClickEvent(QMouseEvent* event) { if (containsRemoveIcon(event->pos()) || containsUpdateIcon(event->pos())) return; QListWidget::mouseDoubleClickEvent(event); } bool GM_SettingsListWidget::containsRemoveIcon(const QPoint &pos) const { QListWidgetItem* item = itemAt(pos); if (!item) { return false; } const QRect rect = visualItemRect(item); const int removeIconPosition = rect.right() - m_delegate->padding() - 16; const int center = rect.height() / 2 + rect.top(); const int removeIconYPos = center - (16 / 2); QRect removeIconRect(removeIconPosition, removeIconYPos, 16, 16); return removeIconRect.contains(pos); } bool GM_SettingsListWidget::containsUpdateIcon(const QPoint &pos) const { QListWidgetItem *item = itemAt(pos); if (!item) return false; GM_Script *script = static_cast(item->data(Qt::UserRole + 10).value()); if (!script || script->downloadUrl().isEmpty()) return false; const QRect rect = visualItemRect(item); const int updateIconPosition = rect.right() - m_delegate->padding() * 2 - 16 * 2; const int center = rect.height() / 2 + rect.top(); const int updateIconYPos = center - (16 / 2); QRect updateIconRect(updateIconPosition, updateIconYPos, 16, 16); return updateIconRect.contains(pos); } diff --git a/src/plugins/GreaseMonkey/settings/gm_settingslistwidget.h b/src/plugins/GreaseMonkey/settings/gm_settingslistwidget.h index d43598ca..ae3e87dc 100644 --- a/src/plugins/GreaseMonkey/settings/gm_settingslistwidget.h +++ b/src/plugins/GreaseMonkey/settings/gm_settingslistwidget.h @@ -1,48 +1,48 @@ /* ============================================================ -* GreaseMonkey plugin for QupZilla +* GreaseMonkey plugin for Falkon * Copyright (C) 2012 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef GM_SETTINGSLISTWIDGET_H #define GM_SETTINGSLISTWIDGET_H #include class GM_SettingsListDelegate; class GM_SettingsListWidget : public QListWidget { Q_OBJECT public: explicit GM_SettingsListWidget(QWidget* parent = 0); signals: void removeItemRequested(QListWidgetItem* item); void updateItemRequested(QListWidgetItem* item); public slots: private: bool containsRemoveIcon(const QPoint &pos) const; bool containsUpdateIcon(const QPoint &pos) const; void mousePressEvent(QMouseEvent* event); void mouseDoubleClickEvent(QMouseEvent* event); GM_SettingsListDelegate* m_delegate; }; #endif // GM_SETTINGSLISTWIDGET_H diff --git a/src/plugins/GreaseMonkey/settings/gm_settingsscriptinfo.cpp b/src/plugins/GreaseMonkey/settings/gm_settingsscriptinfo.cpp index ba67870c..990f0514 100644 --- a/src/plugins/GreaseMonkey/settings/gm_settingsscriptinfo.cpp +++ b/src/plugins/GreaseMonkey/settings/gm_settingsscriptinfo.cpp @@ -1,67 +1,67 @@ /* ============================================================ -* GreaseMonkey plugin for QupZilla +* GreaseMonkey plugin for Falkon * Copyright (C) 2012-2013 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "gm_settingsscriptinfo.h" #include "ui_gm_settingsscriptinfo.h" #include "../gm_script.h" #include GM_SettingsScriptInfo::GM_SettingsScriptInfo(GM_Script* script, QWidget* parent) : QDialog(parent) , ui(new Ui::GM_SettingsScriptInfo) , m_script(script) { setAttribute(Qt::WA_DeleteOnClose); ui->setupUi(this); loadScript(); connect(m_script, SIGNAL(scriptChanged()), this, SLOT(loadScript())); connect(ui->editInEditor, SIGNAL(clicked()), this, SLOT(editInTextEditor())); } void GM_SettingsScriptInfo::editInTextEditor() { QDesktopServices::openUrl(QUrl::fromLocalFile(m_script->fileName())); } void GM_SettingsScriptInfo::loadScript() { setWindowTitle(tr("Script Details of %1").arg(m_script->name())); ui->name->setText(m_script->name()); ui->nspace->setText(m_script->nameSpace()); ui->version->setText(m_script->version()); ui->url->setText(m_script->downloadUrl().toString()); ui->startAt->setText(m_script->startAt() == GM_Script::DocumentStart ? "document-start" : "document-end"); ui->description->setText(m_script->description()); ui->include->setText(m_script->include().join("
")); ui->exclude->setText(m_script->exclude().join("
")); ui->version->setVisible(!m_script->version().isEmpty()); ui->labelVersion->setVisible(!m_script->version().isEmpty()); ui->url->setVisible(!m_script->downloadUrl().isEmpty()); ui->labelUrl->setVisible(!m_script->downloadUrl().isEmpty()); } GM_SettingsScriptInfo::~GM_SettingsScriptInfo() { delete ui; } diff --git a/src/plugins/GreaseMonkey/settings/gm_settingsscriptinfo.h b/src/plugins/GreaseMonkey/settings/gm_settingsscriptinfo.h index 187eb228..e2270798 100644 --- a/src/plugins/GreaseMonkey/settings/gm_settingsscriptinfo.h +++ b/src/plugins/GreaseMonkey/settings/gm_settingsscriptinfo.h @@ -1,48 +1,48 @@ /* ============================================================ -* GreaseMonkey plugin for QupZilla +* GreaseMonkey plugin for Falkon * Copyright (C) 2012 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef GM_SETTINGSSCRIPTINFO_H #define GM_SETTINGSSCRIPTINFO_H #include namespace Ui { class GM_SettingsScriptInfo; } class GM_Script; class GM_SettingsScriptInfo : public QDialog { Q_OBJECT public: explicit GM_SettingsScriptInfo(GM_Script* script, QWidget* parent = 0); ~GM_SettingsScriptInfo(); private slots: void editInTextEditor(); void loadScript(); private: Ui::GM_SettingsScriptInfo* ui; GM_Script* m_script; }; #endif // GM_SETTINGSSCRIPTINFO_H diff --git a/src/plugins/ImageFinder/imagefinder.cpp b/src/plugins/ImageFinder/imagefinder.cpp index 035403ea..b818145a 100644 --- a/src/plugins/ImageFinder/imagefinder.cpp +++ b/src/plugins/ImageFinder/imagefinder.cpp @@ -1,84 +1,84 @@ /* ============================================================ -* ImageFinder plugin for QupZilla +* ImageFinder plugin for Falkon * Copyright (C) 2016 Vladislav Tronko * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "imagefinder.h" #include #include #include #include "qzcommon.h" ImageFinder::ImageFinder(const QString &settingsFile, QObject *parent) : QObject(parent) , m_settingsFile(settingsFile) , m_searchEngine(SearchEngine::Google) { QSettings settings(m_settingsFile, QSettings::IniFormat); settings.beginGroup(QSL("ImageFinder")); m_searchEngine = static_cast(settings.value(QSL("SearchEngine")).toInt()); settings.endGroup(); } ImageFinder::SearchEngine ImageFinder::searchEngine() const { return m_searchEngine; } void ImageFinder::setSearchEngine(ImageFinder::SearchEngine searchEngine) { m_searchEngine = searchEngine; QSettings settings(m_settingsFile, QSettings::IniFormat); settings.beginGroup(QSL("ImageFinder")); settings.setValue(QSL("SearchEngine"), m_searchEngine); settings.endGroup(); } QString ImageFinder::searchEngineName(SearchEngine engine) const { if (engine == SearchEngine::None) engine = m_searchEngine; QStringList searchEngines; searchEngines << QSL("Google") << QSL("Yandex") << QSL("TinEye"); return searchEngines.at(engine); } QUrl ImageFinder::getSearchQuery(const QUrl &imageUrl, SearchEngine engine) { if (engine == SearchEngine::None) engine = m_searchEngine; switch (engine) { case SearchEngine::Google: return QUrl(QSL("https://www.google.com/searchbyimage?site=search&image_url=%1").arg(imageUrl.toString())); break; case SearchEngine::Yandex: return QUrl(QSL("https://yandex.com/images/search?&img_url=%1&rpt=imageview").arg(imageUrl.toString())); break; case SearchEngine::TinEye: return QUrl(QSL("http://www.tineye.com/search?url=%1").arg(imageUrl.toString())); break; default: return QUrl(); } } diff --git a/src/plugins/ImageFinder/imagefinder.h b/src/plugins/ImageFinder/imagefinder.h index cabb4a29..656b50f4 100644 --- a/src/plugins/ImageFinder/imagefinder.h +++ b/src/plugins/ImageFinder/imagefinder.h @@ -1,50 +1,50 @@ /* ============================================================ -* ImageFinder plugin for QupZilla +* ImageFinder plugin for Falkon * Copyright (C) 2016 Vladislav Tronko * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef IMAGEFINDER_H #define IMAGEFINDER_H #include class WebView; class ImageFinder : public QObject { Q_OBJECT public: enum SearchEngine { None = -1, Google = 0, Yandex, TinEye }; explicit ImageFinder(const QString &settingsFile, QObject *parent = Q_NULLPTR); SearchEngine searchEngine() const; void setSearchEngine(SearchEngine searchEngine); QString searchEngineName(SearchEngine engine = SearchEngine::None) const; QUrl getSearchQuery(const QUrl &imageUrl, SearchEngine engine = SearchEngine::None); private: QString m_settingsFile; SearchEngine m_searchEngine; }; #endif // IMAGEFINDER_H diff --git a/src/plugins/ImageFinder/imagefinderplugin.cpp b/src/plugins/ImageFinder/imagefinderplugin.cpp index bb592bba..d4e4e7d1 100644 --- a/src/plugins/ImageFinder/imagefinderplugin.cpp +++ b/src/plugins/ImageFinder/imagefinderplugin.cpp @@ -1,115 +1,115 @@ /* ============================================================ * ImageFinder plugin for QupZilla * Copyright (C) 2016 Vladislav Tronko * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "imagefinderplugin.h" #include "imagefindersettings.h" #include "imagefinder.h" #include "webview.h" #include "webhittestresult.h" #include "pluginproxy.h" #include "mainapplication.h" #include "enhancedmenu.h" #include #include ImageFinderPlugin::ImageFinderPlugin() : QObject() , m_finder(Q_NULLPTR) { } PluginSpec ImageFinderPlugin::pluginSpec() { PluginSpec spec; spec.name = "ImageFinder"; spec.info = "Image Finder Plugin"; spec.description = "Provides context menu with reverse image search engine support"; spec.version = "0.2.0"; spec.author = "Vladislav Tronko "; spec.icon = QPixmap(":/imgfinder/data/icon.png"); spec.hasSettings = true; return spec; } void ImageFinderPlugin::init(InitState state, const QString &settingsPath) { m_finder = new ImageFinder(settingsPath + QL1S("/extensions.ini"), this); Q_UNUSED(state); } void ImageFinderPlugin::unload() { } bool ImageFinderPlugin::testPlugin() { // Require the version that the plugin was built with - return (Qz::VERSION == QLatin1String(QUPZILLA_VERSION)); + return (Qz::VERSION == QLatin1String(FALKON_VERSION)); } QTranslator *ImageFinderPlugin::getTranslator(const QString &locale) { QTranslator *translator = new QTranslator(this); translator->load(locale, QSL(":/imgfinder/locale/")); return translator; } void ImageFinderPlugin::showSettings(QWidget *parent) { if (!m_settings) { m_settings = new ImageFinderSettings(m_finder, parent); } m_settings.data()->show(); m_settings.data()->raise(); } void ImageFinderPlugin::populateWebViewMenu(QMenu *menu, WebView *view, const WebHitTestResult &r) { // Don't let local files fool you if (r.imageUrl().scheme() != QL1S("http") && r.imageUrl().scheme() != QL1S("https")) return; if (!r.imageUrl().isEmpty()) { QString engineName = m_finder->searchEngineName(); Action* action = new Action(tr("Search image in ") + engineName); action->setIcon(QIcon(QSL(":/imgfinder/data/%1.png").arg(engineName.toLower()))); action->setData(m_finder->getSearchQuery(r.imageUrl())); connect(action, SIGNAL(triggered()), view, SLOT(openUrlInSelectedTab())); connect(action, SIGNAL(ctrlTriggered()), view, SLOT(openUrlInBackgroundTab())); menu->addAction(action); Menu* swMenu = new Menu(tr("Search image with..."), menu); swMenu->setCloseOnMiddleClick(true); for (int i = 0; i < 3; ++i) { ImageFinder::SearchEngine e = static_cast(i); QString engineName = m_finder->searchEngineName(e); Action* act = new Action(engineName); act->setIcon(QIcon(QSL(":/imgfinder/data/%1.png").arg(engineName.toLower()))); act->setData(m_finder->getSearchQuery(r.imageUrl(), e)); connect(act, SIGNAL(triggered()), view, SLOT(openUrlInSelectedTab())); connect(act, SIGNAL(ctrlTriggered()), view, SLOT(openUrlInBackgroundTab())); swMenu->addAction(act); } menu->addMenu(swMenu); } } diff --git a/src/plugins/ImageFinder/imagefinderplugin.h b/src/plugins/ImageFinder/imagefinderplugin.h index cd07d868..08a84fe7 100644 --- a/src/plugins/ImageFinder/imagefinderplugin.h +++ b/src/plugins/ImageFinder/imagefinderplugin.h @@ -1,51 +1,51 @@ /* ============================================================ * ImageFinder plugin for QupZilla * Copyright (C) 2016 Vladislav Tronko * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef IMAGEFINDERPLUGIN_H #define IMAGEFINDERPLUGIN_H #include "plugininterface.h" class ImageFinder; class ImageFinderSettings; class ImageFinderPlugin : public QObject, public PluginInterface { Q_OBJECT Q_INTERFACES(PluginInterface) - Q_PLUGIN_METADATA(IID "QupZilla.Browser.plugin.ImageFinderPlugin") + Q_PLUGIN_METADATA(IID "Falkon.Browser.plugin.ImageFinderPlugin") public: explicit ImageFinderPlugin(); PluginSpec pluginSpec(); void init(InitState state, const QString &settingsPath); void unload(); bool testPlugin(); QTranslator *getTranslator(const QString &locale); void showSettings(QWidget *parent = Q_NULLPTR); void populateWebViewMenu(QMenu *menu, WebView *view, const WebHitTestResult &r); private: ImageFinder *m_finder; QPointer m_settings; }; #endif // IMAGEFINDERPLUGIN_H diff --git a/src/plugins/ImageFinder/imagefindersettings.cpp b/src/plugins/ImageFinder/imagefindersettings.cpp index 02a0b6c2..fdaad2b2 100644 --- a/src/plugins/ImageFinder/imagefindersettings.cpp +++ b/src/plugins/ImageFinder/imagefindersettings.cpp @@ -1,47 +1,47 @@ /* ============================================================ -* ImageFinder plugin for QupZilla +* ImageFinder plugin for Falkon * Copyright (C) 2016 Vladislav Tronko * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "imagefindersettings.h" #include "ui_imagefindersettings.h" #include "imagefinder.h" ImageFinderSettings::ImageFinderSettings(ImageFinder* finder, QWidget* parent) : QDialog(parent) , ui(new Ui::ImageFinderSettings) , m_finder(finder) { setAttribute(Qt::WA_DeleteOnClose); ui->setupUi(this); connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &ImageFinderSettings::accepted); connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &ImageFinderSettings::close); ui->cboxEngines->setCurrentIndex(m_finder->searchEngine()); } ImageFinderSettings::~ImageFinderSettings() { delete ui; } void ImageFinderSettings::accepted() { int index = ui->cboxEngines->currentIndex(); ImageFinder::SearchEngine engine = static_cast(index); m_finder->setSearchEngine(engine); close(); } diff --git a/src/plugins/ImageFinder/imagefindersettings.h b/src/plugins/ImageFinder/imagefindersettings.h index 583d0601..7b8b3ab9 100644 --- a/src/plugins/ImageFinder/imagefindersettings.h +++ b/src/plugins/ImageFinder/imagefindersettings.h @@ -1,47 +1,47 @@ /* ============================================================ -* ImageFinder plugin for QupZilla +* ImageFinder plugin for Falkon * Copyright (C) 2016 Vladislav Tronko * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef IMAGEFINDERSETTINGS_H #define IMAGEFINDERSETTINGS_H #include namespace Ui { class ImageFinderSettings; } class ImageFinder; class ImageFinderSettings : public QDialog { Q_OBJECT public: explicit ImageFinderSettings(ImageFinder* finder, QWidget* parent = Q_NULLPTR); ~ImageFinderSettings(); private slots: void accepted(); private: Ui::ImageFinderSettings* ui; ImageFinder* m_finder; }; #endif // IMAGEFINDERSETTINGS_H diff --git a/src/plugins/KWalletPasswords/kwalletpasswordbackend.cpp b/src/plugins/KWalletPasswords/kwalletpasswordbackend.cpp index 4b0b532c..9aa22c32 100644 --- a/src/plugins/KWalletPasswords/kwalletpasswordbackend.cpp +++ b/src/plugins/KWalletPasswords/kwalletpasswordbackend.cpp @@ -1,193 +1,193 @@ /* ============================================================ * KWalletPasswords - KWallet support plugin for QupZilla * Copyright (C) 2013-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "kwalletpasswordbackend.h" #include "kwalletplugin.h" #include #if QT_VERSION >= 0x050000 #include #else #include #endif static PasswordEntry decodeEntry(const QByteArray &data) { QDataStream stream(data); PasswordEntry entry; stream >> entry; return entry; } static QByteArray encodeEntry(const PasswordEntry &entry) { QByteArray data; QDataStream stream(&data, QIODevice::WriteOnly); stream << entry; return data; } KWalletPasswordBackend::KWalletPasswordBackend() : PasswordBackend() , m_wallet(0) { } QString KWalletPasswordBackend::name() const { return KWalletPlugin::tr("KWallet"); } QVector KWalletPasswordBackend::getEntries(const QUrl &url) { initialize(); const QString host = PasswordManager::createHost(url); QVector list; foreach (const PasswordEntry &entry, m_allEntries) { if (entry.host == host) { list.append(entry); } } // Sort to prefer last updated entries qSort(list.begin(), list.end()); return list; } QVector KWalletPasswordBackend::getAllEntries() { initialize(); return m_allEntries; } void KWalletPasswordBackend::addEntry(const PasswordEntry &entry) { initialize(); PasswordEntry stored = entry; stored.id = QString("%1/%2").arg(entry.host, entry.username); stored.updated = QDateTime::currentDateTime().toTime_t(); m_wallet->writeEntry(stored.id.toString(), encodeEntry(stored)); m_allEntries.append(stored); } bool KWalletPasswordBackend::updateEntry(const PasswordEntry &entry) { initialize(); m_wallet->removeEntry(entry.id.toString()); m_wallet->writeEntry(entry.id.toString(), encodeEntry(entry)); int index = m_allEntries.indexOf(entry); if (index > -1) { m_allEntries[index] = entry; } return true; } void KWalletPasswordBackend::updateLastUsed(PasswordEntry &entry) { initialize(); m_wallet->removeEntry(entry.id.toString()); entry.updated = QDateTime::currentDateTime().toTime_t(); m_wallet->writeEntry(entry.id.toString(), encodeEntry(entry)); int index = m_allEntries.indexOf(entry); if (index > -1) { m_allEntries[index] = entry; } } void KWalletPasswordBackend::removeEntry(const PasswordEntry &entry) { initialize(); m_wallet->removeEntry(entry.id.toString()); int index = m_allEntries.indexOf(entry); if (index > -1) { m_allEntries.remove(index); } } void KWalletPasswordBackend::removeAll() { initialize(); m_allEntries.clear(); - m_wallet->removeFolder("QupZilla"); - m_wallet->createFolder("QupZilla"); + m_wallet->removeFolder("Falkon"); + m_wallet->createFolder("Falkon"); } void KWalletPasswordBackend::initialize() { if (m_wallet) { return; } m_wallet = KWallet::Wallet::openWallet(KWallet::Wallet::NetworkWallet(), 0); if (!m_wallet) { qWarning() << "KWalletPasswordBackend::initialize Cannot open wallet!"; return; } - if (!m_wallet->hasFolder("QupZilla") && !m_wallet->createFolder("QupZilla")) { - qWarning() << "KWalletPasswordBackend::initialize Cannot create folder \"QupZilla\"!"; + if (!m_wallet->hasFolder("Falkon") && !m_wallet->createFolder("Falkon")) { + qWarning() << "KWalletPasswordBackend::initialize Cannot create folder \"Falkon\"!"; return; } - if (!m_wallet->setFolder("QupZilla")) { - qWarning() << "KWalletPasswordBackend::initialize Cannot set folder \"QupZilla\"!"; + if (!m_wallet->setFolder("Falkon")) { + qWarning() << "KWalletPasswordBackend::initialize Cannot set folder \"Falkon\"!"; return; } QMap entries; if (m_wallet->readEntryList("*", entries) != 0) { qWarning() << "KWalletPasswordBackend::initialize Cannot read entries!"; return; } QMap::const_iterator i = entries.constBegin(); while (i != entries.constEnd()) { PasswordEntry entry = decodeEntry(i.value()); if (entry.isValid()) { m_allEntries.append(entry); } ++i; } } KWalletPasswordBackend::~KWalletPasswordBackend() { delete m_wallet; } diff --git a/src/plugins/KWalletPasswords/kwalletplugin.cpp b/src/plugins/KWalletPasswords/kwalletplugin.cpp index ec2a0ae8..6e64fdb9 100644 --- a/src/plugins/KWalletPasswords/kwalletplugin.cpp +++ b/src/plugins/KWalletPasswords/kwalletplugin.cpp @@ -1,75 +1,75 @@ /* ============================================================ * KWalletPasswords - KWallet support plugin for QupZilla * Copyright (C) 2013-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "kwalletplugin.h" #include "kwalletpasswordbackend.h" #include "pluginproxy.h" #include "browserwindow.h" #include KWalletPlugin::KWalletPlugin() : QObject() , m_backend(0) { } PluginSpec KWalletPlugin::pluginSpec() { PluginSpec spec; spec.name = "KWallet Passwords"; spec.info = "KWallet password backend"; spec.description = "Provides support for storing passwords in KWallet"; spec.version = "0.1.2"; spec.author = "David Rosca "; spec.icon = QPixmap(":kwp/data/icon.png"); spec.hasSettings = false; return spec; } void KWalletPlugin::init(InitState state, const QString &settingsPath) { Q_UNUSED(state); Q_UNUSED(settingsPath); m_backend = new KWalletPasswordBackend; QZ_REGISTER_PASSWORD_BACKEND("KWallet", m_backend); } void KWalletPlugin::unload() { QZ_UNREGISTER_PASSWORD_BACKEND(m_backend); delete m_backend; } bool KWalletPlugin::testPlugin() { // Require the version that the plugin was built with - return (Qz::VERSION == QLatin1String(QUPZILLA_VERSION)); + return (Qz::VERSION == QLatin1String(FALKON_VERSION)); } QTranslator* KWalletPlugin::getTranslator(const QString &locale) { QTranslator* translator = new QTranslator(this); translator->load(locale, ":/kwp/locale/"); return translator; } #if QT_VERSION < 0x050000 Q_EXPORT_PLUGIN2(KWalletPasswords, KWalletPlugin) #endif diff --git a/src/plugins/KWalletPasswords/kwalletplugin.h b/src/plugins/KWalletPasswords/kwalletplugin.h index 70380f74..3365e266 100644 --- a/src/plugins/KWalletPasswords/kwalletplugin.h +++ b/src/plugins/KWalletPasswords/kwalletplugin.h @@ -1,49 +1,49 @@ /* ============================================================ * KWalletPasswords - KWallet support plugin for QupZilla * Copyright (C) 2013-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef KWALLETPLUGIN_H #define KWALLETPLUGIN_H #include "plugininterface.h" class KWalletPasswordBackend; class KWalletPlugin : public QObject, public PluginInterface { Q_OBJECT Q_INTERFACES(PluginInterface) #if QT_VERSION >= 0x050000 - Q_PLUGIN_METADATA(IID "QupZilla.Browser.plugin.KWalletPasswords") + Q_PLUGIN_METADATA(IID "Falkon.Browser.plugin.KWalletPasswords") #endif public: explicit KWalletPlugin(); PluginSpec pluginSpec(); void init(InitState state, const QString &settingsPath); void unload(); bool testPlugin(); QTranslator* getTranslator(const QString &locale); private: KWalletPasswordBackend* m_backend; }; #endif // KWALLETPLUGIN_H diff --git a/src/plugins/MouseGestures/mousegestures.cpp b/src/plugins/MouseGestures/mousegestures.cpp index f416181a..01142c7a 100644 --- a/src/plugins/MouseGestures/mousegestures.cpp +++ b/src/plugins/MouseGestures/mousegestures.cpp @@ -1,396 +1,396 @@ /* ============================================================ -* Mouse Gestures plugin for QupZilla +* Mouse Gestures plugin for Falkon * Copyright (C) 2013-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "mousegestures.h" #include "webpage.h" #include "tabbedwebview.h" #include "tabwidget.h" #include "mainapplication.h" #include "browserwindow.h" #include "locationbar.h" #include "mousegesturessettingsdialog.h" #include "QjtMouseGestureFilter.h" #include "QjtMouseGesture.h" #include #include #include MouseGestures::MouseGestures(const QString &settingsPath, QObject* parent) : QObject(parent) , m_filter(0) , m_settingsFile(settingsPath + QL1S("/extensions.ini")) , m_button(Qt::MiddleButton) , m_enableRockerNavigation(false) , m_blockNextRightMouseRelease(false) , m_blockNextLeftMouseRelease(false) { loadSettings(); } void MouseGestures::initFilter() { if (m_filter) { m_filter->clearGestures(true); delete m_filter; } m_filter = new QjtMouseGestureFilter(false, m_button, 20); QjtMouseGesture* upGesture = new QjtMouseGesture(DirectionList() << Up, m_filter); connect(upGesture, SIGNAL(gestured()), this, SLOT(upGestured())); QjtMouseGesture* downGesture = new QjtMouseGesture(DirectionList() << Down, m_filter); connect(downGesture, SIGNAL(gestured()), this, SLOT(downGestured())); QjtMouseGesture* leftGesture = new QjtMouseGesture(DirectionList() << Left, m_filter); connect(leftGesture, SIGNAL(gestured()), this, SLOT(leftGestured())); QjtMouseGesture* rightGesture = new QjtMouseGesture(DirectionList() << Right, m_filter); connect(rightGesture, SIGNAL(gestured()), this, SLOT(rightGestured())); QjtMouseGesture* downRightGesture = new QjtMouseGesture(DirectionList() << Down << Right, m_filter); connect(downRightGesture, SIGNAL(gestured()), this, SLOT(downRightGestured())); QjtMouseGesture* downLeftGesture = new QjtMouseGesture(DirectionList() << Down << Left, m_filter); connect(downLeftGesture, SIGNAL(gestured()), this, SLOT(downLeftGestured())); QjtMouseGesture* downUpGesture = new QjtMouseGesture(DirectionList() << Down << Up, m_filter); connect(downUpGesture, SIGNAL(gestured()), this, SLOT(downUpGestured())); QjtMouseGesture* upDownGesture = new QjtMouseGesture(DirectionList() << Up << Down, m_filter); connect(upDownGesture, SIGNAL(gestured()), this, SLOT(upDownGestured())); QjtMouseGesture* upLeftGesture = new QjtMouseGesture(DirectionList() << Up << Left, m_filter); connect(upLeftGesture, SIGNAL(gestured()), this, SLOT(upLeftGestured())); QjtMouseGesture* upRightGesture = new QjtMouseGesture(DirectionList() << Up << Right, m_filter); connect(upRightGesture, SIGNAL(gestured()), this, SLOT(upRightGestured())); m_filter->addGesture(upGesture); m_filter->addGesture(downGesture); m_filter->addGesture(leftGesture); m_filter->addGesture(rightGesture); m_filter->addGesture(downRightGesture); m_filter->addGesture(downLeftGesture); m_filter->addGesture(downUpGesture); m_filter->addGesture(upDownGesture); m_filter->addGesture(upLeftGesture); m_filter->addGesture(upRightGesture); } bool MouseGestures::mousePress(QObject* obj, QMouseEvent* event) { m_view = qobject_cast(obj); if (m_enableRockerNavigation && event->buttons() == (Qt::RightButton | Qt::LeftButton)) { bool accepted = false; if (event->button() == Qt::LeftButton && m_view.data()->history()->canGoBack()) { m_view.data()->back(); accepted = true; } else if (event->button() == Qt::RightButton && m_view.data()->history()->canGoForward()) { m_view.data()->forward(); accepted = true; } if (accepted) { m_blockNextLeftMouseRelease = true; m_blockNextRightMouseRelease = true; return true; } } m_filter->mouseButtonPressEvent(event); return false; } bool MouseGestures::mouseRelease(QObject* obj, QMouseEvent* event) { Q_UNUSED(obj) if (m_blockNextRightMouseRelease && event->button() == Qt::RightButton) { m_blockNextRightMouseRelease = false; return true; } if (m_blockNextLeftMouseRelease && event->button() == Qt::LeftButton) { m_blockNextLeftMouseRelease = false; return true; } return m_filter->mouseButtonReleaseEvent(event); } bool MouseGestures::mouseMove(QObject* obj, QMouseEvent* event) { Q_UNUSED(obj) m_filter->mouseMoveEvent(event); return false; } void MouseGestures::showSettings(QWidget* parent) { if (!m_settings) { m_settings = new MouseGesturesSettingsDialog(this, parent); } m_settings.data()->show(); m_settings.data()->raise(); } void MouseGestures::unloadPlugin() { delete m_settings.data(); } void MouseGestures::upGestured() { if (!m_view) { return; } m_view.data()->stop(); } void MouseGestures::downGestured() { TabbedWebView* view = qobject_cast(m_view.data()); if (!view) return; BrowserWindow* window = view->browserWindow(); if (!window) return; TabWidget* tabWidget = window->tabWidget(); tabWidget->addView(QUrl(), Qz::NT_SelectedNewEmptyTab, true); tabWidget->setCurrentTabFresh(true); if (window->isFullScreen()) window->showNavigationWithFullScreen(); } void MouseGestures::leftGestured() { if (!m_view) { return; } if (QApplication::isRightToLeft()) { m_view.data()->forward(); } else { m_view.data()->back(); } } void MouseGestures::rightGestured() { if (!m_view) { return; } if (QApplication::isRightToLeft()) { m_view.data()->back(); } else { m_view.data()->forward(); } } void MouseGestures::downRightGestured() { TabbedWebView *view = qobject_cast(m_view.data()); if (!view) return; BrowserWindow *window = view->browserWindow(); if (!window) return; TabWidget *tabWidget = window->tabWidget(); if (!m_view) { return; } tabWidget->requestCloseTab(view->tabIndex()); } void MouseGestures::downLeftGestured() { if (!m_view) { return; } m_view.data()->load(mApp->getWindow()->homepageUrl()); } void MouseGestures::downUpGestured() { TabbedWebView* view = qobject_cast(m_view.data()); if (!view) return; BrowserWindow* window = view->browserWindow(); if (!window) return; TabWidget* tabWidget = window->tabWidget(); tabWidget->duplicateTab(tabWidget->currentIndex()); } void MouseGestures::upDownGestured() { if (!m_view) { return; } m_view.data()->reload(); } void MouseGestures::upLeftGestured() { TabbedWebView* view = qobject_cast(m_view.data()); if (!view) return; BrowserWindow* window = view->browserWindow(); if (!window) return; if (QApplication::isRightToLeft()) window->tabWidget()->nextTab(); else window->tabWidget()->previousTab(); } void MouseGestures::upRightGestured() { TabbedWebView* view = qobject_cast(m_view.data()); if (!view) return; BrowserWindow* window = view->browserWindow(); if (!window) return; if (QApplication::isRightToLeft()) window->tabWidget()->previousTab(); else window->tabWidget()->nextTab(); } void MouseGestures::init() { initFilter(); // We need to override right mouse button events m_oldWebViewForceContextMenuOnRelease = WebView::forceContextMenuOnMouseRelease(); WebView::setForceContextMenuOnMouseRelease(m_button == Qt::RightButton || m_enableRockerNavigation); } void MouseGestures::setGestureButton(Qt::MouseButton button) { m_button = button; init(); } void MouseGestures::setGestureButtonByIndex(int index) { switch (index) { case 0: m_button = Qt::MiddleButton; break; case 1: m_button = Qt::RightButton; break; default: m_button = Qt::NoButton; } setGestureButton(m_button); } Qt::MouseButton MouseGestures::gestureButton() const { return m_button; } int MouseGestures::buttonToIndex() const { switch (m_button) { case Qt::MiddleButton: return 0; case Qt::RightButton: return 1; default: return 2; } } bool MouseGestures::rockerNavigationEnabled() const { return m_enableRockerNavigation; } void MouseGestures::setRockerNavigationEnabled(bool enable) { m_enableRockerNavigation = enable; init(); } void MouseGestures::loadSettings() { QSettings settings(m_settingsFile, QSettings::IniFormat); settings.beginGroup("MouseGestures"); setGestureButtonByIndex(settings.value("Button", 0).toInt()); m_enableRockerNavigation = settings.value("RockerNavigation", true).toBool(); settings.endGroup(); init(); } void MouseGestures::saveSettings() { QSettings settings(m_settingsFile, QSettings::IniFormat); settings.beginGroup("MouseGestures"); settings.setValue("Button", buttonToIndex()); settings.setValue("RockerNavigation", m_enableRockerNavigation); settings.endGroup(); } MouseGestures::~MouseGestures() { m_filter->clearGestures(true); delete m_filter; // Restore original value WebView::setForceContextMenuOnMouseRelease(m_oldWebViewForceContextMenuOnRelease); } diff --git a/src/plugins/MouseGestures/mousegestures.h b/src/plugins/MouseGestures/mousegestures.h index 99d23133..ea1b3c08 100644 --- a/src/plugins/MouseGestures/mousegestures.h +++ b/src/plugins/MouseGestures/mousegestures.h @@ -1,87 +1,87 @@ /* ============================================================ -* Mouse Gestures plugin for QupZilla +* Mouse Gestures plugin for Falkon * Copyright (C) 2012-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef MOUSEGESTURES_H #define MOUSEGESTURES_H #include #include class QMouseEvent; class WebView; class QjtMouseGestureFilter; class MouseGesturesSettingsDialog; class MouseGestures : public QObject { Q_OBJECT public: explicit MouseGestures(const QString &settingsPath, QObject* parent = 0); ~MouseGestures(); bool mousePress(QObject* obj, QMouseEvent* event); bool mouseRelease(QObject* obj, QMouseEvent* event); bool mouseMove(QObject* obj, QMouseEvent* event); void showSettings(QWidget* parent); void unloadPlugin(); Qt::MouseButton gestureButton() const; void setGestureButton(Qt::MouseButton button); void setGestureButtonByIndex(int index); int buttonToIndex() const; bool rockerNavigationEnabled() const; void setRockerNavigationEnabled(bool enable); void loadSettings(); void saveSettings(); private slots: void upGestured(); void downGestured(); void leftGestured(); void rightGestured(); void downRightGestured(); void downLeftGestured(); void downUpGestured(); void upDownGestured(); void upLeftGestured(); void upRightGestured(); private: void init(); void initFilter(); QjtMouseGestureFilter* m_filter; QPointer m_settings; QPointer m_view; QString m_settingsFile; Qt::MouseButton m_button; bool m_enableRockerNavigation; bool m_blockNextRightMouseRelease; bool m_blockNextLeftMouseRelease; bool m_oldWebViewForceContextMenuOnRelease = false; }; #endif // MOUSEGESTURES_H diff --git a/src/plugins/MouseGestures/mousegesturesplugin.cpp b/src/plugins/MouseGestures/mousegesturesplugin.cpp index b64c0820..a9a49af0 100644 --- a/src/plugins/MouseGestures/mousegesturesplugin.cpp +++ b/src/plugins/MouseGestures/mousegesturesplugin.cpp @@ -1,106 +1,106 @@ /* ============================================================ -* Mouse Gestures plugin for QupZilla +* Mouse Gestures plugin for Falkon * Copyright (C) 2012-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "mousegesturesplugin.h" #include "pluginproxy.h" #include "mousegestures.h" #include "mainapplication.h" #include "browserwindow.h" #include MouseGesturesPlugin::MouseGesturesPlugin() : QObject() , m_gestures(0) { } PluginSpec MouseGesturesPlugin::pluginSpec() { PluginSpec spec; spec.name = "Mouse Gestures"; - spec.info = "Mouse gestures for QupZilla"; + spec.info = "Mouse gestures for Falkon"; spec.description = "Provides support for navigating in webpages by mouse gestures"; spec.version = "0.5.0"; spec.author = "David Rosca "; spec.icon = QPixmap(":/mousegestures/data/icon.png"); spec.hasSettings = true; return spec; } void MouseGesturesPlugin::init(InitState state, const QString &settingsPath) { Q_UNUSED(state) m_gestures = new MouseGestures(settingsPath, this); QZ_REGISTER_EVENT_HANDLER(PluginProxy::MousePressHandler); QZ_REGISTER_EVENT_HANDLER(PluginProxy::MouseReleaseHandler); QZ_REGISTER_EVENT_HANDLER(PluginProxy::MouseMoveHandler); } void MouseGesturesPlugin::unload() { m_gestures->unloadPlugin(); m_gestures->deleteLater(); } bool MouseGesturesPlugin::testPlugin() { // Require the version that the plugin was built with - return (Qz::VERSION == QLatin1String(QUPZILLA_VERSION)); + return (Qz::VERSION == QLatin1String(FALKON_VERSION)); } QTranslator* MouseGesturesPlugin::getTranslator(const QString &locale) { QTranslator* translator = new QTranslator(this); translator->load(locale, ":/mousegestures/locale/"); return translator; } void MouseGesturesPlugin::showSettings(QWidget* parent) { m_gestures->showSettings(parent); } bool MouseGesturesPlugin::mousePress(const Qz::ObjectName &type, QObject* obj, QMouseEvent* event) { if (type == Qz::ON_WebView) { m_gestures->mousePress(obj, event); } return false; } bool MouseGesturesPlugin::mouseRelease(const Qz::ObjectName &type, QObject* obj, QMouseEvent* event) { if (type == Qz::ON_WebView) { return m_gestures->mouseRelease(obj, event); } return false; } bool MouseGesturesPlugin::mouseMove(const Qz::ObjectName &type, QObject* obj, QMouseEvent* event) { if (type == Qz::ON_WebView) { m_gestures->mouseMove(obj, event); } return false; } diff --git a/src/plugins/MouseGestures/mousegesturesplugin.h b/src/plugins/MouseGestures/mousegesturesplugin.h index dfe8d941..fa29d92a 100644 --- a/src/plugins/MouseGestures/mousegesturesplugin.h +++ b/src/plugins/MouseGestures/mousegesturesplugin.h @@ -1,50 +1,50 @@ /* ============================================================ -* Mouse Gestures plugin for QupZilla +* Mouse Gestures plugin for Falkon * Copyright (C) 2012-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef MOUSEGESTURESPLUGIN_H #define MOUSEGESTURESPLUGIN_H #include "plugininterface.h" class MouseGestures; class MouseGesturesPlugin : public QObject, public PluginInterface { Q_OBJECT Q_INTERFACES(PluginInterface) - Q_PLUGIN_METADATA(IID "QupZilla.Browser.plugin.MouseGestures") + Q_PLUGIN_METADATA(IID "Falkon.Browser.plugin.MouseGestures") public: MouseGesturesPlugin(); PluginSpec pluginSpec(); void init(InitState state, const QString &settingsPath); void unload(); bool testPlugin(); QTranslator* getTranslator(const QString &locale); void showSettings(QWidget* parent = 0); bool mousePress(const Qz::ObjectName &type, QObject* obj, QMouseEvent* event); bool mouseRelease(const Qz::ObjectName &type, QObject* obj, QMouseEvent* event); bool mouseMove(const Qz::ObjectName &type, QObject* obj, QMouseEvent* event); private: MouseGestures* m_gestures; }; #endif // MOUSEGESTURESPLUGIN_H diff --git a/src/plugins/MouseGestures/mousegesturessettingsdialog.cpp b/src/plugins/MouseGestures/mousegesturessettingsdialog.cpp index f1868b46..ced70754 100644 --- a/src/plugins/MouseGestures/mousegesturessettingsdialog.cpp +++ b/src/plugins/MouseGestures/mousegesturessettingsdialog.cpp @@ -1,70 +1,70 @@ /* ============================================================ -* Mouse Gestures plugin for QupZilla +* Mouse Gestures plugin for Falkon * Copyright (C) 2012-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "mousegesturessettingsdialog.h" #include "ui_mousegesturessettingsdialog.h" #include "licenseviewer.h" #include "mousegestures.h" #include MouseGesturesSettingsDialog::MouseGesturesSettingsDialog(MouseGestures* gestures, QWidget* parent) : QDialog(parent) , ui(new Ui::MouseGesturesSettingsDialog) , m_gestures(gestures) { setAttribute(Qt::WA_DeleteOnClose); ui->setupUi(this); if (QApplication::isRightToLeft()) { ui->label_5->setPixmap(QPixmap(":/mousegestures/data/right.gif")); ui->label_6->setPixmap(QPixmap(":/mousegestures/data/left.gif")); ui->label_18->setPixmap(QPixmap(":/mousegestures/data/up-right.gif")); ui->label_20->setPixmap(QPixmap(":/mousegestures/data/up-left.gif")); } m_gestures->loadSettings(); ui->mouseButtonComboBox->setCurrentIndex(m_gestures->buttonToIndex()); ui->enableRockerNavigation->setChecked(m_gestures->rockerNavigationEnabled()); setAttribute(Qt::WA_DeleteOnClose); connect(ui->buttonBox, SIGNAL(accepted()), this, SLOT(accepted())); connect(ui->buttonBox, SIGNAL(rejected()), this, SLOT(close())); connect(ui->licenseButton, SIGNAL(clicked()), this, SLOT(showLicense())); } MouseGesturesSettingsDialog::~MouseGesturesSettingsDialog() { delete ui; } void MouseGesturesSettingsDialog::showLicense() { LicenseViewer* v = new LicenseViewer(this); v->setLicenseFile(":mousegestures/data/copyright"); v->show(); } void MouseGesturesSettingsDialog::accepted() { m_gestures->setGestureButtonByIndex(ui->mouseButtonComboBox->currentIndex()); m_gestures->setRockerNavigationEnabled(ui->enableRockerNavigation->isChecked()); m_gestures->saveSettings(); close(); } diff --git a/src/plugins/MouseGestures/mousegesturessettingsdialog.h b/src/plugins/MouseGestures/mousegesturessettingsdialog.h index ed23e04d..96b01d40 100644 --- a/src/plugins/MouseGestures/mousegesturessettingsdialog.h +++ b/src/plugins/MouseGestures/mousegesturessettingsdialog.h @@ -1,48 +1,48 @@ /* ============================================================ -* Mouse Gestures plugin for QupZilla +* Mouse Gestures plugin for Falkon * Copyright (C) 2012-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef MOUSEGESTURESSETTINGSDIALOG_H #define MOUSEGESTURESSETTINGSDIALOG_H #include #include namespace Ui { class MouseGesturesSettingsDialog; } class MouseGestures; class MouseGesturesSettingsDialog : public QDialog { Q_OBJECT public: explicit MouseGesturesSettingsDialog(MouseGestures* gestures, QWidget* parent = 0); ~MouseGesturesSettingsDialog(); private slots: void showLicense(); void accepted(); private: Ui::MouseGesturesSettingsDialog* ui; MouseGestures* m_gestures; }; #endif // MOUSEGESTURESSETTINGSDIALOG_H diff --git a/src/plugins/PIM/PIM_handler.cpp b/src/plugins/PIM/PIM_handler.cpp index 6acc65fb..27e38027 100644 --- a/src/plugins/PIM/PIM_handler.cpp +++ b/src/plugins/PIM/PIM_handler.cpp @@ -1,256 +1,256 @@ /* ============================================================ -* Personal Information Manager plugin for QupZilla +* Personal Information Manager plugin for Falkon * Copyright (C) 2012-2016 David Rosca * Copyright (C) 2012-2014 Mladen Pejaković * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "PIM_handler.h" #include "PIM_settings.h" #include "webview.h" #include "webpage.h" #include "webhittestresult.h" #include #include #include #include #include PIM_Handler::PIM_Handler(const QString &sPath, QObject* parent) : QObject(parent) , m_settingsFile(sPath + QL1S("/extensions.ini")) , m_loaded(false) { } void PIM_Handler::loadSettings() { QSettings settings(m_settingsFile, QSettings::IniFormat); settings.beginGroup("PIM"); m_allInfo[PI_LastName] = settings.value("LastName", QString()).toString(); m_allInfo[PI_FirstName] = settings.value("FirstName", QString()).toString(); m_allInfo[PI_Email] = settings.value("Email", QString()).toString(); m_allInfo[PI_Mobile] = settings.value("Mobile", QString()).toString(); m_allInfo[PI_Phone] = settings.value("Phone", QString()).toString(); m_allInfo[PI_Address] = settings.value("Address", QString()).toString(); m_allInfo[PI_City] = settings.value("City", QString()).toString(); m_allInfo[PI_Zip] = settings.value("Zip", QString()).toString(); m_allInfo[PI_State] = settings.value("State", QString()).toString(); m_allInfo[PI_Country] = settings.value("Country", QString()).toString(); m_allInfo[PI_HomePage] = settings.value("HomePage", QString()).toString(); m_allInfo[PI_Special1] = settings.value("Special1", QString()).toString(); m_allInfo[PI_Special2] = settings.value("Special2", QString()).toString(); m_allInfo[PI_Special3] = settings.value("Special3", QString()).toString(); settings.endGroup(); m_translations[PI_LastName] = tr("Last Name"); m_translations[PI_FirstName] = tr("First Name"); m_translations[PI_Email] = tr("E-mail"); m_translations[PI_Mobile] = tr("Mobile"); m_translations[PI_Phone] = tr("Phone"); m_translations[PI_Address] = tr("Address"); m_translations[PI_City] = tr("City"); m_translations[PI_Zip] = tr("ZIP Code"); m_translations[PI_State] = tr("State/Region"); m_translations[PI_Country] = tr("Country"); m_translations[PI_HomePage] = tr("Home Page"); m_translations[PI_Special1] = tr("Custom 1"); m_translations[PI_Special2] = tr("Custom 2"); m_translations[PI_Special3] = tr("Custom 3"); m_infoMatches[PI_LastName] << "lastname" << "surname"; m_infoMatches[PI_FirstName] << "firstname" << "name"; m_infoMatches[PI_Email] << "email" << "e-mail" << "mail"; m_infoMatches[PI_Mobile] << "mobile" << "mobilephone"; m_infoMatches[PI_Phone] << "phone" << "telephone"; m_infoMatches[PI_Address] << "address"; m_infoMatches[PI_City] << "city"; m_infoMatches[PI_Zip] << "zip"; m_infoMatches[PI_State] << "state" << "region"; m_infoMatches[PI_Country] << "country"; m_infoMatches[PI_HomePage] << "homepage" << "www"; m_loaded = true; } void PIM_Handler::showSettings(QWidget* parent) { if (!m_settings) { m_settings = new PIM_Settings(m_settingsFile, parent); connect(m_settings.data(), SIGNAL(accepted()), this, SLOT(loadSettings())); } m_settings.data()->show(); m_settings.data()->raise(); } void PIM_Handler::populateWebViewMenu(QMenu* menu, WebView* view, const WebHitTestResult &hitTest) { m_view = view; m_clickedPos = hitTest.pos(); if (!hitTest.isContentEditable()) { return; } if (!m_loaded) { loadSettings(); } QMenu* pimMenu = new QMenu(tr("Insert Personal Information")); pimMenu->setIcon(QIcon(":/PIM/data/PIM.png")); if (!m_allInfo[PI_FirstName].isEmpty() && !m_allInfo[PI_LastName].isEmpty()) { const QString fullname = m_allInfo[PI_FirstName] + " " + m_allInfo[PI_LastName]; QAction* action = pimMenu->addAction(fullname, this, SLOT(pimInsert())); action->setData(fullname); } for (int i = 0; i < PI_Max; ++i) { const QString info = m_allInfo[PI_Type(i)]; if (info.isEmpty()) { continue; } QAction* action = pimMenu->addAction(info, this, SLOT(pimInsert())); action->setData(info); action->setStatusTip(m_translations[PI_Type(i)]); } pimMenu->addSeparator(); pimMenu->addAction(tr("Edit"), this, SLOT(showSettings())); menu->addMenu(pimMenu); menu->addSeparator(); } bool PIM_Handler::keyPress(WebView* view, QKeyEvent* event) { if (!view) { return false; } bool isEnter = event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter; bool isControlModifier = event->modifiers() & Qt::ControlModifier; if (!isEnter || !isControlModifier) { return false; } QString source = QL1S("var inputs = document.getElementsByTagName('input');" "var table = %1;" "for (var i = 0; i < inputs.length; ++i) {" " var input = inputs[i];" " if (input.type != 'text' || input.name == '')" " continue;" " for (var key in table) {" " if (!table.hasOwnProperty(key))" " continue;" " if (key == input.name || input.name.indexOf(key) != -1) {" " input.value = table[key];" " break;" " }" " }" "}"); view->page()->runJavaScript(source.arg(matchingJsTable()), WebPage::SafeJsWorld); return true; } void PIM_Handler::unloadPlugin() { delete m_settings.data(); } void PIM_Handler::webPageCreated(WebPage* page) { connect(page, SIGNAL(loadFinished(bool)), this, SLOT(pageLoadFinished())); } void PIM_Handler::pimInsert() { if (!m_view || m_clickedPos.isNull()) return; QAction* action = qobject_cast(sender()); if (!action) return; QString info = action->data().toString(); info.replace(QLatin1Char('"'), QLatin1String("\\\"")); QString source = QL1S("var e = document.elementFromPoint(%1, %2);" "if (e) {" " var v = e.value.substring(0, e.selectionStart);" " v += \"%3\" + e.value.substring(e.selectionEnd);" " e.value = v;" "}"); source = source.arg(m_clickedPos.x()).arg(m_clickedPos.y()).arg(info); m_view->page()->runJavaScript(source, WebPage::SafeJsWorld); } void PIM_Handler::pageLoadFinished() { WebPage* page = qobject_cast(sender()); if (!page) { return; } if (!m_loaded) { loadSettings(); } QString source = QL1S("var inputs = document.getElementsByTagName('input');" "var table = %1;" "for (var i = 0; i < inputs.length; ++i) {" " var input = inputs[i];" " if (input.type != 'text' || input.name == '')" " continue;" " for (var key in table) {" " if (!table.hasOwnProperty(key) || table[key] == '')" " continue;" " if (key == input.name || input.name.indexOf(key) != -1) {" " input.style['-webkit-appearance'] = 'none';" " input.style['-webkit-box-shadow'] = 'inset 0 0 2px 1px #EEE000';" " break;" " }" " }" "}"); page->runJavaScript(source.arg(matchingJsTable()), WebPage::SafeJsWorld); } QString PIM_Handler::matchingJsTable() const { QString values; QHashIterator i(m_infoMatches); while (i.hasNext()) { i.next(); foreach (const QString &value, i.value()) { QString key = m_allInfo.value(i.key()); key.replace(QL1C('"'), QL1S("\\\"")); values.append(QSL("\"%1\":\"%2\",").arg(value, key)); } } if (!values.isEmpty()) values = values.left(values.size() - 1); return QSL("{ %1 }").arg(values); } diff --git a/src/plugins/PIM/PIM_handler.h b/src/plugins/PIM/PIM_handler.h index c977ab1d..e8535700 100644 --- a/src/plugins/PIM/PIM_handler.h +++ b/src/plugins/PIM/PIM_handler.h @@ -1,91 +1,91 @@ /* ============================================================ -* Personal Information Manager plugin for QupZilla +* Personal Information Manager plugin for Falkon * Copyright (C) 2012-2014 David Rosca * Copyright (C) 2012-2014 Mladen Pejaković * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef PIM_HANDLER_H #define PIM_HANDLER_H #include #include #include #include #include class WebView; class WebPage; class WebHitTestResult; class PIM_Settings; class PIM_Handler : public QObject { Q_OBJECT public: explicit PIM_Handler(const QString &sPath, QObject* parent = 0); void populateWebViewMenu(QMenu* menu, WebView* view, const WebHitTestResult &hitTest); bool keyPress(WebView* view, QKeyEvent* event); void unloadPlugin(); signals: public slots: void webPageCreated(WebPage* page); void showSettings(QWidget* parent = 0); private slots: void loadSettings(); void pimInsert(); void pageLoadFinished(); private: enum PI_Type { PI_LastName = 0, PI_FirstName = 1, PI_Email = 2, PI_Mobile = 3, PI_Phone = 4, PI_Address = 5, PI_City = 6, PI_Zip = 7, PI_State = 8, PI_Country = 9, PI_HomePage = 10, PI_Special1 = 11, PI_Special2 = 12, PI_Special3 = 13, PI_Max = 14, PI_Invalid = 128 }; QString matchingJsTable() const; QHash m_allInfo; QHash m_infoMatches; QHash m_translations; QPointer m_settings; QPointer m_view; QPoint m_clickedPos; QString m_settingsFile; bool m_loaded; }; #endif // PIM_HANDLER_H diff --git a/src/plugins/PIM/PIM_plugin.cpp b/src/plugins/PIM/PIM_plugin.cpp index 0dad8b63..e3fb4638 100644 --- a/src/plugins/PIM/PIM_plugin.cpp +++ b/src/plugins/PIM/PIM_plugin.cpp @@ -1,97 +1,97 @@ /* ============================================================ -* Personal Information Manager plugin for QupZilla +* Personal Information Manager plugin for Falkon * Copyright (C) 2012-2014 David Rosca * Copyright (C) 2012-2014 Mladen Pejaković * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "PIM_plugin.h" #include "PIM_handler.h" #include "PIM_settings.h" #include "mainapplication.h" #include "pluginproxy.h" #include "browserwindow.h" #include "webview.h" #include PIM_Plugin::PIM_Plugin() : QObject() , m_handler(0) { } PluginSpec PIM_Plugin::pluginSpec() { PluginSpec spec; spec.name = "PIM"; spec.info = "Personal Information Manager"; - spec.description = "Adds ability for QupZilla to store some personal data"; + spec.description = "Adds ability for Falkon to store some personal data"; spec.version = "0.2.0"; spec.author = QString::fromUtf8("Mladen Pejaković "); spec.icon = QPixmap(":/PIM/data/PIM.png"); spec.hasSettings = true; return spec; } void PIM_Plugin::init(InitState state, const QString &settingsPath) { Q_UNUSED(state) m_handler = new PIM_Handler(settingsPath, this); QZ_REGISTER_EVENT_HANDLER(PluginProxy::KeyPressHandler); connect(mApp->plugins(), SIGNAL(webPageCreated(WebPage*)), m_handler, SLOT(webPageCreated(WebPage*))); } void PIM_Plugin::unload() { m_handler->unloadPlugin(); m_handler->deleteLater(); } bool PIM_Plugin::testPlugin() { // Require the version that the plugin was built with - return (Qz::VERSION == QLatin1String(QUPZILLA_VERSION)); + return (Qz::VERSION == QLatin1String(FALKON_VERSION)); } QTranslator* PIM_Plugin::getTranslator(const QString &locale) { QTranslator* translator = new QTranslator(this); translator->load(locale, ":/PIM/locale/"); return translator; } void PIM_Plugin::showSettings(QWidget* parent) { m_handler->showSettings(parent); } void PIM_Plugin::populateWebViewMenu(QMenu* menu, WebView* view, const WebHitTestResult &r) { m_handler->populateWebViewMenu(menu, view, r); } bool PIM_Plugin::keyPress(const Qz::ObjectName &type, QObject* obj, QKeyEvent* event) { if (type == Qz::ON_WebView) { WebView* view = qobject_cast(obj); return m_handler->keyPress(view, event); } return false; } diff --git a/src/plugins/PIM/PIM_plugin.h b/src/plugins/PIM/PIM_plugin.h index 1a8e860d..5f68b59e 100644 --- a/src/plugins/PIM/PIM_plugin.h +++ b/src/plugins/PIM/PIM_plugin.h @@ -1,52 +1,52 @@ /* ============================================================ -* Personal Information Manager plugin for QupZilla +* Personal Information Manager plugin for Falkon * Copyright (C) 2012-2014 David Rosca * Copyright (C) 2012-2014 Mladen Pejaković * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef PIM_PLUGIN_H #define PIM_PLUGIN_H #include "plugininterface.h" class WebPage; class BrowserWindow; class PIM_Handler; class PIM_Plugin : public QObject, public PluginInterface { Q_OBJECT Q_INTERFACES(PluginInterface) - Q_PLUGIN_METADATA(IID "QupZilla.Browser.plugin.PIM") + Q_PLUGIN_METADATA(IID "Falkon.Browser.plugin.PIM") public: PIM_Plugin(); PluginSpec pluginSpec(); void init(InitState state, const QString &settingsPath); void unload(); bool testPlugin(); QTranslator* getTranslator(const QString &locale); void showSettings(QWidget* parent = 0); void populateWebViewMenu(QMenu* menu, WebView* view, const WebHitTestResult &r); bool keyPress(const Qz::ObjectName &type, QObject* obj, QKeyEvent* event); private: PIM_Handler* m_handler; }; #endif // PIM_PLUGIN_H diff --git a/src/plugins/PIM/PIM_settings.cpp b/src/plugins/PIM/PIM_settings.cpp index 1a505d41..452a2dc3 100644 --- a/src/plugins/PIM/PIM_settings.cpp +++ b/src/plugins/PIM/PIM_settings.cpp @@ -1,79 +1,79 @@ /* ============================================================ -* Personal Information Manager plugin for QupZilla +* Personal Information Manager plugin for Falkon * Copyright (C) 2012-2014 David Rosca * Copyright (C) 2012-2014 Mladen Pejaković * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "PIM_settings.h" #include "ui_PIM_settings.h" #include "PIM_handler.h" #include PIM_Settings::PIM_Settings(const QString &settingsFile, QWidget* parent) : QDialog(parent) , ui(new Ui::PIM_Settings) , m_settingsFile(settingsFile) { setAttribute(Qt::WA_DeleteOnClose); ui->setupUi(this); QSettings settings(m_settingsFile, QSettings::IniFormat); settings.beginGroup("PIM"); ui->pim_firstname->setText(settings.value("FirstName", QString()).toString()); ui->pim_lastname->setText(settings.value("LastName", QString()).toString()); ui->pim_email->setText(settings.value("Email", QString()).toString()); ui->pim_phone->setText(settings.value("Phone", QString()).toString()); ui->pim_mobile->setText(settings.value("Mobile", QString()).toString()); ui->pim_address->setText(settings.value("Address", QString()).toString()); ui->pim_city->setText(settings.value("City", QString()).toString()); ui->pim_zip->setText(settings.value("Zip", QString()).toString()); ui->pim_state->setText(settings.value("State", QString()).toString()); ui->pim_country->setText(settings.value("Country", QString()).toString()); ui->pim_homepage->setText(settings.value("HomePage", QString()).toString()); ui->pim_special1->setText(settings.value("Special1", QString()).toString()); ui->pim_special2->setText(settings.value("Special2", QString()).toString()); ui->pim_special3->setText(settings.value("Special3", QString()).toString()); settings.endGroup(); connect(this, SIGNAL(accepted()), this, SLOT(dialogAccepted())); } void PIM_Settings::dialogAccepted() { QSettings settings(m_settingsFile, QSettings::IniFormat); settings.beginGroup("PIM"); settings.setValue("FirstName", ui->pim_firstname->text()); settings.setValue("LastName", ui->pim_lastname->text()); settings.setValue("Email", ui->pim_email->text()); settings.setValue("Phone", ui->pim_phone->text()); settings.setValue("Mobile", ui->pim_mobile->text()); settings.setValue("Address", ui->pim_address->text()); settings.setValue("City", ui->pim_city->text()); settings.setValue("Zip", ui->pim_zip->text()); settings.setValue("State", ui->pim_state->text()); settings.setValue("Country", ui->pim_country->text()); settings.setValue("HomePage", ui->pim_homepage->text()); settings.setValue("Special1", ui->pim_special1->text()); settings.setValue("Special2", ui->pim_special2->text()); settings.setValue("Special3", ui->pim_special3->text()); settings.endGroup(); } PIM_Settings::~PIM_Settings() { delete ui; } diff --git a/src/plugins/PIM/PIM_settings.h b/src/plugins/PIM/PIM_settings.h index 23cc68d3..60b6a411 100644 --- a/src/plugins/PIM/PIM_settings.h +++ b/src/plugins/PIM/PIM_settings.h @@ -1,48 +1,48 @@ /* ============================================================ -* Personal Information Manager plugin for QupZilla +* Personal Information Manager plugin for Falkon * Copyright (C) 2012-2014 David Rosca * Copyright (C) 2012-2014 Mladen Pejaković * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef PIM_SETTINGS_H #define PIM_SETTINGS_H #include namespace Ui { class PIM_Settings; } class PIM_Handler; class PIM_Settings : public QDialog { Q_OBJECT public: explicit PIM_Settings(const QString &settingsFile, QWidget* parent = 0); ~PIM_Settings(); private slots: void dialogAccepted(); private: Ui::PIM_Settings* ui; QString m_settingsFile; }; #endif // PIM_SETTINGS_H diff --git a/src/plugins/PIM/PIM_settings.ui b/src/plugins/PIM/PIM_settings.ui index 8bbf53f2..cd7ca559 100644 --- a/src/plugins/PIM/PIM_settings.ui +++ b/src/plugins/PIM/PIM_settings.ui @@ -1,313 +1,313 @@ PIM_Settings 0 0 539 346 PIM Settings Qt::Horizontal 40 20 :/PIM/data/PIM.png <h2>Personal Information Manager</h2> Qt::Horizontal 40 20 Your personal information that will be used on webpages. Qt::AlignCenter First Name: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Last Name: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter E-mail: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Phone: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Mobile Phone: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Address: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter City: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter ZIP Code: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter State/Region: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Country: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Home Page: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Custom 1: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Custom 2: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Custom 3: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - <b>Note:</b> Press Ctrl+ENTER to autofill form fields for which QupZilla finds personal entries. + <b>Note:</b> Press Ctrl+ENTER to autofill form fields for which Falkon finds personal entries. Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok buttonBox accepted() PIM_Settings accept() 248 254 157 274 buttonBox rejected() PIM_Settings reject() 316 260 286 274 diff --git a/src/plugins/StatusBarIcons/sbi_icon.cpp b/src/plugins/StatusBarIcons/sbi_icon.cpp index 752f84f1..8b16548d 100644 --- a/src/plugins/StatusBarIcons/sbi_icon.cpp +++ b/src/plugins/StatusBarIcons/sbi_icon.cpp @@ -1,59 +1,59 @@ /* ============================================================ -* StatusBarIcons - Extra icons in statusbar for QupZilla +* StatusBarIcons - Extra icons in statusbar for Falkon * Copyright (C) 2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "sbi_icon.h" #include "browserwindow.h" #include "tabbedwebview.h" #include "webpage.h" SBI_Icon::SBI_Icon(BrowserWindow* window, const QString &settingsPath) : ClickableLabel(window) , m_window(window) , m_settingsFile(settingsPath + QL1S("/extensions.ini")) { } bool SBI_Icon::testCurrentPageWebAttribute(QWebEngineSettings::WebAttribute attr) const { return currentPageSettings() && currentPageSettings()->testAttribute(attr); } void SBI_Icon::setCurrentPageWebAttribute(QWebEngineSettings::WebAttribute attr, bool value) { if (currentPageSettings()) { currentPageSettings()->setAttribute(attr, value); } } QWebEngineSettings* SBI_Icon::currentPageSettings() const { if (!m_window->weView()) { return 0; } return m_window->weView()->page()->settings(); } WebPage* SBI_Icon::currentPage() const { if (!m_window->weView()) { return 0; } return m_window->weView()->page(); } diff --git a/src/plugins/StatusBarIcons/sbi_icon.h b/src/plugins/StatusBarIcons/sbi_icon.h index c450c498..e45198e8 100644 --- a/src/plugins/StatusBarIcons/sbi_icon.h +++ b/src/plugins/StatusBarIcons/sbi_icon.h @@ -1,46 +1,46 @@ /* ============================================================ -* StatusBarIcons - Extra icons in statusbar for QupZilla +* StatusBarIcons - Extra icons in statusbar for Falkon * Copyright (C) 2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef SBI_ICON_H #define SBI_ICON_H #include #include "clickablelabel.h" class BrowserWindow; class WebPage; class SBI_Icon : public ClickableLabel { Q_OBJECT public: explicit SBI_Icon(BrowserWindow* window, const QString &settingsPath = QString()); protected: bool testCurrentPageWebAttribute(QWebEngineSettings::WebAttribute attr) const; void setCurrentPageWebAttribute(QWebEngineSettings::WebAttribute attr, bool value); QWebEngineSettings* currentPageSettings() const; WebPage* currentPage() const; BrowserWindow* m_window; QString m_settingsFile; }; #endif // SBI_ICON_H diff --git a/src/plugins/StatusBarIcons/sbi_iconsmanager.cpp b/src/plugins/StatusBarIcons/sbi_iconsmanager.cpp index 84c34038..82b1db6d 100644 --- a/src/plugins/StatusBarIcons/sbi_iconsmanager.cpp +++ b/src/plugins/StatusBarIcons/sbi_iconsmanager.cpp @@ -1,169 +1,169 @@ /* ============================================================ -* StatusBarIcons - Extra icons in statusbar for QupZilla +* StatusBarIcons - Extra icons in statusbar for Falkon * Copyright (C) 2013-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "sbi_iconsmanager.h" #include "sbi_imagesicon.h" #include "sbi_javascripticon.h" #include "sbi_zoomwidget.h" #include "sbi_networkicon.h" #include "sbi_networkmanager.h" #include "browserwindow.h" #include #include SBI_IconsManager::SBI_IconsManager(const QString &settingsPath, QObject* parent) : QObject(parent) , m_settingsPath(settingsPath) , m_showImagesIcon(false) , m_showJavaScriptIcon(false) , m_showNetworkIcon(false) , m_showZoomWidget(false) , m_networkManager(0) { loadSettings(); } void SBI_IconsManager::loadSettings() { QSettings settings(m_settingsPath + QL1S("/extensions.ini"), QSettings::IniFormat); settings.beginGroup("StatusBarIcons"); m_showImagesIcon = settings.value("showImagesIcon", true).toBool(); m_showJavaScriptIcon = settings.value("showJavaScriptIcon", true).toBool(); m_showNetworkIcon = settings.value("showNetworkIcon", true).toBool(); m_showZoomWidget = settings.value("showZoomWidget", true).toBool(); settings.endGroup(); } bool SBI_IconsManager::showImagesIcon() const { return m_showImagesIcon; } void SBI_IconsManager::setShowImagesIcon(bool show) { QSettings settings(m_settingsPath + QL1S("/extensions.ini"), QSettings::IniFormat); settings.setValue("StatusBarIcons/showImagesIcon", show); m_showImagesIcon = show; } bool SBI_IconsManager::showJavaScriptIcon() const { return m_showJavaScriptIcon; } void SBI_IconsManager::setShowJavaScriptIcon(bool show) { QSettings settings(m_settingsPath + QL1S("/extensions.ini"), QSettings::IniFormat); settings.setValue("StatusBarIcons/showJavaScriptIcon", show); m_showJavaScriptIcon = show; } bool SBI_IconsManager::showNetworkIcon() const { return m_showNetworkIcon; } void SBI_IconsManager::setShowNetworkIcon(bool show) { QSettings settings(m_settingsPath + QL1S("/extensions.ini"), QSettings::IniFormat); settings.setValue("StatusBarIcons/showNetworkIcon", show); m_showNetworkIcon = show; } bool SBI_IconsManager::showZoomWidget() const { return m_showZoomWidget; } void SBI_IconsManager::setShowZoomWidget(bool show) { QSettings settings(m_settingsPath + QL1S("/extensions.ini"), QSettings::IniFormat); settings.setValue("StatusBarIcons/showZoomWidget", show); m_showZoomWidget = show; } void SBI_IconsManager::reloadIcons() { QHashIterator it(m_windows); while (it.hasNext()) { it.next(); mainWindowDeleted(it.key()); mainWindowCreated(it.key()); } } void SBI_IconsManager::destroyIcons() { QHashIterator it(m_windows); while (it.hasNext()) { it.next(); mainWindowDeleted(it.key()); } } void SBI_IconsManager::mainWindowCreated(BrowserWindow* window) { if (m_showImagesIcon) { SBI_ImagesIcon* w = new SBI_ImagesIcon(window, m_settingsPath); window->statusBar()->addPermanentWidget(w); m_windows[window].append(w); } if (m_showJavaScriptIcon) { SBI_JavaScriptIcon* w = new SBI_JavaScriptIcon(window); window->statusBar()->addPermanentWidget(w); m_windows[window].append(w); } if (m_showNetworkIcon) { if (!m_networkManager) { m_networkManager = new SBI_NetworkManager(m_settingsPath, this); } SBI_NetworkIcon* w = new SBI_NetworkIcon(window); window->statusBar()->addPermanentWidget(w); m_windows[window].append(w); } if (m_showZoomWidget) { SBI_ZoomWidget* w = new SBI_ZoomWidget(window); window->statusBar()->addPermanentWidget(w); m_windows[window].append(w); } } void SBI_IconsManager::mainWindowDeleted(BrowserWindow* window) { foreach (QWidget* w, m_windows[window]) { window->statusBar()->removeWidget(w); delete w; } m_windows[window].clear(); } SBI_IconsManager::~SBI_IconsManager() { delete m_networkManager; } diff --git a/src/plugins/StatusBarIcons/sbi_iconsmanager.h b/src/plugins/StatusBarIcons/sbi_iconsmanager.h index 175528e2..fe0d9b47 100644 --- a/src/plugins/StatusBarIcons/sbi_iconsmanager.h +++ b/src/plugins/StatusBarIcons/sbi_iconsmanager.h @@ -1,68 +1,68 @@ /* ============================================================ -* StatusBarIcons - Extra icons in statusbar for QupZilla +* StatusBarIcons - Extra icons in statusbar for Falkon * Copyright (C) 2013-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef SBI_ICONSMANAGER_H #define SBI_ICONSMANAGER_H #include #include class BrowserWindow; class SBI_NetworkManager; class SBI_IconsManager : public QObject { Q_OBJECT public: explicit SBI_IconsManager(const QString &settingsPath, QObject* parent = 0); ~SBI_IconsManager(); void loadSettings(); bool showImagesIcon() const; void setShowImagesIcon(bool show); bool showJavaScriptIcon() const; void setShowJavaScriptIcon(bool show); bool showNetworkIcon() const; void setShowNetworkIcon(bool show); bool showZoomWidget() const; void setShowZoomWidget(bool show); void reloadIcons(); void destroyIcons(); signals: public slots: void mainWindowCreated(BrowserWindow* window); void mainWindowDeleted(BrowserWindow* window); private: QString m_settingsPath; bool m_showImagesIcon; bool m_showJavaScriptIcon; bool m_showNetworkIcon; bool m_showZoomWidget; QHash m_windows; SBI_NetworkManager* m_networkManager; }; #endif // SBI_ICONSMANAGER_H diff --git a/src/plugins/StatusBarIcons/sbi_imagesicon.cpp b/src/plugins/StatusBarIcons/sbi_imagesicon.cpp index e851ece6..83719ab6 100644 --- a/src/plugins/StatusBarIcons/sbi_imagesicon.cpp +++ b/src/plugins/StatusBarIcons/sbi_imagesicon.cpp @@ -1,119 +1,119 @@ /* ============================================================ -* StatusBarIcons - Extra icons in statusbar for QupZilla +* StatusBarIcons - Extra icons in statusbar for Falkon * Copyright (C) 2013-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "sbi_imagesicon.h" #include "browserwindow.h" #include "tabwidget.h" #include "tabbedwebview.h" #include "webpage.h" #include #include #include SBI_ImagesIcon::SBI_ImagesIcon(BrowserWindow* window, const QString &settingsPath) : SBI_Icon(window, settingsPath) { setObjectName(QSL("sbi_imagesicon")); setCursor(Qt::PointingHandCursor); setToolTip(tr("Modify images loading settings per-site and globally")); m_icon = QIcon::fromTheme("image-x-generics", QIcon(":sbi/data/images.png")); setPixmap(m_icon.pixmap(16)); QSettings settings(m_settingsFile, QSettings::IniFormat); settings.beginGroup("StatusBarIcons_Images"); m_loadingImages = settings.value("LoadImages", true).toBool(); settings.endGroup(); QWebEngineSettings::defaultSettings()->setAttribute(QWebEngineSettings::AutoLoadImages, m_loadingImages); updateIcon(); connect(m_window->tabWidget(), SIGNAL(currentChanged(int)), this, SLOT(updateIcon())); connect(this, SIGNAL(clicked(QPoint)), this, SLOT(showMenu(QPoint))); } void SBI_ImagesIcon::showMenu(const QPoint &point) { QFont boldFont = font(); boldFont.setBold(true); QMenu menu; menu.addAction(m_icon, tr("Current Page Settings"))->setFont(boldFont); if (testCurrentPageWebAttribute(QWebEngineSettings::AutoLoadImages)) { menu.addAction(tr("Disable loading images (temporarily)"), this, SLOT(toggleLoadingImages())); } else { menu.addAction(tr("Enable loading images (temporarily)"), this, SLOT(toggleLoadingImages())); } menu.addSeparator(); menu.addAction(m_icon, tr("Global Settings"))->setFont(boldFont); QAction* act = menu.addAction(tr("Automatically load images")); act->setCheckable(true); act->setChecked(m_loadingImages); connect(act, SIGNAL(toggled(bool)), this, SLOT(setGlobalLoadingImages(bool))); menu.exec(point); } void SBI_ImagesIcon::toggleLoadingImages() { bool current = testCurrentPageWebAttribute(QWebEngineSettings::AutoLoadImages); setCurrentPageWebAttribute(QWebEngineSettings::AutoLoadImages, !current); // We should reload page on disabling images if (current) { m_window->weView()->reload(); } updateIcon(); } void SBI_ImagesIcon::setGlobalLoadingImages(bool enable) { // Save it permanently QSettings settings(m_settingsFile, QSettings::IniFormat); settings.beginGroup("StatusBarIcons_Images"); settings.setValue("LoadImages", enable); settings.endGroup(); // Switch it in websettings m_loadingImages = enable; QWebEngineSettings::defaultSettings()->setAttribute(QWebEngineSettings::AutoLoadImages, m_loadingImages); updateIcon(); // We should reload page on disabling images if (!enable) { m_window->weView()->reload(); } } void SBI_ImagesIcon::updateIcon() { if (testCurrentPageWebAttribute(QWebEngineSettings::AutoLoadImages)) { setGraphicsEffect(0); } else { QGraphicsColorizeEffect* effect = new QGraphicsColorizeEffect(this); effect->setColor(Qt::gray); setGraphicsEffect(effect); } } diff --git a/src/plugins/StatusBarIcons/sbi_imagesicon.h b/src/plugins/StatusBarIcons/sbi_imagesicon.h index 4b9c287a..378e4b32 100644 --- a/src/plugins/StatusBarIcons/sbi_imagesicon.h +++ b/src/plugins/StatusBarIcons/sbi_imagesicon.h @@ -1,44 +1,44 @@ /* ============================================================ -* StatusBarIcons - Extra icons in statusbar for QupZilla +* StatusBarIcons - Extra icons in statusbar for Falkon * Copyright (C) 2013-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef SBI_IMAGESICON_H #define SBI_IMAGESICON_H #include #include "sbi_icon.h" class SBI_ImagesIcon : public SBI_Icon { Q_OBJECT public: explicit SBI_ImagesIcon(BrowserWindow* window, const QString &settingsPath); private slots: void showMenu(const QPoint &point); void updateIcon(); void toggleLoadingImages(); void setGlobalLoadingImages(bool enable); private: QIcon m_icon; bool m_loadingImages; }; #endif // SBI_IMAGESICON_H diff --git a/src/plugins/StatusBarIcons/sbi_javascripticon.cpp b/src/plugins/StatusBarIcons/sbi_javascripticon.cpp index d1767563..aae999c5 100644 --- a/src/plugins/StatusBarIcons/sbi_javascripticon.cpp +++ b/src/plugins/StatusBarIcons/sbi_javascripticon.cpp @@ -1,102 +1,102 @@ /* ============================================================ * StatusBarIcons - Extra icons in statusbar for QupZilla * Copyright (C) 2013-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "sbi_javascripticon.h" #include "browserwindow.h" #include "tabwidget.h" #include "tabbedwebview.h" #include "webpage.h" #include "jsoptions.h" #include #include #include SBI_JavaScriptIcon::SBI_JavaScriptIcon(BrowserWindow* window) : SBI_Icon(window) { setObjectName(QSL("sbi_javascripticon")); setCursor(Qt::PointingHandCursor); setToolTip(tr("Modify JavaScript settings per-site and globally")); m_icon = QIcon::fromTheme("application-x-javascript", QIcon(":sbi/data/javascript.png")); setPixmap(m_icon.pixmap(16)); connect(m_window->tabWidget(), SIGNAL(currentChanged(int)), this, SLOT(updateIcon())); connect(this, SIGNAL(clicked(QPoint)), this, SLOT(showMenu(QPoint))); updateIcon(); } void SBI_JavaScriptIcon::showMenu(const QPoint &point) { QFont boldFont = font(); boldFont.setBold(true); QMenu menu; menu.addAction(m_icon, tr("Current Page Settings"))->setFont(boldFont); if (testCurrentPageWebAttribute(QWebEngineSettings::JavascriptEnabled)) { menu.addAction(tr("Disable JavaScript (temporarily)"), this, SLOT(toggleJavaScript())); } else { menu.addAction(tr("Enable JavaScript (temporarily)"), this, SLOT(toggleJavaScript())); } - // JavaScript needs to be always enabled for qupzilla: sites - if (currentPage() && currentPage()->url().scheme() == QLatin1String("qupzilla")) { + // JavaScript needs to be always enabled for falkon: sites + if (currentPage() && currentPage()->url().scheme() == QLatin1String("falkon")) { menu.actions().at(1)->setEnabled(false); } menu.addSeparator(); menu.addAction(m_icon, tr("Global Settings"))->setFont(boldFont); menu.addAction(tr("Manage JavaScript settings"), this, SLOT(openJavaScriptSettings())); menu.exec(point); } void SBI_JavaScriptIcon::updateIcon() { if (testCurrentPageWebAttribute(QWebEngineSettings::JavascriptEnabled)) { setGraphicsEffect(0); } else { QGraphicsColorizeEffect* effect = new QGraphicsColorizeEffect(this); effect->setColor(Qt::gray); setGraphicsEffect(effect); } } void SBI_JavaScriptIcon::toggleJavaScript() { if (!currentPage()) { return; } bool current = testCurrentPageWebAttribute(QWebEngineSettings::JavascriptEnabled); currentPage()->setJavaScriptEnabled(!current); m_window->weView()->reload(); updateIcon(); } void SBI_JavaScriptIcon::openJavaScriptSettings() { JsOptions* dialog = new JsOptions(m_window); dialog->open(); } diff --git a/src/plugins/StatusBarIcons/sbi_javascripticon.h b/src/plugins/StatusBarIcons/sbi_javascripticon.h index 8f436ccb..70e201f1 100644 --- a/src/plugins/StatusBarIcons/sbi_javascripticon.h +++ b/src/plugins/StatusBarIcons/sbi_javascripticon.h @@ -1,43 +1,43 @@ /* ============================================================ -* StatusBarIcons - Extra icons in statusbar for QupZilla +* StatusBarIcons - Extra icons in statusbar for Falkon * Copyright (C) 2013-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef SBI_JAVASCRIPTICON_H #define SBI_JAVASCRIPTICON_H #include #include "sbi_icon.h" class SBI_JavaScriptIcon : public SBI_Icon { Q_OBJECT public: explicit SBI_JavaScriptIcon(BrowserWindow* window); private slots: void showMenu(const QPoint &point); void updateIcon(); void toggleJavaScript(); void openJavaScriptSettings(); private: QIcon m_icon; }; #endif // SBI_JAVASCRIPTICON_H diff --git a/src/plugins/StatusBarIcons/sbi_networkicon.cpp b/src/plugins/StatusBarIcons/sbi_networkicon.cpp index f61cccd2..38b28e29 100644 --- a/src/plugins/StatusBarIcons/sbi_networkicon.cpp +++ b/src/plugins/StatusBarIcons/sbi_networkicon.cpp @@ -1,133 +1,133 @@ /* ============================================================ -* StatusBarIcons - Extra icons in statusbar for QupZilla +* StatusBarIcons - Extra icons in statusbar for Falkon * Copyright (C) 2013-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "sbi_networkicon.h" #include "sbi_networkicondialog.h" #include "sbi_networkproxy.h" #include "sbi_networkmanager.h" #include "mainapplication.h" #include "browserwindow.h" #include #include SBI_NetworkIcon::SBI_NetworkIcon(BrowserWindow* window) : SBI_Icon(window) , m_networkConfiguration(new QNetworkConfigurationManager(this)) { setObjectName(QSL("sbi_networkicon")); setCursor(Qt::PointingHandCursor); onlineStateChanged(m_networkConfiguration->isOnline()); connect(m_networkConfiguration, SIGNAL(onlineStateChanged(bool)), this, SLOT(onlineStateChanged(bool))); connect(this, SIGNAL(clicked(QPoint)), this, SLOT(showMenu(QPoint))); } void SBI_NetworkIcon::onlineStateChanged(bool online) { if (online) { setPixmap(QIcon(":sbi/data/network-online.png").pixmap(16)); } else { setPixmap(QIcon(":sbi/data/network-offline.png").pixmap(16)); } updateToolTip(); } void SBI_NetworkIcon::showDialog() { SBI_NetworkIconDialog* dialog = new SBI_NetworkIconDialog(m_window); dialog->open(); } void SBI_NetworkIcon::showMenu(const QPoint &pos) { QFont boldFont = font(); boldFont.setBold(true); QMenu menu; menu.addAction(QIcon::fromTheme("preferences-system-network", QIcon(":sbi/data/preferences-network.png")), tr("Proxy Configuration"))->setFont(boldFont); QMenu* proxyMenu = menu.addMenu(tr("Select proxy")); const QHash &proxies = SBINetManager->proxies(); QHashIterator it(proxies); while (it.hasNext()) { it.next(); QAction* act = proxyMenu->addAction(it.key(), this, SLOT(useProxy())); act->setData(it.key()); act->setCheckable(true); act->setChecked(it.value() == SBINetManager->currentProxy()); } if (proxyMenu->actions().count() == 0) { proxyMenu->addAction(tr("Empty"))->setEnabled(false); } menu.addSeparator(); menu.addAction(tr("Manage proxies"), this, SLOT(showDialog())); menu.exec(pos); } void SBI_NetworkIcon::useProxy() { if (QAction* act = qobject_cast(sender())) { SBINetManager->setCurrentProxy(act->data().toString()); } } void SBI_NetworkIcon::updateToolTip() { QString tooltip = tr("Shows network status and manages proxy

Network:
%1

Proxy:
%2"); if (m_networkConfiguration->isOnline()) { tooltip = tooltip.arg(tr("Connected")); } else { tooltip = tooltip.arg(tr("Offline")); } switch (QNetworkProxy::applicationProxy().type()) { case QNetworkProxy::DefaultProxy: tooltip = tooltip.arg(tr("System proxy")); break; case QNetworkProxy::NoProxy: tooltip = tooltip.arg(tr("No proxy")); break; default: tooltip = tooltip.arg(tr("User defined")); break; } if (SBINetManager->currentProxy()) { tooltip.append(QString(" (%1)").arg(SBINetManager->currentProxyName())); } setToolTip(tooltip); } void SBI_NetworkIcon::enterEvent(QEvent* event) { updateToolTip(); SBI_Icon::enterEvent(event); } diff --git a/src/plugins/StatusBarIcons/sbi_networkicon.h b/src/plugins/StatusBarIcons/sbi_networkicon.h index e941f2b7..b4c8a0e0 100644 --- a/src/plugins/StatusBarIcons/sbi_networkicon.h +++ b/src/plugins/StatusBarIcons/sbi_networkicon.h @@ -1,48 +1,48 @@ /* ============================================================ -* StatusBarIcons - Extra icons in statusbar for QupZilla +* StatusBarIcons - Extra icons in statusbar for Falkon * Copyright (C) 2013-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef SBI_NETWORKICON_H #define SBI_NETWORKICON_H #include #include "sbi_icon.h" class QNetworkConfigurationManager; class SBI_NetworkIcon : public SBI_Icon { Q_OBJECT public: explicit SBI_NetworkIcon(BrowserWindow* window); private slots: void onlineStateChanged(bool online); void showDialog(); void showMenu(const QPoint &pos); void useProxy(); private: void updateToolTip(); void enterEvent(QEvent* event); QNetworkConfigurationManager* m_networkConfiguration; }; #endif // SBI_NETWORKICON_H diff --git a/src/plugins/StatusBarIcons/sbi_networkicondialog.cpp b/src/plugins/StatusBarIcons/sbi_networkicondialog.cpp index 6e9288c5..319c13a2 100644 --- a/src/plugins/StatusBarIcons/sbi_networkicondialog.cpp +++ b/src/plugins/StatusBarIcons/sbi_networkicondialog.cpp @@ -1,114 +1,114 @@ /* ============================================================ -* StatusBarIcons - Extra icons in statusbar for QupZilla +* StatusBarIcons - Extra icons in statusbar for Falkon * Copyright (C) 2013-2016 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "sbi_networkicondialog.h" #include "sbi_networkmanager.h" #include "sbi_networkproxy.h" #include "ui_sbi_networkicondialog.h" #include #include SBI_NetworkIconDialog::SBI_NetworkIconDialog(QWidget* parent) : QDialog(parent) , ui(new Ui::SBI_NetworkIconDialog) { setAttribute(Qt::WA_DeleteOnClose); ui->setupUi(this); ui->addButton->setIcon(QIcon::fromTheme("document-new", QIcon(":sbi/data/add.png"))); ui->removeButton->setIcon(QIcon::fromTheme("edit-delete", QIcon(":sbi/data/remove.png"))); const QHash &proxies = SBINetManager->proxies(); QHashIterator it(proxies); while (it.hasNext()) { it.next(); ui->comboBox->addItem(it.key()); } updateWidgets(); showProxy(ui->comboBox->currentText()); connect(ui->addButton, SIGNAL(clicked()), this, SLOT(addProxy())); connect(ui->removeButton, SIGNAL(clicked()), this, SLOT(removeProxy())); connect(ui->comboBox, SIGNAL(currentIndexChanged(QString)), this, SLOT(showProxy(QString))); connect(ui->proxyButtonBox, SIGNAL(accepted()), this, SLOT(saveProxy())); connect(ui->closeButton, SIGNAL(clicked(QAbstractButton*)), this, SLOT(close())); } void SBI_NetworkIconDialog::addProxy() { const QString name = QInputDialog::getText(this, tr("Add proxy"), tr("Name of proxy:")); if (name.isEmpty() || ui->comboBox->findText(name) > -1) { return; } ui->comboBox->addItem(name); ui->comboBox->setCurrentIndex(ui->comboBox->count() - 1); updateWidgets(); } void SBI_NetworkIconDialog::removeProxy() { QMessageBox::StandardButton button = QMessageBox::warning(this, tr("Remove current proxy"), tr("Are you sure you want to remove current proxy?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No); if (button != QMessageBox::Yes) { return; } int index = ui->comboBox->currentIndex(); if (index < 0) { return; } SBINetManager->removeProxy(ui->comboBox->currentText()); ui->comboBox->removeItem(index); updateWidgets(); } void SBI_NetworkIconDialog::saveProxy() { SBINetManager->saveProxy(ui->comboBox->currentText(), ui->proxyWidget->getProxy()); } void SBI_NetworkIconDialog::showProxy(const QString &name) { SBI_NetworkProxy* proxy = SBINetManager->proxies()[name]; ui->proxyWidget->clear(); if (proxy) { ui->proxyWidget->setProxy(*proxy); } } void SBI_NetworkIconDialog::updateWidgets() { ui->removeButton->setEnabled(ui->comboBox->count() > 0); ui->noProxiesLabel->setVisible(ui->comboBox->count() == 0); ui->proxyWidget->setVisible(ui->comboBox->count() > 0); } SBI_NetworkIconDialog::~SBI_NetworkIconDialog() { delete ui; } diff --git a/src/plugins/StatusBarIcons/sbi_networkicondialog.h b/src/plugins/StatusBarIcons/sbi_networkicondialog.h index 69983140..54a418bc 100644 --- a/src/plugins/StatusBarIcons/sbi_networkicondialog.h +++ b/src/plugins/StatusBarIcons/sbi_networkicondialog.h @@ -1,51 +1,51 @@ /* ============================================================ -* StatusBarIcons - Extra icons in statusbar for QupZilla +* StatusBarIcons - Extra icons in statusbar for Falkon * Copyright (C) 2013-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef SBI_NETWORKICONDIALOG_H #define SBI_NETWORKICONDIALOG_H #include namespace Ui { class SBI_NetworkIconDialog; } class SBI_NetworkIcon; class SBI_NetworkIconDialog : public QDialog { Q_OBJECT public: explicit SBI_NetworkIconDialog(QWidget* parent = 0); ~SBI_NetworkIconDialog(); private slots: void addProxy(); void removeProxy(); void saveProxy(); void showProxy(const QString &name); private: void updateWidgets(); Ui::SBI_NetworkIconDialog* ui; }; #endif // SBI_NETWORKICONDIALOG_H diff --git a/src/plugins/StatusBarIcons/sbi_networkmanager.cpp b/src/plugins/StatusBarIcons/sbi_networkmanager.cpp index aac53b33..7f207fac 100644 --- a/src/plugins/StatusBarIcons/sbi_networkmanager.cpp +++ b/src/plugins/StatusBarIcons/sbi_networkmanager.cpp @@ -1,137 +1,137 @@ /* ============================================================ -* StatusBarIcons - Extra icons in statusbar for QupZilla +* StatusBarIcons - Extra icons in statusbar for Falkon * Copyright (C) 2013-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "sbi_networkmanager.h" #include "sbi_networkproxy.h" #include "mainapplication.h" #include "networkmanager.h" #include "datapaths.h" #include SBI_NetworkManager* SBI_NetworkManager::s_instance = 0; SBI_NetworkManager::SBI_NetworkManager(const QString &settingsPath, QObject* parent) : QObject(parent) , m_settingsFile(settingsPath + QL1S("/networkicon.ini")) , m_currentProxy(0) { s_instance = this; loadSettings(); } SBI_NetworkManager* SBI_NetworkManager::instance() { return s_instance; } void SBI_NetworkManager::loadSettings() { QSettings settings(m_settingsFile, QSettings::IniFormat); foreach (const QString &group, settings.childGroups()) { if (group.isEmpty()) { continue; } SBI_NetworkProxy* proxy = new SBI_NetworkProxy; settings.beginGroup(group); proxy->loadFromSettings(settings); settings.endGroup(); m_proxies[group] = proxy; } const QString currentName = settings.value("CurrentProxy", QString()).toString(); m_currentProxy = m_proxies.contains(currentName) ? m_proxies.value(currentName) : 0; applyCurrentProxy(); } QString SBI_NetworkManager::currentProxyName() const { return m_proxies.key(m_currentProxy); } SBI_NetworkProxy* SBI_NetworkManager::currentProxy() const { return m_currentProxy; } void SBI_NetworkManager::setCurrentProxy(const QString &name) { QSettings settings(m_settingsFile, QSettings::IniFormat); settings.setValue("CurrentProxy", name); m_currentProxy = m_proxies.contains(name) ? m_proxies.value(name) : 0; applyCurrentProxy(); } void SBI_NetworkManager::saveProxy(const QString &name, SBI_NetworkProxy* proxy) { if (name.isEmpty()) { return; } QSettings settings(m_settingsFile, QSettings::IniFormat); settings.beginGroup(name); proxy->saveToSettings(settings); settings.endGroup(); m_proxies[name] = proxy; } void SBI_NetworkManager::removeProxy(const QString &name) { if (name.isEmpty()) { return; } QSettings settings(m_settingsFile, QSettings::IniFormat); settings.beginGroup(name); settings.remove(QString()); // Removes all keys in current group settings.endGroup(); m_proxies.remove(name); } QHash SBI_NetworkManager::proxies() const { return m_proxies; } void SBI_NetworkManager::applyCurrentProxy() { if (!m_currentProxy) { return; } m_currentProxy->applyProxy(); } void SBI_NetworkManager::deleteProxies() { qDeleteAll(m_proxies); m_proxies.clear(); } SBI_NetworkManager::~SBI_NetworkManager() { deleteProxies(); } diff --git a/src/plugins/StatusBarIcons/sbi_networkmanager.h b/src/plugins/StatusBarIcons/sbi_networkmanager.h index bb4f2214..112fcdef 100644 --- a/src/plugins/StatusBarIcons/sbi_networkmanager.h +++ b/src/plugins/StatusBarIcons/sbi_networkmanager.h @@ -1,59 +1,59 @@ /* ============================================================ -* StatusBarIcons - Extra icons in statusbar for QupZilla +* StatusBarIcons - Extra icons in statusbar for Falkon * Copyright (C) 2013-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef SBI_NETWORKMANAGER_H #define SBI_NETWORKMANAGER_H #include #include class SBI_NetworkProxy; class SBI_NetworkManager : public QObject { Q_OBJECT public: explicit SBI_NetworkManager(const QString &settingsPath, QObject* parent = 0); ~SBI_NetworkManager(); static SBI_NetworkManager* instance(); void loadSettings(); QString currentProxyName() const; SBI_NetworkProxy* currentProxy() const; void setCurrentProxy(const QString &name); void saveProxy(const QString &name, SBI_NetworkProxy* proxy); void removeProxy(const QString &name); QHash proxies() const; private: void applyCurrentProxy(); void deleteProxies(); QString m_settingsFile; QHash m_proxies; SBI_NetworkProxy* m_currentProxy; static SBI_NetworkManager* s_instance; }; #define SBINetManager SBI_NetworkManager::instance() #endif // SBI_NETWORKMANAGER_H diff --git a/src/plugins/StatusBarIcons/sbi_networkproxy.cpp b/src/plugins/StatusBarIcons/sbi_networkproxy.cpp index 28a8922e..cf9de19a 100644 --- a/src/plugins/StatusBarIcons/sbi_networkproxy.cpp +++ b/src/plugins/StatusBarIcons/sbi_networkproxy.cpp @@ -1,115 +1,115 @@ /* ============================================================ -* StatusBarIcons - Extra icons in statusbar for QupZilla +* StatusBarIcons - Extra icons in statusbar for Falkon * Copyright (C) 2013-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "sbi_networkproxy.h" #include SBI_NetworkProxy::SBI_NetworkProxy() : m_port(0) , m_type(QNetworkProxy::NoProxy) { } bool SBI_NetworkProxy::operator ==(const SBI_NetworkProxy &other) const { return m_port == other.m_port && m_hostname == other.m_hostname && m_username == other.m_username && m_password == other.m_password && m_type == other.m_type; } quint16 SBI_NetworkProxy::port() const { return m_port; } void SBI_NetworkProxy::setPort(quint16 port) { m_port = port; } QString SBI_NetworkProxy::hostName() const { return m_hostname; } void SBI_NetworkProxy::setHostName(const QString &hostName) { m_hostname = hostName; } QString SBI_NetworkProxy::userName() const { return m_username; } void SBI_NetworkProxy::setUserName(const QString &userName) { m_username = userName; } QString SBI_NetworkProxy::password() const { return m_password; } void SBI_NetworkProxy::setPassword(const QString &password) { m_password = password; } QNetworkProxy::ProxyType SBI_NetworkProxy::type() const { return m_type; } void SBI_NetworkProxy::setType(QNetworkProxy::ProxyType type) { m_type = type; } void SBI_NetworkProxy::loadFromSettings(const QSettings &settings) { m_hostname = settings.value("HostName", QString()).toString(); m_port = settings.value("Port", 0).toInt(); m_username = settings.value("Username", QString()).toString(); m_password = settings.value("Password", QString()).toString(); m_type = QNetworkProxy::ProxyType(settings.value("ProxyType", QNetworkProxy::NoProxy).toInt()); } void SBI_NetworkProxy::saveToSettings(QSettings &settings) const { settings.setValue("HostName", m_hostname); settings.setValue("Port", m_port); settings.setValue("Username", m_username); settings.setValue("Password", m_password); settings.setValue("ProxyType", m_type); } void SBI_NetworkProxy::applyProxy() { QNetworkProxy proxy; proxy.setHostName(m_hostname); proxy.setPort(m_port); proxy.setUser(m_username); proxy.setPassword(m_password); proxy.setType(m_type); QNetworkProxy::setApplicationProxy(proxy); } diff --git a/src/plugins/StatusBarIcons/sbi_networkproxy.h b/src/plugins/StatusBarIcons/sbi_networkproxy.h index 3ba4e32a..0125acb8 100644 --- a/src/plugins/StatusBarIcons/sbi_networkproxy.h +++ b/src/plugins/StatusBarIcons/sbi_networkproxy.h @@ -1,63 +1,63 @@ /* ============================================================ -* StatusBarIcons - Extra icons in statusbar for QupZilla +* StatusBarIcons - Extra icons in statusbar for Falkon * Copyright (C) 2013-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef SBI_NETWORKPROXY_H #define SBI_NETWORKPROXY_H #include #include "networkproxyfactory.h" class QSettings; class SBI_NetworkProxy { public: explicit SBI_NetworkProxy(); bool operator==(const SBI_NetworkProxy &other) const; quint16 port() const; void setPort(quint16 port); QString hostName() const; void setHostName(const QString &hostName); QString userName() const; void setUserName(const QString &userName); QString password() const; void setPassword(const QString &password); QNetworkProxy::ProxyType type() const; void setType(QNetworkProxy::ProxyType type); void loadFromSettings(const QSettings &settings); void saveToSettings(QSettings &settings) const; void applyProxy(); private: quint16 m_port; QString m_hostname; QString m_username; QString m_password; QNetworkProxy::ProxyType m_type; }; #endif // SBI_NETWORKPROXY_H diff --git a/src/plugins/StatusBarIcons/sbi_proxywidget.cpp b/src/plugins/StatusBarIcons/sbi_proxywidget.cpp index 59f3640b..00375f86 100644 --- a/src/plugins/StatusBarIcons/sbi_proxywidget.cpp +++ b/src/plugins/StatusBarIcons/sbi_proxywidget.cpp @@ -1,89 +1,89 @@ /* ============================================================ -* StatusBarIcons - Extra icons in statusbar for QupZilla +* StatusBarIcons - Extra icons in statusbar for Falkon * Copyright (C) 2013-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "sbi_proxywidget.h" #include "sbi_networkproxy.h" #include "ui_sbi_proxywidget.h" SBI_ProxyWidget::SBI_ProxyWidget(QWidget* parent) : QWidget(parent), ui(new Ui::SBI_ProxyWidget) { ui->setupUi(this); } void SBI_ProxyWidget::clear() { ui->proxyServer->clear(); ui->proxyPort->clear(); ui->proxyUsername->clear(); ui->proxyPassword->clear(); ui->proxyType->setCurrentIndex(0); ui->systemProxy->setChecked(true); } SBI_NetworkProxy* SBI_ProxyWidget::getProxy() const { SBI_NetworkProxy* proxy = new SBI_NetworkProxy; proxy->setHostName(ui->proxyServer->text()); proxy->setPort(ui->proxyPort->text().toInt()); proxy->setUserName(ui->proxyUsername->text()); proxy->setPassword(ui->proxyPassword->text()); if (ui->systemProxy->isChecked()) { proxy->setType(QNetworkProxy::NoProxy); } else { proxy->setType(ui->proxyType->currentIndex() == 0 ? QNetworkProxy::HttpProxy : QNetworkProxy::Socks5Proxy); } return proxy; } void SBI_ProxyWidget::setProxy(const SBI_NetworkProxy &proxy) { ui->proxyServer->setText(proxy.hostName()); ui->proxyPort->setText(QString::number(proxy.port())); ui->proxyUsername->setText(proxy.userName()); ui->proxyPassword->setText(proxy.password()); ui->proxyType->setCurrentIndex(0); switch (proxy.type()) { case QNetworkProxy::NoProxy: ui->systemProxy->setChecked(true); break; case QNetworkProxy::HttpProxy: ui->manualProxy->setChecked(true); ui->proxyType->setCurrentIndex(0); break; case QNetworkProxy::Socks5Proxy: ui->manualProxy->setChecked(true); ui->proxyType->setCurrentIndex(1); break; default: break; } } SBI_ProxyWidget::~SBI_ProxyWidget() { delete ui; } diff --git a/src/plugins/StatusBarIcons/sbi_proxywidget.h b/src/plugins/StatusBarIcons/sbi_proxywidget.h index 3f3c5bb9..3e97c3bd 100644 --- a/src/plugins/StatusBarIcons/sbi_proxywidget.h +++ b/src/plugins/StatusBarIcons/sbi_proxywidget.h @@ -1,47 +1,47 @@ /* ============================================================ -* StatusBarIcons - Extra icons in statusbar for QupZilla +* StatusBarIcons - Extra icons in statusbar for Falkon * Copyright (C) 2013-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef SBI_PROXYWIDGET_H #define SBI_PROXYWIDGET_H #include namespace Ui { class SBI_ProxyWidget; } class SBI_NetworkProxy; class SBI_ProxyWidget : public QWidget { Q_OBJECT public: explicit SBI_ProxyWidget(QWidget* parent = 0); ~SBI_ProxyWidget(); SBI_NetworkProxy* getProxy() const; void setProxy(const SBI_NetworkProxy &proxy); void clear(); private: Ui::SBI_ProxyWidget* ui; }; #endif // SBI_PROXYWIDGET_H diff --git a/src/plugins/StatusBarIcons/sbi_settingsdialog.cpp b/src/plugins/StatusBarIcons/sbi_settingsdialog.cpp index 82311267..8a2aecfa 100644 --- a/src/plugins/StatusBarIcons/sbi_settingsdialog.cpp +++ b/src/plugins/StatusBarIcons/sbi_settingsdialog.cpp @@ -1,54 +1,54 @@ /* ============================================================ -* StatusBarIcons - Extra icons in statusbar for QupZilla +* StatusBarIcons - Extra icons in statusbar for Falkon * Copyright (C) 2013-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "sbi_settingsdialog.h" #include "ui_sbi_settingsdialog.h" #include "sbi_iconsmanager.h" SBI_SettingsDialog::SBI_SettingsDialog(SBI_IconsManager* manager, QWidget* parent) : QDialog(parent) , ui(new Ui::SBI_SettingsDialog) , m_manager(manager) { setAttribute(Qt::WA_DeleteOnClose); ui->setupUi(this); ui->showImagesIcon->setChecked(m_manager->showImagesIcon()); ui->showJavaScriptIcon->setChecked(m_manager->showJavaScriptIcon()); ui->showNetworkIcon->setChecked(m_manager->showNetworkIcon()); ui->showZoomWidget->setChecked(m_manager->showZoomWidget()); connect(ui->buttonBox, SIGNAL(accepted()), this, SLOT(saveSettings())); connect(ui->buttonBox, SIGNAL(rejected()), this, SLOT(close())); } void SBI_SettingsDialog::saveSettings() { m_manager->setShowImagesIcon(ui->showImagesIcon->isChecked()); m_manager->setShowJavaScriptIcon(ui->showJavaScriptIcon->isChecked()); m_manager->setShowNetworkIcon(ui->showNetworkIcon->isChecked()); m_manager->setShowZoomWidget(ui->showZoomWidget->isChecked()); m_manager->reloadIcons(); close(); } SBI_SettingsDialog::~SBI_SettingsDialog() { delete ui; } diff --git a/src/plugins/StatusBarIcons/sbi_settingsdialog.h b/src/plugins/StatusBarIcons/sbi_settingsdialog.h index 1b5fef0b..16545f34 100644 --- a/src/plugins/StatusBarIcons/sbi_settingsdialog.h +++ b/src/plugins/StatusBarIcons/sbi_settingsdialog.h @@ -1,47 +1,47 @@ /* ============================================================ -* StatusBarIcons - Extra icons in statusbar for QupZilla +* StatusBarIcons - Extra icons in statusbar for Falkon * Copyright (C) 2013-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef SBI_SETTINGSDIALOG_H #define SBI_SETTINGSDIALOG_H #include namespace Ui { class SBI_SettingsDialog; } class SBI_IconsManager; class SBI_SettingsDialog : public QDialog { Q_OBJECT public: explicit SBI_SettingsDialog(SBI_IconsManager* manager, QWidget* parent = 0); ~SBI_SettingsDialog(); private slots: void saveSettings(); private: Ui::SBI_SettingsDialog* ui; SBI_IconsManager* m_manager; }; #endif // SBI_SETTINGSDIALOG_H diff --git a/src/plugins/StatusBarIcons/sbi_zoomwidget.cpp b/src/plugins/StatusBarIcons/sbi_zoomwidget.cpp index 1d403b2d..4b5f661c 100644 --- a/src/plugins/StatusBarIcons/sbi_zoomwidget.cpp +++ b/src/plugins/StatusBarIcons/sbi_zoomwidget.cpp @@ -1,60 +1,60 @@ /* ============================================================ -* StatusBarIcons - Extra icons in statusbar for QupZilla +* StatusBarIcons - Extra icons in statusbar for Falkon * Copyright (C) 2014-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "sbi_zoomwidget.h" #include "tabbedwebview.h" #include "browserwindow.h" #include "tabwidget.h" SBI_ZoomWidget::SBI_ZoomWidget(BrowserWindow* parent) : QSlider(parent) , m_window(parent) { setObjectName(QSL("sbi_zoomwidget")); setOrientation(Qt::Horizontal); setFixedWidth(100); setMaximumHeight(20); setPageStep(2); setSingleStep(1); setRange(0, WebView::zoomLevels().count() - 1); connect(this, SIGNAL(valueChanged(int)), this, SLOT(valueChanged(int))); connect(m_window->tabWidget(), SIGNAL(currentChanged(int)), this, SLOT(currentViewChanged())); currentViewChanged(); } void SBI_ZoomWidget::valueChanged(int value) { TabbedWebView* view = m_window->weView(); if (view) { view->setZoomLevel(value); setToolTip(tr("Zoom: %1%").arg(view->zoomFactor() * 100)); } } void SBI_ZoomWidget::currentViewChanged() { TabbedWebView* view = m_window->weView(); if (view) { connect(view, SIGNAL(zoomLevelChanged(int)), this, SLOT(setValue(int))); setValue(view->zoomLevel()); } } diff --git a/src/plugins/StatusBarIcons/sbi_zoomwidget.h b/src/plugins/StatusBarIcons/sbi_zoomwidget.h index 086ff483..c2e583ba 100644 --- a/src/plugins/StatusBarIcons/sbi_zoomwidget.h +++ b/src/plugins/StatusBarIcons/sbi_zoomwidget.h @@ -1,40 +1,40 @@ /* ============================================================ -* StatusBarIcons - Extra icons in statusbar for QupZilla +* StatusBarIcons - Extra icons in statusbar for Falkon * Copyright (C) 2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef SBI_ZOOMWIDGET_H #define SBI_ZOOMWIDGET_H #include class BrowserWindow; class SBI_ZoomWidget : public QSlider { Q_OBJECT public: explicit SBI_ZoomWidget(BrowserWindow* parent = 0); private slots: void valueChanged(int value); void currentViewChanged(); private: BrowserWindow* m_window; }; #endif // SBI_ZOOMWIDGET_H diff --git a/src/plugins/StatusBarIcons/statusbariconsplugin.cpp b/src/plugins/StatusBarIcons/statusbariconsplugin.cpp index 372d9879..53e7e4f2 100644 --- a/src/plugins/StatusBarIcons/statusbariconsplugin.cpp +++ b/src/plugins/StatusBarIcons/statusbariconsplugin.cpp @@ -1,90 +1,90 @@ /* ============================================================ * StatusBarIcons - Extra icons in statusbar for QupZilla * Copyright (C) 2013-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "statusbariconsplugin.h" #include "sbi_iconsmanager.h" #include "sbi_settingsdialog.h" #include "pluginproxy.h" #include "browserwindow.h" #include StatusBarIconsPlugin::StatusBarIconsPlugin() : QObject() , m_manager(0) { } PluginSpec StatusBarIconsPlugin::pluginSpec() { PluginSpec spec; spec.name = "StatusBar Icons"; spec.info = "Icons in statusbar providing various actions"; spec.description = "Adds additional icons and zoom widget to statusbar"; spec.version = "0.2.0"; spec.author = "David Rosca "; spec.icon = QPixmap(":sbi/data/icon.png"); spec.hasSettings = true; return spec; } void StatusBarIconsPlugin::init(InitState state, const QString &settingsPath) { m_manager = new SBI_IconsManager(settingsPath); connect(mApp->plugins(), SIGNAL(mainWindowCreated(BrowserWindow*)), m_manager, SLOT(mainWindowCreated(BrowserWindow*))); connect(mApp->plugins(), SIGNAL(mainWindowDeleted(BrowserWindow*)), m_manager, SLOT(mainWindowDeleted(BrowserWindow*))); // Make sure icons are added also to already created windows if (state == LateInitState) { foreach (BrowserWindow* window, mApp->windows()) { m_manager->mainWindowCreated(window); } } } void StatusBarIconsPlugin::unload() { // Make sure icons are properly removed when unloading plugin (but not when closing app) if (!mApp->isClosing()) { foreach (BrowserWindow* window, mApp->windows()) { m_manager->mainWindowDeleted(window); } delete m_manager; } } bool StatusBarIconsPlugin::testPlugin() { // Require the version that the plugin was built with - return (Qz::VERSION == QLatin1String(QUPZILLA_VERSION)); + return (Qz::VERSION == QLatin1String(FALKON_VERSION)); } QTranslator* StatusBarIconsPlugin::getTranslator(const QString &locale) { QTranslator* translator = new QTranslator(this); translator->load(locale, ":/sbi/locale/"); return translator; } void StatusBarIconsPlugin::showSettings(QWidget* parent) { SBI_SettingsDialog* dialog = new SBI_SettingsDialog(m_manager, parent); dialog->open(); } diff --git a/src/plugins/StatusBarIcons/statusbariconsplugin.h b/src/plugins/StatusBarIcons/statusbariconsplugin.h index 422a710d..37079503 100644 --- a/src/plugins/StatusBarIcons/statusbariconsplugin.h +++ b/src/plugins/StatusBarIcons/statusbariconsplugin.h @@ -1,47 +1,47 @@ /* ============================================================ * StatusBarIcons - Extra icons in statusbar for QupZilla * Copyright (C) 2013-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef STATUSBARICONSPLUGIN_H #define STATUSBARICONSPLUGIN_H #include "plugininterface.h" class SBI_IconsManager; class StatusBarIconsPlugin : public QObject, public PluginInterface { Q_OBJECT Q_INTERFACES(PluginInterface) - Q_PLUGIN_METADATA(IID "QupZilla.Browser.plugin.StatusBarIcons") + Q_PLUGIN_METADATA(IID "Falkon.Browser.plugin.StatusBarIcons") public: explicit StatusBarIconsPlugin(); PluginSpec pluginSpec(); void init(InitState state, const QString &settingsPath); void unload(); bool testPlugin(); QTranslator* getTranslator(const QString &locale); void showSettings(QWidget* parent = 0); private: SBI_IconsManager* m_manager; }; #endif // STATUSBARICONSPLUGIN_H diff --git a/src/plugins/TabManager/tabmanagerdelegate.cpp b/src/plugins/TabManager/tabmanagerdelegate.cpp index 21add911..0a233416 100644 --- a/src/plugins/TabManager/tabmanagerdelegate.cpp +++ b/src/plugins/TabManager/tabmanagerdelegate.cpp @@ -1,280 +1,280 @@ /* ============================================================ -* QupZilla - Qt web browser +* Falkon - Qt web browser * Copyright (C) 2016-2017 S. Razi Alavizadeh * Copyright (C) 2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "tabmanagerdelegate.h" #include #include #include TabManagerDelegate::TabManagerDelegate(QObject* parent) : QStyledItemDelegate(parent) { } // most of codes taken from QCommonStyle::drawControl() and add our custom text drawer void TabManagerDelegate::paint(QPainter* painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { QStyleOptionViewItem opt = option; initStyleOption(&opt, index); const QWidget* w = opt.widget; const QStyle* style = w ? w->style() : QApplication::style(); const Qt::LayoutDirection direction = w ? w->layoutDirection() : QApplication::layoutDirection(); const QPalette::ColorRole colorRole = opt.state & QStyle::State_Selected ? QPalette::HighlightedText : QPalette::Text; QPalette::ColorGroup cg = opt.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled; if (cg == QPalette::Normal && !(opt.state & QStyle::State_Active)) { cg = QPalette::Inactive; } #ifdef Q_OS_WIN opt.palette.setColor(QPalette::All, QPalette::HighlightedText, opt.palette.color(QPalette::Active, QPalette::Text)); opt.palette.setColor(QPalette::All, QPalette::Highlight, opt.palette.base().color().darker(108)); #endif QPalette textPalette = opt.palette; textPalette.setCurrentColorGroup(cg); painter->save(); painter->setClipRect(opt.rect); QRect checkRect = style->subElementRect(QStyle::SE_ItemViewItemCheckIndicator, &opt, w); QRect iconRect = style->subElementRect(QStyle::SE_ItemViewItemDecoration, &opt, w); QRect textRect = style->subElementRect(QStyle::SE_ItemViewItemText, &opt, w); // draw the background style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, w); // draw close button if (index.column() == 1) { if (opt.state & QStyle::State_MouseOver) { static const int buttonSize = 16; static const QPixmap closeTabButton(":tabmanager/data/closetab.png"); static const QPixmap addTabButton(":tabmanager/data/addtab.png"); const QRect rect(opt.rect.right() - buttonSize, (opt.rect.height() - buttonSize) / 2 + opt.rect.y(), buttonSize, buttonSize); painter->drawPixmap(style->visualRect(direction, opt.rect, rect), (index.parent().isValid() ? closeTabButton : addTabButton)); } painter->restore(); return; } // draw the check mark if (opt.features & QStyleOptionViewItem::HasCheckIndicator) { QStyleOptionViewItem opt2(opt); opt2.rect = checkRect; opt2.state = opt2.state & ~QStyle::State_HasFocus; switch (opt.checkState) { case Qt::Unchecked: opt2.state |= QStyle::State_Off; break; case Qt::PartiallyChecked: opt2.state |= QStyle::State_NoChange; break; case Qt::Checked: opt2.state |= QStyle::State_On; break; } style->drawPrimitive(QStyle::PE_IndicatorViewItemCheck, &opt2, painter, w); } // draw the icon QIcon::Mode mode = QIcon::Normal; if (!(opt.state & QStyle::State_Enabled)) mode = QIcon::Disabled; else if (opt.state & QStyle::State_Selected) mode = QIcon::Selected; QIcon::State state = opt.state & QStyle::State_Open ? QIcon::On : QIcon::Off; opt.icon.paint(painter, iconRect, opt.decorationAlignment, mode, state); // draw the text if (!opt.text.isEmpty()) { const QString filterText = property("filterText").toString(); QPalette::ColorGroup cg = opt.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled; if (cg == QPalette::Normal && !(opt.state & QStyle::State_Active)) cg = QPalette::Inactive; if (opt.state & QStyle::State_Selected) { painter->setPen(opt.palette.color(cg, QPalette::HighlightedText)); } else { painter->setPen(opt.palette.color(cg, QPalette::Text)); } if (opt.state & QStyle::State_Editing) { painter->setPen(opt.palette.color(cg, QPalette::Text)); painter->drawRect(textRect.adjusted(0, 0, -1, -1)); } painter->setFont(opt.font); viewItemDrawText(painter, &opt, textRect, opt.text, textPalette.color(colorRole), filterText); } painter->restore(); } static bool sizeBiggerThan(const QString &s1, const QString &s2) { return s1.size() > s2.size(); } static QSizeF viewItemTextLayout(QTextLayout &textLayout, int lineWidth) { qreal height = 0; qreal widthUsed = 0; textLayout.beginLayout(); QTextLine line = textLayout.createLine(); if (line.isValid()) { line.setLineWidth(lineWidth); line.setPosition(QPointF(0, height)); height += line.height(); widthUsed = qMax(widthUsed, line.naturalTextWidth()); textLayout.endLayout(); } return QSizeF(widthUsed, height); } // most of codes taken from QCommonStylePrivate::viewItemDrawText() // added highlighting and simplified for single-line textlayouts void TabManagerDelegate::viewItemDrawText(QPainter *p, const QStyleOptionViewItem *option, const QRect &rect, const QString &text, const QColor &color, const QString &searchText) const { if (text.isEmpty()) { return; } const QWidget* widget = option->widget; const bool isRtlLayout = widget ? widget->isRightToLeft() : QApplication::isRightToLeft(); const QStyle* proxyStyle = widget ? widget->style()->proxy() : QApplication::style()->proxy(); const int textMargin = proxyStyle->pixelMetric(QStyle::PM_FocusFrameHMargin, 0, widget) + 1; QRect textRect = rect.adjusted(textMargin, 0, -textMargin, 0); // remove width padding const QFontMetrics fontMetrics(p->font()); QString elidedText = fontMetrics.elidedText(text, option->textElideMode, textRect.width()); QTextOption textOption; textOption.setWrapMode(QTextOption::NoWrap); textOption.setTextDirection(text.isRightToLeft() ? Qt::RightToLeft : Qt::LeftToRight); textOption.setAlignment(Qt::AlignVCenter | (isRtlLayout ? Qt::AlignRight : Qt::AlignLeft)); QTextLayout textLayout; textLayout.setFont(p->font()); textLayout.setText(elidedText); textLayout.setTextOption(textOption); if (!searchText.isEmpty()) { QList delimiters; QStringList searchStrings = searchText.split(QLatin1Char(' '), QString::SkipEmptyParts); // Look for longer parts first std::sort(searchStrings.begin(), searchStrings.end(), sizeBiggerThan); foreach (const QString &string, searchStrings) { int delimiter = text.indexOf(string, 0, Qt::CaseInsensitive); while (delimiter != -1) { int start = delimiter; int end = delimiter + string.length(); bool alreadyContains = false; for (int i = 0; i < delimiters.count(); ++i) { int dStart = delimiters.at(i); int dEnd = delimiters.at(++i); if (dStart <= start && dEnd >= end) { alreadyContains = true; break; } } if (!alreadyContains) { delimiters.append(start); delimiters.append(end); } delimiter = text.indexOf(string, end, Qt::CaseInsensitive); } } // We need to sort delimiters to properly paint all parts that user typed std::sort(delimiters.begin(), delimiters.end()); // If we don't find any match, just paint it without any highlight if (!delimiters.isEmpty() && !(delimiters.count() % 2)) { QList highlightParts; QTextLayout::FormatRange lighterWholeLine; lighterWholeLine.start = 0; lighterWholeLine.length = elidedText.size(); QColor lighterColor = color.lighter(130); if (lighterColor == color) { lighterColor = QColor(Qt::gray).darker(180); } lighterWholeLine.format.setForeground(lighterColor); highlightParts << lighterWholeLine; while (!delimiters.isEmpty()) { QTextLayout::FormatRange highlightedPart; int start = delimiters.takeFirst(); int end = delimiters.takeFirst(); highlightedPart.start = start; highlightedPart.length = end - start; highlightedPart.format.setFontWeight(QFont::Bold); highlightedPart.format.setUnderlineStyle(QTextCharFormat::SingleUnderline); highlightedPart.format.setForeground(color); highlightParts << highlightedPart; } textLayout.setAdditionalFormats(highlightParts); } } // do layout viewItemTextLayout(textLayout, textRect.width()); if (textLayout.lineCount() <= 0) { return; } QTextLine textLine = textLayout.lineAt(0); // if elidedText after highlighting is longer // than available width then re-elide it and redo layout int diff = textLine.naturalTextWidth() - textRect.width(); if (diff > 0) { elidedText = fontMetrics.elidedText(elidedText, option->textElideMode, textRect.width() - diff); textLayout.setText(elidedText); // redo layout viewItemTextLayout(textLayout, textRect.width()); if (textLayout.lineCount() <= 0) { return; } textLine = textLayout.lineAt(0); } // draw line p->setPen(color); qreal width = qMax(textRect.width(), textLayout.lineAt(0).width()); const QRect &layoutRect = QStyle::alignedRect(option->direction, option->displayAlignment, QSize(int(width), int(textLine.height())), textRect); const QPointF &position = layoutRect.topLeft(); textLine.draw(p, position); } diff --git a/src/plugins/TabManager/tabmanagerdelegate.h b/src/plugins/TabManager/tabmanagerdelegate.h index 5b76db25..f8a08bce 100644 --- a/src/plugins/TabManager/tabmanagerdelegate.h +++ b/src/plugins/TabManager/tabmanagerdelegate.h @@ -1,39 +1,39 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2016-2017 S. Razi Alavizadeh * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef TABMANAGERDELEGATE_H #define TABMANAGERDELEGATE_H #include class TabManagerDelegate : public QStyledItemDelegate { public: explicit TabManagerDelegate(QObject* parent = 0); void paint(QPainter* painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; private: void viewItemDrawText(QPainter *p, const QStyleOptionViewItem *option, const QRect &rect, const QString &text, const QColor &color, const QString &searchText = QString()) const; QString m_filterText; }; #endif // TABMANAGERDELEGATE_H diff --git a/src/plugins/TabManager/tabmanagerplugin.cpp b/src/plugins/TabManager/tabmanagerplugin.cpp index 98c7512f..8647af99 100644 --- a/src/plugins/TabManager/tabmanagerplugin.cpp +++ b/src/plugins/TabManager/tabmanagerplugin.cpp @@ -1,239 +1,239 @@ /* ============================================================ * TabManager plugin for QupZilla * Copyright (C) 2013-2017 S. Razi Alavizadeh * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "tabmanagerplugin.h" #include "tabmanagerwidgetcontroller.h" #include "tabmanagerwidget.h" #include "browserwindow.h" #include "pluginproxy.h" #include "mainapplication.h" #include "sidebar.h" #include "tabwidget.h" #include "tabbar.h" #include "tabmanagersettings.h" #include #include #include #include #include #include QString TabManagerPlugin::s_settingsPath; TabManagerPlugin::TabManagerPlugin() : QObject() , m_controller(0) , m_tabManagerWidget(0) , m_viewType(Undefined) , m_initState(false) , m_asTabBarReplacement(false) { } PluginSpec TabManagerPlugin::pluginSpec() { PluginSpec spec; spec.name = "Tab Manager"; - spec.info = "Simple yet powerful tab manager for QupZilla"; + spec.info = "Simple yet powerful tab manager for Falkon"; spec.description = "Adds ability to managing tabs and windows"; spec.version = "0.7.0"; spec.author = "Razi Alavizadeh "; spec.icon = QPixmap(":tabmanager/data/tabmanager.png"); spec.hasSettings = true; return spec; } void TabManagerPlugin::init(InitState state, const QString &settingsPath) { Q_UNUSED(state) m_controller = new TabManagerWidgetController(this); connect(mApp->plugins(), SIGNAL(mainWindowCreated(BrowserWindow*)), this, SLOT(mainWindowCreated(BrowserWindow*))); connect(mApp->plugins(), SIGNAL(mainWindowDeleted(BrowserWindow*)), m_controller, SLOT(mainWindowDeleted(BrowserWindow*))); connect(mApp->plugins(), SIGNAL(webPageCreated(WebPage*)), m_controller, SIGNAL(requestRefreshTree())); connect(mApp->plugins(), SIGNAL(webPageDeleted(WebPage*)), m_controller, SIGNAL(requestRefreshTree(WebPage*))); s_settingsPath = settingsPath + QL1S("/TabManager"); m_initState = true; // load settings QSettings settings(s_settingsPath + QL1S("/tabmanager.ini"), QSettings::IniFormat); settings.beginGroup("View"); m_controller->setGroupType(TabManagerWidget::GroupType(settings.value("GroupType", TabManagerWidget::GroupByWindow).toInt())); m_viewType = ViewType(settings.value("ViewType", ShowAsWindow).toInt()); m_asTabBarReplacement = settings.value("AsTabBarReplacement", false).toBool(); settings.endGroup(); setAsTabBarReplacement(m_asTabBarReplacement); insertManagerWidget(); } void TabManagerPlugin::unload() { saveSettings(); setTabBarVisible(true); removeManagerWidget(); delete m_controller; } bool TabManagerPlugin::testPlugin() { - return (Qz::VERSION == QLatin1String(QUPZILLA_VERSION)); + return (Qz::VERSION == QLatin1String(FALKON_VERSION)); } QTranslator* TabManagerPlugin::getTranslator(const QString &locale) { QTranslator* translator = new QTranslator(this); translator->load(locale, ":/tabmanager/locale/"); return translator; } void TabManagerPlugin::showSettings(QWidget* parent) { TabManagerSettings* settings = new TabManagerSettings(this, parent); settings->exec(); } void TabManagerPlugin::populateExtensionsMenu(QMenu* menu) { if (viewType() == ShowAsWindow) { QAction* showAction = m_controller->createMenuAction(); showAction->setCheckable(false); connect(showAction, SIGNAL(triggered()), m_controller, SLOT(raiseTabManager())); menu->addAction(showAction); } } void TabManagerPlugin::insertManagerWidget() { if (viewType() == ShowAsSideBar) { SideBarManager::addSidebar("TabManager", m_controller); } else if (viewType() == ShowAsWindow) { if (!m_tabManagerWidget) { m_tabManagerWidget = m_controller->createTabManagerWidget(mApp->getWindow(), 0, true); m_tabManagerWidget->setWindowFlags(Qt::Window); } } if (m_initState) { foreach (BrowserWindow* window, mApp->windows()) { mainWindowCreated(window, false); } m_initState = false; } } void TabManagerPlugin::mainWindowCreated(BrowserWindow* window, bool refresh) { if (window) { window->tabWidget()->tabBar()->setForceHidden(m_asTabBarReplacement); if (m_viewType == ShowAsWindow) { m_controller->addStatusBarIcon(window); } connect(window->tabWidget(), SIGNAL(currentChanged(int)), m_controller, SIGNAL(requestRefreshTree())); connect(window->tabWidget(), SIGNAL(pinStateChanged(int,bool)), m_controller, SIGNAL(pinStateChanged(int,bool))); } if (refresh) { m_controller->emitRefreshTree(); } } void TabManagerPlugin::setTabBarVisible(bool visible) { foreach (BrowserWindow* window, mApp->windows()) { window->tabWidget()->tabBar()->setForceHidden(!visible); } } void TabManagerPlugin::removeManagerWidget() { if (viewType() == ShowAsSideBar) { SideBarManager::removeSidebar("TabManager"); } else if (viewType() == ShowAsWindow) { // remove statusbar icon foreach (BrowserWindow* window, mApp->windows()) { m_controller->removeStatusBarIcon(window); } m_tabManagerWidget->close(); delete m_tabManagerWidget; m_tabManagerWidget = 0; } } TabManagerPlugin::ViewType TabManagerPlugin::viewType() { return m_viewType; } void TabManagerPlugin::setViewType(ViewType type) { if (m_viewType != type) { removeManagerWidget(); m_viewType = type; insertManagerWidget(); if (!m_initState) { if (m_viewType == ShowAsSideBar) { mApp->getWindow()->sideBarManager()->showSideBar("TabManager"); } else if (m_viewType == ShowAsWindow) { // add statusbar icon foreach (BrowserWindow* window, mApp->windows()) { m_controller->addStatusBarIcon(window); } } } } } QString TabManagerPlugin::settingsPath() { return s_settingsPath; } void TabManagerPlugin::saveSettings() { QSettings settings(s_settingsPath + QL1S("/tabmanager.ini"), QSettings::IniFormat); settings.beginGroup("View"); settings.setValue("GroupType", m_controller->groupType()); settings.setValue("ViewType", viewType()); settings.setValue("AsTabBarReplacement", asTabBarReplacement()); settings.endGroup(); } bool TabManagerPlugin::asTabBarReplacement() const { return m_asTabBarReplacement; } void TabManagerPlugin::setAsTabBarReplacement(bool yes) { m_asTabBarReplacement = yes; setTabBarVisible(!m_asTabBarReplacement); } diff --git a/src/plugins/TabManager/tabmanagerplugin.h b/src/plugins/TabManager/tabmanagerplugin.h index b0a41048..be89cb41 100644 --- a/src/plugins/TabManager/tabmanagerplugin.h +++ b/src/plugins/TabManager/tabmanagerplugin.h @@ -1,85 +1,85 @@ /* ============================================================ * TabManager plugin for QupZilla * Copyright (C) 2013-2017 S. Razi Alavizadeh * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef TABMANAGERPLUGIN_H #define TABMANAGERPLUGIN_H #include "plugininterface.h" #include "tabmanagerwidgetcontroller.h" #include #include #include #include #include class TabManagerWidget; class TabManagerPlugin : public QObject, public PluginInterface { Q_OBJECT Q_INTERFACES(PluginInterface) - Q_PLUGIN_METADATA(IID "QupZilla.Browser.plugin.TabManagerPlugin") + Q_PLUGIN_METADATA(IID "Falkon.Browser.plugin.TabManagerPlugin") public: explicit TabManagerPlugin(); PluginSpec pluginSpec(); void init(InitState state, const QString &settingsPath); void unload(); bool testPlugin(); QTranslator* getTranslator(const QString &locale); void showSettings(QWidget* parent = 0); void populateExtensionsMenu(QMenu* menu); enum ViewType { ShowAsSideBar = 0, ShowAsWindow = 1, Undefined = -1 }; void removeManagerWidget(); ViewType viewType(); void setViewType(ViewType type); static QString settingsPath(); void saveSettings(); bool asTabBarReplacement() const; void setAsTabBarReplacement(bool yes); public slots: void insertManagerWidget(); private slots: void mainWindowCreated(BrowserWindow* window, bool refresh = true); private: void setTabBarVisible(bool visible); TabManagerWidgetController* m_controller; TabManagerWidget* m_tabManagerWidget; static QString s_settingsPath; ViewType m_viewType; bool m_initState; bool m_asTabBarReplacement; }; #endif // TABMANAGERPLUGIN_H diff --git a/src/plugins/TabManager/tabmanagerwidget.cpp b/src/plugins/TabManager/tabmanagerwidget.cpp index 4c1f202b..9146cdc8 100644 --- a/src/plugins/TabManager/tabmanagerwidget.cpp +++ b/src/plugins/TabManager/tabmanagerwidget.cpp @@ -1,731 +1,731 @@ /* ============================================================ * TabManager plugin for QupZilla * Copyright (C) 2013-2017 S. Razi Alavizadeh * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "tabmanagerwidget.h" #include "ui_tabmanagerwidget.h" #include "mainapplication.h" #include "browserwindow.h" #include "webtab.h" #include "webpage.h" #include "tabbedwebview.h" #include "tabwidget.h" #include "locationbar.h" #include "bookmarkstools.h" #include "bookmarkitem.h" #include "bookmarks.h" #include "tabmanagerplugin.h" #include "tldextractor/tldextractor.h" #include "tabmanagerdelegate.h" #include #include #include #include #include #include TLDExtractor* TabManagerWidget::s_tldExtractor = 0; TabManagerWidget::TabManagerWidget(BrowserWindow* mainClass, QWidget* parent, bool defaultWidget) : QWidget(parent) , ui(new Ui::TabManagerWidget) - , p_QupZilla(mainClass) + , m_window(mainClass) , m_webPage(0) , m_isRefreshing(false) , m_refreshBlocked(false) , m_waitForRefresh(false) , m_isDefaultWidget(defaultWidget) { if(s_tldExtractor == 0) { s_tldExtractor = TLDExtractor::instance(); s_tldExtractor->setDataSearchPaths(QStringList() << TabManagerPlugin::settingsPath()); } ui->setupUi(this); ui->treeWidget->setUniformRowHeights(true); ui->treeWidget->setColumnCount(2); ui->treeWidget->header()->hide(); ui->treeWidget->header()->setStretchLastSection(false); ui->treeWidget->header()->setSectionResizeMode(0, QHeaderView::Stretch); ui->treeWidget->header()->setSectionResizeMode(1, QHeaderView::Fixed); ui->treeWidget->header()->resizeSection(1, 16); ui->treeWidget->setExpandsOnDoubleClick(false); ui->treeWidget->setContextMenuPolicy(Qt::CustomContextMenu); ui->treeWidget->installEventFilter(this); ui->filterBar->installEventFilter(this); QPushButton* closeButton = new QPushButton(ui->filterBar); closeButton->setFlat(true); closeButton->setIcon(style()->standardIcon(QStyle::SP_TitleBarCloseButton)); ui->filterBar->addWidget(closeButton, LineEdit::RightSide); ui->filterBar->hide(); ui->treeWidget->setItemDelegate(new TabManagerDelegate(ui->treeWidget)); connect(closeButton, SIGNAL(clicked(bool)), this, SLOT(filterBarClosed())); connect(ui->filterBar, SIGNAL(textChanged(QString)), this, SLOT(filterChanged(QString))); connect(ui->treeWidget, SIGNAL(itemClicked(QTreeWidgetItem*,int)), this, SLOT(onItemActivated(QTreeWidgetItem*,int))); connect(ui->treeWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(customContextMenuRequested(QPoint))); } TabManagerWidget::~TabManagerWidget() { delete ui; } void TabManagerWidget::setGroupType(GroupType type) { m_groupType = type; } QString TabManagerWidget::domainFromUrl(const QUrl &url, bool useHostName) { QString appendString = QL1S(":"); QString urlString = url.toString(); if (url.scheme() == "file") { return tr("Local File System:"); } - else if (url.scheme() == "qupzilla" || urlString.isEmpty()) { - return tr("QupZilla:"); + else if (url.scheme() == "falkon" || urlString.isEmpty()) { + return tr("Falkon:"); } else if (url.scheme() == "ftp") { appendString.prepend(tr(" [FTP]")); } QString host = url.host(); if (host.isEmpty()) { return urlString.append(appendString); } if (useHostName || host.contains(QRegExp("^[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+$"))) { if (host.startsWith("www.", Qt::CaseInsensitive)) { host.remove(0, 4); } return host.append(appendString); } else { const QString registeredDomain = s_tldExtractor->registrableDomain(host); if (!registeredDomain.isEmpty()) { host = registeredDomain; } return host.append(appendString); } } void TabManagerWidget::delayedRefreshTree(WebPage* p) { if (m_refreshBlocked || m_waitForRefresh) { return; } if (m_isRefreshing && !p) { return; } m_webPage = p; m_waitForRefresh = true; QTimer::singleShot(50, this, SLOT(refreshTree())); } void TabManagerWidget::refreshTree() { if (m_refreshBlocked) { return; } if (m_isRefreshing && !m_webPage) { return; } // store selected items QList selectedTabs; for (int i = 0; i < ui->treeWidget->topLevelItemCount(); ++i) { QTreeWidgetItem* winItem = ui->treeWidget->topLevelItem(i); if (winItem->checkState(0) == Qt::Unchecked) { continue; } for (int j = 0; j < winItem->childCount(); ++j) { QTreeWidgetItem* tabItem = winItem->child(j); if (tabItem->checkState(0) == Qt::Unchecked) { continue; } selectedTabs << qvariant_cast(tabItem->data(0, WebTabPointerRole)); } } ui->treeWidget->clear(); if (m_groupType == GroupByHost) { groupByDomainName(true); } else if (m_groupType == GroupByDomain) { groupByDomainName(); } else { // fallback to GroupByWindow m_groupType = GroupByWindow; groupByWindow(); } // restore selected items for (int i = 0; i < ui->treeWidget->topLevelItemCount(); ++i) { QTreeWidgetItem* winItem = ui->treeWidget->topLevelItem(i); for (int j = 0; j < winItem->childCount(); ++j) { QTreeWidgetItem* tabItem = winItem->child(j); if (selectedTabs.contains(qvariant_cast(tabItem->data(0, WebTabPointerRole)))) { tabItem->setCheckState(0, Qt::Checked); } } } filterChanged(m_filterText, true); ui->treeWidget->expandAll(); m_isRefreshing = false; m_waitForRefresh = false; } void TabManagerWidget::onItemActivated(QTreeWidgetItem* item, int column) { if (!item) { return; } - BrowserWindow* mainWindow = qobject_cast(qvariant_cast(item->data(0, QupZillaPointerRole))); + BrowserWindow* mainWindow = qobject_cast(qvariant_cast(item->data(0, BrowserWindowPointerRole))); QWidget* tabWidget = qvariant_cast(item->data(0, WebTabPointerRole)); if (column == 1) { if (item->childCount() > 0) QMetaObject::invokeMethod(mainWindow ? mainWindow : mApp->getWindow(), "addTab"); else if (tabWidget && mainWindow) mainWindow->tabWidget()->requestCloseTab(mainWindow->tabWidget()->indexOf(tabWidget)); return; } if (!mainWindow) { return; } if (mainWindow->isMinimized()) { mainWindow->showNormal(); } else { mainWindow->show(); } mainWindow->activateWindow(); mainWindow->raise(); mainWindow->weView()->setFocus(); if (tabWidget && tabWidget != mainWindow->tabWidget()->currentWidget()) { mainWindow->tabWidget()->setCurrentIndex(mainWindow->tabWidget()->indexOf(tabWidget)); } } bool TabManagerWidget::isTabSelected() { bool selected = false; for (int i = 0; i < ui->treeWidget->topLevelItemCount(); ++i) { QTreeWidgetItem* parentItem = ui->treeWidget->topLevelItem(i); if (parentItem->checkState(0) != Qt::Unchecked) { selected = true; break; } } return selected; } void TabManagerWidget::customContextMenuRequested(const QPoint &pos) { QMenu menu; QAction* action; QMenu groupTypeSubmenu(tr("Group by")); action = groupTypeSubmenu.addAction(tr("&Window"), this, SLOT(changeGroupType())); action->setData(GroupByWindow); action->setCheckable(true); action->setChecked(m_groupType == GroupByWindow); action = groupTypeSubmenu.addAction(tr("&Domain"), this, SLOT(changeGroupType())); action->setData(GroupByDomain); action->setCheckable(true); action->setChecked(m_groupType == GroupByDomain); action = groupTypeSubmenu.addAction(tr("&Host"), this, SLOT(changeGroupType())); action->setData(GroupByHost); action->setCheckable(true); action->setChecked(m_groupType == GroupByHost); menu.addMenu(&groupTypeSubmenu); if (m_isDefaultWidget) { menu.addAction(QIcon(":/tabmanager/data/side-by-side.png"), tr("&Show side by side"), this, SIGNAL(showSideBySide()))->setObjectName("sideBySide"); } menu.addSeparator(); if (isTabSelected()) { menu.addAction(QIcon(":/tabmanager/data/tab-detach.png"), tr("&Detach checked tabs"), this, SLOT(processActions()))->setObjectName("detachSelection"); menu.addAction(QIcon(":/tabmanager/data/tab-bookmark.png"), tr("Book&mark checked tabs"), this, SLOT(processActions()))->setObjectName("bookmarkSelection"); menu.addAction(QIcon(":/tabmanager/data/tab-close.png"), tr("&Close checked tabs"), this, SLOT(processActions()))->setObjectName("closeSelection"); } menu.exec(ui->treeWidget->viewport()->mapToGlobal(pos)); } void TabManagerWidget::filterChanged(const QString &filter, bool force) { if (force || filter != m_filterText) { m_filterText = filter.simplified(); ui->treeWidget->itemDelegate()->setProperty("filterText", m_filterText); if (m_filterText.isEmpty()) { for (int i = 0; i < ui->treeWidget->topLevelItemCount(); ++i) { QTreeWidgetItem* parentItem = ui->treeWidget->topLevelItem(i); for (int j = 0; j < parentItem->childCount(); ++j) { QTreeWidgetItem* childItem = parentItem->child(j); childItem->setHidden(false); } parentItem->setHidden(false); parentItem->setExpanded(true); } return; } const QRegularExpression filterRegExp(filter.simplified().replace(QChar(' '), QLatin1String(".*")) .append(QLatin1String(".*")).prepend(QLatin1String(".*")), QRegularExpression::CaseInsensitiveOption); for (int i = 0; i < ui->treeWidget->topLevelItemCount(); ++i) { QTreeWidgetItem* parentItem = ui->treeWidget->topLevelItem(i); int visibleChildCount = 0; for (int j = 0; j < parentItem->childCount(); ++j) { QTreeWidgetItem* childItem = parentItem->child(j); if (childItem->text(0).contains(filterRegExp) || childItem->data(0, UrlRole).toString().simplified().contains(filterRegExp)) { ++visibleChildCount; childItem->setHidden(false); } else { childItem->setHidden(true); } } if (visibleChildCount == 0) { parentItem->setHidden(true); } else { parentItem->setHidden(false); parentItem->setExpanded(true); } } } } void TabManagerWidget::filterBarClosed() { ui->filterBar->clear(); ui->filterBar->hide(); ui->treeWidget->setFocusProxy(0); ui->treeWidget->setFocus(); } bool TabManagerWidget::eventFilter(QObject* obj, QEvent* event) { if (event->type() == QEvent::KeyPress) { QKeyEvent *keyEvent = static_cast(event); const QString text = keyEvent->text().simplified(); if (obj == ui->treeWidget) { // switch to tab/window on enter if (keyEvent->key() == Qt::Key_Enter || keyEvent->key() == Qt::Key_Return) { onItemActivated(ui->treeWidget->currentItem(), 0); return QObject::eventFilter(obj, event); } if (!text.isEmpty() || ((keyEvent->modifiers() & Qt::ControlModifier) && keyEvent->key() == Qt::Key_F)) { ui->filterBar->show(); ui->treeWidget->setFocusProxy(ui->filterBar); ui->filterBar->setFocus(); if (!text.isEmpty() && text.at(0).isPrint()) { ui->filterBar->setText(ui->filterBar->text() + text); } return true; } } else if (obj == ui->filterBar) { bool isNavigationOrActionKey = keyEvent->key() == Qt::Key_Up || keyEvent->key() == Qt::Key_Down || keyEvent->key() == Qt::Key_PageDown || keyEvent->key() == Qt::Key_PageUp || keyEvent->key() == Qt::Key_Enter || keyEvent->key() == Qt::Key_Return; // send scroll or action press key to treeWidget if (isNavigationOrActionKey) { QKeyEvent ev(QKeyEvent::KeyPress, keyEvent->key(), keyEvent->modifiers()); QApplication::sendEvent(ui->treeWidget, &ev); return false; } } } if (obj == ui->treeWidget && (event->type() == QEvent::Resize || event->type() == QEvent::Show)) ui->treeWidget->setColumnHidden(1, ui->treeWidget->viewport()->width() < 150); return QObject::eventFilter(obj, event); } void TabManagerWidget::processActions() { if (!sender()) { return; } m_refreshBlocked = true; QHash selectedTabs; const QString &command = sender()->objectName(); for (int i = 0; i < ui->treeWidget->topLevelItemCount(); ++i) { QTreeWidgetItem* winItem = ui->treeWidget->topLevelItem(i); if (winItem->checkState(0) == Qt::Unchecked) { continue; } for (int j = 0; j < winItem->childCount(); ++j) { QTreeWidgetItem* tabItem = winItem->child(j); if (tabItem->checkState(0) == Qt::Unchecked) { continue; } - BrowserWindow* mainWindow = qobject_cast(qvariant_cast(tabItem->data(0, QupZillaPointerRole))); + BrowserWindow* mainWindow = qobject_cast(qvariant_cast(tabItem->data(0, BrowserWindowPointerRole))); WebTab* webTab = qobject_cast(qvariant_cast(tabItem->data(0, WebTabPointerRole))); // current supported actions are not applied to pinned tabs if (webTab->isPinned()) { tabItem->setCheckState(0, Qt::Unchecked); continue; } if (command == "closeSelection") { - if (webTab->url().toString() == "qupzilla:restore") { + if (webTab->url().toString() == "falkon:restore") { continue; } selectedTabs.insertMulti(mainWindow, webTab); } else if (command == "detachSelection" || command == "bookmarkSelection") { selectedTabs.insertMulti(mainWindow, webTab); } } winItem->setCheckState(0, Qt::Unchecked); } if (!selectedTabs.isEmpty()) { if (command == "closeSelection") { closeSelectedTabs(selectedTabs); } else if (command == "detachSelection") { detachSelectedTabs(selectedTabs); } else if (command == "bookmarkSelection") { bookmarkSelectedTabs(selectedTabs); } } m_refreshBlocked = false; delayedRefreshTree(); } void TabManagerWidget::changeGroupType() { QAction* action = qobject_cast(sender()); if (action) { int type = action->data().toInt(); if (m_groupType != GroupType(type)) { m_groupType = GroupType(type); delayedRefreshTree(); emit groupTypeChanged(m_groupType); } } } void TabManagerWidget::closeSelectedTabs(const QHash &tabsHash) { if (tabsHash.isEmpty()) { return; } const QList &windows = tabsHash.uniqueKeys(); foreach (BrowserWindow* mainWindow, windows) { QList tabs = tabsHash.values(mainWindow); foreach (WebTab* webTab, tabs) { mainWindow->tabWidget()->requestCloseTab(webTab->tabIndex()); } } } void TabManagerWidget::detachSelectedTabs(const QHash &tabsHash) { // TODO: use TabWidget::detachTab() if (tabsHash.isEmpty() || (tabsHash.uniqueKeys().size() == 1 && tabsHash.size() == tabsHash.keys().at(0)->tabWidget()->count())) { return; } BrowserWindow* newWindow = mApp->createWindow(Qz::BW_OtherRestoredWindow); newWindow->move(mApp->desktop()->availableGeometry(this).topLeft() + QPoint(30, 30)); const QList &windows = tabsHash.uniqueKeys(); foreach (BrowserWindow* mainWindow, windows) { const QList &tabs = tabsHash.values(mainWindow); foreach (WebTab* webTab, tabs) { mainWindow->tabWidget()->locationBars()->removeWidget(webTab->locationBar()); disconnect(webTab->webView(), SIGNAL(wantsCloseTab(int)), mainWindow->tabWidget(), SLOT(closeTab(int))); disconnect(webTab->webView(), SIGNAL(changed()), mainWindow->tabWidget(), SIGNAL(changed())); disconnect(webTab->webView(), SIGNAL(ipChanged(QString)), mainWindow->ipLabel(), SLOT(setText(QString))); webTab->detach(); if (mainWindow && mainWindow->tabWidget()->count() == 0) { mainWindow->close(); mainWindow = 0; } newWindow->tabWidget()->addView(webTab); } } } bool TabManagerWidget::bookmarkSelectedTabs(const QHash &tabsHash) { - QDialog* dialog = new QDialog(getQupZilla(), Qt::WindowStaysOnTopHint | Qt::MSWindowsFixedSizeDialogHint); + QDialog* dialog = new QDialog(getWindow(), Qt::WindowStaysOnTopHint | Qt::MSWindowsFixedSizeDialogHint); QBoxLayout* layout = new QBoxLayout(QBoxLayout::TopToBottom, dialog); QLabel* label = new QLabel(dialog); BookmarksFoldersButton* folderButton = new BookmarksFoldersButton(dialog); QDialogButtonBox* box = new QDialogButtonBox(dialog); box->addButton(QDialogButtonBox::Ok); box->addButton(QDialogButtonBox::Cancel); QObject::connect(box, SIGNAL(rejected()), dialog, SLOT(reject())); QObject::connect(box, SIGNAL(accepted()), dialog, SLOT(accept())); layout->addWidget(label); layout->addWidget(folderButton); layout->addWidget(box); label->setText(tr("Choose folder for bookmarks:")); dialog->setWindowTitle(tr("Bookmark Selected Tabs")); QSize size = dialog->size(); size.setWidth(350); dialog->resize(size); dialog->exec(); if (dialog->result() == QDialog::Rejected) { return false; } foreach (WebTab* tab, tabsHash) { if (!tab->url().isEmpty()) { BookmarkItem* bookmark = new BookmarkItem(BookmarkItem::Url); bookmark->setTitle(tab->title()); bookmark->setUrl(tab->url()); mApp->bookmarks()->addBookmark(folderButton->selectedFolder(), bookmark); } } delete dialog; return true; } QTreeWidgetItem* TabManagerWidget::createEmptyItem(QTreeWidgetItem* parent, bool addToTree) { QTreeWidgetItem* item = new QTreeWidgetItem(addToTree ? (parent ? parent : ui->treeWidget->invisibleRootItem()) : 0); item->setFlags(item->flags() | (parent ? Qt::ItemIsUserCheckable : Qt::ItemIsUserCheckable | Qt::ItemIsTristate)); item->setCheckState(0, Qt::Unchecked); return item; } void TabManagerWidget::groupByDomainName(bool useHostName) { QList windows = mApp->windows(); - int currentWindowIdx = windows.indexOf(getQupZilla()); + int currentWindowIdx = windows.indexOf(getWindow()); if (currentWindowIdx == -1) { - // getQupZilla() instance is closing + // getWindow() instance is closing return; } windows.move(currentWindowIdx, 0); QMap tabsGroupedByDomain; for (int win = 0; win < windows.count(); ++win) { BrowserWindow* mainWin = windows.at(win); QList tabs = mainWin->tabWidget()->allTabs(); for (int tab = 0; tab < tabs.count(); ++tab) { WebTab* webTab = tabs.at(tab); if (webTab->webView() && m_webPage == webTab->webView()->page()) { m_webPage = 0; continue; } QString domain = domainFromUrl(webTab->url(), useHostName); if (!tabsGroupedByDomain.contains(domain)) { QTreeWidgetItem* groupItem = createEmptyItem(0, false); groupItem->setText(0, domain); groupItem->setToolTip(0, domain); QFont font = groupItem->font(0); font.setBold(true); groupItem->setFont(0, font); tabsGroupedByDomain.insert(domain, groupItem); } QTreeWidgetItem* groupItem = tabsGroupedByDomain.value(domain); QTreeWidgetItem* tabItem = createEmptyItem(groupItem); if (webTab == mainWin->weView()->webTab()) { QFont font = tabItem->font(0); font.setBold(true); tabItem->setFont(0, font); } if (!webTab->isLoading()) { if (!webTab->isPinned()) { tabItem->setIcon(0, webTab->icon()); } else { tabItem->setIcon(0, QIcon(":tabmanager/data/tab-pinned.png")); } } else { tabItem->setIcon(0, QIcon(":tabmanager/data/tab-loading.png")); } tabItem->setText(0, webTab->title()); tabItem->setToolTip(0, webTab->title()); tabItem->setData(0, UrlRole, webTab->url().toString()); tabItem->setData(0, WebTabPointerRole, QVariant::fromValue(qobject_cast(webTab))); - tabItem->setData(0, QupZillaPointerRole, QVariant::fromValue(qobject_cast(mainWin))); + tabItem->setData(0, BrowserWindowPointerRole, QVariant::fromValue(qobject_cast(mainWin))); makeWebViewConnections(webTab->webView()); } } ui->treeWidget->insertTopLevelItems(0, tabsGroupedByDomain.values()); } void TabManagerWidget::groupByWindow() { QList windows = mApp->windows(); - int currentWindowIdx = windows.indexOf(getQupZilla()); + int currentWindowIdx = windows.indexOf(getWindow()); if (currentWindowIdx == -1) { return; } m_isRefreshing = true; if (!m_isDefaultWidget) { windows.move(currentWindowIdx, 0); currentWindowIdx = 0; } for (int win = 0; win < windows.count(); ++win) { BrowserWindow* mainWin = windows.at(win); QTreeWidgetItem* winItem = createEmptyItem(); winItem->setText(0, tr("Window %1").arg(QString::number(win + 1))); winItem->setToolTip(0, tr("Double click to switch")); if (win == currentWindowIdx) { QFont font = winItem->font(0); font.setBold(true); winItem->setFont(0, font); } - winItem->setData(0, QupZillaPointerRole, QVariant::fromValue(qobject_cast(mainWin))); + winItem->setData(0, BrowserWindowPointerRole, QVariant::fromValue(qobject_cast(mainWin))); QList tabs = mainWin->tabWidget()->allTabs(); for (int tab = 0; tab < tabs.count(); ++tab) { WebTab* webTab = tabs.at(tab); if (webTab->webView() && m_webPage == webTab->webView()->page()) { m_webPage = 0; continue; } QTreeWidgetItem* tabItem = createEmptyItem(winItem); if (webTab == mainWin->weView()->webTab()) { QFont font = tabItem->font(0); font.setBold(true); tabItem->setFont(0, font); } if (!webTab->isLoading()) { if (!webTab->isPinned()) { tabItem->setIcon(0, webTab->icon()); } else { tabItem->setIcon(0, QIcon(":tabmanager/data/tab-pinned.png")); } } else { tabItem->setIcon(0, QIcon(":tabmanager/data/tab-loading.png")); } tabItem->setText(0, webTab->title()); tabItem->setToolTip(0, webTab->title()); tabItem->setData(0, UrlRole, webTab->url().toString()); tabItem->setData(0, WebTabPointerRole, QVariant::fromValue(qobject_cast(webTab))); - tabItem->setData(0, QupZillaPointerRole, QVariant::fromValue(qobject_cast(mainWin))); + tabItem->setData(0, BrowserWindowPointerRole, QVariant::fromValue(qobject_cast(mainWin))); makeWebViewConnections(webTab->webView()); } } } -BrowserWindow* TabManagerWidget::getQupZilla() +BrowserWindow* TabManagerWidget::getWindow() { - if (m_isDefaultWidget || !p_QupZilla) { + if (m_isDefaultWidget || !m_window) { return mApp->getWindow(); } else { - return p_QupZilla.data(); + return m_window.data(); } } void TabManagerWidget::makeWebViewConnections(WebView* view) { if (view) { connect(view->page(), SIGNAL(loadFinished(bool)), this, SLOT(delayedRefreshTree())); connect(view->page(), SIGNAL(loadStarted()), this, SLOT(delayedRefreshTree())); connect(view, SIGNAL(titleChanged(QString)), this, SLOT(delayedRefreshTree())); connect(view, &WebView::iconChanged, this, [this]() { delayedRefreshTree(); }); } } diff --git a/src/plugins/TabManager/tabmanagerwidget.h b/src/plugins/TabManager/tabmanagerwidget.h index a2918f25..d2ebab23 100644 --- a/src/plugins/TabManager/tabmanagerwidget.h +++ b/src/plugins/TabManager/tabmanagerwidget.h @@ -1,108 +1,108 @@ /* ============================================================ * TabManager plugin for QupZilla * Copyright (C) 2013-2017 S. Razi Alavizadeh * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef TABMANAGERWIDGET_H #define TABMANAGERWIDGET_H #include #include #include namespace Ui { class TabManagerWidget; } class QUrl; class QTreeWidgetItem; class BrowserWindow; class WebPage; class WebTab; class WebView; class TLDExtractor; class TabManagerWidget : public QWidget { Q_OBJECT public: enum GroupType { GroupByWindow = 0, GroupByDomain = 1, GroupByHost = 2 }; explicit TabManagerWidget(BrowserWindow* mainClass, QWidget* parent = 0, bool defaultWidget = false); ~TabManagerWidget(); void closeSelectedTabs(const QHash &tabsHash); void detachSelectedTabs(const QHash &tabsHash); bool bookmarkSelectedTabs(const QHash &tabsHash); void setGroupType(GroupType type); static QString domainFromUrl(const QUrl &url, bool useHostName = false); public slots: void delayedRefreshTree(WebPage* p = 0); void changeGroupType(); private: enum TabDataRole { WebTabPointerRole = Qt::UserRole + 10, - QupZillaPointerRole = Qt::UserRole + 20, + BrowserWindowPointerRole = Qt::UserRole + 20, UrlRole = Qt::UserRole + 30 }; QTreeWidgetItem* createEmptyItem(QTreeWidgetItem* parent = 0, bool addToTree = true); void groupByDomainName(bool useHostName = false); void groupByWindow(); - BrowserWindow* getQupZilla(); + BrowserWindow* getWindow(); void makeWebViewConnections(WebView *view); Ui::TabManagerWidget* ui; - QPointer p_QupZilla; + QPointer m_window; WebPage* m_webPage; bool m_isRefreshing; bool m_refreshBlocked; bool m_waitForRefresh; bool m_isDefaultWidget; GroupType m_groupType; QString m_filterText; static TLDExtractor* s_tldExtractor; private slots: void refreshTree(); void processActions(); void onItemActivated(QTreeWidgetItem* item, int column); bool isTabSelected(); void customContextMenuRequested(const QPoint &pos); void filterChanged(const QString &filter, bool force = false); void filterBarClosed(); protected: bool eventFilter(QObject* obj, QEvent* event); signals: void showSideBySide(); void groupTypeChanged(TabManagerWidget::GroupType); }; #endif // TABMANAGERWIDGET_H diff --git a/src/plugins/TabManager/tabmanagerwidgetcontroller.cpp b/src/plugins/TabManager/tabmanagerwidgetcontroller.cpp index a2734625..7a2a4ea4 100644 --- a/src/plugins/TabManager/tabmanagerwidgetcontroller.cpp +++ b/src/plugins/TabManager/tabmanagerwidgetcontroller.cpp @@ -1,215 +1,215 @@ /* ============================================================ * TabManager plugin for QupZilla * Copyright (C) 2013 S. Razi Alavizadeh * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "tabmanagerwidgetcontroller.h" #include "tabmanagerwidget.h" #include "clickablelabel.h" #include "browserwindow.h" #include "tabwidget.h" #include "mainapplication.h" #include "tabbar.h" #include #include #include #include #include TabManagerWidgetController::TabManagerWidgetController(QObject* parent) : SideBarInterface(parent) , m_defaultTabManager(0) , m_groupType(TabManagerWidget::GroupByWindow) { } TabManagerWidgetController::~TabManagerWidgetController() { } QString TabManagerWidgetController::title() const { return tr("Tab Manager"); } QAction* TabManagerWidgetController::createMenuAction() { QAction* act = new QAction(tr("Tab Manager"), this); act->setCheckable(true); act->setIcon(QIcon(":tabmanager/data/tabmanager.png")); act->setShortcut(QKeySequence("Ctrl+Shift+M")); act->setData("TabManager"); return act; } QWidget* TabManagerWidgetController::createSideBarWidget(BrowserWindow* mainWindow) { return createTabManagerWidget(mainWindow, mainWindow); } QWidget* TabManagerWidgetController::createStatusBarIcon(BrowserWindow* mainWindow) { if (!defaultTabManager()) { return 0; } if (m_statusBarIcons.contains(mainWindow)) { return m_statusBarIcons.value(mainWindow); } ClickableLabel* icon = new ClickableLabel(mainWindow); icon->setCursor(Qt::PointingHandCursor); QPixmap p(":tabmanager/data/tabmanager.png"); icon->setPixmap(p.scaledToHeight(16)); icon->setToolTip(tr("Show Tab Manager")); QAction* showAction = createMenuAction(); showAction->setCheckable(false); showAction->setParent(icon); mainWindow->addAction(showAction); connect(showAction, SIGNAL(triggered()), this, SLOT(raiseTabManager())); connect(icon, SIGNAL(clicked(QPoint)), this, SLOT(raiseTabManager())); m_statusBarIcons.insert(mainWindow, icon); m_actions.insert(mainWindow, showAction); return icon; } TabManagerWidget::GroupType TabManagerWidgetController::groupType() { return m_groupType; } void TabManagerWidgetController::setGroupType(TabManagerWidget::GroupType type) { m_groupType = type; } TabManagerWidget* TabManagerWidgetController::createTabManagerWidget(BrowserWindow* mainClass, QWidget* parent, bool defaultWidget) { TabManagerWidget* tabManagerWidget = new TabManagerWidget(mainClass, parent, defaultWidget); tabManagerWidget->setGroupType(m_groupType); if (defaultWidget) { m_defaultTabManager = tabManagerWidget; QAction* showAction = createMenuAction(); showAction->setCheckable(false); showAction->setParent(m_defaultTabManager); m_defaultTabManager->addAction(showAction); connect(showAction, SIGNAL(triggered()), this, SLOT(raiseTabManager())); connect(tabManagerWidget, SIGNAL(showSideBySide()), this, SLOT(showSideBySide())); } else { m_defaultTabManager = 0; } connect(tabManagerWidget, SIGNAL(groupTypeChanged(TabManagerWidget::GroupType)), this, SLOT(setGroupType(TabManagerWidget::GroupType))); connect(this, SIGNAL(requestRefreshTree(WebPage*)), tabManagerWidget, SLOT(delayedRefreshTree(WebPage*))); connect(this, SIGNAL(pinStateChanged(int,bool)), tabManagerWidget, SLOT(delayedRefreshTree())); emit requestRefreshTree(); return tabManagerWidget; } TabManagerWidget* TabManagerWidgetController::defaultTabManager() { return m_defaultTabManager; } void TabManagerWidgetController::addStatusBarIcon(BrowserWindow* window) { if (window) { window->statusBar()->addPermanentWidget(createStatusBarIcon(window)); } } void TabManagerWidgetController::removeStatusBarIcon(BrowserWindow* window) { if (window) { window->statusBar()->removeWidget(m_statusBarIcons.value(window)); window->removeAction(m_actions.value(window)); delete m_actions.value(window); delete m_statusBarIcons.value(window); m_statusBarIcons.remove(window); m_actions.remove(window); } } void TabManagerWidgetController::mainWindowDeleted(BrowserWindow* window) { removeStatusBarIcon(window); emit requestRefreshTree(); } void TabManagerWidgetController::raiseTabManager() { if (!defaultTabManager()) { return; } ClickableLabel* icon = qobject_cast(sender()); if (icon) { static int frameWidth = (defaultTabManager()->frameGeometry().width() - defaultTabManager()->geometry().width()) / 2; static int titleBarHeight = defaultTabManager()->style()->pixelMetric(QStyle::PM_TitleBarHeight); int y = qMax(0, icon->mapToGlobal(QPoint(0, 0)).y() - 1 - icon->window()->height() + titleBarHeight - frameWidth); int x = icon->mapToGlobal(QPoint(0, 0)).x(); if (!mApp->isRightToLeft()) { x -= defaultTabManager()->width(); } QRect newGeo(x, y, defaultTabManager()->width(), icon->window()->height() - titleBarHeight - frameWidth); defaultTabManager()->setGeometry(newGeo); } defaultTabManager()->activateWindow(); defaultTabManager()->showNormal(); defaultTabManager()->raise(); } void TabManagerWidgetController::showSideBySide() { if (!defaultTabManager()) { return; } const QRect &availableGeometry = mApp->desktop()->availableGeometry(defaultTabManager()); static int frameWidth = (defaultTabManager()->frameGeometry().width() - defaultTabManager()->geometry().width()) / 2; static int titleBarHeight = defaultTabManager()->style()->pixelMetric(QStyle::PM_TitleBarHeight); QRect managerRect(availableGeometry.left() + frameWidth, availableGeometry.top() + titleBarHeight, defaultTabManager()->width(), availableGeometry.height() - titleBarHeight - frameWidth); - QRect qupzillaRect(managerRect.topRight().x() + 2 * frameWidth, managerRect.top(), + QRect windowRect(managerRect.topRight().x() + 2 * frameWidth, managerRect.top(), availableGeometry.width() - managerRect.width() - 4 * frameWidth, managerRect.height()); defaultTabManager()->setGeometry(managerRect); - mApp->getWindow()->setGeometry(qupzillaRect); + mApp->getWindow()->setGeometry(windowRect); mApp->getWindow()->showNormal(); mApp->getWindow()->raise(); defaultTabManager()->show(); defaultTabManager()->activateWindow(); defaultTabManager()->raise(); } void TabManagerWidgetController::emitRefreshTree() { emit requestRefreshTree(); } diff --git a/src/plugins/TabManager/tabmanagerwidgetcontroller.h b/src/plugins/TabManager/tabmanagerwidgetcontroller.h index 713c143c..57c8cb20 100644 --- a/src/plugins/TabManager/tabmanagerwidgetcontroller.h +++ b/src/plugins/TabManager/tabmanagerwidgetcontroller.h @@ -1,66 +1,66 @@ /* ============================================================ -* TabManager plugin for QupZilla +* TabManager plugin for Falkon * Copyright (C) 2013 S. Razi Alavizadeh * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef TABMANAGERWIDGETCONTROLLER_H #define TABMANAGERWIDGETCONTROLLER_H #include "sidebarinterface.h" #include "tabmanagerwidget.h" class WebPage; class TabManagerWidgetController : public SideBarInterface { Q_OBJECT public: explicit TabManagerWidgetController(QObject* parent = 0); ~TabManagerWidgetController(); QString title() const; QAction* createMenuAction(); QWidget* createSideBarWidget(BrowserWindow* mainWindow); QWidget* createStatusBarIcon(BrowserWindow* mainWindow); TabManagerWidget::GroupType groupType(); TabManagerWidget* createTabManagerWidget(BrowserWindow* mainClass, QWidget* parent = 0, bool defaultWidget = false); TabManagerWidget* defaultTabManager(); void addStatusBarIcon(BrowserWindow* window); void removeStatusBarIcon(BrowserWindow* window); public slots: void setGroupType(TabManagerWidget::GroupType type); void mainWindowDeleted(BrowserWindow* window); void raiseTabManager(); void showSideBySide(); void emitRefreshTree(); private: TabManagerWidget* m_defaultTabManager; TabManagerWidget::GroupType m_groupType; QHash m_statusBarIcons; QHash m_actions; signals: void requestRefreshTree(WebPage* p = 0); void pinStateChanged(int index, bool pinned); }; #endif // TABMANAGERWIDGETCONTROLLER_H diff --git a/src/plugins/TestPlugin/testplugin.cpp b/src/plugins/TestPlugin/testplugin.cpp index 3be7db07..ee856ca6 100644 --- a/src/plugins/TestPlugin/testplugin.cpp +++ b/src/plugins/TestPlugin/testplugin.cpp @@ -1,179 +1,179 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "testplugin.h" #include "testplugin_sidebar.h" #include "browserwindow.h" #include "webview.h" #include "pluginproxy.h" #include "mainapplication.h" #include "sidebar.h" #include "webhittestresult.h" #include #include #include TestPlugin::TestPlugin() : QObject() , m_view(0) { // Don't do anything expensive in constructor! // It will be called even if user doesn't have the plugin allowed } PluginSpec TestPlugin::pluginSpec() { PluginSpec spec; spec.name = "Example Plugin"; spec.info = "Example minimal plugin"; spec.description = "Very simple minimal plugin example"; spec.version = "0.1.7"; spec.author = "David Rosca "; spec.icon = QPixmap(":qupzilla.png"); spec.hasSettings = true; return spec; } void TestPlugin::init(InitState state, const QString &settingsPath) { qDebug() << __FUNCTION__ << "called"; // This function is called right after plugin is loaded // it will be called even if we return false from testPlugin() - // so it is recommended not to call any QupZilla function here + // so it is recommended not to call any Falkon function here // Settings path is PROFILE/extensions (without trailign slash), // in this directory you can use global .ini file for QSettings // named "extensions.ini" or create new folder for your plugin // and save in it anything you want m_settingsPath = settingsPath; // State can be either StartupInitState or LateInitState, and it // indicates when the plugin have been loaded. // Currently, it can be from preferences, or automatically at startup. // Plugins are loaded before first BrowserWindow is created. Q_UNUSED(state) // Registering this plugin as a MousePressHandler. // Otherwise mousePress() function will never be called QZ_REGISTER_EVENT_HANDLER(PluginProxy::MousePressHandler); // Adding new sidebar into application SideBarManager::addSidebar("testplugin-sidebar", new TestPlugin_Sidebar(this)); } void TestPlugin::unload() { qDebug() << __FUNCTION__ << "called"; // This function will be called when unloading plugin // it will be also called if we return false from testPlugin() // Removing sidebar from application SideBarManager::removeSidebar("testplugin-sidebar"); // Deleting settings dialog if opened delete m_settings.data(); } bool TestPlugin::testPlugin() { // This function is called right after init() // There should be some testing if plugin is loaded correctly // If this function returns false, plugin is automatically unloaded - return (Qz::VERSION == QLatin1String(QUPZILLA_VERSION)); + return (Qz::VERSION == QLatin1String(FALKON_VERSION)); } QTranslator* TestPlugin::getTranslator(const QString &locale) { // Loads translation according to locale file // QString locale will contains "fr_FR.qm" for French locale QTranslator* translator = new QTranslator(this); translator->load(locale, ":/testplugin/locale/"); return translator; } void TestPlugin::showSettings(QWidget* parent) { // This function will be called from Preferences after clicking on Settings button. // Settings button will be enabled if PluginSpec.hasSettings == true if (!m_settings) { m_settings = new QDialog(parent); QPushButton* b = new QPushButton("Example Plugin v0.0.1"); QPushButton* closeButton = new QPushButton(tr("Close")); QLabel* label = new QLabel(); label->setPixmap(QPixmap(":icons/other/about.png")); QVBoxLayout* l = new QVBoxLayout(m_settings.data()); l->addWidget(label); l->addWidget(b); l->addWidget(closeButton); m_settings.data()->setLayout(l); m_settings.data()->setAttribute(Qt::WA_DeleteOnClose); m_settings.data()->setWindowTitle(tr("Example Plugin Settings")); m_settings.data()->setWindowIcon(QIcon(":qupzilla.png")); connect(closeButton, SIGNAL(clicked()), m_settings.data(), SLOT(close())); } m_settings.data()->show(); m_settings.data()->raise(); } void TestPlugin::populateWebViewMenu(QMenu* menu, WebView* view, const WebHitTestResult &r) { Q_UNUSED(r) // Called from WebView when creating context menu m_view = view; QString title; if (!r.imageUrl().isEmpty()) { title += " on image"; } if (!r.linkUrl().isEmpty()) { title += " on link"; } if (r.isContentEditable()) { title += " on input"; } menu->addAction(tr("My first plugin action") + title, this, SLOT(actionSlot())); } bool TestPlugin::mousePress(const Qz::ObjectName &type, QObject* obj, QMouseEvent* event) { qDebug() << "mousePress" << type << obj << event; // Returning false means, that we don't want to block propagating this event - // Returning true may affect behaviour of QupZilla, so make sure you know what + // Returning true may affect behaviour of Falkon, so make sure you know what // you are doing! return false; } void TestPlugin::actionSlot() { QMessageBox::information(m_view, tr("Hello"), tr("First plugin action works :-)")); } diff --git a/src/plugins/TestPlugin/testplugin.h b/src/plugins/TestPlugin/testplugin.h index 4c122e59..68ea75fa 100644 --- a/src/plugins/TestPlugin/testplugin.h +++ b/src/plugins/TestPlugin/testplugin.h @@ -1,60 +1,60 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef TESTPLUGIN_H #define TESTPLUGIN_H -// Include plugininterface.h for your version of QupZilla +// Include plugininterface.h for your version of Falkon #include "plugininterface.h" #include #include #include #include class TestPlugin : public QObject, public PluginInterface { Q_OBJECT Q_INTERFACES(PluginInterface) - Q_PLUGIN_METADATA(IID "QupZilla.Browser.plugin.TestPlugin") + Q_PLUGIN_METADATA(IID "Falkon.Browser.plugin.TestPlugin") public: explicit TestPlugin(); PluginSpec pluginSpec(); void init(InitState state, const QString &settingsPath); void unload(); bool testPlugin(); QTranslator* getTranslator(const QString &locale); void showSettings(QWidget* parent = 0); void populateWebViewMenu(QMenu* menu, WebView* view, const WebHitTestResult &r); bool mousePress(const Qz::ObjectName &type, QObject* obj, QMouseEvent* event); private slots: void actionSlot(); private: QPointer m_settings; WebView* m_view; QString m_settingsPath; }; #endif // TESTPLUGIN_H diff --git a/src/plugins/TestPlugin/testplugin_sidebar.cpp b/src/plugins/TestPlugin/testplugin_sidebar.cpp index 1bc22436..738dbe9f 100644 --- a/src/plugins/TestPlugin/testplugin_sidebar.cpp +++ b/src/plugins/TestPlugin/testplugin_sidebar.cpp @@ -1,61 +1,61 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "testplugin_sidebar.h" #include #include #include #include TestPlugin_Sidebar::TestPlugin_Sidebar(QObject* parent) : SideBarInterface(parent) { } QString TestPlugin_Sidebar::title() const { return tr("Testing Sidebar"); } QAction* TestPlugin_Sidebar::createMenuAction() { // The action must be parented to some object from plugin, otherwise // there may be a crash when unloading the plugin. QAction* act = new QAction(tr("Testing Sidebar"), this); act->setCheckable(true); return act; } QWidget* TestPlugin_Sidebar::createSideBarWidget(BrowserWindow* mainWindow) { Q_UNUSED(mainWindow) QWidget* w = new QWidget; QPushButton* b = new QPushButton("Example Plugin v0.0.1"); QLabel* label = new QLabel(); label->setPixmap(QPixmap(":icons/other/about.png")); QVBoxLayout* l = new QVBoxLayout(w); l->addWidget(label); l->addWidget(b); w->setLayout(l); return w; } diff --git a/src/plugins/TestPlugin/testplugin_sidebar.h b/src/plugins/TestPlugin/testplugin_sidebar.h index 279d39ae..efdd19fb 100644 --- a/src/plugins/TestPlugin/testplugin_sidebar.h +++ b/src/plugins/TestPlugin/testplugin_sidebar.h @@ -1,35 +1,35 @@ /* ============================================================ -* QupZilla - WebKit based browser +* Falkon - Qt web browser * Copyright (C) 2010-2014 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #ifndef TESTPLUGIN_SIDEBAR_H #define TESTPLUGIN_SIDEBAR_H #include "sidebarinterface.h" class TestPlugin_Sidebar : public SideBarInterface { Q_OBJECT public: explicit TestPlugin_Sidebar(QObject* parent = 0); QString title() const; QAction* createMenuAction(); QWidget* createSideBarWidget(BrowserWindow* mainWindow); }; #endif // TESTPLUGIN_SIDEBAR_H diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro index 694746a7..eb16f93f 100644 --- a/src/plugins/plugins.pro +++ b/src/plugins/plugins.pro @@ -1,44 +1,44 @@ TEMPLATE = subdirs include(../defines.pri) defineTest(addSubdir) { for(subdir, 1) { entries = $$files($$subdir/*) for(entry, entries) { fullPath = $$replace(entry, ;,"") fullPath = $$replace(fullPath, \\\\, /) name = $$replace(fullPath, $$re_escape("$$subdir/"), "") os2|win32: fullPath = $$lower($$fullPath) exists($$fullPath/*.pro): SUBDIRS += $$fullPath } } export (SUBDIRS) } defineTest(disablePlugin) { SUBDIRS -= $$PWD/$$1 os2|win32: SUBDIRS -= $$lower($$PWD/$$1) export(SUBDIRS) } addSubdir($$PWD) -outOfDirPlugins = $$(QUPZILLA_PLUGINS_SRCDIR) -!equals(outOfDirPlugins, ""): addSubdir($$(QUPZILLA_PLUGINS_SRCDIR)) +outOfDirPlugins = $$(FALKON_PLUGINS_SRCDIR) +!equals(outOfDirPlugins, ""): addSubdir($$(FALKON_PLUGINS_SRCDIR)) # TestPlugin only in debug build !CONFIG(debug, debug|release): disablePlugin(TestPlugin) # KWalletPasswords only with KDE_INTEGRATION and KWallet framework !contains(DEFINES, KDE_INTEGRATION): disablePlugin(KWalletPasswords) !qtHaveModule(KWallet): disablePlugin(KWalletPasswords) # GnomeKeyringPasswords only with GNOME_INTEGRATION and gnome-keyring pkg-config !contains(DEFINES, GNOME_INTEGRATION): disablePlugin(GnomeKeyringPasswords) !system(pkg-config --exists gnome-keyring-1): disablePlugin(GnomeKeyringPasswords) # QtWebEngine disable disablePlugin(AccessKeysNavigation) diff --git a/tests/autotests/autotests.pro b/tests/autotests/autotests.pro index 972f3e3b..ea1c29c6 100644 --- a/tests/autotests/autotests.pro +++ b/tests/autotests/autotests.pro @@ -1,77 +1,77 @@ include($$PWD/../../src/defines.pri) QT += webenginewidgets network widgets printsupport sql script dbus testlib TARGET = autotests CONFIG -= app_bundle -!unix|mac: LIBS += -L$$PWD/../../bin -lQupZilla -!mac:unix: LIBS += $$PWD/../../bin/libQupZilla.so +!unix|mac: LIBS += -L$$PWD/../../bin -lFalkon +!mac:unix: LIBS += $$PWD/../../bin/libFalkon.so QMAKE_LFLAGS+=$${QMAKE_LFLAGS_RPATH}$$PWD/../../bin # KWallet plugin exists($$PWD/../../bin/plugins/libKWalletPasswords.so) { LIBS += $$PWD/../../bin/plugins/libKWalletPasswords.so DEFINES += HAVE_KDE_PASSWORDS_PLUGIN } # GnomeKeyring plugin exists($$PWD/../../bin/plugins/libGnomeKeyringPasswords.so) { LIBS += $$PWD/../../bin/plugins/libGnomeKeyringPasswords.so DEFINES += HAVE_GNOME_PASSWORDS_PLUGIN } mac { # homebrew openssl BREW_OPENSSL = $$system("brew --prefix openssl") INCLUDEPATH += $$BREW_OPENSSL/include LIBS += -L$$BREW_OPENSSL/lib LIBS += -lcrypto -framework CoreServices } DESTDIR = OBJECTS_DIR = build MOC_DIR = build RCC_DIR = build UI_DIR = build INCLUDEPATH += $$PWD/../../src/lib/3rdparty \ $$PWD/../../src/lib/adblock \ $$PWD/../../src/lib/app \ $$PWD/../../src/lib/autofill \ $$PWD/../../src/lib/bookmarks \ $$PWD/../../src/lib/cookies \ $$PWD/../../src/lib/downloads \ $$PWD/../../src/lib/history \ $$PWD/../../src/lib/navigation \ $$PWD/../../src/lib/network \ $$PWD/../../src/lib/notifications \ $$PWD/../../src/lib/opensearch \ $$PWD/../../src/lib/other \ $$PWD/../../src/lib/plugins \ $$PWD/../../src/lib/popupwindow \ $$PWD/../../src/lib/preferences \ $$PWD/../../src/lib/session \ $$PWD/../../src/lib/sidebar \ $$PWD/../../src/lib/tabwidget \ $$PWD/../../src/lib/tools \ $$PWD/../../src/lib/webengine \ $$PWD/../../src/lib/webtab \ HEADERS += \ qztoolstest.h \ cookiestest.h \ adblocktest.h \ updatertest.h \ passwordbackendtest.h \ SOURCES += \ qztoolstest.cpp \ main.cpp \ cookiestest.cpp \ adblocktest.cpp \ updatertest.cpp \ passwordbackendtest.cpp \ diff --git a/tests/benchmarks/benchmarks.pri b/tests/benchmarks/benchmarks.pri index 9a791274..459613a1 100644 --- a/tests/benchmarks/benchmarks.pri +++ b/tests/benchmarks/benchmarks.pri @@ -1,43 +1,43 @@ include($$PWD/../../src/defines.pri) isEqual(QT_MAJOR_VERSION, 5) { QT += webkitwidgets network widgets printsupport sql script gui-private testlib } else { QT += core gui webkit sql network script CONFIG += qtestlib } -!unix|mac: LIBS += -L$$PWD/../../bin -lQupZilla -!mac:unix: LIBS += $$PWD/../../bin/libQupZilla.so +!unix|mac: LIBS += -L$$PWD/../../bin -lFalkon +!mac:unix: LIBS += $$PWD/../../bin/libFalkon.so QMAKE_LFLAGS+=$${QMAKE_LFLAGS_RPATH}$$PWD/../../bin DESTDIR = OBJECTS_DIR = build MOC_DIR = build RCC_DIR = build UI_DIR = build INCLUDEPATH += $$PWD/../../src/lib/3rdparty \ $$PWD/../../src/lib/adblock \ $$PWD/../../src/lib/app \ $$PWD/../../src/lib/autofill \ $$PWD/../../src/lib/bookmarks \ $$PWD/../../src/lib/cookies \ $$PWD/../../src/lib/downloads \ $$PWD/../../src/lib/history \ $$PWD/../../src/lib/navigation \ $$PWD/../../src/lib/network \ $$PWD/../../src/lib/notifications \ $$PWD/../../src/lib/opensearch \ $$PWD/../../src/lib/other \ $$PWD/../../src/lib/plugins \ $$PWD/../../src/lib/popupwindow \ $$PWD/../../src/lib/preferences \ $$PWD/../../src/lib/rss \ $$PWD/../../src/lib/session \ $$PWD/../../src/lib/sidebar \ $$PWD/../../src/lib/tabwidget \ $$PWD/../../src/lib/tools \ $$PWD/../../src/lib/webkit \ $$PWD/../../src/lib/webtab \ diff --git a/windows/installer.nsi b/windows/installer.nsi index 6d446199..349873ac 100644 --- a/windows/installer.nsi +++ b/windows/installer.nsi @@ -1,465 +1,465 @@ -; QupZilla Windows Installer NSIS Script -; Copyright (C) 2010-2017 David Rosca -; 2012-2017 S. Razi Alavizadeh -; -; For compiling this script you need following plugins: -; FindProcDLL_plug-in, KillProcDLL_plug-in and 'AllAssociation.nsh' needs -; Registry_plug-in, Application_Association_Registration_plug-in -; Unicode version of them can be downloaded from: -; http://sourceforge.net/projects/findkillprocuni/files/bin/ -; http://nsis.sourceforge.net/Application_Association_Registration_plug-in -; http://nsis.sourceforge.net/Registry_plug-in - -!ifndef CUSTOM - !define VERSION 2.1.2 - !define ARCH x86 - !define MSVC_VER 140 - !define OPENSSL_BIN_DIR . - !define MSVC_REDIST_DIR . - !define QZ_BIN_DIR . - !define ICU_BIN_DIR . - !define QT_DIR . - !define QT_BIN_DIR . - !define QT_PLUGINS_DIR . - !define QTWEBENGINE_DICTIONARIES_DIR qtwebengine_dictionaries - !undef PORTABLE -!endif - -; WinVer.nsh was added in the same release that RequestExecutionLevel so check -; if ___WINVER__NSH___ is defined to determine if RequestExecutionLevel is -; available. -!include /NONFATAL WinVer.nsh -!include x64.nsh - -!ifndef PORTABLE - RequestExecutionLevel admin -!else - RequestExecutionLevel user -!endif - -!addplugindir "wininstall\" - -!include "StdUtils.nsh" -!include "FileFunc.nsh" -!include "wininstall\AllAssociation.nsh" -SetCompressor /SOLID /FINAL lzma - -!define PRODUCT_NAME "QupZilla" -!define /date PRODUCT_VERSION "${VERSION}" -!define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\qupzilla.exe" -!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" -!define PRODUCT_UNINST_ROOT_KEY "HKLM" -!define PRODUCT_CAPABILITIES_KEY "Software\${PRODUCT_NAME}\Capabilities" - -!include "MUI.nsh" -!define MUI_ABORTWARNING -!define MUI_ICON "wininstall\install.ico" -!define MUI_UNICON "wininstall\uninstall.ico" -!define MUI_WELCOMEFINISHPAGE_BITMAP "wininstall\welcome.bmp" -!define MUI_UNWELCOMEFINISHPAGE_BITMAP "wininstall\welcome.bmp" - -!insertmacro MUI_PAGE_WELCOME -!insertmacro MUI_PAGE_LICENSE ${QZ_BIN_DIR}\COPYRIGHT.txt -!insertmacro MUI_PAGE_COMPONENTS -!insertmacro MUI_PAGE_DIRECTORY -!insertmacro MUI_PAGE_INSTFILES - -!define MUI_FINISHPAGE_RUN -!define MUI_FINISHPAGE_RUN_FUNCTION "RunQupZillaAsUser" -!insertmacro MUI_PAGE_FINISH - -!insertmacro MUI_UNPAGE_WELCOME -!insertmacro MUI_UNPAGE_CONFIRM -!insertmacro MUI_UNPAGE_INSTFILES -!insertmacro MUI_UNPAGE_FINISH - -!insertmacro MUI_LANGUAGE "English" -!insertmacro MUI_LANGUAGE "Czech" -!insertmacro MUI_LANGUAGE "Slovak" -!insertmacro MUI_LANGUAGE "German" -!insertmacro MUI_LANGUAGE "Dutch" -!insertmacro MUI_LANGUAGE "Portuguese" -!insertmacro MUI_LANGUAGE "Greek" -!insertmacro MUI_LANGUAGE "French" -!insertmacro MUI_LANGUAGE "Italian" -!insertmacro MUI_LANGUAGE "Romanian" -!insertmacro MUI_LANGUAGE "Tradchinese" -!insertmacro MUI_LANGUAGE "Simpchinese" -!insertmacro MUI_LANGUAGE "Indonesian" -!insertmacro MUI_LANGUAGE "Georgian" -!insertmacro MUI_LANGUAGE "Japanese" -!insertmacro MUI_LANGUAGE "Swedish" -!insertmacro MUI_LANGUAGE "Polish" -!insertmacro MUI_LANGUAGE "Ukrainian" -!insertmacro MUI_LANGUAGE "Catalan" -!insertmacro MUI_LANGUAGE "Serbian" -!insertmacro MUI_LANGUAGE "SerbianLatin" -!insertmacro MUI_LANGUAGE "Farsi" -!insertmacro MUI_LANGUAGE "Hebrew" -!insertmacro MUI_LANGUAGE "Spanish" -!insertmacro MUI_LANGUAGE "Arabic" -!insertmacro MUI_LANGUAGE "Basque" -!insertmacro MUI_LANGUAGE "Danish" - -!insertmacro MUI_RESERVEFILE_LANGDLL - -Name "${PRODUCT_NAME} ${PRODUCT_VERSION}" -OutFile "${PRODUCT_NAME} ${PRODUCT_VERSION} Installer.exe" -InstallDir "$PROGRAMFILES\${PRODUCT_NAME}\" -InstallDirRegKey HKLM "${PRODUCT_DIR_REGKEY}" "" -ShowInstDetails show -ShowUnInstDetails show - -!include "wininstall\languages.nsh" - -Section !$(TITLE_SecMain) SecMain - SectionIn RO - FindProcDLL::FindProc "qupzilla.exe" - IntCmp $R0 1 0 notRunning - MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION "$(MSG_RunningInstance)" /SD IDOK IDCANCEL AbortInstallation - KillProcDLL::KillProc "qupzilla.exe" - Sleep 100 - Goto notRunning -AbortInstallation: - Abort "$(MSG_InstallationCanceled)" - -notRunning: - SetOverwrite on - - SetOutPath "$INSTDIR" - File "${QZ_BIN_DIR}\COPYRIGHT.txt" - File "${QZ_BIN_DIR}\qupzilla.exe" - File "${QZ_BIN_DIR}\qupzilla.dll" - File "${QZ_BIN_DIR}\qt.conf" - File "${OPENSSL_BIN_DIR}\libeay32.dll" - File "${OPENSSL_BIN_DIR}\ssleay32.dll" - File "${MSVC_REDIST_DIR}\*" - File "${ICU_BIN_DIR}\icudt54.dll" - File "${ICU_BIN_DIR}\icuin54.dll" - File "${ICU_BIN_DIR}\icuuc54.dll" - File "${QT_BIN_DIR}\libEGL.dll" - File "${QT_BIN_DIR}\libGLESv2.dll" - File "${QT_BIN_DIR}\opengl32sw.dll" - File "${QT_BIN_DIR}\D3Dcompiler_47.dll" - File "${QT_BIN_DIR}\Qt5Core.dll" - File "${QT_BIN_DIR}\Qt5Gui.dll" - File "${QT_BIN_DIR}\Qt5Network.dll" - File "${QT_BIN_DIR}\Qt5Positioning.dll" - File "${QT_BIN_DIR}\Qt5PrintSupport.dll" - File "${QT_BIN_DIR}\Qt5Qml.dll" - File "${QT_BIN_DIR}\Qt5Quick.dll" - File "${QT_BIN_DIR}\Qt5QuickWidgets.dll" - File "${QT_BIN_DIR}\Qt5Sql.dll" - File "${QT_BIN_DIR}\Qt5Svg.dll" - File "${QT_BIN_DIR}\Qt5WinExtras.dll" - File "${QT_BIN_DIR}\Qt5WebEngine.dll" - File "${QT_BIN_DIR}\Qt5WebEngineCore.dll" - File "${QT_BIN_DIR}\Qt5WebEngineWidgets.dll" - File "${QT_BIN_DIR}\Qt5WebChannel.dll" - File "${QT_BIN_DIR}\Qt5Widgets.dll" - File "${QT_BIN_DIR}\QtWebEngineProcess.exe" - - SetOutPath "$INSTDIR\iconengines" - File "${QT_PLUGINS_DIR}\iconengines\qsvgicon.dll" - - SetOutPath "$INSTDIR\imageformats" - File "${QT_PLUGINS_DIR}\imageformats\*.dll" - - SetOutPath "$INSTDIR\platforms" - File "${QT_PLUGINS_DIR}\platforms\qwindows.dll" - - SetOutPath "$INSTDIR\printsupport" - File "${QT_PLUGINS_DIR}\printsupport\windowsprintersupport.dll" - - SetOutPath "$INSTDIR\qml\QtQuick.2" - File "${QT_DIR}\qml\QtQuick.2\*" - - SetOutPath "$INSTDIR\qml\QtWebEngine" - File "${QT_DIR}\qml\QtWebEngine\*" - - SetOutPath "$INSTDIR\resources" - File "${QT_DIR}\resources\*" - - SetOutPath "$INSTDIR\sqldrivers" - File "${QT_PLUGINS_DIR}\sqldrivers\qsqlite.dll" - - SetOutPath "$INSTDIR\translations\qtwebengine_locales" - File "${QT_DIR}\translations\qtwebengine_locales\*" - - SetOutPath "$INSTDIR\qtwebengine_dictionaries\doc" - ; In some packages underline '_' is used and in some other packages dash '-' is used so we use wildcard - File "${QTWEBENGINE_DICTIONARIES_DIR}\doc\README*en*US.txt" - - SetOutPath "$INSTDIR\qtwebengine_dictionaries" - ; in some packages *.bdic files use dash '-' instead of underline '_' followed by a version number. e.g. en-US-3-0.bdic - File "${QTWEBENGINE_DICTIONARIES_DIR}\en*US*.bdic" - - !ifndef PORTABLE - call RegisterCapabilities - !endif -SectionEnd - -SectionGroup $(TITLE_SecThemes) SecThemes - - Section Default SecDefault - SectionIn RO - SetOutPath "$INSTDIR\themes\windows" - File "${QZ_BIN_DIR}\themes\windows\*" - SetOutPath "$INSTDIR\themes\windows\images" - File "${QZ_BIN_DIR}\themes\windows\images\*" - SectionEnd - - Section Chrome SecChrome - SetOutPath "$INSTDIR\themes\chrome" - File "${QZ_BIN_DIR}\themes\chrome\*" - SetOutPath "$INSTDIR\themes\chrome\images" - File "${QZ_BIN_DIR}\themes\chrome\images\*" - SectionEnd - - Section Mac SecMac - SetOutPath "$INSTDIR\themes\mac" - File "${QZ_BIN_DIR}\themes\mac\*" - SetOutPath "$INSTDIR\themes\mac\images" - File "${QZ_BIN_DIR}\themes\mac\images\*" - SectionEnd - - Section Breathe SecBreathe - SetOutPath "$INSTDIR\themes\breathe" - File "${QZ_BIN_DIR}\themes\breathe\*" - SetOutPath "$INSTDIR\themes\breathe\images" - File "${QZ_BIN_DIR}\themes\breathe\images\*" - SectionEnd -SectionGroupEnd - -Section $(TITLE_SecTranslations) SecTranslations - SetOutPath "$INSTDIR\locale" - File "${QZ_BIN_DIR}\locale\*.qm" - SetOutPath "$INSTDIR\qtwebengine_dictionaries\doc" - File "${QTWEBENGINE_DICTIONARIES_DIR}\doc\*" - SetOutPath "$INSTDIR\qtwebengine_dictionaries" - File "${QTWEBENGINE_DICTIONARIES_DIR}\*.bdic" -SectionEnd - -Section $(TITLE_SecPlugins) SecPlugins - SetOutPath "$INSTDIR\plugins" - File "${QZ_BIN_DIR}\plugins\*.dll" -SectionEnd - - -!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN - !insertmacro MUI_DESCRIPTION_TEXT ${SecMain} $(DESC_SecMain) - !insertmacro MUI_DESCRIPTION_TEXT ${SecTranslations} $(DESC_SecTranslations) - !insertmacro MUI_DESCRIPTION_TEXT ${SecPlugins} $(DESC_SecPlugins) - !ifndef PORTABLE - !insertmacro MUI_DESCRIPTION_TEXT ${SecDesktop} $(DESC_SecDesktop) - !insertmacro MUI_DESCRIPTION_TEXT ${SecExtensions} $(DESC_SecExtensions) - !endif - !insertmacro MUI_DESCRIPTION_TEXT ${SecThemes} $(DESC_SecThemes) - - !ifndef PORTABLE - !insertmacro MUI_DESCRIPTION_TEXT ${SecSetASDefault} $(DESC_SecSetASDefault) - !insertmacro MUI_DESCRIPTION_TEXT ${SecProtocols} $(DESC_SecProtocols) - !endif -!insertmacro MUI_FUNCTION_DESCRIPTION_END - - -!ifndef PORTABLE - SectionGroup $(TITLE_SecSetASDefault) SecSetASDefault - Section $(TITLE_SecExtensions) SecExtensions - SetOutPath "$INSTDIR" - ${RegisterAssociation} ".htm" "$INSTDIR\qupzilla.exe" "QupZilla.HTM" $(FILE_Htm) "$INSTDIR\qupzilla.exe,1" "file" - ${RegisterAssociation} ".html" "$INSTDIR\qupzilla.exe" "QupZilla.HTML" $(FILE_Html) "$INSTDIR\qupzilla.exe,1" "file" - ${UpdateSystemIcons} - SectionEnd - - Section $(TITLE_SecProtocols) SecProtocols - ${RegisterAssociation} "http" "$INSTDIR\qupzilla.exe" "QupZilla.HTTP" "URL:HyperText Transfer Protocol" "$INSTDIR\qupzilla.exe,0" "protocol" - ${RegisterAssociation} "https" "$INSTDIR\qupzilla.exe" "QupZilla.HTTPS" "URL:HyperText Transfer Protocol with Privacy" "$INSTDIR\qupzilla.exe,0" "protocol" - ${UpdateSystemIcons} - SectionEnd - SectionGroupEnd - - Section -StartMenu - SetOutPath "$INSTDIR" - SetShellVarContext all - CreateDirectory "$SMPROGRAMS\QupZilla" - CreateShortCut "$SMPROGRAMS\QupZilla\Uninstall.lnk" "$INSTDIR\Uninstall.exe" - CreateShortCut "$SMPROGRAMS\QupZilla\QupZilla.lnk" "$INSTDIR\qupzilla.exe" - CreateShortCut "$SMPROGRAMS\QupZilla\License.lnk" "$INSTDIR\COPYRIGHT.txt" - SectionEnd - - Section $(TITLE_SecDesktop) SecDesktop - SetOutPath "$INSTDIR" - CreateShortCut "$DESKTOP\QupZilla.lnk" "$INSTDIR\qupzilla.exe" "" - SectionEnd - - Section -Uninstaller - WriteUninstaller "$INSTDIR\uninstall.exe" - WriteRegStr HKLM "${PRODUCT_DIR_REGKEY}" "" "$INSTDIR\qupzilla.exe" - WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)" - WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\Uninstall.exe" - WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\qupzilla.exe" - WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}" - WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "Publisher" "QupZilla Team" - WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "HelpLink" "https://github.com/QupZilla/qupzilla/wiki" - WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "InstallLocation" "$INSTDIR" - WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "InstallSource" "$EXEDIR" - WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "URLInfoAbout" "http://www.qupzilla.com" - WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "URLUpdateInfo" "http://blog.qupzilla.com/" - ${GetSize} "$INSTDIR" "/S=0K" $0 $1 $2 - WriteRegDWORD ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "EstimatedSize" "$0" - SectionEnd - - Section Uninstall - FindProcDLL::FindProc "qupzilla.exe" - IntCmp $R0 1 0 notRunning - MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION "$(MSG_RunningInstance)" /SD IDOK IDCANCEL AbortInstallation - KillProcDLL::KillProc "qupzilla.exe" - Sleep 100 - Goto notRunning - AbortInstallation: - Abort "$(MSG_InstallationCanceled)" - - notRunning: - SetShellVarContext all - Delete "$DESKTOP\QupZilla.lnk" - RMDir /r "$INSTDIR" - RMDir /r "$SMPROGRAMS\QupZilla" - DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" - DeleteRegKey HKLM "${PRODUCT_DIR_REGKEY}" - - DeleteRegKey HKLM "Software\${PRODUCT_NAME}" - DeleteRegValue HKLM "SOFTWARE\RegisteredApplications" "${PRODUCT_NAME}" - - ${UnRegisterAssociation} ".htm" "QupZilla.HTM" "$INSTDIR\qupzilla.exe" "file" - ${UnRegisterAssociation} ".html" "QupZilla.HTML" "$INSTDIR\qupzilla.exe" "file" - ${UnRegisterAssociation} "http" "QupZilla.HTTP" "$INSTDIR\qupzilla.exe" "protocol" - ${UnRegisterAssociation} "https" "QupZilla.HTTPS" "$INSTDIR\qupzilla.exe" "protocol" - ${UpdateSystemIcons} - SectionEnd -!endif - -BrandingText "${PRODUCT_NAME} ${PRODUCT_VERSION} Installer" - -Function .onInit - ;Prevent running installer of 64-bit QupZilla on 32-bit Windows - ${If} ${RunningX64} - ${If} ${ARCH} == "x64" - StrCpy $InstDir "$PROGRAMFILES64\${PRODUCT_NAME}\" - ${Else} - StrCpy $InstDir "$PROGRAMFILES32\${PRODUCT_NAME}\" - ${Endif} - ${Else} - ${If} ${ARCH} == "x64" - MessageBox MB_OK|MB_ICONEXCLAMATION "This installation requiers Windows x64!" - Quit - ${Else} - StrCpy $InstDir "$PROGRAMFILES\${PRODUCT_NAME}\" - ${Endif} - ${EndIf} - - !ifdef PORTABLE - StrCpy $InstDir "$DESKTOP\${PRODUCT_NAME} Portable\" - !endif - - ;Prevent Multiple Instances - System::Call 'kernel32::CreateMutexA(i 0, i 0, t "QupZillaInstaller-4ECB4694-2C39-4f93-9122-A986344C4E7B") i .r1 ?e' - Pop $R0 - StrCmp $R0 0 +3 - MessageBox MB_OK|MB_ICONEXCLAMATION "QupZilla installer is already running!" /SD IDOK - Abort - - ;Language selection dialog¨ - ;Return when running silent instalation - - IfSilent 0 +2 - return - - Push "" - Push ${LANG_ENGLISH} - Push English - Push ${LANG_CZECH} - Push Czech - Push ${LANG_SLOVAK} - Push Slovak - Push ${LANG_GERMAN} - Push German - Push ${LANG_DUTCH} - Push Dutch - Push ${LANG_PORTUGUESE} - Push Portuguese - Push ${LANG_GREEK} - Push Greek - Push ${LANG_FRENCH} - Push French - Push ${LANG_ITALIAN} - Push Italian - Push ${LANG_ROMANIAN} - Push Romanian - Push ${LANG_TRADCHINESE} - Push TraditionalChinese - Push ${LANG_SIMPCHINESE} - Push SimplifiedChinese - Push ${LANG_INDONESIAN} - Push Indonesian - Push ${LANG_GEORGIAN} - Push Georgian - Push ${LANG_JAPANESE} - Push Japanese - Push ${LANG_SWEDISH} - Push Swedish - Push ${LANG_POLISH} - Push Polish - Push ${LANG_UKRAINIAN} - Push Ukrainian - Push ${LANG_CATALAN} - Push Catalan - Push ${LANG_SERBIAN} - Push Serbian - Push ${LANG_SERBIANLATIN} - Push SerbianLatin - Push ${LANG_FARSI} - Push Persian - Push ${LANG_HEBREW} - Push Hebrew - Push ${LANG_SPANISH} - Push Spanish - Push ${LANG_DANISH} - Push Danish - Push A ; A means auto count languages - ; for the auto count to work the first empty push (Push "") must remain - LangDLL::LangDialog "Installer Language" "Please select the language of the installer" - - Pop $LANGUAGE - StrCmp $LANGUAGE "cancel" 0 +2 - Abort -FunctionEnd - -Function RegisterCapabilities - !ifdef ___WINVER__NSH___ - ${If} ${AtLeastWinVista} - ; even if we don't associate QupZilla as default for ".htm" and ".html" - ; we need to write these ProgIds for future use! - ;(e.g.: user uses "Default Programs" on Win7 or Vista to set QupZilla as default.) - ${CreateProgId} "QupZilla.HTM" "$INSTDIR\qupzilla.exe" $(FILE_Htm) "$INSTDIR\qupzilla.exe,1" - ${CreateProgId} "QupZilla.HTML" "$INSTDIR\qupzilla.exe" $(FILE_Html) "$INSTDIR\qupzilla.exe,1" - ${CreateProgId} "QupZilla.HTTP" "$INSTDIR\qupzilla.exe" "URL:HyperText Transfer Protocol" "$INSTDIR\qupzilla.exe,0" - ${CreateProgId} "QupZilla.HTTPS" "$INSTDIR\qupzilla.exe" "URL:HyperText Transfer Protocol with Privacy" "$INSTDIR\qupzilla.exe,0" - - ; note: these lines just introduce capabilities of QupZilla to OS and don't change defaults! - WriteRegStr HKLM "${PRODUCT_CAPABILITIES_KEY}" "ApplicationDescription" "$(PRODUCT_DESC)" - WriteRegStr HKLM "${PRODUCT_CAPABILITIES_KEY}" "ApplicationIcon" "$INSTDIR\qupzilla.exe,0" - WriteRegStr HKLM "${PRODUCT_CAPABILITIES_KEY}" "ApplicationName" "${PRODUCT_NAME}" - WriteRegStr HKLM "${PRODUCT_CAPABILITIES_KEY}\FileAssociations" ".htm" "QupZilla.HTM" - WriteRegStr HKLM "${PRODUCT_CAPABILITIES_KEY}\FileAssociations" ".html" "QupZilla.HTML" - WriteRegStr HKLM "${PRODUCT_CAPABILITIES_KEY}\URLAssociations" "http" "QupZilla.HTTP" - WriteRegStr HKLM "${PRODUCT_CAPABILITIES_KEY}\URLAssociations" "https" "QupZilla.HTTPS" - WriteRegStr HKLM "${PRODUCT_CAPABILITIES_KEY}\Startmenu" "StartMenuInternet" "$INSTDIR\qupzilla.exe" - WriteRegStr HKLM "SOFTWARE\RegisteredApplications" "${PRODUCT_NAME}" "${PRODUCT_CAPABILITIES_KEY}" - ${EndIf} - !endif -FunctionEnd - -Function RunQupZillaAsUser - ${StdUtils.ExecShellAsUser} $0 "$INSTDIR\qupzilla.exe" "open" "" -FunctionEnd +; Falkon Windows Installer NSIS Script +; Copyright (C) 2010-2017 David Rosca +; 2012-2017 S. Razi Alavizadeh +; +; For compiling this script you need following plugins: +; FindProcDLL_plug-in, KillProcDLL_plug-in and 'AllAssociation.nsh' needs +; Registry_plug-in, Application_Association_Registration_plug-in +; Unicode version of them can be downloaded from: +; http://sourceforge.net/projects/findkillprocuni/files/bin/ +; http://nsis.sourceforge.net/Application_Association_Registration_plug-in +; http://nsis.sourceforge.net/Registry_plug-in + +!ifndef CUSTOM + !define VERSION 2.1.2 + !define ARCH x86 + !define MSVC_VER 140 + !define OPENSSL_BIN_DIR . + !define MSVC_REDIST_DIR . + !define QZ_BIN_DIR . + !define ICU_BIN_DIR . + !define QT_DIR . + !define QT_BIN_DIR . + !define QT_PLUGINS_DIR . + !define QTWEBENGINE_DICTIONARIES_DIR qtwebengine_dictionaries + !undef PORTABLE +!endif + +; WinVer.nsh was added in the same release that RequestExecutionLevel so check +; if ___WINVER__NSH___ is defined to determine if RequestExecutionLevel is +; available. +!include /NONFATAL WinVer.nsh +!include x64.nsh + +!ifndef PORTABLE + RequestExecutionLevel admin +!else + RequestExecutionLevel user +!endif + +!addplugindir "wininstall\" + +!include "StdUtils.nsh" +!include "FileFunc.nsh" +!include "wininstall\AllAssociation.nsh" +SetCompressor /SOLID /FINAL lzma + +!define PRODUCT_NAME "Falkon" +!define /date PRODUCT_VERSION "${VERSION}" +!define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\falkon.exe" +!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" +!define PRODUCT_UNINST_ROOT_KEY "HKLM" +!define PRODUCT_CAPABILITIES_KEY "Software\${PRODUCT_NAME}\Capabilities" + +!include "MUI.nsh" +!define MUI_ABORTWARNING +!define MUI_ICON "wininstall\install.ico" +!define MUI_UNICON "wininstall\uninstall.ico" +!define MUI_WELCOMEFINISHPAGE_BITMAP "wininstall\welcome.bmp" +!define MUI_UNWELCOMEFINISHPAGE_BITMAP "wininstall\welcome.bmp" + +!insertmacro MUI_PAGE_WELCOME +!insertmacro MUI_PAGE_LICENSE ${QZ_BIN_DIR}\COPYRIGHT.txt +!insertmacro MUI_PAGE_COMPONENTS +!insertmacro MUI_PAGE_DIRECTORY +!insertmacro MUI_PAGE_INSTFILES + +!define MUI_FINISHPAGE_RUN +!define MUI_FINISHPAGE_RUN_FUNCTION "RunFalkonAsUser" +!insertmacro MUI_PAGE_FINISH + +!insertmacro MUI_UNPAGE_WELCOME +!insertmacro MUI_UNPAGE_CONFIRM +!insertmacro MUI_UNPAGE_INSTFILES +!insertmacro MUI_UNPAGE_FINISH + +!insertmacro MUI_LANGUAGE "English" +!insertmacro MUI_LANGUAGE "Czech" +!insertmacro MUI_LANGUAGE "Slovak" +!insertmacro MUI_LANGUAGE "German" +!insertmacro MUI_LANGUAGE "Dutch" +!insertmacro MUI_LANGUAGE "Portuguese" +!insertmacro MUI_LANGUAGE "Greek" +!insertmacro MUI_LANGUAGE "French" +!insertmacro MUI_LANGUAGE "Italian" +!insertmacro MUI_LANGUAGE "Romanian" +!insertmacro MUI_LANGUAGE "Tradchinese" +!insertmacro MUI_LANGUAGE "Simpchinese" +!insertmacro MUI_LANGUAGE "Indonesian" +!insertmacro MUI_LANGUAGE "Georgian" +!insertmacro MUI_LANGUAGE "Japanese" +!insertmacro MUI_LANGUAGE "Swedish" +!insertmacro MUI_LANGUAGE "Polish" +!insertmacro MUI_LANGUAGE "Ukrainian" +!insertmacro MUI_LANGUAGE "Catalan" +!insertmacro MUI_LANGUAGE "Serbian" +!insertmacro MUI_LANGUAGE "SerbianLatin" +!insertmacro MUI_LANGUAGE "Farsi" +!insertmacro MUI_LANGUAGE "Hebrew" +!insertmacro MUI_LANGUAGE "Spanish" +!insertmacro MUI_LANGUAGE "Arabic" +!insertmacro MUI_LANGUAGE "Basque" +!insertmacro MUI_LANGUAGE "Danish" + +!insertmacro MUI_RESERVEFILE_LANGDLL + +Name "${PRODUCT_NAME} ${PRODUCT_VERSION}" +OutFile "${PRODUCT_NAME} ${PRODUCT_VERSION} Installer.exe" +InstallDir "$PROGRAMFILES\${PRODUCT_NAME}\" +InstallDirRegKey HKLM "${PRODUCT_DIR_REGKEY}" "" +ShowInstDetails show +ShowUnInstDetails show + +!include "wininstall\languages.nsh" + +Section !$(TITLE_SecMain) SecMain + SectionIn RO + FindProcDLL::FindProc "falkon.exe" + IntCmp $R0 1 0 notRunning + MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION "$(MSG_RunningInstance)" /SD IDOK IDCANCEL AbortInstallation + KillProcDLL::KillProc "falkon.exe" + Sleep 100 + Goto notRunning +AbortInstallation: + Abort "$(MSG_InstallationCanceled)" + +notRunning: + SetOverwrite on + + SetOutPath "$INSTDIR" + File "${QZ_BIN_DIR}\COPYRIGHT.txt" + File "${QZ_BIN_DIR}\falkon.exe" + File "${QZ_BIN_DIR}\falkon.dll" + File "${QZ_BIN_DIR}\qt.conf" + File "${OPENSSL_BIN_DIR}\libeay32.dll" + File "${OPENSSL_BIN_DIR}\ssleay32.dll" + File "${MSVC_REDIST_DIR}\*" + File "${ICU_BIN_DIR}\icudt54.dll" + File "${ICU_BIN_DIR}\icuin54.dll" + File "${ICU_BIN_DIR}\icuuc54.dll" + File "${QT_BIN_DIR}\libEGL.dll" + File "${QT_BIN_DIR}\libGLESv2.dll" + File "${QT_BIN_DIR}\opengl32sw.dll" + File "${QT_BIN_DIR}\D3Dcompiler_47.dll" + File "${QT_BIN_DIR}\Qt5Core.dll" + File "${QT_BIN_DIR}\Qt5Gui.dll" + File "${QT_BIN_DIR}\Qt5Network.dll" + File "${QT_BIN_DIR}\Qt5Positioning.dll" + File "${QT_BIN_DIR}\Qt5PrintSupport.dll" + File "${QT_BIN_DIR}\Qt5Qml.dll" + File "${QT_BIN_DIR}\Qt5Quick.dll" + File "${QT_BIN_DIR}\Qt5QuickWidgets.dll" + File "${QT_BIN_DIR}\Qt5Sql.dll" + File "${QT_BIN_DIR}\Qt5Svg.dll" + File "${QT_BIN_DIR}\Qt5WinExtras.dll" + File "${QT_BIN_DIR}\Qt5WebEngine.dll" + File "${QT_BIN_DIR}\Qt5WebEngineCore.dll" + File "${QT_BIN_DIR}\Qt5WebEngineWidgets.dll" + File "${QT_BIN_DIR}\Qt5WebChannel.dll" + File "${QT_BIN_DIR}\Qt5Widgets.dll" + File "${QT_BIN_DIR}\QtWebEngineProcess.exe" + + SetOutPath "$INSTDIR\iconengines" + File "${QT_PLUGINS_DIR}\iconengines\qsvgicon.dll" + + SetOutPath "$INSTDIR\imageformats" + File "${QT_PLUGINS_DIR}\imageformats\*.dll" + + SetOutPath "$INSTDIR\platforms" + File "${QT_PLUGINS_DIR}\platforms\qwindows.dll" + + SetOutPath "$INSTDIR\printsupport" + File "${QT_PLUGINS_DIR}\printsupport\windowsprintersupport.dll" + + SetOutPath "$INSTDIR\qml\QtQuick.2" + File "${QT_DIR}\qml\QtQuick.2\*" + + SetOutPath "$INSTDIR\qml\QtWebEngine" + File "${QT_DIR}\qml\QtWebEngine\*" + + SetOutPath "$INSTDIR\resources" + File "${QT_DIR}\resources\*" + + SetOutPath "$INSTDIR\sqldrivers" + File "${QT_PLUGINS_DIR}\sqldrivers\qsqlite.dll" + + SetOutPath "$INSTDIR\translations\qtwebengine_locales" + File "${QT_DIR}\translations\qtwebengine_locales\*" + + SetOutPath "$INSTDIR\qtwebengine_dictionaries\doc" + ; In some packages underline '_' is used and in some other packages dash '-' is used so we use wildcard + File "${QTWEBENGINE_DICTIONARIES_DIR}\doc\README*en*US.txt" + + SetOutPath "$INSTDIR\qtwebengine_dictionaries" + ; in some packages *.bdic files use dash '-' instead of underline '_' followed by a version number. e.g. en-US-3-0.bdic + File "${QTWEBENGINE_DICTIONARIES_DIR}\en*US*.bdic" + + !ifndef PORTABLE + call RegisterCapabilities + !endif +SectionEnd + +SectionGroup $(TITLE_SecThemes) SecThemes + + Section Default SecDefault + SectionIn RO + SetOutPath "$INSTDIR\themes\windows" + File "${QZ_BIN_DIR}\themes\windows\*" + SetOutPath "$INSTDIR\themes\windows\images" + File "${QZ_BIN_DIR}\themes\windows\images\*" + SectionEnd + + Section Chrome SecChrome + SetOutPath "$INSTDIR\themes\chrome" + File "${QZ_BIN_DIR}\themes\chrome\*" + SetOutPath "$INSTDIR\themes\chrome\images" + File "${QZ_BIN_DIR}\themes\chrome\images\*" + SectionEnd + + Section Mac SecMac + SetOutPath "$INSTDIR\themes\mac" + File "${QZ_BIN_DIR}\themes\mac\*" + SetOutPath "$INSTDIR\themes\mac\images" + File "${QZ_BIN_DIR}\themes\mac\images\*" + SectionEnd + + Section Breathe SecBreathe + SetOutPath "$INSTDIR\themes\breathe" + File "${QZ_BIN_DIR}\themes\breathe\*" + SetOutPath "$INSTDIR\themes\breathe\images" + File "${QZ_BIN_DIR}\themes\breathe\images\*" + SectionEnd +SectionGroupEnd + +Section $(TITLE_SecTranslations) SecTranslations + SetOutPath "$INSTDIR\locale" + File "${QZ_BIN_DIR}\locale\*.qm" + SetOutPath "$INSTDIR\qtwebengine_dictionaries\doc" + File "${QTWEBENGINE_DICTIONARIES_DIR}\doc\*" + SetOutPath "$INSTDIR\qtwebengine_dictionaries" + File "${QTWEBENGINE_DICTIONARIES_DIR}\*.bdic" +SectionEnd + +Section $(TITLE_SecPlugins) SecPlugins + SetOutPath "$INSTDIR\plugins" + File "${QZ_BIN_DIR}\plugins\*.dll" +SectionEnd + + +!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN + !insertmacro MUI_DESCRIPTION_TEXT ${SecMain} $(DESC_SecMain) + !insertmacro MUI_DESCRIPTION_TEXT ${SecTranslations} $(DESC_SecTranslations) + !insertmacro MUI_DESCRIPTION_TEXT ${SecPlugins} $(DESC_SecPlugins) + !ifndef PORTABLE + !insertmacro MUI_DESCRIPTION_TEXT ${SecDesktop} $(DESC_SecDesktop) + !insertmacro MUI_DESCRIPTION_TEXT ${SecExtensions} $(DESC_SecExtensions) + !endif + !insertmacro MUI_DESCRIPTION_TEXT ${SecThemes} $(DESC_SecThemes) + + !ifndef PORTABLE + !insertmacro MUI_DESCRIPTION_TEXT ${SecSetASDefault} $(DESC_SecSetASDefault) + !insertmacro MUI_DESCRIPTION_TEXT ${SecProtocols} $(DESC_SecProtocols) + !endif +!insertmacro MUI_FUNCTION_DESCRIPTION_END + + +!ifndef PORTABLE + SectionGroup $(TITLE_SecSetASDefault) SecSetASDefault + Section $(TITLE_SecExtensions) SecExtensions + SetOutPath "$INSTDIR" + ${RegisterAssociation} ".htm" "$INSTDIR\falkon.exe" "Falkon.HTM" $(FILE_Htm) "$INSTDIR\falkon.exe,1" "file" + ${RegisterAssociation} ".html" "$INSTDIR\falkon.exe" "Falkon.HTML" $(FILE_Html) "$INSTDIR\falkon.exe,1" "file" + ${UpdateSystemIcons} + SectionEnd + + Section $(TITLE_SecProtocols) SecProtocols + ${RegisterAssociation} "http" "$INSTDIR\falkon.exe" "Falkon.HTTP" "URL:HyperText Transfer Protocol" "$INSTDIR\falkon.exe,0" "protocol" + ${RegisterAssociation} "https" "$INSTDIR\falkon.exe" "Falkon.HTTPS" "URL:HyperText Transfer Protocol with Privacy" "$INSTDIR\falkon.exe,0" "protocol" + ${UpdateSystemIcons} + SectionEnd + SectionGroupEnd + + Section -StartMenu + SetOutPath "$INSTDIR" + SetShellVarContext all + CreateDirectory "$SMPROGRAMS\Falkon" + CreateShortCut "$SMPROGRAMS\Falkon\Uninstall.lnk" "$INSTDIR\Uninstall.exe" + CreateShortCut "$SMPROGRAMS\Falkon\Falkon.lnk" "$INSTDIR\falkon.exe" + CreateShortCut "$SMPROGRAMS\Falkon\License.lnk" "$INSTDIR\COPYRIGHT.txt" + SectionEnd + + Section $(TITLE_SecDesktop) SecDesktop + SetOutPath "$INSTDIR" + CreateShortCut "$DESKTOP\Falkon.lnk" "$INSTDIR\falkon.exe" "" + SectionEnd + + Section -Uninstaller + WriteUninstaller "$INSTDIR\uninstall.exe" + WriteRegStr HKLM "${PRODUCT_DIR_REGKEY}" "" "$INSTDIR\falkon.exe" + WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)" + WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\Uninstall.exe" + WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\falkon.exe" + WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}" + WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "Publisher" "Falkon Team" + WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "HelpLink" "https://github.com/QupZilla/qupzilla/wiki" + WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "InstallLocation" "$INSTDIR" + WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "InstallSource" "$EXEDIR" + WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "URLInfoAbout" "http://www.qupzilla.com" + WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "URLUpdateInfo" "http://blog.qupzilla.com/" + ${GetSize} "$INSTDIR" "/S=0K" $0 $1 $2 + WriteRegDWORD ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "EstimatedSize" "$0" + SectionEnd + + Section Uninstall + FindProcDLL::FindProc "falkon.exe" + IntCmp $R0 1 0 notRunning + MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION "$(MSG_RunningInstance)" /SD IDOK IDCANCEL AbortInstallation + KillProcDLL::KillProc "falkon.exe" + Sleep 100 + Goto notRunning + AbortInstallation: + Abort "$(MSG_InstallationCanceled)" + + notRunning: + SetShellVarContext all + Delete "$DESKTOP\Falkon.lnk" + RMDir /r "$INSTDIR" + RMDir /r "$SMPROGRAMS\Falkon" + DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" + DeleteRegKey HKLM "${PRODUCT_DIR_REGKEY}" + + DeleteRegKey HKLM "Software\${PRODUCT_NAME}" + DeleteRegValue HKLM "SOFTWARE\RegisteredApplications" "${PRODUCT_NAME}" + + ${UnRegisterAssociation} ".htm" "Falkon.HTM" "$INSTDIR\falkon.exe" "file" + ${UnRegisterAssociation} ".html" "Falkon.HTML" "$INSTDIR\falkon.exe" "file" + ${UnRegisterAssociation} "http" "Falkon.HTTP" "$INSTDIR\falkon.exe" "protocol" + ${UnRegisterAssociation} "https" "Falkon.HTTPS" "$INSTDIR\falkon.exe" "protocol" + ${UpdateSystemIcons} + SectionEnd +!endif + +BrandingText "${PRODUCT_NAME} ${PRODUCT_VERSION} Installer" + +Function .onInit + ;Prevent running installer of 64-bit Falkon on 32-bit Windows + ${If} ${RunningX64} + ${If} ${ARCH} == "x64" + StrCpy $InstDir "$PROGRAMFILES64\${PRODUCT_NAME}\" + ${Else} + StrCpy $InstDir "$PROGRAMFILES32\${PRODUCT_NAME}\" + ${Endif} + ${Else} + ${If} ${ARCH} == "x64" + MessageBox MB_OK|MB_ICONEXCLAMATION "This installation requiers Windows x64!" + Quit + ${Else} + StrCpy $InstDir "$PROGRAMFILES\${PRODUCT_NAME}\" + ${Endif} + ${EndIf} + + !ifdef PORTABLE + StrCpy $InstDir "$DESKTOP\${PRODUCT_NAME} Portable\" + !endif + + ;Prevent Multiple Instances + System::Call 'kernel32::CreateMutexA(i 0, i 0, t "FalkonInstaller-4ECB4694-2C39-4f93-9122-A986344C4E7B") i .r1 ?e' + Pop $R0 + StrCmp $R0 0 +3 + MessageBox MB_OK|MB_ICONEXCLAMATION "Falkon installer is already running!" /SD IDOK + Abort + + ;Language selection dialog¨ + ;Return when running silent instalation + + IfSilent 0 +2 + return + + Push "" + Push ${LANG_ENGLISH} + Push English + Push ${LANG_CZECH} + Push Czech + Push ${LANG_SLOVAK} + Push Slovak + Push ${LANG_GERMAN} + Push German + Push ${LANG_DUTCH} + Push Dutch + Push ${LANG_PORTUGUESE} + Push Portuguese + Push ${LANG_GREEK} + Push Greek + Push ${LANG_FRENCH} + Push French + Push ${LANG_ITALIAN} + Push Italian + Push ${LANG_ROMANIAN} + Push Romanian + Push ${LANG_TRADCHINESE} + Push TraditionalChinese + Push ${LANG_SIMPCHINESE} + Push SimplifiedChinese + Push ${LANG_INDONESIAN} + Push Indonesian + Push ${LANG_GEORGIAN} + Push Georgian + Push ${LANG_JAPANESE} + Push Japanese + Push ${LANG_SWEDISH} + Push Swedish + Push ${LANG_POLISH} + Push Polish + Push ${LANG_UKRAINIAN} + Push Ukrainian + Push ${LANG_CATALAN} + Push Catalan + Push ${LANG_SERBIAN} + Push Serbian + Push ${LANG_SERBIANLATIN} + Push SerbianLatin + Push ${LANG_FARSI} + Push Persian + Push ${LANG_HEBREW} + Push Hebrew + Push ${LANG_SPANISH} + Push Spanish + Push ${LANG_DANISH} + Push Danish + Push A ; A means auto count languages + ; for the auto count to work the first empty push (Push "") must remain + LangDLL::LangDialog "Installer Language" "Please select the language of the installer" + + Pop $LANGUAGE + StrCmp $LANGUAGE "cancel" 0 +2 + Abort +FunctionEnd + +Function RegisterCapabilities + !ifdef ___WINVER__NSH___ + ${If} ${AtLeastWinVista} + ; even if we don't associate Falkon as default for ".htm" and ".html" + ; we need to write these ProgIds for future use! + ;(e.g.: user uses "Default Programs" on Win7 or Vista to set Falkon as default.) + ${CreateProgId} "Falkon.HTM" "$INSTDIR\falkon.exe" $(FILE_Htm) "$INSTDIR\falkon.exe,1" + ${CreateProgId} "Falkon.HTML" "$INSTDIR\falkon.exe" $(FILE_Html) "$INSTDIR\falkon.exe,1" + ${CreateProgId} "Falkon.HTTP" "$INSTDIR\falkon.exe" "URL:HyperText Transfer Protocol" "$INSTDIR\falkon.exe,0" + ${CreateProgId} "Falkon.HTTPS" "$INSTDIR\falkon.exe" "URL:HyperText Transfer Protocol with Privacy" "$INSTDIR\falkon.exe,0" + + ; note: these lines just introduce capabilities of Falkon to OS and don't change defaults! + WriteRegStr HKLM "${PRODUCT_CAPABILITIES_KEY}" "ApplicationDescription" "$(PRODUCT_DESC)" + WriteRegStr HKLM "${PRODUCT_CAPABILITIES_KEY}" "ApplicationIcon" "$INSTDIR\falkon.exe,0" + WriteRegStr HKLM "${PRODUCT_CAPABILITIES_KEY}" "ApplicationName" "${PRODUCT_NAME}" + WriteRegStr HKLM "${PRODUCT_CAPABILITIES_KEY}\FileAssociations" ".htm" "Falkon.HTM" + WriteRegStr HKLM "${PRODUCT_CAPABILITIES_KEY}\FileAssociations" ".html" "Falkon.HTML" + WriteRegStr HKLM "${PRODUCT_CAPABILITIES_KEY}\URLAssociations" "http" "Falkon.HTTP" + WriteRegStr HKLM "${PRODUCT_CAPABILITIES_KEY}\URLAssociations" "https" "Falkon.HTTPS" + WriteRegStr HKLM "${PRODUCT_CAPABILITIES_KEY}\Startmenu" "StartMenuInternet" "$INSTDIR\falkon.exe" + WriteRegStr HKLM "SOFTWARE\RegisteredApplications" "${PRODUCT_NAME}" "${PRODUCT_CAPABILITIES_KEY}" + ${EndIf} + !endif +FunctionEnd + +Function RunFalkonAsUser + ${StdUtils.ExecShellAsUser} $0 "$INSTDIR\falkon.exe" "open" "" +FunctionEnd diff --git a/windows/languages.nsh b/windows/languages.nsh index 6b3a2303..44676f8f 100644 --- a/windows/languages.nsh +++ b/windows/languages.nsh @@ -1,748 +1,748 @@ -;;;;English -LangString PRODUCT_DESC ${LANG_ENGLISH} "QupZilla is a new, fast and secure open-source WWW browser. QupZilla is licensed under GPL version 3 or (at your option) any later version. It is based on WebKit core and Qt Framework." -; -LangString TITLE_SecMain ${LANG_ENGLISH} "Main Components" -LangString TITLE_SecTranslations ${LANG_ENGLISH} "Translations" -LangString TITLE_SecPlugins ${LANG_ENGLISH} "Plugins" -LangString TITLE_SecDesktop ${LANG_ENGLISH} "Desktop Icon" -LangString TITLE_SecExtensions ${LANG_ENGLISH} "File Associations" -LangString TITLE_SecThemes ${LANG_ENGLISH} "Themes" -LangString TITLE_SecSetASDefault ${LANG_ENGLISH} "Default Browser" -LangString TITLE_SecProtocols ${LANG_ENGLISH} "Protocol Associations" - -LangString FILE_Htm ${LANG_ENGLISH} "HTM File" -LangString FILE_Html ${LANG_ENGLISH} "HTML File" -; -LangString DESC_SecMain ${LANG_ENGLISH} "Main components of application." -LangString DESC_SecTranslations ${LANG_ENGLISH} "Other translations available to install. Default is English." -LangString DESC_SecPlugins ${LANG_ENGLISH} "Other plugins available to install." -LangString DESC_SecDesktop ${LANG_ENGLISH} "Add launcher to desktop." -LangString DESC_SecExtensions ${LANG_ENGLISH} "Associate QupZilla with .htm(l) files" -LangString DESC_SecThemes ${LANG_ENGLISH} "Additional themes for QupZilla" -LangString DESC_SecSetASDefault ${LANG_ENGLISH} "Set QupZilla as default internet browser" -LangString DESC_SecProtocols ${LANG_ENGLISH} "Associate QupZilla with http(s) and ftp protocols" -; -LangString MSG_RunningInstance ${LANG_ENGLISH} "QupZilla is already running! Do you want the installer try to terminate it?" -LangString MSG_InstallationCanceled ${LANG_ENGLISH} "Process cancelled by user." - -;;;;Arabic -LangString PRODUCT_DESC ${LANG_ARABIC} "كَبزيلّا متصفّح للوب جديد سريع وآمن ومفتوح المصدر. يُرخَّص استخدامه وفق الإصدار الثالث من رخصة جنو العمومية (GPL) أو أي إصدار أحدث من ذلك (اختر كما تشاء). يُبنى كَبزيلّا على محرّك العرض WebKitوإطار العمل Qt." -; -LangString TITLE_SecMain ${LANG_ARABIC} "المكونات الأساسية" -LangString TITLE_SecTranslations ${LANG_ARABIC} "الترجمات" -LangString TITLE_SecPlugins ${LANG_ARABIC} "الإضافات" -LangString TITLE_SecDesktop ${LANG_ARABIC} "رمز على سطح المكتب" -LangString TITLE_SecExtensions ${LANG_ARABIC} "ارتباطات الملفات" -LangString TITLE_SecThemes ${LANG_ARABIC} "السمات" -LangString TITLE_SecSetASDefault ${LANG_ARABIC} "المتصفح المبدئي" -LangString TITLE_SecProtocols ${LANG_ARABIC} "ارتباطات البروتوكولات" - -LangString FILE_Htm ${LANG_ARABIC} "ملف HTM" -LangString FILE_Html ${LANG_ARABIC} "ملف HTML" -; -LangString DESC_SecMain ${LANG_ARABIC} "المكونات الرئيسية للبرنامج." -LangString DESC_SecTranslations ${LANG_ARABIC} "ترجمات أخرى متوفرة للتثبيت. اللغة المبدئية هي الإنكليزية." -LangString DESC_SecPlugins ${LANG_ARABIC} "إضافات أخرى متوفّرة للتنزيل." -LangString DESC_SecDesktop ${LANG_ARABIC} "أضف اختصارًا لتشغيل كَبزيلا من سطح المكتب." -LangString DESC_SecExtensions ${LANG_ARABIC} "اربط كَبزيلّا بملفات HTML ذات اللواحق .htm أو .html." -LangString DESC_SecThemes ${LANG_ARABIC} "سمات أخرى لكَبزيلّا" -LangString DESC_SecSetASDefault ${LANG_ARABIC} "اجعل كَبزيلا المتصفح المبدئيّ" -LangString DESC_SecProtocols ${LANG_ARABIC} "اربط كَبزيلّا ببروتوكولات HTTP وHTTPS وFTP." -; -LangString MSG_RunningInstance ${LANG_ARABIC} "كَبزيلّا مفتوح الآن! أتريد من المُثبِّت إنهاءه الآن؟" -LangString MSG_InstallationCanceled ${LANG_ARABIC} "ألغى المستخدم العملية." - -;;;;Spanish -LangString PRODUCT_DESC ${LANG_SPANISH} "QupZilla es un nuevo, rápido y seguro navegador web de código abierto. QupZilla está bajo licencia GPL versión 3 o (o en su opción) en cualquier versión. Está basado en el motor WebKit y en Qt Framework." -; -LangString TITLE_SecMain ${LANG_SPANISH} "Componentes iniciales" -LangString TITLE_SecTranslations ${LANG_SPANISH} "Traducciones" -LangString TITLE_SecPlugins ${LANG_SPANISH} "Plugins" -LangString TITLE_SecDesktop ${LANG_SPANISH} "Icono de escritorio" -LangString TITLE_SecExtensions ${LANG_SPANISH} "Asociación de archivos" -LangString TITLE_SecThemes ${LANG_SPANISH} "Temas" -LangString TITLE_SecSetASDefault ${LANG_SPANISH} "Navegador por defecto" -LangString TITLE_SecProtocols ${LANG_SPANISH} "Asociaciones de protocolo" - -LangString FILE_Htm ${LANG_SPANISH} "Archivo HTM" -LangString FILE_Html ${LANG_SPANISH} "Archivo HTML" -; -LangString DESC_SecMain ${LANG_SPANISH} "Componentes iniciales de aplicación" -LangString DESC_SecTranslations ${LANG_SPANISH} "Otras traduciones disponibles al instalar. Por defecto en inglés." -LangString DESC_SecPlugins ${LANG_SPANISH} "Otros plugins disponibles al instalar." -LangString DESC_SecDesktop ${LANG_SPANISH} "Añade acceso directo al escritorio." -LangString DESC_SecExtensions ${LANG_SPANISH} "Asociar QupZilla con archivos .htm(l)" -LangString DESC_SecThemes ${LANG_SPANISH} "Temas adicionales para QupZilla" -LangString DESC_SecSetASDefault ${LANG_SPANISH} "Hacer QupZilla tu navegador web por defecto" -LangString DESC_SecProtocols ${LANG_SPANISH} "Asociar QupZilla con los protocolos http(s) y ftp" -; -LangString MSG_RunningInstance ${LANG_SPANISH} "QupZilla se está ejecutando, Quieres que el instalador intente finalizarlo?" -LangString MSG_InstallationCanceled ${LANG_SPANISH} "Proceso cancelado por usuario." - -;;;;Czech -LangString TITLE_SecMain ${LANG_CZECH} "Hlavní komponenty" -LangString TITLE_SecTranslations ${LANG_CZECH} "Překlady" -LangString TITLE_SecPlugins ${LANG_CZECH} "Doplňky" -LangString TITLE_SecDesktop ${LANG_CZECH} "Zástupce na ploše" -LangString TITLE_SecExtensions ${LANG_CZECH} "Asociace souborů" -LangString TITLE_SecThemes ${LANG_CZECH} "Témata" - -LangString FILE_Htm ${LANG_CZECH} "Soubor HTM" -LangString FILE_Html ${LANG_CZECH} "Soubor HTML" -; -LangString DESC_SecMain ${LANG_CZECH} "Hlavní komponenty aplikace." -LangString DESC_SecTranslations ${LANG_CZECH} "Ostatní překlady dostupné k instalaci. Angličtina je defaultní." -LangString DESC_SecPlugins ${LANG_CZECH} "Ostatní doplňky dostupné k instalaci." -LangString DESC_SecDesktop ${LANG_CZECH} "Přidat zástupce na plochu." -LangString DESC_SecExtensions ${LANG_CZECH} "Associovat QupZillu s .htm(l) soubory" -LangString DESC_SecThemes ${LANG_CZECH} "Dodatečná témata pro QupZillu" - -LangString PRODUCT_DESC ${LANG_CZECH} "QupZilla je nový, rychlý a bezpečný open-source WWW prohlížeč. QupZilla je licencována pod GPL verze 3 nebo (podle vaší volby) jakékoliv vyšší verze. Prohlížeč je založen na jádru WebKit a Qt Frameworku." -LangString TITLE_SecSetASDefault ${LANG_CZECH} "Výchozí prohlížeč" -LangString TITLE_SecProtocols ${LANG_CZECH} "Asociace protokolů" -LangString DESC_SecSetASDefault ${LANG_CZECH} "Nastavit QupZillu jako výchozí internetový prohlížeč" -LangString DESC_SecProtocols ${LANG_CZECH} "Asociovat QupZillu s http(s) a ftp protokoly" -LangString MSG_RunningInstance ${LANG_CZECH} "QupZilla je právě spuštěna. Chcete aby ji instalátor zkusil ukončit?" -LangString MSG_InstallationCanceled ${LANG_CZECH} "Proces zrušen uživatelem." - -;;;;Catalan -LangString PRODUCT_DESC ${LANG_CATALAN} "El QupZilla és un navegador web de codi obert nou, ràpid i segur. QupZilla està llicenciat sota GPL versió 3.0 o (si ho preferiu) qualsevol versió posterior. Està basat en WebKit i Qt." -; -LangString TITLE_SecMain ${LANG_CATALAN} "Components principals" -LangString TITLE_SecTranslations ${LANG_CATALAN} "Traduccions" -LangString TITLE_SecPlugins ${LANG_CATALAN} "Complements" -LangString TITLE_SecDesktop ${LANG_CATALAN} "Icona de l'escriptori" -LangString TITLE_SecExtensions ${LANG_CATALAN} "Associacions de fitxers" -LangString TITLE_SecThemes ${LANG_CATALAN} "Temes" -LangString TITLE_SecSetASDefault ${LANG_CATALAN} "Navegador per defecte" -LangString TITLE_SecProtocols ${LANG_CATALAN} "Associacions de protocols" - -LangString FILE_Htm ${LANG_CATALAN} "Fitxer HTM" -LangString FILE_Html ${LANG_CATALAN} "Fitxer HTML" -; -LangString DESC_SecMain ${LANG_CATALAN} "Components principals de l'aplicació." -LangString DESC_SecTranslations ${LANG_CATALAN} "Altres traduccions disponibles per instal·lar. L'idioma predeterminat és l'anglès." -LangString DESC_SecPlugins ${LANG_CATALAN} "Altres plugins disponibles per instal·lar." -LangString DESC_SecDesktop ${LANG_CATALAN} "Afegeix una drecera a l'escriptori." -LangString DESC_SecExtensions ${LANG_CATALAN} "Associa el QupZilla amb els fitxers .htm i .html" -LangString DESC_SecThemes ${LANG_CATALAN} "Temes addicionals per al QupZilla" -LangString DESC_SecSetASDefault ${LANG_CATALAN} "Fes que el QupZilla sigui el navegador predeterminat" -LangString DESC_SecProtocols ${LANG_CATALAN} "Associa el QupZilla amb els protocols http i https" -; -LangString MSG_RunningInstance ${LANG_CATALAN} "El QupZilla ja està actiu. Voleu que l'instal·lador provi d'aturar-lo?" -LangString MSG_InstallationCanceled ${LANG_CATALAN} "L'usuari ha cancel·lat el procés." - -;;;;Slovak -LangString PRODUCT_DESC ${LANG_SLOVAK} "QupZilla je nový, rýchly a bezpečný open-source internetový prehliadač. QupZilla je licencovaná pod licenciou GPL verzie 3 alebo (podľa vášho uváženia) hocijakej novšej verzie. Je založená na jadre WebKit a frameworku Qt." -; -LangString TITLE_SecMain ${LANG_SLOVAK} "Hlavné komponenty" -LangString TITLE_SecTranslations ${LANG_SLOVAK} "Preklady" -LangString TITLE_SecPlugins ${LANG_SLOVAK} "Doplnky" -LangString TITLE_SecDesktop ${LANG_SLOVAK} "Odkaz na ploche" -LangString TITLE_SecExtensions ${LANG_SLOVAK} "Asociácia súborov" -LangString TITLE_SecThemes ${LANG_SLOVAK} "Témy" -LangString TITLE_SecSetASDefault ${LANG_SLOVAK} "Predvolený prehliadač" -LangString TITLE_SecProtocols ${LANG_SLOVAK} "Asociácie protokolov" - -LangString FILE_Htm ${LANG_SLOVAK} "Súbor HTM" -LangString FILE_Html ${LANG_SLOVAK} "Súbor HTML" -; -LangString DESC_SecMain ${LANG_SLOVAK} "Hlavné komponenty programu." -LangString DESC_SecTranslations ${LANG_SLOVAK} "Ostatné preklady dostupné na inštaláciu. Angličtina je predvolená" -LangString DESC_SecPlugins ${LANG_SLOVAK} "Ostatné doplnky dustupné na inštaláciu" -LangString DESC_SecDesktop ${LANG_SLOVAK} "Pridať odkaz na plochu." -LangString DESC_SecExtensions ${LANG_SLOVAK} "Associovať QupZillu s .htm(l) súbormi" -LangString DESC_SecThemes ${LANG_SLOVAK} "Ďalšie témy vzhľadu pre QupZillu" -LangString DESC_SecSetASDefault ${LANG_SLOVAK} "Nastaviť Qupzillu ako predvolený internetový prehliadač" -LangString DESC_SecProtocols ${LANG_SLOVAK} "Asociovať QupZillu s http(s) a ftp protokolmi" -; -LangString MSG_RunningInstance ${LANG_SLOVAK} "QupZilla je už spustená! Chcete, aby sa inštalátor pokúsil ju násilne ukončiť?" -LangString MSG_InstallationCanceled ${LANG_SLOVAK} "Proces zrušený používateľom." - -;;;;German -LangString PRODUCT_DESC ${LANG_GERMAN} "QupZilla ist ein neuer, schneller und sicherer, quelloffener Web Browser. QupZilla ist lizensiert unter GPL Version 3 oder später. Er nutzt Webkit und das Qt Framework." -; -LangString TITLE_SecMain ${LANG_GERMAN} "Hauptkomponenten" -LangString TITLE_SecTranslations ${LANG_GERMAN} "Übersetzungen" -LangString TITLE_SecPlugins ${LANG_GERMAN} "Plugins" -LangString TITLE_SecDesktop ${LANG_GERMAN} "Desktop Symbol" -LangString TITLE_SecExtensions ${LANG_GERMAN} "Dateiverknüpfungen" -LangString TITLE_SecThemes ${LANG_GERMAN} "Themen" -LangString TITLE_SecSetASDefault ${LANG_GERMAN} "Standard-Browser" -LangString TITLE_SecProtocols ${LANG_GERMAN} "Protokollverknüpfungen" - -LangString FILE_Htm ${LANG_GERMAN} "HTM-Datei" -LangString FILE_Html ${LANG_GERMAN} "HTML-Datei" - -LangString DESC_SecMain ${LANG_GERMAN} "Hauptkomponenten der Anwendung." -LangString DESC_SecTranslations ${LANG_GERMAN} "Weitere Übersetzungen sind verfügbar. Die Standardsprache ist Englisch." -LangString DESC_SecPlugins ${LANG_GERMAN} "Weitere Plugins stehen zur Verfügung." -LangString DESC_SecDesktop ${LANG_GERMAN} "Starter zum Desktop hinzufügen." -LangString DESC_SecExtensions ${LANG_GERMAN} "Verknüpfe QupZilla mit *.htm(l) Dateien" -LangString DESC_SecThemes ${LANG_GERMAN} "Weitere Themen für QupZilla" -LangString DESC_SecSetASDefault ${LANG_GERMAN} "QupZilla als Standard-Browser verwenden" -LangString DESC_SecProtocols ${LANG_GERMAN} "Verknüpfe QupZilla mit HTTP(S)- und FTP-Protokoll" -; -LangString MSG_RunningInstance ${LANG_GERMAN} "QupZilla ist bereits gestartet! Soll die Installationsroutine versuchen, QupZilla zu beenden?" -LangString MSG_InstallationCanceled ${LANG_GERMAN} "Die Installation wurde vom Benutzer abgebrochen." - -;;;;Dutch -LangString TITLE_SecMain ${LANG_DUTCH} "Hoofdonderdelen" -LangString TITLE_SecTranslations ${LANG_DUTCH} "Vertalingen" -LangString TITLE_SecPlugins ${LANG_DUTCH} "Plugins" -LangString TITLE_SecDesktop ${LANG_DUTCH} "Bureaublad-pictogram" -LangString TITLE_SecExtensions ${LANG_DUTCH} "Bestandsassociaties" -LangString TITLE_SecThemes ${LANG_DUTCH} "Thema's" - -LangString FILE_Htm ${LANG_DUTCH} "HTM-bestand" -LangString FILE_Html ${LANG_DUTCH} "HTML-bestand" - -LangString DESC_SecMain ${LANG_DUTCH} "Hoofdonderdelen van het programma." -LangString DESC_SecTranslations ${LANG_DUTCH} "Beschikbare vertalingen om te installeren. Standaardtaal is Engels." -LangString DESC_SecPlugins ${LANG_DUTCH} "Beschikbare plugins om te installeren." -LangString DESC_SecDesktop ${LANG_DUTCH} "Voeg starter toe op bureaublad." -LangString DESC_SecExtensions ${LANG_DUTCH} "Associeer QupZilla met .htm en .html-bestanden" -LangString DESC_SecThemes ${LANG_DUTCH} "Extra thema's voor QupZilla" - -;;;;Portuguese -LangString PRODUCT_DESC ${LANG_PORTUGUESE} "O QupZilla é um navegador web rápido, seguro e de código livre. O QupZilla está sujeito aos termos da GPL versão 3 ou (por opção) qualquer versão posterior. O QupZilla é baseado nas tecnologias WebKit e Qt." -; -LangString TITLE_SecMain ${LANG_PORTUGUESE} "Principais componentes" -LangString TITLE_SecTranslations ${LANG_PORTUGUESE} "Traduções" -LangString TITLE_SecPlugins ${LANG_PORTUGUESE} "Plugins" -LangString TITLE_SecDesktop ${LANG_PORTUGUESE} "Ícone no ambiente de trabalho" -LangString TITLE_SecExtensions ${LANG_PORTUGUESE} "Associação de ficheiros" -LangString TITLE_SecThemes ${LANG_PORTUGUESE} "Temas" -LangString TITLE_SecSetASDefault ${LANG_PORTUGUESE} "Navegador pré-definido" -LangString TITLE_SecProtocols ${LANG_PORTUGUESE} "Associações" - -LangString FILE_Htm ${LANG_PORTUGUESE} "Ficheiro HTM" -LangString FILE_Html ${LANG_PORTUGUESE} "Ficheiro HTML" -; -LangString DESC_SecMain ${LANG_PORTUGUESE} "Principais componentes da aplicação" -LangString DESC_SecTranslations ${LANG_PORTUGUESE} "Outros idiomas disponíveis. O idioma padrão é inglês" -LangString DESC_SecPlugins ${LANG_PORTUGUESE} "Outros plugins disponíveis" -LangString DESC_SecDesktop ${LANG_PORTUGUESE} "Adicionar ícone ao ambiente de trabalho" -LangString DESC_SecExtensions ${LANG_PORTUGUESE} "Associar QupZilla aos ficheiros .htm e .html" -LangString DESC_SecThemes ${LANG_PORTUGUESE} "Temas extra para o QupZilla" -LangString DESC_SecSetASDefault ${LANG_PORTUGUESE} "Definir o QupZilla como navegador web padrão" -LangString DESC_SecProtocols ${LANG_PORTUGUESE} "Associar o QupZilla com os protocolos http e https" -; -LangString MSG_RunningInstance ${LANG_PORTUGUESE} "O QupZilla está em execução! Pretende que o instalador tente terminar o processo?" -LangString MSG_InstallationCanceled ${LANG_PORTUGUESE} "Processo cancelado pelo utilizador" -; -;;;;Greek -LangString TITLE_SecMain ${LANG_GREEK} "Κύρια στοιχεία" -LangString TITLE_SecTranslations ${LANG_GREEK} "Μεταφράσεις" -LangString TITLE_SecPlugins ${LANG_GREEK} "Πρόσθετα" -LangString TITLE_SecDesktop ${LANG_GREEK} "Εικονίδιο επιφάνειας" -LangString TITLE_SecExtensions ${LANG_GREEK} "Συσχετίσεις αρχείων" -LangString TITLE_SecThemes ${LANG_GREEK} "Θέματα" - -LangString FILE_Htm ${LANG_GREEK} "Αρχείο HTM" -LangString FILE_Html ${LANG_GREEK} "Αρχείο HTML" - -LangString DESC_SecMain ${LANG_GREEK} "Κυρια στοιχεία της εφαρμογής." -LangString DESC_SecTranslations ${LANG_GREEK} "Άλλες μεταφράσεις διαθέσιμες προς εγκατάσταση. Η προεπιλεγμένη είναι Αγγλικά." -LangString DESC_SecPlugins ${LANG_GREEK} "Άλλα πρόσθετα διαθέσιμα προς εγκατάσταση." -LangString DESC_SecDesktop ${LANG_GREEK} "Προσθήκη εκκινητή στην επιφάνεια." -LangString DESC_SecExtensions ${LANG_GREEK} "Συσχέτιση του QupZilla με αρχεία .htm και .html" -LangString DESC_SecThemes ${LANG_GREEK} "Πρόσθετα θέματα για το QupZilla" - -;;;;French -LangString PRODUCT_DESC ${LANG_FRENCH} "QupZilla est un nouveau navigateur Internet, libre, rapide et sûr. QupZilla est sous licence GPLv3 ou (selon votre version) une version plus récente. Il est basé sur WebKit et le framework Qt." - -LangString TITLE_SecMain ${LANG_FRENCH} "Composants principaux" -LangString TITLE_SecTranslations ${LANG_FRENCH} "Langues" -LangString TITLE_SecPlugins ${LANG_FRENCH} "Plugins" -LangString TITLE_SecDesktop ${LANG_FRENCH} "Icône de Bureau" -LangString TITLE_SecExtensions ${LANG_FRENCH} "Associations de fichiers" -LangString TITLE_SecThemes ${LANG_FRENCH} "Thèmes" -LangString TITLE_SecSetASDefault ${LANG_FRENCH} "Navigateur par défaut" -LangString TITLE_SecProtocols ${LANG_FRENCH} "Associations de protocoles" - -LangString FILE_Htm ${LANG_FRENCH} "Fichiers HTM " -LangString FILE_Html ${LANG_FRENCH} "Fichiers HTML" - -LangString DESC_SecMain ${LANG_FRENCH} "Composants principaux de l'application." -LangString DESC_SecTranslations ${LANG_FRENCH} "Autres langues disponibles à l'installation. La langue par défaut est l'anglais." -LangString DESC_SecPlugins ${LANG_FRENCH} "Autres plugins disponibles pour l'installation." -LangString DESC_SecDesktop ${LANG_FRENCH} "Ajouter une icône sur le bureau." -LangString DESC_SecExtensions ${LANG_FRENCH} "Associer QupZilla aux fichiers .htm et .html" -LangString DESC_SecThemes ${LANG_FRENCH} "Thèmes supplémentaires pour QupZilla" -LangString DESC_SecSetASDefault ${LANG_FRENCH} "Utiliser QupZilla comme navigateur par défaut" -LangString DESC_SecProtocols ${LANG_FRENCH} "Associer QupZilla aux protocoles http(s) et ftp" - -LangString MSG_RunningInstance ${LANG_FRENCH} "QupZilla est déjà en fonctionnement ! Voulez vous que l'installeur le ferme pour vous ?" -LangString MSG_InstallationCanceled ${LANG_FRENCH} "Processus annulé par l'utilisateur." - -;;;;Italian -LangString TITLE_SecMain ${LANG_ITALIAN} "Componenti principali" -LangString TITLE_SecTranslations ${LANG_ITALIAN} "Traduzioni" -LangString TITLE_SecPlugins ${LANG_ITALIAN} "Plugins" -LangString TITLE_SecDesktop ${LANG_ITALIAN} "Icona Desktop" -LangString TITLE_SecExtensions ${LANG_ITALIAN} "Associazione file" -LangString TITLE_SecThemes ${LANG_ITALIAN} "Temi" - -LangString FILE_Htm ${LANG_ITALIAN} "File HTM" -LangString FILE_Html ${LANG_ITALIAN} "File HTML" -; -LangString DESC_SecMain ${LANG_ITALIAN} "Componenti principali dell'applicazione." -LangString DESC_SecTranslations ${LANG_ITALIAN} "Altre traduzioni disponibili per l'installazione. Quella predefinita è l'Inglese." -LangString DESC_SecPlugins ${LANG_ITALIAN} "Altri plugins disponibili per l'installazione." -LangString DESC_SecDesktop ${LANG_ITALIAN} "Aggiunge il lanciatore al desktop." -LangString DESC_SecExtensions ${LANG_ITALIAN} "Associa QupZilla ai file .htm and .html" -LangString DESC_SecThemes ${LANG_ITALIAN} "Temi aggiuntivi per QupZilla" - -;;;;Romanian -LangString TITLE_SecMain ${LANG_ROMANIAN} "Componente principale" -LangString TITLE_SecTranslations ${LANG_ROMANIAN} "Traduceri" -LangString TITLE_SecPlugins ${LANG_ROMANIAN} "Plugin-uri" -LangString TITLE_SecDesktop ${LANG_ROMANIAN} "Iconiță Desktop" -LangString TITLE_SecExtensions ${LANG_ROMANIAN} "Asocieri fișiere" -LangString TITLE_SecThemes ${LANG_ROMANIAN} "Teme" - -LangString FILE_Htm ${LANG_ROMANIAN} "Fișier HTM" -LangString FILE_Html ${LANG_ROMANIAN} "Fișier HTML" -; -LangString DESC_SecMain ${LANG_ROMANIAN} "Componentele principale ale aplicației." -LangString DESC_SecTranslations ${LANG_ROMANIAN} "Alte traduceri disponibile pentru instalare. Predefinită este Engleza." -LangString DESC_SecPlugins ${LANG_ROMANIAN} "Alte plugin-uri sunt disponibile pentru instalare." -LangString DESC_SecDesktop ${LANG_ROMANIAN} "Adaugă scurtătură pe Desktop." -LangString DESC_SecExtensions ${LANG_ROMANIAN} "Asociază QupZilla cu .htm și fișiere .html" -LangString DESC_SecThemes ${LANG_ROMANIAN} "Teme adiționale pentru QupZilla" - -;;;;Hongkongese -LangString PRODUCT_DESC ${LANG_HONGKONG} "QupZilla是一個嶄新、快速、安全和開放原始碼的網頁瀏覽器。QupZilla基於GPL的3或(你意願下的)較新版本釋出授權。QupZilla使用WebKit核心和Qt框架。" -; -LangString TITLE_SecMain ${LANG_HONGKONG} "主要組件" -LangString TITLE_SecTranslations ${LANG_HONGKONG} "語言" -LangString TITLE_SecPlugins ${LANG_HONGKONG} "外掛程式" -LangString TITLE_SecDesktop ${LANG_HONGKONG} "桌面圖示" -LangString TITLE_SecExtensions ${LANG_HONGKONG} "檔案管理" -LangString TITLE_SecThemes ${LANG_HONGKONG} "主題" -LangString TITLE_SecSetASDefault ${LANG_HONGKONG} "預設瀏覽器" -LangString TITLE_SecProtocols ${LANG_HONGKONG} "網絡協定關聯" - -LangString FILE_Htm ${LANG_HONGKONG} "HTM檔案" -LangString FILE_Html ${LANG_HONGKONG} "HTML檔案" -; -LangString DESC_SecMain ${LANG_HONGKONG} "程式主要組件。" -LangString DESC_SecTranslations ${LANG_HONGKONG} "可選用的語言,預設為英語。" -LangString DESC_SecPlugins ${LANG_HONGKONG} "可選用的外掛程式。" -LangString DESC_SecDesktop ${LANG_HONGKONG} "建立桌面捷徑。" -LangString DESC_SecExtensions ${LANG_HONGKONG} "預設QupZilla為開啟「.htm」和「.html」檔案的瀏覽器。" -LangString DESC_SecThemes ${LANG_HONGKONG} "其他QupZilla主題。" -LangString DESC_SecSetASDefault ${LANG_HONGKONG} "設定QupZilla為預設瀏覽器。" -LangString DESC_SecProtocols ${LANG_HONGKONG} "關聯QupZilla到http、https和ftp協定。" -; -LangString MSG_RunningInstance ${LANG_HONGKONG} "QupZilla啟用中。是否要求安裝程式代為關閉QupZilla?" -LangString MSG_InstallationCanceled ${LANG_HONGKONG} "用戶主動終止安裝。" - -;;;;Traditional Chinese -LangString PRODUCT_DESC ${LANG_TRADCHINESE} "QupZilla 是一個新穎、快速、安全且開放原始碼的 WWW 瀏覽器。QupZilla 以 GPLv3 或是 (在您的選擇下) 更新的版本釋出。QupZilla 是基於 WebKit 內核及 Qt 框架。" -; -LangString TITLE_SecMain ${LANG_TRADCHINESE} "主要組件" -LangString TITLE_SecTranslations ${LANG_TRADCHINESE} "語言版本" -LangString TITLE_SecPlugins ${LANG_TRADCHINESE} "外掛" -LangString TITLE_SecDesktop ${LANG_TRADCHINESE} "桌面圖示" -LangString TITLE_SecExtensions ${LANG_TRADCHINESE} "檔案管理" -LangString TITLE_SecThemes ${LANG_TRADCHINESE} "主題" -LangString TITLE_SecSetASDefault ${LANG_TRADCHINESE} "預設瀏覽器" -LangString TITLE_SecProtocols ${LANG_TRADCHINESE} "通訊協定關聯" - -LangString FILE_Htm ${LANG_TRADCHINESE} "HTM 檔案" -LangString FILE_Html ${LANG_TRADCHINESE} "HTML 檔案" -; -LangString DESC_SecMain ${LANG_TRADCHINESE} "程式主要組件。" -LangString DESC_SecTranslations ${LANG_TRADCHINESE} "可安裝的語言版本,預設是英語。" -LangString DESC_SecPlugins ${LANG_TRADCHINESE} "可安裝的外掛。" -LangString DESC_SecDesktop ${LANG_TRADCHINESE} "在桌面新增啟動圖示。" -LangString DESC_SecExtensions ${LANG_TRADCHINESE} "將 QupZilla 做為預設開啟 .htm 以及 .html 檔案的瀏覽器。" -LangString DESC_SecThemes ${LANG_TRADCHINESE} "額外的 QupZilla 主題。" -LangString DESC_SecSetASDefault ${LANG_TRADCHINESE} "將 QupZilla 做為預設瀏覽器。" -LangString DESC_SecProtocols ${LANG_TRADCHINESE} "關聯 http、https 與 ftp 協定至 QupZilla。" -; -LangString MSG_RunningInstance ${LANG_TRADCHINESE} "正在執行 QupZilla。要求安裝程式嘗試終止它嗎?" -LangString MSG_InstallationCanceled ${LANG_TRADCHINESE} "使用者取消安裝。" - -;;;;Simplified Chinese -LangString PRODUCT_DESC ${LANG_SIMPCHINESE} "QupZilla 是新出、高速、安全的开源 WWW 浏览器。QupZilla 基于 GPL 协议第 3 版或(如果您需要)任何之后的版本。它使用 WebKit 排版引擎。" -; -LangString TITLE_SecMain ${LANG_SIMPCHINESE} "核心部件" -LangString TITLE_SecTranslations ${LANG_SIMPCHINESE} "翻译" -LangString TITLE_SecPlugins ${LANG_SIMPCHINESE} "应用扩展" -LangString TITLE_SecDesktop ${LANG_SIMPCHINESE} "桌面图标" -LangString TITLE_SecExtensions ${LANG_SIMPCHINESE} "文件管理" -LangString TITLE_SecThemes ${LANG_SIMPCHINESE} "皮肤" -LangString TITLE_SecSetASDefault ${LANG_SIMPCHINESE} "默认浏览器" -LangString TITLE_SecProtocols ${LANG_SIMPCHINESE} "关联协议" - -LangString FILE_Htm ${LANG_SIMPCHINESE} "HTM 文件" -LangString FILE_Html ${LANG_SIMPCHINESE} "HTML 文件" -; -LangString DESC_SecMain ${LANG_SIMPCHINESE} "程序核心部件。" -LangString DESC_SecTranslations ${LANG_SIMPCHINESE} "可以安装其它翻译,默认为英文。" -LangString DESC_SecPlugins ${LANG_SIMPCHINESE} "可以安装其它应用扩展。" -LangString DESC_SecDesktop ${LANG_SIMPCHINESE} "在桌面新建启动图标。" -LangString DESC_SecExtensions ${LANG_SIMPCHINESE} "将 QupZilla 做为默认打开 .htm 以及 .html 文件的浏览器。" -LangString DESC_SecThemes ${LANG_SIMPCHINESE} "其它的 QupZilla 皮肤。" -LangString DESC_SecSetASDefault ${LANG_SIMPCHINESE} "将 QupZilla 做为默认浏览器。" -LangString DESC_SecProtocols ${LANG_SIMPCHINESE} "关联 http、https 与 ftp 协议至 QupZilla。" -; -LangString MSG_RunningInstance ${LANG_SIMPCHINESE} "正在使用 QupZilla。您希望安装程序试着结束它吗?" -LangString MSG_InstallationCanceled ${LANG_SIMPCHINESE} "用户撤销程序。" - -;;;;Bahasa Indonesia -LangString TITLE_SecMain ${LANG_INDONESIAN} "Komponen Utama" -LangString TITLE_SecTranslations ${LANG_INDONESIAN} "Terjemahan" -LangString TITLE_SecPlugins ${LANG_INDONESIAN} "Pengaya" -LangString TITLE_SecDesktop ${LANG_INDONESIAN} "Ikon Desktop" -LangString TITLE_SecExtensions ${LANG_INDONESIAN} "Asosiasi Berkas" -LangString TITLE_SecThemes ${LANG_INDONESIAN} "Tema" - -LangString FILE_Htm ${LANG_INDONESIAN} "Berkas HTM" -LangString FILE_Html ${LANG_INDONESIAN} "Berkas HTML" -; -LangString DESC_SecMain ${LANG_INDONESIAN} "Komponen utama dari aplikasi." -LangString DESC_SecTranslations ${LANG_INDONESIAN} "Tersedia terjemahan lain untuk diinstal. Default adalah Bahasa Inggris." -LangString DESC_SecPlugins ${LANG_INDONESIAN} "Tersedia pengaya lain untuk diinstal." -LangString DESC_SecDesktop ${LANG_INDONESIAN} "Tambahkan peluncur ke desktop." -LangString DESC_SecExtensions ${LANG_INDONESIAN} "Asosiasikan QupZilla dengan berkas .htm dan .html" -LangString DESC_SecThemes ${LANG_INDONESIAN} "Tema tambahan untuk QupZilla" - -;;;;Georgian -LangString TITLE_SecMain ${LANG_GEORGIAN} "მთავარი კომპონენტები" -LangString TITLE_SecTranslations ${LANG_GEORGIAN} "თარგმანები" -LangString TITLE_SecPlugins ${LANG_GEORGIAN} "მოდულები" -LangString TITLE_SecDesktop ${LANG_GEORGIAN} "სამუშაო მაგიდის ხატულა" -LangString TITLE_SecExtensions ${LANG_GEORGIAN} "ფაილებთან ასოცირება" -LangString TITLE_SecThemes ${LANG_GEORGIAN} "თემები" - -LangString FILE_Htm ${LANG_GEORGIAN} "HTM ფაილი" -LangString FILE_Html ${LANG_GEORGIAN} "HTML ფაილი" -; -LangString DESC_SecMain ${LANG_GEORGIAN} "პროგრამის მთავარი კომპონენტები." -LangString DESC_SecTranslations ${LANG_GEORGIAN} "სხვა ენები რომელთა დაყენებაც შესაძლებელია. ნაგულისხმევი არის ინგლისური." -LangString DESC_SecPlugins ${LANG_GEORGIAN} "სხვა მოდულები რომელთა დაყენებაც შესაძლებელია." -LangString DESC_SecDesktop ${LANG_GEORGIAN} "გამშვების დამატება სამუშაო მაგიდაზე." -LangString DESC_SecExtensions ${LANG_GEORGIAN} "QupZilla-ს ასოცირება .htm და .html ფაილებთან" -LangString DESC_SecThemes ${LANG_GEORGIAN} "დამატებითი თემები QupZilla-სთვის" - -;;;;Japanese -LangString PRODUCT_DESC ${LANG_JAPANESE} "QupZilla は新しくて、高速で、安全なオープンソース WWW ブラウザです。 QupZilla は GPL version 3 (任意の)それ以降のバージョンでライセンスされています。WebKit コアと Qt Framework ベースで開発されています。" -; -LangString TITLE_SecMain ${LANG_JAPANESE} "メインコンポーネント" -LangString TITLE_SecTranslations ${LANG_JAPANESE} "言語ファイル" -LangString TITLE_SecPlugins ${LANG_JAPANESE} "エクステンション(拡張機能)" -LangString TITLE_SecDesktop ${LANG_JAPANESE} "デスクトップアイコン" -LangString TITLE_SecExtensions ${LANG_JAPANESE} "ファイルの関連付け" -LangString TITLE_SecThemes ${LANG_JAPANESE} "テーマ" -LangString TITLE_SecSetASDefault ${LANG_JAPANESE} "既定のブラウザ" -LangString TITLE_SecProtocols ${LANG_JAPANESE} "プロトコルの関連付け" - -LangString FILE_Htm ${LANG_JAPANESE} "HTM ファイル" -LangString FILE_Html ${LANG_JAPANESE} "HTML ファイル" -; -LangString DESC_SecMain ${LANG_JAPANESE} "アプリケーションのメインとなる部分です。" -LangString DESC_SecTranslations ${LANG_JAPANESE} "他の言語でも QupZilla を使えるようになります。デフォルトでは英語です。" -LangString DESC_SecPlugins ${LANG_JAPANESE} "プラグイン(拡張機能)を追加してダウンロードします。" -LangString DESC_SecDesktop ${LANG_JAPANESE} "デスクトップにアイコンを作成します。" -LangString DESC_SecExtensions ${LANG_JAPANESE} "QupZilla に htm, html ファイルを関連付けます。" -LangString DESC_SecThemes ${LANG_JAPANESE} "QupZilla のデフォルトテーマ以外のテーマをダウンロードします。" -LangString DESC_SecSetASDefault ${LANG_JAPANESE} "QupZilla を既定の Web ブラウザに設定する。" -LangString DESC_SecProtocols ${LANG_JAPANESE} "QupZilla を http, https プロトコルに関連付けます。" -; -LangString MSG_RunningInstance ${LANG_JAPANESE} "QupZilla は起動中です!インストーラーによって終了させますか?" -LangString MSG_InstallationCanceled ${LANG_JAPANESE} "プロセスはユーザーによって中止されました。" - -;;;;SWEDISH -LangString TITLE_SecMain ${LANG_SWEDISH} "Huvudkomponenter" -LangString DESC_SecMain ${LANG_SWEDISH} "Programmets viktigaste komponenter." -LangString TITLE_SecTranslations ${LANG_SWEDISH} "Översättningar" -LangString DESC_SecTranslations ${LANG_SWEDISH} "Andra översättningar tillgängliga för installation. Förval är Engelska." -LangString TITLE_SecPlugins ${LANG_SWEDISH} "Insticksmoduler" -LangString DESC_SecPlugins ${LANG_SWEDISH} "Andra insticksmoduler tillgängliga för installation." -LangString TITLE_SecDesktop ${LANG_SWEDISH} "Skrivbordsikon" -LangString DESC_SecDesktop ${LANG_SWEDISH} "Lägg till en ikon på skrivbordet." -LangString TITLE_SecExtensions ${LANG_SWEDISH} "Filbindningar" -LangString DESC_SecExtensions ${LANG_SWEDISH} "Associera QupZilla med .htm- och .html-filer" -LangString FILE_Htm ${LANG_SWEDISH} "HTM-fil" -LangString FILE_Html ${LANG_SWEDISH} "HTML-fil" -LangString TITLE_SecThemes ${LANG_SWEDISH} "Teman" -LangString DESC_SecThemes ${LANG_SWEDISH} "Ytterligare teman för QupZilla" - -;;;;Polish -LangString TITLE_SecMain ${LANG_POLISH} "Składniki podstawowe" -LangString TITLE_SecTranslations ${LANG_POLISH} "Tłumaczenia" -LangString TITLE_SecPlugins ${LANG_POLISH} "Wtyczki" -LangString TITLE_SecDesktop ${LANG_POLISH} "Ikona pulpitu" -LangString TITLE_SecExtensions ${LANG_POLISH} "Skojarzenia plików" -LangString TITLE_SecThemes ${LANG_POLISH} "Motywy" - -LangString FILE_Htm ${LANG_POLISH} "Plik HTM" -LangString FILE_Html ${LANG_POLISH} "Plik HTML" -; -LangString DESC_SecMain ${LANG_POLISH} "Podstawowe składniki programu." -LangString DESC_SecTranslations ${LANG_POLISH} "Instalacja dodatkowych wersji językowych. Domyślnie tylko język angielski." -LangString DESC_SecPlugins ${LANG_POLISH} "Instalacja dodatkowych wtyczek." -LangString DESC_SecDesktop ${LANG_POLISH} "Dodaj skrót do pulpitu." -LangString DESC_SecExtensions ${LANG_POLISH} "Skojarz przeglądarkę QupZilla z plikami .htm i .html" -LangString DESC_SecThemes ${LANG_POLISH} "Dodatkowe motywy dla przeglądarki QupZilla" - -LangString MSG_InstallationCanceled ${LANG_POLISH} "Proces anulowany przez użytkownika." -LangString MSG_RunningInstance ${LANG_POLISH} "QupZilla jest już uruchomiona! Chcesz aby instalator spróbował ją wyłączyć?" -LangString DESC_SecProtocols ${LANG_POLISH} "Skojarz QupZille z linkami http(s) i protokołem ftp" -LangString DESC_SecSetASDefault ${LANG_POLISH} "Ustaw QupZille jako domyślną przeglądarke" -LangString TITLE_SecProtocols ${LANG_POLISH} "Protokół Skojarzeń" -LangString TITLE_SecSetASDefault ${LANG_POLISH} "Domyślna Przeglądarka" - -LangString PRODUCT_DESC ${LANG_POLISH} "QupZilla jest nową, szybką i bezpieczną zbudowaną na otwartych źródłach przeglądarką . QupZilla podlega licencji GPL wersji 3 lub każdej późniejszej. Bazuje na silniku WebKit oraz Frameworku Qt." - -;;;;Ukrainian -LangString TITLE_SecMain ${LANG_UKRAINIAN} "Основні компоненти" -LangString TITLE_SecTranslations ${LANG_UKRAINIAN} "Переклади" -LangString TITLE_SecPlugins ${LANG_UKRAINIAN} "Плаґіни" -LangString TITLE_SecDesktop ${LANG_UKRAINIAN} "Іконка на робочому столі" -LangString TITLE_SecExtensions ${LANG_UKRAINIAN} "Асоціювання файлів" -LangString TITLE_SecThemes ${LANG_UKRAINIAN} "Теми" - -LangString FILE_Htm ${LANG_UKRAINIAN} "Файл HTM" -LangString FILE_Html ${LANG_UKRAINIAN} "Файл HTML" -; -LangString DESC_SecMain ${LANG_UKRAINIAN} "Основні компоненти програми." -LangString DESC_SecTranslations ${LANG_UKRAINIAN} "Доступні інші переклади для встановлення. Мова за умовчуванням - англійська." -LangString DESC_SecPlugins ${LANG_UKRAINIAN} "Доступні інші плаґіни для встановлення." -LangString DESC_SecDesktop ${LANG_UKRAINIAN} "Додати посилання на робочий стіл." -LangString DESC_SecExtensions ${LANG_UKRAINIAN} "Асоціювати QupZill'у з файлами .htm і .html" -LangString DESC_SecThemes ${LANG_UKRAINIAN} "Додаткові теми для QupZill'и" - -;;;;Persian (Farsi) -LangString PRODUCT_DESC ${LANG_FARSI} "‫کوپزیلا مرورگر اینترنتی متن‌باز، جدید، سریع و ایمنی است. کوپزیلا تحت توافقنامه GPL نسخه ۳ یا هر نسخه جدیدتر آن است. کوپزیلا تحت هسته وب‌کیت و چارچوب کیوت می‌باشد.‬" -; -LangString TITLE_SecMain ${LANG_FARSI} "بخش اصلی" -LangString TITLE_SecTranslations ${LANG_FARSI} "برگردان‌ها" -LangString TITLE_SecPlugins ${LANG_FARSI} "افزونه‌ها" -LangString TITLE_SecDesktop ${LANG_FARSI} "آیکون میزکار" -LangString TITLE_SecExtensions ${LANG_FARSI} "تخصیص فایل" -LangString TITLE_SecThemes ${LANG_FARSI} "فرهشت‌ها" -LangString TITLE_SecSetASDefault ${LANG_FARSI} "مرورگر پیش‌فرض" -LangString TITLE_SecProtocols ${LANG_FARSI} "تخصیص پروتکل" - -LangString FILE_Htm ${LANG_FARSI} "HTM File" -LangString FILE_Html ${LANG_FARSI} "HTML File" -; -LangString DESC_SecMain ${LANG_FARSI} "بخش اصلی نرم‌افزار." -LangString DESC_SecTranslations ${LANG_FARSI} "دیگر برگردان‌های دردسترس. پیش فرض انگلیسی است." -LangString DESC_SecPlugins ${LANG_FARSI} "افزونه‌های دیگر که برای نصب در دسترس هستند." -LangString DESC_SecDesktop ${LANG_FARSI} "افزودن میان‌برِ آغازگر به میزکار" -LangString DESC_SecExtensions ${LANG_FARSI} "کوپزیلا را برای بازکردن فایل‌های ‎.htm(l)‎ اختصاص می‌دهد." -LangString DESC_SecThemes ${LANG_FARSI} "فرهشت‌های اضافی برای کوپزیلا" -LangString DESC_SecSetASDefault ${LANG_FARSI} "تنظیم کوپزیلا به عنوان مرورگر پیش‌فرض" -LangString DESC_SecProtocols ${LANG_FARSI} "کوپزیلا را به پروتکل‌های http(s)‎ و ftp اختصاص می‌دهد." -; -LangString MSG_RunningInstance ${LANG_FARSI} "کوپزیلا هم‌اکنون در حال اجراست! آیا می‌خواهید برنامه نصب تلاش کند به اجرای آن خاتمه دهد؟" -LangString MSG_InstallationCanceled ${LANG_FARSI} "فرایند توسط کاربر لغو گردید." - -;;;;Serbian -LangString PRODUCT_DESC ${LANG_SERBIAN} "Капзила је нови, брз и сигуран веб прегледач отвореног кода. Лиценцирана под ГПЛ в3 лиценцом или (по властитом нахођењу) каснијим издањем те лиценце. Заснована на ВебКит језгри и Кјут програмском окружењу." -; -LangString TITLE_SecMain ${LANG_SERBIAN} "Главне компоненте" -LangString TITLE_SecTranslations ${LANG_SERBIAN} "Преводи" -LangString TITLE_SecPlugins ${LANG_SERBIAN} "Проширења" -LangString TITLE_SecDesktop ${LANG_SERBIAN} "Икона на радној површи" -LangString TITLE_SecExtensions ${LANG_SERBIAN} "Придружења фајлова" -LangString TITLE_SecThemes ${LANG_SERBIAN} "Теме" -LangString TITLE_SecSetASDefault ${LANG_SERBIAN} "Подразумеван прегледач" -LangString TITLE_SecProtocols ${LANG_SERBIAN} "Придружења протокола" - -LangString FILE_Htm ${LANG_SERBIAN} "ХТМ фајл" -LangString FILE_Html ${LANG_SERBIAN} "ХТМЛ фајл" -; -LangString DESC_SecMain ${LANG_SERBIAN} "Главне компоненте програма." -LangString DESC_SecTranslations ${LANG_SERBIAN} "Остали доступни преводи. Енглески је подразумеван." -LangString DESC_SecPlugins ${LANG_SERBIAN} "Остала проширења - прикључци." -LangString DESC_SecDesktop ${LANG_SERBIAN} "Покретач програма на радној површи." -LangString DESC_SecExtensions ${LANG_SERBIAN} "Отварај .htm(l) фајлове у Капзили." -LangString DESC_SecThemes ${LANG_SERBIAN} "Додатне теме за Капзилу" -LangString DESC_SecSetASDefault ${LANG_SERBIAN} "Постави Капзилу за подразумевани веб прегледач." -LangString DESC_SecProtocols ${LANG_SERBIAN} "Отварај http(s) и ftp протоколе у Капзили." -; -LangString MSG_RunningInstance ${LANG_SERBIAN} "Капзила је већ покренута! Желите ли да инсталатер покуша да је угаси?" -LangString MSG_InstallationCanceled ${LANG_SERBIAN} "Корисник је отказао процес." - -;;;;SerbianLatin -LangString PRODUCT_DESC ${LANG_SERBIANLATIN} "Kapzila je novi, brz i siguran veb pregledač otvorenog koda. Licencirana pod GPL v3 licencom ili (po vlastitom nahođenju) kasnijim izdanjem te licence. Zasnovana na VebKit jezgri i Kjut programskom okruženju." -; -LangString TITLE_SecMain ${LANG_SERBIANLATIN} "Glavne komponente" -LangString TITLE_SecTranslations ${LANG_SERBIANLATIN} "Prevodi" -LangString TITLE_SecPlugins ${LANG_SERBIANLATIN} "Proširenja" -LangString TITLE_SecDesktop ${LANG_SERBIANLATIN} "Ikona na radnoj površi" -LangString TITLE_SecExtensions ${LANG_SERBIANLATIN} "Pridruženja fajlova" -LangString TITLE_SecThemes ${LANG_SERBIANLATIN} "Teme" -LangString TITLE_SecSetASDefault ${LANG_SERBIANLATIN} "Podrazumevan pregledač" -LangString TITLE_SecProtocols ${LANG_SERBIANLATIN} "Pridruženja protokola" - -LangString FILE_Htm ${LANG_SERBIANLATIN} "HTM fajl" -LangString FILE_Html ${LANG_SERBIANLATIN} "HTML fajl" -; -LangString DESC_SecMain ${LANG_SERBIANLATIN} "Glavne komponente programa." -LangString DESC_SecTranslations ${LANG_SERBIANLATIN} "Ostali dostupni prevodi. Engleski je podrazumevan." -LangString DESC_SecPlugins ${LANG_SERBIANLATIN} "Ostala proširenja - priključci." -LangString DESC_SecDesktop ${LANG_SERBIANLATIN} "Pokretač programa na radnoj površi." -LangString DESC_SecExtensions ${LANG_SERBIANLATIN} "Otvaraj .htm(l) fajlove u Kapzili." -LangString DESC_SecThemes ${LANG_SERBIANLATIN} "Dodatne teme za Kapzilu" -LangString DESC_SecSetASDefault ${LANG_SERBIANLATIN} "Postavi Kapzilu za podrazumevani veb pregledač." -LangString DESC_SecProtocols ${LANG_SERBIANLATIN} "Otvaraj http(s) i ftp protokole u Kapzili." -; -LangString MSG_RunningInstance ${LANG_SERBIANLATIN} "Kapzila je već pokrenuta! Želite li da instalater pokuša da je ugasi?" -LangString MSG_InstallationCanceled ${LANG_SERBIANLATIN} "Korisnik je otkazao proces." - -;;;;Hebrew -LangString PRODUCT_DESC ${LANG_HEBREW} "QupZilla הינו דפדפן WWW קוד פתוח חדש, מהיר ומאובטח. QupZilla רשוי תחת הרשיון GPL גרסא 3 או (כאופציה השמורה לך) כל גרסא מאוחרת יותר. זה מבוסס על ליבת WebKit ועל Qt Framework." -; -LangString TITLE_SecMain ${LANG_HEBREW} "רכיבים עיקריים" -LangString TITLE_SecTranslations ${LANG_HEBREW} "תרגומים" -LangString TITLE_SecPlugins ${LANG_HEBREW} "תוספות" -LangString TITLE_SecDesktop ${LANG_HEBREW} "סמל שולחן עבודה" -LangString TITLE_SecExtensions ${LANG_HEBREW} "שיוכי קובץ" -LangString TITLE_SecThemes ${LANG_HEBREW} "ערכות נושא" -LangString TITLE_SecSetASDefault ${LANG_HEBREW} "דפדפן ברירת מחדל" -LangString TITLE_SecProtocols ${LANG_HEBREW} "שיוכי פרוטוקול" - -LangString FILE_Htm ${LANG_HEBREW} "קובץ HTM" -LangString FILE_Html ${LANG_HEBREW} "קובץ HTML" -; -LangString DESC_SecMain ${LANG_HEBREW} "רכיבים עיקריים של יישום." -LangString DESC_SecTranslations ${LANG_HEBREW} "תרגומים אחרים זמינים להתקנה. ברירת מחדל הינה English." -LangString DESC_SecPlugins ${LANG_HEBREW} "תוספות אחרות זמינות להתקנה." -LangString DESC_SecDesktop ${LANG_HEBREW} "הוסף משגר אל שולחן עבודה." -LangString DESC_SecExtensions ${LANG_HEBREW} "שייך את QupZilla עם קבצי .htm(l)" -LangString DESC_SecThemes ${LANG_HEBREW} "ערכות נושא נוספות עבור QupZilla" -LangString DESC_SecSetASDefault ${LANG_HEBREW} "הגדר את QupZilla כדפדפן אינטרנט ברירת מחדל" -LangString DESC_SecProtocols ${LANG_HEBREW} "שייך את QupZilla עם פרוטוקול http(s) ופרוטוקול ftp" -; -LangString MSG_RunningInstance ${LANG_HEBREW} "QupZilla כבר מורץ כעת! האם ברצונך מהמתקין לנסות לסיימו?" -LangString MSG_InstallationCanceled ${LANG_HEBREW} "תהליך בוטל על ידי משתמש." - -;;;;Basque -LangString PRODUCT_DESC ${LANG_BASQUE} "QupZilla iturburu-irekiko WWW nabigatzaile berri, azkar eta seguru bat da. QupZilla GPL 3 bertsioa baimenpean dago edo (zure aukeran) edozein bertsio berriagoan. WebKit nukleoan eta Qt Framework-ean ohinarrituta dago." -; -LangString TITLE_SecMain ${LANG_BASQUE} "Osagai Nagusiak" -LangString TITLE_SecTranslations ${LANG_BASQUE} "Itzulpenak" -LangString TITLE_SecPlugins ${LANG_BASQUE} "Pluginak" -LangString TITLE_SecDesktop ${LANG_BASQUE} "Mahaigain Ikurra" -LangString TITLE_SecExtensions ${LANG_BASQUE} "Agiri Elkarketa" -LangString TITLE_SecThemes ${LANG_BASQUE} "Azalgaiak" -LangString TITLE_SecSetASDefault ${LANG_BASQUE} "Berezko Nabigatzailea" -LangString TITLE_SecProtocols ${LANG_BASQUE} "Protokolo Elkarketak" - -LangString FILE_Htm ${LANG_BASQUE} "HTM Agiria" -LangString FILE_Html ${LANG_BASQUE} "HTML Agiria" -; -LangString DESC_SecMain ${LANG_BASQUE} "Aplikazioaren osagai nagusiak." -LangString DESC_SecTranslations ${LANG_BASQUE} "Ezartzeko eskuragarri dauden beste itzulpenak. Berezkoa Ingelera da." -LangString DESC_SecPlugins ${LANG_BASQUE} "Ezartzeko eskuragarri dauden beste pluginak." -LangString DESC_SecDesktop ${LANG_BASQUE} "Gehitu abiarazlea mahaigainean." -LangString DESC_SecExtensions ${LANG_BASQUE} "Elkartu QupZilla .htm(l) agiriekin" -LangString DESC_SecThemes ${LANG_BASQUE} "QupZilla-rentzako azalgai gehigarriak" -LangString DESC_SecSetASDefault ${LANG_BASQUE} "Ezarri QupZilla berezko internet nabigatzaile bezala" -LangString DESC_SecProtocols ${LANG_BASQUE} "Elkartu QupZilla http(s) eta ftp protokoloekin" -; -LangString MSG_RunningInstance ${LANG_BASQUE} "QupZilla jadanik ekinean dago! Nahi duzu ezartzaileak hura amaitzen saiatzea?" -LangString MSG_InstallationCanceled ${LANG_BASQUE} "Prozesua erabiltzaileak ezeztaturik." - -;;;;Danish -LangString PRODUCT_DESC ${LANG_DANISH} "QupZilla er en ny, hurtig og sikker open source WWW-browser. QupZilla er licenseret under GPL version 3 eller (efter eget valg) en senere version. Den er baseret på WebKit-kerne og Qt-framework." -; -LangString TITLE_SecMain ${LANG_DANISH} "Hovedkomponenter" -LangString TITLE_SecTranslations ${LANG_DANISH} "Oversættelser" -LangString TITLE_SecPlugins ${LANG_DANISH} "Plugins" -LangString TITLE_SecDesktop ${LANG_DANISH} "Skrivebordsikon" -LangString TITLE_SecExtensions ${LANG_DANISH} "Filtilknytninger" -LangString TITLE_SecThemes ${LANG_DANISH} "Temaer" -LangString TITLE_SecSetASDefault ${LANG_DANISH} "Standardbrowser" -LangString TITLE_SecProtocols ${LANG_DANISH} "Protokoltilknytninger" - -LangString FILE_Htm ${LANG_DANISH} "HTM-fil" -LangString FILE_Html ${LANG_DANISH} "HTML-fil" -; -LangString DESC_SecMain ${LANG_DANISH} "Programmets hovedkomponenter." -LangString DESC_SecTranslations ${LANG_DANISH} "Andre oversættelser som kan installeres. Engelsk er standard." -LangString DESC_SecPlugins ${LANG_DANISH} "Andre plugins som kan installeres." -LangString DESC_SecDesktop ${LANG_DANISH} "Tilføj genvej på skrivebordet." -LangString DESC_SecExtensions ${LANG_DANISH} "Tilknyt QupZilla med .htm(l)-filer" -LangString DESC_SecThemes ${LANG_DANISH} "Yderligere temaer til QupZilla" -LangString DESC_SecSetASDefault ${LANG_DANISH} "Indstil QupZilla som standardinternetbrowser" -LangString DESC_SecProtocols ${LANG_DANISH} "Tilknyt QupZilla med http(s)- og ftp-protokoller" -; -LangString MSG_RunningInstance ${LANG_DANISH} "QupZilla kører allerede! Vil du have installationsprogrammet til at stoppe den?" -LangString MSG_InstallationCanceled ${LANG_DANISH} "Proces annulleret af bruger." - -;;;;;;;;; -;;;;;;;;; -; Unfinished translations -;;;;;;;;; -;;;;;;;;; -LangString PRODUCT_DESC ${LANG_DUTCH} "QupZilla is a new, fast and secure open-source WWW browser. QupZilla is licensed under GPL version 3 or (at your option) any later version. It is based on WebKit core and Qt Framework." -LangString PRODUCT_DESC ${LANG_GREEK} "QupZilla is a new, fast and secure open-source WWW browser. QupZilla is licensed under GPL version 3 or (at your option) any later version. It is based on WebKit core and Qt Framework." -LangString PRODUCT_DESC ${LANG_ITALIAN} "QupZilla is a new, fast and secure open-source WWW browser. QupZilla is licensed under GPL version 3 or (at your option) any later version. It is based on WebKit core and Qt Framework." -LangString PRODUCT_DESC ${LANG_ROMANIAN} "QupZilla is a new, fast and secure open-source WWW browser. QupZilla is licensed under GPL version 3 or (at your option) any later version. It is based on WebKit core and Qt Framework." -LangString PRODUCT_DESC ${LANG_INDONESIAN} "QupZilla is a new, fast and secure open-source WWW browser. QupZilla is licensed under GPL version 3 or (at your option) any later version. It is based on WebKit core and Qt Framework." -LangString PRODUCT_DESC ${LANG_GEORGIAN} "QupZilla is a new, fast and secure open-source WWW browser. QupZilla is licensed under GPL version 3 or (at your option) any later version. It is based on WebKit core and Qt Framework." -LangString PRODUCT_DESC ${LANG_SWEDISH} "QupZilla is a new, fast and secure open-source WWW browser. QupZilla is licensed under GPL version 3 or (at your option) any later version. It is based on WebKit core and Qt Framework." -LangString PRODUCT_DESC ${LANG_UKRAINIAN} "QupZilla is a new, fast and secure open-source WWW browser. QupZilla is licensed under GPL version 3 or (at your option) any later version. It is based on WebKit core and Qt Framework." - -LangString TITLE_SecSetASDefault ${LANG_DUTCH} "Default Browser" -LangString TITLE_SecSetASDefault ${LANG_GREEK} "Default Browser" -LangString TITLE_SecSetASDefault ${LANG_ITALIAN} "Default Browser" -LangString TITLE_SecSetASDefault ${LANG_ROMANIAN} "Default Browser" -LangString TITLE_SecSetASDefault ${LANG_INDONESIAN} "Default Browser" -LangString TITLE_SecSetASDefault ${LANG_GEORGIAN} "Default Browser" -LangString TITLE_SecSetASDefault ${LANG_SWEDISH} "Default Browser" -LangString TITLE_SecSetASDefault ${LANG_UKRAINIAN} "Default Browser" - -LangString TITLE_SecProtocols ${LANG_DUTCH} "Protocol Associations" -LangString TITLE_SecProtocols ${LANG_GREEK} "Protocol Associations" -LangString TITLE_SecProtocols ${LANG_ITALIAN} "Protocol Associations" -LangString TITLE_SecProtocols ${LANG_ROMANIAN} "Protocol Associations" -LangString TITLE_SecProtocols ${LANG_INDONESIAN} "Protocol Associations" -LangString TITLE_SecProtocols ${LANG_GEORGIAN} "Protocol Associations" -LangString TITLE_SecProtocols ${LANG_SWEDISH} "Protocol Associations" -LangString TITLE_SecProtocols ${LANG_UKRAINIAN} "Protocol Associations" - -LangString DESC_SecSetASDefault ${LANG_DUTCH} "Set QupZilla as default internet browser" -LangString DESC_SecSetASDefault ${LANG_GREEK} "Set QupZilla as default internet browser" -LangString DESC_SecSetASDefault ${LANG_ITALIAN} "Set QupZilla as default internet browser" -LangString DESC_SecSetASDefault ${LANG_ROMANIAN} "Set QupZilla as default internet browser" -LangString DESC_SecSetASDefault ${LANG_INDONESIAN} "Set QupZilla as default internet browser" -LangString DESC_SecSetASDefault ${LANG_GEORGIAN} "Set QupZilla as default internet browser" -LangString DESC_SecSetASDefault ${LANG_SWEDISH} "Set QupZilla as default internet browser" -LangString DESC_SecSetASDefault ${LANG_UKRAINIAN} "Set QupZilla as default internet browser" - -LangString DESC_SecProtocols ${LANG_DUTCH} "Associate QupZilla with http(s) and ftp protocols" -LangString DESC_SecProtocols ${LANG_GREEK} "Associate QupZilla with http(s) and ftp protocols" -LangString DESC_SecProtocols ${LANG_ITALIAN} "Associate QupZilla with http(s) and ftp protocols" -LangString DESC_SecProtocols ${LANG_ROMANIAN} "Associate QupZilla with http(s) and ftp protocols" -LangString DESC_SecProtocols ${LANG_INDONESIAN} "Associate QupZilla with http(s) and ftp protocols" -LangString DESC_SecProtocols ${LANG_GEORGIAN} "Associate QupZilla with http(s) and ftp protocols" -LangString DESC_SecProtocols ${LANG_SWEDISH} "Associate QupZilla with http(s) and ftp protocols" -LangString DESC_SecProtocols ${LANG_UKRAINIAN} "Associate QupZilla with http(s) and ftp protocols" - -LangString MSG_RunningInstance ${LANG_DUTCH} "QupZilla is already running! Do you want the installer try to terminate it?" -LangString MSG_RunningInstance ${LANG_GREEK} "QupZilla is already running! Do you want the installer try to terminate it?" -LangString MSG_RunningInstance ${LANG_ITALIAN} "QupZilla is already running! Do you want the installer try to terminate it?" -LangString MSG_RunningInstance ${LANG_ROMANIAN} "QupZilla is already running! Do you want the installer try to terminate it?" -LangString MSG_RunningInstance ${LANG_INDONESIAN} "QupZilla is already running! Do you want the installer try to terminate it?" -LangString MSG_RunningInstance ${LANG_GEORGIAN} "QupZilla is already running! Do you want the installer try to terminate it?" -LangString MSG_RunningInstance ${LANG_SWEDISH} "QupZilla is already running! Do you want the installer try to terminate it?" -LangString MSG_RunningInstance ${LANG_UKRAINIAN} "QupZilla is already running! Do you want the installer try to terminate it?" - -LangString MSG_InstallationCanceled ${LANG_DUTCH} "Process cancelled by user." -LangString MSG_InstallationCanceled ${LANG_GREEK} "Process cancelled by user." -LangString MSG_InstallationCanceled ${LANG_ITALIAN} "Process cancelled by user." -LangString MSG_InstallationCanceled ${LANG_ROMANIAN} "Process cancelled by user." -LangString MSG_InstallationCanceled ${LANG_INDONESIAN} "Process cancelled by user." -LangString MSG_InstallationCanceled ${LANG_GEORGIAN} "Process cancelled by user." -LangString MSG_InstallationCanceled ${LANG_SWEDISH} "Process cancelled by user." -LangString MSG_InstallationCanceled ${LANG_UKRAINIAN} "Process cancelled by user." +;;;;English +LangString PRODUCT_DESC ${LANG_ENGLISH} "Falkon is a new, fast and secure open-source WWW browser. Falkon is licensed under GPL version 3 or (at your option) any later version. It is based on WebKit core and Qt Framework." +; +LangString TITLE_SecMain ${LANG_ENGLISH} "Main Components" +LangString TITLE_SecTranslations ${LANG_ENGLISH} "Translations" +LangString TITLE_SecPlugins ${LANG_ENGLISH} "Plugins" +LangString TITLE_SecDesktop ${LANG_ENGLISH} "Desktop Icon" +LangString TITLE_SecExtensions ${LANG_ENGLISH} "File Associations" +LangString TITLE_SecThemes ${LANG_ENGLISH} "Themes" +LangString TITLE_SecSetASDefault ${LANG_ENGLISH} "Default Browser" +LangString TITLE_SecProtocols ${LANG_ENGLISH} "Protocol Associations" + +LangString FILE_Htm ${LANG_ENGLISH} "HTM File" +LangString FILE_Html ${LANG_ENGLISH} "HTML File" +; +LangString DESC_SecMain ${LANG_ENGLISH} "Main components of application." +LangString DESC_SecTranslations ${LANG_ENGLISH} "Other translations available to install. Default is English." +LangString DESC_SecPlugins ${LANG_ENGLISH} "Other plugins available to install." +LangString DESC_SecDesktop ${LANG_ENGLISH} "Add launcher to desktop." +LangString DESC_SecExtensions ${LANG_ENGLISH} "Associate Falkon with .htm(l) files" +LangString DESC_SecThemes ${LANG_ENGLISH} "Additional themes for Falkon" +LangString DESC_SecSetASDefault ${LANG_ENGLISH} "Set Falkon as default internet browser" +LangString DESC_SecProtocols ${LANG_ENGLISH} "Associate Falkon with http(s) and ftp protocols" +; +LangString MSG_RunningInstance ${LANG_ENGLISH} "Falkon is already running! Do you want the installer try to terminate it?" +LangString MSG_InstallationCanceled ${LANG_ENGLISH} "Process cancelled by user." + +;;;;Arabic +LangString PRODUCT_DESC ${LANG_ARABIC} "كَبزيلّا متصفّح للوب جديد سريع وآمن ومفتوح المصدر. يُرخَّص استخدامه وفق الإصدار الثالث من رخصة جنو العمومية (GPL) أو أي إصدار أحدث من ذلك (اختر كما تشاء). يُبنى كَبزيلّا على محرّك العرض WebKitوإطار العمل Qt." +; +LangString TITLE_SecMain ${LANG_ARABIC} "المكونات الأساسية" +LangString TITLE_SecTranslations ${LANG_ARABIC} "الترجمات" +LangString TITLE_SecPlugins ${LANG_ARABIC} "الإضافات" +LangString TITLE_SecDesktop ${LANG_ARABIC} "رمز على سطح المكتب" +LangString TITLE_SecExtensions ${LANG_ARABIC} "ارتباطات الملفات" +LangString TITLE_SecThemes ${LANG_ARABIC} "السمات" +LangString TITLE_SecSetASDefault ${LANG_ARABIC} "المتصفح المبدئي" +LangString TITLE_SecProtocols ${LANG_ARABIC} "ارتباطات البروتوكولات" + +LangString FILE_Htm ${LANG_ARABIC} "ملف HTM" +LangString FILE_Html ${LANG_ARABIC} "ملف HTML" +; +LangString DESC_SecMain ${LANG_ARABIC} "المكونات الرئيسية للبرنامج." +LangString DESC_SecTranslations ${LANG_ARABIC} "ترجمات أخرى متوفرة للتثبيت. اللغة المبدئية هي الإنكليزية." +LangString DESC_SecPlugins ${LANG_ARABIC} "إضافات أخرى متوفّرة للتنزيل." +LangString DESC_SecDesktop ${LANG_ARABIC} "أضف اختصارًا لتشغيل كَبزيلا من سطح المكتب." +LangString DESC_SecExtensions ${LANG_ARABIC} "اربط كَبزيلّا بملفات HTML ذات اللواحق .htm أو .html." +LangString DESC_SecThemes ${LANG_ARABIC} "سمات أخرى لكَبزيلّا" +LangString DESC_SecSetASDefault ${LANG_ARABIC} "اجعل كَبزيلا المتصفح المبدئيّ" +LangString DESC_SecProtocols ${LANG_ARABIC} "اربط كَبزيلّا ببروتوكولات HTTP وHTTPS وFTP." +; +LangString MSG_RunningInstance ${LANG_ARABIC} "كَبزيلّا مفتوح الآن! أتريد من المُثبِّت إنهاءه الآن؟" +LangString MSG_InstallationCanceled ${LANG_ARABIC} "ألغى المستخدم العملية." + +;;;;Spanish +LangString PRODUCT_DESC ${LANG_SPANISH} "Falkon es un nuevo, rápido y seguro navegador web de código abierto. Falkon está bajo licencia GPL versión 3 o (o en su opción) en cualquier versión. Está basado en el motor WebKit y en Qt Framework." +; +LangString TITLE_SecMain ${LANG_SPANISH} "Componentes iniciales" +LangString TITLE_SecTranslations ${LANG_SPANISH} "Traducciones" +LangString TITLE_SecPlugins ${LANG_SPANISH} "Plugins" +LangString TITLE_SecDesktop ${LANG_SPANISH} "Icono de escritorio" +LangString TITLE_SecExtensions ${LANG_SPANISH} "Asociación de archivos" +LangString TITLE_SecThemes ${LANG_SPANISH} "Temas" +LangString TITLE_SecSetASDefault ${LANG_SPANISH} "Navegador por defecto" +LangString TITLE_SecProtocols ${LANG_SPANISH} "Asociaciones de protocolo" + +LangString FILE_Htm ${LANG_SPANISH} "Archivo HTM" +LangString FILE_Html ${LANG_SPANISH} "Archivo HTML" +; +LangString DESC_SecMain ${LANG_SPANISH} "Componentes iniciales de aplicación" +LangString DESC_SecTranslations ${LANG_SPANISH} "Otras traduciones disponibles al instalar. Por defecto en inglés." +LangString DESC_SecPlugins ${LANG_SPANISH} "Otros plugins disponibles al instalar." +LangString DESC_SecDesktop ${LANG_SPANISH} "Añade acceso directo al escritorio." +LangString DESC_SecExtensions ${LANG_SPANISH} "Asociar Falkon con archivos .htm(l)" +LangString DESC_SecThemes ${LANG_SPANISH} "Temas adicionales para Falkon" +LangString DESC_SecSetASDefault ${LANG_SPANISH} "Hacer Falkon tu navegador web por defecto" +LangString DESC_SecProtocols ${LANG_SPANISH} "Asociar Falkon con los protocolos http(s) y ftp" +; +LangString MSG_RunningInstance ${LANG_SPANISH} "Falkon se está ejecutando, Quieres que el instalador intente finalizarlo?" +LangString MSG_InstallationCanceled ${LANG_SPANISH} "Proceso cancelado por usuario." + +;;;;Czech +LangString TITLE_SecMain ${LANG_CZECH} "Hlavní komponenty" +LangString TITLE_SecTranslations ${LANG_CZECH} "Překlady" +LangString TITLE_SecPlugins ${LANG_CZECH} "Doplňky" +LangString TITLE_SecDesktop ${LANG_CZECH} "Zástupce na ploše" +LangString TITLE_SecExtensions ${LANG_CZECH} "Asociace souborů" +LangString TITLE_SecThemes ${LANG_CZECH} "Témata" + +LangString FILE_Htm ${LANG_CZECH} "Soubor HTM" +LangString FILE_Html ${LANG_CZECH} "Soubor HTML" +; +LangString DESC_SecMain ${LANG_CZECH} "Hlavní komponenty aplikace." +LangString DESC_SecTranslations ${LANG_CZECH} "Ostatní překlady dostupné k instalaci. Angličtina je defaultní." +LangString DESC_SecPlugins ${LANG_CZECH} "Ostatní doplňky dostupné k instalaci." +LangString DESC_SecDesktop ${LANG_CZECH} "Přidat zástupce na plochu." +LangString DESC_SecExtensions ${LANG_CZECH} "Associovat QupZillu s .htm(l) soubory" +LangString DESC_SecThemes ${LANG_CZECH} "Dodatečná témata pro QupZillu" + +LangString PRODUCT_DESC ${LANG_CZECH} "Falkon je nový, rychlý a bezpečný open-source WWW prohlížeč. Falkon je licencována pod GPL verze 3 nebo (podle vaší volby) jakékoliv vyšší verze. Prohlížeč je založen na jádru WebKit a Qt Frameworku." +LangString TITLE_SecSetASDefault ${LANG_CZECH} "Výchozí prohlížeč" +LangString TITLE_SecProtocols ${LANG_CZECH} "Asociace protokolů" +LangString DESC_SecSetASDefault ${LANG_CZECH} "Nastavit QupZillu jako výchozí internetový prohlížeč" +LangString DESC_SecProtocols ${LANG_CZECH} "Asociovat QupZillu s http(s) a ftp protokoly" +LangString MSG_RunningInstance ${LANG_CZECH} "Falkon je právě spuštěna. Chcete aby ji instalátor zkusil ukončit?" +LangString MSG_InstallationCanceled ${LANG_CZECH} "Proces zrušen uživatelem." + +;;;;Catalan +LangString PRODUCT_DESC ${LANG_CATALAN} "El Falkon és un navegador web de codi obert nou, ràpid i segur. Falkon està llicenciat sota GPL versió 3.0 o (si ho preferiu) qualsevol versió posterior. Està basat en WebKit i Qt." +; +LangString TITLE_SecMain ${LANG_CATALAN} "Components principals" +LangString TITLE_SecTranslations ${LANG_CATALAN} "Traduccions" +LangString TITLE_SecPlugins ${LANG_CATALAN} "Complements" +LangString TITLE_SecDesktop ${LANG_CATALAN} "Icona de l'escriptori" +LangString TITLE_SecExtensions ${LANG_CATALAN} "Associacions de fitxers" +LangString TITLE_SecThemes ${LANG_CATALAN} "Temes" +LangString TITLE_SecSetASDefault ${LANG_CATALAN} "Navegador per defecte" +LangString TITLE_SecProtocols ${LANG_CATALAN} "Associacions de protocols" + +LangString FILE_Htm ${LANG_CATALAN} "Fitxer HTM" +LangString FILE_Html ${LANG_CATALAN} "Fitxer HTML" +; +LangString DESC_SecMain ${LANG_CATALAN} "Components principals de l'aplicació." +LangString DESC_SecTranslations ${LANG_CATALAN} "Altres traduccions disponibles per instal·lar. L'idioma predeterminat és l'anglès." +LangString DESC_SecPlugins ${LANG_CATALAN} "Altres plugins disponibles per instal·lar." +LangString DESC_SecDesktop ${LANG_CATALAN} "Afegeix una drecera a l'escriptori." +LangString DESC_SecExtensions ${LANG_CATALAN} "Associa el Falkon amb els fitxers .htm i .html" +LangString DESC_SecThemes ${LANG_CATALAN} "Temes addicionals per al Falkon" +LangString DESC_SecSetASDefault ${LANG_CATALAN} "Fes que el Falkon sigui el navegador predeterminat" +LangString DESC_SecProtocols ${LANG_CATALAN} "Associa el Falkon amb els protocols http i https" +; +LangString MSG_RunningInstance ${LANG_CATALAN} "El Falkon ja està actiu. Voleu que l'instal·lador provi d'aturar-lo?" +LangString MSG_InstallationCanceled ${LANG_CATALAN} "L'usuari ha cancel·lat el procés." + +;;;;Slovak +LangString PRODUCT_DESC ${LANG_SLOVAK} "Falkon je nový, rýchly a bezpečný open-source internetový prehliadač. Falkon je licencovaná pod licenciou GPL verzie 3 alebo (podľa vášho uváženia) hocijakej novšej verzie. Je založená na jadre WebKit a frameworku Qt." +; +LangString TITLE_SecMain ${LANG_SLOVAK} "Hlavné komponenty" +LangString TITLE_SecTranslations ${LANG_SLOVAK} "Preklady" +LangString TITLE_SecPlugins ${LANG_SLOVAK} "Doplnky" +LangString TITLE_SecDesktop ${LANG_SLOVAK} "Odkaz na ploche" +LangString TITLE_SecExtensions ${LANG_SLOVAK} "Asociácia súborov" +LangString TITLE_SecThemes ${LANG_SLOVAK} "Témy" +LangString TITLE_SecSetASDefault ${LANG_SLOVAK} "Predvolený prehliadač" +LangString TITLE_SecProtocols ${LANG_SLOVAK} "Asociácie protokolov" + +LangString FILE_Htm ${LANG_SLOVAK} "Súbor HTM" +LangString FILE_Html ${LANG_SLOVAK} "Súbor HTML" +; +LangString DESC_SecMain ${LANG_SLOVAK} "Hlavné komponenty programu." +LangString DESC_SecTranslations ${LANG_SLOVAK} "Ostatné preklady dostupné na inštaláciu. Angličtina je predvolená" +LangString DESC_SecPlugins ${LANG_SLOVAK} "Ostatné doplnky dustupné na inštaláciu" +LangString DESC_SecDesktop ${LANG_SLOVAK} "Pridať odkaz na plochu." +LangString DESC_SecExtensions ${LANG_SLOVAK} "Associovať QupZillu s .htm(l) súbormi" +LangString DESC_SecThemes ${LANG_SLOVAK} "Ďalšie témy vzhľadu pre QupZillu" +LangString DESC_SecSetASDefault ${LANG_SLOVAK} "Nastaviť Qupzillu ako predvolený internetový prehliadač" +LangString DESC_SecProtocols ${LANG_SLOVAK} "Asociovať QupZillu s http(s) a ftp protokolmi" +; +LangString MSG_RunningInstance ${LANG_SLOVAK} "Falkon je už spustená! Chcete, aby sa inštalátor pokúsil ju násilne ukončiť?" +LangString MSG_InstallationCanceled ${LANG_SLOVAK} "Proces zrušený používateľom." + +;;;;German +LangString PRODUCT_DESC ${LANG_GERMAN} "Falkon ist ein neuer, schneller und sicherer, quelloffener Web Browser. Falkon ist lizensiert unter GPL Version 3 oder später. Er nutzt Webkit und das Qt Framework." +; +LangString TITLE_SecMain ${LANG_GERMAN} "Hauptkomponenten" +LangString TITLE_SecTranslations ${LANG_GERMAN} "Übersetzungen" +LangString TITLE_SecPlugins ${LANG_GERMAN} "Plugins" +LangString TITLE_SecDesktop ${LANG_GERMAN} "Desktop Symbol" +LangString TITLE_SecExtensions ${LANG_GERMAN} "Dateiverknüpfungen" +LangString TITLE_SecThemes ${LANG_GERMAN} "Themen" +LangString TITLE_SecSetASDefault ${LANG_GERMAN} "Standard-Browser" +LangString TITLE_SecProtocols ${LANG_GERMAN} "Protokollverknüpfungen" + +LangString FILE_Htm ${LANG_GERMAN} "HTM-Datei" +LangString FILE_Html ${LANG_GERMAN} "HTML-Datei" + +LangString DESC_SecMain ${LANG_GERMAN} "Hauptkomponenten der Anwendung." +LangString DESC_SecTranslations ${LANG_GERMAN} "Weitere Übersetzungen sind verfügbar. Die Standardsprache ist Englisch." +LangString DESC_SecPlugins ${LANG_GERMAN} "Weitere Plugins stehen zur Verfügung." +LangString DESC_SecDesktop ${LANG_GERMAN} "Starter zum Desktop hinzufügen." +LangString DESC_SecExtensions ${LANG_GERMAN} "Verknüpfe Falkon mit *.htm(l) Dateien" +LangString DESC_SecThemes ${LANG_GERMAN} "Weitere Themen für Falkon" +LangString DESC_SecSetASDefault ${LANG_GERMAN} "Falkon als Standard-Browser verwenden" +LangString DESC_SecProtocols ${LANG_GERMAN} "Verknüpfe Falkon mit HTTP(S)- und FTP-Protokoll" +; +LangString MSG_RunningInstance ${LANG_GERMAN} "Falkon ist bereits gestartet! Soll die Installationsroutine versuchen, Falkon zu beenden?" +LangString MSG_InstallationCanceled ${LANG_GERMAN} "Die Installation wurde vom Benutzer abgebrochen." + +;;;;Dutch +LangString TITLE_SecMain ${LANG_DUTCH} "Hoofdonderdelen" +LangString TITLE_SecTranslations ${LANG_DUTCH} "Vertalingen" +LangString TITLE_SecPlugins ${LANG_DUTCH} "Plugins" +LangString TITLE_SecDesktop ${LANG_DUTCH} "Bureaublad-pictogram" +LangString TITLE_SecExtensions ${LANG_DUTCH} "Bestandsassociaties" +LangString TITLE_SecThemes ${LANG_DUTCH} "Thema's" + +LangString FILE_Htm ${LANG_DUTCH} "HTM-bestand" +LangString FILE_Html ${LANG_DUTCH} "HTML-bestand" + +LangString DESC_SecMain ${LANG_DUTCH} "Hoofdonderdelen van het programma." +LangString DESC_SecTranslations ${LANG_DUTCH} "Beschikbare vertalingen om te installeren. Standaardtaal is Engels." +LangString DESC_SecPlugins ${LANG_DUTCH} "Beschikbare plugins om te installeren." +LangString DESC_SecDesktop ${LANG_DUTCH} "Voeg starter toe op bureaublad." +LangString DESC_SecExtensions ${LANG_DUTCH} "Associeer Falkon met .htm en .html-bestanden" +LangString DESC_SecThemes ${LANG_DUTCH} "Extra thema's voor Falkon" + +;;;;Portuguese +LangString PRODUCT_DESC ${LANG_PORTUGUESE} "O Falkon é um navegador web rápido, seguro e de código livre. O Falkon está sujeito aos termos da GPL versão 3 ou (por opção) qualquer versão posterior. O Falkon é baseado nas tecnologias WebKit e Qt." +; +LangString TITLE_SecMain ${LANG_PORTUGUESE} "Principais componentes" +LangString TITLE_SecTranslations ${LANG_PORTUGUESE} "Traduções" +LangString TITLE_SecPlugins ${LANG_PORTUGUESE} "Plugins" +LangString TITLE_SecDesktop ${LANG_PORTUGUESE} "Ícone no ambiente de trabalho" +LangString TITLE_SecExtensions ${LANG_PORTUGUESE} "Associação de ficheiros" +LangString TITLE_SecThemes ${LANG_PORTUGUESE} "Temas" +LangString TITLE_SecSetASDefault ${LANG_PORTUGUESE} "Navegador pré-definido" +LangString TITLE_SecProtocols ${LANG_PORTUGUESE} "Associações" + +LangString FILE_Htm ${LANG_PORTUGUESE} "Ficheiro HTM" +LangString FILE_Html ${LANG_PORTUGUESE} "Ficheiro HTML" +; +LangString DESC_SecMain ${LANG_PORTUGUESE} "Principais componentes da aplicação" +LangString DESC_SecTranslations ${LANG_PORTUGUESE} "Outros idiomas disponíveis. O idioma padrão é inglês" +LangString DESC_SecPlugins ${LANG_PORTUGUESE} "Outros plugins disponíveis" +LangString DESC_SecDesktop ${LANG_PORTUGUESE} "Adicionar ícone ao ambiente de trabalho" +LangString DESC_SecExtensions ${LANG_PORTUGUESE} "Associar Falkon aos ficheiros .htm e .html" +LangString DESC_SecThemes ${LANG_PORTUGUESE} "Temas extra para o Falkon" +LangString DESC_SecSetASDefault ${LANG_PORTUGUESE} "Definir o Falkon como navegador web padrão" +LangString DESC_SecProtocols ${LANG_PORTUGUESE} "Associar o Falkon com os protocolos http e https" +; +LangString MSG_RunningInstance ${LANG_PORTUGUESE} "O Falkon está em execução! Pretende que o instalador tente terminar o processo?" +LangString MSG_InstallationCanceled ${LANG_PORTUGUESE} "Processo cancelado pelo utilizador" +; +;;;;Greek +LangString TITLE_SecMain ${LANG_GREEK} "Κύρια στοιχεία" +LangString TITLE_SecTranslations ${LANG_GREEK} "Μεταφράσεις" +LangString TITLE_SecPlugins ${LANG_GREEK} "Πρόσθετα" +LangString TITLE_SecDesktop ${LANG_GREEK} "Εικονίδιο επιφάνειας" +LangString TITLE_SecExtensions ${LANG_GREEK} "Συσχετίσεις αρχείων" +LangString TITLE_SecThemes ${LANG_GREEK} "Θέματα" + +LangString FILE_Htm ${LANG_GREEK} "Αρχείο HTM" +LangString FILE_Html ${LANG_GREEK} "Αρχείο HTML" + +LangString DESC_SecMain ${LANG_GREEK} "Κυρια στοιχεία της εφαρμογής." +LangString DESC_SecTranslations ${LANG_GREEK} "Άλλες μεταφράσεις διαθέσιμες προς εγκατάσταση. Η προεπιλεγμένη είναι Αγγλικά." +LangString DESC_SecPlugins ${LANG_GREEK} "Άλλα πρόσθετα διαθέσιμα προς εγκατάσταση." +LangString DESC_SecDesktop ${LANG_GREEK} "Προσθήκη εκκινητή στην επιφάνεια." +LangString DESC_SecExtensions ${LANG_GREEK} "Συσχέτιση του Falkon με αρχεία .htm και .html" +LangString DESC_SecThemes ${LANG_GREEK} "Πρόσθετα θέματα για το Falkon" + +;;;;French +LangString PRODUCT_DESC ${LANG_FRENCH} "Falkon est un nouveau navigateur Internet, libre, rapide et sûr. Falkon est sous licence GPLv3 ou (selon votre version) une version plus récente. Il est basé sur WebKit et le framework Qt." + +LangString TITLE_SecMain ${LANG_FRENCH} "Composants principaux" +LangString TITLE_SecTranslations ${LANG_FRENCH} "Langues" +LangString TITLE_SecPlugins ${LANG_FRENCH} "Plugins" +LangString TITLE_SecDesktop ${LANG_FRENCH} "Icône de Bureau" +LangString TITLE_SecExtensions ${LANG_FRENCH} "Associations de fichiers" +LangString TITLE_SecThemes ${LANG_FRENCH} "Thèmes" +LangString TITLE_SecSetASDefault ${LANG_FRENCH} "Navigateur par défaut" +LangString TITLE_SecProtocols ${LANG_FRENCH} "Associations de protocoles" + +LangString FILE_Htm ${LANG_FRENCH} "Fichiers HTM " +LangString FILE_Html ${LANG_FRENCH} "Fichiers HTML" + +LangString DESC_SecMain ${LANG_FRENCH} "Composants principaux de l'application." +LangString DESC_SecTranslations ${LANG_FRENCH} "Autres langues disponibles à l'installation. La langue par défaut est l'anglais." +LangString DESC_SecPlugins ${LANG_FRENCH} "Autres plugins disponibles pour l'installation." +LangString DESC_SecDesktop ${LANG_FRENCH} "Ajouter une icône sur le bureau." +LangString DESC_SecExtensions ${LANG_FRENCH} "Associer Falkon aux fichiers .htm et .html" +LangString DESC_SecThemes ${LANG_FRENCH} "Thèmes supplémentaires pour Falkon" +LangString DESC_SecSetASDefault ${LANG_FRENCH} "Utiliser Falkon comme navigateur par défaut" +LangString DESC_SecProtocols ${LANG_FRENCH} "Associer Falkon aux protocoles http(s) et ftp" + +LangString MSG_RunningInstance ${LANG_FRENCH} "Falkon est déjà en fonctionnement ! Voulez vous que l'installeur le ferme pour vous ?" +LangString MSG_InstallationCanceled ${LANG_FRENCH} "Processus annulé par l'utilisateur." + +;;;;Italian +LangString TITLE_SecMain ${LANG_ITALIAN} "Componenti principali" +LangString TITLE_SecTranslations ${LANG_ITALIAN} "Traduzioni" +LangString TITLE_SecPlugins ${LANG_ITALIAN} "Plugins" +LangString TITLE_SecDesktop ${LANG_ITALIAN} "Icona Desktop" +LangString TITLE_SecExtensions ${LANG_ITALIAN} "Associazione file" +LangString TITLE_SecThemes ${LANG_ITALIAN} "Temi" + +LangString FILE_Htm ${LANG_ITALIAN} "File HTM" +LangString FILE_Html ${LANG_ITALIAN} "File HTML" +; +LangString DESC_SecMain ${LANG_ITALIAN} "Componenti principali dell'applicazione." +LangString DESC_SecTranslations ${LANG_ITALIAN} "Altre traduzioni disponibili per l'installazione. Quella predefinita è l'Inglese." +LangString DESC_SecPlugins ${LANG_ITALIAN} "Altri plugins disponibili per l'installazione." +LangString DESC_SecDesktop ${LANG_ITALIAN} "Aggiunge il lanciatore al desktop." +LangString DESC_SecExtensions ${LANG_ITALIAN} "Associa Falkon ai file .htm and .html" +LangString DESC_SecThemes ${LANG_ITALIAN} "Temi aggiuntivi per Falkon" + +;;;;Romanian +LangString TITLE_SecMain ${LANG_ROMANIAN} "Componente principale" +LangString TITLE_SecTranslations ${LANG_ROMANIAN} "Traduceri" +LangString TITLE_SecPlugins ${LANG_ROMANIAN} "Plugin-uri" +LangString TITLE_SecDesktop ${LANG_ROMANIAN} "Iconiță Desktop" +LangString TITLE_SecExtensions ${LANG_ROMANIAN} "Asocieri fișiere" +LangString TITLE_SecThemes ${LANG_ROMANIAN} "Teme" + +LangString FILE_Htm ${LANG_ROMANIAN} "Fișier HTM" +LangString FILE_Html ${LANG_ROMANIAN} "Fișier HTML" +; +LangString DESC_SecMain ${LANG_ROMANIAN} "Componentele principale ale aplicației." +LangString DESC_SecTranslations ${LANG_ROMANIAN} "Alte traduceri disponibile pentru instalare. Predefinită este Engleza." +LangString DESC_SecPlugins ${LANG_ROMANIAN} "Alte plugin-uri sunt disponibile pentru instalare." +LangString DESC_SecDesktop ${LANG_ROMANIAN} "Adaugă scurtătură pe Desktop." +LangString DESC_SecExtensions ${LANG_ROMANIAN} "Asociază Falkon cu .htm și fișiere .html" +LangString DESC_SecThemes ${LANG_ROMANIAN} "Teme adiționale pentru Falkon" + +;;;;Hongkongese +LangString PRODUCT_DESC ${LANG_HONGKONG} "Falkon是一個嶄新、快速、安全和開放原始碼的網頁瀏覽器。Falkon基於GPL的3或(你意願下的)較新版本釋出授權。Falkon使用WebKit核心和Qt框架。" +; +LangString TITLE_SecMain ${LANG_HONGKONG} "主要組件" +LangString TITLE_SecTranslations ${LANG_HONGKONG} "語言" +LangString TITLE_SecPlugins ${LANG_HONGKONG} "外掛程式" +LangString TITLE_SecDesktop ${LANG_HONGKONG} "桌面圖示" +LangString TITLE_SecExtensions ${LANG_HONGKONG} "檔案管理" +LangString TITLE_SecThemes ${LANG_HONGKONG} "主題" +LangString TITLE_SecSetASDefault ${LANG_HONGKONG} "預設瀏覽器" +LangString TITLE_SecProtocols ${LANG_HONGKONG} "網絡協定關聯" + +LangString FILE_Htm ${LANG_HONGKONG} "HTM檔案" +LangString FILE_Html ${LANG_HONGKONG} "HTML檔案" +; +LangString DESC_SecMain ${LANG_HONGKONG} "程式主要組件。" +LangString DESC_SecTranslations ${LANG_HONGKONG} "可選用的語言,預設為英語。" +LangString DESC_SecPlugins ${LANG_HONGKONG} "可選用的外掛程式。" +LangString DESC_SecDesktop ${LANG_HONGKONG} "建立桌面捷徑。" +LangString DESC_SecExtensions ${LANG_HONGKONG} "預設Falkon為開啟「.htm」和「.html」檔案的瀏覽器。" +LangString DESC_SecThemes ${LANG_HONGKONG} "其他Falkon主題。" +LangString DESC_SecSetASDefault ${LANG_HONGKONG} "設定Falkon為預設瀏覽器。" +LangString DESC_SecProtocols ${LANG_HONGKONG} "關聯Falkon到http、https和ftp協定。" +; +LangString MSG_RunningInstance ${LANG_HONGKONG} "Falkon啟用中。是否要求安裝程式代為關閉Falkon?" +LangString MSG_InstallationCanceled ${LANG_HONGKONG} "用戶主動終止安裝。" + +;;;;Traditional Chinese +LangString PRODUCT_DESC ${LANG_TRADCHINESE} "Falkon 是一個新穎、快速、安全且開放原始碼的 WWW 瀏覽器。Falkon 以 GPLv3 或是 (在您的選擇下) 更新的版本釋出。Falkon 是基於 WebKit 內核及 Qt 框架。" +; +LangString TITLE_SecMain ${LANG_TRADCHINESE} "主要組件" +LangString TITLE_SecTranslations ${LANG_TRADCHINESE} "語言版本" +LangString TITLE_SecPlugins ${LANG_TRADCHINESE} "外掛" +LangString TITLE_SecDesktop ${LANG_TRADCHINESE} "桌面圖示" +LangString TITLE_SecExtensions ${LANG_TRADCHINESE} "檔案管理" +LangString TITLE_SecThemes ${LANG_TRADCHINESE} "主題" +LangString TITLE_SecSetASDefault ${LANG_TRADCHINESE} "預設瀏覽器" +LangString TITLE_SecProtocols ${LANG_TRADCHINESE} "通訊協定關聯" + +LangString FILE_Htm ${LANG_TRADCHINESE} "HTM 檔案" +LangString FILE_Html ${LANG_TRADCHINESE} "HTML 檔案" +; +LangString DESC_SecMain ${LANG_TRADCHINESE} "程式主要組件。" +LangString DESC_SecTranslations ${LANG_TRADCHINESE} "可安裝的語言版本,預設是英語。" +LangString DESC_SecPlugins ${LANG_TRADCHINESE} "可安裝的外掛。" +LangString DESC_SecDesktop ${LANG_TRADCHINESE} "在桌面新增啟動圖示。" +LangString DESC_SecExtensions ${LANG_TRADCHINESE} "將 Falkon 做為預設開啟 .htm 以及 .html 檔案的瀏覽器。" +LangString DESC_SecThemes ${LANG_TRADCHINESE} "額外的 Falkon 主題。" +LangString DESC_SecSetASDefault ${LANG_TRADCHINESE} "將 Falkon 做為預設瀏覽器。" +LangString DESC_SecProtocols ${LANG_TRADCHINESE} "關聯 http、https 與 ftp 協定至 Falkon。" +; +LangString MSG_RunningInstance ${LANG_TRADCHINESE} "正在執行 Falkon。要求安裝程式嘗試終止它嗎?" +LangString MSG_InstallationCanceled ${LANG_TRADCHINESE} "使用者取消安裝。" + +;;;;Simplified Chinese +LangString PRODUCT_DESC ${LANG_SIMPCHINESE} "Falkon 是新出、高速、安全的开源 WWW 浏览器。Falkon 基于 GPL 协议第 3 版或(如果您需要)任何之后的版本。它使用 WebKit 排版引擎。" +; +LangString TITLE_SecMain ${LANG_SIMPCHINESE} "核心部件" +LangString TITLE_SecTranslations ${LANG_SIMPCHINESE} "翻译" +LangString TITLE_SecPlugins ${LANG_SIMPCHINESE} "应用扩展" +LangString TITLE_SecDesktop ${LANG_SIMPCHINESE} "桌面图标" +LangString TITLE_SecExtensions ${LANG_SIMPCHINESE} "文件管理" +LangString TITLE_SecThemes ${LANG_SIMPCHINESE} "皮肤" +LangString TITLE_SecSetASDefault ${LANG_SIMPCHINESE} "默认浏览器" +LangString TITLE_SecProtocols ${LANG_SIMPCHINESE} "关联协议" + +LangString FILE_Htm ${LANG_SIMPCHINESE} "HTM 文件" +LangString FILE_Html ${LANG_SIMPCHINESE} "HTML 文件" +; +LangString DESC_SecMain ${LANG_SIMPCHINESE} "程序核心部件。" +LangString DESC_SecTranslations ${LANG_SIMPCHINESE} "可以安装其它翻译,默认为英文。" +LangString DESC_SecPlugins ${LANG_SIMPCHINESE} "可以安装其它应用扩展。" +LangString DESC_SecDesktop ${LANG_SIMPCHINESE} "在桌面新建启动图标。" +LangString DESC_SecExtensions ${LANG_SIMPCHINESE} "将 Falkon 做为默认打开 .htm 以及 .html 文件的浏览器。" +LangString DESC_SecThemes ${LANG_SIMPCHINESE} "其它的 Falkon 皮肤。" +LangString DESC_SecSetASDefault ${LANG_SIMPCHINESE} "将 Falkon 做为默认浏览器。" +LangString DESC_SecProtocols ${LANG_SIMPCHINESE} "关联 http、https 与 ftp 协议至 Falkon。" +; +LangString MSG_RunningInstance ${LANG_SIMPCHINESE} "正在使用 Falkon。您希望安装程序试着结束它吗?" +LangString MSG_InstallationCanceled ${LANG_SIMPCHINESE} "用户撤销程序。" + +;;;;Bahasa Indonesia +LangString TITLE_SecMain ${LANG_INDONESIAN} "Komponen Utama" +LangString TITLE_SecTranslations ${LANG_INDONESIAN} "Terjemahan" +LangString TITLE_SecPlugins ${LANG_INDONESIAN} "Pengaya" +LangString TITLE_SecDesktop ${LANG_INDONESIAN} "Ikon Desktop" +LangString TITLE_SecExtensions ${LANG_INDONESIAN} "Asosiasi Berkas" +LangString TITLE_SecThemes ${LANG_INDONESIAN} "Tema" + +LangString FILE_Htm ${LANG_INDONESIAN} "Berkas HTM" +LangString FILE_Html ${LANG_INDONESIAN} "Berkas HTML" +; +LangString DESC_SecMain ${LANG_INDONESIAN} "Komponen utama dari aplikasi." +LangString DESC_SecTranslations ${LANG_INDONESIAN} "Tersedia terjemahan lain untuk diinstal. Default adalah Bahasa Inggris." +LangString DESC_SecPlugins ${LANG_INDONESIAN} "Tersedia pengaya lain untuk diinstal." +LangString DESC_SecDesktop ${LANG_INDONESIAN} "Tambahkan peluncur ke desktop." +LangString DESC_SecExtensions ${LANG_INDONESIAN} "Asosiasikan Falkon dengan berkas .htm dan .html" +LangString DESC_SecThemes ${LANG_INDONESIAN} "Tema tambahan untuk Falkon" + +;;;;Georgian +LangString TITLE_SecMain ${LANG_GEORGIAN} "მთავარი კომპონენტები" +LangString TITLE_SecTranslations ${LANG_GEORGIAN} "თარგმანები" +LangString TITLE_SecPlugins ${LANG_GEORGIAN} "მოდულები" +LangString TITLE_SecDesktop ${LANG_GEORGIAN} "სამუშაო მაგიდის ხატულა" +LangString TITLE_SecExtensions ${LANG_GEORGIAN} "ფაილებთან ასოცირება" +LangString TITLE_SecThemes ${LANG_GEORGIAN} "თემები" + +LangString FILE_Htm ${LANG_GEORGIAN} "HTM ფაილი" +LangString FILE_Html ${LANG_GEORGIAN} "HTML ფაილი" +; +LangString DESC_SecMain ${LANG_GEORGIAN} "პროგრამის მთავარი კომპონენტები." +LangString DESC_SecTranslations ${LANG_GEORGIAN} "სხვა ენები რომელთა დაყენებაც შესაძლებელია. ნაგულისხმევი არის ინგლისური." +LangString DESC_SecPlugins ${LANG_GEORGIAN} "სხვა მოდულები რომელთა დაყენებაც შესაძლებელია." +LangString DESC_SecDesktop ${LANG_GEORGIAN} "გამშვების დამატება სამუშაო მაგიდაზე." +LangString DESC_SecExtensions ${LANG_GEORGIAN} "Falkon-ს ასოცირება .htm და .html ფაილებთან" +LangString DESC_SecThemes ${LANG_GEORGIAN} "დამატებითი თემები Falkon-სთვის" + +;;;;Japanese +LangString PRODUCT_DESC ${LANG_JAPANESE} "Falkon は新しくて、高速で、安全なオープンソース WWW ブラウザです。 Falkon は GPL version 3 (任意の)それ以降のバージョンでライセンスされています。WebKit コアと Qt Framework ベースで開発されています。" +; +LangString TITLE_SecMain ${LANG_JAPANESE} "メインコンポーネント" +LangString TITLE_SecTranslations ${LANG_JAPANESE} "言語ファイル" +LangString TITLE_SecPlugins ${LANG_JAPANESE} "エクステンション(拡張機能)" +LangString TITLE_SecDesktop ${LANG_JAPANESE} "デスクトップアイコン" +LangString TITLE_SecExtensions ${LANG_JAPANESE} "ファイルの関連付け" +LangString TITLE_SecThemes ${LANG_JAPANESE} "テーマ" +LangString TITLE_SecSetASDefault ${LANG_JAPANESE} "既定のブラウザ" +LangString TITLE_SecProtocols ${LANG_JAPANESE} "プロトコルの関連付け" + +LangString FILE_Htm ${LANG_JAPANESE} "HTM ファイル" +LangString FILE_Html ${LANG_JAPANESE} "HTML ファイル" +; +LangString DESC_SecMain ${LANG_JAPANESE} "アプリケーションのメインとなる部分です。" +LangString DESC_SecTranslations ${LANG_JAPANESE} "他の言語でも Falkon を使えるようになります。デフォルトでは英語です。" +LangString DESC_SecPlugins ${LANG_JAPANESE} "プラグイン(拡張機能)を追加してダウンロードします。" +LangString DESC_SecDesktop ${LANG_JAPANESE} "デスクトップにアイコンを作成します。" +LangString DESC_SecExtensions ${LANG_JAPANESE} "Falkon に htm, html ファイルを関連付けます。" +LangString DESC_SecThemes ${LANG_JAPANESE} "Falkon のデフォルトテーマ以外のテーマをダウンロードします。" +LangString DESC_SecSetASDefault ${LANG_JAPANESE} "Falkon を既定の Web ブラウザに設定する。" +LangString DESC_SecProtocols ${LANG_JAPANESE} "Falkon を http, https プロトコルに関連付けます。" +; +LangString MSG_RunningInstance ${LANG_JAPANESE} "Falkon は起動中です!インストーラーによって終了させますか?" +LangString MSG_InstallationCanceled ${LANG_JAPANESE} "プロセスはユーザーによって中止されました。" + +;;;;SWEDISH +LangString TITLE_SecMain ${LANG_SWEDISH} "Huvudkomponenter" +LangString DESC_SecMain ${LANG_SWEDISH} "Programmets viktigaste komponenter." +LangString TITLE_SecTranslations ${LANG_SWEDISH} "Översättningar" +LangString DESC_SecTranslations ${LANG_SWEDISH} "Andra översättningar tillgängliga för installation. Förval är Engelska." +LangString TITLE_SecPlugins ${LANG_SWEDISH} "Insticksmoduler" +LangString DESC_SecPlugins ${LANG_SWEDISH} "Andra insticksmoduler tillgängliga för installation." +LangString TITLE_SecDesktop ${LANG_SWEDISH} "Skrivbordsikon" +LangString DESC_SecDesktop ${LANG_SWEDISH} "Lägg till en ikon på skrivbordet." +LangString TITLE_SecExtensions ${LANG_SWEDISH} "Filbindningar" +LangString DESC_SecExtensions ${LANG_SWEDISH} "Associera Falkon med .htm- och .html-filer" +LangString FILE_Htm ${LANG_SWEDISH} "HTM-fil" +LangString FILE_Html ${LANG_SWEDISH} "HTML-fil" +LangString TITLE_SecThemes ${LANG_SWEDISH} "Teman" +LangString DESC_SecThemes ${LANG_SWEDISH} "Ytterligare teman för Falkon" + +;;;;Polish +LangString TITLE_SecMain ${LANG_POLISH} "Składniki podstawowe" +LangString TITLE_SecTranslations ${LANG_POLISH} "Tłumaczenia" +LangString TITLE_SecPlugins ${LANG_POLISH} "Wtyczki" +LangString TITLE_SecDesktop ${LANG_POLISH} "Ikona pulpitu" +LangString TITLE_SecExtensions ${LANG_POLISH} "Skojarzenia plików" +LangString TITLE_SecThemes ${LANG_POLISH} "Motywy" + +LangString FILE_Htm ${LANG_POLISH} "Plik HTM" +LangString FILE_Html ${LANG_POLISH} "Plik HTML" +; +LangString DESC_SecMain ${LANG_POLISH} "Podstawowe składniki programu." +LangString DESC_SecTranslations ${LANG_POLISH} "Instalacja dodatkowych wersji językowych. Domyślnie tylko język angielski." +LangString DESC_SecPlugins ${LANG_POLISH} "Instalacja dodatkowych wtyczek." +LangString DESC_SecDesktop ${LANG_POLISH} "Dodaj skrót do pulpitu." +LangString DESC_SecExtensions ${LANG_POLISH} "Skojarz przeglądarkę Falkon z plikami .htm i .html" +LangString DESC_SecThemes ${LANG_POLISH} "Dodatkowe motywy dla przeglądarki Falkon" + +LangString MSG_InstallationCanceled ${LANG_POLISH} "Proces anulowany przez użytkownika." +LangString MSG_RunningInstance ${LANG_POLISH} "Falkon jest już uruchomiona! Chcesz aby instalator spróbował ją wyłączyć?" +LangString DESC_SecProtocols ${LANG_POLISH} "Skojarz QupZille z linkami http(s) i protokołem ftp" +LangString DESC_SecSetASDefault ${LANG_POLISH} "Ustaw QupZille jako domyślną przeglądarke" +LangString TITLE_SecProtocols ${LANG_POLISH} "Protokół Skojarzeń" +LangString TITLE_SecSetASDefault ${LANG_POLISH} "Domyślna Przeglądarka" + +LangString PRODUCT_DESC ${LANG_POLISH} "Falkon jest nową, szybką i bezpieczną zbudowaną na otwartych źródłach przeglądarką . Falkon podlega licencji GPL wersji 3 lub każdej późniejszej. Bazuje na silniku WebKit oraz Frameworku Qt." + +;;;;Ukrainian +LangString TITLE_SecMain ${LANG_UKRAINIAN} "Основні компоненти" +LangString TITLE_SecTranslations ${LANG_UKRAINIAN} "Переклади" +LangString TITLE_SecPlugins ${LANG_UKRAINIAN} "Плаґіни" +LangString TITLE_SecDesktop ${LANG_UKRAINIAN} "Іконка на робочому столі" +LangString TITLE_SecExtensions ${LANG_UKRAINIAN} "Асоціювання файлів" +LangString TITLE_SecThemes ${LANG_UKRAINIAN} "Теми" + +LangString FILE_Htm ${LANG_UKRAINIAN} "Файл HTM" +LangString FILE_Html ${LANG_UKRAINIAN} "Файл HTML" +; +LangString DESC_SecMain ${LANG_UKRAINIAN} "Основні компоненти програми." +LangString DESC_SecTranslations ${LANG_UKRAINIAN} "Доступні інші переклади для встановлення. Мова за умовчуванням - англійська." +LangString DESC_SecPlugins ${LANG_UKRAINIAN} "Доступні інші плаґіни для встановлення." +LangString DESC_SecDesktop ${LANG_UKRAINIAN} "Додати посилання на робочий стіл." +LangString DESC_SecExtensions ${LANG_UKRAINIAN} "Асоціювати QupZill'у з файлами .htm і .html" +LangString DESC_SecThemes ${LANG_UKRAINIAN} "Додаткові теми для QupZill'и" + +;;;;Persian (Farsi) +LangString PRODUCT_DESC ${LANG_FARSI} "‫کوپزیلا مرورگر اینترنتی متن‌باز، جدید، سریع و ایمنی است. کوپزیلا تحت توافقنامه GPL نسخه ۳ یا هر نسخه جدیدتر آن است. کوپزیلا تحت هسته وب‌کیت و چارچوب کیوت می‌باشد.‬" +; +LangString TITLE_SecMain ${LANG_FARSI} "بخش اصلی" +LangString TITLE_SecTranslations ${LANG_FARSI} "برگردان‌ها" +LangString TITLE_SecPlugins ${LANG_FARSI} "افزونه‌ها" +LangString TITLE_SecDesktop ${LANG_FARSI} "آیکون میزکار" +LangString TITLE_SecExtensions ${LANG_FARSI} "تخصیص فایل" +LangString TITLE_SecThemes ${LANG_FARSI} "فرهشت‌ها" +LangString TITLE_SecSetASDefault ${LANG_FARSI} "مرورگر پیش‌فرض" +LangString TITLE_SecProtocols ${LANG_FARSI} "تخصیص پروتکل" + +LangString FILE_Htm ${LANG_FARSI} "HTM File" +LangString FILE_Html ${LANG_FARSI} "HTML File" +; +LangString DESC_SecMain ${LANG_FARSI} "بخش اصلی نرم‌افزار." +LangString DESC_SecTranslations ${LANG_FARSI} "دیگر برگردان‌های دردسترس. پیش فرض انگلیسی است." +LangString DESC_SecPlugins ${LANG_FARSI} "افزونه‌های دیگر که برای نصب در دسترس هستند." +LangString DESC_SecDesktop ${LANG_FARSI} "افزودن میان‌برِ آغازگر به میزکار" +LangString DESC_SecExtensions ${LANG_FARSI} "کوپزیلا را برای بازکردن فایل‌های ‎.htm(l)‎ اختصاص می‌دهد." +LangString DESC_SecThemes ${LANG_FARSI} "فرهشت‌های اضافی برای کوپزیلا" +LangString DESC_SecSetASDefault ${LANG_FARSI} "تنظیم کوپزیلا به عنوان مرورگر پیش‌فرض" +LangString DESC_SecProtocols ${LANG_FARSI} "کوپزیلا را به پروتکل‌های http(s)‎ و ftp اختصاص می‌دهد." +; +LangString MSG_RunningInstance ${LANG_FARSI} "کوپزیلا هم‌اکنون در حال اجراست! آیا می‌خواهید برنامه نصب تلاش کند به اجرای آن خاتمه دهد؟" +LangString MSG_InstallationCanceled ${LANG_FARSI} "فرایند توسط کاربر لغو گردید." + +;;;;Serbian +LangString PRODUCT_DESC ${LANG_SERBIAN} "Капзила је нови, брз и сигуран веб прегледач отвореног кода. Лиценцирана под ГПЛ в3 лиценцом или (по властитом нахођењу) каснијим издањем те лиценце. Заснована на ВебКит језгри и Кјут програмском окружењу." +; +LangString TITLE_SecMain ${LANG_SERBIAN} "Главне компоненте" +LangString TITLE_SecTranslations ${LANG_SERBIAN} "Преводи" +LangString TITLE_SecPlugins ${LANG_SERBIAN} "Проширења" +LangString TITLE_SecDesktop ${LANG_SERBIAN} "Икона на радној површи" +LangString TITLE_SecExtensions ${LANG_SERBIAN} "Придружења фајлова" +LangString TITLE_SecThemes ${LANG_SERBIAN} "Теме" +LangString TITLE_SecSetASDefault ${LANG_SERBIAN} "Подразумеван прегледач" +LangString TITLE_SecProtocols ${LANG_SERBIAN} "Придружења протокола" + +LangString FILE_Htm ${LANG_SERBIAN} "ХТМ фајл" +LangString FILE_Html ${LANG_SERBIAN} "ХТМЛ фајл" +; +LangString DESC_SecMain ${LANG_SERBIAN} "Главне компоненте програма." +LangString DESC_SecTranslations ${LANG_SERBIAN} "Остали доступни преводи. Енглески је подразумеван." +LangString DESC_SecPlugins ${LANG_SERBIAN} "Остала проширења - прикључци." +LangString DESC_SecDesktop ${LANG_SERBIAN} "Покретач програма на радној површи." +LangString DESC_SecExtensions ${LANG_SERBIAN} "Отварај .htm(l) фајлове у Капзили." +LangString DESC_SecThemes ${LANG_SERBIAN} "Додатне теме за Капзилу" +LangString DESC_SecSetASDefault ${LANG_SERBIAN} "Постави Капзилу за подразумевани веб прегледач." +LangString DESC_SecProtocols ${LANG_SERBIAN} "Отварај http(s) и ftp протоколе у Капзили." +; +LangString MSG_RunningInstance ${LANG_SERBIAN} "Капзила је већ покренута! Желите ли да инсталатер покуша да је угаси?" +LangString MSG_InstallationCanceled ${LANG_SERBIAN} "Корисник је отказао процес." + +;;;;SerbianLatin +LangString PRODUCT_DESC ${LANG_SERBIANLATIN} "Kapzila je novi, brz i siguran veb pregledač otvorenog koda. Licencirana pod GPL v3 licencom ili (po vlastitom nahođenju) kasnijim izdanjem te licence. Zasnovana na VebKit jezgri i Kjut programskom okruženju." +; +LangString TITLE_SecMain ${LANG_SERBIANLATIN} "Glavne komponente" +LangString TITLE_SecTranslations ${LANG_SERBIANLATIN} "Prevodi" +LangString TITLE_SecPlugins ${LANG_SERBIANLATIN} "Proširenja" +LangString TITLE_SecDesktop ${LANG_SERBIANLATIN} "Ikona na radnoj površi" +LangString TITLE_SecExtensions ${LANG_SERBIANLATIN} "Pridruženja fajlova" +LangString TITLE_SecThemes ${LANG_SERBIANLATIN} "Teme" +LangString TITLE_SecSetASDefault ${LANG_SERBIANLATIN} "Podrazumevan pregledač" +LangString TITLE_SecProtocols ${LANG_SERBIANLATIN} "Pridruženja protokola" + +LangString FILE_Htm ${LANG_SERBIANLATIN} "HTM fajl" +LangString FILE_Html ${LANG_SERBIANLATIN} "HTML fajl" +; +LangString DESC_SecMain ${LANG_SERBIANLATIN} "Glavne komponente programa." +LangString DESC_SecTranslations ${LANG_SERBIANLATIN} "Ostali dostupni prevodi. Engleski je podrazumevan." +LangString DESC_SecPlugins ${LANG_SERBIANLATIN} "Ostala proširenja - priključci." +LangString DESC_SecDesktop ${LANG_SERBIANLATIN} "Pokretač programa na radnoj površi." +LangString DESC_SecExtensions ${LANG_SERBIANLATIN} "Otvaraj .htm(l) fajlove u Kapzili." +LangString DESC_SecThemes ${LANG_SERBIANLATIN} "Dodatne teme za Kapzilu" +LangString DESC_SecSetASDefault ${LANG_SERBIANLATIN} "Postavi Kapzilu za podrazumevani veb pregledač." +LangString DESC_SecProtocols ${LANG_SERBIANLATIN} "Otvaraj http(s) i ftp protokole u Kapzili." +; +LangString MSG_RunningInstance ${LANG_SERBIANLATIN} "Kapzila je već pokrenuta! Želite li da instalater pokuša da je ugasi?" +LangString MSG_InstallationCanceled ${LANG_SERBIANLATIN} "Korisnik je otkazao proces." + +;;;;Hebrew +LangString PRODUCT_DESC ${LANG_HEBREW} "Falkon הינו דפדפן WWW קוד פתוח חדש, מהיר ומאובטח. Falkon רשוי תחת הרשיון GPL גרסא 3 או (כאופציה השמורה לך) כל גרסא מאוחרת יותר. זה מבוסס על ליבת WebKit ועל Qt Framework." +; +LangString TITLE_SecMain ${LANG_HEBREW} "רכיבים עיקריים" +LangString TITLE_SecTranslations ${LANG_HEBREW} "תרגומים" +LangString TITLE_SecPlugins ${LANG_HEBREW} "תוספות" +LangString TITLE_SecDesktop ${LANG_HEBREW} "סמל שולחן עבודה" +LangString TITLE_SecExtensions ${LANG_HEBREW} "שיוכי קובץ" +LangString TITLE_SecThemes ${LANG_HEBREW} "ערכות נושא" +LangString TITLE_SecSetASDefault ${LANG_HEBREW} "דפדפן ברירת מחדל" +LangString TITLE_SecProtocols ${LANG_HEBREW} "שיוכי פרוטוקול" + +LangString FILE_Htm ${LANG_HEBREW} "קובץ HTM" +LangString FILE_Html ${LANG_HEBREW} "קובץ HTML" +; +LangString DESC_SecMain ${LANG_HEBREW} "רכיבים עיקריים של יישום." +LangString DESC_SecTranslations ${LANG_HEBREW} "תרגומים אחרים זמינים להתקנה. ברירת מחדל הינה English." +LangString DESC_SecPlugins ${LANG_HEBREW} "תוספות אחרות זמינות להתקנה." +LangString DESC_SecDesktop ${LANG_HEBREW} "הוסף משגר אל שולחן עבודה." +LangString DESC_SecExtensions ${LANG_HEBREW} "שייך את Falkon עם קבצי .htm(l)" +LangString DESC_SecThemes ${LANG_HEBREW} "ערכות נושא נוספות עבור Falkon" +LangString DESC_SecSetASDefault ${LANG_HEBREW} "הגדר את Falkon כדפדפן אינטרנט ברירת מחדל" +LangString DESC_SecProtocols ${LANG_HEBREW} "שייך את Falkon עם פרוטוקול http(s) ופרוטוקול ftp" +; +LangString MSG_RunningInstance ${LANG_HEBREW} "Falkon כבר מורץ כעת! האם ברצונך מהמתקין לנסות לסיימו?" +LangString MSG_InstallationCanceled ${LANG_HEBREW} "תהליך בוטל על ידי משתמש." + +;;;;Basque +LangString PRODUCT_DESC ${LANG_BASQUE} "Falkon iturburu-irekiko WWW nabigatzaile berri, azkar eta seguru bat da. Falkon GPL 3 bertsioa baimenpean dago edo (zure aukeran) edozein bertsio berriagoan. WebKit nukleoan eta Qt Framework-ean ohinarrituta dago." +; +LangString TITLE_SecMain ${LANG_BASQUE} "Osagai Nagusiak" +LangString TITLE_SecTranslations ${LANG_BASQUE} "Itzulpenak" +LangString TITLE_SecPlugins ${LANG_BASQUE} "Pluginak" +LangString TITLE_SecDesktop ${LANG_BASQUE} "Mahaigain Ikurra" +LangString TITLE_SecExtensions ${LANG_BASQUE} "Agiri Elkarketa" +LangString TITLE_SecThemes ${LANG_BASQUE} "Azalgaiak" +LangString TITLE_SecSetASDefault ${LANG_BASQUE} "Berezko Nabigatzailea" +LangString TITLE_SecProtocols ${LANG_BASQUE} "Protokolo Elkarketak" + +LangString FILE_Htm ${LANG_BASQUE} "HTM Agiria" +LangString FILE_Html ${LANG_BASQUE} "HTML Agiria" +; +LangString DESC_SecMain ${LANG_BASQUE} "Aplikazioaren osagai nagusiak." +LangString DESC_SecTranslations ${LANG_BASQUE} "Ezartzeko eskuragarri dauden beste itzulpenak. Berezkoa Ingelera da." +LangString DESC_SecPlugins ${LANG_BASQUE} "Ezartzeko eskuragarri dauden beste pluginak." +LangString DESC_SecDesktop ${LANG_BASQUE} "Gehitu abiarazlea mahaigainean." +LangString DESC_SecExtensions ${LANG_BASQUE} "Elkartu Falkon .htm(l) agiriekin" +LangString DESC_SecThemes ${LANG_BASQUE} "Falkon-rentzako azalgai gehigarriak" +LangString DESC_SecSetASDefault ${LANG_BASQUE} "Ezarri Falkon berezko internet nabigatzaile bezala" +LangString DESC_SecProtocols ${LANG_BASQUE} "Elkartu Falkon http(s) eta ftp protokoloekin" +; +LangString MSG_RunningInstance ${LANG_BASQUE} "Falkon jadanik ekinean dago! Nahi duzu ezartzaileak hura amaitzen saiatzea?" +LangString MSG_InstallationCanceled ${LANG_BASQUE} "Prozesua erabiltzaileak ezeztaturik." + +;;;;Danish +LangString PRODUCT_DESC ${LANG_DANISH} "Falkon er en ny, hurtig og sikker open source WWW-browser. Falkon er licenseret under GPL version 3 eller (efter eget valg) en senere version. Den er baseret på WebKit-kerne og Qt-framework." +; +LangString TITLE_SecMain ${LANG_DANISH} "Hovedkomponenter" +LangString TITLE_SecTranslations ${LANG_DANISH} "Oversættelser" +LangString TITLE_SecPlugins ${LANG_DANISH} "Plugins" +LangString TITLE_SecDesktop ${LANG_DANISH} "Skrivebordsikon" +LangString TITLE_SecExtensions ${LANG_DANISH} "Filtilknytninger" +LangString TITLE_SecThemes ${LANG_DANISH} "Temaer" +LangString TITLE_SecSetASDefault ${LANG_DANISH} "Standardbrowser" +LangString TITLE_SecProtocols ${LANG_DANISH} "Protokoltilknytninger" + +LangString FILE_Htm ${LANG_DANISH} "HTM-fil" +LangString FILE_Html ${LANG_DANISH} "HTML-fil" +; +LangString DESC_SecMain ${LANG_DANISH} "Programmets hovedkomponenter." +LangString DESC_SecTranslations ${LANG_DANISH} "Andre oversættelser som kan installeres. Engelsk er standard." +LangString DESC_SecPlugins ${LANG_DANISH} "Andre plugins som kan installeres." +LangString DESC_SecDesktop ${LANG_DANISH} "Tilføj genvej på skrivebordet." +LangString DESC_SecExtensions ${LANG_DANISH} "Tilknyt Falkon med .htm(l)-filer" +LangString DESC_SecThemes ${LANG_DANISH} "Yderligere temaer til Falkon" +LangString DESC_SecSetASDefault ${LANG_DANISH} "Indstil Falkon som standardinternetbrowser" +LangString DESC_SecProtocols ${LANG_DANISH} "Tilknyt Falkon med http(s)- og ftp-protokoller" +; +LangString MSG_RunningInstance ${LANG_DANISH} "Falkon kører allerede! Vil du have installationsprogrammet til at stoppe den?" +LangString MSG_InstallationCanceled ${LANG_DANISH} "Proces annulleret af bruger." + +;;;;;;;;; +;;;;;;;;; +; Unfinished translations +;;;;;;;;; +;;;;;;;;; +LangString PRODUCT_DESC ${LANG_DUTCH} "Falkon is a new, fast and secure open-source WWW browser. Falkon is licensed under GPL version 3 or (at your option) any later version. It is based on WebKit core and Qt Framework." +LangString PRODUCT_DESC ${LANG_GREEK} "Falkon is a new, fast and secure open-source WWW browser. Falkon is licensed under GPL version 3 or (at your option) any later version. It is based on WebKit core and Qt Framework." +LangString PRODUCT_DESC ${LANG_ITALIAN} "Falkon is a new, fast and secure open-source WWW browser. Falkon is licensed under GPL version 3 or (at your option) any later version. It is based on WebKit core and Qt Framework." +LangString PRODUCT_DESC ${LANG_ROMANIAN} "Falkon is a new, fast and secure open-source WWW browser. Falkon is licensed under GPL version 3 or (at your option) any later version. It is based on WebKit core and Qt Framework." +LangString PRODUCT_DESC ${LANG_INDONESIAN} "Falkon is a new, fast and secure open-source WWW browser. Falkon is licensed under GPL version 3 or (at your option) any later version. It is based on WebKit core and Qt Framework." +LangString PRODUCT_DESC ${LANG_GEORGIAN} "Falkon is a new, fast and secure open-source WWW browser. Falkon is licensed under GPL version 3 or (at your option) any later version. It is based on WebKit core and Qt Framework." +LangString PRODUCT_DESC ${LANG_SWEDISH} "Falkon is a new, fast and secure open-source WWW browser. Falkon is licensed under GPL version 3 or (at your option) any later version. It is based on WebKit core and Qt Framework." +LangString PRODUCT_DESC ${LANG_UKRAINIAN} "Falkon is a new, fast and secure open-source WWW browser. Falkon is licensed under GPL version 3 or (at your option) any later version. It is based on WebKit core and Qt Framework." + +LangString TITLE_SecSetASDefault ${LANG_DUTCH} "Default Browser" +LangString TITLE_SecSetASDefault ${LANG_GREEK} "Default Browser" +LangString TITLE_SecSetASDefault ${LANG_ITALIAN} "Default Browser" +LangString TITLE_SecSetASDefault ${LANG_ROMANIAN} "Default Browser" +LangString TITLE_SecSetASDefault ${LANG_INDONESIAN} "Default Browser" +LangString TITLE_SecSetASDefault ${LANG_GEORGIAN} "Default Browser" +LangString TITLE_SecSetASDefault ${LANG_SWEDISH} "Default Browser" +LangString TITLE_SecSetASDefault ${LANG_UKRAINIAN} "Default Browser" + +LangString TITLE_SecProtocols ${LANG_DUTCH} "Protocol Associations" +LangString TITLE_SecProtocols ${LANG_GREEK} "Protocol Associations" +LangString TITLE_SecProtocols ${LANG_ITALIAN} "Protocol Associations" +LangString TITLE_SecProtocols ${LANG_ROMANIAN} "Protocol Associations" +LangString TITLE_SecProtocols ${LANG_INDONESIAN} "Protocol Associations" +LangString TITLE_SecProtocols ${LANG_GEORGIAN} "Protocol Associations" +LangString TITLE_SecProtocols ${LANG_SWEDISH} "Protocol Associations" +LangString TITLE_SecProtocols ${LANG_UKRAINIAN} "Protocol Associations" + +LangString DESC_SecSetASDefault ${LANG_DUTCH} "Set Falkon as default internet browser" +LangString DESC_SecSetASDefault ${LANG_GREEK} "Set Falkon as default internet browser" +LangString DESC_SecSetASDefault ${LANG_ITALIAN} "Set Falkon as default internet browser" +LangString DESC_SecSetASDefault ${LANG_ROMANIAN} "Set Falkon as default internet browser" +LangString DESC_SecSetASDefault ${LANG_INDONESIAN} "Set Falkon as default internet browser" +LangString DESC_SecSetASDefault ${LANG_GEORGIAN} "Set Falkon as default internet browser" +LangString DESC_SecSetASDefault ${LANG_SWEDISH} "Set Falkon as default internet browser" +LangString DESC_SecSetASDefault ${LANG_UKRAINIAN} "Set Falkon as default internet browser" + +LangString DESC_SecProtocols ${LANG_DUTCH} "Associate Falkon with http(s) and ftp protocols" +LangString DESC_SecProtocols ${LANG_GREEK} "Associate Falkon with http(s) and ftp protocols" +LangString DESC_SecProtocols ${LANG_ITALIAN} "Associate Falkon with http(s) and ftp protocols" +LangString DESC_SecProtocols ${LANG_ROMANIAN} "Associate Falkon with http(s) and ftp protocols" +LangString DESC_SecProtocols ${LANG_INDONESIAN} "Associate Falkon with http(s) and ftp protocols" +LangString DESC_SecProtocols ${LANG_GEORGIAN} "Associate Falkon with http(s) and ftp protocols" +LangString DESC_SecProtocols ${LANG_SWEDISH} "Associate Falkon with http(s) and ftp protocols" +LangString DESC_SecProtocols ${LANG_UKRAINIAN} "Associate Falkon with http(s) and ftp protocols" + +LangString MSG_RunningInstance ${LANG_DUTCH} "Falkon is already running! Do you want the installer try to terminate it?" +LangString MSG_RunningInstance ${LANG_GREEK} "Falkon is already running! Do you want the installer try to terminate it?" +LangString MSG_RunningInstance ${LANG_ITALIAN} "Falkon is already running! Do you want the installer try to terminate it?" +LangString MSG_RunningInstance ${LANG_ROMANIAN} "Falkon is already running! Do you want the installer try to terminate it?" +LangString MSG_RunningInstance ${LANG_INDONESIAN} "Falkon is already running! Do you want the installer try to terminate it?" +LangString MSG_RunningInstance ${LANG_GEORGIAN} "Falkon is already running! Do you want the installer try to terminate it?" +LangString MSG_RunningInstance ${LANG_SWEDISH} "Falkon is already running! Do you want the installer try to terminate it?" +LangString MSG_RunningInstance ${LANG_UKRAINIAN} "Falkon is already running! Do you want the installer try to terminate it?" + +LangString MSG_InstallationCanceled ${LANG_DUTCH} "Process cancelled by user." +LangString MSG_InstallationCanceled ${LANG_GREEK} "Process cancelled by user." +LangString MSG_InstallationCanceled ${LANG_ITALIAN} "Process cancelled by user." +LangString MSG_InstallationCanceled ${LANG_ROMANIAN} "Process cancelled by user." +LangString MSG_InstallationCanceled ${LANG_INDONESIAN} "Process cancelled by user." +LangString MSG_InstallationCanceled ${LANG_GEORGIAN} "Process cancelled by user." +LangString MSG_InstallationCanceled ${LANG_SWEDISH} "Process cancelled by user." +LangString MSG_InstallationCanceled ${LANG_UKRAINIAN} "Process cancelled by user."