From 2c380f75b275780859774f3947db39cdf6f4f021 Mon Sep 17 00:00:00 2001 From: Soren Stoutner Date: Fri, 18 Feb 2022 11:39:34 -0700 Subject: [PATCH] Add on-the-fly settings. --- src/BrowserWindow.cpp | 203 ++++++++++++++++++++++++++++++++++ src/BrowserWindow.h | 17 +++ src/MainView.cpp | 50 +++++++-- src/MainView.h | 7 +- src/UrlRequestInterceptor.cpp | 44 ++++++-- src/privacybrowserui.rc | 27 ++++- 6 files changed, 325 insertions(+), 23 deletions(-) diff --git a/src/BrowserWindow.cpp b/src/BrowserWindow.cpp index 29fe464..1265c0d 100644 --- a/src/BrowserWindow.cpp +++ b/src/BrowserWindow.cpp @@ -48,6 +48,87 @@ BrowserWindow::BrowserWindow() : KXmlGuiWindow() KStandardAction::quit(qApp, SLOT(closeAllWindows()), actionCollectionPointer); KStandardAction::preferences(this, SLOT(settingsConfigure()), actionCollectionPointer); + // Add the custom actions. + userAgentPrivacyBrowserActionPointer = actionCollectionPointer->addAction(QStringLiteral("user_agent_privacy_browser")); + userAgentFirefoxLinuxActionPointer = actionCollectionPointer->addAction(QStringLiteral("user_agent_firefox_linux")); + userAgentChromiumLinuxActionPointer = actionCollectionPointer->addAction(QStringLiteral("user_agent_chromium_linux")); + userAgentFirefoxWindowsActionPointer = actionCollectionPointer->addAction(QStringLiteral("user_agent_firefox_windows")); + userAgentChromeWindowsActionPointer = actionCollectionPointer->addAction(QStringLiteral("user_agent_chrome_windows")); + userAgentEdgeWindowsActionPointer = actionCollectionPointer->addAction(QStringLiteral("user_agent_edge_windows")); + userAgentSafariMacosActionPointer = actionCollectionPointer->addAction(QStringLiteral("user_agent_safari_macos")); + userAgentCustomActionPointer = actionCollectionPointer->addAction(QStringLiteral("user_agent_custom")); + searchEngineMojeekActionPointer = actionCollectionPointer->addAction(QStringLiteral("search_engine_mojeek")); + searchEngineMonoclesActionPointer = actionCollectionPointer->addAction(QStringLiteral("search_engine_monocles")); + searchEngineMetagerActionPointer = actionCollectionPointer->addAction(QStringLiteral("search_engine_metager")); + searchEngineGoogleActionPointer = actionCollectionPointer->addAction(QStringLiteral("search_engine_google")); + searchEngineBingActionPointer = actionCollectionPointer->addAction(QStringLiteral("search_engine_bing")); + searchEngineYahooActionPointer = actionCollectionPointer->addAction(QStringLiteral("search_engine_yahoo")); + searchEngineCustomActionPointer = actionCollectionPointer->addAction(QStringLiteral("search_engine_custom")); + + // Create the action groups + QActionGroup *userAgentActionGroupPointer = new QActionGroup(this); + QActionGroup *searchEngineActionGroupPointer = new QActionGroup(this); + + // Add the actions to the groups. + userAgentActionGroupPointer->addAction(userAgentPrivacyBrowserActionPointer); + userAgentActionGroupPointer->addAction(userAgentFirefoxLinuxActionPointer); + userAgentActionGroupPointer->addAction(userAgentChromiumLinuxActionPointer); + userAgentActionGroupPointer->addAction(userAgentFirefoxWindowsActionPointer); + userAgentActionGroupPointer->addAction(userAgentChromeWindowsActionPointer); + userAgentActionGroupPointer->addAction(userAgentEdgeWindowsActionPointer); + userAgentActionGroupPointer->addAction(userAgentSafariMacosActionPointer); + userAgentActionGroupPointer->addAction(userAgentCustomActionPointer); + searchEngineActionGroupPointer->addAction(searchEngineMojeekActionPointer); + searchEngineActionGroupPointer->addAction(searchEngineMonoclesActionPointer); + searchEngineActionGroupPointer->addAction(searchEngineMetagerActionPointer); + searchEngineActionGroupPointer->addAction(searchEngineGoogleActionPointer); + searchEngineActionGroupPointer->addAction(searchEngineBingActionPointer); + searchEngineActionGroupPointer->addAction(searchEngineYahooActionPointer); + searchEngineActionGroupPointer->addAction(searchEngineCustomActionPointer); + + // Set some actions to be checkable. + userAgentPrivacyBrowserActionPointer->setCheckable(true); + userAgentFirefoxLinuxActionPointer->setCheckable(true); + userAgentChromiumLinuxActionPointer->setCheckable(true); + userAgentFirefoxWindowsActionPointer->setCheckable(true); + userAgentChromeWindowsActionPointer->setCheckable(true); + userAgentEdgeWindowsActionPointer->setCheckable(true); + userAgentSafariMacosActionPointer->setCheckable(true); + userAgentCustomActionPointer->setCheckable(true); + searchEngineMojeekActionPointer->setCheckable(true); + searchEngineMonoclesActionPointer->setCheckable(true); + searchEngineMetagerActionPointer->setCheckable(true); + searchEngineGoogleActionPointer->setCheckable(true); + searchEngineBingActionPointer->setCheckable(true); + searchEngineYahooActionPointer->setCheckable(true); + searchEngineCustomActionPointer->setCheckable(true); + + // Set the action names. The custom action text will be set later in the on-the-fly update slots. + userAgentPrivacyBrowserActionPointer->setText(i18nc("@action", "Privacy Browser")); + userAgentFirefoxLinuxActionPointer->setText(i18nc("@action", "Firefox Linux")); + userAgentChromiumLinuxActionPointer->setText(i18nc("@action", "Chromium Linux")); + userAgentFirefoxWindowsActionPointer->setText(i18nc("@action", "Firefox Windows")); + userAgentChromeWindowsActionPointer->setText(i18nc("@action", "Chrome Windows")); + userAgentEdgeWindowsActionPointer->setText(i18nc("@action", "Edge Windows")); + userAgentSafariMacosActionPointer->setText(i18nc("@action", "Safari macOS")); + searchEngineMojeekActionPointer->setText(i18nc("@action", "Mojeek")); + searchEngineMonoclesActionPointer->setText(i18nc("@action", "Monocles")); + searchEngineMetagerActionPointer->setText(i18nc("@action", "MetaGer")); + searchEngineGoogleActionPointer->setText(i18nc("@action", "Google")); + searchEngineBingActionPointer->setText(i18nc("@action", "Bing")); + searchEngineYahooActionPointer->setText(i18nc("@action", "Yahoo")); + + // Update the on-the-fly menus. + connect(mainViewPointer, SIGNAL(userAgentUpdated(QString)), this, SLOT(updateOnTheFlyUserAgent(QString))); + connect(mainViewPointer, SIGNAL(searchEngineUpdated(QString)), this, SLOT(updateOnTheFlySearchEngine(QString))); + + // Apply the on-the-fly settings when selected. + connect(userAgentActionGroupPointer, SIGNAL(triggered(QAction*)), mainViewPointer, SLOT(applyOnTheFlyUserAgent(QAction*))); + connect(searchEngineActionGroupPointer, SIGNAL(triggered(QAction*)), mainViewPointer, SLOT(applyOnTheFlySearchEngine(QAction*))); + + // Initialize the on-the-fly search engine menu, as the slot connection had not been created when MainView was constructed. + updateOnTheFlySearchEngine(Settings::searchEngine()); + // Update the status bar with the URL when a link is hovered. connect(mainViewPointer, SIGNAL(linkHovered(QString)), this, SLOT(updateStatusBar(QString))); @@ -114,6 +195,128 @@ void BrowserWindow::settingsConfigure() } } +void BrowserWindow::updateOnTheFlySearchEngine(const QString &searchEngine) const +{ + // Initialize the custom search engine flag. + bool customSearchEngine = false; + + if (searchEngine == "Mojeek") // Mojeek. + { + searchEngineMojeekActionPointer->setChecked(true); + } + else if (searchEngine == "Monocles") // Monocles. + { + searchEngineMonoclesActionPointer->setChecked(true); + } + else if (searchEngine == "MetaGer") // MetaGer. + { + searchEngineMetagerActionPointer->setChecked(true); + } + else if (searchEngine == "Google") // Google. + { + searchEngineGoogleActionPointer->setChecked(true); + } + else if (searchEngine == "Bing") // Bing. + { + searchEngineBingActionPointer->setChecked(true); + } + else if (searchEngine == "Yahoo") // Yahoo. + { + searchEngineYahooActionPointer->setChecked(true); + } + else // Custom search engine. + { + // Check the user agent. + searchEngineCustomActionPointer->setChecked(true); + + // Set the custom search engine flag. + customSearchEngine = true; + } + + + // Format the custom search engine. + if (customSearchEngine) + { + // Enable the custom search engine. + searchEngineCustomActionPointer->setEnabled(true); + + // Set the custom search engine text. + searchEngineCustomActionPointer->setText(searchEngine); + } + else + { + // Disable the custom search engine. + searchEngineCustomActionPointer->setEnabled(false); + + // Reset the custom search engine text. + searchEngineCustomActionPointer->setText(i18nc("@action", "Custom")); + } +} + +void BrowserWindow::updateOnTheFlyUserAgent(const QString &userAgent) const +{ + // Initialize the custom user agent flag. + bool customUserAgent = false; + + // Check the indicated on-the-fly user agent. + if (userAgent == "Privacy Browser") // Privacy Browser. + { + userAgentPrivacyBrowserActionPointer->setChecked(true); + } + else if (userAgent == "Firefox Linux") // Firefox Linux. + { + userAgentFirefoxLinuxActionPointer->setChecked(true); + } + else if (userAgent == "Chromium Linux") // Chromium Linux. + { + userAgentChromiumLinuxActionPointer->setChecked(true); + } + else if (userAgent == "Firefox Windows") // Firefox Windows. + { + userAgentFirefoxWindowsActionPointer->setChecked(true); + } + else if (userAgent == "Chrome Windows") // Chrome Windows. + { + userAgentChromeWindowsActionPointer->setChecked(true); + } + else if (userAgent == "Edge Windows") // Edge Windows. + { + userAgentEdgeWindowsActionPointer->setChecked(true); + } + else if (userAgent == "Safari macOS") // Safari macOS. + { + userAgentSafariMacosActionPointer->setChecked(true); + } + else // Custom user agent. + { + // Check the user agent. + userAgentCustomActionPointer->setChecked(true); + + // Set the custom user agent flag. + customUserAgent = true; + } + + + // Format the custom user agent. + if (customUserAgent) + { + // Enable the custom user agent. + userAgentCustomActionPointer->setEnabled(true); + + // Set the custom user agent text. + userAgentCustomActionPointer->setText(userAgent); + } + else + { + // Disable the custom user agent. + userAgentCustomActionPointer->setEnabled(false); + + // Reset the custom user agent text. + userAgentCustomActionPointer->setText(i18nc("@action", "Custom")); + } +} + + void BrowserWindow::updateSearchEngineLabel(const QString &searchEngineString) const { // Update the search engine label. diff --git a/src/BrowserWindow.h b/src/BrowserWindow.h index a8679ad..8158100 100644 --- a/src/BrowserWindow.h +++ b/src/BrowserWindow.h @@ -42,6 +42,8 @@ private Q_SLOTS: // The private slots. void fileNew() const; void settingsConfigure(); + void updateOnTheFlySearchEngine(const QString &searchEngine) const; + void updateOnTheFlyUserAgent(const QString &userAgent) const; void updateSearchEngineLabel(const QString &searchEngineString) const; void updateStatusBar(const QString &statusBarMessage) const; void updateUserAgentLabel(const QString &userAgentName) const; @@ -50,6 +52,21 @@ private: // The private variables. MainView *mainViewPointer; QLabel *searchEngineLabelPointer; + QAction *searchEngineMojeekActionPointer; + QAction *searchEngineMonoclesActionPointer; + QAction *searchEngineMetagerActionPointer; + QAction *searchEngineGoogleActionPointer; + QAction *searchEngineBingActionPointer; + QAction *searchEngineYahooActionPointer; + QAction *searchEngineCustomActionPointer; QLabel *userAgentLabelPointer; + QAction *userAgentPrivacyBrowserActionPointer; + QAction *userAgentFirefoxLinuxActionPointer; + QAction *userAgentChromiumLinuxActionPointer; + QAction *userAgentFirefoxWindowsActionPointer; + QAction *userAgentChromeWindowsActionPointer; + QAction *userAgentEdgeWindowsActionPointer; + QAction *userAgentSafariMacosActionPointer; + QAction *userAgentCustomActionPointer; }; #endif diff --git a/src/MainView.cpp b/src/MainView.cpp index 3bef104..99c9355 100644 --- a/src/MainView.cpp +++ b/src/MainView.cpp @@ -28,6 +28,7 @@ #include "helpers/UserAgentHelper.h" // Qt framework headers. +#include #include MainView::MainView(QWidget *parent) : QWidget(parent) @@ -92,15 +93,9 @@ MainView::MainView(QWidget *parent) : QWidget(parent) // Don't allow JavaScript to open windows. webEngineSettingsPointer->setAttribute(QWebEngineSettings::JavascriptCanOpenWindows, false); - // Set the zoom factor. - webEngineViewPointer->setZoomFactor(Settings::zoomFactor()); - // Apply the application settings. applyApplicationSettings(); - // Apply the domain settings. `false` does not reload the website. - applyDomainSettings(false); - // Set the focus on the WebEngine view. webEngineViewPointer->setFocus(); @@ -120,9 +115,13 @@ MainView::MainView(QWidget *parent) : QWidget(parent) } } -void MainView::applyApplicationSettings() const +void MainView::applyApplicationSettings() { - // TODO. + // Set the search engine URL. + searchEngineUrl = SearchEngineHelper::getSearchUrl(Settings::searchEngine()); + + // Emit the search engine updated signal, which causes the on-the-fly menu to be updated. + emit searchEngineUpdated(Settings::searchEngine()); } // This exists as a separate function from `applyDomainSettings()` so it can be listed as a slot and function without the need for a boolean argument. @@ -157,6 +156,12 @@ void MainView::applyDomainSettings(bool reloadWebsite) const // Apply the user agent. webEngineProfilePointer->setHttpUserAgent(UserAgentHelper::getUserAgent(Settings::userAgent())); + // Emit the user agent updated signal, which causes the on-the-fly menu to be updated. + emit userAgentUpdated(Settings::userAgent()); + + // Set the zoom factor. + webEngineViewPointer->setZoomFactor(Settings::zoomFactor()); + // Reload the website if requested. if (reloadWebsite) { @@ -164,6 +169,33 @@ void MainView::applyDomainSettings(bool reloadWebsite) const } } +void MainView::applyOnTheFlySearchEngine(QAction *searchEngineActionPointer) +{ + // Store the search engine name. + QString searchEngineName = searchEngineActionPointer->text(); + + // Strip out any `&` characters. + searchEngineName.remove('&'); + + // Store the search engine string. + searchEngineUrl = SearchEngineHelper::getSearchUrl(searchEngineName); +} + +void MainView::applyOnTheFlyUserAgent(QAction *userAgentActionPointer) const +{ + // Get the user agent name. + QString userAgentName = userAgentActionPointer->text(); + + // Strip out any `&` characters. + userAgentName.remove('&'); + + // Apply the user agent. + webEngineProfilePointer->setHttpUserAgent(UserAgentHelper::getUserAgent(userAgentName)); + + // Reload the website. + webEngineViewPointer->reload(); +} + void MainView::goHome() const { // Load the homepage. @@ -191,7 +223,7 @@ void MainView::loadUrlFromTextBox(QString urlFromUser) const else // The text is likely a search. { // Load the search. - webEngineViewPointer->setUrl(QUrl::fromUserInput(SearchEngineHelper::getSearchUrl(Settings::searchEngine()) + urlFromUser)); + webEngineViewPointer->setUrl(QUrl::fromUserInput(searchEngineUrl + urlFromUser)); } } diff --git a/src/MainView.h b/src/MainView.h index 17c189d..506d0be 100644 --- a/src/MainView.h +++ b/src/MainView.h @@ -41,12 +41,16 @@ public: signals: // The signals. void linkHovered(const QString &linkUrl) const; + void userAgentUpdated(const QString &userAgent) const; + void searchEngineUpdated(const QString &searchEngine) const; public Q_SLOTS: // The public slots. - void applyApplicationSettings() const; + void applyApplicationSettings(); void applyDomainSettingsAndReload() const; void applyDomainSettingsWithoutReloading() const; + void applyOnTheFlySearchEngine(QAction *searchEngineActionPointer); + void applyOnTheFlyUserAgent(QAction *userAgentActionPointer) const; private Q_SLOTS: // The private slots. @@ -61,6 +65,7 @@ private: QPushButton *backButtonPointer; QPushButton *forwardButtonPointer; QPushButton *javaScriptButtonPointer; + QString searchEngineUrl; KLineEdit *urlLineEditPointer; QWebEngineHistory *webEngineHistoryPointer; QWebEngineProfile *webEngineProfilePointer; diff --git a/src/UrlRequestInterceptor.cpp b/src/UrlRequestInterceptor.cpp index 94a88aa..12be0ed 100644 --- a/src/UrlRequestInterceptor.cpp +++ b/src/UrlRequestInterceptor.cpp @@ -25,26 +25,50 @@ UrlRequestInterceptor::UrlRequestInterceptor(QObject *parentObjectPointer) : QWe void UrlRequestInterceptor::interceptRequest(QWebEngineUrlRequestInfo &urlRequestInfo) { + // Handle the request according to the navigation type. + switch (urlRequestInfo.navigationType()) + { + case QWebEngineUrlRequestInfo::NavigationTypeLink: + case QWebEngineUrlRequestInfo::NavigationTypeTyped: + { + // Only check the hosts if the main URL is changing. + if (urlRequestInfo.resourceType() == QWebEngineUrlRequestInfo::ResourceTypeMainFrame) + { + // Get the hosts. + QString requestingHost = urlRequestInfo.initiator().host(); + QString requestedHost = urlRequestInfo.requestUrl().host(); + + // Reapply the domain settings if the host is changing. + if (requestingHost != requestedHost) + { + emit applyDomainSettings(); + } + } + + break; + } + + default: + // Do nothing. + break; + } + // Handle the request according to the resource type. switch (urlRequestInfo.resourceType()) { + // A naughty HTTP ping request. case QWebEngineUrlRequestInfo::ResourceTypePing: + { // Block HTTP ping requests. urlRequestInfo.block(true); + break; + } default: + { // Do nothing. break; - } - - // Get the hosts. - QString requestingHost = urlRequestInfo.firstPartyUrl().host(); - QString requestedHost = urlRequestInfo.requestUrl().host(); - - // Reapply the domain settings if the host is changing. - if (requestingHost != requestedHost) - { - emit applyDomainSettings(); + } } } diff --git a/src/privacybrowserui.rc b/src/privacybrowserui.rc index fc7ae9d..516486f 100644 --- a/src/privacybrowserui.rc +++ b/src/privacybrowserui.rc @@ -26,14 +26,35 @@ xsi:schemaLocation="http://www.kde.org/standards/kxmlgui/1.0 http://www.kde.org/standards/kxmlgui/1.0/kxmlgui.xsd" > - - + On-The-Fly Settings + User Agent + + + + + + + + + + + + + Search Engine + + + + + + + + Main Toolbar - + -- 2.45.2