]> gitweb.stoutner.com Git - PrivacyBrowserPC.git/blobdiff - src/widgets/TabWidget.cpp
Add a default folder icon to the edit folder dialog. https://redmine.stoutner.com...
[PrivacyBrowserPC.git] / src / widgets / TabWidget.cpp
index 4a6b11c64d2bb7800497c4da9c70a970b4c0c489..f65c79ea2177b404eef157f441245dab7175ed73 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2022-2023 Soren Stoutner <soren@stoutner.com>.
+ * Copyright 2022-2024 Soren Stoutner <soren@stoutner.com>.
  *
  * This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
  *
  */
 
 // Application headers.
+#include "DevToolsWebEngineView.h"
 #include "TabWidget.h"
 #include "Settings.h"
 #include "ui_AddTabWidget.h"
+#include "ui_Tab.h"
 #include "ui_TabWidget.h"
 #include "databases/CookiesDatabase.h"
 #include "dialogs/SaveDialog.h"
@@ -127,11 +129,16 @@ TabWidget::~TabWidget()
     // Manually delete each WebEngine page.
     for (int i = 0; i < numberOfTabs; ++i)
     {
-        // Get the privacy WebEngine view.
-        PrivacyWebEngineView *privacyWebEngineViewPointer = qobject_cast<PrivacyWebEngineView *>(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<PrivacyWebEngineView *>();
+        DevToolsWebEngineView *devToolsWebEngineViewPointer = tabSplitterWidgetPointer->findChild<DevToolsWebEngineView *>();
+
+        // 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 +178,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.  This must be done here to preserve the bottom half of the window as the initial development tools size.
+    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)
     {
@@ -206,10 +243,10 @@ PrivacyWebEngineView* TabWidget::addTab(const bool removeUrlLineEditFocus, const
     });
 
     // 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);
@@ -220,10 +257,10 @@ PrivacyWebEngineView* TabWidget::addTab(const bool removeUrlLineEditFocus, const
     });
 
     // 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 +268,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 +277,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())
@@ -278,7 +315,7 @@ PrivacyWebEngineView* TabWidget::addTab(const bool removeUrlLineEditFocus, const
     });
 
     // 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;
@@ -291,7 +328,7 @@ PrivacyWebEngineView* TabWidget::addTab(const bool removeUrlLineEditFocus, const
             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 +343,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<PrivacyWebEngineView*>(qTabWidgetPointer->widget(i));
+            PrivacyWebEngineView *privacyWebEngineViewPointer = qTabWidgetPointer->widget(i)->findChild<PrivacyWebEngineView *>();
 
             // 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)
@@ -475,7 +512,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<PrivacyWebEngineView *>(qTabWidgetPointer->widget(i));
+        PrivacyWebEngineView *privacyWebEngineViewPointer = qTabWidgetPointer->widget(i)->findChild<PrivacyWebEngineView *>();
 
         // Apply the spatial navigation settings to each page.
         privacyWebEngineViewPointer->page()->settings()->setAttribute(QWebEngineSettings::SpatialNavigationEnabled, Settings::spatialNavigation());
@@ -496,7 +533,7 @@ 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<PrivacyWebEngineView *>(qTabWidgetPointer->widget(i));
+        PrivacyWebEngineView *privacyWebEngineViewPointer = qTabWidgetPointer->widget(i)->findChild<PrivacyWebEngineView *>();
 
         // Apply the spatial navigation settings to each page.
         privacyWebEngineViewPointer->applyDomainSettings(privacyWebEngineViewPointer->url().host(), true);
@@ -536,10 +573,10 @@ void TabWidget::applyOnTheFlyUserAgent(QAction *userAgentActionPointer) const
     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 +588,7 @@ void TabWidget::applySpellCheckLanguages() const
     for (int i = 0; i < numberOfTabs; ++i)
     {
         // Get the WebEngine view pointer.
-        PrivacyWebEngineView *privacyWebEngineViewPointer = qobject_cast<PrivacyWebEngineView *>(qTabWidgetPointer->widget(i));
+        PrivacyWebEngineView *privacyWebEngineViewPointer = qTabWidgetPointer->widget(i)->findChild<PrivacyWebEngineView *>();
 
         // Get the WebEngine page pointer.
         QWebEnginePage *webEnginePagePointer = privacyWebEngineViewPointer->page();
@@ -584,20 +621,29 @@ void TabWidget::deleteCookieFromStore(const QNetworkCookie &cookie) const
 
 void TabWidget::deleteTab(const int tabIndex)
 {
-    // Get the privacy WebEngine view.
-    PrivacyWebEngineView *privacyWebEngineViewPointer = qobject_cast<PrivacyWebEngineView *>(qTabWidgetPointer->widget(tabIndex));
+    // Get the tab splitter widget.
+    QWidget *tabSplitterWidgetPointer = qTabWidgetPointer->widget(tabIndex);
+
+    // Get the WebEngine views.
+    PrivacyWebEngineView *privacyWebEngineViewPointer = tabSplitterWidgetPointer->findChild<PrivacyWebEngineView *>();
+    DevToolsWebEngineView *devToolsWebEngineViewPointer = tabSplitterWidgetPointer->findChild<DevToolsWebEngineView *>();
 
     // 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.
     {
@@ -691,6 +737,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.
@@ -854,6 +906,9 @@ void TabWidget::printWebpage(QPrinter *printerPointer) const
 
 void TabWidget::refresh() const
 {
+    // Reset the HTTP authentication dialog counter.
+    currentPrivacyWebEngineViewPointer->httpAuthenticationDialogsDisplayed = 0;
+
     // Reload the website.
     currentPrivacyWebEngineViewPointer->reload();
 }
@@ -867,10 +922,10 @@ void TabWidget::reloadAndBypassCache() const
 void TabWidget::saveArchive()
 {
     // Get the suggested file name.
-    QString suggestedFileName = currentPrivacyWebEngineViewPointer->url().host() + ".mht";
+    QString suggestedFileName = currentPrivacyWebEngineViewPointer->title() + ".mht";
 
     // 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"))
@@ -882,6 +937,10 @@ void TabWidget::saveArchive()
     // 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;
 
@@ -911,7 +970,7 @@ void TabWidget::showSaveDialog(QWebEngineDownloadItem *webEngineDownloadItemPoin
         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);
+            SaveDialog *saveDialogPointer = new SaveDialog(this, downloadUrl, mimeTypeString, totalBytes);
 
             // Display the save dialog.
             int saveDialogResult = saveDialogPointer->exec();
@@ -920,7 +979,7 @@ void TabWidget::showSaveDialog(QWebEngineDownloadItem *webEngineDownloadItemPoin
             if (saveDialogResult == QDialog::Accepted)  // Save was selected.
             {
                 // 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"))
@@ -932,6 +991,10 @@ void TabWidget::showSaveDialog(QWebEngineDownloadItem *webEngineDownloadItemPoin
                 // 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);
+
                     // Create a save file path file info.
                     QFileInfo saveFilePathFileInfo = QFileInfo(saveFilePath);
 
@@ -1050,7 +1113,7 @@ void TabWidget::showSaveDialog(QWebEngineDownloadItem *webEngineDownloadItemPoin
             // 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);
+            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 &)));
@@ -1064,6 +1127,44 @@ void TabWidget::showSaveDialog(QWebEngineDownloadItem *webEngineDownloadItemPoin
     savingArchive = false;
 }
 
+void TabWidget::stop() const
+{
+    // Stop the loading of the current privacy WebEngine.
+    currentPrivacyWebEngineViewPointer->stop();
+}
+
+void TabWidget::toggleDeveloperTools(const bool enabled) const
+{
+    // Get a handle for the current developer tools WebEngine.
+    DevToolsWebEngineView *devToolsWebEngineViewPointer = qTabWidgetPointer->currentWidget()->findChild<DevToolsWebEngineView *>();
+
+    if (enabled)
+    {
+        // Set the zoom factor on the development tools WebEngine.
+        devToolsWebEngineViewPointer->setZoomFactor(currentWebEnginePagePointer->zoomFactor());
+
+        // Enable the development tools.
+        currentWebEnginePagePointer->setDevToolsPage(devToolsWebEngineViewPointer->page());
+
+        // Enable JavaScript on the development tools WebEngine.
+        devToolsWebEngineViewPointer->settings()->setAttribute(QWebEngineSettings::JavascriptEnabled, true);
+
+        // Display the developer tools.
+        devToolsWebEngineViewPointer->setVisible(true);
+    }
+    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);
+    }
+}
+
 void TabWidget::toggleDomStorage() const
 {
     // Toggle DOM storage.
@@ -1115,6 +1216,21 @@ void TabWidget::toggleLocalStorage()
     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.
@@ -1134,7 +1250,7 @@ void TabWidget::updateUiFromWebEngineView(const PrivacyWebEngineView *privacyWeb
 void TabWidget::updateUiWithTabSettings()
 {
     // Update the current WebEngine pointers.
-    currentPrivacyWebEngineViewPointer = qobject_cast<PrivacyWebEngineView *>(qTabWidgetPointer->currentWidget());
+    currentPrivacyWebEngineViewPointer = qTabWidgetPointer->currentWidget()->findChild<PrivacyWebEngineView *>();
     currentWebEngineSettingsPointer = currentPrivacyWebEngineViewPointer->settings();
     currentWebEnginePagePointer = currentPrivacyWebEngineViewPointer->page();
     currentWebEngineProfilePointer = currentWebEnginePagePointer->profile();
@@ -1144,10 +1260,14 @@ void TabWidget::updateUiWithTabSettings()
     // Clear the URL line edit focus.
     emit clearUrlLineEditFocus();
 
+    // Get a handle for the development tools WebEngine view.
+    DevToolsWebEngineView *devToolsWebEngineViewPointer = qTabWidgetPointer->currentWidget()->findChild<DevToolsWebEngineView *>();
+
     // Update the actions.
     emit updateDefaultZoomFactor(currentPrivacyWebEngineViewPointer->defaultZoomFactor);
     emit updateBackAction(currentWebEngineHistoryPointer->canGoBack());
     emit updateCookiesAction(currentPrivacyWebEngineViewPointer->cookieListPointer->size());
+    emit updateDeveloperToolsAction(devToolsWebEngineViewPointer->isVisible());
     emit updateDomStorageAction(currentWebEngineSettingsPointer->testAttribute(QWebEngineSettings::LocalStorageEnabled));
     emit updateForwardAction(currentWebEngineHistoryPointer->canGoForward());
     emit updateJavaScriptAction(currentWebEngineSettingsPointer->testAttribute(QWebEngineSettings::JavascriptEnabled));
@@ -1174,7 +1294,7 @@ void TabWidget::updateUiWithTabSettings()
 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"))
@@ -1193,11 +1313,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);