Add on-the-fly settings.
authorSoren Stoutner <soren@stoutner.com>
Fri, 18 Feb 2022 18:39:34 +0000 (11:39 -0700)
committerSoren Stoutner <soren@stoutner.com>
Fri, 18 Feb 2022 18:39:34 +0000 (11:39 -0700)
src/BrowserWindow.cpp
src/BrowserWindow.h
src/MainView.cpp
src/MainView.h
src/UrlRequestInterceptor.cpp
src/privacybrowserui.rc

index 29fe4644feb31db29f80f92ea8bdd798e82d7862..1265c0d38a2c92a922f4d942af7e03f90330b2d5 100644 (file)
@@ -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.
index a8679ad4eab8a9eb04c14e65f1573abd48832fb5..8158100cc6e04f49bd348e9afe7b82298a6c6de2 100644 (file)
@@ -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
index 3bef1040a88bb160939b685cd2fbf10635f69844..99c9355053652253527d727961ba751041dbb898 100644 (file)
@@ -28,6 +28,7 @@
 #include "helpers/UserAgentHelper.h"
 
 // Qt framework headers.
+#include <QAction>
 #include <QWebEngineProfile>
 
 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));
     }
 }
 
index 17c189dee5842be8256c228492f1a5869c18ed47..506d0be27fe26ef6febd61e350980f21f9e7b3b4 100644 (file)
@@ -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;
index 94a88aa11287691f33ae0f184cacd8b38bd8af41..12be0ed944dae1f6d60bf558bb5ed7d2371fdd69 100644 (file)
@@ -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();
+        }
     }
 }
index fc7ae9deaaff1620e74593ba74f07821e2f0d8f0..516486f617b0257679f8bcbc8f3d4e2595ab940e 100644 (file)
     xsi:schemaLocation="http://www.kde.org/standards/kxmlgui/1.0 http://www.kde.org/standards/kxmlgui/1.0/kxmlgui.xsd" >
 
     <MenuBar>
-        <Menu name="edit">
-            <Action name="switch_action"/>
+        <Menu name="on_the_fly_settings"> <text>On-The-Fly Settings</text>
+            <Menu name="user_agent"> <text>User Agent</text>
+                <Action name="user_agent_privacy_browser" />
+                <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>
+
+            <Separator />
+
+            <Menu name="search_engine"> <text>Search Engine</text>
+                <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>
     </MenuBar>
 
     <ToolBar name="mainToolBar" noMerge="1">
         <text>Main Toolbar</text>
 
-        <Action name="options_configure"/>
+        <Action name="options_configure" />
     </ToolBar>
 </gui>