diff options
author | Aqua-sama <aqua@iserlohn-fortress.net> | 2018-11-23 16:09:12 +0100 |
---|---|---|
committer | Aqua-sama <aqua@iserlohn-fortress.net> | 2018-11-23 16:09:12 +0100 |
commit | b25829645d15aa54caf9ea4f53de2489ea04f863 (patch) | |
tree | 4df8b715f4b4587a3b04061b4cf2ac8c50b1e375 | |
parent | Update About Dialog text (diff) | |
download | smolbote-b25829645d15aa54caf9ea4f53de2489ea04f863.tar.xz |
Adding and Removing plugins at runtime
-rw-r--r-- | src/browser.cpp | 79 | ||||
-rw-r--r-- | src/browser.h | 21 | ||||
-rw-r--r-- | src/mainwindow/mainwindow.ui | 11 |
3 files changed, 88 insertions, 23 deletions
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 <QAction> #include <QDir> +#include <QFileDialog> #include <QFileInfo> #include <QFileInfoList> #include <QJsonArray> @@ -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<QPluginLoader *> plugins) { Q_ASSERT(m_config); - m_plugins = plugins; + for(QPluginLoader *loader : plugins) { + m_plugins.append(new PluginInfo(loader)); + } auto stylesheet = m_config->value<QString>("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<PluginInterface *>(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<PluginInterface *>(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 <functional> #include <memory> #include <singleapplication.h> +#include <QMenu> +#include <QPluginLoader> 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<QString, Profile *> 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<Configuration> &config); void setup(QVector<QPluginLoader *> 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<QMenu *> menus; + }; + void addPluginTo(PluginInfo *info, MainWindow *window); + Q_DISABLE_COPY(Browser) std::unique_ptr<Configuration> m_config; @@ -70,7 +87,7 @@ private: std::unique_ptr<Filter> m_urlFilter; QVector<MainWindow *> m_windows; - QVector<QPluginLoader *> m_plugins; + QVector<PluginInfo*> 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 @@ <addaction name="actionBookmarks"/> <addaction name="actionDownloads"/> <addaction name="separator"/> + <addaction name="actionAddPlugin"/> + <addaction name="separator"/> </widget> <widget class="QMenu" name="menuPage"> <property name="title"> @@ -154,12 +156,17 @@ </action> <action name="actionBookmarks"> <property name="text"> - <string>Bookmarks</string> + <string>&Bookmarks</string> </property> </action> <action name="actionDownloads"> <property name="text"> - <string>Downloads</string> + <string>&Downloads</string> + </property> + </action> + <action name="actionAddPlugin"> + <property name="text"> + <string>Add Plugin</string> </property> </action> </widget> |