From b25829645d15aa54caf9ea4f53de2489ea04f863 Mon Sep 17 00:00:00 2001 From: Aqua-sama Date: Fri, 23 Nov 2018 16:09:12 +0100 Subject: Adding and Removing plugins at runtime --- src/browser.cpp | 79 +++++++++++++++++++++++++++++++++----------- src/browser.h | 21 ++++++++++-- src/mainwindow/mainwindow.ui | 11 ++++-- 3 files changed, 88 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/browser.cpp b/src/browser.cpp index 4547e08..7130096 100644 --- a/src/browser.cpp +++ b/src/browser.cpp @@ -24,6 +24,7 @@ #include "webprofile.h" #include #include +#include #include #include #include @@ -47,6 +48,9 @@ Browser::~Browser() if(m_bookmarks) m_bookmarks->save(); + for(auto *info : m_plugins) + delete info; + qDeleteAll(m_windows); m_windows.clear(); } @@ -122,10 +126,30 @@ ProfileManager *Browser::getProfileManager() return m_profileManager; } +QPluginLoader *Browser::addPlugin(const QString &path) +{ + if(path.isEmpty()) + return nullptr; + + auto *loader = new QPluginLoader(path, this); + loader->load(); + + auto *info = new PluginInfo(loader); + m_plugins.append(info); + + for(MainWindow *window : m_windows) { + addPluginTo(info, window); + } + + return loader; +} + void Browser::setup(QVector plugins) { Q_ASSERT(m_config); - m_plugins = plugins; + for(QPluginLoader *loader : plugins) { + m_plugins.append(new PluginInfo(loader)); + } auto stylesheet = m_config->value("browser.stylesheet"); if(stylesheet) { @@ -242,25 +266,12 @@ MainWindow *Browser::createWindow() } }); - for(QPluginLoader *loader : qAsConst(m_plugins)) { - auto *pluginMenu = window->ui->menuTools->addMenu(loader->metaData().value("MetaData").toObject().value("name").toString()); - - auto *aboutAction = pluginMenu->addAction(tr("About")); - connect(aboutAction, &QAction::triggered, this, [loader, window]() { - auto *dlg = new AboutPluginDialog(loader, window); - dlg->exec(); - }); - - auto *runAction = pluginMenu->addAction(tr("Run")); - runAction->setShortcut(QKeySequence::fromString(loader->metaData().value("MetaData").toObject().value("shortcut").toString())); + connect(window->ui->actionAddPlugin, &QAction::triggered, this, [this]() { + this->addPlugin(QFileDialog::getOpenFileName(nullptr, tr("Add Plugin"), QDir::homePath(), tr("Plugins (*.so)"))); + }); - connect(runAction, &QAction::triggered, window, [loader, window]() { - if(loader->isLoaded()) { - const auto *interface = qobject_cast(loader->instance()); - Q_CHECK_PTR(interface); - interface->createWidget(window)->exec(); - } - }); + for(auto *info : m_plugins) { + addPluginTo(info, window); } m_windows.append(window); @@ -270,3 +281,33 @@ MainWindow *Browser::createWindow() return window; } + +void Browser::addPluginTo(PluginInfo *info, MainWindow *window) +{ + QPluginLoader *loader = info->loader; + auto *pluginMenu = window->ui->menuTools->addMenu(loader->metaData().value("MetaData").toObject().value("name").toString()); + info->menus.append(pluginMenu); + + auto *aboutAction = pluginMenu->addAction(tr("About")); + connect(aboutAction, &QAction::triggered, this, [loader, window]() { + auto *dlg = new AboutPluginDialog(loader, window); + dlg->exec(); + }); + + auto *runAction = pluginMenu->addAction(tr("Run")); + runAction->setShortcut(QKeySequence::fromString(loader->metaData().value("MetaData").toObject().value("shortcut").toString())); + + connect(runAction, &QAction::triggered, window, [loader, window]() { + if(loader->isLoaded()) { + const auto *interface = qobject_cast(loader->instance()); + Q_CHECK_PTR(interface); + interface->createWidget(window)->exec(); + } + }); + + auto *removeAction = pluginMenu->addAction(tr("Remove")); + connect(removeAction, &QAction::triggered, this, [this, info]() {; + m_plugins.removeOne(info); + delete info; + }); +} diff --git a/src/browser.h b/src/browser.h index e871202..2148484 100644 --- a/src/browser.h +++ b/src/browser.h @@ -16,6 +16,8 @@ #include #include #include +#include +#include class Configuration; class BookmarksWidget; @@ -23,7 +25,6 @@ class DownloadsWidget; class Filter; class MainWindow; class ProfileManager; -class QPluginLoader; class Browser : public SingleApplication, public BrowserInterface { Q_OBJECT @@ -47,6 +48,7 @@ public: QPair loadProfile(const QString &id, bool isOffTheRecord = true) override; void removeProfile(const QString &id) override; + QPluginLoader *addPlugin(const QString &path = QString()); void setConfiguration(std::unique_ptr &config); void setup(QVector plugins); @@ -61,6 +63,21 @@ public slots: MainWindow *createWindow(); private: + struct PluginInfo { + explicit PluginInfo(QPluginLoader *l) { + this->loader = l; + } + ~PluginInfo() { + loader->unload(); + for(auto *m : menus) + m->deleteLater(); + }; + + QPluginLoader *loader; + QVector menus; + }; + void addPluginTo(PluginInfo *info, MainWindow *window); + Q_DISABLE_COPY(Browser) std::unique_ptr m_config; @@ -70,7 +87,7 @@ private: std::unique_ptr m_urlFilter; QVector m_windows; - QVector m_plugins; + QVector m_plugins; }; #endif // SMOLBOTE_BROWSER_H diff --git a/src/mainwindow/mainwindow.ui b/src/mainwindow/mainwindow.ui index 587b4fd..309bfaf 100644 --- a/src/mainwindow/mainwindow.ui +++ b/src/mainwindow/mainwindow.ui @@ -58,6 +58,8 @@ + + @@ -154,12 +156,17 @@ - Bookmarks + &Bookmarks - Downloads + &Downloads + + + + + Add Plugin -- cgit v1.2.1