diff --git a/src/lib/app/mainapplication.cpp b/src/lib/app/mainapplication.cpp index 360d3efd..919fc74a 100644 --- a/src/lib/app/mainapplication.cpp +++ b/src/lib/app/mainapplication.cpp @@ -1,1271 +1,1275 @@ /* ============================================================ * Falkon - Qt web browser * Copyright (C) 2010-2018 David Rosca * * 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 . * ============================================================ */ #include "mainapplication.h" #include "history.h" #include "qztools.h" #include "updater.h" #include "autofill.h" #include "settings.h" #include "autosaver.h" #include "datapaths.h" #include "tabwidget.h" #include "cookiejar.h" #include "bookmarks.h" #include "qzsettings.h" #include "proxystyle.h" #include "pluginproxy.h" #include "iconprovider.h" #include "browserwindow.h" #include "checkboxdialog.h" #include "networkmanager.h" #include "profilemanager.h" #include "restoremanager.h" #include "browsinglibrary.h" #include "downloadmanager.h" #include "clearprivatedata.h" #include "useragentmanager.h" #include "commandlineoptions.h" #include "searchenginesmanager.h" #include "desktopnotificationsfactory.h" #include "html5permissions/html5permissionsmanager.h" #include "scripts.h" #include "sessionmanager.h" #include "closedwindowsmanager.h" #include "protocolhandlermanager.h" #include "../config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if QTWEBENGINECORE_VERSION >= QT_VERSION_CHECK(5, 13, 0) #include #endif #ifdef Q_OS_WIN #include #include #include #endif #include #if defined(Q_OS_WIN) && !defined(Q_OS_OS2) #include "registerqappassociation.h" #endif static bool s_testMode = false; MainApplication::MainApplication(int &argc, char** argv) : QtSingleApplication(argc, argv) , m_isPrivate(false) , m_isPortable(false) , m_isClosing(false) , m_isStartingAfterCrash(false) , m_history(nullptr) , m_bookmarks(nullptr) , m_autoFill(nullptr) , m_cookieJar(nullptr) , m_plugins(nullptr) , m_browsingLibrary(nullptr) , m_networkManager(nullptr) , m_restoreManager(nullptr) , m_sessionManager(nullptr) , m_downloadManager(nullptr) , m_userAgentManager(nullptr) , m_searchEnginesManager(nullptr) , m_closedWindowsManager(nullptr) , m_protocolHandlerManager(nullptr) , m_html5PermissionsManager(nullptr) , m_desktopNotifications(nullptr) , m_webProfile(nullptr) , m_autoSaver(nullptr) #if defined(Q_OS_WIN) && !defined(Q_OS_OS2) , m_registerQAppAssociation(0) #endif { setAttribute(Qt::AA_UseHighDpiPixmaps); setAttribute(Qt::AA_DontCreateNativeWidgetSiblings); setApplicationName(QStringLiteral("falkon")); setOrganizationDomain(QStringLiteral("org.kde")); setWindowIcon(QIcon::fromTheme(QSL("falkon"), QIcon(QSL(":icons/falkon.svg")))); setDesktopFileName(QSL("org.kde.falkon")); #ifdef GIT_REVISION setApplicationVersion(QSL("%1 (%2)").arg(Qz::VERSION, GIT_REVISION)); #else setApplicationVersion(QString::fromLatin1(Qz::VERSION)); #endif // Set fallback icon theme (eg. on Windows/Mac) if (QIcon::fromTheme(QSL("view-refresh")).isNull()) { QIcon::setThemeName(QSL("breeze-fallback")); } // QSQLITE database plugin is required if (!QSqlDatabase::isDriverAvailable(QSL("QSQLITE"))) { QMessageBox::critical(nullptr, QSL("Error"), QSL("Qt SQLite database plugin is not available. Please install it and restart the application.")); m_isClosing = true; return; } #ifdef Q_OS_WIN // Set default app font (needed for N'ko) int fontId = QFontDatabase::addApplicationFont(QSL("font.ttf")); if (fontId != -1) { const QStringList families = QFontDatabase::applicationFontFamilies(fontId); if (!families.empty()) setFont(QFont(families.at(0))); } #endif QUrl startUrl; QString startProfile; QStringList messages; bool noAddons = false; bool newInstance = false; if (argc > 1) { CommandLineOptions cmd; const auto actions = cmd.getActions(); for (const CommandLineOptions::ActionPair &pair : actions) { switch (pair.action) { case Qz::CL_StartWithoutAddons: noAddons = true; break; case Qz::CL_StartWithProfile: startProfile = pair.text; break; case Qz::CL_StartPortable: m_isPortable = true; break; case Qz::CL_NewTab: messages.append(QStringLiteral("ACTION:NewTab")); m_postLaunchActions.append(OpenNewTab); break; case Qz::CL_NewWindow: messages.append(QStringLiteral("ACTION:NewWindow")); break; case Qz::CL_ToggleFullScreen: messages.append(QStringLiteral("ACTION:ToggleFullScreen")); m_postLaunchActions.append(ToggleFullScreen); break; case Qz::CL_ShowDownloadManager: messages.append(QStringLiteral("ACTION:ShowDownloadManager")); m_postLaunchActions.append(OpenDownloadManager); break; case Qz::CL_StartPrivateBrowsing: m_isPrivate = true; break; case Qz::CL_StartNewInstance: newInstance = true; break; case Qz::CL_OpenUrlInCurrentTab: startUrl = QUrl::fromUserInput(pair.text); messages.append("ACTION:OpenUrlInCurrentTab" + pair.text); break; case Qz::CL_OpenUrlInNewWindow: startUrl = QUrl::fromUserInput(pair.text); messages.append("ACTION:OpenUrlInNewWindow" + pair.text); break; case Qz::CL_OpenUrl: startUrl = QUrl::fromUserInput(pair.text); messages.append("URL:" + pair.text); break; case Qz::CL_ExitAction: m_isClosing = true; return; case Qz::CL_WMClass: m_wmClass = pair.text.toUtf8(); break; default: break; } } } if (!isPortable()) { QSettings falkonConf(QSL("%1/falkon.conf").arg(applicationDirPath()), QSettings::IniFormat); m_isPortable = falkonConf.value(QSL("Config/Portable")).toBool(); } if (isPortable()) { std::cout << "Falkon: Running in Portable Mode." << std::endl; DataPaths::setPortableVersion(); } // Don't start single application in private browsing if (!isPrivate()) { QString appId = QStringLiteral("org.kde.Falkon"); if (isPortable()) { appId.append(QLatin1String(".Portable")); } if (isTestModeEnabled()) { appId.append(QSL(".TestMode")); } if (newInstance) { if (startProfile.isEmpty() || startProfile == QLatin1String("default")) { std::cout << "New instance cannot be started with default profile!" << std::endl; } else { // Generate unique appId so it is possible to start more separate instances // of the same profile. It is dangerous to run more instances of the same profile, // but if the user wants it, we should allow it. appId.append(QLatin1Char('.') + startProfile + QString::number(QDateTime::currentMSecsSinceEpoch())); } } setAppId(appId); } // If there is nothing to tell other instance, we need to at least wake it if (messages.isEmpty()) { messages.append(QStringLiteral(" ")); } if (isRunning()) { m_isClosing = true; for (const QString &message : qAsConst(messages)) { sendMessage(message); } return; } #ifdef Q_OS_MACOS setQuitOnLastWindowClosed(false); // disable tabbing issue#2261 extern void disableWindowTabbing(); disableWindowTabbing(); #else setQuitOnLastWindowClosed(true); #endif QSettings::setDefaultFormat(QSettings::IniFormat); QDesktopServices::setUrlHandler(QSL("http"), this, "addNewTab"); QDesktopServices::setUrlHandler(QSL("https"), this, "addNewTab"); QDesktopServices::setUrlHandler(QSL("ftp"), this, "addNewTab"); ProfileManager profileManager; profileManager.initConfigDir(); profileManager.initCurrentProfile(startProfile); Settings::createSettings(DataPaths::currentProfilePath() + QLatin1String("/settings.ini")); NetworkManager::registerSchemes(); m_webProfile = isPrivate() ? new QWebEngineProfile() : QWebEngineProfile::defaultProfile(); connect(m_webProfile, &QWebEngineProfile::downloadRequested, this, &MainApplication::downloadRequested); #if QTWEBENGINECORE_VERSION >= QT_VERSION_CHECK(5, 13, 0) m_webProfile->setNotificationPresenter([&] (std::unique_ptr notification) { auto notifications = desktopNotifications(); notifications->showNotification( QPixmap::fromImage(notification->icon()), notification->title(), notification->message() ); }); #endif m_networkManager = new NetworkManager(this); setupUserScripts(); if (!isPrivate() && !isTestModeEnabled()) { m_sessionManager = new SessionManager(this); m_autoSaver = new AutoSaver(this); connect(m_autoSaver, &AutoSaver::save, m_sessionManager, &SessionManager::autoSaveLastSession); Settings settings; settings.beginGroup(QSL("SessionRestore")); const bool wasRunning = settings.value(QSL("isRunning"), false).toBool(); const bool wasRestoring = settings.value(QSL("isRestoring"), false).toBool(); settings.setValue(QSL("isRunning"), true); settings.setValue(QSL("isRestoring"), wasRunning); settings.endGroup(); settings.sync(); m_isStartingAfterCrash = wasRunning && wasRestoring; if (wasRunning) { QTimer::singleShot(60 * 1000, this, [this]() { Settings().setValue(QSL("SessionRestore/isRestoring"), false); }); } // we have to ask about startup session before creating main window if (!m_isStartingAfterCrash && afterLaunch() == SelectSession) m_restoreManager = new RestoreManager(sessionManager()->askSessionFromUser()); } loadSettings(); m_plugins = new PluginProxy(this); m_autoFill = new AutoFill(this); mApp->protocolHandlerManager(); if (!noAddons) m_plugins->loadPlugins(); BrowserWindow* window = createWindow(Qz::BW_FirstAppWindow, startUrl); connect(window, SIGNAL(startingCompleted()), this, SLOT(restoreOverrideCursor())); connect(this, &QApplication::focusChanged, this, &MainApplication::onFocusChanged); if (!isPrivate() && !isTestModeEnabled()) { #ifndef DISABLE_CHECK_UPDATES Settings settings; bool checkUpdates = settings.value("Web-Browser-Settings/CheckUpdates", true).toBool(); if (checkUpdates) { new Updater(window); } #endif sessionManager()->backupSavedSessions(); if (m_isStartingAfterCrash || afterLaunch() == RestoreSession) { m_restoreManager = new RestoreManager(sessionManager()->lastActiveSessionPath()); if (!m_restoreManager->isValid()) { destroyRestoreManager(); } } if (!m_isStartingAfterCrash && m_restoreManager) { restoreSession(window, m_restoreManager->restoreData()); } } QSettings::setPath(QSettings::IniFormat, QSettings::UserScope, DataPaths::currentProfilePath()); connect(this, SIGNAL(messageReceived(QString)), this, SLOT(messageReceived(QString))); connect(this, &QCoreApplication::aboutToQuit, this, &MainApplication::saveSettings); QTimer::singleShot(0, this, &MainApplication::postLaunch); } MainApplication::~MainApplication() { m_isClosing = true; IconProvider::instance()->saveIconsToDatabase(); // Wait for all QtConcurrent jobs to finish QThreadPool::globalInstance()->waitForDone(); // Delete all classes that are saving data in destructor delete m_bookmarks; m_bookmarks = nullptr; delete m_cookieJar; m_cookieJar = nullptr; Settings::syncSettings(); } bool MainApplication::isClosing() const { return m_isClosing; } bool MainApplication::isPrivate() const { return m_isPrivate; } bool MainApplication::isPortable() const { #ifdef PORTABLE_BUILD return true; #else return m_isPortable; #endif } bool MainApplication::isStartingAfterCrash() const { return m_isStartingAfterCrash; } int MainApplication::windowCount() const { return m_windows.count(); } QList MainApplication::windows() const { return m_windows; } BrowserWindow* MainApplication::getWindow() const { if (m_lastActiveWindow) { return m_lastActiveWindow.data(); } return m_windows.isEmpty() ? 0 : m_windows.at(0); } BrowserWindow* MainApplication::createWindow(Qz::BrowserWindowType type, const QUrl &startUrl) { if (windowCount() == 0 && type != Qz::BW_MacFirstWindow) { type = Qz::BW_FirstAppWindow; } BrowserWindow* window = new BrowserWindow(type, startUrl); connect(window, &QObject::destroyed, this, &MainApplication::windowDestroyed); m_windows.prepend(window); return window; } MainApplication::AfterLaunch MainApplication::afterLaunch() const { return static_cast(Settings().value(QSL("Web-URL-Settings/afterLaunch"), RestoreSession).toInt()); } void MainApplication::openSession(BrowserWindow* window, RestoreData &restoreData) { setOverrideCursor(Qt::BusyCursor); if (!window) window = createWindow(Qz::BW_OtherRestoredWindow); if (window->tabCount() != 0) { // This can only happen when recovering crashed session! // Don't restore tabs in current window as user already opened some new tabs. createWindow(Qz::BW_OtherRestoredWindow)->restoreWindow(restoreData.windows.takeAt(0)); } else { window->restoreWindow(restoreData.windows.takeAt(0)); } const auto restoreWindows = restoreData.windows; for (const BrowserWindow::SavedWindow &data : restoreWindows) { BrowserWindow* window = createWindow(Qz::BW_OtherRestoredWindow); window->restoreWindow(data); } m_closedWindowsManager->restoreState(restoreData.closedWindows); restoreOverrideCursor(); } bool MainApplication::restoreSession(BrowserWindow* window, RestoreData restoreData) { if (m_isPrivate || !restoreData.isValid()) { return false; } openSession(window, restoreData); m_restoreManager->clearRestoreData(); destroyRestoreManager(); return true; } void MainApplication::destroyRestoreManager() { if (m_restoreManager && m_restoreManager->isValid()) { return; } delete m_restoreManager; m_restoreManager = 0; } void MainApplication::reloadSettings() { loadSettings(); emit settingsReloaded(); } QString MainApplication::styleName() const { return m_proxyStyle ? m_proxyStyle->name() : QString(); } void MainApplication::setProxyStyle(ProxyStyle *style) { m_proxyStyle = style; setStyle(style); } QByteArray MainApplication::wmClass() const { return m_wmClass; } History* MainApplication::history() { if (!m_history) { m_history = new History(this); } return m_history; } Bookmarks* MainApplication::bookmarks() { if (!m_bookmarks) { m_bookmarks = new Bookmarks(this); } return m_bookmarks; } AutoFill* MainApplication::autoFill() { return m_autoFill; } CookieJar* MainApplication::cookieJar() { if (!m_cookieJar) { m_cookieJar = new CookieJar(this); } return m_cookieJar; } PluginProxy* MainApplication::plugins() { return m_plugins; } BrowsingLibrary* MainApplication::browsingLibrary() { if (!m_browsingLibrary) { m_browsingLibrary = new BrowsingLibrary(getWindow()); } return m_browsingLibrary; } NetworkManager *MainApplication::networkManager() { return m_networkManager; } RestoreManager* MainApplication::restoreManager() { return m_restoreManager; } SessionManager* MainApplication::sessionManager() { return m_sessionManager; } DownloadManager* MainApplication::downloadManager() { if (!m_downloadManager) { m_downloadManager = new DownloadManager(); } return m_downloadManager; } UserAgentManager* MainApplication::userAgentManager() { if (!m_userAgentManager) { m_userAgentManager = new UserAgentManager(this); } return m_userAgentManager; } SearchEnginesManager* MainApplication::searchEnginesManager() { if (!m_searchEnginesManager) { m_searchEnginesManager = new SearchEnginesManager(this); } return m_searchEnginesManager; } ClosedWindowsManager* MainApplication::closedWindowsManager() { if (!m_closedWindowsManager) { m_closedWindowsManager = new ClosedWindowsManager(this); } return m_closedWindowsManager; } ProtocolHandlerManager *MainApplication::protocolHandlerManager() { if (!m_protocolHandlerManager) { m_protocolHandlerManager = new ProtocolHandlerManager(this); } return m_protocolHandlerManager; } HTML5PermissionsManager* MainApplication::html5PermissionsManager() { if (!m_html5PermissionsManager) { m_html5PermissionsManager = new HTML5PermissionsManager(this); } return m_html5PermissionsManager; } DesktopNotificationsFactory* MainApplication::desktopNotifications() { if (!m_desktopNotifications) { m_desktopNotifications = new DesktopNotificationsFactory(this); } return m_desktopNotifications; } QWebEngineProfile *MainApplication::webProfile() const { return m_webProfile; } QWebEngineSettings *MainApplication::webSettings() const { return m_webProfile->settings(); } // static MainApplication* MainApplication::instance() { return static_cast(QCoreApplication::instance()); } // static bool MainApplication::isTestModeEnabled() { return s_testMode; } // static void MainApplication::setTestModeEnabled(bool enabled) { s_testMode = enabled; } void MainApplication::addNewTab(const QUrl &url) { BrowserWindow* window = getWindow(); if (window) { window->tabWidget()->addView(url, url.isEmpty() ? Qz::NT_SelectedNewEmptyTab : Qz::NT_SelectedTabAtTheEnd); } } void MainApplication::startPrivateBrowsing(const QUrl &startUrl) { QUrl url = startUrl; if (QAction* act = qobject_cast(sender())) { url = act->data().toUrl(); } QStringList args; args.append(QSL("--private-browsing")); args.append(QSL("--profile=") + ProfileManager::currentProfile()); if (!url.isEmpty()) { args << url.toEncoded(); } if (!QProcess::startDetached(applicationFilePath(), args)) { qWarning() << "MainApplication: Cannot start new browser process for private browsing!" << applicationFilePath() << args; } } void MainApplication::reloadUserStyleSheet() { const QString userCssFile = Settings().value(QSL("Web-Browser-Settings/userStyleSheet"), QString()).toString(); setUserStyleSheet(userCssFile); } void MainApplication::restoreOverrideCursor() { QApplication::restoreOverrideCursor(); } void MainApplication::changeOccurred() { if (m_autoSaver) m_autoSaver->changeOccurred(); } void MainApplication::quitApplication() { if (m_downloadManager && !m_downloadManager->canClose()) { m_downloadManager->show(); return; } for (BrowserWindow *window : qAsConst(m_windows)) { emit window->aboutToClose(); } if (m_sessionManager && m_windows.count() > 0) { m_sessionManager->autoSaveLastSession(); } m_isClosing = true; for (BrowserWindow *window : qAsConst(m_windows)) { window->close(); } // Saving settings in saveSettings() slot called from quit() so // everything gets saved also when quitting application in other // way than clicking Quit action in File menu or closing last window // eg. on Mac (#157) if (!isPrivate()) { removeLockFile(); } quit(); } void MainApplication::postLaunch() { if (m_postLaunchActions.contains(OpenDownloadManager)) { downloadManager()->show(); } if (m_postLaunchActions.contains(OpenNewTab)) { getWindow()->tabWidget()->addView(QUrl(), Qz::NT_SelectedNewEmptyTab); } if (m_postLaunchActions.contains(ToggleFullScreen)) { getWindow()->toggleFullScreen(); } createJumpList(); initPulseSupport(); QTimer::singleShot(5000, this, &MainApplication::runDeferredPostLaunchActions); } QByteArray MainApplication::saveState() const { RestoreData restoreData; restoreData.windows.reserve(m_windows.count()); for (BrowserWindow *window : qAsConst(m_windows)) { restoreData.windows.append(BrowserWindow::SavedWindow(window)); } if (m_restoreManager && m_restoreManager->isValid()) { QDataStream stream(&restoreData.crashedSession, QIODevice::WriteOnly); stream << m_restoreManager->restoreData(); } restoreData.closedWindows = m_closedWindowsManager->saveState(); QByteArray data; QDataStream stream(&data, QIODevice::WriteOnly); stream << Qz::sessionVersion; stream << restoreData; return data; } void MainApplication::saveSettings() { if (isPrivate()) { return; } m_isClosing = true; Settings settings; settings.beginGroup(QSL("SessionRestore")); settings.setValue(QSL("isRunning"), false); settings.setValue(QSL("isRestoring"), false); settings.endGroup(); settings.beginGroup(QSL("Web-Browser-Settings")); bool deleteCache = settings.value(QSL("deleteCacheOnClose"), false).toBool(); bool deleteHistory = settings.value(QSL("deleteHistoryOnClose"), false).toBool(); bool deleteHtml5Storage = settings.value(QSL("deleteHTML5StorageOnClose"), false).toBool(); settings.endGroup(); settings.beginGroup(QSL("Cookie-Settings")); bool deleteCookies = settings.value(QSL("deleteCookiesOnClose"), false).toBool(); settings.endGroup(); if (deleteHistory) { m_history->clearHistory(); } if (deleteHtml5Storage) { ClearPrivateData::clearLocalStorage(); } if (deleteCookies) { m_cookieJar->deleteAllCookies(false); } if (deleteCache) { QzTools::removeRecursively(mApp->webProfile()->cachePath()); } m_searchEnginesManager->saveSettings(); m_plugins->shutdown(); m_networkManager->shutdown(); qzSettings->saveSettings(); QFile::remove(DataPaths::currentProfilePath() + QLatin1String("/WebpageIcons.db")); sessionManager()->saveSettings(); } void MainApplication::messageReceived(const QString &message) { QWidget* actWin = getWindow(); QUrl actUrl; if (message.startsWith(QLatin1String("URL:"))) { const QUrl url = QUrl::fromUserInput(message.mid(4)); addNewTab(url); actWin = getWindow(); } else if (message.startsWith(QLatin1String("ACTION:"))) { const QString text = message.mid(7); if (text == QLatin1String("NewTab")) { addNewTab(); } else if (text == QLatin1String("NewWindow")) { actWin = createWindow(Qz::BW_NewWindow); } else if (text == QLatin1String("ShowDownloadManager")) { downloadManager()->show(); actWin = downloadManager(); } else if (text == QLatin1String("ToggleFullScreen") && actWin) { BrowserWindow* qz = static_cast(actWin); qz->toggleFullScreen(); } else if (text.startsWith(QLatin1String("OpenUrlInCurrentTab"))) { actUrl = QUrl::fromUserInput(text.mid(19)); } else if (text.startsWith(QLatin1String("OpenUrlInNewWindow"))) { createWindow(Qz::BW_NewWindow, QUrl::fromUserInput(text.mid(18))); return; } } else { // User attempted to start another instance, let's open a new window actWin = createWindow(Qz::BW_NewWindow); } if (!actWin) { if (!isClosing()) { // It can only occur if download manager window was still opened createWindow(Qz::BW_NewWindow, actUrl); } return; } actWin->setWindowState(actWin->windowState() & ~Qt::WindowMinimized); actWin->raise(); actWin->activateWindow(); actWin->setFocus(); BrowserWindow* win = qobject_cast(actWin); if (win && !actUrl.isEmpty()) { win->loadAddress(actUrl); } } void MainApplication::windowDestroyed(QObject* window) { // qobject_cast doesn't work because QObject::destroyed is emitted from destructor Q_ASSERT(static_cast(window)); Q_ASSERT(m_windows.contains(static_cast(window))); m_windows.removeOne(static_cast(window)); } void MainApplication::onFocusChanged() { BrowserWindow* activeBrowserWindow = qobject_cast(activeWindow()); if (activeBrowserWindow) { m_lastActiveWindow = activeBrowserWindow; emit activeWindowChanged(m_lastActiveWindow); } } void MainApplication::runDeferredPostLaunchActions() { checkDefaultWebBrowser(); checkOptimizeDatabase(); } void MainApplication::downloadRequested(QWebEngineDownloadItem *download) { downloadManager()->download(download); } void MainApplication::loadSettings() { Settings settings; settings.beginGroup(QSL("Themes")); QString activeTheme = settings.value(QSL("activeTheme"), DEFAULT_THEME_NAME).toString(); settings.endGroup(); loadTheme(activeTheme); QWebEngineSettings* webSettings = m_webProfile->settings(); // Web browsing settings settings.beginGroup(QSL("Web-Browser-Settings")); webSettings->setAttribute(QWebEngineSettings::LocalStorageEnabled, settings.value(QSL("HTML5StorageEnabled"), true).toBool()); webSettings->setAttribute(QWebEngineSettings::PluginsEnabled, settings.value(QSL("allowPlugins"), true).toBool()); webSettings->setAttribute(QWebEngineSettings::JavascriptEnabled, settings.value(QSL("allowJavaScript"), true).toBool()); webSettings->setAttribute(QWebEngineSettings::JavascriptCanOpenWindows, settings.value(QSL("allowJavaScriptOpenWindow"), false).toBool()); webSettings->setAttribute(QWebEngineSettings::JavascriptCanAccessClipboard, settings.value(QSL("allowJavaScriptAccessClipboard"), true).toBool()); webSettings->setAttribute(QWebEngineSettings::LinksIncludedInFocusChain, settings.value(QSL("IncludeLinkInFocusChain"), false).toBool()); webSettings->setAttribute(QWebEngineSettings::XSSAuditingEnabled, settings.value(QSL("XSSAuditing"), false).toBool()); webSettings->setAttribute(QWebEngineSettings::PrintElementBackgrounds, settings.value(QSL("PrintElementBackground"), true).toBool()); webSettings->setAttribute(QWebEngineSettings::SpatialNavigationEnabled, settings.value(QSL("SpatialNavigation"), false).toBool()); webSettings->setAttribute(QWebEngineSettings::ScrollAnimatorEnabled, settings.value(QSL("AnimateScrolling"), true).toBool()); webSettings->setAttribute(QWebEngineSettings::HyperlinkAuditingEnabled, false); webSettings->setAttribute(QWebEngineSettings::FullScreenSupportEnabled, true); webSettings->setAttribute(QWebEngineSettings::LocalContentCanAccessRemoteUrls, true); webSettings->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, false); #if QTWEBENGINEWIDGETS_VERSION >= QT_VERSION_CHECK(5, 10, 0) webSettings->setAttribute(QWebEngineSettings::AllowWindowActivationFromJavaScript, settings.value(QSL("allowJavaScriptActivateWindow"), false).toBool()); #endif #if QTWEBENGINEWIDGETS_VERSION >= QT_VERSION_CHECK(5, 11, 0) webSettings->setAttribute(QWebEngineSettings::JavascriptCanPaste, settings.value(QSL("allowJavaScriptPaste"), true).toBool()); webSettings->setAttribute(QWebEngineSettings::PlaybackRequiresUserGesture, settings.value(QSL("DisableVideoAutoPlay"), false).toBool()); webSettings->setAttribute(QWebEngineSettings::WebRTCPublicInterfacesOnly, settings.value(QSL("WebRTCPublicIpOnly"), true).toBool()); webSettings->setUnknownUrlSchemePolicy(QWebEngineSettings::AllowAllUnknownUrlSchemes); #endif #if QTWEBENGINEWIDGETS_VERSION >= QT_VERSION_CHECK(5, 12, 0) webSettings->setAttribute(QWebEngineSettings::DnsPrefetchEnabled, settings.value(QSL("DNSPrefetch"), true).toBool()); #endif +#if QTWEBENGINEWIDGETS_VERSION >= QT_VERSION_CHECK(5, 13, 0) + webSettings->setAttribute(QWebEngineSettings::PdfViewerEnabled, settings.value(QSL("intPDFViewer"), false).toBool()); +#endif + webSettings->setDefaultTextEncoding(settings.value(QSL("DefaultEncoding"), webSettings->defaultTextEncoding()).toString()); setWheelScrollLines(settings.value(QSL("wheelScrollLines"), wheelScrollLines()).toInt()); const QString userCss = settings.value(QSL("userStyleSheet"), QString()).toString(); settings.endGroup(); setUserStyleSheet(userCss); settings.beginGroup(QSL("Browser-Fonts")); webSettings->setFontFamily(QWebEngineSettings::StandardFont, settings.value(QSL("StandardFont"), webSettings->fontFamily(QWebEngineSettings::StandardFont)).toString()); webSettings->setFontFamily(QWebEngineSettings::CursiveFont, settings.value(QSL("CursiveFont"), webSettings->fontFamily(QWebEngineSettings::CursiveFont)).toString()); webSettings->setFontFamily(QWebEngineSettings::FantasyFont, settings.value(QSL("FantasyFont"), webSettings->fontFamily(QWebEngineSettings::FantasyFont)).toString()); webSettings->setFontFamily(QWebEngineSettings::FixedFont, settings.value(QSL("FixedFont"), webSettings->fontFamily(QWebEngineSettings::FixedFont)).toString()); webSettings->setFontFamily(QWebEngineSettings::SansSerifFont, settings.value(QSL("SansSerifFont"), webSettings->fontFamily(QWebEngineSettings::SansSerifFont)).toString()); webSettings->setFontFamily(QWebEngineSettings::SerifFont, settings.value(QSL("SerifFont"), webSettings->fontFamily(QWebEngineSettings::SerifFont)).toString()); webSettings->setFontSize(QWebEngineSettings::DefaultFontSize, settings.value(QSL("DefaultFontSize"), 15).toInt()); webSettings->setFontSize(QWebEngineSettings::DefaultFixedFontSize, settings.value(QSL("FixedFontSize"), 14).toInt()); webSettings->setFontSize(QWebEngineSettings::MinimumFontSize, settings.value(QSL("MinimumFontSize"), 3).toInt()); webSettings->setFontSize(QWebEngineSettings::MinimumLogicalFontSize, settings.value(QSL("MinimumLogicalFontSize"), 5).toInt()); settings.endGroup(); QWebEngineProfile* profile = QWebEngineProfile::defaultProfile(); profile->setPersistentCookiesPolicy(QWebEngineProfile::AllowPersistentCookies); profile->setPersistentStoragePath(DataPaths::currentProfilePath()); QString defaultPath = DataPaths::path(DataPaths::Cache); if (!defaultPath.startsWith(DataPaths::currentProfilePath())) defaultPath.append(QLatin1Char('/') + ProfileManager::currentProfile()); const QString &cachePath = settings.value(QSL("Web-Browser-Settings/CachePath"), defaultPath).toString(); profile->setCachePath(cachePath); const bool allowCache = settings.value(QSL("Web-Browser-Settings/AllowLocalCache"), true).toBool(); profile->setHttpCacheType(allowCache ? QWebEngineProfile::DiskHttpCache : QWebEngineProfile::MemoryHttpCache); const int cacheSize = settings.value(QSL("Web-Browser-Settings/LocalCacheSize"), 50).toInt() * 1000 * 1000; profile->setHttpCacheMaximumSize(cacheSize); settings.beginGroup(QSL("SpellCheck")); profile->setSpellCheckEnabled(settings.value(QSL("Enabled"), false).toBool()); profile->setSpellCheckLanguages(settings.value(QSL("Languages")).toStringList()); settings.endGroup(); if (isPrivate()) { webSettings->setAttribute(QWebEngineSettings::LocalStorageEnabled, false); history()->setSaving(false); } if (m_downloadManager) { m_downloadManager->loadSettings(); } qzSettings->loadSettings(); userAgentManager()->loadSettings(); networkManager()->loadSettings(); } void MainApplication::loadTheme(const QString &name) { QString activeThemePath = DataPaths::locate(DataPaths::Themes, name); if (activeThemePath.isEmpty()) { qWarning() << "Cannot load theme " << name; activeThemePath = QSL("%1/%2").arg(DataPaths::path(DataPaths::Themes), DEFAULT_THEME_NAME); } QString qss = QzTools::readAllFileContents(activeThemePath + QLatin1String("/main.css")); #if defined(Q_OS_MACOS) qss.append(QzTools::readAllFileContents(activeThemePath + QLatin1String("/mac.css"))); #elif defined(Q_OS_UNIX) qss.append(QzTools::readAllFileContents(activeThemePath + QLatin1String("/linux.css"))); #elif defined(Q_OS_WIN) || defined(Q_OS_OS2) qss.append(QzTools::readAllFileContents(activeThemePath + QLatin1String("/windows.css"))); #endif if (isRightToLeft()) { qss.append(QzTools::readAllFileContents(activeThemePath + QLatin1String("/rtl.css"))); } if (isPrivate()) { qss.append(QzTools::readAllFileContents(activeThemePath + QLatin1String("/private.css"))); } qss.append(QzTools::readAllFileContents(DataPaths::currentProfilePath() + QL1S("/userChrome.css"))); QString relativePath = QDir::current().relativeFilePath(activeThemePath); qss.replace(QRegularExpression(QSL("url\\s*\\(\\s*([^\\*:\\);]+)\\s*\\)")), QSL("url(%1/\\1)").arg(relativePath)); setStyleSheet(qss); } void MainApplication::checkDefaultWebBrowser() { if (isPortable()) { return; } #if defined(Q_OS_WIN) && !defined(Q_OS_OS2) Settings settings; bool checkNow = settings.value(QSL("Web-Browser-Settings/CheckDefaultBrowser"), DEFAULT_CHECK_DEFAULTBROWSER).toBool(); if (!checkNow) { return; } bool checkAgain = true; if (!associationManager()->isDefaultForAllCapabilities()) { CheckBoxDialog dialog(QMessageBox::Yes | QMessageBox::No, getWindow()); dialog.setDefaultButton(QMessageBox::Yes); dialog.setText(tr("Falkon is not currently your default browser. Would you like to make it your default browser?")); dialog.setCheckBoxText(tr("Always perform this check when starting Falkon.")); dialog.setDefaultCheckState(Qt::Checked); dialog.setWindowTitle(tr("Default Browser")); dialog.setIcon(QMessageBox::Warning); if (dialog.exec() == QMessageBox::Yes) { if (!mApp->associationManager()->showNativeDefaultAppSettingsUi()) mApp->associationManager()->registerAllAssociation(); } checkAgain = dialog.isChecked(); } settings.setValue(QSL("Web-Browser-Settings/CheckDefaultBrowser"), checkAgain); #endif } void MainApplication::checkOptimizeDatabase() { Settings settings; settings.beginGroup(QSL("Browser")); const int numberOfRuns = settings.value(QSL("RunsWithoutOptimizeDb"), 0).toInt(); settings.setValue(QSL("RunsWithoutOptimizeDb"), numberOfRuns + 1); if (numberOfRuns > 20) { std::cout << "Optimizing database..." << std::endl; IconProvider::instance()->clearOldIconsInDatabase(); settings.setValue(QSL("RunsWithoutOptimizeDb"), 0); } settings.endGroup(); } void MainApplication::setupUserScripts() { // WebChannel for SafeJsWorld QWebEngineScript script; script.setName(QSL("_falkon_webchannel")); script.setInjectionPoint(QWebEngineScript::DocumentCreation); script.setWorldId(WebPage::SafeJsWorld); script.setRunsOnSubFrames(true); script.setSourceCode(Scripts::setupWebChannel()); m_webProfile->scripts()->insert(script); // falkon:restore QWebEngineScript falkonRestore; falkonRestore.setWorldId(WebPage::SafeJsWorld); falkonRestore.setSourceCode(QzTools::readAllFileContents(QSL(":html/restore.user.js"))); m_webProfile->scripts()->insert(falkonRestore); // falkon:speeddial QWebEngineScript falkonSpeedDial; falkonSpeedDial.setWorldId(WebPage::SafeJsWorld); falkonSpeedDial.setSourceCode(Scripts::setupSpeedDial()); m_webProfile->scripts()->insert(falkonSpeedDial); // document.window object addons QWebEngineScript documentWindowAddons; documentWindowAddons.setName(QSL("_falkon_window_object")); documentWindowAddons.setInjectionPoint(QWebEngineScript::DocumentCreation); documentWindowAddons.setWorldId(WebPage::UnsafeJsWorld); documentWindowAddons.setRunsOnSubFrames(true); documentWindowAddons.setSourceCode(Scripts::setupWindowObject()); m_webProfile->scripts()->insert(documentWindowAddons); } void MainApplication::setUserStyleSheet(const QString &filePath) { QString userCss; #if !defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) // Don't grey out selection on losing focus (to prevent graying out found text) QString highlightColor; QString highlightedTextColor; #ifdef Q_OS_MACOS highlightColor = QLatin1String("#b6d6fc"); highlightedTextColor = QLatin1String("#000"); #else QPalette pal = style()->standardPalette(); highlightColor = pal.color(QPalette::Highlight).name(); highlightedTextColor = pal.color(QPalette::HighlightedText).name(); #endif userCss += QString("::selection {background: %1; color: %2;} ").arg(highlightColor, highlightedTextColor); #endif userCss += QzTools::readAllFileContents(filePath).remove(QLatin1Char('\n')); const QString name = QStringLiteral("_falkon_userstylesheet"); QWebEngineScript oldScript = m_webProfile->scripts()->findScript(name); if (!oldScript.isNull()) { m_webProfile->scripts()->remove(oldScript); } if (userCss.isEmpty()) return; QWebEngineScript script; script.setName(name); script.setInjectionPoint(QWebEngineScript::DocumentReady); script.setWorldId(WebPage::SafeJsWorld); script.setRunsOnSubFrames(true); script.setSourceCode(Scripts::setCss(userCss)); m_webProfile->scripts()->insert(script); } void MainApplication::createJumpList() { #ifdef Q_OS_WIN QWinJumpList *jumpList = new QWinJumpList(this); jumpList->clear(); // Frequent QWinJumpListCategory *frequent = jumpList->frequent(); frequent->setVisible(true); const QVector mostList = m_history->mostVisited(7); for (const HistoryEntry &entry : mostList) { frequent->addLink(IconProvider::iconForUrl(entry.url), entry.title, applicationFilePath(), QStringList{entry.url.toEncoded()}); } // Tasks QWinJumpListCategory *tasks = jumpList->tasks(); tasks->setVisible(true); tasks->addLink(IconProvider::newTabIcon(), tr("Open new tab"), applicationFilePath(), {QSL("--new-tab")}); tasks->addLink(IconProvider::newWindowIcon(), tr("Open new window"), applicationFilePath(), {QSL("--new-window")}); tasks->addLink(IconProvider::privateBrowsingIcon(), tr("Open new private window"), applicationFilePath(), {QSL("--private-browsing")}); #endif } void MainApplication::initPulseSupport() { qputenv("PULSE_PROP_OVERRIDE_application.name", "Falkon"); qputenv("PULSE_PROP_OVERRIDE_application.icon_name", "falkon"); qputenv("PULSE_PROP_OVERRIDE_media.icon_name", "falkon"); } #if defined(Q_OS_WIN) && !defined(Q_OS_OS2) RegisterQAppAssociation* MainApplication::associationManager() { if (!m_registerQAppAssociation) { QString desc = tr("Falkon is a new and very fast Qt web browser. Falkon is licensed under GPL version 3 or (at your option) any later version. It is based on QtWebEngine and Qt Framework."); QString fileIconPath = QApplication::applicationFilePath() + ",1"; QString appIconPath = QApplication::applicationFilePath() + ",0"; m_registerQAppAssociation = new RegisterQAppAssociation("Falkon", QApplication::applicationFilePath(), appIconPath, desc, this); m_registerQAppAssociation->addCapability(".html", "FalkonHTML", "Falkon HTML Document", fileIconPath, RegisterQAppAssociation::FileAssociation); m_registerQAppAssociation->addCapability(".htm", "FalkonHTML", "Falkon HTML Document", fileIconPath, RegisterQAppAssociation::FileAssociation); m_registerQAppAssociation->addCapability("http", "FalkonURL", "Falkon URL", appIconPath, RegisterQAppAssociation::UrlAssociation); m_registerQAppAssociation->addCapability("https", "FalkonURL", "Falkon URL", appIconPath, RegisterQAppAssociation::UrlAssociation); m_registerQAppAssociation->addCapability("ftp", "FalkonURL", "Falkon URL", appIconPath, RegisterQAppAssociation::UrlAssociation); } return m_registerQAppAssociation; } #endif #ifdef Q_OS_MACOS #include bool MainApplication::event(QEvent* e) { switch (e->type()) { case QEvent::FileOpen: { QFileOpenEvent *ev = static_cast(e); if (!ev->url().isEmpty()) { addNewTab(ev->url()); } else if (!ev->file().isEmpty()) { addNewTab(QUrl::fromLocalFile(ev->file())); } else { return false; } return true; } case QEvent::ApplicationActivate: if (!activeWindow() && m_windows.isEmpty()) createWindow(Qz::BW_NewWindow); break; default: break; } return QtSingleApplication::event(e); } #endif diff --git a/src/lib/preferences/preferences.cpp b/src/lib/preferences/preferences.cpp index 91c581a1..f3e6f1a0 100644 --- a/src/lib/preferences/preferences.cpp +++ b/src/lib/preferences/preferences.cpp @@ -1,1090 +1,1103 @@ /* ============================================================ * Falkon - Qt web browser * Copyright (C) 2010-2018 David Rosca * * 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 . * ============================================================ */ #include "preferences.h" #include "ui_preferences.h" #include "browserwindow.h" #include "bookmarkstoolbar.h" #include "history.h" #include "tabwidget.h" #include "cookiejar.h" #include "locationbar.h" #include "autofillmanager.h" #include "mainapplication.h" #include "cookiemanager.h" #include "pluginproxy.h" #include "pluginsmanager.h" #include "jsoptions.h" #include "networkmanager.h" #include "desktopnotificationsfactory.h" #include "desktopnotification.h" #include "thememanager.h" #include "acceptlanguage.h" #include "qztools.h" #include "autofill.h" #include "settings.h" #include "datapaths.h" #include "tabbedwebview.h" #include "clearprivatedata.h" #include "useragentdialog.h" #include "registerqappassociation.h" #include "profilemanager.h" #include "html5permissions/html5permissionsdialog.h" #include "searchenginesdialog.h" #include "webscrollbarmanager.h" #include "protocolhandlerdialog.h" #include "../config.h" #include #include #include #include #include #include #include #include #include #include #include static QString createLanguageItem(const QString &lang) { QLocale locale(lang); if (locale.language() == QLocale::C) { return lang; } QString country = QLocale::countryToString(locale.country()); QString language = QLocale::languageToString(locale.language()); if (lang == QLatin1String("es_ES")) { return QString::fromUtf8("Castellano"); } if (lang == QLatin1String("nqo")) { return QString("N'ko (nqo)"); } if (lang == QLatin1String("sr")) { return QString::fromUtf8("српски екавски"); } if (lang == QLatin1String("sr@ijekavian")) { return QString::fromUtf8("српски ијекавски"); } if (lang == QLatin1String("sr@latin")) { return QString::fromUtf8("srpski ekavski"); } if (lang == QLatin1String("sr@ijekavianlatin")) { return QString::fromUtf8("srpski ijekavski"); } return QString("%1, %2 (%3)").arg(language, country, lang); } Preferences::Preferences(BrowserWindow* window) : QDialog(window) , ui(new Ui::Preferences) , m_window(window) , m_autoFillManager(0) , m_pluginsList(0) { setAttribute(Qt::WA_DeleteOnClose); ui->setupUi(this); QzTools::centerWidgetOnScreen(this); m_themesManager = new ThemeManager(ui->themesWidget, this); m_pluginsList = new PluginsManager(this); ui->pluginsFrame->addWidget(m_pluginsList); #ifdef DISABLE_CHECK_UPDATES ui->checkUpdates->setVisible(false); #endif #if QTWEBENGINEWIDGETS_VERSION < QT_VERSION_CHECK(5, 11, 0) ui->disableVideoAutoPlay->setVisible(false); ui->webRTCPublicIpOnly->setVisible(false); #endif #if QTWEBENGINEWIDGETS_VERSION < QT_VERSION_CHECK(5, 12, 0) ui->dnsPrefetch->setVisible(false); #endif +#if QTWEBENGINEWIDGETS_VERSION < QT_VERSION_CHECK(5, 13, 0) + ui->intPDFViewer->setVisible(false); +#endif + auto setCategoryIcon = [this](int index, const QIcon &icon) { ui->listWidget->item(index)->setIcon(QIcon(icon.pixmap(32))); }; setCategoryIcon(0, QIcon(":/icons/preferences/general.svg")); setCategoryIcon(1, QIcon(":/icons/preferences/appearance.svg")); setCategoryIcon(2, QIcon(":/icons/preferences/tabs.svg")); setCategoryIcon(3, QIcon(":/icons/preferences/browsing.svg")); setCategoryIcon(4, QIcon(":/icons/preferences/fonts.svg")); setCategoryIcon(5, QIcon(":/icons/preferences/shortcuts.svg")); setCategoryIcon(6, QIcon(":/icons/preferences/downloads.svg")); setCategoryIcon(7, QIcon(":/icons/preferences/passwords.svg")); setCategoryIcon(8, QIcon(":/icons/preferences/privacy.svg")); setCategoryIcon(9, QIcon(":/icons/preferences/notifications.svg")); setCategoryIcon(10, QIcon(":/icons/preferences/extensions.svg")); setCategoryIcon(11, QIcon(":/icons/preferences/spellcheck.svg")); setCategoryIcon(12, QIcon(":/icons/preferences/other.svg")); Settings settings; //GENERAL URLs settings.beginGroup("Web-URL-Settings"); m_homepage = settings.value("homepage", QUrl(QSL("falkon:start"))).toUrl(); m_newTabUrl = settings.value("newTabUrl", QUrl(QSL("falkon:speeddial"))).toUrl(); ui->homepage->setText(m_homepage.toEncoded()); ui->newTabUrl->setText(m_newTabUrl.toEncoded()); settings.endGroup(); ui->afterLaunch->setCurrentIndex(mApp->afterLaunch()); ui->checkUpdates->setChecked(settings.value("Web-Browser-Settings/CheckUpdates", true).toBool()); ui->dontLoadTabsUntilSelected->setChecked(settings.value("Web-Browser-Settings/LoadTabsOnActivation", true).toBool()); #if defined(Q_OS_WIN) && !defined(Q_OS_OS2) if (!mApp->isPortable()) { ui->checkDefaultBrowser->setChecked(settings.value("Web-Browser-Settings/CheckDefaultBrowser", DEFAULT_CHECK_DEFAULTBROWSER).toBool()); if (mApp->associationManager()->isDefaultForAllCapabilities()) { ui->checkNowDefaultBrowser->setText(tr("Default")); ui->checkNowDefaultBrowser->setEnabled(false); } else { ui->checkNowDefaultBrowser->setText(tr("Set as default")); ui->checkNowDefaultBrowser->setEnabled(true); connect(ui->checkNowDefaultBrowser, SIGNAL(clicked()), this, SLOT(makeFalkonDefault())); } } else { ui->checkDefaultBrowser->hide(); ui->checkNowDefaultBrowser->hide(); } #else // No Default Browser settings on non-Windows platform ui->hSpacerDefaultBrowser->changeSize(0, 0, QSizePolicy::Fixed, QSizePolicy::Fixed); ui->hLayoutDefaultBrowser->invalidate(); delete ui->hLayoutDefaultBrowser; delete ui->checkDefaultBrowser; delete ui->checkNowDefaultBrowser; #endif ui->newTabFrame->setVisible(false); if (m_newTabUrl.isEmpty() || m_newTabUrl.toString() == QL1S("about:blank")) { ui->newTab->setCurrentIndex(0); } else if (m_newTabUrl == m_homepage) { ui->newTab->setCurrentIndex(1); } else if (m_newTabUrl.toString() == QL1S("falkon:speeddial")) { ui->newTab->setCurrentIndex(2); } else { ui->newTab->setCurrentIndex(3); ui->newTabFrame->setVisible(true); } afterLaunchChanged(ui->afterLaunch->currentIndex()); connect(ui->afterLaunch, SIGNAL(currentIndexChanged(int)), this, SLOT(afterLaunchChanged(int))); connect(ui->newTab, SIGNAL(currentIndexChanged(int)), this, SLOT(newTabChanged(int))); if (m_window) { connect(ui->useCurrentBut, &QAbstractButton::clicked, this, &Preferences::useActualHomepage); connect(ui->newTabUseCurrent, &QAbstractButton::clicked, this, &Preferences::useActualNewTab); } else { ui->useCurrentBut->setEnabled(false); ui->newTabUseCurrent->setEnabled(false); } // PROFILES QString startingProfile = ProfileManager::startingProfile(); ui->activeProfile->setText("" + ProfileManager::currentProfile() + ""); ui->startProfile->addItem(startingProfile); const auto names = ProfileManager::availableProfiles(); for (const QString &name : names) { if (startingProfile != name) { ui->startProfile->addItem(name); } } connect(ui->createProfile, &QAbstractButton::clicked, this, &Preferences::createProfile); connect(ui->deleteProfile, &QAbstractButton::clicked, this, &Preferences::deleteProfile); connect(ui->startProfile, SIGNAL(currentIndexChanged(int)), this, SLOT(startProfileIndexChanged(int))); startProfileIndexChanged(ui->startProfile->currentIndex()); //APPEREANCE settings.beginGroup("Browser-View-Settings"); ui->showStatusbar->setChecked(settings.value("showStatusBar", false).toBool()); // NOTE: instantBookmarksToolbar and showBookmarksToolbar cannot be both enabled at the same time ui->instantBookmarksToolbar->setChecked(settings.value("instantBookmarksToolbar", false).toBool()); ui->showBookmarksToolbar->setChecked(settings.value("showBookmarksToolbar", false).toBool()); ui->instantBookmarksToolbar->setDisabled(settings.value("showBookmarksToolbar", false).toBool()); ui->showBookmarksToolbar->setDisabled(settings.value("instantBookmarksToolbar").toBool()); connect(ui->instantBookmarksToolbar, &QAbstractButton::toggled, ui->showBookmarksToolbar, &QWidget::setDisabled); connect(ui->showBookmarksToolbar, &QAbstractButton::toggled, ui->instantBookmarksToolbar, &QWidget::setDisabled); ui->showNavigationToolbar->setChecked(settings.value("showNavigationToolbar", true).toBool()); int currentSettingsPage = settings.value("settingsDialogPage", 0).toInt(0); settings.endGroup(); //TABS settings.beginGroup("Browser-Tabs-Settings"); ui->hideTabsOnTab->setChecked(settings.value("hideTabsWithOneTab", false).toBool()); ui->activateLastTab->setChecked(settings.value("ActivateLastTabWhenClosingActual", false).toBool()); ui->openNewTabAfterActive->setChecked(settings.value("newTabAfterActive", true).toBool()); ui->openNewEmptyTabAfterActive->setChecked(settings.value("newEmptyTabAfterActive", false).toBool()); ui->openPopupsInTabs->setChecked(settings.value("OpenPopupsInTabs", false).toBool()); ui->alwaysSwitchTabsWithWheel->setChecked(settings.value("AlwaysSwitchTabsWithWheel", false).toBool()); ui->switchToNewTabs->setChecked(settings.value("OpenNewTabsSelected", false).toBool()); ui->dontCloseOnLastTab->setChecked(settings.value("dontCloseWithOneTab", false).toBool()); ui->askWhenClosingMultipleTabs->setChecked(settings.value("AskOnClosing", false).toBool()); ui->showClosedTabsButton->setChecked(settings.value("showClosedTabsButton", false).toBool()); ui->showCloseOnInactive->setCurrentIndex(settings.value("showCloseOnInactiveTabs", 0).toInt()); settings.endGroup(); //AddressBar settings.beginGroup("AddressBar"); ui->addressbarCompletion->setCurrentIndex(settings.value("showSuggestions", 0).toInt()); ui->useInlineCompletion->setChecked(settings.value("useInlineCompletion", true).toBool()); ui->completionShowSwitchTab->setChecked(settings.value("showSwitchTab", true).toBool()); ui->alwaysShowGoIcon->setChecked(settings.value("alwaysShowGoIcon", false).toBool()); ui->selectAllOnFocus->setChecked(settings.value("SelectAllTextOnDoubleClick", true).toBool()); ui->selectAllOnClick->setChecked(settings.value("SelectAllTextOnClick", false).toBool()); bool showPBinAB = settings.value("ShowLoadingProgress", false).toBool(); ui->showLoadingInAddressBar->setChecked(showPBinAB); ui->adressProgressSettings->setEnabled(showPBinAB); ui->progressStyleSelector->setCurrentIndex(settings.value("ProgressStyle", 0).toInt()); bool pbInABuseCC = settings.value("UseCustomProgressColor", false).toBool(); ui->checkBoxCustomProgressColor->setChecked(pbInABuseCC); ui->progressBarColorSelector->setEnabled(pbInABuseCC); QColor pbColor = settings.value("CustomProgressColor", palette().color(QPalette::Highlight)).value(); setProgressBarColorIcon(pbColor); connect(ui->customColorToolButton, &QAbstractButton::clicked, this, &Preferences::selectCustomProgressBarColor); connect(ui->resetProgressBarcolor, SIGNAL(clicked()), SLOT(setProgressBarColorIcon())); settings.endGroup(); settings.beginGroup("SearchEngines"); bool searchFromAB = settings.value("SearchFromAddressBar", true).toBool(); ui->searchFromAddressBar->setChecked(searchFromAB); ui->searchWithDefaultEngine->setEnabled(searchFromAB); ui->searchWithDefaultEngine->setChecked(settings.value("SearchWithDefaultEngine", false).toBool()); ui->showABSearchSuggestions->setEnabled(searchFromAB); ui->showABSearchSuggestions->setChecked(settings.value("showSearchSuggestions", true).toBool()); connect(ui->searchFromAddressBar, &QAbstractButton::toggled, this, &Preferences::searchFromAddressBarChanged); settings.endGroup(); // BROWSING settings.beginGroup("Web-Browser-Settings"); ui->allowPlugins->setChecked(settings.value("allowPlugins", true).toBool()); + connect(ui->allowPlugins, &QAbstractButton::toggled, this, &Preferences::allowPluginsToggled); ui->allowJavaScript->setChecked(settings.value("allowJavaScript", true).toBool()); ui->linksInFocusChain->setChecked(settings.value("IncludeLinkInFocusChain", false).toBool()); ui->spatialNavigation->setChecked(settings.value("SpatialNavigation", false).toBool()); ui->animateScrolling->setChecked(settings.value("AnimateScrolling", true).toBool()); ui->wheelScroll->setValue(settings.value("wheelScrollLines", qApp->wheelScrollLines()).toInt()); ui->xssAuditing->setChecked(settings.value("XSSAuditing", false).toBool()); ui->printEBackground->setChecked(settings.value("PrintElementBackground", true).toBool()); ui->useNativeScrollbars->setChecked(settings.value("UseNativeScrollbars", false).toBool()); ui->disableVideoAutoPlay->setChecked(settings.value("DisableVideoAutoPlay", false).toBool()); ui->webRTCPublicIpOnly->setChecked(settings.value("WebRTCPublicIpOnly", true).toBool()); ui->dnsPrefetch->setChecked(settings.value("DNSPrefetch", true).toBool()); + ui->intPDFViewer->setChecked(settings.value("intPDFViewer", false).toBool()); + ui->intPDFViewer->setEnabled(ui->allowPlugins->isChecked()); const auto levels = WebView::zoomLevels(); for (int level : levels) { ui->defaultZoomLevel->addItem(QString("%1%").arg(level)); } ui->defaultZoomLevel->setCurrentIndex(settings.value("DefaultZoomLevel", WebView::zoomLevels().indexOf(100)).toInt()); ui->closeAppWithCtrlQ->setChecked(settings.value("closeAppWithCtrlQ", true).toBool()); //Cache ui->allowCache->setChecked(settings.value("AllowLocalCache", true).toBool()); ui->removeCache->setChecked(settings.value("deleteCacheOnClose", false).toBool()); ui->cacheMB->setValue(settings.value("LocalCacheSize", 50).toInt()); ui->cachePath->setText(settings.value("CachePath", QWebEngineProfile::defaultProfile()->cachePath()).toString()); connect(ui->allowCache, &QAbstractButton::clicked, this, &Preferences::allowCacheChanged); connect(ui->changeCachePath, &QAbstractButton::clicked, this, &Preferences::changeCachePathClicked); allowCacheChanged(ui->allowCache->isChecked()); //PASSWORD MANAGER ui->allowPassManager->setChecked(settings.value("SavePasswordsOnSites", true).toBool()); ui->autoCompletePasswords->setChecked(settings.value("AutoCompletePasswords", true).toBool()); //PRIVACY //Web storage ui->saveHistory->setChecked(settings.value("allowHistory", true).toBool()); ui->deleteHistoryOnClose->setChecked(settings.value("deleteHistoryOnClose", false).toBool()); if (!ui->saveHistory->isChecked()) { ui->deleteHistoryOnClose->setEnabled(false); } connect(ui->saveHistory, &QAbstractButton::toggled, this, &Preferences::saveHistoryChanged); // Html5Storage ui->html5storage->setChecked(settings.value("HTML5StorageEnabled", true).toBool()); ui->deleteHtml5storageOnClose->setChecked(settings.value("deleteHTML5StorageOnClose", false).toBool()); connect(ui->html5storage, &QAbstractButton::toggled, this, &Preferences::allowHtml5storageChanged); // Other ui->doNotTrack->setChecked(settings.value("DoNotTrack", false).toBool()); //CSS Style ui->userStyleSheet->setText(settings.value("userStyleSheet", "").toString()); connect(ui->chooseUserStylesheet, &QAbstractButton::clicked, this, &Preferences::chooseUserStyleClicked); settings.endGroup(); //DOWNLOADS settings.beginGroup("DownloadManager"); ui->downLoc->setText(settings.value("defaultDownloadPath", "").toString()); ui->closeDownManOnFinish->setChecked(settings.value("CloseManagerOnFinish", false).toBool()); if (ui->downLoc->text().isEmpty()) { ui->askEverytime->setChecked(true); } else { ui->useDefined->setChecked(true); } ui->useExternalDownManager->setChecked(settings.value("UseExternalManager", false).toBool()); ui->externalDownExecutable->setText(settings.value("ExternalManagerExecutable", "").toString()); ui->externalDownArguments->setText(settings.value("ExternalManagerArguments", "").toString()); connect(ui->useExternalDownManager, &QAbstractButton::toggled, this, &Preferences::useExternalDownManagerChanged); connect(ui->useDefined, &QAbstractButton::toggled, this, &Preferences::downLocChanged); connect(ui->downButt, &QAbstractButton::clicked, this, &Preferences::chooseDownPath); connect(ui->chooseExternalDown, &QAbstractButton::clicked, this, &Preferences::chooseExternalDownloadManager); downLocChanged(ui->useDefined->isChecked()); useExternalDownManagerChanged(ui->useExternalDownManager->isChecked()); settings.endGroup(); //FONTS settings.beginGroup("Browser-Fonts"); QWebEngineSettings* webSettings = mApp->webSettings(); auto defaultFont = [&](QWebEngineSettings::FontFamily font) -> const QString { const QString family = webSettings->fontFamily(font); if (!family.isEmpty()) return family; switch (font) { case QWebEngineSettings::FixedFont: return QFontDatabase::systemFont(QFontDatabase::FixedFont).family(); case QWebEngineSettings::SerifFont: // TODO default: return QFontDatabase::systemFont(QFontDatabase::GeneralFont).family(); } }; ui->fontStandard->setCurrentFont(QFont(settings.value("StandardFont", defaultFont(QWebEngineSettings::StandardFont)).toString())); ui->fontCursive->setCurrentFont(QFont(settings.value("CursiveFont", defaultFont(QWebEngineSettings::CursiveFont)).toString())); ui->fontFantasy->setCurrentFont(QFont(settings.value("FantasyFont", defaultFont(QWebEngineSettings::FantasyFont)).toString())); ui->fontFixed->setCurrentFont(QFont(settings.value("FixedFont", defaultFont(QWebEngineSettings::FixedFont)).toString())); ui->fontSansSerif->setCurrentFont(QFont(settings.value("SansSerifFont", defaultFont(QWebEngineSettings::SansSerifFont)).toString())); ui->fontSerif->setCurrentFont(QFont(settings.value("SerifFont", defaultFont(QWebEngineSettings::SerifFont)).toString())); ui->sizeDefault->setValue(settings.value("DefaultFontSize", webSettings->fontSize(QWebEngineSettings::DefaultFontSize)).toInt()); ui->sizeFixed->setValue(settings.value("FixedFontSize", webSettings->fontSize(QWebEngineSettings::DefaultFixedFontSize)).toInt()); ui->sizeMinimum->setValue(settings.value("MinimumFontSize", webSettings->fontSize(QWebEngineSettings::MinimumFontSize)).toInt()); ui->sizeMinimumLogical->setValue(settings.value("MinimumLogicalFontSize", webSettings->fontSize(QWebEngineSettings::MinimumLogicalFontSize)).toInt()); settings.endGroup(); //KEYBOARD SHORTCUTS settings.beginGroup("Shortcuts"); ui->switchTabsAlt->setChecked(settings.value("useTabNumberShortcuts", true).toBool()); ui->loadSpeedDialsCtrl->setChecked(settings.value("useSpeedDialNumberShortcuts", true).toBool()); ui->singleKeyShortcuts->setChecked(settings.value("useSingleKeyShortcuts", false).toBool()); settings.endGroup(); //NOTIFICATIONS ui->useNativeSystemNotifications->setEnabled(mApp->desktopNotifications()->supportsNativeNotifications()); DesktopNotificationsFactory::Type notifyType; settings.beginGroup("Notifications"); ui->notificationTimeout->setValue(settings.value("Timeout", 6000).toInt() / 1000); #if defined(Q_OS_UNIX) && !defined(DISABLE_DBUS) notifyType = settings.value("UseNativeDesktop", true).toBool() ? DesktopNotificationsFactory::DesktopNative : DesktopNotificationsFactory::PopupWidget; #else notifyType = DesktopNotificationsFactory::PopupWidget; #endif if (ui->useNativeSystemNotifications->isEnabled() && notifyType == DesktopNotificationsFactory::DesktopNative) { ui->useNativeSystemNotifications->setChecked(true); } else { ui->useOSDNotifications->setChecked(true); } connect(ui->notificationPreview, &QPushButton::clicked, this, &Preferences::showNotificationPreview); ui->doNotUseNotifications->setChecked(!settings.value("Enabled", true).toBool()); m_notifPosition = settings.value("Position", QPoint(10, 10)).toPoint(); settings.endGroup(); //SPELLCHECK settings.beginGroup(QSL("SpellCheck")); ui->spellcheckEnabled->setChecked(settings.value(QSL("Enabled"), false).toBool()); const QStringList spellcheckLanguages = settings.value(QSL("Languages")).toStringList(); settings.endGroup(); auto updateSpellCheckEnabled = [this]() { ui->spellcheckLanguages->setEnabled(ui->spellcheckEnabled->isChecked()); ui->spellcheckNoLanguages->setEnabled(ui->spellcheckEnabled->isChecked()); }; updateSpellCheckEnabled(); connect(ui->spellcheckEnabled, &QCheckBox::toggled, this, updateSpellCheckEnabled); QStringList dictionariesDirs = { #ifdef Q_OS_OSX QDir::cleanPath(QCoreApplication::applicationDirPath() + QL1S("/../Resources/qtwebengine_dictionaries")), QDir::cleanPath(QCoreApplication::applicationDirPath() + QL1S("/../Frameworks/QtWebEngineCore.framework/Resources/qtwebengine_dictionaries")) #else QDir::cleanPath(QCoreApplication::applicationDirPath() + QL1S("/qtwebengine_dictionaries")), QDir::cleanPath(QLibraryInfo::location(QLibraryInfo::DataPath) + QL1S("/qtwebengine_dictionaries")) #endif }; dictionariesDirs.removeDuplicates(); ui->spellcheckDirectories->setText(dictionariesDirs.join(QL1C('\n'))); for (const QString &path : dictionariesDirs) { QDir dir(path); const QStringList files = dir.entryList({QSL("*.bdic")}); for (const QString &file : files) { const QString lang = file.left(file.size() - 5); const QString langName = createLanguageItem(lang); if (!ui->spellcheckLanguages->findItems(langName, Qt::MatchExactly).isEmpty()) { continue; } QListWidgetItem *item = new QListWidgetItem; item->setText(langName); item->setData(Qt::UserRole, lang); item->setFlags(item->flags() & ~Qt::ItemIsSelectable); item->setCheckState(Qt::Unchecked); ui->spellcheckLanguages->addItem(item); } } int topIndex = 0; for (const QString &lang : spellcheckLanguages) { const auto items = ui->spellcheckLanguages->findItems(createLanguageItem(lang), Qt::MatchExactly); if (items.isEmpty()) { continue; } QListWidgetItem *item = items.at(0); ui->spellcheckLanguages->takeItem(ui->spellcheckLanguages->row(item)); ui->spellcheckLanguages->insertItem(topIndex++, item); item->setCheckState(Qt::Checked); } if (ui->spellcheckLanguages->count() == 0) { ui->spellcheckLanguages->hide(); } else { ui->spellcheckNoLanguages->hide(); } // Proxy Configuration settings.beginGroup("Web-Proxy"); int proxyType = settings.value("ProxyType", 2).toInt(); if (proxyType == 0) { ui->noProxy->setChecked(true); } else if (proxyType == 2) { ui->systemProxy->setChecked(true); } else if (proxyType == 3) { ui->manualProxy->setChecked(true); ui->proxyType->setCurrentIndex(0); } else { ui->manualProxy->setChecked(true); ui->proxyType->setCurrentIndex(1); } ui->proxyServer->setText(settings.value("HostName", "").toString()); ui->proxyPort->setText(settings.value("Port", 8080).toString()); ui->proxyUsername->setText(settings.value("Username", "").toString()); ui->proxyPassword->setText(settings.value("Password", "").toString()); settings.endGroup(); setManualProxyConfigurationEnabled(ui->manualProxy->isChecked()); connect(ui->manualProxy, &QAbstractButton::toggled, this, &Preferences::setManualProxyConfigurationEnabled); //CONNECTS connect(ui->buttonBox, &QDialogButtonBox::clicked, this, &Preferences::buttonClicked); connect(ui->cookieManagerBut, &QAbstractButton::clicked, this, &Preferences::showCookieManager); connect(ui->html5permissions, &QAbstractButton::clicked, this, &Preferences::showHtml5Permissions); connect(ui->preferredLanguages, &QAbstractButton::clicked, this, &Preferences::showAcceptLanguage); connect(ui->deleteHtml5storage, &QAbstractButton::clicked, this, &Preferences::deleteHtml5storage); connect(ui->uaManager, &QAbstractButton::clicked, this, &Preferences::openUserAgentManager); connect(ui->jsOptionsButton, &QAbstractButton::clicked, this, &Preferences::openJsOptions); connect(ui->searchEngines, &QAbstractButton::clicked, this, &Preferences::openSearchEnginesManager); connect(ui->protocolHandlers, &QAbstractButton::clicked, this, &Preferences::openProtocolHandlersManager); connect(ui->listWidget, &QListWidget::currentItemChanged, this, &Preferences::showStackedPage); ui->listWidget->itemAt(5, 5)->setSelected(true); ui->listWidget->setCurrentRow(currentSettingsPage); QDesktopWidget* desktop = QApplication::desktop(); QSize s = size(); if (desktop->availableGeometry(this).size().width() < s.width()) { s.setWidth(desktop->availableGeometry(this).size().width() - 50); } if (desktop->availableGeometry(this).size().height() < s.height()) { s.setHeight(desktop->availableGeometry(this).size().height() - 50); } resize(s); settings.beginGroup(QSL("Preferences")); restoreGeometry(settings.value(QSL("Geometry")).toByteArray()); settings.endGroup(); QzTools::setWmClass("Preferences", this); } +void Preferences::allowPluginsToggled(bool checked) +{ + ui->intPDFViewer->setEnabled(checked); +} + void Preferences::chooseExternalDownloadManager() { QString path = QzTools::getOpenFileName("Preferences-ExternalDownloadManager", this, tr("Choose executable location..."), QDir::homePath()); if (path.isEmpty()) { return; } ui->externalDownExecutable->setText(path); } void Preferences::showStackedPage(QListWidgetItem* item) { if (!item) { return; } int index = ui->listWidget->currentRow(); ui->caption->setText("" + item->text() + ""); ui->stackedWidget->setCurrentIndex(index); if (m_notification) { m_notifPosition = m_notification.data()->pos(); delete m_notification.data(); } if (index == 10) { m_pluginsList->load(); } if (index == 7 && !m_autoFillManager) { m_autoFillManager = new AutoFillManager(this); ui->autoFillFrame->addWidget(m_autoFillManager); } } void Preferences::showNotificationPreview() { if (ui->useOSDNotifications->isChecked()) { if (m_notification) { m_notifPosition = m_notification.data()->pos(); delete m_notification.data(); } m_notification = new DesktopNotification(true); m_notification.data()->setHeading(tr("OSD Notification")); m_notification.data()->setText(tr("Drag it on the screen to place it where you want.")); m_notification.data()->move(m_notifPosition); m_notification.data()->show(); } else if (ui->useNativeSystemNotifications->isChecked()) { mApp->desktopNotifications()->nativeNotificationPreview(); } } void Preferences::makeFalkonDefault() { #if defined(Q_OS_WIN) && !defined(Q_OS_OS2) disconnect(ui->checkNowDefaultBrowser, SIGNAL(clicked()), this, SLOT(makeFalkonDefault())); ui->checkNowDefaultBrowser->setText(tr("Default")); ui->checkNowDefaultBrowser->setEnabled(false); if (!mApp->associationManager()->showNativeDefaultAppSettingsUi()) mApp->associationManager()->registerAllAssociation(); #endif } void Preferences::allowCacheChanged(bool state) { ui->removeCache->setEnabled(state); ui->maxCacheLabel->setEnabled(state); ui->cacheMB->setEnabled(state); ui->storeCacheLabel->setEnabled(state); ui->cachePath->setEnabled(state); ui->changeCachePath->setEnabled(state); } void Preferences::useActualHomepage() { if (!m_window) return; ui->homepage->setText(m_window->weView()->url().toString()); } void Preferences::useActualNewTab() { if (!m_window) return; ui->newTabUrl->setText(m_window->weView()->url().toString()); } void Preferences::chooseDownPath() { QString userFileName = QzTools::getExistingDirectory("Preferences-ChooseDownPath", this, tr("Choose download location..."), QDir::homePath()); if (userFileName.isEmpty()) { return; } #ifdef Q_OS_WIN //QFileDialog::getExistingDirectory returns path with \ instead of / (??) userFileName.replace(QLatin1Char('\\'), QLatin1Char('/')); #endif userFileName += QLatin1Char('/'); ui->downLoc->setText(userFileName); } void Preferences::chooseUserStyleClicked() { QString file = QzTools::getOpenFileName("Preferences-UserStyle", this, tr("Choose stylesheet location..."), QDir::homePath(), "*.css"); if (file.isEmpty()) { return; } ui->userStyleSheet->setText(file); } void Preferences::deleteHtml5storage() { ClearPrivateData::clearLocalStorage(); ui->deleteHtml5storage->setText(tr("Deleted")); ui->deleteHtml5storage->setEnabled(false); } void Preferences::openUserAgentManager() { UserAgentDialog* dialog = new UserAgentDialog(this); dialog->open(); } void Preferences::downLocChanged(bool state) { ui->downButt->setEnabled(state); ui->downLoc->setEnabled(state); } void Preferences::setManualProxyConfigurationEnabled(bool state) { ui->proxyType->setEnabled(state); ui->proxyServer->setEnabled(state); ui->proxyPort->setEnabled(state); ui->proxyUsername->setEnabled(state); ui->proxyPassword->setEnabled(state); } void Preferences::searchFromAddressBarChanged(bool stat) { ui->searchWithDefaultEngine->setEnabled(stat); ui->showABSearchSuggestions->setEnabled(stat); } void Preferences::saveHistoryChanged(bool stat) { ui->deleteHistoryOnClose->setEnabled(stat); } void Preferences::allowHtml5storageChanged(bool stat) { ui->deleteHtml5storageOnClose->setEnabled(stat); } void Preferences::showCookieManager() { CookieManager* dialog = new CookieManager(this); dialog->show(); } void Preferences::showHtml5Permissions() { HTML5PermissionsDialog* dialog = new HTML5PermissionsDialog(this); dialog->open(); } void Preferences::openJsOptions() { JsOptions* dialog = new JsOptions(this); dialog->open(); } void Preferences::useExternalDownManagerChanged(bool state) { ui->externalDownExecutable->setEnabled(state); ui->externalDownArguments->setEnabled(state); ui->chooseExternalDown->setEnabled(state); } void Preferences::openSearchEnginesManager() { SearchEnginesDialog* dialog = new SearchEnginesDialog(this); dialog->open(); } void Preferences::openProtocolHandlersManager() { ProtocolHandlerDialog *dialog = new ProtocolHandlerDialog(this); dialog->open(); } void Preferences::showAcceptLanguage() { AcceptLanguage* dialog = new AcceptLanguage(this); dialog->open(); } void Preferences::newTabChanged(int value) { ui->newTabFrame->setVisible(value == 3); } void Preferences::afterLaunchChanged(int value) { ui->dontLoadTabsUntilSelected->setEnabled(value == 3 || value == 4); } void Preferences::changeCachePathClicked() { QString path = QzTools::getExistingDirectory("Preferences-CachePath", this, tr("Choose cache path..."), ui->cachePath->text()); if (path.isEmpty()) { return; } ui->cachePath->setText(path); } void Preferences::buttonClicked(QAbstractButton* button) { switch (ui->buttonBox->buttonRole(button)) { case QDialogButtonBox::ApplyRole: saveSettings(); break; case QDialogButtonBox::RejectRole: close(); break; case QDialogButtonBox::AcceptRole: saveSettings(); close(); break; default: break; } } void Preferences::createProfile() { QString name = QInputDialog::getText(this, tr("New Profile"), tr("Enter the new profile's name:")); name = QzTools::filterCharsFromFilename(name); if (name.isEmpty()) { return; } int res = ProfileManager::createProfile(name); if (res == -1) { QMessageBox::warning(this, tr("Error!"), tr("This profile already exists!")); return; } if (res != 0) { QMessageBox::warning(this, tr("Error!"), tr("Cannot create profile directory!")); return; } ui->startProfile->addItem(name); ui->startProfile->setCurrentIndex(ui->startProfile->count() - 1); } void Preferences::deleteProfile() { QString name = ui->startProfile->currentText(); QMessageBox::StandardButton button = QMessageBox::warning(this, tr("Confirmation"), tr("Are you sure you want to permanently delete \"%1\" profile? This action cannot be undone!").arg(name), QMessageBox::Yes | QMessageBox::No); if (button != QMessageBox::Yes) { return; } ProfileManager::removeProfile(name); ui->startProfile->removeItem(ui->startProfile->currentIndex()); } void Preferences::startProfileIndexChanged(int index) { const bool current = ui->startProfile->itemText(index) == ProfileManager::currentProfile(); ui->deleteProfile->setEnabled(!current); ui->cannotDeleteActiveProfileLabel->setText(current ? tr("Note: You cannot delete active profile.") : QString()); } void Preferences::closeEvent(QCloseEvent* event) { Settings settings; settings.beginGroup("Browser-View-Settings"); settings.setValue("settingsDialogPage", ui->stackedWidget->currentIndex()); settings.endGroup(); event->accept(); } void Preferences::saveSettings() { Settings settings; //GENERAL URLs QUrl homepage = QUrl::fromUserInput(ui->homepage->text()); settings.beginGroup("Web-URL-Settings"); settings.setValue("homepage", homepage); settings.setValue("afterLaunch", ui->afterLaunch->currentIndex()); switch (ui->newTab->currentIndex()) { case 0: settings.setValue("newTabUrl", QUrl()); break; case 1: settings.setValue("newTabUrl", homepage); break; case 2: settings.setValue("newTabUrl", QUrl(QSL("falkon:speeddial"))); break; case 3: settings.setValue("newTabUrl", QUrl::fromUserInput(ui->newTabUrl->text())); break; default: break; } settings.endGroup(); //PROFILES /* * * * */ //WINDOW settings.beginGroup("Browser-View-Settings"); settings.setValue("showStatusBar", ui->showStatusbar->isChecked()); settings.setValue("instantBookmarksToolbar", ui->instantBookmarksToolbar->isChecked()); settings.setValue("showBookmarksToolbar", ui->showBookmarksToolbar->isChecked()); settings.setValue("showNavigationToolbar", ui->showNavigationToolbar->isChecked()); settings.endGroup(); //TABS settings.beginGroup("Browser-Tabs-Settings"); settings.setValue("hideTabsWithOneTab", ui->hideTabsOnTab->isChecked()); settings.setValue("ActivateLastTabWhenClosingActual", ui->activateLastTab->isChecked()); settings.setValue("newTabAfterActive", ui->openNewTabAfterActive->isChecked()); settings.setValue("newEmptyTabAfterActive", ui->openNewEmptyTabAfterActive->isChecked()); settings.setValue("OpenPopupsInTabs", ui->openPopupsInTabs->isChecked()); settings.setValue("AlwaysSwitchTabsWithWheel", ui->alwaysSwitchTabsWithWheel->isChecked()); settings.setValue("OpenNewTabsSelected", ui->switchToNewTabs->isChecked()); settings.setValue("dontCloseWithOneTab", ui->dontCloseOnLastTab->isChecked()); settings.setValue("AskOnClosing", ui->askWhenClosingMultipleTabs->isChecked()); settings.setValue("showClosedTabsButton", ui->showClosedTabsButton->isChecked()); settings.setValue("showCloseOnInactiveTabs", ui->showCloseOnInactive->currentIndex()); settings.endGroup(); //DOWNLOADS settings.beginGroup("DownloadManager"); if (ui->askEverytime->isChecked()) { settings.setValue("defaultDownloadPath", ""); } else { settings.setValue("defaultDownloadPath", ui->downLoc->text()); } settings.setValue("CloseManagerOnFinish", ui->closeDownManOnFinish->isChecked()); settings.setValue("UseExternalManager", ui->useExternalDownManager->isChecked()); settings.setValue("ExternalManagerExecutable", ui->externalDownExecutable->text()); settings.setValue("ExternalManagerArguments", ui->externalDownArguments->text()); settings.endGroup(); //FONTS settings.beginGroup("Browser-Fonts"); settings.setValue("StandardFont", ui->fontStandard->currentFont().family()); settings.setValue("CursiveFont", ui->fontCursive->currentFont().family()); settings.setValue("FantasyFont", ui->fontFantasy->currentFont().family()); settings.setValue("FixedFont", ui->fontFixed->currentFont().family()); settings.setValue("SansSerifFont", ui->fontSansSerif->currentFont().family()); settings.setValue("SerifFont", ui->fontSerif->currentFont().family()); settings.setValue("DefaultFontSize", ui->sizeDefault->value()); settings.setValue("FixedFontSize", ui->sizeFixed->value()); settings.setValue("MinimumFontSize", ui->sizeMinimum->value()); settings.setValue("MinimumLogicalFontSize", ui->sizeMinimumLogical->value()); settings.endGroup(); //KEYBOARD SHORTCUTS settings.beginGroup("Shortcuts"); settings.setValue("useTabNumberShortcuts", ui->switchTabsAlt->isChecked()); settings.setValue("useSpeedDialNumberShortcuts", ui->loadSpeedDialsCtrl->isChecked()); settings.setValue("useSingleKeyShortcuts", ui->singleKeyShortcuts->isChecked()); settings.endGroup(); //BROWSING settings.beginGroup("Web-Browser-Settings"); settings.setValue("allowPlugins", ui->allowPlugins->isChecked()); settings.setValue("allowJavaScript", ui->allowJavaScript->isChecked()); settings.setValue("IncludeLinkInFocusChain", ui->linksInFocusChain->isChecked()); settings.setValue("SpatialNavigation", ui->spatialNavigation->isChecked()); settings.setValue("AnimateScrolling", ui->animateScrolling->isChecked()); settings.setValue("wheelScrollLines", ui->wheelScroll->value()); settings.setValue("DoNotTrack", ui->doNotTrack->isChecked()); settings.setValue("CheckUpdates", ui->checkUpdates->isChecked()); settings.setValue("LoadTabsOnActivation", ui->dontLoadTabsUntilSelected->isChecked()); settings.setValue("DefaultZoomLevel", ui->defaultZoomLevel->currentIndex()); settings.setValue("XSSAuditing", ui->xssAuditing->isChecked()); settings.setValue("PrintElementBackground", ui->printEBackground->isChecked()); settings.setValue("closeAppWithCtrlQ", ui->closeAppWithCtrlQ->isChecked()); settings.setValue("UseNativeScrollbars", ui->useNativeScrollbars->isChecked()); settings.setValue("DisableVideoAutoPlay", ui->disableVideoAutoPlay->isChecked()); settings.setValue("WebRTCPublicIpOnly", ui->webRTCPublicIpOnly->isChecked()); settings.setValue("DNSPrefetch", ui->dnsPrefetch->isChecked()); + settings.setValue("intPDFViewer", ui->intPDFViewer->isChecked()); #ifdef Q_OS_WIN settings.setValue("CheckDefaultBrowser", ui->checkDefaultBrowser->isChecked()); #endif //Cache settings.setValue("AllowLocalCache", ui->allowCache->isChecked()); settings.setValue("deleteCacheOnClose", ui->removeCache->isChecked()); settings.setValue("LocalCacheSize", ui->cacheMB->value()); settings.setValue("CachePath", ui->cachePath->text()); //CSS Style settings.setValue("userStyleSheet", ui->userStyleSheet->text()); //PASSWORD MANAGER settings.setValue("SavePasswordsOnSites", ui->allowPassManager->isChecked()); settings.setValue("AutoCompletePasswords", ui->autoCompletePasswords->isChecked()); //PRIVACY //Web storage settings.setValue("allowHistory", ui->saveHistory->isChecked()); settings.setValue("deleteHistoryOnClose", ui->deleteHistoryOnClose->isChecked()); settings.setValue("HTML5StorageEnabled", ui->html5storage->isChecked()); settings.setValue("deleteHTML5StorageOnClose", ui->deleteHtml5storageOnClose->isChecked()); settings.endGroup(); //NOTIFICATIONS settings.beginGroup("Notifications"); settings.setValue("Timeout", ui->notificationTimeout->value() * 1000); settings.setValue("Enabled", !ui->doNotUseNotifications->isChecked()); settings.setValue("UseNativeDesktop", ui->useNativeSystemNotifications->isChecked()); settings.setValue("Position", m_notification.data() ? m_notification.data()->pos() : m_notifPosition); settings.endGroup(); //SPELLCHECK settings.beginGroup(QSL("SpellCheck")); settings.setValue("Enabled", ui->spellcheckEnabled->isChecked()); QStringList languages; for (int i = 0; i < ui->spellcheckLanguages->count(); ++i) { QListWidgetItem *item = ui->spellcheckLanguages->item(i); if (item->checkState() == Qt::Checked) { languages.append(item->data(Qt::UserRole).toString()); } } settings.setValue("Languages", languages); settings.endGroup(); //OTHER //AddressBar settings.beginGroup("AddressBar"); settings.setValue("showSuggestions", ui->addressbarCompletion->currentIndex()); settings.setValue("useInlineCompletion", ui->useInlineCompletion->isChecked()); settings.setValue("alwaysShowGoIcon", ui->alwaysShowGoIcon->isChecked()); settings.setValue("showSwitchTab", ui->completionShowSwitchTab->isChecked()); settings.setValue("SelectAllTextOnDoubleClick", ui->selectAllOnFocus->isChecked()); settings.setValue("SelectAllTextOnClick", ui->selectAllOnClick->isChecked()); settings.setValue("ShowLoadingProgress", ui->showLoadingInAddressBar->isChecked()); settings.setValue("ProgressStyle", ui->progressStyleSelector->currentIndex()); settings.setValue("UseCustomProgressColor", ui->checkBoxCustomProgressColor->isChecked()); settings.setValue("CustomProgressColor", ui->customColorToolButton->property("ProgressColor").value()); settings.endGroup(); settings.beginGroup("SearchEngines"); settings.setValue("SearchFromAddressBar", ui->searchFromAddressBar->isChecked()); settings.setValue("SearchWithDefaultEngine", ui->searchWithDefaultEngine->isChecked()); settings.setValue("showSearchSuggestions", ui->showABSearchSuggestions->isChecked()); settings.endGroup(); //Proxy Configuration int proxyType; if (ui->noProxy->isChecked()) { proxyType = 0; } else if (ui->systemProxy->isChecked()) { proxyType = 2; } else if (ui->proxyType->currentIndex() == 0) { // Http proxyType = 3; } else { // Socks5 proxyType = 4; } settings.beginGroup("Web-Proxy"); settings.setValue("ProxyType", proxyType); settings.setValue("HostName", ui->proxyServer->text()); settings.setValue("Port", ui->proxyPort->text().toInt()); settings.setValue("Username", ui->proxyUsername->text()); settings.setValue("Password", ui->proxyPassword->text()); settings.endGroup(); ProfileManager::setStartingProfile(ui->startProfile->currentText()); m_pluginsList->save(); m_themesManager->save(); mApp->cookieJar()->loadSettings(); mApp->history()->loadSettings(); mApp->reloadSettings(); mApp->desktopNotifications()->loadSettings(); mApp->autoFill()->loadSettings(); mApp->networkManager()->loadSettings(); WebScrollBarManager::instance()->loadSettings(); } Preferences::~Preferences() { Settings().setValue(QSL("Preferences/Geometry"), saveGeometry()); delete ui; delete m_autoFillManager; delete m_pluginsList; delete m_notification.data(); } void Preferences::setProgressBarColorIcon(QColor color) { const int size = style()->pixelMetric(QStyle::PM_ToolBarIconSize); QPixmap pm(QSize(size, size)); if (!color.isValid()) { color = palette().color(QPalette::Highlight); } pm.fill(color); ui->customColorToolButton->setIcon(pm); ui->customColorToolButton->setProperty("ProgressColor", color); } void Preferences::selectCustomProgressBarColor() { QColor newColor = QColorDialog::getColor(ui->customColorToolButton->property("ProgressColor").value(), this, tr("Select Color")); if (newColor.isValid()) { setProgressBarColorIcon(newColor); } } diff --git a/src/lib/preferences/preferences.h b/src/lib/preferences/preferences.h index 052551c1..7905fd30 100644 --- a/src/lib/preferences/preferences.h +++ b/src/lib/preferences/preferences.h @@ -1,110 +1,111 @@ /* ============================================================ * Falkon - Qt web browser * Copyright (C) 2010-2018 David Rosca * * 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 . * ============================================================ */ #ifndef PREFERENCES_H #define PREFERENCES_H #include #include #include #include "qzcommon.h" namespace Ui { class Preferences; } class QAbstractButton; class QListWidgetItem; class AutoFillManager; class BrowserWindow; class PluginsManager; class DesktopNotification; class ThemeManager; class FALKON_EXPORT Preferences : public QDialog { Q_OBJECT public: explicit Preferences(BrowserWindow* window); ~Preferences(); private Q_SLOTS: void saveSettings(); void buttonClicked(QAbstractButton* button); void showStackedPage(QListWidgetItem* item); void chooseDownPath(); void showCookieManager(); void showHtml5Permissions(); void useActualHomepage(); void useActualNewTab(); void showAcceptLanguage(); void chooseUserStyleClicked(); void deleteHtml5storage(); void chooseExternalDownloadManager(); void openUserAgentManager(); void openJsOptions(); void openSearchEnginesManager(); void openProtocolHandlersManager(); void searchFromAddressBarChanged(bool state); void saveHistoryChanged(bool state); void allowHtml5storageChanged(bool state); void downLocChanged(bool state); void allowCacheChanged(bool state); void setManualProxyConfigurationEnabled(bool state); void useExternalDownManagerChanged(bool state); void changeCachePathClicked(); + void allowPluginsToggled(bool checked); void newTabChanged(int value); void afterLaunchChanged(int value); void createProfile(); void deleteProfile(); void startProfileIndexChanged(int index); void setProgressBarColorIcon(QColor col = QColor()); void selectCustomProgressBarColor(); void showNotificationPreview(); void makeFalkonDefault(); private: void closeEvent(QCloseEvent* event) override; Ui::Preferences* ui; BrowserWindow* m_window; AutoFillManager* m_autoFillManager; PluginsManager* m_pluginsList; ThemeManager* m_themesManager; QPointer m_notification; QUrl m_homepage; QUrl m_newTabUrl; QString m_actProfileName; int m_afterLaunch; int m_onNewTab; QPoint m_notifPosition; }; #endif // PREFERENCES_H diff --git a/src/lib/preferences/preferences.ui b/src/lib/preferences/preferences.ui index bb041486..215d4fcc 100644 --- a/src/lib/preferences/preferences.ui +++ b/src/lib/preferences/preferences.ui @@ -1,2797 +1,2804 @@ Preferences 0 0 840 550 Preferences 220 0 220 16777215 false 32 32 QAbstractItemView::ScrollPerPixel QListView::Static 2 true true false General Appearance Tabs Browsing Fonts Keyboard Shortcuts Downloads Password Manager Privacy Notifications Extensions Spell Check Other Qt::Horizontal QFrame::NoFrame true 0 0 582 476 0 0 0 0 Qt::NoFocus 0 0 0 0 0 Use current QFrame::NoFrame QFrame::Raised 0 0 20 0 Note: You cannot delete active profile. Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 0 0 Create New false 0 0 Delete Qt::Horizontal QSizePolicy::Fixed 20 10 <b>Launching</b> After launch: Open blank page Open homepage Open speed dial Restore session Select session Homepage: Use current On new tab: Open blank tab Open homepage Open speed dial Open other page... <b>Profiles</b> Startup profile: Check for updates on start Active profile: Don't load tabs until selected Qt::Vertical 20 40 Check to see if Falkon is the default browser on startup false Check Now Qt::Horizontal 40 20 0 Themes 0 0 0 0 Advanced options Show StatusBar on start Show Bookmarks ToolBar on start Show Navigation ToolBar on start Enable instant Bookmarks ToolBar Qt::Horizontal 40 20 <b>Browser Window</b> Qt::Horizontal QSizePolicy::Fixed 20 20 Qt::Vertical 20 40 0 Tabs behaviour Hide tabs when there is only one tab Activate last tab when closing active tab Open new tabs after active tab Open new empty tabs after active tab Open popup windows in tabs Always switch between tabs with mouse wheel Automatically switch to newly opened tab Don't close window upon closing last tab Ask when closing multiple tabs Show closed tabs button Show close buttons on inactive tabs: Automatic Always Never Qt::Horizontal QSizePolicy::Expanding 40 20 Qt::Vertical 20 40 Address Bar behaviour Suggest when typing into address bar: 170 0 History and Bookmarks History Bookmarks Nothing Qt::Horizontal QSizePolicy::Expanding 40 20 Enable inline suggestions Press "Shift" to not switch the tab but load the url in the current tab Propose to switch tab if completed url is already loaded Always show go icon Select all text by double clicking in address bar Select all text by clicking in address bar Enable automatic searching from the address bar Search with Default Engine Show search suggestions Qt::Vertical QSizePolicy::Fixed 20 10 Show loading progress in address bar 0 0 Qt::Horizontal QSizePolicy::Fixed 20 20 Fill Bottom Top Custom color: 0 0 Select color ... Reset Qt::Horizontal 40 20 Qt::Vertical 20 40 0 Web Configuration - Allow Pepper Plugins (Flash plugin) + Enable Pepper plugin API (PPAPI) + + + + + + + Use built-in PDF viewer (requires PPAPI) Allow JavaScript Include links in focus chain Enable XSS Auditing Print element background Animated scrolling Enable spatial navigation Use native scrollbars Disable automatic playing of videos Prevent WebRTC from leaking local IP address Enable DNS prefetching 0 0 Mouse wheel scrolls 0 0 1 lines on page Default zoom on pages: Qt::Horizontal 40 20 Qt::Vertical 20 40 Local Storage Allow storing network cache on disk Qt::Horizontal QSizePolicy::Fixed 40 20 Delete cache on close Maximum: MB 1 999999999 50 Store cache in: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter ... Allow saving history Delete history on close Qt::Horizontal QSizePolicy::Fixed 40 20 Allow local storage of HTML5 web content Delete locally stored HTML5 web content on close Qt::Horizontal 40 20 0 0 Delete now Qt::Vertical 20 40 Qt::Vertical QSizePolicy::Fixed 20 10 Proxy Configuration Qt::Vertical 20 40 System proxy configuration Qt::Horizontal QSizePolicy::Fixed 40 20 Manual configuration HTTP SOCKS5 Port: 50 16777215 Username: Password: QLineEdit::Password Qt::Horizontal 40 20 No proxy <b>Font Families</b> 0 0 Standard Fixed Serif Sans Serif Cursive Qt::Vertical 20 40 Qt::Horizontal QSizePolicy::Fixed 20 20 0 0 Fantasy <b>Font Sizes</b> Fixed Font Size Default Font Size 0 0 0 0 Minimum Font Size Minimum Logical Font Size 0 0 0 0 <b>Shortcuts</b> Switch to tabs with Alt + number of tab Load speed dials with Ctrl + number of speed dial Existing shortcuts:<br/><b>1</b> - previous tab<br/><b>2</b> - next tab<br/><b>/</b> - search on page Use single key shortcuts If unchecked, prevents accidental exit from the application if the Ctrl-W shortcut was intended. Close application with Ctrl-Q Qt::Vertical 20 40 <b>Download Location</b> Ask everytime for download location Use defined location: ... Qt::Horizontal 40 20 Qt::Horizontal QSizePolicy::Fixed 20 20 <b>Download Options</b> Close download manager when downloading finishes <b>External download manager</b> Use external download manager QFormLayout::AllNonFixedFieldsGrow Executable: Arguments: Leave blank if unsure ... <b>%d</b> will be replaced with URL to be downloaded Qt::Vertical 20 40 <b>AutoFill options</b> Allow saving passwords from sites Qt::Horizontal QSizePolicy::Fixed 20 20 Qt::Horizontal 40 20 0 0 QLayout::SetMinAndMaxSize Automatically complete passwords on sites <b>Cookies</b> <b>Other</b> Qt::Vertical 20 40 0 0 JavaScript options true <b>JavaScript</b> 0 0 Cookies Manager false Manage JavaScript privacy options Qt::Horizontal QSizePolicy::Fixed 20 20 Manage HTML5 permissions Manage Cookies Qt::Horizontal 40 20 <b>HTML5 Permissions</b> 0 0 HTML5 Permissions Send Do Not Track header to servers Qt::Horizontal 40 20 Expiration timeout: 0 0 seconds Qt::Horizontal 40 20 <b>Notifications</b> Qt::Vertical 20 40 false Use Native System Notifications (Linux only) Do not use Notifications Qt::Horizontal QSizePolicy::Fixed 20 20 <b>Note: </b>You can change position of OSD Notification by dragging it on the screen. true Qt::Vertical QSizePolicy::Fixed 0 20 Use OSD Notifications Preview Qt::Horizontal 40 20 0 0 0 0 0 0 Qt::Horizontal 40 20 For more information about Spell Check, please see <a href="https://userbase.kde.org/Falkon#Spell_Check">wiki</a>. Qt::AlignCenter true Qt::Vertical 20 40 Qt::Vertical QSizePolicy::Fixed 20 40 <b>Spell Check options</b> Enable Spell Check <b>Dictionary directories</b> 0 0 true 0 0 560 80 16777215 100 true QAbstractItemView::InternalMove No languages found ... <b>Manage search engines</b> <b>User Style Sheet</b> Qt::Horizontal QSizePolicy::Fixed 20 20 Languages Qt::Horizontal 40 20 <b>Change browser identification</b> Qt::Horizontal QSizePolicy::Fixed 20 20 Protocol Handlers Manager Qt::Horizontal 40 20 Qt::Horizontal QSizePolicy::Fixed 20 20 Search Engines Manager Qt::Horizontal 40 20 Qt::Horizontal 40 20 Qt::Vertical 20 40 Style Sheet automatically loaded with all websites: <b>Preferred language for web sites</b> Qt::Horizontal QSizePolicy::Fixed 20 20 User Agent Manager Qt::Horizontal 40 20 <b>Manage protocol handlers</b> Qt::Horizontal QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok MacToolButton QToolButton
mactoolbutton.h
buttonBox afterLaunch homepage useCurrentBut newTab newTabUrl newTabUseCurrent checkUpdates startProfile createProfile deleteProfile tabWidget_2 hideTabsOnTab askWhenClosingMultipleTabs selectAllOnFocus selectAllOnClick tabWidget allowPlugins wheelScroll fontStandard fontFixed fontSerif fontSansSerif fontCursive fontFantasy askEverytime useDefined downLoc downButt closeDownManOnFinish allowPassManager useOSDNotifications useNativeSystemNotifications doNotUseNotifications notificationTimeout preferredLanguages userStyleSheet chooseUserStylesheet allowCache cacheMB saveHistory deleteHistoryOnClose proxyServer proxyPort manualProxy systemProxy showStatusbar showNavigationToolbar showBookmarksToolbar showLoadingInAddressBar toggled(bool) adressProgressSettings setEnabled(bool) 513 117 513 154 checkBoxCustomProgressColor toggled(bool) progressBarColorSelector setEnabled(bool) 405 152 567 157