/* * 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: git://neueland.iserlohn-fortress.net/smolbote.git * * SPDX-License-Identifier: GPL-3.0 */ #include "browser.h" #include "mainwindow.h" #include "webengine/urlinterceptor.h" #include #include #include Browser::Browser(int &argc, char *argv[]) : SingleApplication(argc, argv) { QApplication::setApplicationName("smolbote"); QApplication::setWindowIcon(QIcon(":/icon.svg")); connect(this, &Browser::messageAvailable, this, &Browser::createSession); } Browser::~Browser() { if(m_config) { //QtConcurrent::run(QThreadPool::globalInstance(), m_config.get(), &Configuration::writeIfNeeded); QtConcurrent::run([c = m_config.get()]() { qDebug("Writing configuration: %s", c->writeIfNeeded() ? "ok" : "failed"); }); } if(m_bookmarksManager) { QtConcurrent::run(QThreadPool::globalInstance(), m_bookmarksManager.get(), &BookmarksWidget::save); } qDebug("Waiting for threads to wind down..."); qDebug("Thread pool is done: %s", QThreadPool::globalInstance()->waitForDone() ? "okay" : "failed"); } void Browser::setConfiguration(std::shared_ptr &config) { m_config = config; QDir pluginsDir(QString::fromStdString(m_config->value("plugins.path").value())); if(pluginsDir.exists()) { const QStringList entries = pluginsDir.entryList(QDir::Files | QDir::Readable); for (const QString &name : entries) { QPluginLoader loader(pluginsDir.absoluteFilePath(name)); qDebug("Loading plugin %s: %s", qUtf8Printable(name), loader.load() ? "ok" : "failed"); if (!loader.isLoaded()) { qDebug("Error: %s", qUtf8Printable(loader.errorString())); } else { Plugin d; d.meta = loader.metaData()["MetaData"].toObject(); d.pointer = loader.instance(); d.pointer->setParent(this); m_plugins.append(d); } } } m_bookmarksManager = std::make_shared(QString::fromStdString(m_config->value("bookmarks.path").value())); m_downloadManager = std::make_shared(QString::fromStdString(m_config->value("downloads.path").value())); m_urlRequestInterceptor = std::make_shared(QString::fromStdString(m_config->value("filter.path").value())); m_cookieInterceptor = std::make_shared(""); // set default profile m_defaultProfile = profile(QString::fromStdString(m_config->value("browser.profile").value())); } MainWindow *Browser::createWindow() { // the window will delete itself when it closes, so we don't need to delete it MainWindow *window = new MainWindow(m_config); window->setBookmarksWidget(m_bookmarksManager); window->setDownloadsWidget(m_downloadManager); window->setProfile(m_defaultProfile); window->addPlugins(m_plugins); m_windows.append(window); // has to be window.get(), but can't be *window connect(window, &MainWindow::destroyed, this, [this, window]() { m_windows.removeOne(window); }); window->show(); return window; } MainWindow *Browser::createSession(const QString &profileName, bool newWindow, const QStringList &urls) { MainWindow *window = nullptr; // if we need to open in a new window, or there are no windows, make one if(newWindow || m_windows.isEmpty()) { window = createWindow(); window->setProfile(profile(profileName)); } else { // reverse-iterate through windows to check for window with the same profile for(auto it = m_windows.rbegin(); it != m_windows.rend(); ++it) { if((*it)->profile()->storageName() == profileName) { window = *it; break; } } // if none is found, create one if(window == nullptr) { window = createWindow(); window->setProfile(profile(profileName)); } } Q_CHECK_PTR(window); if(urls.isEmpty()) { // no URLs were given window->newTab(QUrl::fromUserInput(m_config->value("profile.homepage").value().c_str())); } else { for(const QString &url : urls) { window->newTab(QUrl::fromUserInput(url)); } } return window; } std::shared_ptr Browser::profile(const QString storageName) { if(m_profiles.contains(storageName)) { return m_profiles[storageName]; } // profile with name storageName has not been loaded Q_ASSERT(m_config); const QString &path = QString::fromStdString(m_config->value("profile.path").value()); std::shared_ptr _profile = std::shared_ptr(createProfile(storageName, path, nullptr)); _profile->setRequestInterceptor(m_urlRequestInterceptor.get()); _profile->setCookieInterceptor(m_cookieInterceptor.get()); connect(_profile.get(), &WebEngineProfile::downloadRequested, m_downloadManager.get(), &DownloadsWidget::addDownload); m_profiles.insert(storageName, _profile); return _profile; }