X-Git-Url: https://gitweb.stoutner.com/?a=blobdiff_plain;f=src%2Fwidgets%2FPrivacyWebEngineView.cpp;h=42c331fec5340447ed05da6433a6475db30f7de4;hb=refs%2Fheads%2Fmaster;hp=6080288e4f5b4238404e8e13795e305f2fd9c65e;hpb=3ea5ede1fd0721bea6813f36388ba6387bdbfcfe;p=PrivacyBrowserPC.git diff --git a/src/widgets/PrivacyWebEngineView.cpp b/src/widgets/PrivacyWebEngineView.cpp index 6080288..298cdb9 100644 --- a/src/widgets/PrivacyWebEngineView.cpp +++ b/src/widgets/PrivacyWebEngineView.cpp @@ -1,33 +1,37 @@ -/* - * Copyright 2022-2024 Soren Stoutner . +/* SPDX-License-Identifier: GPL-3.0-or-later + * SPDX-FileCopyrightText: 2022-2025 Soren Stoutner * - * This file is part of Privacy Browser PC . + * This file is part of 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. + * This program is free software: you can redistribute it and/or modify it under + * the terms of the 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. + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR 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 . + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . */ // Application headers. +#include "GlobalVariables.h" #include "PrivacyWebEngineView.h" +#include "PrivacyWebEnginePage.h" #include "Settings.h" +#include "TemporaryWebEngineView.h" #include "ui_HttpAuthenticationDialog.h" #include "databases/CookiesDatabase.h" #include "databases/DomainsDatabase.h" #include "dialogs/HttpAuthenticationDialog.h" +#include "helpers/FilterListHelper.h" #include "interceptors/UrlRequestInterceptor.h" #include "windows/BrowserWindow.h" -// Qt toolkit headers. +// Qt framework headers. #include #include @@ -37,14 +41,17 @@ PrivacyWebEngineView::PrivacyWebEngineView(QWidget *parentWidgetPointer) : QWebE // Create an off-the-record profile (the default when no profile name is specified). webEngineProfilePointer = new QWebEngineProfile(QLatin1String("")); + // Disable the HTTP cache. + webEngineProfilePointer->setHttpCacheType(QWebEngineProfile::NoCache); + // Create a WebEngine page. - QWebEnginePage *webEnginePagePointer = new QWebEnginePage(webEngineProfilePointer); + PrivacyWebEnginePage *privacyWebEnginePagePointer = new PrivacyWebEnginePage(webEngineProfilePointer); // Set the WebEngine page. - setPage(webEnginePagePointer); + setPage(privacyWebEnginePagePointer); // Get handles for the various aspects of the WebEngine. - webEngineSettingsPointer = webEnginePagePointer->settings(); + webEngineSettingsPointer = privacyWebEnginePagePointer->settings(); // Instantiate the URL request interceptor. UrlRequestInterceptor *urlRequestInterceptorPointer = new UrlRequestInterceptor(this); @@ -52,14 +59,20 @@ PrivacyWebEngineView::PrivacyWebEngineView(QWidget *parentWidgetPointer) : QWebE // Set the URL request interceptor. webEngineProfilePointer->setUrlRequestInterceptor(urlRequestInterceptorPointer); - // Reapply the domain settings when the host changes. - connect(urlRequestInterceptorPointer, SIGNAL(applyDomainSettings(const QString&)), this, SLOT(applyDomainSettingsWithoutReloading(const QString&))); - - // Display HTTP Ping blocked dialogs. + // Connect the URL request interceptor signals. + connect(urlRequestInterceptorPointer, SIGNAL(applyDomainSettings(const QUrl&, const bool)), this, SLOT(applyDomainSettings(const QUrl&, const bool))); + connect(urlRequestInterceptorPointer, SIGNAL(newMainFrameResource()), this, SLOT(clearRequestsList())); connect(urlRequestInterceptorPointer, SIGNAL(displayHttpPingDialog(const QString&)), this, SLOT(displayHttpPingDialog(const QString&))); + connect(urlRequestInterceptorPointer, SIGNAL(requestProcessed(RequestStruct*)), this, SLOT(storeRequest(RequestStruct*))); // Handle HTTP authentication requests. - connect(webEnginePagePointer, SIGNAL(authenticationRequired(const QUrl&, QAuthenticator*)), this, SLOT(handleAuthenticationRequest(const QUrl&, QAuthenticator*))); + connect(privacyWebEnginePagePointer, SIGNAL(authenticationRequired(const QUrl&, QAuthenticator*)), this, SLOT(handleAuthenticationRequest(const QUrl&, QAuthenticator*))); + + // Store the link URL whenever a link is hovered. + connect(privacyWebEnginePagePointer, SIGNAL(linkHovered(const QString)), this, SLOT(saveHoveredLink(const QString))); + + // Store the URL when it changes. + connect(this, SIGNAL(urlChanged(const QUrl&)), this, SLOT(storeUpdatedUrl(const QUrl&))); } void PrivacyWebEngineView::addCookieToList(const QNetworkCookie &cookie) const @@ -74,22 +87,22 @@ void PrivacyWebEngineView::addCookieToList(const QNetworkCookie &cookie) const CookiesDatabase::updateCookie(cookie); // Update the cookies action. - emit updateCookiesAction(cookieListPointer->size()); + Q_EMIT numberOfCookiesChanged(cookieListPointer->size()); } -void PrivacyWebEngineView::applyDomainSettingsWithoutReloading(const QString &hostname) +void PrivacyWebEngineView::applyDomainSettings(const QUrl &newUrl, const bool navigatingHistory) { - // Apply the domain settings `false` does not reload the website. - applyDomainSettings(hostname, false); -} + // Store the current host. + currentHost = newUrl.host(); -void PrivacyWebEngineView::applyDomainSettings(const QString &hostname, const bool reloadWebsite) -{ - // Get the record for the hostname. - QSqlQuery domainQuery = DomainsDatabase::getDomainQuery(hostname); + // Create a user agent changed tracker. + bool userAgentChanged = false; - // Check if the hostname has domain settings. - if (domainQuery.isValid()) // The hostname has domain settings. + // Get the record for the current host. + QSqlQuery domainQuery = DomainsDatabase::getDomainQuery(currentHost); + + // Check if the current host has domain settings. + if (domainQuery.isValid()) // The current host has domain settings. { // Store the domain settings name. domainSettingsName = domainQuery.value(DomainsDatabase::DOMAIN_NAME).toString(); @@ -97,89 +110,76 @@ void PrivacyWebEngineView::applyDomainSettings(const QString &hostname, const bo // Set the JavaScript status. switch (domainQuery.value(DomainsDatabase::JAVASCRIPT).toInt()) { - // Set the default JavaScript status. - case (DomainsDatabase::SYSTEM_DEFAULT): - { - webEngineSettingsPointer->setAttribute(QWebEngineSettings::JavascriptEnabled, Settings::javaScriptEnabled()); - - break; - } - - // Enable JavaScript. - case (DomainsDatabase::ENABLED): - { - webEngineSettingsPointer->setAttribute(QWebEngineSettings::JavascriptEnabled, true); - - break; - } - - // Disable JavaScript. - case (DomainsDatabase::DISABLED): - { - webEngineSettingsPointer->setAttribute(QWebEngineSettings::JavascriptEnabled, false); - - break; - } + case (DomainsDatabase::SYSTEM_DEFAULT): webEngineSettingsPointer->setAttribute(QWebEngineSettings::JavascriptEnabled, Settings::javaScriptEnabled()); break; + case (DomainsDatabase::ENABLED): webEngineSettingsPointer->setAttribute(QWebEngineSettings::JavascriptEnabled, true); break; + case (DomainsDatabase::DISABLED): webEngineSettingsPointer->setAttribute(QWebEngineSettings::JavascriptEnabled, false); break; } // Set the local storage status. switch (domainQuery.value(DomainsDatabase::LOCAL_STORAGE).toInt()) { - // Set the default local storage status. - case (DomainsDatabase::SYSTEM_DEFAULT): - { - localStorageEnabled = Settings::localStorageEnabled(); + case (DomainsDatabase::SYSTEM_DEFAULT): localStorageEnabled = Settings::localStorageEnabled(); break; + case (DomainsDatabase::ENABLED): localStorageEnabled = true; break; + case (DomainsDatabase::DISABLED): localStorageEnabled = false; break; + } - break; - } + // Set the DOM storage status. QWebEngineSettings confusingly calls this local storage. + switch (domainQuery.value(DomainsDatabase::DOM_STORAGE).toInt()) + { + case (DomainsDatabase::SYSTEM_DEFAULT): webEngineSettingsPointer->setAttribute(QWebEngineSettings::LocalStorageEnabled, Settings::domStorageEnabled()); break; + case (DomainsDatabase::ENABLED): webEngineSettingsPointer->setAttribute(QWebEngineSettings::LocalStorageEnabled, true); break; + case (DomainsDatabase::DISABLED): webEngineSettingsPointer->setAttribute(QWebEngineSettings::LocalStorageEnabled, false); break; + } - // Enable local storage. - case (DomainsDatabase::ENABLED): - { - localStorageEnabled = true; + // Get the domain settings user agent. + QString domainSettingsUserAgent = UserAgentHelper::getResultingDomainSettingsUserAgent(domainQuery.value(DomainsDatabase::USER_AGENT).toString()); - break; - } + // Determine if the user agent is changing. + if (webEngineProfilePointer->httpUserAgent() != domainSettingsUserAgent) + userAgentChanged = true; - // Disable local storage. - case (DomainsDatabase::DISABLED): - { - localStorageEnabled = false; + // Set the user agent. Setting the user agent, even if it isn't changing, causes the pre-rendered page to enter a locked state where reload doesn't work. + webEngineProfilePointer->setHttpUserAgent(domainSettingsUserAgent); - break; - } + // Set the UltraPrivacy status. + switch (domainQuery.value(DomainsDatabase::ULTRAPRIVACY).toInt()) + { + case (DomainsDatabase::SYSTEM_DEFAULT): ultraPrivacyEnabled = Settings::ultraPrivacyEnabled(); break; + case (DomainsDatabase::ENABLED): ultraPrivacyEnabled = true; break; + case (DomainsDatabase::DISABLED): ultraPrivacyEnabled = false; break; } - // Set the DOM storage status. - switch (domainQuery.value(DomainsDatabase::DOM_STORAGE).toInt()) + // Set the UltraList status. + switch (domainQuery.value(DomainsDatabase::ULTRALIST).toInt()) { - // Set the default DOM storage status. QWebEngineSettings confusingly calls this local storage. - case (DomainsDatabase::SYSTEM_DEFAULT): - { - webEngineSettingsPointer->setAttribute(QWebEngineSettings::LocalStorageEnabled, Settings::domStorageEnabled()); - - break; - } - - // Enable DOM storage. QWebEngineSettings confusingly calls this local storage. - case (DomainsDatabase::ENABLED): - { - webEngineSettingsPointer->setAttribute(QWebEngineSettings::LocalStorageEnabled, true); - - break; - } + case (DomainsDatabase::SYSTEM_DEFAULT): ultraListEnabled = Settings::ultraListEnabled(); break; + case (DomainsDatabase::ENABLED): ultraListEnabled = true; break; + case (DomainsDatabase::DISABLED): ultraListEnabled = false; break; + } - // Disable DOM storage. QWebEngineSettings confusingly calls this local storage. - case (DomainsDatabase::DISABLED): - { - webEngineSettingsPointer->setAttribute(QWebEngineSettings::LocalStorageEnabled, false); + // Set the EasyPrivacy status. + switch (domainQuery.value(DomainsDatabase::EASYPRIVACY).toInt()) + { + case (DomainsDatabase::SYSTEM_DEFAULT): easyPrivacyEnabled = Settings::easyPrivacyEnabled(); break; + case (DomainsDatabase::ENABLED): easyPrivacyEnabled = true; break; + case (DomainsDatabase::DISABLED): easyPrivacyEnabled = false; break; + } - break; - } + // Set the EasyList status. + switch (domainQuery.value(DomainsDatabase::EASYLIST).toInt()) + { + case (DomainsDatabase::SYSTEM_DEFAULT): easyListEnabled = Settings::easyListEnabled(); break; + case (DomainsDatabase::ENABLED): easyListEnabled = true; break; + case (DomainsDatabase::DISABLED): easyListEnabled = false; break; } - // Set the user agent. - webEngineProfilePointer->setHttpUserAgent(UserAgentHelper::getResultingDomainSettingsUserAgent(domainQuery.value(DomainsDatabase::USER_AGENT).toString())); + // Set the Fanboy's Annoyance List status. + switch (domainQuery.value(DomainsDatabase::FANBOYS_ANNOYANCE_LIST).toInt()) + { + case (DomainsDatabase::SYSTEM_DEFAULT): fanboysAnnoyanceListEnabled = Settings::fanboysAnnoyanceListEnabled(); break; + case (DomainsDatabase::ENABLED): fanboysAnnoyanceListEnabled = true; break; + case (DomainsDatabase::DISABLED): fanboysAnnoyanceListEnabled = false; break; + } // Check if a custom zoom factor is set. if (domainQuery.value(DomainsDatabase::ZOOM_FACTOR).toInt()) @@ -193,7 +193,7 @@ void PrivacyWebEngineView::applyDomainSettings(const QString &hostname, const bo defaultZoomFactor = Settings::zoomFactor(); } } - else // The hostname does not have domain settings. + else // The current host does not have domain settings. { // Reset the domain settings name. domainSettingsName = QLatin1String(""); @@ -207,8 +207,22 @@ void PrivacyWebEngineView::applyDomainSettings(const QString &hostname, const bo // Set DOM storage. In QWebEngineSettings it is called Local Storage. webEngineSettingsPointer->setAttribute(QWebEngineSettings::LocalStorageEnabled, Settings::domStorageEnabled()); - // Set the user agent. - webEngineProfilePointer->setHttpUserAgent(UserAgentHelper::getUserAgentFromDatabaseName(Settings::userAgent())); + // Get the default user agent. + QString defaultUserAgent = UserAgentHelper::getUserAgentFromDatabaseName(Settings::userAgent()); + + // Determine if the user agent is changing. + if (webEngineProfilePointer->httpUserAgent() != defaultUserAgent) + userAgentChanged = true; + + // Set the user agent. Setting the user agent, even if it isn't changing, causes the pre-rendered page to enter a locked state where reload doesn't work. + webEngineProfilePointer->setHttpUserAgent(defaultUserAgent); + + // Set the status for each filter list. + ultraPrivacyEnabled = Settings::ultraPrivacyEnabled(); + ultraListEnabled = Settings::ultraListEnabled(); + easyPrivacyEnabled = Settings::easyPrivacyEnabled(); + easyListEnabled = Settings::easyListEnabled(); + fanboysAnnoyanceListEnabled = Settings::fanboysAnnoyanceListEnabled(); // Store the zoom factor. defaultZoomFactor = Settings::zoomFactor(); @@ -217,20 +231,83 @@ void PrivacyWebEngineView::applyDomainSettings(const QString &hostname, const bo // Set the current zoom factor. setZoomFactor(defaultZoomFactor); - // Reload the website if requested. - if (reloadWebsite) - reload(); + // Reset the HTTP authentication dialog counter. + httpAuthenticationDialogsDisplayed = 0; // Update the UI. - emit updateUi(this); + Q_EMIT updateUi(this); + + // Reload the URL. + // This works around a bug in Qt WebEngine that causes massive problems when the user agent is changed after the page has started pre-rendering. + if (navigatingHistory) + { + // Get a handle for the WebEngine history. + QWebEngineHistory *webEngineHistoryPointer = history(); + + // Navigate the history according to the status of the user agent. + if (userAgentChanged) // The user agent changed. + { + // Go back once. This current navigation will fail, but the next one will succeed. + //back(); + + if (webEngineHistoryPointer->canGoBack() && (newUrl == webEngineHistoryPointer->backItem().url())) + { + // Go back twice. The first one will fail, but the second will succeed. + back(); + } + else + { + // Go forward twice. The first one will fail, but the second will succeed. + forward(); + } + } + else // The user agent did not change. + { + // The WebEngine history will think it has loaded the final URL, and will be in the correct location, but it will have been interrupted and reloaded the original URL. + // The solution is to direct the WebEngine history to offset one and then return, which will actually load the correct URL because `applyDomainSettings` will not be triggered. + if (webEngineHistoryPointer->canGoForward()) + { + // Go forward and back one. + forward(); + back(); + } + else + { + // Go back and forward one. + back(); + forward(); + } + } + } else { + // Load the new URL again. + load(newUrl); + } } -void PrivacyWebEngineView::contextMenuEvent(QContextMenuEvent *contextMenuEvent) { - // Get a handle for the +void PrivacyWebEngineView::clearRequestsList() +{ + // Reset the number of blocked requests. + blockedRequestsVector[ULTRAPRIVACY] = 0; + blockedRequestsVector[ULTRALIST] = 0; + blockedRequestsVector[EASYPRIVACY] = 0; + blockedRequestsVector[EASYLIST] = 0; + blockedRequestsVector[FANBOYS_ANNOYANCE_LIST] = 0; + blockedRequestsVector[TOTAL] = 0; + + // Clear the requests list. + requestsListPointer->clear(); + + // Update the blocked requests action. + Q_EMIT requestBlocked(blockedRequestsVector); +} + +void PrivacyWebEngineView::contextMenuEvent(QContextMenuEvent *contextMenuEvent) +{ + // Get a handle for the WebEngine page. QWebEnginePage *webEnginePagePointer = page(); // Get a handle for the menu. - QMenu *contextMenu = webEnginePagePointer->createStandardContextMenu(); + QMenu *contextMenu = createStandardContextMenu(); // Get the list of context menu actions. const QList contextMenuActionsList = contextMenu->actions(); @@ -238,24 +315,64 @@ void PrivacyWebEngineView::contextMenuEvent(QContextMenuEvent *contextMenuEvent) // Add the open link in new background tab action if the context menu already contains the open link in new window action. if (contextMenuActionsList.contains(webEnginePagePointer->action(QWebEnginePage::OpenLinkInNewWindow))) { - // Move the open in new tab action to the top of the list. - contextMenu->insertAction(webEnginePagePointer->action(QWebEnginePage::Back), webEnginePagePointer->action(QWebEnginePage::OpenLinkInNewTab)); + // Create a manual open in new tab action. + QAction *manualOpenLinkInNewTabActionPointer = new QAction(i18nc("Open link in new tab action", "Open link in new tab"), contextMenu); + + // Connect the actions. + connect(manualOpenLinkInNewTabActionPointer, SIGNAL(triggered()), this, SLOT(manualOpenInNewTab())); + + // Move the open in new tab action above the back action. + contextMenu->insertAction(webEnginePagePointer->action(QWebEnginePage::Back), manualOpenLinkInNewTabActionPointer); - // Add the open link in background tab action below the open in new tab action. + // Add the open link in background tab action above the back action. contextMenu->insertAction(webEnginePagePointer->action(QWebEnginePage::Back), webEnginePagePointer->action(QWebEnginePage::OpenLinkInNewBackgroundTab)); - // Move the open in new window action below the open in background tab action. + // Move the open in new window action above the back action. contextMenu->insertAction(webEnginePagePointer->action(QWebEnginePage::Back), webEnginePagePointer->action(QWebEnginePage::OpenLinkInNewWindow)); - // Add a separator below the open in new window action. + // Add a separator above the back action. contextMenu->insertSeparator(webEnginePagePointer->action(QWebEnginePage::Back)); + + if (globalFirefoxInstalled || globalChromiumInstalled) + { + // Add the open with Firefox action if Firefox is installed. + if (globalFirefoxInstalled) + { + // Create an open with Firefox action. + QAction *openWithFirefoxActionPointer = new QAction(QIcon::fromTheme(QLatin1String("firefox-esr")), i18nc("Open with Firefox context menu action", "Open with Firefox"), contextMenu); + + // Add the open with Firefox action above the back action. + contextMenu->insertAction(webEnginePagePointer->action(QWebEnginePage::Back), openWithFirefoxActionPointer); + + // Connect the action. + connect(openWithFirefoxActionPointer, SIGNAL(triggered()), this, SLOT(openWithFirefox())); + } + + // Add the open with Chromium action if Chromium is installed. + if (globalChromiumInstalled) + { + // Create an open with Chromium action. + QAction *openWithChromiumActionPointer = new QAction(QIcon::fromTheme(QLatin1String("chromium")), i18nc("Open with Chromium context menu action", "Open with Chromium"), contextMenu); + + // Add the open with Chromium action above the back action. + contextMenu->insertAction(webEnginePagePointer->action(QWebEnginePage::Back), openWithChromiumActionPointer); + + // Connect the action. + connect(openWithChromiumActionPointer, SIGNAL(triggered()), this, SLOT(openWithChromium())); + } + + + // Add a separator above the back action. + contextMenu->insertSeparator(webEnginePagePointer->action(QWebEnginePage::Back)); + } } // Display the menu using the location in the context menu event. contextMenu->popup(contextMenuEvent->globalPos()); } -QWebEngineView* PrivacyWebEngineView::createWindow(QWebEnginePage::WebWindowType webWindowType) { +QWebEngineView* PrivacyWebEngineView::createWindow(QWebEnginePage::WebWindowType webWindowType) +{ // Get a handle for the browser window. BrowserWindow *browserWindowPointer = qobject_cast(window()); @@ -264,9 +381,25 @@ QWebEngineView* PrivacyWebEngineView::createWindow(QWebEnginePage::WebWindowType { case QWebEnginePage::WebBrowserTab: { - // Create the new tab and return the privacy WebEngine view pointer. `true` removes the focus from the blank URL line edit. `true` adds the new tab adjacent to the current tab. - // The new privacy WebEngine view pointer is returned so it can be populated with the link from the context menu. - return browserWindowPointer->tabWidgetPointer->addTab(true, true); + if (manuallyOpeninginNewTab) + { + // Reset the manually opening in new tab flag. + manuallyOpeninginNewTab = false; + + // Create the new tab and return the privacy WebEngine view pointer. `true` removes the focus from the blank URL line edit. `true` adds the new tab adjacent to the current tab. + // The new privacy WebEngine view pointer is returned so it can be populated with the link from the context menu. + return browserWindowPointer->tabWidgetPointer->addTab(true, true); + } + else + { + // The web page is trying to automatically open a new tab by setting the target to be "_blank". Create a temporary WebEngine view and open it there. + // The URL cannot be loaded into this privacy WebEngine view because it will clear the web history. + // But the temporary WebEngine will capture the URL and then pass it back to this privacy WebEngine view. + TemporaryWebEngineView *temporaryWebEngineViewPointer = new TemporaryWebEngineView(this); + + // Return the temporary WebEngine view. + return temporaryWebEngineViewPointer; + } } case QWebEnginePage::WebBrowserWindow: @@ -300,16 +433,43 @@ QWebEngineView* PrivacyWebEngineView::createWindow(QWebEnginePage::WebWindowType void PrivacyWebEngineView::displayHttpPingDialog(const QString &httpPingUrl) const { // Display the HTTP Ping blocked dialog. - emit displayHttpPingBlockedDialog(httpPingUrl); + Q_EMIT displayHttpPingBlockedDialog(httpPingUrl); } void PrivacyWebEngineView::handleAuthenticationRequest(const QUrl &requestUrl, QAuthenticator *authenticatorPointer) { - // Instantiate an HTTP authentication dialog. - HttpAuthenticationDialog *httpAuthenticationDialogPointer = new HttpAuthenticationDialog(parentWidget(), requestUrl, authenticatorPointer); + // Only display the HTTP authentication dialog if it hasn't already been displayed three times for this URL. + if (httpAuthenticationDialogsDisplayed < 3) { + // Increment the HTTP authentication dialog display counter. + ++httpAuthenticationDialogsDisplayed; - // Display the dialog. This must be `exec()` instead of `show()` so that the website doesn't proceed before populating the authentication pointer. - httpAuthenticationDialogPointer->exec(); + // Instantiate an HTTP authentication dialog. + HttpAuthenticationDialog *httpAuthenticationDialogPointer = new HttpAuthenticationDialog(parentWidget(), requestUrl, authenticatorPointer); + + // Display the dialog. This must be `exec()` instead of `show()` so that the website doesn't proceed before populating the authentication pointer. + httpAuthenticationDialogPointer->exec(); + } +} + +void PrivacyWebEngineView::manualOpenInNewTab() +{ + // Set the manually opening in new tab flag. + manuallyOpeninginNewTab = true; + + // Open the url in a new tab. + triggerPageAction(QWebEnginePage::OpenLinkInNewTab); +} + +void PrivacyWebEngineView::openWithChromium() const +{ + // Open the current URL in Chromium + QProcess::startDetached(QLatin1String("chromium"), QStringList(hoveredLinkString)); +} + +void PrivacyWebEngineView::openWithFirefox() const +{ + // Open the current URL in Firefox. + QProcess::startDetached(QLatin1String("firefox-esr"), QStringList(hoveredLinkString)); } void PrivacyWebEngineView::removeCookieFromList(const QNetworkCookie &cookie) const @@ -320,5 +480,46 @@ void PrivacyWebEngineView::removeCookieFromList(const QNetworkCookie &cookie) co cookieListPointer->remove(cookie); // Update the cookies action. - emit updateCookiesAction(cookieListPointer->size()); + Q_EMIT numberOfCookiesChanged(cookieListPointer->size()); +} + +void PrivacyWebEngineView::saveHoveredLink(const QString &hoveredLink) +{ + // Save the hovered link. + hoveredLinkString = hoveredLink; +} + +void PrivacyWebEngineView::storeRequest(RequestStruct *requestStructPointer) +{ + // Store the request struct in the list. + requestsListPointer->append(requestStructPointer); + + // Track blocked requests. + if (requestStructPointer->dispositionInt == FilterListHelper::BLOCKED) + { + // Update the individual filter list block counters. + if (requestStructPointer->filterListTitle == QLatin1String("UltraPrivacy")) + ++blockedRequestsVector[ULTRAPRIVACY]; + else if (requestStructPointer->filterListTitle == QLatin1String("UltraList")) + ++blockedRequestsVector[ULTRALIST]; + else if (requestStructPointer->filterListTitle == QLatin1String("EasyPrivacy")) + ++blockedRequestsVector[EASYPRIVACY]; + else if (requestStructPointer->filterListTitle == QLatin1String("EasyList")) + ++blockedRequestsVector[EASYLIST]; + else if (requestStructPointer->filterListTitle == QLatin1String("Fanboy's Annoyance List")) + ++blockedRequestsVector[FANBOYS_ANNOYANCE_LIST]; + + // Update the total requests blocked counter. + ++blockedRequestsVector[TOTAL]; + + // Update the blocked requests action. + Q_EMIT(requestBlocked(blockedRequestsVector)); + } } + +void PrivacyWebEngineView::storeUpdatedUrl(const QUrl &newUrl) +{ + // Store the new URL string (which changes when a new page is loaded as the current URL text. This is important when loading a new tab from a link. + currentUrlText = newUrl.toString(); +} +