aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAqua-sama <aqua@iserlohn-fortress.net>2018-11-23 16:09:12 +0100
committerAqua-sama <aqua@iserlohn-fortress.net>2018-11-23 16:09:12 +0100
commitb25829645d15aa54caf9ea4f53de2489ea04f863 (patch)
tree4df8b715f4b4587a3b04061b4cf2ac8c50b1e375
parentUpdate About Dialog text (diff)
downloadsmolbote-b25829645d15aa54caf9ea4f53de2489ea04f863.tar.xz
Adding and Removing plugins at runtime
-rw-r--r--src/browser.cpp79
-rw-r--r--src/browser.h21
-rw-r--r--src/mainwindow/mainwindow.ui11
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>&amp;Bookmarks</string>
</property>
</action>
<action name="actionDownloads">
<property name="text">
- <string>Downloads</string>
+ <string>&amp;Downloads</string>
+ </property>
+ </action>
+ <action name="actionAddPlugin">
+ <property name="text">
+ <string>Add Plugin</string>
</property>
</action>
</widget>