File indexing completed on 2024-05-12 04:58:20

0001 /* ============================================================
0002 * Falkon - Qt web browser
0003 * Copyright (C) 2010-2018 David Rosca <nowrep@gmail.com>
0004 *
0005 * This program is free software: you can redistribute it and/or modify
0006 * it under the terms of the GNU General Public License as published by
0007 * the Free Software Foundation, either version 3 of the License, or
0008 * (at your option) any later version.
0009 *
0010 * This program is distributed in the hope that it will be useful,
0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0013 * GNU General Public License for more details.
0014 *
0015 * You should have received a copy of the GNU General Public License
0016 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
0017 * ============================================================ */
0018 #include "preferences.h"
0019 #include "ui_preferences.h"
0020 #include "browserwindow.h"
0021 #include "bookmarkstoolbar.h"
0022 #include "history.h"
0023 #include "tabwidget.h"
0024 #include "cookiejar.h"
0025 #include "locationbar.h"
0026 #include "autofillmanager.h"
0027 #include "mainapplication.h"
0028 #include "cookiemanager.h"
0029 #include "pluginproxy.h"
0030 #include "pluginsmanager.h"
0031 #include "jsoptions.h"
0032 #include "networkmanager.h"
0033 #include "desktopnotificationsfactory.h"
0034 #include "desktopnotification.h"
0035 #include "thememanager.h"
0036 #include "acceptlanguage.h"
0037 #include "qztools.h"
0038 #include "autofill.h"
0039 #include "settings.h"
0040 #include "datapaths.h"
0041 #include "tabbedwebview.h"
0042 #include "clearprivatedata.h"
0043 #include "useragentdialog.h"
0044 #include "registerqappassociation.h"
0045 #include "profilemanager.h"
0046 #include "html5permissions/html5permissionsdialog.h"
0047 #include "certificatemanager.h"
0048 #include "searchenginesdialog.h"
0049 #include "webscrollbarmanager.h"
0050 #include "protocolhandlerdialog.h"
0051 #include "schememanager.h"
0052 #include "../config.h"
0053 
0054 #include <QSettings>
0055 #include <QInputDialog>
0056 #include <QFileDialog>
0057 #include <QMessageBox>
0058 #include <QCloseEvent>
0059 #include <QColorDialog>
0060 #include <QWebEngineProfile>
0061 #include <QWebEngineSettings>
0062 #include <QLibraryInfo>
0063 #include <QtWebEngineWidgetsVersion>
0064 
0065 static QString createLanguageItem(const QString &lang)
0066 {
0067     QLocale locale(lang);
0068 
0069     if (locale.language() == QLocale::C) {
0070         return lang;
0071     }
0072 
0073     const QString country = QLocale::countryToString(locale.country());
0074     const QString language = QLocale::languageToString(locale.language());
0075 
0076     if (lang == QLatin1String("es_ES")) {
0077         return QString::fromUtf8("Castellano");
0078     }
0079     if (lang == QLatin1String("nqo")) {
0080         return QSL("N'ko (nqo)");
0081     }
0082     if (lang == QLatin1String("sr")) {
0083         return QString::fromUtf8("српски екавски");
0084     }
0085     if (lang == QLatin1String("sr@ijekavian")) {
0086         return QString::fromUtf8("српски ијекавски");
0087     }
0088     if (lang == QLatin1String("sr@latin")) {
0089         return QString::fromUtf8("srpski ekavski");
0090     }
0091     if (lang == QLatin1String("sr@ijekavianlatin")) {
0092         return QString::fromUtf8("srpski ijekavski");
0093     }
0094     return QStringLiteral("%1, %2 (%3)").arg(language, country, lang);
0095 }
0096 
0097 Preferences::Preferences(BrowserWindow* window)
0098     : QDialog(window)
0099     , ui(new Ui::Preferences)
0100     , m_window(window)
0101     , m_autoFillManager(nullptr)
0102     , m_pluginsList(nullptr)
0103 {
0104     setAttribute(Qt::WA_DeleteOnClose);
0105     ui->setupUi(this);
0106     QzTools::centerWidgetOnScreen(this);
0107 
0108     m_themesManager = new ThemeManager(ui->themesWidget, this);
0109     m_pluginsList = new PluginsManager(this);
0110     ui->pluginsFrame->addWidget(m_pluginsList);
0111 
0112 #ifdef DISABLE_CHECK_UPDATES
0113     ui->checkUpdates->setVisible(false);
0114 #endif
0115 
0116 
0117     auto setCategoryIcon = [this](int index, const QIcon &icon) {
0118         ui->listWidget->item(index)->setIcon(QIcon(icon.pixmap(32)));
0119     };
0120 
0121     setCategoryIcon(0, QIcon(QStringLiteral(":/icons/preferences/general.svg")));
0122     setCategoryIcon(1, QIcon(QStringLiteral(":/icons/preferences/appearance.svg")));
0123     setCategoryIcon(2, QIcon(QStringLiteral(":/icons/preferences/tabs.svg")));
0124     setCategoryIcon(3, QIcon(QStringLiteral(":/icons/preferences/browsing.svg")));
0125     setCategoryIcon(4, QIcon(QStringLiteral(":/icons/preferences/fonts.svg")));
0126     setCategoryIcon(5, QIcon(QStringLiteral(":/icons/preferences/shortcuts.svg")));
0127     setCategoryIcon(6, QIcon(QStringLiteral(":/icons/preferences/downloads.svg")));
0128     setCategoryIcon(7, QIcon(QStringLiteral(":/icons/preferences/passwords.svg")));
0129     setCategoryIcon(8, QIcon(QStringLiteral(":/icons/preferences/privacy.svg")));
0130     setCategoryIcon(9, QIcon(QStringLiteral(":/icons/preferences/notifications.svg")));
0131     setCategoryIcon(10, QIcon(QStringLiteral(":/icons/preferences/extensions.svg")));
0132     setCategoryIcon(11, QIcon(QStringLiteral(":/icons/preferences/spellcheck.svg")));
0133     setCategoryIcon(12, QIcon(QStringLiteral(":/icons/preferences/other.svg")));
0134 
0135     Settings settings;
0136     //GENERAL URLs
0137     settings.beginGroup(QSL("Web-URL-Settings"));
0138     m_homepage = settings.value(QSL("homepage"), QUrl(QSL("falkon:start"))).toUrl();
0139     m_newTabUrl = settings.value(QSL("newTabUrl"), QUrl(QSL("falkon:speeddial"))).toUrl();
0140     ui->homepage->setText(QString::fromUtf8(m_homepage.toEncoded()));
0141     ui->newTabUrl->setText(QString::fromUtf8(m_newTabUrl.toEncoded()));
0142     settings.endGroup();
0143     ui->afterLaunch->setCurrentIndex(mApp->afterLaunch());
0144     ui->checkUpdates->setChecked(settings.value(QSL("Web-Browser-Settings/CheckUpdates"), true).toBool());
0145     ui->dontLoadTabsUntilSelected->setChecked(settings.value(QSL("Web-Browser-Settings/LoadTabsOnActivation"), true).toBool());
0146 
0147 #if defined(Q_OS_WIN) && !defined(Q_OS_OS2)
0148     if (!mApp->isPortable()) {
0149         ui->checkDefaultBrowser->setChecked(settings.value(QSL("Web-Browser-Settings/CheckDefaultBrowser"),
0150                                                            DEFAULT_CHECK_DEFAULTBROWSER).toBool());
0151         if (mApp->associationManager()->isDefaultForAllCapabilities()) {
0152             ui->checkNowDefaultBrowser->setText(tr("Default"));
0153             ui->checkNowDefaultBrowser->setEnabled(false);
0154         }
0155         else {
0156             ui->checkNowDefaultBrowser->setText(tr("Set as default"));
0157             ui->checkNowDefaultBrowser->setEnabled(true);
0158             connect(ui->checkNowDefaultBrowser, SIGNAL(clicked()), this, SLOT(makeFalkonDefault()));
0159         }
0160     }
0161     else {
0162         ui->checkDefaultBrowser->hide();
0163         ui->checkNowDefaultBrowser->hide();
0164     }
0165 #else // No Default Browser settings on non-Windows platform
0166     ui->hSpacerDefaultBrowser->changeSize(0, 0, QSizePolicy::Fixed, QSizePolicy::Fixed);
0167     ui->hLayoutDefaultBrowser->invalidate();
0168     delete ui->hLayoutDefaultBrowser;
0169     delete ui->checkDefaultBrowser;
0170     delete ui->checkNowDefaultBrowser;
0171 #endif
0172 
0173     ui->newTabFrame->setVisible(false);
0174     if (m_newTabUrl.isEmpty() || m_newTabUrl.toString() == QL1S("about:blank")) {
0175         ui->newTab->setCurrentIndex(0);
0176     }
0177     else if (m_newTabUrl == m_homepage) {
0178         ui->newTab->setCurrentIndex(1);
0179     }
0180     else if (m_newTabUrl.toString() == QL1S("falkon:speeddial")) {
0181         ui->newTab->setCurrentIndex(2);
0182     }
0183     else {
0184         ui->newTab->setCurrentIndex(3);
0185         ui->newTabFrame->setVisible(true);
0186     }
0187 
0188     afterLaunchChanged(ui->afterLaunch->currentIndex());
0189     connect(ui->afterLaunch, SIGNAL(currentIndexChanged(int)), this, SLOT(afterLaunchChanged(int)));
0190     connect(ui->newTab, SIGNAL(currentIndexChanged(int)), this, SLOT(newTabChanged(int)));
0191     if (m_window) {
0192         connect(ui->useCurrentBut, &QAbstractButton::clicked, this, &Preferences::useActualHomepage);
0193         connect(ui->newTabUseCurrent, &QAbstractButton::clicked, this, &Preferences::useActualNewTab);
0194     }
0195     else {
0196         ui->useCurrentBut->setEnabled(false);
0197         ui->newTabUseCurrent->setEnabled(false);
0198     }
0199 
0200     // PROFILES
0201     QString startingProfile = ProfileManager::startingProfile();
0202     ui->activeProfile->setText(QStringLiteral("<b>") + ProfileManager::currentProfile() + QStringLiteral("</b>"));
0203     ui->startProfile->addItem(startingProfile);
0204 
0205     const auto names = ProfileManager::availableProfiles();
0206     for (const QString &name : names) {
0207         if (startingProfile != name) {
0208             ui->startProfile->addItem(name);
0209         }
0210     }
0211 
0212     connect(ui->createProfile, &QAbstractButton::clicked, this, &Preferences::createProfile);
0213     connect(ui->deleteProfile, &QAbstractButton::clicked, this, &Preferences::deleteProfile);
0214     connect(ui->startProfile, SIGNAL(currentIndexChanged(int)), this, SLOT(startProfileIndexChanged(int)));
0215     startProfileIndexChanged(ui->startProfile->currentIndex());
0216 
0217     //APPEREANCE
0218     settings.beginGroup(QSL("Browser-View-Settings"));
0219     ui->showStatusbar->setChecked(settings.value(QSL("showStatusBar"), false).toBool());
0220     // NOTE: instantBookmarksToolbar and showBookmarksToolbar cannot be both enabled at the same time
0221     ui->instantBookmarksToolbar->setChecked(settings.value(QSL("instantBookmarksToolbar"), false).toBool());
0222     ui->showBookmarksToolbar->setChecked(settings.value(QSL("showBookmarksToolbar"), false).toBool());
0223     ui->instantBookmarksToolbar->setDisabled(settings.value(QSL("showBookmarksToolbar"), false).toBool());
0224     ui->showBookmarksToolbar->setDisabled(settings.value(QSL("instantBookmarksToolbar")).toBool());
0225     connect(ui->instantBookmarksToolbar, &QAbstractButton::toggled, ui->showBookmarksToolbar, &QWidget::setDisabled);
0226     connect(ui->showBookmarksToolbar, &QAbstractButton::toggled, ui->instantBookmarksToolbar, &QWidget::setDisabled);
0227     ui->showNavigationToolbar->setChecked(settings.value(QSL("showNavigationToolbar"), true).toBool());
0228     int currentSettingsPage = settings.value(QSL("settingsDialogPage"), 0).toInt(nullptr);
0229     settings.endGroup();
0230 
0231     //TABS
0232     settings.beginGroup(QSL("Browser-Tabs-Settings"));
0233     ui->hideTabsOnTab->setChecked(settings.value(QSL("hideTabsWithOneTab"), false).toBool());
0234     ui->activateLastTab->setChecked(settings.value(QSL("ActivateLastTabWhenClosingActual"), false).toBool());
0235     ui->openNewTabAfterActive->setChecked(settings.value(QSL("newTabAfterActive"), true).toBool());
0236     ui->openNewEmptyTabAfterActive->setChecked(settings.value(QSL("newEmptyTabAfterActive"), false).toBool());
0237     ui->openPopupsInTabs->setChecked(settings.value(QSL("OpenPopupsInTabs"), false).toBool());
0238     ui->alwaysSwitchTabsWithWheel->setChecked(settings.value(QSL("AlwaysSwitchTabsWithWheel"), false).toBool());
0239     ui->switchToNewTabs->setChecked(settings.value(QSL("OpenNewTabsSelected"), false).toBool());
0240     ui->dontCloseOnLastTab->setChecked(settings.value(QSL("dontCloseWithOneTab"), false).toBool());
0241     ui->askWhenClosingMultipleTabs->setChecked(settings.value(QSL("AskOnClosing"), false).toBool());
0242     ui->showClosedTabsButton->setChecked(settings.value(QSL("showClosedTabsButton"), false).toBool());
0243     ui->showCloseOnInactive->setCurrentIndex(settings.value(QSL("showCloseOnInactiveTabs"), 0).toInt());
0244     settings.endGroup();
0245 
0246     //AddressBar
0247     settings.beginGroup(QSL("AddressBar"));
0248     ui->addressbarCompletion->setCurrentIndex(settings.value(QSL("showSuggestions"), 0).toInt());
0249     ui->useInlineCompletion->setChecked(settings.value(QSL("useInlineCompletion"), true).toBool());
0250     ui->completionShowSwitchTab->setChecked(settings.value(QSL("showSwitchTab"), true).toBool());
0251     ui->alwaysShowGoIcon->setChecked(settings.value(QSL("alwaysShowGoIcon"), false).toBool());
0252     ui->showZoomLabel->setChecked(settings.value(QSL("showZoomLabel"), true).toBool());
0253     ui->selectAllOnFocus->setChecked(settings.value(QSL("SelectAllTextOnDoubleClick"), true).toBool());
0254     ui->selectAllOnClick->setChecked(settings.value(QSL("SelectAllTextOnClick"), false).toBool());
0255     ui->completionPopupExpandToWindow->setChecked(settings.value(QSL("CompletionPopupExpandToWindow"), false).toBool());
0256     bool showPBinAB = settings.value(QSL("ShowLoadingProgress"), false).toBool();
0257     ui->showLoadingInAddressBar->setChecked(showPBinAB);
0258     ui->adressProgressSettings->setEnabled(showPBinAB);
0259     ui->progressStyleSelector->setCurrentIndex(settings.value(QSL("ProgressStyle"), 0).toInt());
0260     bool pbInABuseCC = settings.value(QSL("UseCustomProgressColor"), false).toBool();
0261     ui->checkBoxCustomProgressColor->setChecked(pbInABuseCC);
0262     ui->progressBarColorSelector->setEnabled(pbInABuseCC);
0263     QColor pbColor = settings.value(QSL("CustomProgressColor"), palette().color(QPalette::Highlight)).value<QColor>();
0264     setProgressBarColorIcon(pbColor);
0265     connect(ui->customColorToolButton, &QAbstractButton::clicked, this, &Preferences::selectCustomProgressBarColor);
0266     connect(ui->resetProgressBarcolor, SIGNAL(clicked()), SLOT(setProgressBarColorIcon()));
0267     settings.endGroup();
0268 
0269     settings.beginGroup(QSL("SearchEngines"));
0270     bool searchFromAB = settings.value(QSL("SearchFromAddressBar"), true).toBool();
0271     ui->searchFromAddressBar->setChecked(searchFromAB);
0272     ui->searchWithDefaultEngine->setEnabled(searchFromAB);
0273     ui->searchWithDefaultEngine->setChecked(settings.value(QSL("SearchWithDefaultEngine"), true).toBool());
0274     ui->showABSearchSuggestions->setEnabled(searchFromAB);
0275     ui->showABSearchSuggestions->setChecked(settings.value(QSL("showSearchSuggestions"), true).toBool());
0276     connect(ui->searchFromAddressBar, &QAbstractButton::toggled, this, &Preferences::searchFromAddressBarChanged);
0277     settings.endGroup();
0278 
0279     // BROWSING
0280     settings.beginGroup(QSL("Web-Browser-Settings"));
0281     ui->allowPlugins->setChecked(settings.value(QSL("allowPlugins"), true).toBool());
0282     connect(ui->allowPlugins, &QAbstractButton::toggled, this, &Preferences::allowPluginsToggled);
0283     ui->allowJavaScript->setChecked(settings.value(QSL("allowJavaScript"), true).toBool());
0284     ui->linksInFocusChain->setChecked(settings.value(QSL("IncludeLinkInFocusChain"), false).toBool());
0285     ui->spatialNavigation->setChecked(settings.value(QSL("SpatialNavigation"), false).toBool());
0286     ui->animateScrolling->setChecked(settings.value(QSL("AnimateScrolling"), true).toBool());
0287     ui->wheelScroll->setValue(settings.value(QSL("wheelScrollLines"), qApp->wheelScrollLines()).toInt());
0288     ui->xssAuditing->setChecked(settings.value(QSL("XSSAuditing"), false).toBool());
0289     ui->printEBackground->setChecked(settings.value(QSL("PrintElementBackground"), true).toBool());
0290     ui->useNativeScrollbars->setChecked(settings.value(QSL("UseNativeScrollbars"), false).toBool());
0291     ui->disableVideoAutoPlay->setChecked(settings.value(QSL("DisableVideoAutoPlay"), false).toBool());
0292     ui->webRTCPublicIpOnly->setChecked(settings.value(QSL("WebRTCPublicIpOnly"), true).toBool());
0293     ui->dnsPrefetch->setChecked(settings.value(QSL("DNSPrefetch"), true).toBool());
0294     ui->intPDFViewer->setChecked(settings.value(QSL("intPDFViewer"), false).toBool());
0295     ui->intPDFViewer->setEnabled(ui->allowPlugins->isChecked());
0296     ui->screenCaptureEnabled->setChecked(settings.value(QSL("screenCaptureEnabled"), false).toBool());
0297     ui->hardwareAccel->setChecked(settings.value(QSL("hardwareAccel"), false).toBool());
0298 
0299     const auto levels = WebView::zoomLevels();
0300     for (int level : levels) {
0301         ui->defaultZoomLevel->addItem(tr("%1%").arg(QString::number(level)));
0302     }
0303     ui->defaultZoomLevel->setCurrentIndex(settings.value(QSL("DefaultZoomLevel"), WebView::zoomLevels().indexOf(100)).toInt());
0304     ui->closeAppWithCtrlQ->setChecked(settings.value(QSL("closeAppWithCtrlQ"), true).toBool());
0305 
0306     //Cache
0307     ui->allowCache->setChecked(settings.value(QSL("AllowLocalCache"), true).toBool());
0308     ui->removeCache->setChecked(settings.value(QSL("deleteCacheOnClose"), false).toBool());
0309     ui->cacheMB->setValue(settings.value(QSL("LocalCacheSize"), 50).toInt());
0310     ui->cachePath->setText(settings.value(QSL("CachePath"), mApp->webProfile()->cachePath()).toString());
0311     connect(ui->allowCache, &QAbstractButton::clicked, this, &Preferences::allowCacheChanged);
0312     connect(ui->changeCachePath, &QAbstractButton::clicked, this, &Preferences::changeCachePathClicked);
0313     allowCacheChanged(ui->allowCache->isChecked());
0314 
0315     //PASSWORD MANAGER
0316     ui->allowPassManager->setChecked(settings.value(QSL("SavePasswordsOnSites"), true).toBool());
0317     ui->autoCompletePasswords->setChecked(settings.value(QSL("AutoCompletePasswords"), true).toBool());
0318 
0319     //PRIVACY
0320     //Web storage
0321     ui->saveHistory->setChecked(settings.value(QSL("allowHistory"), true).toBool());
0322     ui->deleteHistoryOnClose->setChecked(settings.value(QSL("deleteHistoryOnClose"), false).toBool());
0323     if (!ui->saveHistory->isChecked()) {
0324         ui->deleteHistoryOnClose->setEnabled(false);
0325     }
0326     connect(ui->saveHistory, &QAbstractButton::toggled, this, &Preferences::saveHistoryChanged);
0327 
0328     // Html5Storage
0329     ui->html5storage->setChecked(settings.value(QSL("HTML5StorageEnabled"), true).toBool());
0330     ui->deleteHtml5storageOnClose->setChecked(settings.value(QSL("deleteHTML5StorageOnClose"), false).toBool());
0331     connect(ui->html5storage, &QAbstractButton::toggled, this, &Preferences::allowHtml5storageChanged);
0332     // Other
0333     ui->doNotTrack->setChecked(settings.value(QSL("DoNotTrack"), false).toBool());
0334 
0335     //CSS Style
0336     ui->userStyleSheet->setText(settings.value(QSL("userStyleSheet"), QSL("")).toString());
0337     connect(ui->chooseUserStylesheet, &QAbstractButton::clicked, this, &Preferences::chooseUserStyleClicked);
0338     settings.endGroup();
0339 
0340     //DOWNLOADS
0341     settings.beginGroup(QSL("DownloadManager"));
0342     ui->downLoc->setText(settings.value(QSL("defaultDownloadPath"), QSL("")).toString());
0343     ui->closeDownManOnFinish->setChecked(settings.value(QSL("CloseManagerOnFinish"), false).toBool());
0344     if (ui->downLoc->text().isEmpty()) {
0345         ui->askEverytime->setChecked(true);
0346     }
0347     else {
0348         ui->useDefined->setChecked(true);
0349     }
0350     ui->useExternalDownManager->setChecked(settings.value(QSL("UseExternalManager"), false).toBool());
0351     ui->externalDownExecutable->setText(settings.value(QSL("ExternalManagerExecutable"), QSL("")).toString());
0352     ui->externalDownArguments->setText(settings.value(QSL("ExternalManagerArguments"), QSL("")).toString());
0353 
0354     connect(ui->useExternalDownManager, &QAbstractButton::toggled, this, &Preferences::useExternalDownManagerChanged);
0355 
0356 
0357     connect(ui->useDefined, &QAbstractButton::toggled, this, &Preferences::downLocChanged);
0358     connect(ui->downButt, &QAbstractButton::clicked, this, &Preferences::chooseDownPath);
0359     connect(ui->chooseExternalDown, &QAbstractButton::clicked, this, &Preferences::chooseExternalDownloadManager);
0360     downLocChanged(ui->useDefined->isChecked());
0361     useExternalDownManagerChanged(ui->useExternalDownManager->isChecked());
0362     settings.endGroup();
0363 
0364     //FONTS
0365     settings.beginGroup(QSL("Browser-Fonts"));
0366     QWebEngineSettings* webSettings = mApp->webSettings();
0367     auto defaultFont = [&](QWebEngineSettings::FontFamily font) -> const QString {
0368         const QString family = webSettings->fontFamily(font);
0369         if (!family.isEmpty())
0370             return family;
0371         switch (font) {
0372         case QWebEngineSettings::FixedFont:
0373             return QFontDatabase::systemFont(QFontDatabase::FixedFont).family();
0374         case QWebEngineSettings::SerifFont:
0375             // TODO
0376         default:
0377             return QFontDatabase::systemFont(QFontDatabase::GeneralFont).family();
0378         }
0379     };
0380     ui->fontStandard->setCurrentFont(QFont(settings.value(QSL("StandardFont"), defaultFont(QWebEngineSettings::StandardFont)).toString()));
0381     ui->fontCursive->setCurrentFont(QFont(settings.value(QSL("CursiveFont"), defaultFont(QWebEngineSettings::CursiveFont)).toString()));
0382     ui->fontFantasy->setCurrentFont(QFont(settings.value(QSL("FantasyFont"), defaultFont(QWebEngineSettings::FantasyFont)).toString()));
0383     ui->fontFixed->setCurrentFont(QFont(settings.value(QSL("FixedFont"), defaultFont(QWebEngineSettings::FixedFont)).toString()));
0384     ui->fontSansSerif->setCurrentFont(QFont(settings.value(QSL("SansSerifFont"), defaultFont(QWebEngineSettings::SansSerifFont)).toString()));
0385     ui->fontSerif->setCurrentFont(QFont(settings.value(QSL("SerifFont"), defaultFont(QWebEngineSettings::SerifFont)).toString()));
0386     ui->sizeDefault->setValue(settings.value(QSL("DefaultFontSize"), webSettings->fontSize(QWebEngineSettings::DefaultFontSize)).toInt());
0387     ui->sizeFixed->setValue(settings.value(QSL("FixedFontSize"), webSettings->fontSize(QWebEngineSettings::DefaultFixedFontSize)).toInt());
0388     ui->sizeMinimum->setValue(settings.value(QSL("MinimumFontSize"), webSettings->fontSize(QWebEngineSettings::MinimumFontSize)).toInt());
0389     ui->sizeMinimumLogical->setValue(settings.value(QSL("MinimumLogicalFontSize"), webSettings->fontSize(QWebEngineSettings::MinimumLogicalFontSize)).toInt());
0390     settings.endGroup();
0391 
0392     //KEYBOARD SHORTCUTS
0393     settings.beginGroup(QSL("Shortcuts"));
0394     ui->switchTabsAlt->setChecked(settings.value(QSL("useTabNumberShortcuts"), true).toBool());
0395     ui->loadSpeedDialsCtrl->setChecked(settings.value(QSL("useSpeedDialNumberShortcuts"), true).toBool());
0396     ui->singleKeyShortcuts->setChecked(settings.value(QSL("useSingleKeyShortcuts"), false).toBool());
0397     settings.endGroup();
0398 
0399     //NOTIFICATIONS
0400     ui->useNativeSystemNotifications->setEnabled(mApp->desktopNotifications()->supportsNativeNotifications());
0401 
0402     DesktopNotificationsFactory::Type notifyType;
0403     settings.beginGroup(QSL("Notifications"));
0404     ui->notificationTimeout->setValue(settings.value(QSL("Timeout"), 6000).toInt() / 1000);
0405 #if defined(Q_OS_UNIX) && !defined(DISABLE_DBUS)
0406     notifyType = settings.value(QSL("UseNativeDesktop"), true).toBool() ? DesktopNotificationsFactory::DesktopNative : DesktopNotificationsFactory::PopupWidget;
0407 #else
0408     notifyType = DesktopNotificationsFactory::PopupWidget;
0409 #endif
0410     if (ui->useNativeSystemNotifications->isEnabled() && notifyType == DesktopNotificationsFactory::DesktopNative) {
0411         ui->useNativeSystemNotifications->setChecked(true);
0412     }
0413     else {
0414         ui->useOSDNotifications->setChecked(true);
0415     }
0416 
0417     connect(ui->notificationPreview, &QPushButton::clicked, this, &Preferences::showNotificationPreview);
0418 
0419     ui->doNotUseNotifications->setChecked(!settings.value(QSL("Enabled"), true).toBool());
0420     m_notifPosition = settings.value(QSL("Position"), QPoint(10, 10)).toPoint();
0421     settings.endGroup();
0422 
0423     //SPELLCHECK
0424     settings.beginGroup(QSL("SpellCheck"));
0425     ui->spellcheckEnabled->setChecked(settings.value(QSL("Enabled"), false).toBool());
0426     const QStringList spellcheckLanguages = settings.value(QSL("Languages")).toStringList();
0427     settings.endGroup();
0428 
0429     auto updateSpellCheckEnabled = [this]() {
0430         ui->spellcheckLanguages->setEnabled(ui->spellcheckEnabled->isChecked());
0431         ui->spellcheckNoLanguages->setEnabled(ui->spellcheckEnabled->isChecked());
0432     };
0433     updateSpellCheckEnabled();
0434     connect(ui->spellcheckEnabled, &QCheckBox::toggled, this, updateSpellCheckEnabled);
0435 
0436     QStringList dictionariesDirs = {};
0437     const QByteArray qtWeDictionariesDirs = qgetenv("QTWEBENGINE_DICTIONARIES_PATH");
0438     if (!qtWeDictionariesDirs.isNull()) {
0439         dictionariesDirs.append(QDir::cleanPath(QString::fromLocal8Bit(qtWeDictionariesDirs)));
0440     }
0441     else {
0442 #ifdef Q_OS_OSX
0443         dictionariesDirs.append(QDir::cleanPath(QCoreApplication::applicationDirPath() + QL1S("/../Resources/qtwebengine_dictionaries")));
0444         dictionariesDirs.append(QDir::cleanPath(QCoreApplication::applicationDirPath() + QL1S("/../Frameworks/QtWebEngineCore.framework/Resources/qtwebengine_dictionaries")));
0445 #else
0446         dictionariesDirs.append(QDir::cleanPath(QCoreApplication::applicationDirPath() + QL1S("/qtwebengine_dictionaries")));
0447         dictionariesDirs.append(QDir::cleanPath(QLibraryInfo::location(QLibraryInfo::DataPath) + QL1S("/qtwebengine_dictionaries")));
0448 #endif
0449     }
0450     dictionariesDirs.removeDuplicates();
0451 
0452     ui->spellcheckDirectories->setText(dictionariesDirs.join(QL1C('\n')));
0453 
0454     for (const QString &path : dictionariesDirs) {
0455         QDir dir(path);
0456         const QStringList files = dir.entryList({QSL("*.bdic")});
0457         for (const QString &file : files) {
0458             const QString lang = file.left(file.size() - 5);
0459             const QString langName = createLanguageItem(lang);
0460             if (!ui->spellcheckLanguages->findItems(langName, Qt::MatchExactly).isEmpty()) {
0461                 continue;
0462             }
0463             auto *item = new QListWidgetItem;
0464             item->setText(langName);
0465             item->setData(Qt::UserRole, lang);
0466             item->setFlags(item->flags() & ~Qt::ItemIsSelectable);
0467             item->setCheckState(Qt::Unchecked);
0468             ui->spellcheckLanguages->addItem(item);
0469         }
0470     }
0471 
0472     int topIndex = 0;
0473     for (const QString &lang : spellcheckLanguages) {
0474         const auto items = ui->spellcheckLanguages->findItems(createLanguageItem(lang), Qt::MatchExactly);
0475         if (items.isEmpty()) {
0476             continue;
0477         }
0478         QListWidgetItem *item = items.at(0);
0479         ui->spellcheckLanguages->takeItem(ui->spellcheckLanguages->row(item));
0480         ui->spellcheckLanguages->insertItem(topIndex++, item);
0481         item->setCheckState(Qt::Checked);
0482     }
0483 
0484     if (ui->spellcheckLanguages->count() == 0) {
0485         ui->spellcheckLanguages->hide();
0486     } else {
0487         ui->spellcheckNoLanguages->hide();
0488     }
0489 
0490     // Proxy Configuration
0491     settings.beginGroup(QSL("Web-Proxy"));
0492     int proxyType = settings.value(QSL("ProxyType"), 2).toInt();
0493     if (proxyType == 0) {
0494         ui->noProxy->setChecked(true);
0495     } else if (proxyType == 2) {
0496         ui->systemProxy->setChecked(true);
0497     } else if (proxyType == 3) {
0498         ui->manualProxy->setChecked(true);
0499         ui->proxyType->setCurrentIndex(0);
0500     } else {
0501         ui->manualProxy->setChecked(true);
0502         ui->proxyType->setCurrentIndex(1);
0503     }
0504 
0505     ui->proxyServer->setText(settings.value(QSL("HostName"), QSL("")).toString());
0506     ui->proxyPort->setText(settings.value(QSL("Port"), 8080).toString());
0507     ui->proxyUsername->setText(settings.value(QSL("Username"), QSL("")).toString());
0508     ui->proxyPassword->setText(settings.value(QSL("Password"), QSL("")).toString());
0509     settings.endGroup();
0510 
0511     setManualProxyConfigurationEnabled(ui->manualProxy->isChecked());
0512     connect(ui->manualProxy, &QAbstractButton::toggled, this, &Preferences::setManualProxyConfigurationEnabled);
0513 
0514     //CONNECTS
0515     connect(ui->buttonBox, &QDialogButtonBox::clicked, this, &Preferences::buttonClicked);
0516     connect(ui->cookieManagerBut, &QAbstractButton::clicked, this, &Preferences::showCookieManager);
0517     connect(ui->html5permissions, &QAbstractButton::clicked, this, &Preferences::showHtml5Permissions);
0518     connect(ui->preferredLanguages, &QAbstractButton::clicked, this, &Preferences::showAcceptLanguage);
0519     connect(ui->deleteHtml5storage, &QAbstractButton::clicked, this, &Preferences::deleteHtml5storage);
0520     connect(ui->uaManager, &QAbstractButton::clicked, this, &Preferences::openUserAgentManager);
0521     connect(ui->jsOptionsButton, &QAbstractButton::clicked, this, &Preferences::openJsOptions);
0522     connect(ui->searchEngines, &QAbstractButton::clicked, this, &Preferences::openSearchEnginesManager);
0523     connect(ui->certificateManager, &QAbstractButton::clicked, this, &Preferences::openCertificateManager);
0524     connect(ui->protocolHandlers, &QAbstractButton::clicked, this, &Preferences::openProtocolHandlersManager);
0525     connect(ui->customSchemes, &QAbstractButton::clicked, this, &Preferences::openSchemesManager);
0526 
0527     connect(ui->listWidget, &QListWidget::currentItemChanged, this, &Preferences::showStackedPage);
0528     ui->listWidget->itemAt(5, 5)->setSelected(true);
0529 
0530     ui->listWidget->setCurrentRow(currentSettingsPage);
0531 
0532     QSize s = size();
0533     const QRect &availableGeometryForScreen = screen()->availableGeometry();
0534     if (availableGeometryForScreen.size().width() < s.width()) {
0535         s.setWidth(availableGeometryForScreen.size().width() - 50);
0536     }
0537     if (availableGeometryForScreen.size().height() < s.height()) {
0538         s.setHeight(availableGeometryForScreen.size().height() - 50);
0539     }
0540     resize(s);
0541 
0542     settings.beginGroup(QSL("Preferences"));
0543     restoreGeometry(settings.value(QSL("Geometry")).toByteArray());
0544     settings.endGroup();
0545 
0546     QzTools::setWmClass(QSL("Preferences"), this);
0547 }
0548 
0549 void Preferences::allowPluginsToggled(bool checked)
0550 {
0551     ui->intPDFViewer->setEnabled(checked);
0552 }
0553 
0554 void Preferences::chooseExternalDownloadManager()
0555 {
0556     QString path = QzTools::getOpenFileName(QSL("Preferences-ExternalDownloadManager"), this, tr("Choose executable location..."), QDir::homePath());
0557     if (path.isEmpty()) {
0558         return;
0559     }
0560 
0561     ui->externalDownExecutable->setText(path);
0562 }
0563 
0564 void Preferences::showStackedPage(QListWidgetItem* item)
0565 {
0566     if (!item) {
0567         return;
0568     }
0569 
0570     int index = ui->listWidget->currentRow();
0571 
0572     ui->caption->setText(QSL("<b>") + item->text() + QSL("</b>"));
0573     ui->stackedWidget->setCurrentIndex(index);
0574 
0575     if (m_notification) {
0576         m_notifPosition = m_notification.data()->pos();
0577         delete m_notification.data();
0578     }
0579 
0580     if (index == 10) {
0581         m_pluginsList->load();
0582     }
0583 
0584     if (index == 7 && !m_autoFillManager) {
0585         m_autoFillManager = new AutoFillManager(this);
0586         ui->autoFillFrame->addWidget(m_autoFillManager);
0587     }
0588 }
0589 
0590 void Preferences::showNotificationPreview()
0591 {
0592     if (ui->useOSDNotifications->isChecked()) {
0593         if (m_notification) {
0594             m_notifPosition = m_notification.data()->pos();
0595             delete m_notification.data();
0596         }
0597 
0598         m_notification = new DesktopNotification(true);
0599         m_notification.data()->setHeading(tr("OSD Notification"));
0600         m_notification.data()->setText(tr("Drag it on the screen to place it where you want."));
0601         m_notification.data()->move(m_notifPosition);
0602         m_notification.data()->show();
0603     }
0604     else if (ui->useNativeSystemNotifications->isChecked()) {
0605         mApp->desktopNotifications()->nativeNotificationPreview();
0606     }
0607 }
0608 
0609 void Preferences::makeFalkonDefault()
0610 {
0611 #if defined(Q_OS_WIN) && !defined(Q_OS_OS2)
0612     disconnect(ui->checkNowDefaultBrowser, SIGNAL(clicked()), this, SLOT(makeFalkonDefault()));
0613     ui->checkNowDefaultBrowser->setText(tr("Default"));
0614     ui->checkNowDefaultBrowser->setEnabled(false);
0615 
0616     if (!mApp->associationManager()->showNativeDefaultAppSettingsUi())
0617         mApp->associationManager()->registerAllAssociation();
0618 #endif
0619 }
0620 
0621 void Preferences::allowCacheChanged(bool state)
0622 {
0623     ui->removeCache->setEnabled(state);
0624     ui->maxCacheLabel->setEnabled(state);
0625     ui->cacheMB->setEnabled(state);
0626     ui->storeCacheLabel->setEnabled(state);
0627     ui->cachePath->setEnabled(state);
0628     ui->changeCachePath->setEnabled(state);
0629 }
0630 
0631 void Preferences::useActualHomepage()
0632 {
0633     if (!m_window)
0634         return;
0635 
0636     ui->homepage->setText(m_window->weView()->url().toString());
0637 }
0638 
0639 void Preferences::useActualNewTab()
0640 {
0641     if (!m_window)
0642         return;
0643 
0644     ui->newTabUrl->setText(m_window->weView()->url().toString());
0645 }
0646 
0647 void Preferences::chooseDownPath()
0648 {
0649     QString userFileName = QzTools::getExistingDirectory(QSL("Preferences-ChooseDownPath"), this, tr("Choose download location..."), QDir::homePath());
0650     if (userFileName.isEmpty()) {
0651         return;
0652     }
0653 #ifdef Q_OS_WIN   //QFileDialog::getExistingDirectory returns path with \ instead of / (??)
0654     userFileName.replace(QLatin1Char('\\'), QLatin1Char('/'));
0655 #endif
0656     userFileName += QLatin1Char('/');
0657 
0658     ui->downLoc->setText(userFileName);
0659 }
0660 
0661 void Preferences::chooseUserStyleClicked()
0662 {
0663     QString file = QzTools::getOpenFileName(QSL("Preferences-UserStyle"), this, tr("Choose stylesheet location..."), QDir::homePath(), QSL("*.css"));
0664     if (file.isEmpty()) {
0665         return;
0666     }
0667     ui->userStyleSheet->setText(file);
0668 }
0669 
0670 void Preferences::deleteHtml5storage()
0671 {
0672     ClearPrivateData::clearLocalStorage();
0673 
0674     ui->deleteHtml5storage->setText(tr("Deleted"));
0675     ui->deleteHtml5storage->setEnabled(false);
0676 }
0677 
0678 void Preferences::openUserAgentManager()
0679 {
0680     auto* dialog = new UserAgentDialog(this);
0681     dialog->open();
0682 }
0683 
0684 void Preferences::downLocChanged(bool state)
0685 {
0686     ui->downButt->setEnabled(state);
0687     ui->downLoc->setEnabled(state);
0688 }
0689 
0690 void Preferences::setManualProxyConfigurationEnabled(bool state)
0691 {
0692     ui->proxyType->setEnabled(state);
0693     ui->proxyServer->setEnabled(state);
0694     ui->proxyPort->setEnabled(state);
0695     ui->proxyUsername->setEnabled(state);
0696     ui->proxyPassword->setEnabled(state);
0697 }
0698 
0699 void Preferences::searchFromAddressBarChanged(bool stat)
0700 {
0701     ui->searchWithDefaultEngine->setEnabled(stat);
0702     ui->showABSearchSuggestions->setEnabled(stat);
0703 }
0704 
0705 void Preferences::saveHistoryChanged(bool stat)
0706 {
0707     ui->deleteHistoryOnClose->setEnabled(stat);
0708 }
0709 
0710 void Preferences::allowHtml5storageChanged(bool stat)
0711 {
0712     ui->deleteHtml5storageOnClose->setEnabled(stat);
0713 }
0714 
0715 void Preferences::showCookieManager()
0716 {
0717     auto* dialog = new CookieManager(this);
0718     dialog->show();
0719 }
0720 
0721 void Preferences::showHtml5Permissions()
0722 {
0723     auto* dialog = new HTML5PermissionsDialog(this);
0724     dialog->open();
0725 }
0726 
0727 void Preferences::openJsOptions()
0728 {
0729     auto* dialog = new JsOptions(this);
0730     dialog->open();
0731 }
0732 
0733 void Preferences::useExternalDownManagerChanged(bool state)
0734 {
0735     ui->externalDownExecutable->setEnabled(state);
0736     ui->externalDownArguments->setEnabled(state);
0737     ui->chooseExternalDown->setEnabled(state);
0738 }
0739 
0740 void Preferences::openSearchEnginesManager()
0741 {
0742     auto* dialog = new SearchEnginesDialog(this);
0743     dialog->open();
0744 }
0745 
0746 void Preferences::openCertificateManager()
0747 {
0748     auto *dialog = new CertificateManager(this);
0749     dialog->open();
0750 }
0751 
0752 void Preferences::openProtocolHandlersManager()
0753 {
0754     auto *dialog = new ProtocolHandlerDialog(this);
0755     dialog->open();
0756 }
0757 
0758 void Preferences::openSchemesManager()
0759 {
0760     auto *dialog = new SchemeManager(this);
0761     dialog->open();
0762 }
0763 
0764 void Preferences::showAcceptLanguage()
0765 {
0766     auto* dialog = new AcceptLanguage(this);
0767     dialog->open();
0768 }
0769 
0770 void Preferences::newTabChanged(int value)
0771 {
0772     ui->newTabFrame->setVisible(value == 3);
0773 }
0774 
0775 void Preferences::afterLaunchChanged(int value)
0776 {
0777     ui->dontLoadTabsUntilSelected->setEnabled(value == 3 || value == 4);
0778 }
0779 
0780 void Preferences::changeCachePathClicked()
0781 {
0782     QString path = QzTools::getExistingDirectory(QSL("Preferences-CachePath"), this, tr("Choose cache path..."), ui->cachePath->text());
0783     if (path.isEmpty()) {
0784         return;
0785     }
0786 
0787     ui->cachePath->setText(path);
0788 }
0789 
0790 void Preferences::buttonClicked(QAbstractButton* button)
0791 {
0792     switch (ui->buttonBox->buttonRole(button)) {
0793     case QDialogButtonBox::ApplyRole:
0794         saveSettings();
0795         break;
0796 
0797     case QDialogButtonBox::RejectRole:
0798         close();
0799         break;
0800 
0801     case QDialogButtonBox::AcceptRole:
0802         saveSettings();
0803         close();
0804         break;
0805 
0806     default:
0807         break;
0808     }
0809 }
0810 
0811 void Preferences::createProfile()
0812 {
0813     QString name = QInputDialog::getText(this, tr("New Profile"), tr("Enter the new profile's name:"));
0814     name = QzTools::filterCharsFromFilename(name);
0815 
0816     if (name.isEmpty()) {
0817         return;
0818     }
0819 
0820     int res = ProfileManager::createProfile(name);
0821 
0822     if (res == -1) {
0823         QMessageBox::warning(this, tr("Error!"), tr("This profile already exists!"));
0824         return;
0825     }
0826 
0827     if (res != 0) {
0828         QMessageBox::warning(this, tr("Error!"), tr("Cannot create profile directory!"));
0829         return;
0830     }
0831 
0832     ui->startProfile->addItem(name);
0833     ui->startProfile->setCurrentIndex(ui->startProfile->count() - 1);
0834 }
0835 
0836 void Preferences::deleteProfile()
0837 {
0838     QString name = ui->startProfile->currentText();
0839     QMessageBox::StandardButton button = QMessageBox::warning(this, tr("Confirmation"),
0840                                          tr("Are you sure you want to permanently delete \"%1\" profile? This action cannot be undone!").arg(name), QMessageBox::Yes | QMessageBox::No);
0841     if (button != QMessageBox::Yes) {
0842         return;
0843     }
0844 
0845     ProfileManager::removeProfile(name);
0846 
0847     ui->startProfile->removeItem(ui->startProfile->currentIndex());
0848 }
0849 
0850 void Preferences::startProfileIndexChanged(int index)
0851 {
0852     const bool current = ui->startProfile->itemText(index) == ProfileManager::currentProfile();
0853 
0854     ui->deleteProfile->setEnabled(!current);
0855     ui->cannotDeleteActiveProfileLabel->setText(current ? tr("Note: You cannot delete active profile.") : QString());
0856 }
0857 
0858 void Preferences::closeEvent(QCloseEvent* event)
0859 {
0860     Settings settings;
0861     settings.beginGroup(QSL("Browser-View-Settings"));
0862     settings.setValue(QSL("settingsDialogPage"), ui->stackedWidget->currentIndex());
0863     settings.endGroup();
0864 
0865     event->accept();
0866 }
0867 
0868 void Preferences::saveSettings()
0869 {
0870     Settings settings;
0871     //GENERAL URLs
0872     QUrl homepage = QUrl::fromUserInput(ui->homepage->text());
0873 
0874     settings.beginGroup(QSL("Web-URL-Settings"));
0875     settings.setValue(QSL("homepage"), homepage);
0876     settings.setValue(QSL("afterLaunch"), ui->afterLaunch->currentIndex());
0877 
0878     switch (ui->newTab->currentIndex()) {
0879     case 0:
0880         settings.setValue(QSL("newTabUrl"), QUrl());
0881         break;
0882 
0883     case 1:
0884         settings.setValue(QSL("newTabUrl"), homepage);
0885         break;
0886 
0887     case 2:
0888         settings.setValue(QSL("newTabUrl"), QUrl(QSL("falkon:speeddial")));
0889         break;
0890 
0891     case 3:
0892         settings.setValue(QSL("newTabUrl"), QUrl::fromUserInput(ui->newTabUrl->text()));
0893         break;
0894 
0895     default:
0896         break;
0897     }
0898 
0899     settings.endGroup();
0900     //PROFILES
0901     /*
0902      *
0903      *
0904      *
0905      */
0906 
0907     //WINDOW
0908     settings.beginGroup(QSL("Browser-View-Settings"));
0909     settings.setValue(QSL("showStatusBar"), ui->showStatusbar->isChecked());
0910     settings.setValue(QSL("instantBookmarksToolbar"), ui->instantBookmarksToolbar->isChecked());
0911     settings.setValue(QSL("showBookmarksToolbar"), ui->showBookmarksToolbar->isChecked());
0912     settings.setValue(QSL("showNavigationToolbar"), ui->showNavigationToolbar->isChecked());
0913     settings.endGroup();
0914 
0915     //TABS
0916     settings.beginGroup(QSL("Browser-Tabs-Settings"));
0917     settings.setValue(QSL("hideTabsWithOneTab"), ui->hideTabsOnTab->isChecked());
0918     settings.setValue(QSL("ActivateLastTabWhenClosingActual"), ui->activateLastTab->isChecked());
0919     settings.setValue(QSL("newTabAfterActive"), ui->openNewTabAfterActive->isChecked());
0920     settings.setValue(QSL("newEmptyTabAfterActive"), ui->openNewEmptyTabAfterActive->isChecked());
0921     settings.setValue(QSL("OpenPopupsInTabs"), ui->openPopupsInTabs->isChecked());
0922     settings.setValue(QSL("AlwaysSwitchTabsWithWheel"), ui->alwaysSwitchTabsWithWheel->isChecked());
0923     settings.setValue(QSL("OpenNewTabsSelected"), ui->switchToNewTabs->isChecked());
0924     settings.setValue(QSL("dontCloseWithOneTab"), ui->dontCloseOnLastTab->isChecked());
0925     settings.setValue(QSL("AskOnClosing"), ui->askWhenClosingMultipleTabs->isChecked());
0926     settings.setValue(QSL("showClosedTabsButton"), ui->showClosedTabsButton->isChecked());
0927     settings.setValue(QSL("showCloseOnInactiveTabs"), ui->showCloseOnInactive->currentIndex());
0928     settings.endGroup();
0929 
0930     //DOWNLOADS
0931     settings.beginGroup(QSL("DownloadManager"));
0932     if (ui->askEverytime->isChecked()) {
0933         settings.setValue(QSL("defaultDownloadPath"), QSL(""));
0934     }
0935     else {
0936         settings.setValue(QSL("defaultDownloadPath"), ui->downLoc->text());
0937     }
0938     settings.setValue(QSL("CloseManagerOnFinish"), ui->closeDownManOnFinish->isChecked());
0939     settings.setValue(QSL("UseExternalManager"), ui->useExternalDownManager->isChecked());
0940     settings.setValue(QSL("ExternalManagerExecutable"), ui->externalDownExecutable->text());
0941     settings.setValue(QSL("ExternalManagerArguments"), ui->externalDownArguments->text());
0942 
0943     settings.endGroup();
0944 
0945     //FONTS
0946     settings.beginGroup(QSL("Browser-Fonts"));
0947     settings.setValue(QSL("StandardFont"), ui->fontStandard->currentFont().family());
0948     settings.setValue(QSL("CursiveFont"), ui->fontCursive->currentFont().family());
0949     settings.setValue(QSL("FantasyFont"), ui->fontFantasy->currentFont().family());
0950     settings.setValue(QSL("FixedFont"), ui->fontFixed->currentFont().family());
0951     settings.setValue(QSL("SansSerifFont"), ui->fontSansSerif->currentFont().family());
0952     settings.setValue(QSL("SerifFont"), ui->fontSerif->currentFont().family());
0953 
0954     settings.setValue(QSL("DefaultFontSize"), ui->sizeDefault->value());
0955     settings.setValue(QSL("FixedFontSize"), ui->sizeFixed->value());
0956     settings.setValue(QSL("MinimumFontSize"), ui->sizeMinimum->value());
0957     settings.setValue(QSL("MinimumLogicalFontSize"), ui->sizeMinimumLogical->value());
0958     settings.endGroup();
0959 
0960     //KEYBOARD SHORTCUTS
0961     settings.beginGroup(QSL("Shortcuts"));
0962     settings.setValue(QSL("useTabNumberShortcuts"), ui->switchTabsAlt->isChecked());
0963     settings.setValue(QSL("useSpeedDialNumberShortcuts"), ui->loadSpeedDialsCtrl->isChecked());
0964     settings.setValue(QSL("useSingleKeyShortcuts"), ui->singleKeyShortcuts->isChecked());
0965     settings.endGroup();
0966 
0967     //BROWSING
0968     settings.beginGroup(QSL("Web-Browser-Settings"));
0969     settings.setValue(QSL("allowPlugins"), ui->allowPlugins->isChecked());
0970     settings.setValue(QSL("allowJavaScript"), ui->allowJavaScript->isChecked());
0971     settings.setValue(QSL("IncludeLinkInFocusChain"), ui->linksInFocusChain->isChecked());
0972     settings.setValue(QSL("SpatialNavigation"), ui->spatialNavigation->isChecked());
0973     settings.setValue(QSL("AnimateScrolling"), ui->animateScrolling->isChecked());
0974     settings.setValue(QSL("wheelScrollLines"), ui->wheelScroll->value());
0975     settings.setValue(QSL("DoNotTrack"), ui->doNotTrack->isChecked());
0976     settings.setValue(QSL("CheckUpdates"), ui->checkUpdates->isChecked());
0977     settings.setValue(QSL("LoadTabsOnActivation"), ui->dontLoadTabsUntilSelected->isChecked());
0978     settings.setValue(QSL("DefaultZoomLevel"), ui->defaultZoomLevel->currentIndex());
0979     settings.setValue(QSL("XSSAuditing"), ui->xssAuditing->isChecked());
0980     settings.setValue(QSL("PrintElementBackground"), ui->printEBackground->isChecked());
0981     settings.setValue(QSL("closeAppWithCtrlQ"), ui->closeAppWithCtrlQ->isChecked());
0982     settings.setValue(QSL("UseNativeScrollbars"), ui->useNativeScrollbars->isChecked());
0983     settings.setValue(QSL("DisableVideoAutoPlay"), ui->disableVideoAutoPlay->isChecked());
0984     settings.setValue(QSL("WebRTCPublicIpOnly"), ui->webRTCPublicIpOnly->isChecked());
0985     settings.setValue(QSL("DNSPrefetch"), ui->dnsPrefetch->isChecked());
0986     settings.setValue(QSL("intPDFViewer"), ui->intPDFViewer->isChecked());
0987     settings.setValue(QSL("screenCaptureEnabled"), ui->screenCaptureEnabled->isChecked());
0988     settings.setValue(QSL("hardwareAccel"), ui->hardwareAccel->isChecked());
0989 #ifdef Q_OS_WIN
0990     settings.setValue(QSL("CheckDefaultBrowser"), ui->checkDefaultBrowser->isChecked());
0991 #endif
0992     //Cache
0993     settings.setValue(QSL("AllowLocalCache"), ui->allowCache->isChecked());
0994     settings.setValue(QSL("deleteCacheOnClose"), ui->removeCache->isChecked());
0995     settings.setValue(QSL("LocalCacheSize"), ui->cacheMB->value());
0996     settings.setValue(QSL("CachePath"), ui->cachePath->text());
0997     //CSS Style
0998     settings.setValue(QSL("userStyleSheet"), ui->userStyleSheet->text());
0999 
1000     //PASSWORD MANAGER
1001     settings.setValue(QSL("SavePasswordsOnSites"), ui->allowPassManager->isChecked());
1002     settings.setValue(QSL("AutoCompletePasswords"), ui->autoCompletePasswords->isChecked());
1003 
1004     //PRIVACY
1005     //Web storage
1006     settings.setValue(QSL("allowHistory"), ui->saveHistory->isChecked());
1007     settings.setValue(QSL("deleteHistoryOnClose"), ui->deleteHistoryOnClose->isChecked());
1008     settings.setValue(QSL("HTML5StorageEnabled"), ui->html5storage->isChecked());
1009     settings.setValue(QSL("deleteHTML5StorageOnClose"), ui->deleteHtml5storageOnClose->isChecked());
1010     settings.endGroup();
1011 
1012     //NOTIFICATIONS
1013     settings.beginGroup(QSL("Notifications"));
1014     settings.setValue(QSL("Timeout"), ui->notificationTimeout->value() * 1000);
1015     settings.setValue(QSL("Enabled"), !ui->doNotUseNotifications->isChecked());
1016     settings.setValue(QSL("UseNativeDesktop"), ui->useNativeSystemNotifications->isChecked());
1017     settings.setValue(QSL("Position"), m_notification.data() ? m_notification.data()->pos() : m_notifPosition);
1018     settings.endGroup();
1019 
1020     //SPELLCHECK
1021     settings.beginGroup(QSL("SpellCheck"));
1022     settings.setValue(QSL("Enabled"), ui->spellcheckEnabled->isChecked());
1023     QStringList languages;
1024     for (int i = 0; i < ui->spellcheckLanguages->count(); ++i) {
1025         QListWidgetItem *item = ui->spellcheckLanguages->item(i);
1026         if (item->checkState() == Qt::Checked) {
1027             languages.append(item->data(Qt::UserRole).toString());
1028         }
1029     }
1030     settings.setValue(QSL("Languages"), languages);
1031     settings.endGroup();
1032 
1033     //OTHER
1034     //AddressBar
1035     settings.beginGroup(QSL("AddressBar"));
1036     settings.setValue(QSL("showSuggestions"), ui->addressbarCompletion->currentIndex());
1037     settings.setValue(QSL("useInlineCompletion"), ui->useInlineCompletion->isChecked());
1038     settings.setValue(QSL("alwaysShowGoIcon"), ui->alwaysShowGoIcon->isChecked());
1039     settings.setValue(QSL("showZoomLabel"), ui->showZoomLabel->isChecked());
1040     settings.setValue(QSL("showSwitchTab"), ui->completionShowSwitchTab->isChecked());
1041     settings.setValue(QSL("SelectAllTextOnDoubleClick"), ui->selectAllOnFocus->isChecked());
1042     settings.setValue(QSL("SelectAllTextOnClick"), ui->selectAllOnClick->isChecked());
1043     settings.setValue(QSL("CompletionPopupExpandToWindow"), ui->completionPopupExpandToWindow->isChecked());
1044     settings.setValue(QSL("ShowLoadingProgress"), ui->showLoadingInAddressBar->isChecked());
1045     settings.setValue(QSL("ProgressStyle"), ui->progressStyleSelector->currentIndex());
1046     settings.setValue(QSL("UseCustomProgressColor"), ui->checkBoxCustomProgressColor->isChecked());
1047     settings.setValue(QSL("CustomProgressColor"), ui->customColorToolButton->property("ProgressColor").value<QColor>());
1048     settings.endGroup();
1049 
1050     settings.beginGroup(QSL("SearchEngines"));
1051     settings.setValue(QSL("SearchFromAddressBar"), ui->searchFromAddressBar->isChecked());
1052     settings.setValue(QSL("SearchWithDefaultEngine"), ui->searchWithDefaultEngine->isChecked());
1053     settings.setValue(QSL("showSearchSuggestions"), ui->showABSearchSuggestions->isChecked());
1054     settings.endGroup();
1055 
1056     //Proxy Configuration
1057     int proxyType;
1058     if (ui->noProxy->isChecked()) {
1059         proxyType = 0;
1060     } else if (ui->systemProxy->isChecked()) {
1061         proxyType = 2;
1062     } else if (ui->proxyType->currentIndex() == 0) { // Http
1063         proxyType = 3;
1064     } else { // Socks5
1065         proxyType = 4;
1066     }
1067 
1068     settings.beginGroup(QSL("Web-Proxy"));
1069     settings.setValue(QSL("ProxyType"), proxyType);
1070     settings.setValue(QSL("HostName"), ui->proxyServer->text());
1071     settings.setValue(QSL("Port"), ui->proxyPort->text().toInt());
1072     settings.setValue(QSL("Username"), ui->proxyUsername->text());
1073     settings.setValue(QSL("Password"), ui->proxyPassword->text());
1074     settings.endGroup();
1075 
1076     ProfileManager::setStartingProfile(ui->startProfile->currentText());
1077 
1078     m_pluginsList->save();
1079     m_themesManager->save();
1080     mApp->cookieJar()->loadSettings();
1081     mApp->history()->loadSettings();
1082     mApp->reloadSettings();
1083     mApp->desktopNotifications()->loadSettings();
1084     mApp->autoFill()->loadSettings();
1085     mApp->networkManager()->loadSettings();
1086 
1087     WebScrollBarManager::instance()->loadSettings();
1088 }
1089 
1090 Preferences::~Preferences()
1091 {
1092     Settings().setValue(QSL("Preferences/Geometry"), saveGeometry());
1093 
1094     delete ui;
1095     delete m_autoFillManager;
1096     delete m_pluginsList;
1097     delete m_notification.data();
1098 }
1099 
1100 void Preferences::setProgressBarColorIcon(QColor color)
1101 {
1102     const int size = style()->pixelMetric(QStyle::PM_ToolBarIconSize);
1103     QPixmap pm(QSize(size, size));
1104     if (!color.isValid()) {
1105         color = palette().color(QPalette::Highlight);
1106     }
1107     pm.fill(color);
1108     ui->customColorToolButton->setIcon(pm);
1109     ui->customColorToolButton->setProperty("ProgressColor", color);
1110 }
1111 
1112 void Preferences::selectCustomProgressBarColor()
1113 {
1114     QColor newColor = QColorDialog::getColor(ui->customColorToolButton->property("ProgressColor").value<QColor>(), this, tr("Select Color"));
1115     if (newColor.isValid()) {
1116         setProgressBarColorIcon(newColor);
1117     }
1118 }