X-Git-Url: https://gitweb.stoutner.com/?a=blobdiff_plain;f=src%2Fwidgets%2FTabWidget.cpp;h=84cd3aca089de34bcd188e3e5baa006508254595;hb=e715eca23297fb10dcf70e4c8bb2712413d16e3d;hp=76ff617c3e180f3e253884d277dfd2a536f94dce;hpb=dcb48bab299233e40e9518076c3e032ca072cb57;p=PrivacyBrowserPC.git diff --git a/src/widgets/TabWidget.cpp b/src/widgets/TabWidget.cpp index 76ff617..84cd3ac 100644 --- a/src/widgets/TabWidget.cpp +++ b/src/widgets/TabWidget.cpp @@ -47,8 +47,24 @@ QString TabWidget::webEngineDefaultUserAgent = QLatin1String(""); // Construct the class. -TabWidget::TabWidget(QWidget *parent) : QWidget(parent) +TabWidget::TabWidget(QWidget *windowPointer) : QWidget(windowPointer) { + // Create a QProcess to check if KDE is running. + QProcess *checkIfRunningKdeQProcessPointer = new QProcess(); + + // Create an argument string list that contains `ksmserver` (KDE Session Manager). + QStringList argument = QStringList(QLatin1String("ksmserver")); + + // Run `pidof` to check for the presence of `ksmserver`. + checkIfRunningKdeQProcessPointer->start(QLatin1String("pidof"), argument); + + // Monitor any standard output. + connect(checkIfRunningKdeQProcessPointer, &QProcess::readyReadStandardOutput, [this] + { + // If there is any standard output, `ksmserver` is running. + isRunningKde = true; + }); + // Instantiate the user agent helper. userAgentHelperPointer = new UserAgentHelper(); @@ -78,6 +94,9 @@ TabWidget::TabWidget(QWidget *parent) : QWidget(parent) // Set the loading favorite icon movie file name. loadingFavoriteIconMoviePointer->setFileName(QStringLiteral(":/icons/loading.gif")); + // Stop the loading favorite icon movie if the window is destroyed. Otherwise, the app will crash if there is more than one window open and a window is closed while at tab is loading. + connect(windowPointer, SIGNAL(destroyed()), this, SLOT(stopLoadingFavoriteIconMovie())); + // Add the first tab. addFirstTab(); @@ -102,8 +121,11 @@ TabWidget::TabWidget(QWidget *parent) : QWidget(parent) TabWidget::~TabWidget() { + // Get the number of tabs. + int numberOfTabs = qTabWidgetPointer->count(); + // Manually delete each WebEngine page. - for (int i = 0; i < qTabWidgetPointer->count(); ++i) + for (int i = 0; i < numberOfTabs; ++i) { // Get the privacy WebEngine view. PrivacyWebEngineView *privacyWebEngineViewPointer = qobject_cast(qTabWidgetPointer->widget(i)); @@ -149,7 +171,7 @@ void TabWidget::addFirstTab() qTabWidgetPointer->currentWidget()->setFocus(); } -PrivacyWebEngineView* TabWidget::addTab(const bool removeUrlLineEditFocus, const bool backgroundTab) +PrivacyWebEngineView* TabWidget::addTab(const bool removeUrlLineEditFocus, const bool backgroundTab, const QString urlString) { // Create a privacy WebEngine view. PrivacyWebEngineView *privacyWebEngineViewPointer = new PrivacyWebEngineView(); @@ -169,7 +191,7 @@ PrivacyWebEngineView* TabWidget::addTab(const bool removeUrlLineEditFocus, const QWebEngineSettings *webEngineSettingsPointer = webEnginePagePointer->settings(); // Update the URL line edit when the URL changes. - connect(privacyWebEngineViewPointer, &PrivacyWebEngineView::urlChanged, [privacyWebEngineViewPointer, this] (const QUrl &newUrl) + connect(privacyWebEngineViewPointer, &PrivacyWebEngineView::urlChanged, [this, privacyWebEngineViewPointer] (const QUrl &newUrl) { // Only update the UI if this is the current tab. if (privacyWebEngineViewPointer == currentPrivacyWebEngineViewPointer) @@ -198,7 +220,7 @@ PrivacyWebEngineView* TabWidget::addTab(const bool removeUrlLineEditFocus, const }); // Connect the loading favorite icon movie to the tab icon. - connect(loadingFavoriteIconMoviePointer, &QMovie::frameChanged, [privacyWebEngineViewPointer, this] + connect(loadingFavoriteIconMoviePointer, &QMovie::frameChanged, [this, privacyWebEngineViewPointer] { // Get the index for this tab. int tabIndex = qTabWidgetPointer->indexOf(privacyWebEngineViewPointer); @@ -209,7 +231,7 @@ PrivacyWebEngineView* TabWidget::addTab(const bool removeUrlLineEditFocus, const }); // Update the icon when it changes. - connect(privacyWebEngineViewPointer, &PrivacyWebEngineView::iconChanged, [privacyWebEngineViewPointer, this] (const QIcon &newFavoriteIcon) + connect(privacyWebEngineViewPointer, &PrivacyWebEngineView::iconChanged, [this, privacyWebEngineViewPointer] (const QIcon &newFavoriteIcon) { // Store the favorite icon in the privacy web engine view. if (newFavoriteIcon.isNull()) @@ -228,7 +250,7 @@ PrivacyWebEngineView* TabWidget::addTab(const bool removeUrlLineEditFocus, const }); // Update the progress bar and the favorite icon when a load is started. - connect(privacyWebEngineViewPointer, &PrivacyWebEngineView::loadStarted, [privacyWebEngineViewPointer, this] () + connect(privacyWebEngineViewPointer, &PrivacyWebEngineView::loadStarted, [this, privacyWebEngineViewPointer] () { // Set the privacy web engine view to be loading. privacyWebEngineViewPointer->isLoading = true; @@ -245,7 +267,7 @@ PrivacyWebEngineView* TabWidget::addTab(const bool removeUrlLineEditFocus, const }); // Update the progress bar when a load progresses. - connect(privacyWebEngineViewPointer, &PrivacyWebEngineView::loadProgress, [privacyWebEngineViewPointer, this] (const int progress) + connect(privacyWebEngineViewPointer, &PrivacyWebEngineView::loadProgress, [this, privacyWebEngineViewPointer] (const int progress) { // Store the load progress. privacyWebEngineViewPointer->loadProgressInt = progress; @@ -256,7 +278,7 @@ PrivacyWebEngineView* TabWidget::addTab(const bool removeUrlLineEditFocus, const }); // Update the progress bar when a load finishes. - connect(privacyWebEngineViewPointer, &PrivacyWebEngineView::loadFinished, [privacyWebEngineViewPointer, this] () + connect(privacyWebEngineViewPointer, &PrivacyWebEngineView::loadFinished, [this, privacyWebEngineViewPointer] () { // Set the privacy web engine view to be not loading. privacyWebEngineViewPointer->isLoading = false; @@ -277,14 +299,17 @@ PrivacyWebEngineView* TabWidget::addTab(const bool removeUrlLineEditFocus, const // Create a no tabs loading variable. bool noTabsLoading = true; + // Get the number of tabs. + int numberOfTabs = qTabWidgetPointer->count(); + // Check to see if any other tabs are loading. - for (int i = 0; i < qTabWidgetPointer->count(); i++) + for (int i = 0; i < numberOfTabs; i++) { // Get the privacy WebEngine view for the tab. - PrivacyWebEngineView *webEngineViewPointer = qobject_cast(qTabWidgetPointer->widget(i)); + PrivacyWebEngineView *privacyWebEngineViewPointer = qobject_cast(qTabWidgetPointer->widget(i)); - // Check to see if it is currently loading. - if (webEngineViewPointer->isLoading) + // 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) noTabsLoading = false; } @@ -294,7 +319,7 @@ PrivacyWebEngineView* TabWidget::addTab(const bool removeUrlLineEditFocus, const }); // Display HTTP Ping blocked dialogs. - connect(privacyWebEngineViewPointer, &PrivacyWebEngineView::displayHttpPingBlockedDialog, [privacyWebEngineViewPointer, this] (const QString &httpPingUrl) + connect(privacyWebEngineViewPointer, &PrivacyWebEngineView::displayHttpPingBlockedDialog, [this, privacyWebEngineViewPointer] (const QString &httpPingUrl) { // Only display the HTTP Ping blocked dialog if this is the current tab. if (privacyWebEngineViewPointer == currentPrivacyWebEngineViewPointer) @@ -319,12 +344,12 @@ PrivacyWebEngineView* TabWidget::addTab(const bool removeUrlLineEditFocus, const } }); - // Update the zoom factor when changed by CTRL-Scrolling. This can be modified when is fixed. + // Update the zoom actions when changed by CTRL-Scrolling. This can be modified when is fixed. connect(webEnginePagePointer, &QWebEnginePage::contentsSizeChanged, [webEnginePagePointer, this] () { - // Only update the zoom factor action text if this is the current tab. + // Only update the zoom actions if this is the current tab. if (webEnginePagePointer == currentWebEnginePagePointer) - emit updateZoomFactorAction(webEnginePagePointer->zoomFactor()); + emit updateZoomActions(webEnginePagePointer->zoomFactor()); }); // Display find text results. @@ -372,8 +397,8 @@ PrivacyWebEngineView* TabWidget::addTab(const bool removeUrlLineEditFocus, const // Don't allow JavaScript to open windows. webEngineSettingsPointer->setAttribute(QWebEngineSettings::JavascriptCanOpenWindows, false); - // Allow keyboard navigation. - webEngineSettingsPointer->setAttribute(QWebEngineSettings::SpatialNavigationEnabled, true); + // Allow keyboard navigation between links and input fields. + webEngineSettingsPointer->setAttribute(QWebEngineSettings::SpatialNavigationEnabled, Settings::spatialNavigation()); // Enable full screen support. webEngineSettingsPointer->setAttribute(QWebEngineSettings::FullScreenSupportEnabled, true); @@ -391,7 +416,7 @@ PrivacyWebEngineView* TabWidget::addTab(const bool removeUrlLineEditFocus, const webEngineSettingsPointer->setAttribute(QWebEngineSettings::PluginsEnabled, true); // Update the cookies action. - connect(privacyWebEngineViewPointer, &PrivacyWebEngineView::updateCookiesAction, [privacyWebEngineViewPointer, this] (const int numberOfCookies) + connect(privacyWebEngineViewPointer, &PrivacyWebEngineView::updateCookiesAction, [this, privacyWebEngineViewPointer] (const int numberOfCookies) { // Update the cookie action if the specified privacy WebEngine view is the current privacy WebEngine view. if (privacyWebEngineViewPointer == currentPrivacyWebEngineViewPointer) @@ -429,6 +454,9 @@ PrivacyWebEngineView* TabWidget::addTab(const bool removeUrlLineEditFocus, const if (removeUrlLineEditFocus) emit clearUrlLineEditFocus(); + if (urlString != nullptr) + privacyWebEngineViewPointer->load(QUrl::fromUserInput(urlString)); + // Return the privacy WebEngine view pointer. return privacyWebEngineViewPointer; } @@ -441,6 +469,18 @@ void TabWidget::applyApplicationSettings() else qTabWidgetPointer->setTabPosition(QTabWidget::South); + // Get the number of tabs. + int numberOfTabs = qTabWidgetPointer->count(); + + // 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)); + + // Apply the spatial navigation settings to each page. + privacyWebEngineViewPointer->page()->settings()->setAttribute(QWebEngineSettings::SpatialNavigationEnabled, Settings::spatialNavigation()); + } + // Set the search engine URL. searchEngineUrl = SearchEngineHelper::getSearchUrl(Settings::searchEngine()); @@ -450,8 +490,17 @@ void TabWidget::applyApplicationSettings() void TabWidget::applyDomainSettingsAndReload() { - // Apply the domain settings. `true` reloads the website. - currentPrivacyWebEngineViewPointer->applyDomainSettings(currentPrivacyWebEngineViewPointer->url().host(), true); + // Get the number of tabs. + int numberOfTabs = qTabWidgetPointer->count(); + + // 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)); + + // Apply the spatial navigation settings to each page. + privacyWebEngineViewPointer->applyDomainSettings(privacyWebEngineViewPointer->url().host(), true); + } } void TabWidget::applyOnTheFlySearchEngine(QAction *searchEngineActionPointer) @@ -502,10 +551,10 @@ void TabWidget::applySpellCheckLanguages() const for (int i = 0; i < numberOfTabs; ++i) { // Get the WebEngine view pointer. - PrivacyWebEngineView *webEngineViewPointer = qobject_cast(qTabWidgetPointer->currentWidget()); + PrivacyWebEngineView *privacyWebEngineViewPointer = qobject_cast(qTabWidgetPointer->widget(i)); // Get the WebEngine page pointer. - QWebEnginePage *webEnginePagePointer = webEngineViewPointer->page(); + QWebEnginePage *webEnginePagePointer = privacyWebEngineViewPointer->page(); // Get the WebEngine profile pointer. QWebEngineProfile *webEngineProfilePointer = webEnginePagePointer->profile(); @@ -587,7 +636,7 @@ void TabWidget::findText(const QString &text) const void TabWidget::findTextFinished(const QWebEngineFindTextResult &findTextResult) { - // Update the find text UI if it wasn't simply wiping the current find text selection. Otherwise the UI temporarially flashes `0/0`. + // Update the find text UI if it wasn't simply wiping the current find text selection. Otherwise the UI temporarily flashes `0/0`. if (wipingCurrentFindTextSelection) // The current selection is being wiped. { // Reset the flag. @@ -624,6 +673,24 @@ std::list* TabWidget::getCookieList() const return currentPrivacyWebEngineViewPointer->cookieListPointer; } +QIcon TabWidget::getCurrentTabFavoritIcon() const +{ + // Return the current Privacy WebEngine favorite icon. + return currentPrivacyWebEngineViewPointer->favoriteIcon; +} + +QString TabWidget::getCurrentTabTitle() const +{ + // Return the current Privacy WebEngine title. + return currentPrivacyWebEngineViewPointer->title(); +} + +QString TabWidget::getCurrentTabUrl() const +{ + // Return the current Privacy WebEngine URL as a string. + return currentPrivacyWebEngineViewPointer->url().toString(); +} + QString& TabWidget::getDomainSettingsName() const { // Return the domain settings name. @@ -669,7 +736,7 @@ 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://")) // The text is likely a file URL. + if (url.startsWith("file://") || url.startsWith("view-source:")) // The text is likely a file or view source URL. { // Load the URL. currentPrivacyWebEngineViewPointer->load(QUrl::fromUserInput(url)); @@ -725,6 +792,12 @@ void TabWidget::pageLinkHovered(const QString &linkUrl) const emit linkHovered(linkUrl); } +void TabWidget::stopLoadingFavoriteIconMovie() const +{ + // Stop the loading favorite icon movie. Otherwise, the browser will crash if a second window is closed while a tab in it is loading. + loadingFavoriteIconMoviePointer->stop(); +} + void TabWidget::print() const { // Create a printer. @@ -785,6 +858,13 @@ void TabWidget::refresh() const currentPrivacyWebEngineViewPointer->reload(); } +void TabWidget::reloadAndBypassCache() const +{ + // Reload the website, bypassing the cache. + currentWebEnginePagePointer->triggerAction(QWebEnginePage::ReloadAndBypassCache); +} + + void TabWidget::setTabBarVisible(const bool visible) const { // Set the tab bar visibility. @@ -799,8 +879,8 @@ void TabWidget::showSaveDialog(QWebEngineDownloadItem *webEngineDownloadItemPoin QString suggestedFileName = webEngineDownloadItemPointer->suggestedFileName(); int totalBytes = webEngineDownloadItemPointer->totalBytes(); - // Check to see if local storage (cookies) is enabled. - if (currentPrivacyWebEngineViewPointer->localStorageEnabled) // Local storage (cookies) is enabled. Use WebEngine's downloader. + // 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(downloadUrl, mimeTypeString, totalBytes); @@ -818,7 +898,7 @@ void TabWidget::showSaveDialog(QWebEngineDownloadItem *webEngineDownloadItemPoin if (downloadDirectory == QLatin1String("System Download Directory")) downloadDirectory = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation); - // Display a save file dialog. + // 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. @@ -844,21 +924,18 @@ void TabWidget::showSaveDialog(QWebEngineDownloadItem *webEngineDownloadItemPoin // Set the notification text. fileDownloadNotificationPointer->setText(i18nc("Downloading notification text", "Downloading %1", saveFileName)); + // Get the download icon from the theme. + QIcon downloadIcon = QIcon::fromTheme(QLatin1String("download"), QIcon::fromTheme(QLatin1String("document-save"))); + // Set the notification icon. - fileDownloadNotificationPointer->setIconName(QLatin1String("download")); + fileDownloadNotificationPointer->setIconName(downloadIcon.name()); // Set the action list cancel button. fileDownloadNotificationPointer->setActions(QStringList({i18nc("Download notification action","Cancel")})); - // Set the notification to display indefinitely. - fileDownloadNotificationPointer->setFlags(KNotification::Persistent); - // Prevent the notification from being autodeleted if it is closed. Otherwise, the updates to the notification below cause a crash. fileDownloadNotificationPointer->setAutoDelete(false); - // Display the notification. - fileDownloadNotificationPointer->sendEvent(); - // Handle clicks on the cancel button. connect(fileDownloadNotificationPointer, &KNotification::action1Activated, [webEngineDownloadItemPointer, saveFileName] () { @@ -923,6 +1000,9 @@ void TabWidget::showSaveDialog(QWebEngineDownloadItem *webEngineDownloadItemPoin fileDownloadNotificationPointer->update(); }); + // Display the notification. + fileDownloadNotificationPointer->sendEvent(); + // Start the download. webEngineDownloadItemPointer->accept(); } @@ -938,14 +1018,14 @@ void TabWidget::showSaveDialog(QWebEngineDownloadItem *webEngineDownloadItemPoin webEngineDownloadItemPointer->cancel(); } } - else // Local storage (cookies) is disabled. Use KDE's native downloader. + 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. { // Instantiate the save dialog. `true` instructs it to use the native downloader SaveDialog *saveDialogPointer = new SaveDialog(downloadUrl, mimeTypeString, totalBytes, suggestedFileName, true); // Connect the save button. - connect(saveDialogPointer, SIGNAL(useNativeDownloader(QUrl &, QString &)), this, SLOT(useNativeDownloader(QUrl &, QString &))); + connect(saveDialogPointer, SIGNAL(useNativeKdeDownloader(QUrl &, QString &)), this, SLOT(useNativeKdeDownloader(QUrl &, QString &))); // Show the dialog. saveDialogPointer->show(); @@ -1009,12 +1089,13 @@ void TabWidget::updateUiFromWebEngineView(const PrivacyWebEngineView *privacyWeb 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 updateZoomFactorAction(currentPrivacyWebEngineViewPointer->zoomFactor()); + emit updateZoomActions(currentPrivacyWebEngineViewPointer->zoomFactor()); } } @@ -1032,6 +1113,7 @@ void TabWidget::updateUiWithTabSettings() emit clearUrlLineEditFocus(); // Update the actions. + emit updateDefaultZoomFactor(currentPrivacyWebEngineViewPointer->defaultZoomFactor); emit updateBackAction(currentWebEngineHistoryPointer->canGoBack()); emit updateCookiesAction(currentPrivacyWebEngineViewPointer->cookieListPointer->size()); emit updateDomStorageAction(currentWebEngineSettingsPointer->testAttribute(QWebEngineSettings::LocalStorageEnabled)); @@ -1039,7 +1121,7 @@ void TabWidget::updateUiWithTabSettings() emit updateJavaScriptAction(currentWebEngineSettingsPointer->testAttribute(QWebEngineSettings::JavascriptEnabled)); emit updateLocalStorageAction(currentPrivacyWebEngineViewPointer->localStorageEnabled); emit updateUserAgentActions(currentWebEngineProfilePointer->httpUserAgent(), true); - emit updateZoomFactorAction(currentPrivacyWebEngineViewPointer->zoomFactor()); + emit updateZoomActions(currentPrivacyWebEngineViewPointer->zoomFactor()); // Update the URL. emit updateWindowTitle(currentPrivacyWebEngineViewPointer->title()); @@ -1057,7 +1139,7 @@ void TabWidget::updateUiWithTabSettings() emit hideProgressBar(); } -void TabWidget::useNativeDownloader(QUrl &downloadUrl, QString &suggestedFileName) +void TabWidget::useNativeKdeDownloader(QUrl &downloadUrl, QString &suggestedFileName) { // Get the download directory. QString downloadDirectory = Settings::downloadLocation(); @@ -1087,7 +1169,8 @@ void TabWidget::useNativeDownloader(QUrl &downloadUrl, QString &suggestedFileNam // Create a file copy job. `-1` creates the file with default permissions. KIO::FileCopyJob *fileCopyJobPointer = KIO::file_copy(downloadUrl, saveLocation, -1, KIO::Overwrite); - // Set the download job to display any error messages. + // Set the download job to display any warning and error messages. + fileCopyJobPointer->uiDelegate()->setAutoWarningHandlingEnabled(true); fileCopyJobPointer->uiDelegate()->setAutoErrorHandlingEnabled(true); // Start the download.