X-Git-Url: https://gitweb.stoutner.com/?p=PrivacyBrowserPC.git;a=blobdiff_plain;f=src%2Fwidgets%2FTabWidget.cpp;h=9e843ef306da564f362d7c5e434a0589b7dda21d;hp=2f4582a9b2e6943af0b7c32982823315ae400aa0;hb=refs%2Fheads%2Fmaster;hpb=7c6edb3608791950c6146ac242e2b6f493ca8e8c diff --git a/src/widgets/TabWidget.cpp b/src/widgets/TabWidget.cpp index 2f4582a..ce8978b 100644 --- a/src/widgets/TabWidget.cpp +++ b/src/widgets/TabWidget.cpp @@ -1,23 +1,24 @@ -/* - * Copyright 2022-2023 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 "DevToolsWebEngineView.h" #include "TabWidget.h" #include "Settings.h" #include "ui_AddTabWidget.h" @@ -127,11 +128,16 @@ TabWidget::~TabWidget() // Manually delete each WebEngine page. for (int i = 0; i < numberOfTabs; ++i) { - // Get the privacy WebEngine view. - PrivacyWebEngineView *privacyWebEngineViewPointer = qobject_cast(qTabWidgetPointer->widget(i)); + // Get the tab splitter widget. + QWidget *tabSplitterWidgetPointer = qTabWidgetPointer->widget(i); - // Deletion the WebEngine page to prevent the following error: `Release of profile requested but WebEnginePage still not deleted. Expect troubles !` + // Get the WebEngine views. + PrivacyWebEngineView *privacyWebEngineViewPointer = tabSplitterWidgetPointer->findChild(); + DevToolsWebEngineView *devToolsWebEngineViewPointer = tabSplitterWidgetPointer->findChild(); + + // Deletion the WebEngine pages to prevent the following error: `Release of profile requested but WebEnginePage still not deleted. Expect troubles !` delete privacyWebEngineViewPointer->page(); + delete devToolsWebEngineViewPointer->page(); } } @@ -171,25 +177,55 @@ void TabWidget::addFirstTab() qTabWidgetPointer->currentWidget()->setFocus(); } -PrivacyWebEngineView* TabWidget::addTab(const bool removeUrlLineEditFocus, const bool backgroundTab, const QString urlString) +PrivacyWebEngineView* TabWidget::addTab(const bool removeUrlLineEditFocus, const bool adjacent, const bool backgroundTab, const QString urlString) { - // Create a privacy WebEngine view. + // Create a splitter widget. + QSplitter *splitterPointer = new QSplitter(); + + // Set the splitter to be vertical. + splitterPointer->setOrientation(Qt::Vertical); + + // Set the splitter handle size. + splitterPointer->setHandleWidth(5); + + // Create the WebEngines. PrivacyWebEngineView *privacyWebEngineViewPointer = new PrivacyWebEngineView(); + DevToolsWebEngineView *devToolsWebEngineViewPointer = new DevToolsWebEngineView(); + + // Add the WebEngines to the splitter. + splitterPointer->addWidget(privacyWebEngineViewPointer); + splitterPointer->addWidget(devToolsWebEngineViewPointer); + + // Initialize the new tab index. + int newTabIndex = 0; // Add a new tab. - int newTabIndex = qTabWidgetPointer->addTab(privacyWebEngineViewPointer, i18nc("New tab label.", "New Tab")); + if (adjacent) // Add the new tab adjacent to the current tab. + newTabIndex = qTabWidgetPointer->insertTab((qTabWidgetPointer->currentIndex() + 1), splitterPointer, i18nc("New tab label.", "New Tab")); + else // Add the new tab at the end of the list. + newTabIndex = qTabWidgetPointer->addTab(splitterPointer, i18nc("New tab label.", "New Tab")); // Set the default tab icon. qTabWidgetPointer->setTabIcon(newTabIndex, defaultFavoriteIcon); - // Get handles for the WebEngine page and profile. + // Get handles for the WebEngine components. QWebEnginePage *webEnginePagePointer = privacyWebEngineViewPointer->page(); QWebEngineProfile *webEngineProfilePointer = webEnginePagePointer->profile(); - - // Get handles for the web engine elements. QWebEngineCookieStore *webEngineCookieStorePointer = webEngineProfilePointer->cookieStore(); QWebEngineSettings *webEngineSettingsPointer = webEnginePagePointer->settings(); + // Set the development tools WebEngine. + webEnginePagePointer->setDevToolsPage(devToolsWebEngineViewPointer->page()); + + // Initially hide the development tools WebEngine. + devToolsWebEngineViewPointer->setVisible(false); + + // Initially disable the development tools WebEngine. + webEnginePagePointer->setDevToolsPage(nullptr); + + // Disable JavaScript on the development tools WebEngine to prevent error messages from being written to the console. + devToolsWebEngineViewPointer->settings()->setAttribute(QWebEngineSettings::JavascriptEnabled, false); + // Update the URL line edit when the URL changes. connect(privacyWebEngineViewPointer, &PrivacyWebEngineView::urlChanged, [this, privacyWebEngineViewPointer] (const QUrl &newUrl) { @@ -197,33 +233,33 @@ PrivacyWebEngineView* TabWidget::addTab(const bool removeUrlLineEditFocus, const if (privacyWebEngineViewPointer == currentPrivacyWebEngineViewPointer) { // Update the URL line edit. - emit updateUrlLineEdit(newUrl); + Q_EMIT updateUrlLineEdit(newUrl); // Update the status of the forward and back buttons. - emit updateBackAction(currentWebEngineHistoryPointer->canGoBack()); - emit updateForwardAction(currentWebEngineHistoryPointer->canGoForward()); + Q_EMIT updateBackAction(currentWebEngineHistoryPointer->canGoBack()); + Q_EMIT updateForwardAction(currentWebEngineHistoryPointer->canGoForward()); } }); // Update the title when it changes. - connect(privacyWebEngineViewPointer, &PrivacyWebEngineView::titleChanged, [this, privacyWebEngineViewPointer] (const QString &title) + connect(privacyWebEngineViewPointer, &PrivacyWebEngineView::titleChanged, [this, splitterPointer] (const QString &title) { // Get the index for this tab. - int tabIndex = qTabWidgetPointer->indexOf(privacyWebEngineViewPointer); + int tabIndex = qTabWidgetPointer->indexOf(splitterPointer); // Update the title for this tab. qTabWidgetPointer->setTabText(tabIndex, title); // Update the window title if this is the current tab. if (tabIndex == qTabWidgetPointer->currentIndex()) - emit updateWindowTitle(title); + Q_EMIT updateWindowTitle(title); }); // Connect the loading favorite icon movie to the tab icon. - connect(loadingFavoriteIconMoviePointer, &QMovie::frameChanged, [this, privacyWebEngineViewPointer] + connect(loadingFavoriteIconMoviePointer, &QMovie::frameChanged, [this, splitterPointer, privacyWebEngineViewPointer] { // Get the index for this tab. - int tabIndex = qTabWidgetPointer->indexOf(privacyWebEngineViewPointer); + int tabIndex = qTabWidgetPointer->indexOf(splitterPointer); // Display the loading favorite icon if this tab is loading. if (privacyWebEngineViewPointer->isLoading) @@ -231,7 +267,7 @@ PrivacyWebEngineView* TabWidget::addTab(const bool removeUrlLineEditFocus, const }); // Update the icon when it changes. - connect(privacyWebEngineViewPointer, &PrivacyWebEngineView::iconChanged, [this, privacyWebEngineViewPointer] (const QIcon &newFavoriteIcon) + connect(privacyWebEngineViewPointer, &PrivacyWebEngineView::iconChanged, [this, splitterPointer, privacyWebEngineViewPointer] (const QIcon &newFavoriteIcon) { // Store the favorite icon in the privacy web engine view. if (newFavoriteIcon.isNull()) @@ -240,7 +276,7 @@ PrivacyWebEngineView* TabWidget::addTab(const bool removeUrlLineEditFocus, const privacyWebEngineViewPointer->favoriteIcon = newFavoriteIcon; // Get the index for this tab. - int tabIndex = qTabWidgetPointer->indexOf(privacyWebEngineViewPointer); + int tabIndex = qTabWidgetPointer->indexOf(splitterPointer); // Update the icon for this tab. if (newFavoriteIcon.isNull()) @@ -260,7 +296,7 @@ PrivacyWebEngineView* TabWidget::addTab(const bool removeUrlLineEditFocus, const // Show the progress bar if this is the current tab. if (privacyWebEngineViewPointer == currentPrivacyWebEngineViewPointer) - emit showProgressBar(0); + Q_EMIT showProgressBar(0); // Start the loading favorite icon movie. loadingFavoriteIconMoviePointer->start(); @@ -274,11 +310,11 @@ PrivacyWebEngineView* TabWidget::addTab(const bool removeUrlLineEditFocus, const // Update the progress bar if this is the current tab. if (privacyWebEngineViewPointer == currentPrivacyWebEngineViewPointer) - emit showProgressBar(progress); + Q_EMIT showProgressBar(progress); }); // Update the progress bar when a load finishes. - connect(privacyWebEngineViewPointer, &PrivacyWebEngineView::loadFinished, [this, privacyWebEngineViewPointer] () + connect(privacyWebEngineViewPointer, &PrivacyWebEngineView::loadFinished, [this, splitterPointer, privacyWebEngineViewPointer] () { // Set the privacy web engine view to be not loading. privacyWebEngineViewPointer->isLoading = false; @@ -288,10 +324,10 @@ PrivacyWebEngineView* TabWidget::addTab(const bool removeUrlLineEditFocus, const // Hide the progress bar if this is the current tab. if (privacyWebEngineViewPointer == currentPrivacyWebEngineViewPointer) - emit hideProgressBar(); + Q_EMIT hideProgressBar(); // Get the index for this tab. - int tabIndex = qTabWidgetPointer->indexOf(privacyWebEngineViewPointer); + int tabIndex = qTabWidgetPointer->indexOf(splitterPointer); // Display the current favorite icon qTabWidgetPointer->setTabIcon(tabIndex, privacyWebEngineViewPointer->favoriteIcon); @@ -306,7 +342,7 @@ PrivacyWebEngineView* TabWidget::addTab(const bool removeUrlLineEditFocus, const for (int i = 0; i < numberOfTabs; i++) { // Get the privacy WebEngine view for the tab. - PrivacyWebEngineView *privacyWebEngineViewPointer = qobject_cast(qTabWidgetPointer->widget(i)); + PrivacyWebEngineView *privacyWebEngineViewPointer = qTabWidgetPointer->widget(i)->findChild(); // Check to see if it is currently loading. If at least one tab is loading, this flag will end up being marked `false` when the for loop has finished. if (privacyWebEngineViewPointer->isLoading) @@ -344,12 +380,12 @@ PrivacyWebEngineView* TabWidget::addTab(const bool removeUrlLineEditFocus, const } }); - // Update the zoom actions when changed by CTRL-Scrolling. This can be modified when is fixed. - connect(webEnginePagePointer, &QWebEnginePage::contentsSizeChanged, [webEnginePagePointer, this] () + // Update the zoom actions when they are changed. + connect(webEnginePagePointer, &QWebEnginePage::zoomFactorChanged, [webEnginePagePointer, this] (const qreal newZoomFactor) { // Only update the zoom actions if this is the current tab. if (webEnginePagePointer == currentWebEnginePagePointer) - emit updateZoomActions(webEnginePagePointer->zoomFactor()); + Q_EMIT updateZoomActions(newZoomFactor); }); // Display find text results. @@ -362,13 +398,13 @@ PrivacyWebEngineView* TabWidget::addTab(const bool removeUrlLineEditFocus, const connect(webEnginePagePointer, SIGNAL(linkHovered(const QString)), this, SLOT(pageLinkHovered(const QString))); // Handle file downloads. - connect(webEngineProfilePointer, SIGNAL(downloadRequested(QWebEngineDownloadItem *)), this, SLOT(showSaveDialog(QWebEngineDownloadItem *))); + connect(webEngineProfilePointer, SIGNAL(downloadRequested(QWebEngineDownloadRequest *)), this, SLOT(showSaveDialog(QWebEngineDownloadRequest *))); // Set the local storage filter. webEngineCookieStorePointer->setCookieFilter([privacyWebEngineViewPointer](const QWebEngineCookieStore::FilterRequest &filterRequest) { // Block all third party local storage requests, including the sneaky ones that don't register a first party URL. - if (filterRequest.thirdParty || (filterRequest.firstPartyUrl == QStringLiteral(""))) + if (filterRequest.thirdParty || (filterRequest.firstPartyUrl == QUrl(QLatin1String("")))) { //qDebug().noquote().nospace() << "Third-party request blocked: " << filterRequest.origin; @@ -415,12 +451,23 @@ PrivacyWebEngineView* TabWidget::addTab(const bool removeUrlLineEditFocus, const // Plugins must be enabled for the PDF viewer to work. webEngineSettingsPointer->setAttribute(QWebEngineSettings::PluginsEnabled, true); + // Allow JavaScript to paste to (but not copy from) the clipboard, but only with user interaction. + webEngineSettingsPointer->setAttribute(QWebEngineSettings::JavascriptCanAccessClipboard, true); + + // Update the blocked requests action. + connect(privacyWebEngineViewPointer, &PrivacyWebEngineView::requestBlocked, [this, privacyWebEngineViewPointer] (const QVector blockedRequestsVector) + { + // Update the blocked requests action if the specified privacy WebEngine view is the current privacy WebEngine view. + if (privacyWebEngineViewPointer == currentPrivacyWebEngineViewPointer) + Q_EMIT blockedRequestsUpdated(blockedRequestsVector); + }); + // Update the cookies action. - connect(privacyWebEngineViewPointer, &PrivacyWebEngineView::updateCookiesAction, [this, privacyWebEngineViewPointer] (const int numberOfCookies) + connect(privacyWebEngineViewPointer, &PrivacyWebEngineView::numberOfCookiesChanged, [this, privacyWebEngineViewPointer] (const int numberOfCookies) { // Update the cookie action if the specified privacy WebEngine view is the current privacy WebEngine view. if (privacyWebEngineViewPointer == currentPrivacyWebEngineViewPointer) - emit updateCookiesAction(numberOfCookies); + Q_EMIT cookiesChanged(numberOfCookies); }); // Process cookie changes. @@ -452,9 +499,10 @@ PrivacyWebEngineView* TabWidget::addTab(const bool removeUrlLineEditFocus, const // Clear the URL line edit focus so that it populates correctly when opening a new tab from the context menu. if (removeUrlLineEditFocus) - emit clearUrlLineEditFocus(); + Q_EMIT clearUrlLineEditFocus(); - if (urlString != nullptr) + // Load the URL if it isn't blank. + if (urlString != QLatin1String("")) privacyWebEngineViewPointer->load(QUrl::fromUserInput(urlString)); // Return the privacy WebEngine view pointer. @@ -475,7 +523,7 @@ void TabWidget::applyApplicationSettings() // Apply the spatial navigation settings to each WebEngine. for (int i = 0; i < numberOfTabs; ++i) { // Get the WebEngine view pointer. - PrivacyWebEngineView *privacyWebEngineViewPointer = qobject_cast(qTabWidgetPointer->widget(i)); + PrivacyWebEngineView *privacyWebEngineViewPointer = qTabWidgetPointer->widget(i)->findChild(); // Apply the spatial navigation settings to each page. privacyWebEngineViewPointer->page()->settings()->setAttribute(QWebEngineSettings::SpatialNavigationEnabled, Settings::spatialNavigation()); @@ -485,7 +533,7 @@ void TabWidget::applyApplicationSettings() searchEngineUrl = SearchEngineHelper::getSearchUrl(Settings::searchEngine()); // Emit the update search engine actions signal. - emit updateSearchEngineActions(Settings::searchEngine(), true); + Q_EMIT updateSearchEngineActions(Settings::searchEngine(), true); } void TabWidget::applyDomainSettingsAndReload() @@ -496,10 +544,10 @@ void TabWidget::applyDomainSettingsAndReload() // Apply the domain settings to each WebEngine. for (int i = 0; i < numberOfTabs; ++i) { // Get the WebEngine view pointer. - PrivacyWebEngineView *privacyWebEngineViewPointer = qobject_cast(qTabWidgetPointer->widget(i)); + PrivacyWebEngineView *privacyWebEngineViewPointer = qTabWidgetPointer->widget(i)->findChild(); - // Apply the spatial navigation settings to each page. - privacyWebEngineViewPointer->applyDomainSettings(privacyWebEngineViewPointer->url().host(), true); + // Apply the domain settings settings to each page. `false` indicates that history is not being navigated. + privacyWebEngineViewPointer->applyDomainSettings(privacyWebEngineViewPointer->url(), false); } } @@ -509,13 +557,13 @@ void TabWidget::applyOnTheFlySearchEngine(QAction *searchEngineActionPointer) QString searchEngineName = searchEngineActionPointer->text(); // Strip out any `&` characters. - searchEngineName.remove('&'); + searchEngineName.remove(QLatin1Char('&')); // Store the search engine string. searchEngineUrl = SearchEngineHelper::getSearchUrl(searchEngineName); // Update the search engine actions. - emit updateSearchEngineActions(searchEngineName, false); + Q_EMIT updateSearchEngineActions(searchEngineName, false); } void TabWidget::applyOnTheFlyUserAgent(QAction *userAgentActionPointer) const @@ -524,22 +572,22 @@ void TabWidget::applyOnTheFlyUserAgent(QAction *userAgentActionPointer) const QString userAgentName = userAgentActionPointer->text(); // Strip out any `&` characters. - userAgentName.remove('&'); + userAgentName.remove(QLatin1Char('&')); // Apply the user agent. currentWebEngineProfilePointer->setHttpUserAgent(userAgentHelperPointer->getUserAgentFromTranslatedName(userAgentName)); // Update the user agent actions. - emit updateUserAgentActions(currentWebEngineProfilePointer->httpUserAgent(), false); + Q_EMIT updateUserAgentActions(currentWebEngineProfilePointer->httpUserAgent(), false); // Reload the website. currentPrivacyWebEngineViewPointer->reload(); } -void TabWidget::applyOnTheFlyZoomFactor(const double &zoomFactor) const +void TabWidget::applyOnTheFlyZoomFactor(const double zoomFactorDouble) const { // Set the zoom factor. - currentPrivacyWebEngineViewPointer->setZoomFactor(zoomFactor); + currentPrivacyWebEngineViewPointer->setZoomFactor(zoomFactorDouble); } void TabWidget::applySpellCheckLanguages() const @@ -551,7 +599,7 @@ void TabWidget::applySpellCheckLanguages() const for (int i = 0; i < numberOfTabs; ++i) { // Get the WebEngine view pointer. - PrivacyWebEngineView *privacyWebEngineViewPointer = qobject_cast(qTabWidgetPointer->widget(i)); + PrivacyWebEngineView *privacyWebEngineViewPointer = qTabWidgetPointer->widget(i)->findChild(); // Get the WebEngine page pointer. QWebEnginePage *webEnginePagePointer = privacyWebEngineViewPointer->page(); @@ -584,20 +632,29 @@ void TabWidget::deleteCookieFromStore(const QNetworkCookie &cookie) const void TabWidget::deleteTab(const int tabIndex) { - // Get the privacy WebEngine view. - PrivacyWebEngineView *privacyWebEngineViewPointer = qobject_cast(qTabWidgetPointer->widget(tabIndex)); + // Get the tab splitter widget. + QWidget *tabSplitterWidgetPointer = qTabWidgetPointer->widget(tabIndex); + + // Get the WebEngine views. + PrivacyWebEngineView *privacyWebEngineViewPointer = tabSplitterWidgetPointer->findChild(); + DevToolsWebEngineView *devToolsWebEngineViewPointer = tabSplitterWidgetPointer->findChild(); // Process the tab delete according to the number of tabs. if (qTabWidgetPointer->count() > 1) // There is more than one tab. { - // Delete the tab. + // Remove the tab. qTabWidgetPointer->removeTab(tabIndex); - // Delete the WebEngine page to prevent the following error: `Release of profile requested but WebEnginePage still not deleted. Expect troubles !` + // Delete the WebEngine pages to prevent the following error: `Release of profile requested but WebEnginePage still not deleted. Expect troubles !` delete privacyWebEngineViewPointer->page(); + delete devToolsWebEngineViewPointer->page(); - // Delete the privacy WebEngine view. + // Delete the WebEngine views. delete privacyWebEngineViewPointer; + delete devToolsWebEngineViewPointer; + + // Delete the tab splitter widget. + delete tabSplitterWidgetPointer; } else // There is only one tab. { @@ -648,7 +705,7 @@ void TabWidget::findTextFinished(const QWebEngineFindTextResult &findTextResult) currentPrivacyWebEngineViewPointer->findTextResult = findTextResult; // Update the UI. - emit updateFindTextResults(findTextResult); + Q_EMIT updateFindTextResults(findTextResult); } } @@ -661,7 +718,7 @@ void TabWidget::forward() const void TabWidget::fullScreenRequested(QWebEngineFullScreenRequest fullScreenRequest) const { // Make it so. - emit fullScreenRequested(fullScreenRequest.toggleOn()); + Q_EMIT fullScreenRequested(fullScreenRequest.toggleOn()); // Accept the request. fullScreenRequest.accept(); @@ -691,6 +748,12 @@ QString TabWidget::getCurrentTabUrl() const return currentPrivacyWebEngineViewPointer->url().toString(); } +QString TabWidget::getCurrentUserAgent() const +{ + // Return the current WebEngine user agent. + return currentWebEngineProfilePointer->httpUserAgent(); +} + QString& TabWidget::getDomainSettingsName() const { // Return the domain settings name. @@ -736,18 +799,18 @@ void TabWidget::loadInitialWebsite() void TabWidget::loadUrlFromLineEdit(QString url) const { // Decide if the text is more likely to be a URL or a search. - if (url.startsWith("file://") || url.startsWith("view-source:")) // The text is likely a file or view source URL. + if (url.startsWith(QLatin1String("file://")) || url.startsWith(QLatin1String("view-source:"))) // The text is likely a file or view source URL. { // Load the URL. currentPrivacyWebEngineViewPointer->load(QUrl::fromUserInput(url)); } - else if (url.contains(".")) // The text is likely a URL. + else if (url.contains(QLatin1String("."))) // The text is likely a URL. { // Check if the URL does not start with a valid protocol. - if (!url.startsWith("http")) + if (!url.startsWith(QLatin1String("http"))) { // Add `https://` to the beginning of the URL. - url = "https://" + url; + url = QLatin1String("https://") + url; } // Load the URL. @@ -766,7 +829,7 @@ void TabWidget::mouseBack() const if (currentPrivacyWebEngineViewPointer->isActiveWindow() && currentWebEngineHistoryPointer->canGoBack()) { // Clear the URL line edit focus. - emit clearUrlLineEditFocus(); + Q_EMIT clearUrlLineEditFocus(); // Go back. currentPrivacyWebEngineViewPointer->back(); @@ -779,7 +842,7 @@ void TabWidget::mouseForward() const if (currentPrivacyWebEngineViewPointer->isActiveWindow() && currentWebEngineHistoryPointer->canGoForward()) { // Clear the URL line edit focus. - emit clearUrlLineEditFocus(); + Q_EMIT clearUrlLineEditFocus(); // Go forward. currentPrivacyWebEngineViewPointer->forward(); @@ -789,7 +852,7 @@ void TabWidget::mouseForward() const void TabWidget::pageLinkHovered(const QString &linkUrl) const { // Emit a signal so that the browser window can update the status bar. - emit linkHovered(linkUrl); + Q_EMIT linkHovered(linkUrl); } void TabWidget::stopLoadingFavoriteIconMovie() const @@ -801,59 +864,57 @@ void TabWidget::stopLoadingFavoriteIconMovie() const void TabWidget::print() const { // Create a printer. - QPrinter printer; + QPrinter *printerPointer = new QPrinter(); // Set the resolution to be 300 dpi. - printer.setResolution(300); + printerPointer->setResolution(300); // Create a printer dialog. - QPrintDialog printDialog(&printer, currentPrivacyWebEngineViewPointer); + QPrintDialog printDialog(printerPointer, currentPrivacyWebEngineViewPointer); // Display the dialog and print the page if instructed. if (printDialog.exec() == QDialog::Accepted) - printWebpage(&printer); + currentPrivacyWebEngineViewPointer->print(printerPointer); } void TabWidget::printPreview() const { // Create a printer. - QPrinter printer; + QPrinter *printerPointer = new QPrinter(); // Set the resolution to be 300 dpi. - printer.setResolution(300); + printerPointer->setResolution(300); // Create a print preview dialog. - QPrintPreviewDialog printPreviewDialog(&printer, currentPrivacyWebEngineViewPointer); + QPrintPreviewDialog printPreviewDialog(printerPointer, currentPrivacyWebEngineViewPointer); // Generate the print preview. - connect(&printPreviewDialog, SIGNAL(paintRequested(QPrinter *)), this, SLOT(printWebpage(QPrinter *))); + auto generatePrintPreview = [this, printerPointer](){ + // Create an event loop. The print preview must be generated in a loop or nothing is displayed. + QEventLoop eventLoop; - // Display the dialog. - printPreviewDialog.exec(); -} + // Quit the event loop once the print preview has been generated. + connect(currentPrivacyWebEngineViewPointer, &QWebEngineView::printFinished, &eventLoop, &QEventLoop::quit); -void TabWidget::printWebpage(QPrinter *printerPointer) const -{ - // Create an event loop. For some reason, the print preview doesn't produce any output unless it is run inside an event loop. - QEventLoop eventLoop; + // Generate the print preview for the current webpage. + currentPrivacyWebEngineViewPointer->print(printerPointer); - // Print the webpage, converting the callback above into a `QWebEngineCallback`. - // Printing requires that the printer be a pointer, not a reference, or it will crash with much cursing. - currentWebEnginePagePointer->print(printerPointer, [&eventLoop](bool printSuccess) - { - // Instruct the compiler to ignore the unused parameter. - (void) printSuccess; + // Execute the loop. + eventLoop.exec(); + }; - // Quit the loop. - eventLoop.quit(); - }); + // Generate the preview. + connect(&printPreviewDialog, &QPrintPreviewDialog::paintRequested, this, generatePrintPreview); - // Execute the loop. - eventLoop.exec(); + // Display the dialog. + printPreviewDialog.exec(); } void TabWidget::refresh() const { + // Reset the HTTP authentication dialog counter. + currentPrivacyWebEngineViewPointer->httpAuthenticationDialogsDisplayed = 0; + // Reload the website. currentPrivacyWebEngineViewPointer->reload(); } @@ -864,6 +925,35 @@ void TabWidget::reloadAndBypassCache() const currentWebEnginePagePointer->triggerAction(QWebEnginePage::ReloadAndBypassCache); } +void TabWidget::saveArchive() +{ + // Get the suggested file name. + QString suggestedFileName = currentPrivacyWebEngineViewPointer->title() + QLatin1String(".mht"); + + // Get the download directory. + QString downloadDirectory = Settings::downloadDirectory(); + + // Resolve the system download directory if specified. + if (downloadDirectory == QLatin1String("System Download Directory")) + downloadDirectory = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation); + + // Get a file path from the file picker. + QString saveFilePath = QFileDialog::getSaveFileName(this, i18nc("Save file dialog caption", "Save File"), downloadDirectory + QLatin1Char('/') + suggestedFileName); + + // Save the webpage as an archive if the file save path is populated. + if (!saveFilePath.isEmpty()) + { + // Update the download directory if specified. + if (Settings::autoUpateDownloadDirectory()) + updateDownloadDirectory(saveFilePath); + + // Set the saving archive flag. Otherwise, a second download tries to run. + savingArchive = true; + + // Save the archive. + currentWebEnginePagePointer->save(saveFilePath); + } +} void TabWidget::setTabBarVisible(const bool visible) const { @@ -871,164 +961,232 @@ void TabWidget::setTabBarVisible(const bool visible) const qTabWidgetPointer->tabBar()->setVisible(visible); } -void TabWidget::showSaveDialog(QWebEngineDownloadItem *webEngineDownloadItemPointer) +void TabWidget::showSaveDialog(QWebEngineDownloadRequest *webEngineDownloadRequestPointer) { - // Get the download attributes. - QUrl downloadUrl = webEngineDownloadItemPointer->url(); - QString mimeTypeString = webEngineDownloadItemPointer->mimeType(); - QString suggestedFileName = webEngineDownloadItemPointer->suggestedFileName(); - int totalBytes = webEngineDownloadItemPointer->totalBytes(); - - // Check to see if Privacy Browser is not running KDE or if local storage (cookies) is enabled. - if (!isRunningKde || currentPrivacyWebEngineViewPointer->localStorageEnabled) // KDE is not running or local storage (cookies) is enabled. Use WebEngine's downloader. + // Only show the save dialog if an archive is not currently being saved. Otherwise, two save dialogs will be shown. + if (!savingArchive) { - // Instantiate the save dialog. - SaveDialog *saveDialogPointer = new SaveDialog(downloadUrl, mimeTypeString, totalBytes); + // Get the download attributes. + QUrl downloadUrl = webEngineDownloadRequestPointer->url(); + QString mimeTypeString = webEngineDownloadRequestPointer->mimeType(); + QString suggestedFileName = webEngineDownloadRequestPointer->suggestedFileName(); + int totalBytes = webEngineDownloadRequestPointer->totalBytes(); + + // Check to see if Privacy Browser is not running KDE or if local storage (cookies) is enabled. + if (!isRunningKde || currentPrivacyWebEngineViewPointer->localStorageEnabled) // KDE is not running or local storage (cookies) is enabled. Use WebEngine's downloader. + { + // Instantiate the save dialog. + SaveDialog *saveDialogPointer = new SaveDialog(this, downloadUrl, mimeTypeString, totalBytes); - // Display the save dialog. - int saveDialogResult = saveDialogPointer->exec(); + // Display the save dialog. + int saveDialogResult = saveDialogPointer->exec(); - // Process the save dialog results. - if (saveDialogResult == QDialog::Accepted) // Save was selected. - { - // Get the download directory. - QString downloadDirectory = Settings::downloadLocation(); + // Process the save dialog results. + if (saveDialogResult == QDialog::Accepted) // Save was selected. + { + // Get the download directory. + QString downloadDirectory = Settings::downloadDirectory(); - // 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 == QLatin1String("System Download Directory")) + downloadDirectory = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation); - // Get a file path from the file picker. - QString saveFilePath = QFileDialog::getSaveFileName(this, i18nc("Save file dialog caption", "Save File"), downloadDirectory + QLatin1Char('/') + suggestedFileName); + // Get a file path from the file picker. + QString saveFilePath = QFileDialog::getSaveFileName(this, i18nc("Save file dialog caption", "Save File"), downloadDirectory + QLatin1Char('/') + suggestedFileName); - // 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); + // Process the save file path. + if (!saveFilePath.isEmpty()) // The file save path is populated. + { + // Update the download directory if specified. + if (Settings::autoUpateDownloadDirectory()) + updateDownloadDirectory(saveFilePath); - // Get the canonical save path and file name. - QString absoluteSavePath = saveFilePathFileInfo.absolutePath(); - QString saveFileName = saveFilePathFileInfo.fileName(); + // Create a save file path file info. + QFileInfo saveFilePathFileInfo = QFileInfo(saveFilePath); - // Set the download directory and file name. - webEngineDownloadItemPointer->setDownloadDirectory(absoluteSavePath); - webEngineDownloadItemPointer->setDownloadFileName(saveFileName); + // Get the canonical save path and file name. + QString absoluteSavePath = saveFilePathFileInfo.absolutePath(); + QString saveFileName = saveFilePathFileInfo.fileName(); - // Create a file download notification. - KNotification *fileDownloadNotificationPointer = new KNotification(QLatin1String("FileDownload")); + // Set the download directory and file name. + webEngineDownloadRequestPointer->setDownloadDirectory(absoluteSavePath); + webEngineDownloadRequestPointer->setDownloadFileName(saveFileName); - // Set the notification title. - fileDownloadNotificationPointer->setTitle(i18nc("Download notification title", "Download")); + // Create a file download notification. + KNotification *fileDownloadNotificationPointer = new KNotification(QLatin1String("FileDownload")); - // Set the notification text. - fileDownloadNotificationPointer->setText(i18nc("Downloading notification text", "Downloading %1", saveFileName)); + // Set the notification title. + fileDownloadNotificationPointer->setTitle(i18nc("Download notification title", "Download")); - // Get the download icon from the theme. - QIcon downloadIcon = QIcon::fromTheme(QLatin1String("download"), QIcon::fromTheme(QLatin1String("document-save"))); + // Set the notification text. + fileDownloadNotificationPointer->setText(i18nc("Downloading notification text", "Downloading %1", saveFileName)); - // Set the notification icon. - fileDownloadNotificationPointer->setIconName(downloadIcon.name()); + // Get the download icon from the theme. + QIcon downloadIcon = QIcon::fromTheme(QLatin1String("download"), QIcon::fromTheme(QLatin1String("document-save"))); - // Set the action list cancel button. - fileDownloadNotificationPointer->setActions(QStringList({i18nc("Download notification action","Cancel")})); + // Set the notification icon. + fileDownloadNotificationPointer->setIconName(downloadIcon.name()); - // Prevent the notification from being autodeleted if it is closed. Otherwise, the updates to the notification below cause a crash. - fileDownloadNotificationPointer->setAutoDelete(false); + // Add the cancel action. + KNotificationAction *cancelActionPointer = fileDownloadNotificationPointer->addDefaultAction(i18nc("Download notification action","Cancel")); - // Display the notification. - fileDownloadNotificationPointer->sendEvent(); + // Prevent the notification from being autodeleted if it is closed. Otherwise, the updates to the notification below cause a crash. + fileDownloadNotificationPointer->setAutoDelete(false); - // Handle clicks on the cancel button. - connect(fileDownloadNotificationPointer, &KNotification::action1Activated, [webEngineDownloadItemPointer, saveFileName] () - { - // Cancel the download. - webEngineDownloadItemPointer->cancel(); + // Handle clicks on the cancel action. + connect(cancelActionPointer, &KNotificationAction::activated, [webEngineDownloadRequestPointer, saveFileName] () + { + // Cancel the download. + webEngineDownloadRequestPointer->cancel(); - // Create a file download notification. - KNotification *canceledDownloadNotificationPointer = new KNotification(QLatin1String("FileDownload")); + // Create a file download notification. + KNotification *canceledDownloadNotificationPointer = new KNotification(QLatin1String("FileDownload")); - // Set the notification title. - canceledDownloadNotificationPointer->setTitle(i18nc("Download notification title", "Download")); + // 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 new text. + canceledDownloadNotificationPointer->setText(i18nc("Download canceled notification", "%1 download canceled", saveFileName)); - // Set the notification icon. - canceledDownloadNotificationPointer->setIconName(QLatin1String("download")); + // Set the notification icon. + canceledDownloadNotificationPointer->setIconName(QLatin1String("download")); - // Display the notification. - canceledDownloadNotificationPointer->sendEvent(); - }); + // Display the notification. + canceledDownloadNotificationPointer->sendEvent(); + }); - // Update the notification when the download progresses. - connect(webEngineDownloadItemPointer, &QWebEngineDownloadItem::downloadProgress, [fileDownloadNotificationPointer, saveFileName] (qint64 bytesReceived, qint64 totalBytes) - { - // Set the new text. Total bytes will be 0 if the download size is unknown. - if (totalBytes > 0) + // Update the notification when the download progresses. + connect(webEngineDownloadRequestPointer, &QWebEngineDownloadRequest::receivedBytesChanged, [webEngineDownloadRequestPointer, fileDownloadNotificationPointer, saveFileName] () { - // Calculate the download percentage. - int downloadPercentage = 100 * bytesReceived / totalBytes; - - // Set the file download notification text. - fileDownloadNotificationPointer->setText(i18nc("Download progress notification text", "%1\% of %2 downloaded (%3 of %4 bytes)", downloadPercentage, saveFileName, - bytesReceived, totalBytes)); - } - else + // Get the download request information. + qint64 receivedBytes = webEngineDownloadRequestPointer->receivedBytes(); + qint64 totalBytes = webEngineDownloadRequestPointer->totalBytes(); + + // Set the new text. Total bytes will be 0 if the download size is unknown. + if (totalBytes > 0) + { + // Calculate the download percentage. + int downloadPercentage = 100 * receivedBytes / totalBytes; + + // Set the file download notification text. + fileDownloadNotificationPointer->setText(i18nc("Download progress notification text", "%1%% of %2 downloaded (%3 of %4 bytes)", downloadPercentage, saveFileName, + receivedBytes, totalBytes)); + } + else + { + // Set the file download notification text. + fileDownloadNotificationPointer->setText(i18nc("Download progress notification text", "%1: %2 bytes downloaded", saveFileName, receivedBytes)); + } + + // Display the updated notification. + fileDownloadNotificationPointer->sendEvent(); + }); + + // Update the notification when the download finishes. The save file name must be copied into the lambda or a crash occurs. + connect(webEngineDownloadRequestPointer, &QWebEngineDownloadRequest::isFinishedChanged, [webEngineDownloadRequestPointer, fileDownloadNotificationPointer, saveFileName, + saveFilePath] () { - // Set the file download notification text. - fileDownloadNotificationPointer->setText(i18nc("Download progress notification text", "%1: %2 bytes downloaded", saveFileName, bytesReceived)); - } + // Update the notification if the download is finished. + if (webEngineDownloadRequestPointer->isFinished()) + { + // Set the new text. + fileDownloadNotificationPointer->setText(i18nc("Download finished notification text", "%1 download finished", saveFileName)); - // Display the updated notification. - fileDownloadNotificationPointer->update(); - }); + // Set the URL so the file options will be displayed. + fileDownloadNotificationPointer->setUrls(QList {QUrl(saveFilePath)}); - // 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(saveFilePath)}); + // Remove the actions from the notification. + fileDownloadNotificationPointer->clearActions(); - // Remove the actions from the notification. - fileDownloadNotificationPointer->setActions(QStringList()); + // Set the notification to disappear after a timeout. + fileDownloadNotificationPointer->setFlags(KNotification::CloseOnTimeout); - // Set the notification to disappear after a timeout. - fileDownloadNotificationPointer->setFlags(KNotification::CloseOnTimeout); + // Display the updated notification. + fileDownloadNotificationPointer->sendEvent(); + } + }); - // Display the updated notification. - fileDownloadNotificationPointer->update(); - }); + // Display the notification. + fileDownloadNotificationPointer->sendEvent(); - // Start the download. - webEngineDownloadItemPointer->accept(); + // Start the download. + webEngineDownloadRequestPointer->accept(); + } + else // The file save path is not populated. + { + // Cancel the download. + webEngineDownloadRequestPointer->cancel(); + } } - else // The file save path is not populated. + else // Cancel was selected. { // Cancel the download. - webEngineDownloadItemPointer->cancel(); + webEngineDownloadRequestPointer->cancel(); } } - else // Cancel was selected. + else // KDE is running and 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. { - // Cancel the download. - webEngineDownloadItemPointer->cancel(); + // Instantiate the save dialog. `true` instructs it to use the native downloader + SaveDialog *saveDialogPointer = new SaveDialog(this, downloadUrl, mimeTypeString, totalBytes, suggestedFileName, true); + + // Connect the save button. + connect(saveDialogPointer, SIGNAL(useNativeKdeDownloader(QUrl &, QString &)), this, SLOT(useNativeKdeDownloader(QUrl &, QString &))); + + // Show the dialog. + saveDialogPointer->show(); } } - else // KDE is running and 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. + + // Reset the saving archive flag. + savingArchive = false; +} + +void TabWidget::stop() const +{ + // Stop the loading of the current privacy WebEngine. + currentPrivacyWebEngineViewPointer->stop(); +} + +void TabWidget::storeCurrentUrlText(const QString &urlText) const +{ + // Store the current URL text in the privacy WebEngine view. + currentPrivacyWebEngineViewPointer->currentUrlText = urlText; +} + +void TabWidget::toggleDeveloperTools(const bool enabled) const +{ + // Get handles for the current tab widgets. + QSplitter *splitterPointer = qobject_cast(qTabWidgetPointer->currentWidget()); + DevToolsWebEngineView *devToolsWebEngineViewPointer = splitterPointer->findChild(); + + if (enabled) { - // Instantiate the save dialog. `true` instructs it to use the native downloader - SaveDialog *saveDialogPointer = new SaveDialog(downloadUrl, mimeTypeString, totalBytes, suggestedFileName, true); + // Set the zoom factor on the development tools WebEngine. + devToolsWebEngineViewPointer->setZoomFactor(currentWebEnginePagePointer->zoomFactor()); + + // Enable the development tools. + currentWebEnginePagePointer->setDevToolsPage(devToolsWebEngineViewPointer->page()); - // Connect the save button. - connect(saveDialogPointer, SIGNAL(useNativeKdeDownloader(QUrl &, QString &)), this, SLOT(useNativeKdeDownloader(QUrl &, QString &))); + // Enable JavaScript on the development tools WebEngine. + devToolsWebEngineViewPointer->settings()->setAttribute(QWebEngineSettings::JavascriptEnabled, true); - // Show the dialog. - saveDialogPointer->show(); + // Display the developer tools. + devToolsWebEngineViewPointer->setVisible(true); + + // Split the visible space equally between the main WebEngine and the developer tools WebEngine. + splitterPointer->setSizes(QList({1, 1})); + } + else + { + // Disable JavaScript on the development tools WebEngine to prevent error messages from being written to the console. + devToolsWebEngineViewPointer->settings()->setAttribute(QWebEngineSettings::JavascriptEnabled, false); + + // Disable the development tools. + currentWebEnginePagePointer->setDevToolsPage(nullptr); + + // Hide the developer tools. + devToolsWebEngineViewPointer->setVisible(false); } } @@ -1038,7 +1196,34 @@ void TabWidget::toggleDomStorage() const currentWebEngineSettingsPointer->setAttribute(QWebEngineSettings::LocalStorageEnabled, !currentWebEngineSettingsPointer->testAttribute(QWebEngineSettings::LocalStorageEnabled)); // Update the DOM storage action. - emit updateDomStorageAction(currentWebEngineSettingsPointer->testAttribute(QWebEngineSettings::LocalStorageEnabled)); + Q_EMIT updateDomStorageAction(currentWebEngineSettingsPointer->testAttribute(QWebEngineSettings::LocalStorageEnabled)); + + // Reload the website. + currentPrivacyWebEngineViewPointer->reload(); +} + +void TabWidget::toggleEasyList() const +{ + // Toggle EasyList. + currentPrivacyWebEngineViewPointer->easyListEnabled = !currentPrivacyWebEngineViewPointer->easyListEnabled; + + // Reload the website. + currentPrivacyWebEngineViewPointer->reload(); +} + +void TabWidget::toggleEasyPrivacy() const +{ + // Toggle EasyPrivacy. + currentPrivacyWebEngineViewPointer->easyPrivacyEnabled = !currentPrivacyWebEngineViewPointer->easyPrivacyEnabled; + + // Reload the website. + currentPrivacyWebEngineViewPointer->reload(); +} + +void TabWidget::toggleFanboysAnnoyanceList() const +{ + // Toggle Fanboy's Annoyance List. + currentPrivacyWebEngineViewPointer->fanboysAnnoyanceListEnabled = !currentPrivacyWebEngineViewPointer->fanboysAnnoyanceListEnabled; // Reload the website. currentPrivacyWebEngineViewPointer->reload(); @@ -1065,7 +1250,7 @@ void TabWidget::toggleJavaScript() const currentWebEngineSettingsPointer->setAttribute(QWebEngineSettings::JavascriptEnabled, !currentWebEngineSettingsPointer->testAttribute(QWebEngineSettings::JavascriptEnabled)); // Update the JavaScript action. - emit updateJavaScriptAction(currentWebEngineSettingsPointer->testAttribute(QWebEngineSettings::JavascriptEnabled)); + Q_EMIT updateJavaScriptAction(currentWebEngineSettingsPointer->testAttribute(QWebEngineSettings::JavascriptEnabled)); // Reload the website. currentPrivacyWebEngineViewPointer->reload(); @@ -1077,72 +1262,120 @@ void TabWidget::toggleLocalStorage() currentPrivacyWebEngineViewPointer->localStorageEnabled = !currentPrivacyWebEngineViewPointer->localStorageEnabled; // Update the local storage action. - emit updateLocalStorageAction(currentPrivacyWebEngineViewPointer->localStorageEnabled); + Q_EMIT updateLocalStorageAction(currentPrivacyWebEngineViewPointer->localStorageEnabled); // Reload the website. currentPrivacyWebEngineViewPointer->reload(); } +void TabWidget::toggleUltraList() const +{ + // Toggle UltraList. + currentPrivacyWebEngineViewPointer->ultraListEnabled = !currentPrivacyWebEngineViewPointer->ultraListEnabled; + + // Reload the website. + currentPrivacyWebEngineViewPointer->reload(); +} + +void TabWidget::toggleUltraPrivacy() const +{ + // Toggle UltraPrivacy. + currentPrivacyWebEngineViewPointer->ultraPrivacyEnabled = !currentPrivacyWebEngineViewPointer->ultraPrivacyEnabled; + + // Reload the website. + currentPrivacyWebEngineViewPointer->reload(); +} + +void TabWidget::updateDownloadDirectory(QString newDownloadDirectory) const +{ + // Remove the file name from the save file path. + newDownloadDirectory.truncate(newDownloadDirectory.lastIndexOf(QLatin1Char('/'))); + + // Update the download location. + Settings::setDownloadDirectory(newDownloadDirectory); + + // Get a handle for the KConfig skeleton. + KConfigSkeleton *kConfigSkeletonPointer = Settings::self(); + + // Write the settings to disk. + kConfigSkeletonPointer->save(); +} + void TabWidget::updateUiFromWebEngineView(const PrivacyWebEngineView *privacyWebEngineViewPointer) const { // Only update the UI if the signal was emitted from the current privacy WebEngine. if (privacyWebEngineViewPointer == currentPrivacyWebEngineViewPointer) { // Update the UI. - emit updateDefaultZoomFactor(currentPrivacyWebEngineViewPointer->defaultZoomFactor); - emit updateDomainSettingsIndicator(currentPrivacyWebEngineViewPointer->domainSettingsName != QLatin1String("")); - emit updateJavaScriptAction(currentWebEngineSettingsPointer->testAttribute(QWebEngineSettings::JavascriptEnabled)); - emit updateLocalStorageAction(currentPrivacyWebEngineViewPointer->localStorageEnabled); - emit updateDomStorageAction(currentWebEngineSettingsPointer->testAttribute(QWebEngineSettings::LocalStorageEnabled)); - emit updateUserAgentActions(currentWebEngineProfilePointer->httpUserAgent(), true); - emit updateZoomActions(currentPrivacyWebEngineViewPointer->zoomFactor()); + Q_EMIT easyListStatusChanged(currentPrivacyWebEngineViewPointer->easyListEnabled); + Q_EMIT easyPrivacyStatusChanged(currentPrivacyWebEngineViewPointer->easyPrivacyEnabled); + Q_EMIT fanboysAnnoyanceListStatusChanged(currentPrivacyWebEngineViewPointer->fanboysAnnoyanceListEnabled); + Q_EMIT ultraListStatusChanged(currentPrivacyWebEngineViewPointer->ultraListEnabled); + Q_EMIT ultraPrivacyStatusChanged(currentPrivacyWebEngineViewPointer->ultraPrivacyEnabled); + Q_EMIT updateDefaultZoomFactor(currentPrivacyWebEngineViewPointer->defaultZoomFactor); + Q_EMIT updateDomainSettingsIndicator(currentPrivacyWebEngineViewPointer->domainSettingsName != QLatin1String("")); + Q_EMIT updateJavaScriptAction(currentWebEngineSettingsPointer->testAttribute(QWebEngineSettings::JavascriptEnabled)); + Q_EMIT updateLocalStorageAction(currentPrivacyWebEngineViewPointer->localStorageEnabled); + Q_EMIT updateDomStorageAction(currentWebEngineSettingsPointer->testAttribute(QWebEngineSettings::LocalStorageEnabled)); + Q_EMIT updateUserAgentActions(currentWebEngineProfilePointer->httpUserAgent(), true); + Q_EMIT updateZoomActions(currentPrivacyWebEngineViewPointer->zoomFactor()); } } void TabWidget::updateUiWithTabSettings() { + // Clear the URL line edit focus. + Q_EMIT clearUrlLineEditFocus(); + // Update the current WebEngine pointers. - currentPrivacyWebEngineViewPointer = qobject_cast(qTabWidgetPointer->currentWidget()); + currentPrivacyWebEngineViewPointer = qTabWidgetPointer->currentWidget()->findChild(); currentWebEngineSettingsPointer = currentPrivacyWebEngineViewPointer->settings(); currentWebEnginePagePointer = currentPrivacyWebEngineViewPointer->page(); currentWebEngineProfilePointer = currentWebEnginePagePointer->profile(); currentWebEngineHistoryPointer = currentWebEnginePagePointer->history(); currentWebEngineCookieStorePointer = currentWebEngineProfilePointer->cookieStore(); - // Clear the URL line edit focus. - emit clearUrlLineEditFocus(); + // Get a handle for the development tools WebEngine view. + DevToolsWebEngineView *devToolsWebEngineViewPointer = qTabWidgetPointer->currentWidget()->findChild(); // Update the actions. - emit updateDefaultZoomFactor(currentPrivacyWebEngineViewPointer->defaultZoomFactor); - emit updateBackAction(currentWebEngineHistoryPointer->canGoBack()); - emit updateCookiesAction(currentPrivacyWebEngineViewPointer->cookieListPointer->size()); - emit updateDomStorageAction(currentWebEngineSettingsPointer->testAttribute(QWebEngineSettings::LocalStorageEnabled)); - emit updateForwardAction(currentWebEngineHistoryPointer->canGoForward()); - emit updateJavaScriptAction(currentWebEngineSettingsPointer->testAttribute(QWebEngineSettings::JavascriptEnabled)); - emit updateLocalStorageAction(currentPrivacyWebEngineViewPointer->localStorageEnabled); - emit updateUserAgentActions(currentWebEngineProfilePointer->httpUserAgent(), true); - emit updateZoomActions(currentPrivacyWebEngineViewPointer->zoomFactor()); - - // Update the URL. - emit updateWindowTitle(currentPrivacyWebEngineViewPointer->title()); - emit updateDomainSettingsIndicator(currentPrivacyWebEngineViewPointer->domainSettingsName != QLatin1String("")); - emit updateUrlLineEdit(currentPrivacyWebEngineViewPointer->url()); + Q_EMIT easyListStatusChanged(currentPrivacyWebEngineViewPointer->easyListEnabled); + Q_EMIT easyPrivacyStatusChanged(currentPrivacyWebEngineViewPointer->easyPrivacyEnabled); + Q_EMIT fanboysAnnoyanceListStatusChanged(currentPrivacyWebEngineViewPointer->fanboysAnnoyanceListEnabled); + Q_EMIT ultraListStatusChanged(currentPrivacyWebEngineViewPointer->ultraListEnabled); + Q_EMIT ultraPrivacyStatusChanged(currentPrivacyWebEngineViewPointer->ultraPrivacyEnabled); + Q_EMIT blockedRequestsUpdated(currentPrivacyWebEngineViewPointer->blockedRequestsVector); + Q_EMIT cookiesChanged(currentPrivacyWebEngineViewPointer->cookieListPointer->size()); + Q_EMIT updateBackAction(currentWebEngineHistoryPointer->canGoBack()); + Q_EMIT updateDefaultZoomFactor(currentPrivacyWebEngineViewPointer->defaultZoomFactor); + Q_EMIT updateDeveloperToolsAction(devToolsWebEngineViewPointer->isVisible()); + Q_EMIT updateDomStorageAction(currentWebEngineSettingsPointer->testAttribute(QWebEngineSettings::LocalStorageEnabled)); + Q_EMIT updateForwardAction(currentWebEngineHistoryPointer->canGoForward()); + Q_EMIT updateJavaScriptAction(currentWebEngineSettingsPointer->testAttribute(QWebEngineSettings::JavascriptEnabled)); + Q_EMIT updateLocalStorageAction(currentPrivacyWebEngineViewPointer->localStorageEnabled); + Q_EMIT updateUserAgentActions(currentWebEngineProfilePointer->httpUserAgent(), true); + Q_EMIT updateZoomActions(currentPrivacyWebEngineViewPointer->zoomFactor()); // Update the find text. - emit updateFindText(currentPrivacyWebEngineViewPointer->findString, currentPrivacyWebEngineViewPointer->findCaseSensitive); - emit updateFindTextResults(currentPrivacyWebEngineViewPointer->findTextResult); + Q_EMIT updateFindText(currentPrivacyWebEngineViewPointer->findString, currentPrivacyWebEngineViewPointer->findCaseSensitive); + Q_EMIT updateFindTextResults(currentPrivacyWebEngineViewPointer->findTextResult); // Update the progress bar. if (currentPrivacyWebEngineViewPointer->loadProgressInt >= 0) - emit showProgressBar(currentPrivacyWebEngineViewPointer->loadProgressInt); + Q_EMIT showProgressBar(currentPrivacyWebEngineViewPointer->loadProgressInt); else - emit hideProgressBar(); + Q_EMIT hideProgressBar(); + + // Update the URL. + Q_EMIT updateWindowTitle(currentPrivacyWebEngineViewPointer->title()); + Q_EMIT updateDomainSettingsIndicator(currentPrivacyWebEngineViewPointer->domainSettingsName != QLatin1String("")); + Q_EMIT updateUrlLineEdit(QUrl(currentPrivacyWebEngineViewPointer->currentUrlText)); } void TabWidget::useNativeKdeDownloader(QUrl &downloadUrl, QString &suggestedFileName) { // Get the download directory. - QString downloadDirectory = Settings::downloadLocation(); + QString downloadDirectory = Settings::downloadDirectory(); // Resolve the system download directory if specified. if (downloadDirectory == QLatin1String("System Download Directory")) @@ -1161,11 +1394,15 @@ void TabWidget::useNativeKdeDownloader(QUrl &downloadUrl, QString &suggestedFile 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] () + auto saveFile = [saveFileDialogPointer, downloadUrl, this] () { // Get the save location. The dialog box should only allow the selecting of one file location. QUrl saveLocation = saveFileDialogPointer->selectedUrls().value(0); + // Update the download directory if specified. + if (Settings::autoUpateDownloadDirectory()) + updateDownloadDirectory(saveLocation.toLocalFile()); + // Create a file copy job. `-1` creates the file with default permissions. KIO::FileCopyJob *fileCopyJobPointer = KIO::file_copy(downloadUrl, saveLocation, -1, KIO::Overwrite); @@ -1183,3 +1420,4 @@ void TabWidget::useNativeKdeDownloader(QUrl &downloadUrl, QString &suggestedFile // Show the dialog. saveFileDialogPointer->show(); } +