/* * This file is part of smolbote. It's copyrighted by the contributors recorded * in the version control history of the file, available from its original * location: https://neueland.iserlohn-fortress.net/gitea/aqua/smolbote * * SPDX-License-Identifier: GPL-3.0 */ #include "browser.h" #include "aboutdialog.h" #include "aboutplugin.h" #include "applicationmenu.h" #include "bookmarks/bookmarkswidget.h" #include "configuration.h" #include "downloadswidget.h" #include "mainwindow/addressbar.h" #include "mainwindow/mainwindow.h" #include "mainwindow/menubar.h" #include "smolbote/plugininterface.hpp" #include "subwindow/subwindow.h" #include "util.h" #include "webengine/webprofile.h" #include "webengine/webprofilemanager.h" #include "webengine/webview.h" #include #include #include #include #include #include #include #include #include Browser::Browser(int &argc, char *argv[], bool allowSecondary) : SingleApplication(argc, argv, allowSecondary, SingleApplication::User | SingleApplication::SecondaryNotification | SingleApplication::ExcludeAppVersion) { Configuration conf; setApplicationName(conf.value("poi.name").value()); setWindowIcon(QIcon(conf.value("poi.icon").value())); setApplicationVersion(QVersionNumber::fromString(QLatin1String(poi_Version)).toString()); if(const auto _translation = conf.value("browser.translation")) { auto *translator = new QTranslator(this); if(translator->load(_translation.value())) installTranslator(translator); else delete translator; } if(const auto _locale = conf.value("browser.locale")) { auto *locale = new QTranslator(this); if(locale->load("qt_" + _locale.value(), QLibraryInfo::location(QLibraryInfo::TranslationsPath))) installTranslator(locale); else delete locale; } if(auto iconTheme = conf.value("browser.iconTheme")) { QIcon::setThemeName(iconTheme.value()); } if(auto stylesheet = conf.value("browser.stylesheet")) { QFile f(stylesheet.value()); if(f.open(QIODevice::ReadOnly)) { setStyleSheet(f.readAll()); f.close(); } } // content filter - register format plugins if(const auto hostlist_plugin = conf.value("smolblok.plugins.hostlist")) { content_filter.registerFormatPlugin("hostlist", hostlist_plugin.value()); } if(const auto adblock_plugin = conf.value("smolblok.plugins.adblock")) { content_filter.registerFormatPlugin("adblock", adblock_plugin.value()); } // load profiles { const auto profiles = Util::files(conf.value("profile.path").value(), { "*.profile" }); const auto search = conf.value("profile.search").value(); const auto homepage = QUrl::fromUserInput(conf.value("profile.homepage").value()); const auto newtab = QUrl::fromUserInput(conf.value("profile.newtab").value()); const auto default_id = conf.value("profile.default").value(); m_profileManager = std::make_unique>(profiles, default_id, search, homepage, newtab); m_profileManager->make_global(); for(auto &id : m_profileManager->idList()) { spdlog::info("Added profile\t{}", qUtf8Printable(id)); } // set default profile auto *profile = m_profileManager->profile(default_id); spdlog::info("Default profile\t{}{}\t{}", qUtf8Printable(default_id), profile->isOffTheRecord() ? "*" : "", qUtf8Printable(profile->name())); } // downloads m_downloads = std::make_unique(conf.value("downloads.path").value()); m_profileManager->walk([this](const QString &, WebProfile *profile, QSettings *) { profile->setUrlRequestInterceptor(content_filter.interceptor()); connect(profile, &QWebEngineProfile::downloadRequested, m_downloads.get(), &DownloadsWidget::addDownload); }); // bookmarks m_bookmarks = std::make_shared(QString::fromStdString(conf.value("bookmarks.path").value())); connect(m_bookmarks.get(), &BookmarksWidget::openUrl, this, [this](const QUrl &url) { m_windows.last()->createTab(url); }); auto *timer = new QTimer(this); connect(timer, &QTimer::timeout, m_bookmarks.get(), &BookmarksWidget::save); timer->start(5 * 60 * 1000); // 5min * 60sec * 1000ms } Browser::~Browser() { if(m_bookmarks) m_bookmarks->save(); for(auto *info : qAsConst(m_plugins)) delete info; qDeleteAll(m_windows); m_windows.clear(); } void Browser::about() { auto *dlg = new AboutDialog; dlg->exec(); } void Browser::aboutPlugins() { auto *dlg = new AboutPluginDialog; for(auto *info : qAsConst(m_plugins)) { dlg->add(info->loader); } dlg->exec(); } bool Browser::loadPlugin(const QString &path) { if(path.isEmpty()) { return false; } Configuration conf; const auto state = PluginLoader::signature_state( conf.value("plugins.signature.ignored").value(), conf.value("plugins.signature.checked").value(), conf.value("plugins.signature.enforced").value()); auto *loader = new PluginLoader(path, state, this); const bool loaded = loader->load(); if(!loaded) { delete loader; return false; } auto *info = new PluginInfo(loader); m_plugins.append(info); emit pluginAdded(loader); return true; } void Browser::showWidget(QWidget *widget, MainWindow *where) const { bool wasVisible = widget->isVisible(); for(MainWindow *w : qAsConst(m_windows)) w->removeDockWidget(widget); if(!wasVisible) where->addDockWidget(Qt::RightDockWidgetArea, widget); } void Browser::open(const QVector &data, bool merge) { if(data.count() == 0 && merge) { m_windows.at(0)->createTab(QUrl()); } if(data.count() == 1 && m_windows.count() >= 1 && merge) { const auto windowData = data.at(0); auto *window = m_windows.at(0); if(windowData.subwindows.count() == 1) { const auto subwindowData = windowData.subwindows.at(0); for(const auto &tab : subwindowData.tabs) { window->createTab(tab); } } else { for(const auto &window_data : windowData.subwindows) { window->createSubWindow(window_data); } } return; } for(const auto &windowData : data) { auto *menu = new ApplicationMenu(this); connect(this, &Browser::pluginAdded, menu, &ApplicationMenu::addPlugin); for(auto *info : qAsConst(m_plugins)) { menu->addPlugin(info->loader); } auto *window = new MainWindow(windowData, menu); connect(window->addressBar, &AddressBar::complete, m_bookmarks.get(), &BookmarksWidget::search); m_windows.append(window); // the window will delete itself when it closes, so we don't need to delete it connect(window, &MainWindow::destroyed, this, [this, window]() { m_windows.removeOne(window); }); } }