-# Copyright © 2022 Soren Stoutner <soren@stoutner.com>.
+# Copyright 2022 Soren Stoutner <soren@stoutner.com>.
#
# This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
#
DBusAddons
DocTools
I18n
+ Notifications
KIO
XmlGui
)
-# Copyright © 2022 Soren Stoutner <soren@stoutner.com>.
+# Copyright 2022 Soren Stoutner <soren@stoutner.com>.
#
# This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
#
KF5::DBusAddons
KF5::DocTools
KF5::I18n
+ KF5::Notifications
KF5::KIOCore
KF5::KIOWidgets
KF5::XmlGui
# Install Privacy Browser's metadata file.
install(FILES com.stoutner.privacybrowser.appdata.xml DESTINATION ${KDE_INSTALL_METAINFODIR})
+# Install Privacy Browser's notifyrc file.
+install(FILES privacybrowser.notifyrc DESTINATION ${KDE_INSTALL_KNOTIFYRCDIR})
+
# Install Privacy Browser's icon.
ecm_install_icons(ICONS icons/sc-apps-privacy-browser.svg DESTINATION ${KDE_INSTALL_ICONDIR})
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright © 2022 Soren Stoutner <soren@stoutner.com>.
+ Copyright 2022 Soren Stoutner <soren@stoutner.com>.
- This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-android>.
+ This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3
-# Copyright © 2022 Soren Stoutner <soren@stoutner.com>.
+# Copyright 2022 Soren Stoutner <soren@stoutner.com>.
#
# This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
#
#include "Settings.h"
#include "ui_DomainSettingsDialog.h"
#include "databases/DomainsDatabase.h"
-#include "helpers/UserAgentHelper.h"
// Qt toolkit headers.
#include <QInputDialog>
setWindowTitle(i18nc("The domain settings dialog window title", "Domain Settings"));
// Set the window modality.
- setWindowModality(Qt::WindowModality::ApplicationModal);;
+ setWindowModality(Qt::WindowModality::ApplicationModal);
+
+ // Instantiate the user agent helper.
+ userAgentHelperPointer = new UserAgentHelper();
// Instantiate the domain settings dialog UI.
Ui::DomainSettingsDialog domainSettingsDialogUi;
void DomainSettingsDialog::populateUserAgentLabel(const QString &userAgentName) const
{
// Populate the label according to the type.
- if (userAgentName == UserAgentHelper::SYSTEM_DEFAULT_TRANSLATED)
+ if (userAgentName == userAgentHelperPointer->SYSTEM_DEFAULT_TRANSLATED)
{
// Display the system default user agent name.
- userAgentLabelPointer->setText(UserAgentHelper::getTranslatedUserAgentNameFromDatabaseName(Settings::userAgent()));
+ userAgentLabelPointer->setText(userAgentHelperPointer->getTranslatedUserAgentNameFromDatabaseName(Settings::userAgent()));
// Reset the palette.
userAgentWidgetPointer->setPalette(defaultPalette);
{
// Update the domains table model.
domainsTableModelPointer->setData(domainsSelectionModelPointer->currentIndex().siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::USER_AGENT)),
- UserAgentHelper::getDatabaseUserAgentNameFromTranslatedName(updatedUserAgent));
+ userAgentHelperPointer->getDatabaseUserAgentNameFromTranslatedName(updatedUserAgent));
// Populate the user agent label.
populateUserAgentLabel(updatedUserAgent);
#ifndef DOMAINSETTINGSDIALOG_H
#define DOMAINSETTINGSDIALOG_H
+// Application headers.
+#include "helpers/UserAgentHelper.h"
+
// KDE Frameworks headers.
#include <KLineEdit>
QPushButton *resetButtonPointer;
QWidget *userAgentWidgetPointer;
QComboBox *userAgentComboBoxPointer;
+ UserAgentHelper *userAgentHelperPointer;
QLabel *userAgentLabelPointer;
QWidget *zoomFactorWidgetPointer;
QComboBox *zoomFactorComboBoxPointer;
QPushButton *deleteAllCookiesButtonPointer;
QPushButton *deleteCookieButtonPointer;
QSqlTableModel *durableCookiesTableModelPointer;
- QItemSelectionModel *tableSelectionModelPointer;
QPushButton *resetButtonPointer;
+ QItemSelectionModel *tableSelectionModelPointer;
};
#endif
/*
- * Copyright © 2022 Soren Stoutner <soren@stoutner.com>.
+ * Copyright 2022 Soren Stoutner <soren@stoutner.com>.
*
* This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
*
#include <QShortcut>
#include <QStandardPaths>
-SaveDialog::SaveDialog(QWebEngineDownloadItem *downloadItemPointer)
+SaveDialog::SaveDialog(QUrl &url, QString &mimeTypeString, int totalBytes, QString fileName, bool nativeDownloader): downloadUrl(url), suggestedFileName(fileName)
{
// Set the dialog window title.
setWindowTitle(i18nc("The save dialog window title", "Save"));
QDialogButtonBox *dialogButtonBoxPointer = saveDialogUi.dialogButtonBox;
QPushButton *saveButtonPointer = dialogButtonBoxPointer->button(QDialogButtonBox::Save);
- // Get the URL and the suggested file name.
- downloadUrl = downloadItemPointer->url();
- suggestedFileName = downloadItemPointer->suggestedFileName();
- QString mimeTypeString = downloadItemPointer->mimeType();
-
// Get a MIME type database.
QMimeDatabase mimeDatabase;
mimeTypeLabelPointer->setText("<b>" + mimeTypeString + "</b>");
// Populate the download size label.
- if (downloadItemPointer->totalBytes() == -1) // The file size is unknown.
+ if (totalBytes == -1) // The file size is unknown.
sizeLabelPointer->setText(i18nc("Unknown download file size. The bold style should be preserved.", "<b>unknown</b>"));
else // The file size is known. Format it according to the locale.
- sizeLabelPointer->setText(ki18nc("Download file size. The bold style should be preserved.", "<b>%1 bytes</b>").subs(downloadItemPointer->totalBytes()).toString());
-
- // Connect the buttons.
- connect(saveButtonPointer, SIGNAL(clicked()), this, SLOT(showFileDialog()));
- connect(dialogButtonBoxPointer, SIGNAL(rejected()), this, SLOT(reject()));
+ sizeLabelPointer->setText(ki18nc("Download file size. The bold style should be preserved.", "<b>%1 bytes</b>").subs(totalBytes).toString());
// Create the keyboard shortcuts.
QShortcut *sShortcutPointer = new QShortcut(QKeySequence(i18nc("The save key shortcut.", "s")), this);
QShortcut *cShortcutPointer = new QShortcut(QKeySequence(i18nc("The close key shortcut.", "c")), this);
- // Connect the shortcuts.
- connect(sShortcutPointer, SIGNAL(activated()), this, SLOT(showFileDialog()));
+ // Connect the save buttons.
+ if (nativeDownloader)
+ {
+ // Show the file picker for the native download.
+ connect(saveButtonPointer, SIGNAL(clicked()), this, SLOT(showFilePicker()));
+ connect(sShortcutPointer, SIGNAL(activated()), this, SLOT(showFilePicker()));
+ }
+ else
+ {
+ // Use WebEngine's downloader
+ connect(saveButtonPointer, SIGNAL(clicked()), this, SLOT(accept()));
+ connect(sShortcutPointer, SIGNAL(activated()), this, SLOT(accept()));
+ }
+
+ // Connect the cancel button.
+ connect(dialogButtonBoxPointer, SIGNAL(rejected()), this, SLOT(reject()));
connect(cShortcutPointer, SIGNAL(activated()), this, SLOT(reject()));
}
-void SaveDialog::showFileDialog()
+void SaveDialog::showFilePicker()
{
// Show the file picker dialog.
- emit showSaveFilePickerDialog(downloadUrl, suggestedFileName);
+ emit useNativeDownloader(downloadUrl, suggestedFileName);
// Close the dialog.
reject();
}
+
/*
- * Copyright © 2022 Soren Stoutner <soren@stoutner.com>.
+ * Copyright 2022 Soren Stoutner <soren@stoutner.com>.
*
* This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
*
public:
// The primary constructor.
- explicit SaveDialog(QWebEngineDownloadItem *downloadItemPointer);
+ explicit SaveDialog(QUrl &url, QString &mimeTypeString, int totalBytes, QString fileName = QString(), bool nativeDownloader = false);
signals:
// The signals.
- void showSaveFilePickerDialog(QUrl &downloadUrl, QString &suggestedFileName);
+ void useNativeDownloader(QUrl &downloadUrl, QString &suggestedFileName);
private Q_SLOTS:
// The private slots.
- void showFileDialog();
+ void showFilePicker();
private:
// The private variables.
/*
- * Copyright © 2022 Soren Stoutner <soren@stoutner.com>.
+ * Copyright 2022 Soren Stoutner <soren@stoutner.com>.
*
* This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
*
#include <KLocalizedString>
// Define the public database constants.
-const QString UserAgentHelper::SYSTEM_DEFAULT_DATABASE = QStringLiteral("System Default");
-const QString UserAgentHelper::PRIVACY_BROWSER_DATABASE = QStringLiteral("Privacy Browser");
-const QString UserAgentHelper::WEB_ENGINE_DEFAULT_DATABASE = QStringLiteral("WebEngine Default");
-const QString UserAgentHelper::FIREFOX_LINUX_DATABASE = QStringLiteral("Firefox Linux");
-const QString UserAgentHelper::CHROMIUM_LINUX_DATABASE = QStringLiteral("Chromium Linux");
-const QString UserAgentHelper::FIREFOX_WINDOWS_DATABASE = QStringLiteral("Firefox Windows");
-const QString UserAgentHelper::CHROME_WINDOWS_DATABASE = QStringLiteral("Chrome Windows");
-const QString UserAgentHelper::EDGE_WINDOWS_DATABASE = QStringLiteral("Edge Windows");
-const QString UserAgentHelper::SAFARI_MACOS_DATABASE = QStringLiteral("Safari macOS");
-
-// Define the public translated constants.
-const QString UserAgentHelper::SYSTEM_DEFAULT_TRANSLATED = i18n("System default");
-const QString UserAgentHelper::PRIVACY_BROWSER_TRANSLATED = i18n("Privacy Browser");
-const QString UserAgentHelper::WEB_ENGINE_DEFAULT_TRANSLATED = i18n("WebEngine default");
-const QString UserAgentHelper::FIREFOX_LINUX_TRANSLATED = i18n("Firefox on Linux");
-const QString UserAgentHelper::CHROMIUM_LINUX_TRANSLATED = i18n("Chromium on Linux");
-const QString UserAgentHelper::FIREFOX_WINDOWS_TRANSLATED = i18n("Firefox on Windows");
-const QString UserAgentHelper::CHROME_WINDOWS_TRANSLATED = i18n("Chrome on Windows");
-const QString UserAgentHelper::EDGE_WINDOWS_TRANSLATED = i18n("Edge on Windows");
-const QString UserAgentHelper::SAFARI_MACOS_TRANSLATED = i18n("Safari on macOS");
+const QString UserAgentHelper::SYSTEM_DEFAULT_DATABASE = QLatin1String("System Default");
+const QString UserAgentHelper::PRIVACY_BROWSER_DATABASE = QLatin1String("Privacy Browser");
+const QString UserAgentHelper::WEB_ENGINE_DEFAULT_DATABASE = QLatin1String("WebEngine Default");
+const QString UserAgentHelper::FIREFOX_LINUX_DATABASE = QLatin1String("Firefox Linux");
+const QString UserAgentHelper::CHROMIUM_LINUX_DATABASE = QLatin1String("Chromium Linux");
+const QString UserAgentHelper::FIREFOX_WINDOWS_DATABASE = QLatin1String("Firefox Windows");
+const QString UserAgentHelper::CHROME_WINDOWS_DATABASE = QLatin1String("Chrome Windows");
+const QString UserAgentHelper::EDGE_WINDOWS_DATABASE = QLatin1String("Edge Windows");
+const QString UserAgentHelper::SAFARI_MACOS_DATABASE = QLatin1String("Safari macOS");
// Define the public user agent constants.
-const QString UserAgentHelper::PRIVACY_BROWSER_USER_AGENT = QStringLiteral("PrivacyBrowser/1.0");
-const QString UserAgentHelper::FIREFOX_LINUX_USER_AGENT = QStringLiteral("Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0");
-const QString UserAgentHelper::CHROMIUM_LINUX_USER_AGENT = QStringLiteral("Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36");
-const QString UserAgentHelper::FIREFOX_WINDOWS_USER_AGENT = QStringLiteral("Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:108.0) Gecko/20100101 Firefox/108.0");
-const QString UserAgentHelper::CHROME_WINDOWS_USER_AGENT = QStringLiteral("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36");
-const QString UserAgentHelper::EDGE_WINDOWS_USER_AGENT = QStringLiteral("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 Edg/108.0.1462.54");
-const QString UserAgentHelper::SAFARI_MACOS_USER_AGENT = QStringLiteral("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Safari/605.1.15");
+const QString UserAgentHelper::PRIVACY_BROWSER_USER_AGENT = QLatin1String("PrivacyBrowser/1.0");
+const QString UserAgentHelper::FIREFOX_LINUX_USER_AGENT = QLatin1String("Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0");
+const QString UserAgentHelper::CHROMIUM_LINUX_USER_AGENT = QLatin1String("Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36");
+const QString UserAgentHelper::FIREFOX_WINDOWS_USER_AGENT = QLatin1String("Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:108.0) Gecko/20100101 Firefox/108.0");
+const QString UserAgentHelper::CHROME_WINDOWS_USER_AGENT = QLatin1String("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36");
+const QString UserAgentHelper::EDGE_WINDOWS_USER_AGENT = QLatin1String("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 Edg/108.0.1462.54");
+const QString UserAgentHelper::SAFARI_MACOS_USER_AGENT = QLatin1String("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Safari/605.1.15");
// Construct the class.
-UserAgentHelper::UserAgentHelper() {};
+UserAgentHelper::UserAgentHelper() {
+ // Populate the translated user agents. Translated entries cannot be public static const.
+ SYSTEM_DEFAULT_TRANSLATED = i18nc("User agents", "System default");
+ PRIVACY_BROWSER_TRANSLATED = i18nc("User agents", "Privacy Browser");
+ WEB_ENGINE_DEFAULT_TRANSLATED = i18nc("User agents", "WebEngine default");
+ FIREFOX_LINUX_TRANSLATED = i18nc("User agents", "Firefox on Linux");
+ CHROMIUM_LINUX_TRANSLATED = i18nc("User agents", "Chromium on Linux");
+ FIREFOX_WINDOWS_TRANSLATED = i18nc("User agents", "Firefox on Windows");
+ CHROME_WINDOWS_TRANSLATED = i18nc("User agents", "Chrome on Windows");
+ EDGE_WINDOWS_TRANSLATED = i18nc("User agents", "Edge on Windows");
+ SAFARI_MACOS_TRANSLATED = i18nc("User agents", "Safari on macOS");
+};
QString UserAgentHelper::getDatabaseUserAgentNameFromTranslatedName(const QString &translatedUserAgentName)
{
// The default constructor.
UserAgentHelper();
+ // The destructor.
+ ~UserAgentHelper();
+
// The public static constants.
static const QString CHROMIUM_LINUX_DATABASE;
- static const QString CHROMIUM_LINUX_TRANSLATED;
static const QString CHROMIUM_LINUX_USER_AGENT;
static const QString CHROME_WINDOWS_DATABASE;
- static const QString CHROME_WINDOWS_TRANSLATED;
static const QString CHROME_WINDOWS_USER_AGENT;
static const QString EDGE_WINDOWS_DATABASE;
- static const QString EDGE_WINDOWS_TRANSLATED;
static const QString EDGE_WINDOWS_USER_AGENT;
static const QString FIREFOX_LINUX_DATABASE;
- static const QString FIREFOX_LINUX_TRANSLATED;
static const QString FIREFOX_LINUX_USER_AGENT;
static const QString FIREFOX_WINDOWS_DATABASE;
- static const QString FIREFOX_WINDOWS_TRANSLATED;
static const QString FIREFOX_WINDOWS_USER_AGENT;
static const QString PRIVACY_BROWSER_DATABASE;
- static const QString PRIVACY_BROWSER_TRANSLATED;
static const QString PRIVACY_BROWSER_USER_AGENT;
static const QString SAFARI_MACOS_DATABASE;
- static const QString SAFARI_MACOS_TRANSLATED;
static const QString SAFARI_MACOS_USER_AGENT;
static const QString SYSTEM_DEFAULT_DATABASE;
- static const QString SYSTEM_DEFAULT_TRANSLATED;
static const QString WEB_ENGINE_DEFAULT_DATABASE;
- static const QString WEB_ENGINE_DEFAULT_TRANSLATED;
// The public static functions.
- static QString getDatabaseUserAgentNameFromTranslatedName(const QString &translatedUserAgentName);
static int getDomainSettingsUserAgentIndex(const QString &userAgentName);
static QString getUserAgentFromDatabaseName(const QString &userAgentDatabaseName);
- static QString getUserAgentFromTranslatedName(const QString &userAgentTranslatedName);
static QString getResultingDomainSettingsUserAgent(const QString &rawUserAgent);
- static QString getTranslatedUserAgentNameFromDatabaseName(const QString &userAgentName);
+
+ // The public variables.
+ QString SYSTEM_DEFAULT_TRANSLATED;
+ QString PRIVACY_BROWSER_TRANSLATED;
+ QString WEB_ENGINE_DEFAULT_TRANSLATED;
+ QString FIREFOX_LINUX_TRANSLATED;
+ QString CHROMIUM_LINUX_TRANSLATED;
+ QString FIREFOX_WINDOWS_TRANSLATED;
+ QString CHROME_WINDOWS_TRANSLATED;
+ QString EDGE_WINDOWS_TRANSLATED;
+ QString SAFARI_MACOS_TRANSLATED;
+
+ // The public functions.
+ QString getDatabaseUserAgentNameFromTranslatedName(const QString &translatedUserAgentName);
+ QString getUserAgentFromTranslatedName(const QString &userAgentTranslatedName);
+ QString getTranslatedUserAgentNameFromDatabaseName(const QString &userAgentName);
};
#endif
This file is derived from `security` and `language`, which are part of the Android Material icon set. They are released under the Apache License 2.0. <https://fonts.google.com/icons>
- This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-android>.
+ This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
Privacy Browser PC is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
This file is derived from `security` and `language`, which are part of the Android Material icon set. They are released under the Apache License 2.0. <https://fonts.google.com/icons>
- This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-android>.
+ This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
Privacy Browser PC is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
This file is derived from `security` and `language`, which are part of the Android Material icon set. They are released under the Apache License 2.0. <https://fonts.google.com/icons>
- This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-android>.
+ This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
Privacy Browser PC is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
--- /dev/null
+# Copyright 2022 Soren Stoutner <soren@stoutner.com>.
+#
+# This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
+#
+# Privacy Browser PC is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Privacy Browser PC is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Privacy Browser PC. If not, see <http://www.gnu.org/licenses/>.
+
+[Global]
+IconName=sc-apps-privacy-browser
+Name=Privacy Browser
+Comment=A browser that respects your privacy.
+DesktopEntry=com.stoutner.privacybrowser.desktop
+
+[Event/FileDownload]
+Name=File Download
+Comment=The file has started downloading
+Action=Popup
<!--
Copyright © 2022 Soren Stoutner <soren@stoutner.com>.
- This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-android>.
+ This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
Privacy Browser PC is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
<!--
Copyright © 2022 Soren Stoutner <soren@stoutner.com>.
- This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-android>.
+ This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
Privacy Browser PC is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
-# Copyright © 2022 Soren Stoutner <soren@stoutner.com>.
+# Copyright 2022 Soren Stoutner <soren@stoutner.com>.
#
# This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
#
# Install Privacy Browser's RC (Runtime Configuration) files.
install(FILES
- browser_window_ui.rc
+ browserwindowui.rc
DESTINATION ${KDE_INSTALL_KXMLGUI5DIR}/privacybrowser)
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!--
- Copyright © 2022 Soren Stoutner <soren@stoutner.com>.
-
- This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-android>.
-
- Privacy Browser PC is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Privacy Browser PC is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Privacy Browser PC. If not, see <http://www.gnu.org/licenses/>. -->
-
-<!-- Documentation at <https://techbase.kde.org/Development/Architecture/KDE4/XMLGUI_Technology>. -->
-<!-- Better documentation at <https://invent.kde.org/frameworks/kxmlgui/-/blob/master/src/kxmlgui.xsd>. -->
-<!-- This file interacts with the default template located at /etc/xdg/ui/ui_standards.rc, which is part of the libkf5xmlgui-data package. -->
-<gui
- name="privacybrowser"
- version="1"
- xmlns="http://www.kde.org/standards/kxmlgui/1.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://www.kde.org/standards/kxmlgui/1.0 http://www.kde.org/standards/kxmlgui/1.0/kxmlgui.xsd" >
-
- <!-- The menu bar. -->
- <MenuBar>
- <!-- On-the-fly Settings. -->
- <Menu name="on_the_fly_settings"> <text>On-The-Fly Settings</text>
- <Menu name="user_agent" icon="user-group-properties">
- <Action name="user_agent_privacy_browser" />
- <Action name="user_agent_webengine_default" />
- <Action name="user_agent_firefox_linux" />
- <Action name="user_agent_chromium_linux" />
- <Action name="user_agent_firefox_windows" />
- <Action name="user_agent_chrome_windows" />
- <Action name="user_agent_edge_windows" />
- <Action name="user_agent_safari_macos" />
- <Action name="user_agent_custom" />
- </Menu>
-
- <Action name="zoom_factor" />
-
- <Separator />
-
- <Menu name="search_engine" icon="search">
- <Action name="search_engine_mojeek" />
- <Action name="search_engine_monocles" />
- <Action name="search_engine_metager" />
- <Action name="search_engine_google" />
- <Action name="search_engine_bing" />
- <Action name="search_engine_yahoo" />
- <Action name="search_engine_custom" />
- </Menu>
- </Menu>
-
- <!-- Settings. -->
- <Menu name="settings">
- <Action name="domain_settings" />
- <Action name="cookies" />
- </Menu>
- </MenuBar>
-
- <!-- The main toolbar is removed. -->
- <ToolBar name="mainToolBar" deleted="true" />
-
- <!-- The navigation toolbar. -->
- <ToolBar name="navigation_toolbar" iconText="icononly"> <text>Navigation Toolbar</text>
- <Action name="go_back" />
- <Action name="go_forward" />
- <Action name="view_redisplay" />
- <Action name="go_home" />
- </ToolBar>
-
- <!-- The URL toolbar. -->
- <ToolBar name="url_toolbar" iconText="icononly"> <text>URL Toolbar</text>
- <Action name="javascript" />
- <Action name="local_storage" />
- <Action name="dom_storage" />
- <Action name="edit_find_next" />
- <Action name="edit_find_prev" />
- <Action name="find_case_sensitive" />
- </ToolBar>
-</gui>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ Copyright 2022 Soren Stoutner <soren@stoutner.com>.
+
+ This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
+
+ Privacy Browser PC is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Privacy Browser PC is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Privacy Browser PC. If not, see <http://www.gnu.org/licenses/>. -->
+
+<!-- Documentation at <https://techbase.kde.org/Development/Architecture/KDE4/XMLGUI_Technology>. -->
+<!-- Better documentation at <https://invent.kde.org/frameworks/kxmlgui/-/blob/master/src/kxmlgui.xsd>. -->
+<!-- This file interacts with the default template located at /etc/xdg/ui/ui_standards.rc, which is part of the libkf5xmlgui-data package. -->
+<gui
+ name="privacybrowser"
+ version="1"
+ xmlns="http://www.kde.org/standards/kxmlgui/1.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.kde.org/standards/kxmlgui/1.0 http://www.kde.org/standards/kxmlgui/1.0/kxmlgui.xsd" >
+
+ <!-- The menu bar. -->
+ <MenuBar>
+ <!-- On-the-fly Settings. -->
+ <Menu name="on_the_fly_settings"> <text>On-The-Fly Settings</text>
+ <Menu name="user_agent" icon="user-group-properties">
+ <Action name="user_agent_privacy_browser" />
+ <Action name="user_agent_webengine_default" />
+ <Action name="user_agent_firefox_linux" />
+ <Action name="user_agent_chromium_linux" />
+ <Action name="user_agent_firefox_windows" />
+ <Action name="user_agent_chrome_windows" />
+ <Action name="user_agent_edge_windows" />
+ <Action name="user_agent_safari_macos" />
+ <Action name="user_agent_custom" />
+ </Menu>
+
+ <Action name="zoom_factor" />
+
+ <Separator />
+
+ <Menu name="search_engine" icon="search">
+ <Action name="search_engine_mojeek" />
+ <Action name="search_engine_monocles" />
+ <Action name="search_engine_metager" />
+ <Action name="search_engine_google" />
+ <Action name="search_engine_bing" />
+ <Action name="search_engine_yahoo" />
+ <Action name="search_engine_custom" />
+ </Menu>
+ </Menu>
+
+ <!-- Settings. -->
+ <Menu name="settings">
+ <Action name="domain_settings" />
+ <Action name="cookies" />
+ </Menu>
+ </MenuBar>
+
+ <!-- The main toolbar is removed. -->
+ <ToolBar name="mainToolBar" deleted="true" />
+
+ <!-- The navigation toolbar. -->
+ <ToolBar name="navigation_toolbar" iconText="icononly"> <text>Navigation Toolbar</text>
+ <Action name="go_back" />
+ <Action name="go_forward" />
+ <Action name="view_redisplay" />
+ <Action name="go_home" />
+ </ToolBar>
+
+ <!-- The URL toolbar. -->
+ <ToolBar name="url_toolbar" iconText="icononly"> <text>URL Toolbar</text>
+ <Action name="javascript" />
+ <Action name="local_storage" />
+ <Action name="dom_storage" />
+ <Action name="edit_find_next" />
+ <Action name="edit_find_prev" />
+ <Action name="find_case_sensitive" />
+ </ToolBar>
+</gui>
<!--
Copyright © 2022 Soren Stoutner <soren@stoutner.com>.
- This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-android>.
+ This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
Privacy Browser PC is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
<?xml version="1.0" encoding="UTF-8"?>
<!--
- Copyright © 2022 Soren Stoutner <soren@stoutner.com>.
+ Copyright 2022 Soren Stoutner <soren@stoutner.com>.
- This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-android>.
+ This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
Privacy Browser PC is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
<?xml version="1.0" encoding="UTF-8"?>
<!--
- Copyright © 2022 Soren Stoutner <soren@stoutner.com>.
+ Copyright 2022 Soren Stoutner <soren@stoutner.com>.
- This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-android>.
+ This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
Privacy Browser PC is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
<?xml version="1.0" encoding="UTF-8"?>
<!--
- Copyright © 2022 Soren Stoutner <soren@stoutner.com>.
+ Copyright 2022 Soren Stoutner <soren@stoutner.com>.
- This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-android>.
+ This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
Privacy Browser PC is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
<!--
Copyright © 2022 Soren Stoutner <soren@stoutner.com>.
- This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-android>.
+ This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
Privacy Browser PC is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
<!--
Copyright © 2022 Soren Stoutner <soren@stoutner.com>.
- This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-android>.
+ This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
Privacy Browser PC is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
<!--
Copyright © 2022 Soren Stoutner <soren@stoutner.com>.
- This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-android>.
+ This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
Privacy Browser PC is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
<!--
Copyright © 2022 Soren Stoutner <soren@stoutner.com>.
- This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-android>.
+ This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
Privacy Browser PC is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
<!--
Copyright © 2022 Soren Stoutner <soren@stoutner.com>.
- This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-android>.
+ This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
Privacy Browser PC is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
/*
- * Copyright © 2022 Soren Stoutner <soren@stoutner.com>.
+ * Copyright 2022 Soren Stoutner <soren@stoutner.com>.
*
* This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
*
#include "dialogs/SaveDialog.h"
#include "filters/MouseEventFilter.h"
#include "helpers/SearchEngineHelper.h"
-#include "helpers/UserAgentHelper.h"
#include "interceptors/UrlRequestInterceptor.h"
#include "windows/BrowserWindow.h"
// KDE Framework headers.
#include <KIO/FileCopyJob>
#include <KIO/JobUiDelegate>
+#include <KNotification>
// Qt toolkit headers.
#include <QAction>
#include <QPrinter>
// Initialize the public static variables.
-QString TabWidget::webEngineDefaultUserAgent = QStringLiteral("");
+QString TabWidget::webEngineDefaultUserAgent = QLatin1String("");
// Construct the class.
TabWidget::TabWidget(QWidget *parent) : QWidget(parent)
{
+ // Instantiate the user agent helper.
+ userAgentHelperPointer = new UserAgentHelper();
+
// Instantiate the UIs.
Ui::TabWidget tabWidgetUi;
Ui::AddTabWidget addTabWidgetUi;
QUrl url;
// Check to see if the domain does not start with a `.` because Qt makes this harder than it should be. <https://doc.qt.io/qt-5/qwebenginecookiestore.html#setCookie>
- if (!cookie.domain().startsWith(QStringLiteral(".")))
+ if (!cookie.domain().startsWith(QLatin1String(".")))
{
// Populate the URL.
url.setHost(cookie.domain());
- url.setScheme(QStringLiteral("https"));
+ url.setScheme(QLatin1String("https"));
// Clear the domain from the cookie.
- cookie.setDomain(QStringLiteral(""));
+ cookie.setDomain(QLatin1String(""));
}
// Add the cookie to the store.
tabWidgetPointer->setTabIcon(newTabIndex, defaultTabIcon);
// Create an off-the-record profile (the default when no profile name is specified).
- QWebEngineProfile *webEngineProfilePointer = new QWebEngineProfile(QStringLiteral(""));
+ QWebEngineProfile *webEngineProfilePointer = new QWebEngineProfile(QLatin1String(""));
// Create a WebEngine page.
QWebEnginePage *webEnginePagePointer = new QWebEnginePage(webEngineProfilePointer);
webEngineProfilePointer->setSpellCheckEnabled(true);
// Set the spell check language.
- webEngineProfilePointer->setSpellCheckLanguages({QStringLiteral("en_US")});
+ webEngineProfilePointer->setSpellCheckLanguages({QLatin1String("en_US")});
// Populate the zoom factor. This is necessary if a URL is being loaded, like a local URL, that does not trigger `applyDomainSettings()`.
privacyWebEngineViewPointer->setZoomFactor(Settings::zoomFactor());
// Set the DOM storage status.
switch (domainRecord.field(DomainsDatabase::DOM_STORAGE).value().toInt())
{
- // Set the default DOM storage status.
+ // Set the default DOM storage status. QWebEngineSettings confusingly calls this local storage.
case (DomainsDatabase::SYSTEM_DEFAULT):
{
currentWebEngineSettingsPointer->setAttribute(QWebEngineSettings::LocalStorageEnabled, Settings::domStorageEnabled());
break;
}
- // Disable DOM storage.
+ // Disable DOM storage. QWebEngineSettings confusingly calls this local storage.
case (DomainsDatabase::DISABLED):
{
currentWebEngineSettingsPointer->setAttribute(QWebEngineSettings::LocalStorageEnabled, false);
break;
}
- // Enable DOM storage.
+ // Enable DOM storage. QWebEngineSettings confusingly calls this local storage.
case (DomainsDatabase::ENABLED):
{
currentWebEngineSettingsPointer->setAttribute(QWebEngineSettings::LocalStorageEnabled, true);
else // The hostname does not have domain settings.
{
// Reset the domain settings name.
- currentPrivacyWebEngineViewPointer->domainSettingsName = QStringLiteral("");
+ currentPrivacyWebEngineViewPointer->domainSettingsName = QLatin1String("");
// Set the JavaScript status.
currentWebEngineSettingsPointer->setAttribute(QWebEngineSettings::JavascriptEnabled, Settings::javaScriptEnabled());
}
// Update the UI.
- emit updateDomainSettingsIndicator(currentPrivacyWebEngineViewPointer->domainSettingsName != QStringLiteral(""));
+ emit updateDomainSettingsIndicator(currentPrivacyWebEngineViewPointer->domainSettingsName != QLatin1String(""));
emit updateJavaScriptAction(currentWebEngineSettingsPointer->testAttribute(QWebEngineSettings::JavascriptEnabled));
emit updateLocalStorageAction(currentPrivacyWebEngineViewPointer->localStorageEnabled);
emit updateDomStorageAction(currentWebEngineSettingsPointer->testAttribute(QWebEngineSettings::LocalStorageEnabled));
userAgentName.remove('&');
// Apply the user agent.
- currentWebEngineProfilePointer->setHttpUserAgent(UserAgentHelper::getUserAgentFromTranslatedName(userAgentName));
+ currentWebEngineProfilePointer->setHttpUserAgent(userAgentHelperPointer->getUserAgentFromTranslatedName(userAgentName));
// Update the user agent actions.
emit updateUserAgentActions(currentWebEngineProfilePointer->httpUserAgent(), false);
tabWidgetPointer->tabBar()->setVisible(visible);
}
-void TabWidget::showSaveDialog(QWebEngineDownloadItem *downloadItemPointer) const
+void TabWidget::showSaveDialog(QWebEngineDownloadItem *webEngineDownloadItemPointer)
{
- // Instantiate the save dialog.
- SaveDialog *saveDialogPointer = new SaveDialog(downloadItemPointer);
+ // Get the download attributes.
+ QUrl downloadUrl = webEngineDownloadItemPointer->url();
+ QString mimeTypeString = webEngineDownloadItemPointer->mimeType();
+ QString suggestedFileName = webEngineDownloadItemPointer->suggestedFileName();
+ int totalBytes = webEngineDownloadItemPointer->totalBytes();
+
+ // Check to see if local storage (cookies) is enabled.
+ if (currentPrivacyWebEngineViewPointer->localStorageEnabled) // Local storage (cookies) is enabled. Use WebEngine's downloader.
+ {
+ // Instantiate the save dialog.
+ SaveDialog *saveDialogPointer = new SaveDialog(downloadUrl, mimeTypeString, totalBytes);
- // Connect the save button.
- connect(saveDialogPointer, SIGNAL(showSaveFilePickerDialog(QUrl &, QString &)), this, SLOT(showSaveFilePickerDialog(QUrl &, QString &)));
+ // Display the save dialog.
+ int saveDialogResult = saveDialogPointer->exec();
- // Show the dialog.
- saveDialogPointer->show();
-}
+ // Process the save dialog results.
+ if (saveDialogResult == QDialog::Accepted) // Save was selected.
+ {
+ // Get the download directory.
+ QString downloadDirectory = Settings::downloadLocation();
-void TabWidget::showSaveFilePickerDialog(QUrl &downloadUrl, QString &suggestedFileName)
-{
- // Get the download location.
- QString downloadDirectory = Settings::downloadLocation();
+ // Resolve the system download directory if specified.
+ if (downloadDirectory == QLatin1String("System Download Directory"))
+ downloadDirectory = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation);
- // Resolve the system download directory if specified.
- if (downloadDirectory == QStringLiteral("System Download Directory"))
- downloadDirectory = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation);
+ // Display a save file dialog.
+ QString saveFilePath = QFileDialog::getSaveFileName(this, i18nc("Save file dialog caption", "Save File"), downloadDirectory + QLatin1Char('/') + suggestedFileName);
- // Create a save file dialog.
- QFileDialog *saveFileDialogPointer = new QFileDialog(this, i18nc("Save file dialog caption", "Save File"), downloadDirectory);
+ // Process the save file path.
+ if (!saveFilePath.isEmpty()) // The file save path is populated.
+ {
+ // Create a save file path file info.
+ QFileInfo saveFilePathFileInfo = QFileInfo(saveFilePath);
- // Tell the dialog to use a save button.
- saveFileDialogPointer->setAcceptMode(QFileDialog::AcceptSave);
+ // Get the canonical save path and file name.
+ QString absoluteSavePath = saveFilePathFileInfo.absolutePath();
+ QString saveFileName = saveFilePathFileInfo.fileName();
- // Populate the file name from the download item pointer.
- saveFileDialogPointer->selectFile(suggestedFileName);
+ // Set the download directory and file name.
+ webEngineDownloadItemPointer->setDownloadDirectory(absoluteSavePath);
+ webEngineDownloadItemPointer->setDownloadFileName(saveFileName);
- // Prevent interaction with the parent window while the dialog is open.
- saveFileDialogPointer->setWindowModality(Qt::WindowModal);
+ // Create a file download notification.
+ KNotification *fileDownloadNotificationPointer = new KNotification(QLatin1String("FileDownload"));
- // Process the saving of the file. The save file dialog pointer must be captured directly instead of by reference or nasty crashes occur.
- auto saveFile = [saveFileDialogPointer, &downloadUrl] () {
- // Get the save location. The dialog box should only allow the selecting of one file location.
- QUrl saveLocation = saveFileDialogPointer->selectedUrls().value(0);
+ // Set the notification title.
+ fileDownloadNotificationPointer->setTitle(i18nc("Download notification title", "Download"));
- // Create a file copy job. `-1` creates the file with default permissions.
- KIO::FileCopyJob *fileCopyJobPointer = KIO::file_copy(downloadUrl, saveLocation, -1, KIO::Overwrite);
+ // Set the notification text.
+ fileDownloadNotificationPointer->setText(i18nc("Downloading notification text", "Downloading %1", saveFileName));
- // Set the download job to display any error messages.
- fileCopyJobPointer->uiDelegate()->setAutoErrorHandlingEnabled(true);
+ // Set the notification icon.
+ fileDownloadNotificationPointer->setIconName(QLatin1String("download"));
- // Start the download.
- fileCopyJobPointer->start();
- };
+ // Set the action list cancel button.
+ fileDownloadNotificationPointer->setActions(QStringList({i18nc("Download notification action","Cancel")}));
- // Handle clicks on the save button.
- connect(saveFileDialogPointer, &QDialog::accepted, this, saveFile);
+ // Set the notification to display indefinitely.
+ fileDownloadNotificationPointer->setFlags(KNotification::Persistent);
- // Show the dialog.
- saveFileDialogPointer->show();
+ // Prevent the notification from being autodeleted if it is closed. Otherwise, the updates to the notification below cause a crash.
+ fileDownloadNotificationPointer->setAutoDelete(false);
+
+ // Display the notification.
+ fileDownloadNotificationPointer->sendEvent();
+
+ // Handle clicks on the cancel button.
+ connect(fileDownloadNotificationPointer, &KNotification::action1Activated, [webEngineDownloadItemPointer, saveFileName] ()
+ {
+ // Cancel the download.
+ webEngineDownloadItemPointer->cancel();
+
+ // Create a file download notification.
+ KNotification *canceledDownloadNotificationPointer = new KNotification(QLatin1String("FileDownload"));
+
+ // Set the notification title.
+ canceledDownloadNotificationPointer->setTitle(i18nc("Download notification title", "Download"));
+
+ // Set the new text.
+ canceledDownloadNotificationPointer->setText(i18nc("Download canceled notification", "%1 download canceled", saveFileName));
+
+ // Set the notification icon.
+ canceledDownloadNotificationPointer->setIconName(QLatin1String("download"));
+
+ // Display the notification.
+ canceledDownloadNotificationPointer->sendEvent();
+ });
+
+ // Update the notification when the download progresses.
+ connect(webEngineDownloadItemPointer, &QWebEngineDownloadItem::downloadProgress, [fileDownloadNotificationPointer, saveFileName] (qint64 bytesReceived, qint64 totalBytes)
+ {
+ // Calculate the download percentage.
+ int downloadPercentage = 100 * bytesReceived / totalBytes;
+
+ // Set the new text. Total bytes will be 0 if the download size is unknown.
+ if (totalBytes > 0)
+ fileDownloadNotificationPointer->setText(i18nc("Download progress notification text", "%1\% of %2 downloaded (%3 of %4 bytes)", downloadPercentage, saveFileName,
+ bytesReceived, totalBytes));
+ else
+ fileDownloadNotificationPointer->setText(i18nc("Download progress notification text", "%1: %2 bytes downloaded", saveFileName, bytesReceived));
+
+ // Display the updated notification.
+ fileDownloadNotificationPointer->update();
+ });
+
+ // Update the notification when the download finishes. The save file name must be copied into the lambda or a crash occurs.
+ connect(webEngineDownloadItemPointer, &QWebEngineDownloadItem::finished, [fileDownloadNotificationPointer, saveFileName, saveFilePath] ()
+ {
+ // Set the new text.
+ fileDownloadNotificationPointer->setText(i18nc("Download finished notification text", "%1 download finished", saveFileName));
+
+ // Set the URL so the file options will be displayed.
+ fileDownloadNotificationPointer->setUrls(QList<QUrl> {QUrl(saveFilePath)});
+
+ // Remove the actions from the notification.
+ fileDownloadNotificationPointer->setActions(QStringList());
+
+ // Set the notification to disappear after a timeout.
+ fileDownloadNotificationPointer->setFlags(KNotification::CloseOnTimeout);
+
+ // Display the updated notification.
+ fileDownloadNotificationPointer->update();
+ });
+
+ // Start the download.
+ webEngineDownloadItemPointer->accept();
+ }
+ else // The file save path is not populated.
+ {
+ // Cancel the download.
+ webEngineDownloadItemPointer->cancel();
+ }
+ }
+ else // Cancel was selected.
+ {
+ // Cancel the download.
+ webEngineDownloadItemPointer->cancel();
+ }
+ }
+ else // Local storage (cookies) is disabled. Use KDE's native downloader.
+ // This must use the show command to launch a separate dialog which cancels WebEngine's automatic background download of the file to a temporary location.
+ {
+ // Instantiate the save dialog. `true` instructs it to use the native downloader
+ SaveDialog *saveDialogPointer = new SaveDialog(downloadUrl, mimeTypeString, totalBytes, suggestedFileName, true);
+
+ // Connect the save button.
+ connect(saveDialogPointer, SIGNAL(useNativeDownloader(QUrl &, QString &)), this, SLOT(useNativeDownloader(QUrl &, QString &)));
+
+ // Show the dialog.
+ saveDialogPointer->show();
+ }
}
void TabWidget::toggleDomStorage() const
wipingCurrentFindTextSelection = true;
// Wipe the previous search. Otherwise currently highlighted words will remain highlighted.
- findText(QStringLiteral(""));
+ findText(QLatin1String(""));
// Update the find text.
findText(text);
// Update the URL.
emit updateWindowTitle(currentPrivacyWebEngineViewPointer->title());
- emit updateDomainSettingsIndicator(currentPrivacyWebEngineViewPointer->domainSettingsName != QStringLiteral(""));
+ emit updateDomainSettingsIndicator(currentPrivacyWebEngineViewPointer->domainSettingsName != QLatin1String(""));
emit updateUrlLineEdit(currentPrivacyWebEngineViewPointer->url());
// Update the find text.
else
emit hideProgressBar();
}
+
+void TabWidget::useNativeDownloader(QUrl &downloadUrl, QString &suggestedFileName)
+{
+ // Get the download directory.
+ QString downloadDirectory = Settings::downloadLocation();
+
+ // Resolve the system download directory if specified.
+ if (downloadDirectory == QLatin1String("System Download Directory"))
+ downloadDirectory = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation);
+
+ // Create a save file dialog.
+ QFileDialog *saveFileDialogPointer = new QFileDialog(this, i18nc("Save file dialog caption", "Save File"), downloadDirectory);
+
+ // Tell the dialog to use a save button.
+ saveFileDialogPointer->setAcceptMode(QFileDialog::AcceptSave);
+
+ // Populate the file name from the download item pointer.
+ saveFileDialogPointer->selectFile(suggestedFileName);
+
+ // Prevent interaction with the parent window while the dialog is open.
+ saveFileDialogPointer->setWindowModality(Qt::WindowModal);
+
+ // Process the saving of the file. The save file dialog pointer must be captured directly instead of by reference or nasty crashes occur.
+ auto saveFile = [saveFileDialogPointer, downloadUrl] ()
+ {
+ // Get the save location. The dialog box should only allow the selecting of one file location.
+ QUrl saveLocation = saveFileDialogPointer->selectedUrls().value(0);
+
+ // Create a file copy job. `-1` creates the file with default permissions.
+ KIO::FileCopyJob *fileCopyJobPointer = KIO::file_copy(downloadUrl, saveLocation, -1, KIO::Overwrite);
+
+ // Set the download job to display any error messages.
+ fileCopyJobPointer->uiDelegate()->setAutoErrorHandlingEnabled(true);
+
+ // Start the download.
+ fileCopyJobPointer->start();
+ };
+
+ // Handle clicks on the save button.
+ connect(saveFileDialogPointer, &QDialog::accepted, this, saveFile);
+
+ // Show the dialog.
+ saveFileDialogPointer->show();
+}
/*
- * Copyright © 2022 Soren Stoutner <soren@stoutner.com>.
+ * Copyright 2022 Soren Stoutner <soren@stoutner.com>.
*
* This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
*
// Application headers.
#include "PrivacyWebEngineView.h"
+#include "helpers/UserAgentHelper.h"
// KDE Framework headers.
#include <KLineEdit>
void fullScreenRequested(QWebEngineFullScreenRequest fullScreenRequest) const;
void pageLinkHovered(const QString &linkUrl) const;
void printWebpage(QPrinter *printerPointer) const;
- void showSaveDialog(QWebEngineDownloadItem *downloadItemPointer) const;
- void showSaveFilePickerDialog(QUrl &downloadUrl, QString &suggestedFileName);
+ void showSaveDialog(QWebEngineDownloadItem *downloadItemPointer);
void updateUiWithTabSettings();
+ void useNativeDownloader(QUrl &downloadUrl, QString &suggestedFileName);
private:
// The private variables.
QIcon defaultTabIcon = QIcon::fromTheme(QStringLiteral("globe"));
QString searchEngineUrl;
QTabWidget *tabWidgetPointer;
+ UserAgentHelper *userAgentHelperPointer;
bool wipingCurrentFindTextSelection = false;
// The private functions.
searchEngineYahooActionPointer->setCheckable(true);
searchEngineCustomActionPointer->setCheckable(true);
+ // Instantiate the user agent helper.
+ UserAgentHelper *userAgentHelperPointer = new UserAgentHelper();
+
// Set the action text.
- userAgentPrivacyBrowserActionPointer->setText(UserAgentHelper::PRIVACY_BROWSER_TRANSLATED);
- userAgentWebEngineDefaultActionPointer->setText(UserAgentHelper::WEB_ENGINE_DEFAULT_TRANSLATED);
- userAgentFirefoxLinuxActionPointer->setText(UserAgentHelper::FIREFOX_LINUX_TRANSLATED);
- userAgentChromiumLinuxActionPointer->setText(UserAgentHelper::CHROMIUM_LINUX_TRANSLATED);
- userAgentFirefoxWindowsActionPointer->setText(UserAgentHelper::FIREFOX_WINDOWS_TRANSLATED);
- userAgentChromeWindowsActionPointer->setText(UserAgentHelper::CHROME_WINDOWS_TRANSLATED);
- userAgentEdgeWindowsActionPointer->setText(UserAgentHelper::EDGE_WINDOWS_TRANSLATED);
- userAgentSafariMacosActionPointer->setText(UserAgentHelper::SAFARI_MACOS_TRANSLATED);
+ userAgentPrivacyBrowserActionPointer->setText(userAgentHelperPointer->PRIVACY_BROWSER_TRANSLATED);
+ userAgentWebEngineDefaultActionPointer->setText(userAgentHelperPointer->WEB_ENGINE_DEFAULT_TRANSLATED);
+ userAgentFirefoxLinuxActionPointer->setText(userAgentHelperPointer->FIREFOX_LINUX_TRANSLATED);
+ userAgentChromiumLinuxActionPointer->setText(userAgentHelperPointer->CHROMIUM_LINUX_TRANSLATED);
+ userAgentFirefoxWindowsActionPointer->setText(userAgentHelperPointer->FIREFOX_WINDOWS_TRANSLATED);
+ userAgentChromeWindowsActionPointer->setText(userAgentHelperPointer->CHROME_WINDOWS_TRANSLATED);
+ userAgentEdgeWindowsActionPointer->setText(userAgentHelperPointer->EDGE_WINDOWS_TRANSLATED);
+ userAgentSafariMacosActionPointer->setText(userAgentHelperPointer->SAFARI_MACOS_TRANSLATED);
searchEngineMojeekActionPointer->setText(i18nc("Search engine", "Mojeek"));
searchEngineMonoclesActionPointer->setText(i18nc("Search engine", "Monocles"));
searchEngineMetagerActionPointer->setText(i18nc("Search engine", "MetaGer"));
connect(findCaseSensitiveActionPointer, SIGNAL(triggered()), this, SLOT(toggleFindCaseSensitive()));
// Setup the GUI based on the browser_window_ui.rc file.
- setupGUI(StandardWindowOption::Default, ("browser_window_ui.rc"));
+ setupGUI(StandardWindowOption::Default, ("browserwindowui.rc"));
// Get lists of the actions' associated widgets.
QList<QWidget*> userAgentAssociatedWidgetsPointerList = userAgentPrivacyBrowserActionPointer->associatedWidgets();