1
mirror of https://invent.kde.org/network/falkon.git synced 2024-09-23 02:32:10 +02:00
falkonOfficial/src/lib/app/browserwindow.cpp

1543 lines
41 KiB
C++
Raw Normal View History

2011-03-03 18:29:20 +01:00
/* ============================================================
* QupZilla - WebKit based browser
2014-01-11 16:11:42 +01:00
* Copyright (C) 2010-2014 David Rosca <nowrep@gmail.com>
2011-03-03 18:29:20 +01:00
*
* 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.
*
* 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 this program. If not, see <http://www.gnu.org/licenses/>.
* ============================================================ */
#include "browserwindow.h"
2011-03-02 16:57:41 +01:00
#include "tabwidget.h"
#include "tabbar.h"
#include "webpage.h"
#include "tabbedwebview.h"
2011-03-02 16:57:41 +01:00
#include "lineedit.h"
#include "history.h"
2011-03-02 16:57:41 +01:00
#include "locationbar.h"
#include "searchtoolbar.h"
#include "websearchbar.h"
#include "pluginproxy.h"
#include "sidebar.h"
2011-03-02 16:57:41 +01:00
#include "downloadmanager.h"
#include "cookiejar.h"
#include "cookiemanager.h"
#include "bookmarkstoolbar.h"
#include "clearprivatedata.h"
#include "sourceviewer.h"
#include "autofill.h"
2011-03-02 16:57:41 +01:00
#include "mainapplication.h"
#include "checkboxdialog.h"
2011-03-27 21:59:40 +02:00
#include "adblockmanager.h"
#include "clickablelabel.h"
#include "docktitlebarwidget.h"
#include "iconprovider.h"
#include "progressbar.h"
#include "adblockicon.h"
#include "closedtabsmanager.h"
#include "statusbarmessage.h"
#include "browsinglibrary.h"
#include "navigationbar.h"
#include "pagescreen.h"
#include "bookmarksimport/bookmarksimportdialog.h"
#include "qztools.h"
#include "reloadstopbutton.h"
#include "enhancedmenu.h"
#include "navigationcontainer.h"
#include "settings.h"
#include "qzsettings.h"
#include "webtab.h"
#include "speeddial.h"
#include "menubar.h"
#include "qtwin.h"
#include "bookmarkstools.h"
#include "bookmarksmenu.h"
#include "historymenu.h"
#include "mainmenu.h"
2011-03-02 16:57:41 +01:00
2014-09-26 19:28:24 +02:00
#include <algorithm>
2012-08-31 15:19:07 +02:00
#include <QKeyEvent>
#include <QSplitter>
#include <QStatusBar>
#include <QMenuBar>
#include <QTimer>
#include <QShortcut>
#include <QStackedWidget>
#include <QSqlQuery>
#include <QTextCodec>
#include <QFileDialog>
#include <QNetworkRequest>
#include <QDesktopServices>
#include <QWebEngineHistory>
#include <QWebEngineSettings>
#include <QMessageBox>
#include <QDesktopWidget>
#include <QToolTip>
#include <QScrollArea>
#include <QCollator>
#ifdef QZ_WS_X11
#include <QX11Info>
#include <xcb/xcb.h>
#include <xcb/xcb_atom.h>
#endif
#ifdef Q_OS_WIN
#include <windows.h>
#ifndef WM_DWMCOMPOSITIONCHANGED
#define WM_DWMCOMPOSITIONCHANGED 0x031E
#endif
#endif /* Q_OS_WIN */
static QKeySequence actionShortcut(QKeySequence shortcut, QKeySequence fallBack, QKeySequence shortcutRTL = QKeySequence(), QKeySequence fallbackRTL = QKeySequence())
{
if (QApplication::isRightToLeft() && (!shortcutRTL.isEmpty() || !fallbackRTL.isEmpty())) {
return (shortcutRTL.isEmpty() ? fallbackRTL : shortcutRTL);
}
else {
return (shortcut.isEmpty() ? fallBack : shortcut);
}
}
BrowserWindow::BrowserWindow(Qz::BrowserWindowType type, const QUrl &startUrl)
: QMainWindow(0)
, m_startUrl(startUrl)
, m_windowType(type)
, m_startTab(0)
, m_sideBarManager(new SideBarManager(this))
, m_statusBarMessage(new StatusBarMessage(this))
, m_hideNavigationTimer(0)
2011-03-02 16:57:41 +01:00
{
setObjectName("mainwindow");
2011-03-05 10:57:36 +01:00
setAttribute(Qt::WA_DeleteOnClose);
setWindowTitle(tr("QupZilla"));
setProperty("private", mApp->isPrivate());
2011-03-02 16:57:41 +01:00
setupUi();
setupMenu();
m_hideNavigationTimer = new QTimer(this);
m_hideNavigationTimer->setInterval(1000);
m_hideNavigationTimer->setSingleShot(true);
connect(m_hideNavigationTimer, SIGNAL(timeout()), this, SLOT(hideNavigationSlot()));
connect(mApp, SIGNAL(settingsReloaded()), this, SLOT(loadSettings()));
QTimer::singleShot(0, this, SLOT(postLaunch()));
if (mApp->isPrivate()) {
QzTools::setWmClass("QupZilla Browser (Private Window)", this);
}
else {
QzTools::setWmClass("QupZilla Browser", this);
}
2011-03-02 16:57:41 +01:00
}
BrowserWindow::~BrowserWindow()
{
mApp->plugins()->emitMainWindowDeleted(this);
foreach (const QPointer<QWidget> &pointer, m_deleteOnCloseWidgets) {
if (pointer) {
pointer->deleteLater();
}
}
}
void BrowserWindow::setStartTab(WebTab* tab)
{
m_startTab = tab;
}
void BrowserWindow::postLaunch()
{
loadSettings();
bool addTab = true;
QUrl startUrl;
2015-09-28 14:51:38 +02:00
switch (mApp->afterLaunch()) {
case MainApplication::OpenBlankPage:
startUrl = QUrl();
break;
2015-09-28 14:51:38 +02:00
case MainApplication::OpenSpeedDial:
startUrl = QUrl("qupzilla:speeddial");
break;
2015-09-28 14:51:38 +02:00
case MainApplication::OpenHomePage:
case MainApplication::RestoreSession:
startUrl = m_homepage;
break;
default:
break;
}
switch (m_windowType) {
case Qz::BW_FirstAppWindow:
if (mApp->isStartingAfterCrash()) {
addTab = false;
startUrl.clear();
m_tabWidget->addView(QUrl("qupzilla:restore"), Qz::NT_CleanSelectedTabAtTheEnd);
}
2015-09-28 14:51:38 +02:00
else if (mApp->afterLaunch() == MainApplication::RestoreSession && mApp->restoreManager()) {
addTab = !mApp->restoreSession(this, mApp->restoreManager()->restoreData());
}
else {
// Restore pinned tabs also when not restoring session
m_tabWidget->restorePinnedTabs();
}
break;
case Qz::BW_MacFirstWindow:
m_tabWidget->restorePinnedTabs();
// fallthrough
case Qz::BW_NewWindow:
addTab = true;
break;
case Qz::BW_OtherRestoredWindow:
addTab = false;
break;
}
show();
if (!m_startUrl.isEmpty()) {
startUrl = m_startUrl;
addTab = true;
}
if (m_startTab) {
addTab = false;
m_tabWidget->addView(m_startTab);
}
if (addTab) {
QNetworkRequest request(startUrl);
request.setRawHeader("X-QupZilla-UserLoadAction", QByteArray("1"));
m_tabWidget->addView(request, Qz::NT_CleanSelectedTabAtTheEnd);
if (startUrl.isEmpty() || startUrl.toString() == QLatin1String("qupzilla:speeddial")) {
locationBar()->setFocus();
}
}
// Something went really wrong .. add one tab
if (m_tabWidget->tabBar()->normalTabsCount() <= 0) {
QNetworkRequest request(m_homepage);
request.setRawHeader("X-QupZilla-UserLoadAction", QByteArray("1"));
m_tabWidget->addView(request, Qz::NT_SelectedTabAtTheEnd);
}
2012-03-05 13:16:34 +01:00
mApp->plugins()->emitMainWindowCreated(this);
emit startingCompleted();
raise();
activateWindow();
QTimer::singleShot(0, tabWidget()->tabBar(), SLOT(ensureVisible()));
}
void BrowserWindow::setupUi()
{
int locationBarWidth;
int websearchBarWidth;
QDesktopWidget* desktop = mApp->desktop();
int windowWidth = desktop->availableGeometry().width() / 1.3;
int windowHeight = desktop->availableGeometry().height() / 1.3;
Settings settings;
settings.beginGroup("Browser-View-Settings");
if (settings.value("WindowMaximised", false).toBool()) {
resize(windowWidth, windowHeight);
setWindowState(Qt::WindowMaximized);
}
else {
// Let the WM decides where to put new browser window
if ((m_windowType != Qz::BW_FirstAppWindow && m_windowType != Qz::BW_MacFirstWindow) && mApp->getWindow()) {
#ifdef Q_WS_WIN
// Windows WM places every new window in the middle of screen .. for some reason
QPoint p = mApp->getWindow()->geometry().topLeft();
p.setX(p.x() + 30);
p.setY(p.y() + 30);
if (!desktop->availableGeometry(mApp->getWindow()).contains(p)) {
p.setX(desktop->availableGeometry(mApp->getWindow()).x() + 30);
p.setY(desktop->availableGeometry(mApp->getWindow()).y() + 30);
}
setGeometry(QRect(p, mApp->getWindow()->size()));
#else
resize(mApp->getWindow()->size());
#endif
}
else if (!restoreGeometry(settings.value("WindowGeometry").toByteArray())) {
#ifdef Q_WS_WIN
setGeometry(QRect(desktop->availableGeometry(mApp->getWindow()).x() + 30,
desktop->availableGeometry(mApp->getWindow()).y() + 30, windowWidth, windowHeight));
#else
resize(windowWidth, windowHeight);
#endif
}
}
locationBarWidth = settings.value("LocationBarWidth", 480).toInt();
websearchBarWidth = settings.value("WebSearchBarWidth", 140).toInt();
settings.endGroup();
QWidget* widget = new QWidget(this);
widget->setCursor(Qt::ArrowCursor);
setCentralWidget(widget);
m_mainLayout = new QVBoxLayout(widget);
m_mainLayout->setContentsMargins(0, 0, 0, 0);
m_mainLayout->setSpacing(0);
m_mainSplitter = new QSplitter(this);
m_mainSplitter->setObjectName("sidebar-splitter");
m_tabWidget = new TabWidget(this);
m_superMenu = new QMenu(this);
m_navigationToolbar = new NavigationBar(this);
m_navigationToolbar->setSplitterSizes(locationBarWidth, websearchBarWidth);
m_bookmarksToolbar = new BookmarksToolbar(this);
m_navigationContainer = new NavigationContainer(this);
m_navigationContainer->addWidget(m_navigationToolbar);
m_navigationContainer->addWidget(m_bookmarksToolbar);
m_navigationContainer->setTabBar(m_tabWidget->tabBar());
m_mainSplitter->addWidget(m_tabWidget);
m_mainSplitter->setCollapsible(0, false);
m_mainLayout->addWidget(m_navigationContainer);
m_mainLayout->addWidget(m_mainSplitter);
statusBar()->setObjectName("mainwindow-statusbar");
statusBar()->setCursor(Qt::ArrowCursor);
m_progressBar = new ProgressBar(statusBar());
m_adblockIcon = new AdBlockIcon(this);
m_ipLabel = new QLabel(this);
m_ipLabel->setObjectName("statusbar-ip-label");
m_ipLabel->setToolTip(tr("IP Address of current page"));
statusBar()->addPermanentWidget(m_progressBar);
statusBar()->addPermanentWidget(m_ipLabel);
statusBar()->addPermanentWidget(m_adblockIcon);
// Workaround for Oxygen tooltips not having transparent background
QPalette pal = QToolTip::palette();
QColor col = pal.window().color();
col.setAlpha(0);
pal.setColor(QPalette::Window, col);
QToolTip::setPalette(pal);
// Set some sane minimum width
setMinimumWidth(300);
}
void BrowserWindow::setupMenu()
{
#ifdef Q_OS_MAC
static MainMenu* macMainMenu = 0;
if (!macMainMenu) {
macMainMenu = new MainMenu(this, 0);
macMainMenu->initMenuBar(new QMenuBar(0));
}
else {
macMainMenu->setWindow(this);
}
m_mainMenu = macMainMenu;
#else
setMenuBar(new MenuBar(this));
m_mainMenu = new MainMenu(this, this);
m_mainMenu->initMenuBar(menuBar());
m_mainMenu->initSuperMenu(m_superMenu);
#endif
// Setup other shortcuts
QShortcut* reloadBypassCacheAction = new QShortcut(QKeySequence(QSL("Ctrl+F5")), this);
QShortcut* reloadBypassCacheAction2 = new QShortcut(QKeySequence(QSL("Ctrl+Shift+R")), this);
connect(reloadBypassCacheAction, SIGNAL(activated()), this, SLOT(reloadBypassCache()));
connect(reloadBypassCacheAction2, SIGNAL(activated()), this, SLOT(reloadBypassCache()));
QShortcut* closeTabAction = new QShortcut(QKeySequence(QSL("Ctrl+W")), this);
QShortcut* closeTabAction2 = new QShortcut(QKeySequence(QSL("Ctrl+F4")), this);
connect(closeTabAction, SIGNAL(activated()), this, SLOT(closeTab()));
connect(closeTabAction2, SIGNAL(activated()), this, SLOT(closeTab()));
QShortcut* reloadAction = new QShortcut(QKeySequence("Ctrl+R"), this);
connect(reloadAction, SIGNAL(activated()), this, SLOT(reload()));
QShortcut* openLocationAction = new QShortcut(QKeySequence("Alt+D"), this);
connect(openLocationAction, SIGNAL(activated()), this, SLOT(openLocation()));
QShortcut* inspectorAction = new QShortcut(QKeySequence(QSL("F12")), this);
connect(inspectorAction, SIGNAL(activated()), this, SLOT(showWebInspector()));
}
QAction* BrowserWindow::createEncodingAction(const QString &codecName,
const QString &activeCodecName, QMenu* menu)
{
QAction* action = new QAction(codecName, menu);
action->setData(codecName);
action->setCheckable(true);
connect(action, SIGNAL(triggered()), this, SLOT(changeEncoding()));
if (activeCodecName.compare(codecName, Qt::CaseInsensitive) == 0) {
action->setChecked(true);
}
return action;
}
void BrowserWindow::createEncodingSubMenu(const QString &name, QStringList &codecNames, QMenu* menu)
{
if (codecNames.isEmpty()) {
return;
}
QCollator collator;
collator.setNumericMode(true);
std::sort(codecNames.begin(), codecNames.end(), [collator](const QString &a, const QString &b) {
return collator.compare(a, b) < 0;
});
QMenu* subMenu = new QMenu(name, menu);
const QString activeCodecName = QWebEngineSettings::globalSettings()->defaultTextEncoding();
foreach (const QString &codecName, codecNames) {
subMenu->addAction(createEncodingAction(codecName, activeCodecName, subMenu));
}
menu->addMenu(subMenu);
}
void BrowserWindow::loadSettings()
2011-03-02 16:57:41 +01:00
{
Settings settings;
2011-03-02 16:57:41 +01:00
//Url settings
settings.beginGroup("Web-URL-Settings");
m_homepage = settings.value("homepage", "qupzilla:start").toUrl();
2011-03-02 16:57:41 +01:00
settings.endGroup();
//Browser Window settings
settings.beginGroup("Browser-View-Settings");
bool showStatusBar = settings.value("showStatusBar", true).toBool();
bool showReloadButton = settings.value("showReloadButton", true).toBool();
bool showHomeButton = settings.value("showHomeButton", true).toBool();
bool showBackForwardButtons = settings.value("showBackForwardButtons", true).toBool();
bool showAddTabButton = settings.value("showAddTabButton", false).toBool();
bool showWebSearchBar = settings.value("showWebSearchBar", true).toBool();
bool showBookmarksToolbar = settings.value("showBookmarksToolbar", true).toBool();
bool showNavigationToolbar = settings.value("showNavigationToolbar", true).toBool();
bool showMenuBar = settings.value("showMenubar", true).toBool();
m_sideBarWidth = settings.value("SideBarWidth", 250).toInt();
m_webViewWidth = settings.value("WebViewWidth", 2000).toInt();
const QString activeSideBar = settings.value("SideBar", "None").toString();
// Make sure both menubar and navigationbar are not hidden
// Fixes #781
if (!showNavigationToolbar) {
showMenuBar = true;
settings.setValue("showMenubar", true);
}
2011-03-02 16:57:41 +01:00
settings.endGroup();
settings.beginGroup("Shortcuts");
m_useTabNumberShortcuts = settings.value("useTabNumberShortcuts", true).toBool();
m_useSpeedDialNumberShortcuts = settings.value("useSpeedDialNumberShortcuts", true).toBool();
m_useSingleKeyShortcuts = settings.value("useSingleKeyShortcuts", false).toBool();
settings.endGroup();
settings.beginGroup("Web-Browser-Settings");
QAction *quitAction = m_mainMenu->action(QSL("Standard/Quit"));
if (settings.value("closeAppWithCtrlQ", true).toBool()) {
quitAction->setShortcut(actionShortcut(QKeySequence::Quit, QKeySequence(QSL("Ctrl+Q"))));
} else {
quitAction->setShortcut(QKeySequence());
}
settings.endGroup();
m_adblockIcon->setEnabled(settings.value("AdBlock/enabled", true).toBool());
2011-03-02 16:57:41 +01:00
statusBar()->setVisible(!isFullScreen() && showStatusBar);
2011-03-02 16:57:41 +01:00
m_bookmarksToolbar->setVisible(showBookmarksToolbar);
m_navigationToolbar->setVisible(showNavigationToolbar);
#ifndef Q_OS_MAC
menuBar()->setVisible(!isFullScreen() && showMenuBar);
#endif
2011-03-02 16:57:41 +01:00
m_navigationToolbar->setSuperMenuVisible(!showMenuBar);
m_navigationToolbar->buttonReloadStop()->setVisible(showReloadButton);
m_navigationToolbar->buttonHome()->setVisible(showHomeButton);
m_navigationToolbar->buttonBack()->setVisible(showBackForwardButtons);
m_navigationToolbar->buttonForward()->setVisible(showBackForwardButtons);
m_navigationToolbar->webSearchBar()->setVisible(showWebSearchBar);
m_navigationToolbar->buttonAddTab()->setVisible(showAddTabButton);
2011-03-02 16:57:41 +01:00
m_sideBarManager->showSideBar(activeSideBar, false);
2011-03-02 16:57:41 +01:00
}
void BrowserWindow::goForward()
{
weView()->forward();
}
void BrowserWindow::reload()
{
weView()->reload();
}
void BrowserWindow::reloadBypassCache()
{
weView()->reloadBypassCache();
}
void BrowserWindow::goBack()
{
weView()->back();
}
TabbedWebView* BrowserWindow::weView() const
{
return weView(m_tabWidget->currentIndex());
}
TabbedWebView* BrowserWindow::weView(int index) const
{
WebTab* webTab = qobject_cast<WebTab*>(m_tabWidget->widget(index));
if (!webTab) {
return 0;
}
return webTab->webView();
}
LocationBar* BrowserWindow::locationBar() const
{
return qobject_cast<LocationBar*>(m_tabWidget->locationBars()->currentWidget());
}
TabWidget* BrowserWindow::tabWidget() const
{
return m_tabWidget;
}
BookmarksToolbar* BrowserWindow::bookmarksToolbar() const
{
return m_bookmarksToolbar;
}
StatusBarMessage* BrowserWindow::statusBarMessage() const
{
return m_statusBarMessage;
}
NavigationBar* BrowserWindow::navigationBar() const
{
return m_navigationToolbar;
}
SideBarManager* BrowserWindow::sideBarManager() const
{
return m_sideBarManager;
}
QLabel* BrowserWindow::ipLabel() const
{
return m_ipLabel;
}
AdBlockIcon* BrowserWindow::adBlockIcon() const
{
return m_adblockIcon;
}
QMenu* BrowserWindow::superMenu() const
2011-03-02 16:57:41 +01:00
{
return m_superMenu;
2011-03-02 16:57:41 +01:00
}
QUrl BrowserWindow::homepageUrl() const
{
return m_homepage;
}
Qz::BrowserWindowType BrowserWindow::windowType() const
{
return m_windowType;
}
QAction* BrowserWindow::action(const QString &name) const
{
return m_mainMenu->action(name);
}
void BrowserWindow::setWindowTitle(const QString &t)
{
QString title = t;
if (mApp->isPrivate()) {
title.append(tr(" (Private Browsing)"));
}
QMainWindow::setWindowTitle(title);
}
void BrowserWindow::changeEncoding()
{
if (QAction* action = qobject_cast<QAction*>(sender())) {
const QString encoding = action->data().toString();
QWebEngineSettings::globalSettings()->setDefaultTextEncoding(encoding);
Settings settings;
settings.setValue("Web-Browser-Settings/DefaultEncoding", encoding);
weView()->reload();
}
}
void BrowserWindow::bookmarkPage()
2011-03-02 16:57:41 +01:00
{
TabbedWebView* view = weView();
BookmarksTools::addBookmarkDialog(this, view->url(), view->title());
2011-03-02 16:57:41 +01:00
}
void BrowserWindow::bookmarkAllTabs()
{
BookmarksTools::bookmarkAllTabsDialog(this, m_tabWidget);
}
void BrowserWindow::addBookmark(const QUrl &url, const QString &title)
2011-03-02 16:57:41 +01:00
{
BookmarksTools::addBookmarkDialog(this, url, title);
2011-03-02 16:57:41 +01:00
}
void BrowserWindow::goHome()
{
loadAddress(m_homepage);
}
void BrowserWindow::goHomeInNewTab()
{
m_tabWidget->addView(m_homepage, Qz::NT_SelectedTab);
}
void BrowserWindow::loadActionUrl(QObject* obj)
2011-03-02 16:57:41 +01:00
{
if (!obj) {
obj = sender();
}
if (QAction* action = qobject_cast<QAction*>(obj)) {
2011-03-02 16:57:41 +01:00
loadAddress(action->data().toUrl());
}
}
void BrowserWindow::loadActionUrlInNewTab(QObject* obj)
2011-09-19 20:49:39 +02:00
{
if (!obj) {
obj = sender();
}
if (QAction* action = qobject_cast<QAction*>(obj)) {
m_tabWidget->addView(action->data().toUrl(), Qz::NT_SelectedTabAtTheEnd);
2011-09-19 20:49:39 +02:00
}
}
void BrowserWindow::loadAddress(const QUrl &url)
{
if (weView()->webTab()->isPinned()) {
int index = m_tabWidget->addView(url, qzSettings->newTabPosition);
weView(index)->setFocus();
}
else {
weView()->setFocus();
weView()->load(url);
}
}
void BrowserWindow::showHistoryManager()
2011-03-02 16:57:41 +01:00
{
mApp->browsingLibrary()->showHistory(this);
2011-03-02 16:57:41 +01:00
}
void BrowserWindow::showSource(WebView *view)
2011-03-02 16:57:41 +01:00
{
if (!view)
view = weView();
view->showSource();
2011-03-02 16:57:41 +01:00
}
SideBar* BrowserWindow::addSideBar()
{
if (m_sideBar) {
return m_sideBar.data();
}
m_sideBar = new SideBar(m_sideBarManager, this);
m_mainSplitter->insertWidget(0, m_sideBar.data());
m_mainSplitter->setCollapsible(0, false);
m_mainSplitter->setSizes(QList<int>() << m_sideBarWidth << m_webViewWidth);
return m_sideBar.data();
}
void BrowserWindow::saveSideBarWidth()
{
// That +1 is important here, without it, the sidebar width would
// decrease by 1 pixel every close
m_sideBarWidth = m_mainSplitter->sizes().at(0) + 1;
m_webViewWidth = width() - m_sideBarWidth;
}
void BrowserWindow::toggleShowMenubar()
2011-03-02 16:57:41 +01:00
{
#ifdef Q_OS_MAC
2014-03-13 15:58:39 +01:00
// We use one shared global menubar on Mac that can't be hidden
return;
#endif
2011-03-02 16:57:41 +01:00
setUpdatesEnabled(false);
menuBar()->setVisible(!menuBar()->isVisible());
m_navigationToolbar->setSuperMenuVisible(!menuBar()->isVisible());
setUpdatesEnabled(true);
2011-03-02 16:57:41 +01:00
Settings().setValue("Browser-View-Settings/showMenubar", menuBar()->isVisible());
// Make sure we show Navigation Toolbar when Menu Bar is hidden
if (!m_navigationToolbar->isVisible() && !menuBar()->isVisible()) {
toggleShowNavigationToolbar();
}
}
2011-03-02 16:57:41 +01:00
void BrowserWindow::toggleShowStatusBar()
{
setUpdatesEnabled(false);
statusBar()->setVisible(!statusBar()->isVisible());
setUpdatesEnabled(true);
Settings().setValue("Browser-View-Settings/showStatusBar", statusBar()->isVisible());
}
void BrowserWindow::toggleShowBookmarksToolbar()
{
setUpdatesEnabled(false);
m_bookmarksToolbar->setVisible(!m_bookmarksToolbar->isVisible());
setUpdatesEnabled(true);
Settings().setValue("Browser-View-Settings/showBookmarksToolbar", m_bookmarksToolbar->isVisible());
}
void BrowserWindow::toggleShowNavigationToolbar()
{
setUpdatesEnabled(false);
m_navigationToolbar->setVisible(!m_navigationToolbar->isVisible());
setUpdatesEnabled(true);
Settings().setValue("Browser-View-Settings/showNavigationToolbar", m_navigationToolbar->isVisible());
#ifndef Q_OS_MAC
// Make sure we show Menu Bar when Navigation Toolbar is hidden
if (!m_navigationToolbar->isVisible() && !menuBar()->isVisible()) {
toggleShowMenubar();
}
#endif
}
void BrowserWindow::toggleTabsOnTop(bool enable)
{
qzSettings->tabsOnTop = enable;
m_navigationContainer->toggleTabsOnTop(enable);
2011-03-02 16:57:41 +01:00
}
void BrowserWindow::toggleFullScreen()
{
if (isFullScreen()) {
showNormal();
}
else {
showFullScreen();
}
2011-03-02 16:57:41 +01:00
}
2014-05-20 18:35:49 +02:00
void BrowserWindow::toggleOfflineMode()
{
bool enable = !qzSettings->workOffline;
Settings().setValue("Web-Browser-Settings/WorkOffline", enable);
2014-05-20 18:35:49 +02:00
qzSettings->workOffline = enable;
}
void BrowserWindow::showWebInspector()
2011-03-02 16:57:41 +01:00
{
if (weView() && weView()->webTab()) {
weView()->webTab()->showWebInspector();
}
2011-03-02 16:57:41 +01:00
}
void BrowserWindow::refreshHistory()
{
m_navigationToolbar->refreshHistory();
}
void BrowserWindow::currentTabChanged()
{
TabbedWebView* view = weView();
if (!view) {
return;
}
setWindowTitle(tr("%1 - QupZilla").arg(view->webTab()->title()));
m_ipLabel->setText(view->getIp());
view->setFocus();
SearchToolBar* search = searchToolBar();
if (search) {
search->setWebView(view);
}
updateLoadingActions();
// Setting correct tab order (LocationBar -> WebSearchBar -> WebView)
setTabOrder(locationBar(), m_navigationToolbar->webSearchBar());
setTabOrder(m_navigationToolbar->webSearchBar(), view);
}
void BrowserWindow::updateLoadingActions()
{
TabbedWebView* view = weView();
if (!view) {
return;
}
bool isLoading = view->isLoading();
m_ipLabel->setVisible(!isLoading);
m_progressBar->setVisible(isLoading);
action(QSL("View/Stop"))->setEnabled(isLoading);
action(QSL("View/Reload"))->setEnabled(!isLoading);
if (isLoading) {
m_progressBar->setValue(view->loadingProgress());
m_navigationToolbar->showStopButton();
}
else {
m_navigationToolbar->showReloadButton();
}
}
void BrowserWindow::addDeleteOnCloseWidget(QWidget* widget)
{
if (!m_deleteOnCloseWidgets.contains(widget)) {
m_deleteOnCloseWidgets.append(widget);
}
}
void BrowserWindow::restoreWindowState(const RestoreManager::WindowData &d)
{
restoreState(d.windowState);
m_tabWidget->restoreState(d.tabsState, d.currentTab);
}
void BrowserWindow::createToolbarsMenu(QMenu* menu)
{
removeActions(menu->actions());
menu->clear();
QAction* action;
#ifndef Q_OS_MAC
action = menu->addAction(tr("&Menu Bar"), this, SLOT(toggleShowMenubar()));
action->setCheckable(true);
action->setChecked(menuBar()->isVisible());
#endif
action = menu->addAction(tr("&Navigation Toolbar"), this, SLOT(toggleShowNavigationToolbar()));
action->setCheckable(true);
action->setChecked(m_navigationToolbar->isVisible());
action = menu->addAction(tr("&Bookmarks Toolbar"), this, SLOT(toggleShowBookmarksToolbar()));
action->setCheckable(true);
action->setChecked(m_bookmarksToolbar->isVisible());
menu->addSeparator();
action = menu->addAction(tr("&Tabs on Top"), this, SLOT(toggleTabsOnTop(bool)));
action->setCheckable(true);
action->setChecked(qzSettings->tabsOnTop);
addActions(menu->actions());
}
void BrowserWindow::createSidebarsMenu(QMenu* menu)
2011-03-02 16:57:41 +01:00
{
m_sideBarManager->createMenu(menu);
}
void BrowserWindow::createEncodingMenu(QMenu* menu)
{
const QString activeCodecName = QWebEngineSettings::globalSettings()->defaultTextEncoding();
QStringList isoCodecs;
QStringList utfCodecs;
QStringList windowsCodecs;
QStringList isciiCodecs;
QStringList ibmCodecs;
QStringList otherCodecs;
QStringList allCodecs;
foreach (const int mib, QTextCodec::availableMibs()) {
const QString codecName = QString::fromUtf8(QTextCodec::codecForMib(mib)->name());
if (!allCodecs.contains(codecName))
allCodecs.append(codecName);
else
continue;
if (codecName.startsWith(QLatin1String("ISO")))
isoCodecs.append(codecName);
else if (codecName.startsWith(QLatin1String("UTF")))
utfCodecs.append(codecName);
else if (codecName.startsWith(QLatin1String("windows")))
windowsCodecs.append(codecName);
else if (codecName.startsWith(QLatin1String("Iscii")))
isciiCodecs.append(codecName);
else if (codecName.startsWith(QLatin1String("IBM")))
ibmCodecs.append(codecName);
else if (codecName == QLatin1String("System"))
menu->addAction(createEncodingAction(codecName, activeCodecName, menu));
else
otherCodecs.append(codecName);
}
if (!menu->isEmpty())
menu->addSeparator();
createEncodingSubMenu("ISO", isoCodecs, menu);
createEncodingSubMenu("UTF", utfCodecs, menu);
createEncodingSubMenu("Windows", windowsCodecs, menu);
createEncodingSubMenu("Iscii", isciiCodecs, menu);
createEncodingSubMenu("IBM", ibmCodecs, menu);
createEncodingSubMenu(tr("Other"), otherCodecs, menu);
2011-03-02 16:57:41 +01:00
}
void BrowserWindow::removeActions(const QList<QAction *> &actions)
{
foreach (QAction *action, actions) {
removeAction(action);
}
}
void BrowserWindow::addTab()
{
m_tabWidget->addView(QUrl(), Qz::NT_SelectedNewEmptyTab, true);
}
void BrowserWindow::webSearch()
{
m_navigationToolbar->webSearchBar()->setFocus();
m_navigationToolbar->webSearchBar()->selectAll();
}
void BrowserWindow::searchOnPage()
2011-03-02 16:57:41 +01:00
{
SearchToolBar* toolBar = searchToolBar();
if (!toolBar) {
const int searchPos = 2;
toolBar = new SearchToolBar(weView(), this);
m_mainLayout->insertWidget(searchPos, toolBar);
2011-03-02 16:57:41 +01:00
}
toolBar->focusSearchLine();
2011-03-02 16:57:41 +01:00
}
void BrowserWindow::openFile()
2011-03-02 16:57:41 +01:00
{
const QString fileTypes = QString("%1(*.html *.htm *.shtml *.shtm *.xhtml);;"
"%2(*.png *.jpg *.jpeg *.bmp *.gif *.svg *.tiff);;"
"%3(*.txt);;"
"%4(*.*)").arg(tr("HTML files"), tr("Image files"), tr("Text files"), tr("All files"));
const QString filePath = QzTools::getOpenFileName("MainWindow-openFile", this, tr("Open file..."), QDir::homePath(), fileTypes);
if (!filePath.isEmpty()) {
loadAddress(QUrl::fromLocalFile(filePath));
}
2011-03-02 16:57:41 +01:00
}
void BrowserWindow::openLocation()
{
if (isFullScreen()) {
showNavigationWithFullScreen();
}
locationBar()->setFocus();
locationBar()->selectAll();
}
bool BrowserWindow::fullScreenNavigationVisible() const
{
return m_navigationContainer->isVisible();
}
void BrowserWindow::showNavigationWithFullScreen()
{
if (m_hideNavigationTimer->isActive()) {
m_hideNavigationTimer->stop();
}
m_navigationContainer->show();
}
void BrowserWindow::hideNavigationWithFullScreen()
{
if (!m_hideNavigationTimer->isActive()) {
m_hideNavigationTimer->start();
}
}
void BrowserWindow::hideNavigationSlot()
{
TabbedWebView* view = weView();
bool mouseInView = view && view->underMouse();
if (isFullScreen() && mouseInView) {
m_navigationContainer->hide();
}
}
bool BrowserWindow::event(QEvent* event)
2011-03-02 16:57:41 +01:00
{
switch (event->type()) {
case QEvent::WindowStateChange: {
QWindowStateChangeEvent* ev = static_cast<QWindowStateChangeEvent*>(event);
if (!(ev->oldState() & Qt::WindowFullScreen) && windowState() & Qt::WindowFullScreen) {
// Enter fullscreen
m_windowStates = ev->oldState();
m_statusBarVisible = statusBar()->isVisible();
#ifndef Q_OS_MAC
m_menuBarVisible = menuBar()->isVisible();
menuBar()->hide();
#endif
statusBar()->hide();
m_navigationContainer->hide();
m_navigationToolbar->setSuperMenuVisible(false);
m_navigationToolbar->buttonExitFullscreen()->setVisible(true);
}
else if (ev->oldState() & Qt::WindowFullScreen && !(windowState() & Qt::WindowFullScreen)) {
// Leave fullscreen
setWindowState(m_windowStates);
statusBar()->setVisible(m_statusBarVisible);
#ifndef Q_OS_MAC
menuBar()->setVisible(m_menuBarVisible);
#endif
m_navigationContainer->show();
m_navigationToolbar->setSuperMenuVisible(!m_menuBarVisible);
m_navigationToolbar->buttonExitFullscreen()->setVisible(false);
}
if (m_hideNavigationTimer) {
m_hideNavigationTimer->stop();
}
break;
2011-03-02 16:57:41 +01:00
}
default:
break;
}
return QMainWindow::event(event);
}
void BrowserWindow::printPage(QWebEngineFrame* frame)
2011-03-02 16:57:41 +01:00
{
2015-08-30 17:42:58 +02:00
Q_UNUSED(frame)
2015-08-29 18:32:57 +02:00
#if QTWEBENGINE_DISABLED
2011-03-02 16:57:41 +01:00
QPrintPreviewDialog* dialog = new QPrintPreviewDialog(this);
dialog->setAttribute(Qt::WA_DeleteOnClose);
dialog->resize(800, 750);
dialog->printer()->setCreator(tr("QupZilla %1 (%2)").arg(Qz::VERSION, Qz::WWWADDRESS));
if (!frame) {
dialog->printer()->setDocName(QzTools::getFileNameFromUrl(weView()->url()));
connect(dialog, SIGNAL(paintRequested(QPrinter*)), weView(), SLOT(print(QPrinter*)));
}
else {
dialog->printer()->setDocName(QzTools::getFileNameFromUrl(QzTools::frameUrl(frame)));
connect(dialog, SIGNAL(paintRequested(QPrinter*)), frame, SLOT(print(QPrinter*)));
}
dialog->open();
2015-08-29 18:32:57 +02:00
#endif
2011-03-02 16:57:41 +01:00
}
void BrowserWindow::savePageScreen()
{
#if QTWEBENGINE_DISABLED
PageScreen* dialog = new PageScreen(weView(), this);
dialog->show();
#endif
}
void BrowserWindow::resizeEvent(QResizeEvent* event)
{
m_bookmarksToolbar->setMaximumWidth(width());
QMainWindow::resizeEvent(event);
}
void BrowserWindow::keyPressEvent(QKeyEvent* event)
{
if (mApp->plugins()->processKeyPress(Qz::ON_BrowserWindow, this, event)) {
2012-03-05 13:16:34 +01:00
return;
}
int number = -1;
TabbedWebView* view = weView();
switch (event->key()) {
case Qt::Key_Back:
if (view) {
view->back();
event->accept();
}
break;
case Qt::Key_Forward:
if (view) {
view->forward();
event->accept();
}
break;
case Qt::Key_Stop:
if (view) {
view->stop();
event->accept();
}
break;
case Qt::Key_Refresh:
if (view) {
view->reload();
event->accept();
}
break;
case Qt::Key_HomePage:
goHome();
event->accept();
break;
case Qt::Key_Favorites:
mApp->browsingLibrary()->showBookmarks(this);
event->accept();
break;
case Qt::Key_Search:
searchOnPage();
event->accept();
break;
case Qt::Key_F6:
case Qt::Key_OpenUrl:
openLocation();
event->accept();
break;
case Qt::Key_History:
showHistoryManager();
event->accept();
break;
case Qt::Key_AddFavorite:
bookmarkPage();
event->accept();
break;
case Qt::Key_News:
action(QSL("Tools/RssReader"))->trigger();
event->accept();
break;
case Qt::Key_Tools:
action(QSL("Standard/Preferences"))->trigger();
event->accept();
break;
case Qt::Key_Tab:
if (event->modifiers() == Qt::ControlModifier) {
m_tabWidget->nextTab();
event->accept();
}
break;
case Qt::Key_Backtab:
if (event->modifiers() == (Qt::ControlModifier + Qt::ShiftModifier)) {
m_tabWidget->previousTab();
event->accept();
}
break;
case Qt::Key_PageDown:
if (event->modifiers() == Qt::ControlModifier) {
m_tabWidget->nextTab();
event->accept();
}
break;
case Qt::Key_PageUp:
if (event->modifiers() == Qt::ControlModifier) {
m_tabWidget->previousTab();
event->accept();
}
break;
case Qt::Key_Equal:
if (view && event->modifiers() == Qt::ControlModifier) {
view->zoomIn();
event->accept();
}
break;
case Qt::Key_I:
if (event->modifiers() == Qt::ControlModifier) {
action(QSL("Tools/SiteInfo"))->trigger();
event->accept();
}
break;
case Qt::Key_U:
if (event->modifiers() == Qt::ControlModifier) {
action(QSL("View/PageSource"))->trigger();
event->accept();
}
break;
case Qt::Key_F:
if (event->modifiers() == Qt::ControlModifier) {
action(QSL("Edit/Find"))->trigger();
event->accept();
}
break;
case Qt::Key_Slash:
if (m_useSingleKeyShortcuts) {
action(QSL("Edit/Find"))->trigger();
event->accept();
}
break;
case Qt::Key_1:
number = 1;
break;
case Qt::Key_2:
number = 2;
break;
case Qt::Key_3:
number = 3;
break;
case Qt::Key_4:
number = 4;
break;
case Qt::Key_5:
number = 5;
break;
case Qt::Key_6:
number = 6;
break;
case Qt::Key_7:
number = 7;
break;
case Qt::Key_8:
number = 8;
break;
case Qt::Key_9:
number = 9;
break;
default:
break;
}
if (number != -1) {
if (event->modifiers() & Qt::AltModifier && m_useTabNumberShortcuts) {
if (number == 9) {
number = m_tabWidget->count();
}
m_tabWidget->setCurrentIndex(number - 1);
return;
}
if (event->modifiers() & Qt::ControlModifier && m_useSpeedDialNumberShortcuts) {
const QUrl url = mApp->plugins()->speedDial()->urlForShortcut(number - 1);
if (url.isValid()) {
loadAddress(url);
return;
}
}
if (event->modifiers() == Qt::NoModifier && m_useSingleKeyShortcuts) {
if (number == 1)
m_tabWidget->previousTab();
if (number == 2)
m_tabWidget->nextTab();
}
}
QMainWindow::keyPressEvent(event);
}
void BrowserWindow::keyReleaseEvent(QKeyEvent* event)
2012-03-05 13:16:34 +01:00
{
if (mApp->plugins()->processKeyRelease(Qz::ON_BrowserWindow, this, event)) {
2012-03-05 13:16:34 +01:00
return;
}
QMainWindow::keyReleaseEvent(event);
}
void BrowserWindow::closeEvent(QCloseEvent* event)
2011-03-02 16:57:41 +01:00
{
if (mApp->isClosing()) {
2011-03-02 16:57:41 +01:00
return;
}
Settings settings;
bool askOnClose = settings.value("Browser-Tabs-Settings/AskOnClosing", true).toBool();
2015-09-28 14:51:38 +02:00
if (mApp->afterLaunch() == MainApplication::RestoreSession && mApp->windowCount() == 1) {
askOnClose = false;
}
if (askOnClose && m_tabWidget->normalTabsCount() > 1) {
CheckBoxDialog dialog(QDialogButtonBox::Yes | QDialogButtonBox::No, this);
dialog.setText(tr("There are still %n open tabs and your session won't be stored. \nAre you sure to close this window?", "", m_tabWidget->count()));
dialog.setCheckBoxText(tr("Don't ask again"));
dialog.setWindowTitle(tr("There are still open tabs"));
dialog.setIcon(IconProvider::standardIcon(QStyle::SP_MessageBoxWarning));
if (dialog.exec() != QDialog::Accepted) {
event->ignore();
return;
}
if (dialog.isChecked()) {
settings.setValue("Browser-Tabs-Settings/AskOnClosing", false);
}
}
#ifndef Q_OS_MAC
if (mApp->windowCount() == 1) {
if (quitApp()) {
2012-01-10 21:15:03 +01:00
event->accept();
}
else {
event->ignore();
}
2011-03-05 10:57:36 +01:00
return;
2011-03-02 16:57:41 +01:00
}
#endif
2011-03-02 16:57:41 +01:00
event->accept();
}
SearchToolBar* BrowserWindow::searchToolBar() const
{
SearchToolBar* toolBar = 0;
const int searchPos = 2;
if (m_mainLayout->count() == searchPos + 1) {
toolBar = qobject_cast<SearchToolBar*>(m_mainLayout->itemAt(searchPos)->widget());
}
return toolBar;
}
void BrowserWindow::closeWindow()
{
#ifdef Q_OS_MAC
2014-03-13 15:58:39 +01:00
close();
return;
#endif
2014-03-13 15:58:39 +01:00
if (mApp->windowCount() > 1) {
close();
}
}
bool BrowserWindow::quitApp()
2011-03-02 16:57:41 +01:00
{
if (m_sideBar) {
saveSideBarWidth();
}
if (!mApp->isPrivate()) {
Settings settings;
settings.beginGroup("Browser-View-Settings");
settings.setValue("WindowMaximised", windowState().testFlag(Qt::WindowMaximized));
settings.setValue("LocationBarWidth", m_navigationToolbar->splitter()->sizes().at(0));
settings.setValue("WebSearchBarWidth", m_navigationToolbar->splitter()->sizes().at(1));
settings.setValue("SideBarWidth", m_sideBarWidth);
settings.setValue("WebViewWidth", m_webViewWidth);
if (!isFullScreen()) {
settings.setValue("WindowGeometry", saveGeometry());
}
settings.endGroup();
2011-03-02 16:57:41 +01:00
}
mApp->quitApplication();
2011-03-05 13:16:13 +01:00
return true;
2011-03-02 16:57:41 +01:00
}
void BrowserWindow::closeTab()
{
// Don't close pinned tabs with keyboard shortcuts (Ctrl+W, Ctrl+F4)
if (weView() && !weView()->webTab()->isPinned()) {
m_tabWidget->closeTab();
}
}
QByteArray BrowserWindow::saveState(int version) const
{
#ifdef QZ_WS_X11
QByteArray data;
QDataStream stream(&data, QIODevice::WriteOnly);
stream << QMainWindow::saveState(version);
stream << getCurrentVirtualDesktop();
return data;
#else
return QMainWindow::saveState(version);
#endif
}
bool BrowserWindow::restoreState(const QByteArray &state, int version)
{
#ifdef QZ_WS_X11
QByteArray windowState;
int desktopId = -1;
QDataStream stream(state);
stream >> windowState;
stream >> desktopId;
moveToVirtualDesktop(desktopId);
return QMainWindow::restoreState(windowState, version);
#else
2012-09-07 20:31:55 +02:00
return QMainWindow::restoreState(state, version);
#endif
}
#ifdef QZ_WS_X11
int BrowserWindow::getCurrentVirtualDesktop() const
{
if (!QX11Info::isPlatformX11())
return 0;
xcb_intern_atom_cookie_t intern_atom;
xcb_intern_atom_reply_t *atom_reply = 0;
xcb_atom_t atom;
xcb_get_property_cookie_t cookie;
xcb_get_property_reply_t *reply = 0;
uint32_t value;
intern_atom = xcb_intern_atom(QX11Info::connection(), false, qstrlen("_NET_WM_DESKTOP"), "_NET_WM_DESKTOP");
atom_reply = xcb_intern_atom_reply(QX11Info::connection(), intern_atom, 0);
if (!atom_reply)
goto error;
atom = atom_reply->atom;
cookie = xcb_get_property(QX11Info::connection(), false, winId(), atom, XCB_ATOM_CARDINAL, 0, 1);
reply = xcb_get_property_reply(QX11Info::connection(), cookie, 0);
if (!reply || reply->type != XCB_ATOM_CARDINAL || reply->value_len != 1 || reply->format != sizeof(uint32_t) * 8)
goto error;
value = *reinterpret_cast<uint32_t*>(xcb_get_property_value(reply));
free(reply);
free(atom_reply);
return value;
error:
free(reply);
free(atom_reply);
return 0;
}
void BrowserWindow::moveToVirtualDesktop(int desktopId)
{
if (!QX11Info::isPlatformX11())
return;
// Don't move when window is already visible or it is first app window
if (desktopId < 0 || isVisible() || m_windowType == Qz::BW_FirstAppWindow)
return;
xcb_intern_atom_cookie_t intern_atom;
xcb_intern_atom_reply_t *atom_reply = 0;
xcb_atom_t atom;
intern_atom = xcb_intern_atom(QX11Info::connection(), false, qstrlen("_NET_WM_DESKTOP"), "_NET_WM_DESKTOP");
atom_reply = xcb_intern_atom_reply(QX11Info::connection(), intern_atom, 0);
if (!atom_reply)
goto error;
atom = atom_reply->atom;
xcb_change_property(QX11Info::connection(), XCB_PROP_MODE_REPLACE, winId(), atom,
XCB_ATOM_CARDINAL, 32, 1, (const void*) &desktopId);
error:
free(atom_reply);
}
#endif