*/
// 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"
// 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();
}
}
PrivacyWebEngineView* TabWidget::addTab(const bool removeUrlLineEditFocus, 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);
// Add a new tab.
- int newTabIndex = qTabWidgetPointer->addTab(privacyWebEngineViewPointer, i18nc("New tab label.", "New Tab"));
+ int 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)
{
});
// 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);
});
// 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)
});
// 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())
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())
});
// 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;
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);
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)
// 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());
// 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);
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();
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.
{
savingArchive = false;
}
+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.
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();
// 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));
QAction *reloadAndBypassCacheActionPointer = actionCollectionPointer->addAction(QLatin1String("reload_and_bypass_cache"));
viewSourceActionPointer = actionCollectionPointer->addAction(QLatin1String("view_source"));
viewSourceInNewTabActionPointer = actionCollectionPointer->addAction(QLatin1String("view_source_in_new_tab"));
+ developerToolsActionPointer = actionCollectionPointer->addAction(QLatin1String("developer_tools"));
javaScriptActionPointer = actionCollectionPointer->addAction(QLatin1String("javascript"));
localStorageActionPointer = actionCollectionPointer->addAction(QLatin1String("local_storage"));
domStorageActionPointer = actionCollectionPointer->addAction(QLatin1String("dom_storage"));
domStorageActionPointer->setCheckable(true);
findCaseSensitiveActionPointer->setCheckable(true);
viewSourceActionPointer->setCheckable(true);
+ developerToolsActionPointer->setCheckable(true);
userAgentPrivacyBrowserActionPointer->setCheckable(true);
userAgentWebEngineDefaultActionPointer->setCheckable(true);
userAgentFirefoxLinuxActionPointer->setCheckable(true);
reloadAndBypassCacheActionPointer->setText(i18nc("Reload and bypass cache action", "Reload and Bypass Cache"));
viewSourceActionPointer->setText(i18nc("View source action", "View Source"));
viewSourceInNewTabActionPointer->setText(i18nc("View source in new tab action", "View Source in New Tab"));
+ developerToolsActionPointer->setText(i18nc("Developer tools action", "Developer Tools"));
javaScriptActionPointer->setText(i18nc("JavaScript action", "JavaScript"));
localStorageActionPointer->setText(i18nc("The Local Storage action", "Local Storage"));
domStorageActionPointer->setText(i18nc("DOM Storage action", "DOM Storage"));
reloadAndBypassCacheActionPointer->setIcon(QIcon::fromTheme(QLatin1String("view-refresh")));
viewSourceActionPointer->setIcon(QIcon::fromTheme(QLatin1String("view-choose"), QIcon::fromTheme(QLatin1String("accessories-text-editor"))));
viewSourceInNewTabActionPointer->setIcon(QIcon::fromTheme(QLatin1String("view-choose"), QIcon::fromTheme(QLatin1String("accessories-text-editor"))));
+ developerToolsActionPointer->setIcon(QIcon::fromTheme(QLatin1String("add-subtitle"), QIcon::fromTheme("system-run")));
domStorageActionPointer->setIcon(QIcon::fromTheme(QLatin1String("code-class"), QIcon(QLatin1String("/usr/share/icons/gnome/32x32/actions/gtk-unindent-ltr.png"))));
userAgentPrivacyBrowserActionPointer->setIcon(QIcon(":/icons/privacy-mode.svg"));
userAgentWebEngineDefaultActionPointer->setIcon(QIcon::fromTheme(QLatin1String("qtlogo"), QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new")))));
QKeySequence ctrlF5KeySequence = QKeySequence(i18nc("The reload and bypass cache key sequence.", "Ctrl+F5"));
QKeySequence ctrlUKeySequence = QKeySequence(i18nc("The view source key sequence.", "Ctrl+U"));
QKeySequence ctrlShiftUKeySequence = QKeySequence(i18nc("The view source in new tab key sequence.", "Ctrl+Shift+U"));
+ QKeySequence f12KeySequence = QKeySequence(i18nc("The developer tools key sequence.", "F12"));
QKeySequence ctrlShiftPKeySequence = QKeySequence(i18nc("The print preview key sequence.", "Ctrl+Shift+P"));
QKeySequence ctrlJKeySequence = QKeySequence(i18nc("The JavaScript key sequence.", "Ctrl+J"));
QKeySequence ctrlLKeySequence = QKeySequence(i18nc("The local storage key sequence.", "Ctrl+L"));
actionCollectionPointer->setDefaultShortcut(reloadAndBypassCacheActionPointer, ctrlF5KeySequence);
actionCollectionPointer->setDefaultShortcut(viewSourceActionPointer, ctrlUKeySequence);
actionCollectionPointer->setDefaultShortcut(viewSourceInNewTabActionPointer, ctrlShiftUKeySequence);
+ actionCollectionPointer->setDefaultShortcut(developerToolsActionPointer, f12KeySequence);
actionCollectionPointer->setDefaultShortcut(printPreviewActionPointer, ctrlShiftPKeySequence);
actionCollectionPointer->setDefaultShortcut(javaScriptActionPointer, ctrlJKeySequence);
actionCollectionPointer->setDefaultShortcut(localStorageActionPointer, ctrlLKeySequence);
connect(reloadAndBypassCacheActionPointer, SIGNAL(triggered()), this, SLOT(reloadAndBypassCache()));
connect(viewSourceActionPointer, SIGNAL(triggered()), this, SLOT(toggleViewSource()));
connect(viewSourceInNewTabActionPointer, SIGNAL(triggered()), this, SLOT(toggleViewSourceInNewTab()));
+ connect(developerToolsActionPointer, SIGNAL(triggered()), this, SLOT(toggleDeveloperTools()));
connect(zoomFactorActionPointer, SIGNAL(triggered()), this, SLOT(getZoomFactorFromUser()));
connect(viewBookmarksToolBarActionPointer, SIGNAL(triggered()), this, SLOT(toggleViewBookmarksToolBar()));
connect(cookiesActionPointer, SIGNAL(triggered()), this, SLOT(showCookiesDialog()));
connect(localStorageActionPointer, SIGNAL(triggered()), this, SLOT(toggleLocalStorage()));
connect(domStorageActionPointer, SIGNAL(triggered()), this, SLOT(toggleDomStorage()));
- // Update the URL toolbar actions.
+ // Update the actions from the tab widget.
+ connect(tabWidgetPointer, SIGNAL(updateDeveloperToolsAction(bool)), developerToolsActionPointer, SLOT(setChecked(bool)));
connect(tabWidgetPointer, SIGNAL(updateBackAction(bool)), backActionPointer, SLOT(setEnabled(bool)));
connect(tabWidgetPointer, SIGNAL(updateForwardAction(bool)), forwardActionPointer, SLOT(setEnabled(bool)));
connect(tabWidgetPointer, SIGNAL(updateJavaScriptAction(bool)), this, SLOT(updateJavaScriptAction(bool)));
void BrowserWindow::populateBookmarksInThisWindow()
{
- qDebug() << "Populating bookmarks.";
-
// Remove all the final bookmark folder menu actions.
for (QPair<QMenu *, QAction *> *finalBookmarkFolderMenuActionPair : finalBookmarkFolderMenuActionList)
{
populateBookmarksInAllWindows();
}
+void BrowserWindow::toggleDeveloperTools() const
+{
+ // Toggle the developer tools.
+ tabWidgetPointer->toggleDeveloperTools(developerToolsActionPointer->isChecked());
+}
+
void BrowserWindow::toggleDomStorage() const
{
// Remove the focus from the URL line edit.