mirror of
https://invent.kde.org/network/falkon.git
synced 2024-12-19 10:16:34 +01:00
Edited build config to build libqupzilla and link to it afterwards.
- edited plugins system - proper plugin loading / unloading - edited plugins interface
This commit is contained in:
parent
d47927feff
commit
b6615f409f
3
.gitignore
vendored
3
.gitignore
vendored
@ -15,7 +15,8 @@ TestPlugin-build
|
||||
search_*
|
||||
src-*
|
||||
bin/qupzilla
|
||||
bin/plugins/libExamplePlugin.so
|
||||
*.so
|
||||
libqupzilla.*
|
||||
bin/core
|
||||
qupzilla.sh
|
||||
git_revision
|
||||
|
@ -11,5 +11,6 @@ lessThan(QT_VERSION, 4.7) {
|
||||
}
|
||||
|
||||
TEMPLATE = subdirs
|
||||
SUBDIRS = src
|
||||
SUBDIRS = src main
|
||||
build_plugins: SUBDIRS += plugins
|
||||
CONFIG += ordered
|
||||
|
16
defines.pri
16
defines.pri
@ -3,6 +3,7 @@ OBJECTS_DIR = $$PWD/build
|
||||
MOC_DIR = $$PWD/build
|
||||
RCC_DIR = $$PWD/build
|
||||
UI_DIR = $$PWD/build
|
||||
VERSION = 1.1.8
|
||||
|
||||
# Please read BUILD information #
|
||||
#DEFINES += NO_SYSTEM_DATAPATH
|
||||
@ -30,3 +31,18 @@ equals(d_use_webgl, "true") { DEFINES += USE_WEBGL }
|
||||
equals(d_w7api, "true") { DEFINES += W7API }
|
||||
equals(d_kde, "true") { DEFINES += KDE }
|
||||
equals(d_portable, "true") { DEFINES += PORTABLE_BUILD }
|
||||
|
||||
!mac:unix {
|
||||
d_prefix = $$(QUPZILLA_PREFIX)
|
||||
data_folder = /usr/share/qupzilla
|
||||
|
||||
!equals(d_prefix, "") {
|
||||
data_folder = "$$d_prefix"share/qupzilla
|
||||
}
|
||||
|
||||
DEFINES += USE_DATADIR=\\\"""$$data_folder/"\\\""
|
||||
|
||||
#Git revision
|
||||
rev = $$system(sh $$PWD/scripts/getrevision.sh)
|
||||
!equals(rev, ""): DEFINES += GIT_REVISION=\\\"""$$rev"\\\""
|
||||
}
|
||||
|
13
install.pri
13
install.pri
@ -12,6 +12,7 @@ mac {
|
||||
!mac:unix {
|
||||
d_prefix = $$(QUPZILLA_PREFIX)
|
||||
binary_folder = /usr/bin
|
||||
library_folder = /usr/lib
|
||||
data_folder = /usr/share/qupzilla
|
||||
launcher_folder = /usr/share/applications
|
||||
icon_folder = /usr/share/pixmaps
|
||||
@ -19,16 +20,18 @@ mac {
|
||||
|
||||
!equals(d_prefix, "") {
|
||||
binary_folder = "$$d_prefix"bin
|
||||
library_folder = "$$d_prefix"lib
|
||||
data_folder = "$$d_prefix"share/qupzilla
|
||||
launcher_folder = "$$d_prefix"share/applications
|
||||
icon_folder = "$$d_prefix"share/pixmaps
|
||||
hicolor_folder = "$$d_prefix"share/icons/hicolor
|
||||
}
|
||||
|
||||
DEFINES += USE_DATADIR=\\\"""$$data_folder/"\\\""
|
||||
|
||||
target.path = $$binary_folder
|
||||
|
||||
targetlib.files = $$PWD/bin/libqupzilla*
|
||||
targetlib.path = $$library_folder
|
||||
|
||||
target1.files += $$PWD/bin/locale
|
||||
target1.files += $$PWD/bin/themes
|
||||
target1.path = $$data_folder
|
||||
@ -57,10 +60,6 @@ mac {
|
||||
ico256.files = $$PWD/linux/hicolor/256x256/apps/qupzilla.png
|
||||
ico256.path = $$hicolor_folder/256x256/apps
|
||||
|
||||
INSTALLS += target target1 target2 target3
|
||||
INSTALLS += target targetlib target1 target2 target3
|
||||
INSTALLS += ico16 ico32 ico48 ico64 ico128 ico256
|
||||
|
||||
#Git revision
|
||||
rev = $$system(sh $$PWD/scripts/getrevision.sh)
|
||||
!equals(rev, ""): DEFINES += GIT_REVISION=\\\"""$$rev"\\\""
|
||||
}
|
||||
|
18
main/main.pro
Normal file
18
main/main.pro
Normal file
@ -0,0 +1,18 @@
|
||||
QT += core gui webkit sql network script
|
||||
unix: QT += dbus
|
||||
|
||||
TARGET = qupzilla
|
||||
TEMPLATE = app
|
||||
LIBS += -L../bin -lqupzilla
|
||||
|
||||
include(../install.pri)
|
||||
include(../defines.pri)
|
||||
include(../translations.pri)
|
||||
include(../src/3rdparty/qtsingleapplication.pri)
|
||||
|
||||
INCLUDEPATH += ../src/app
|
||||
SOURCES = ../src/main.cpp
|
||||
|
||||
unix:contains(DEFINES, "NO_SYSTEM_DATAPATH"): QMAKE_RPATHDIR += $$PWD/../bin
|
||||
|
||||
message(========== Building qupzilla binary ==========)
|
10
plugins.pri
10
plugins.pri
@ -26,9 +26,9 @@ TEMPLATE = lib
|
||||
CONFIG += plugin
|
||||
DESTDIR = $$PWD/bin/plugins
|
||||
|
||||
OBJECTS_DIR = $$TARGET-build
|
||||
MOC_DIR = $$TARGET-build
|
||||
RCC_DIR = $$TARGET-build
|
||||
UI_DIR = $$TARGET-build
|
||||
OBJECTS_DIR = build
|
||||
MOC_DIR = build
|
||||
RCC_DIR = build
|
||||
UI_DIR = build
|
||||
|
||||
LIBS += $$PWD/plugins/libqupzilla/libqupzilla.a
|
||||
LIBS += -L $$PWD/bin -lqupzilla
|
||||
|
@ -1,10 +1,37 @@
|
||||
#include "testplugin.h"
|
||||
#include "qupzilla.h"
|
||||
|
||||
void TestPlugin::init(QString sPath)
|
||||
PluginSpec TestPlugin::pluginSpec()
|
||||
{
|
||||
PluginSpec spec;
|
||||
spec.name = tr("Example Plugin");
|
||||
spec.info = tr("Example minimal plugin");
|
||||
spec.description = tr("Very simple minimal plugin example");
|
||||
spec.version = "0.0.1";
|
||||
spec.author = "David Rosca <nowrep@gmail.com>";
|
||||
spec.icon = QIcon(":qupzilla.png");
|
||||
spec.hasSettings = true;
|
||||
|
||||
return spec;
|
||||
}
|
||||
|
||||
void TestPlugin::init(const QString &sPath)
|
||||
{
|
||||
settingsPath = sPath;
|
||||
//This function is called right after plugin is loaded
|
||||
qDebug() << __FUNCTION__ << "called";
|
||||
|
||||
// This function is called right after plugin is loaded
|
||||
// it will be called even if we return false from testPlugin()
|
||||
// so it is recommended not to call any QupZilla function here
|
||||
|
||||
settingsPath = sPath;
|
||||
}
|
||||
|
||||
void TestPlugin::unload()
|
||||
{
|
||||
qDebug() << __FUNCTION__ << "called";
|
||||
|
||||
// This function will be called when unloading plugin
|
||||
// it will be also called if we return false from testPlugin()
|
||||
}
|
||||
|
||||
bool TestPlugin::testPlugin()
|
||||
@ -13,29 +40,34 @@ bool TestPlugin::testPlugin()
|
||||
//There should be some testing if plugin is loaded correctly
|
||||
//If this function returns false, plugin is automatically unloaded
|
||||
|
||||
return true;
|
||||
return (QupZilla::VERSION == "1.1.8");
|
||||
}
|
||||
|
||||
QTranslator* TestPlugin::getTranslator(QString locale)
|
||||
QTranslator* TestPlugin::getTranslator(const QString &locale)
|
||||
{
|
||||
QTranslator* translator = new QTranslator();
|
||||
translator->load(":/" + locale);
|
||||
return translator;
|
||||
}
|
||||
|
||||
void TestPlugin::showSettings()
|
||||
void TestPlugin::showSettings(QWidget *parent)
|
||||
{
|
||||
QWidget* widget = new QWidget();
|
||||
new QLabel("Example Plugin v0.0.1", widget);
|
||||
widget->resize(200, 200);
|
||||
widget->setAttribute(Qt::WA_DeleteOnClose);
|
||||
widget->setWindowModality(Qt::WindowModal); //As the preferences window is modal too
|
||||
widget->setWindowTitle("Example Plugin Settings");
|
||||
widget->setWindowIcon(pluginIcon());
|
||||
widget->show();
|
||||
QDialog* dialog = new QDialog(parent);
|
||||
QPushButton* b = new QPushButton("Example Plugin v0.0.1");
|
||||
|
||||
QHBoxLayout* l = new QHBoxLayout(dialog);
|
||||
l->addWidget(b);
|
||||
dialog->setLayout(l);
|
||||
|
||||
dialog->resize(200, 200);
|
||||
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||
dialog->setWindowTitle("Example Plugin Settings");
|
||||
dialog->setWindowIcon(QIcon(":/qupzilla.png"));
|
||||
|
||||
dialog->show();
|
||||
}
|
||||
|
||||
void TestPlugin::populateWebViewMenu(QMenu* menu, QWebView* view, QWebHitTestResult r)
|
||||
void TestPlugin::populateWebViewMenu(QMenu* menu, QWebView* view, const QWebHitTestResult &r)
|
||||
{
|
||||
Q_UNUSED(view)
|
||||
QString title;
|
||||
|
@ -5,8 +5,6 @@
|
||||
//This file is available to download at QupZilla website
|
||||
|
||||
#include "plugininterface.h"
|
||||
#include "historymodel.h"
|
||||
|
||||
|
||||
//For clean plugin directory, please build necessary files into
|
||||
//plugin in .qrc data files
|
||||
@ -15,6 +13,7 @@
|
||||
#include <QLabel>
|
||||
#include <QMessageBox>
|
||||
#include <QWebElement>
|
||||
#include <QHBoxLayout>
|
||||
|
||||
class TestPlugin : public QObject, public PluginInterface
|
||||
{
|
||||
@ -22,25 +21,22 @@ class TestPlugin : public QObject, public PluginInterface
|
||||
Q_INTERFACES(PluginInterface)
|
||||
|
||||
public:
|
||||
QString pluginName() { return tr("Example Plugin"); }
|
||||
QString pluginInfo() { return tr("Example minimal plugin"); }
|
||||
QString pluginDescription() { return tr("Very simple minimal plugin example"); }
|
||||
QString pluginVersion() { return "0.0.1"; }
|
||||
QString pluginAuthor() { return "David Rosca <nowrep@gmail.com>"; }
|
||||
void init(QString sPath);
|
||||
PluginSpec pluginSpec();
|
||||
|
||||
void init(const QString &sPath);
|
||||
void unload();
|
||||
bool testPlugin();
|
||||
|
||||
QTranslator* getTranslator(QString locale);
|
||||
QIcon pluginIcon() { return QIcon(":/qupzilla.png"); }
|
||||
bool hasSettings() { return true; }
|
||||
void showSettings();
|
||||
QTranslator* getTranslator(const QString &locale);
|
||||
void showSettings(QWidget* parent = 0);
|
||||
|
||||
void populateWebViewMenu(QMenu* menu, QWebView* view, QWebHitTestResult r);
|
||||
void populateWebViewMenu(QMenu* menu, QWebView* view, const QWebHitTestResult &r);
|
||||
void populateHelpMenu(QMenu* menu);
|
||||
void populateToolsMenu(QMenu* menu);
|
||||
|
||||
private slots:
|
||||
void actionSlot();
|
||||
|
||||
private:
|
||||
QString settingsPath;
|
||||
};
|
||||
|
@ -1,17 +0,0 @@
|
||||
include(../../src/3rdparty/qtsingleapplication.pri)
|
||||
include(../../defines.pri)
|
||||
include(../../install.pri)
|
||||
include(../../src/src.pri)
|
||||
|
||||
QT += core gui webkit sql network script
|
||||
unix:QT += dbus
|
||||
|
||||
TARGET = qupzilla
|
||||
TEMPLATE = lib
|
||||
CONFIG -= shared
|
||||
CONFIG += static
|
||||
|
||||
DESTDIR = $$PWD
|
||||
OBJECTS_DIR = $$PWD/build
|
||||
RESOURCES =
|
||||
win32|os2:RC_FILE =
|
@ -1,7 +1,2 @@
|
||||
TEMPLATE = subdirs
|
||||
|
||||
sub_lib.subdir = libqupzilla
|
||||
sub_testplugin.subdir = TestPlugin
|
||||
sub_testplugin.depends = sub_lib
|
||||
|
||||
SUBDIRS = sub_lib sub_testplugin
|
||||
SUBDIRS = TestPlugin
|
||||
|
@ -40,7 +40,6 @@ void sigpipe_handler(int s)
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
|
||||
Q_INIT_RESOURCE(data);
|
||||
Q_INIT_RESOURCE(icons);
|
||||
Q_INIT_RESOURCE(html);
|
||||
|
@ -328,16 +328,12 @@ QString QupZillaSchemeReply::configPage()
|
||||
QString("<dt>%1</dt><dd>%2<dd>").arg(tr("Platform"), qz_buildSystem()));
|
||||
|
||||
QString pluginsString;
|
||||
QStringList availablePlugins = mApp->plugins()->getAvailablePlugins();
|
||||
const QList<Plugins::Plugin> &availablePlugins = mApp->plugins()->getAvailablePlugins();
|
||||
|
||||
foreach(const QString & fileName, availablePlugins) {
|
||||
PluginInterface* plugin = mApp->plugins()->getPlugin(fileName);
|
||||
if (!plugin) {
|
||||
continue;
|
||||
}
|
||||
foreach(const Plugins::Plugin & plugin, availablePlugins) {
|
||||
PluginSpec spec = plugin.pluginSpec;
|
||||
pluginsString.append(QString("<tr><td>%1</td><td>%2</td><td>%3</td><td>%4</td></tr>").arg(
|
||||
plugin->pluginName(), plugin->pluginVersion(),
|
||||
Qt::escape(plugin->pluginAuthor()), plugin->pluginDescription()));
|
||||
spec.name, spec.version, Qt::escape(spec.author), spec.description));
|
||||
}
|
||||
|
||||
if (pluginsString.isEmpty()) {
|
||||
|
@ -26,29 +26,42 @@
|
||||
#include <QWebView>
|
||||
#include <QWebHitTestResult>
|
||||
|
||||
struct PluginSpec {
|
||||
QString name;
|
||||
QString info;
|
||||
QString description;
|
||||
QString author;
|
||||
QString version;
|
||||
QIcon icon;
|
||||
bool hasSettings;
|
||||
|
||||
bool operator==(const PluginSpec &other) {
|
||||
return (this->name == other.name &&
|
||||
this->info == other.info &&
|
||||
this->description == other.description &&
|
||||
this->author == other.author &&
|
||||
this->version == other.version);
|
||||
}
|
||||
};
|
||||
|
||||
class PluginInterface
|
||||
{
|
||||
public:
|
||||
//Plugin Necessary Init Functions
|
||||
//You have to reimplement those functions, otherwise QupZilla crash
|
||||
virtual ~PluginInterface() { }
|
||||
virtual QString pluginName() = 0;
|
||||
virtual QString pluginInfo() = 0;
|
||||
virtual QString pluginDescription() = 0;
|
||||
virtual QString pluginVersion() = 0;
|
||||
virtual QString pluginAuthor() = 0;
|
||||
virtual void init(QString settingsPath) = 0;
|
||||
virtual PluginSpec pluginSpec() = 0;
|
||||
|
||||
virtual void init(const QString &settingsPath) = 0;
|
||||
virtual void unload() = 0;
|
||||
virtual bool testPlugin() = 0;
|
||||
//End Plugin Necessary Init Functions
|
||||
|
||||
virtual QTranslator* getTranslator(QString locale) { Q_UNUSED(locale) return 0; }
|
||||
virtual QIcon pluginIcon() { return QIcon(); }
|
||||
virtual bool hasSettings() { return false; }
|
||||
virtual void showSettings() { }
|
||||
virtual ~PluginInterface() { }
|
||||
virtual QTranslator* getTranslator(const QString &locale) { Q_UNUSED(locale) return 0; }
|
||||
virtual void showSettings(QWidget* parent = 0) { Q_UNUSED(parent) }
|
||||
|
||||
virtual void populateToolsMenu(QMenu* menu) { Q_UNUSED(menu) }
|
||||
virtual void populateHelpMenu(QMenu* menu) { Q_UNUSED(menu) }
|
||||
virtual void populateWebViewMenu(QMenu* menu, QWebView* view, QWebHitTestResult r) { Q_UNUSED(menu) Q_UNUSED(view) Q_UNUSED(r) }
|
||||
virtual void populateWebViewMenu(QMenu* menu, QWebView* view, const QWebHitTestResult &r) { Q_UNUSED(menu) Q_UNUSED(view) Q_UNUSED(r) }
|
||||
|
||||
virtual void formSent(const QNetworkRequest &request, const QByteArray &outgoingData) { Q_UNUSED(request) Q_UNUSED(outgoingData)}
|
||||
virtual void pageLoaded(QWebView* view) { Q_UNUSED(view) }
|
||||
@ -57,7 +70,7 @@ public:
|
||||
{ Q_UNUSED(op) Q_UNUSED(request) Q_UNUSED(outgoingData) return 0; }
|
||||
};
|
||||
|
||||
Q_DECLARE_INTERFACE(PluginInterface, "Qupzilla.Browser.PluginInterface/1.0")
|
||||
Q_DECLARE_INTERFACE(PluginInterface, "QupZilla.Browser.PluginInterface/1.1")
|
||||
|
||||
|
||||
#endif // PLUGININTERFACE_H
|
||||
|
@ -30,14 +30,14 @@ PluginProxy::PluginProxy()
|
||||
|
||||
void PluginProxy::populateWebViewMenu(QMenu* menu, QWebView* view, QWebHitTestResult r)
|
||||
{
|
||||
if (!menu || !view || loadedPlugins.count() == 0) {
|
||||
if (!menu || !view || m_loadedPlugins.count() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
menu->addSeparator();
|
||||
int count = menu->actions().count();
|
||||
|
||||
foreach(PluginInterface * iPlugin, loadedPlugins)
|
||||
foreach(PluginInterface * iPlugin, m_loadedPlugins)
|
||||
iPlugin->populateWebViewMenu(menu, view, r);
|
||||
|
||||
if (menu->actions().count() == count) {
|
||||
@ -47,13 +47,13 @@ void PluginProxy::populateWebViewMenu(QMenu* menu, QWebView* view, QWebHitTestRe
|
||||
|
||||
void PluginProxy::populateToolsMenu(QMenu* menu)
|
||||
{
|
||||
if (!menu || loadedPlugins.count() == 0) {
|
||||
if (!menu || m_loadedPlugins.count() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
int count = menu->actions().count();
|
||||
|
||||
foreach(PluginInterface * iPlugin, loadedPlugins)
|
||||
foreach(PluginInterface * iPlugin, m_loadedPlugins)
|
||||
iPlugin->populateToolsMenu(menu);
|
||||
|
||||
if (menu->actions().count() != count) {
|
||||
@ -63,13 +63,13 @@ void PluginProxy::populateToolsMenu(QMenu* menu)
|
||||
|
||||
void PluginProxy::populateHelpMenu(QMenu* menu)
|
||||
{
|
||||
if (!menu || loadedPlugins.count() == 0) {
|
||||
if (!menu || m_loadedPlugins.count() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
int count = menu->actions().count();
|
||||
|
||||
foreach(PluginInterface * iPlugin, loadedPlugins)
|
||||
foreach(PluginInterface * iPlugin, m_loadedPlugins)
|
||||
iPlugin->populateHelpMenu(menu);
|
||||
|
||||
if (menu->actions().count() != count) {
|
||||
@ -80,7 +80,7 @@ void PluginProxy::populateHelpMenu(QMenu* menu)
|
||||
QNetworkReply* PluginProxy::createNetworkRequest(QNetworkAccessManager::Operation op, const QNetworkRequest &request, QIODevice* outgoingData)
|
||||
{
|
||||
QNetworkReply* reply = 0;
|
||||
foreach(PluginInterface * iPlugin, loadedPlugins) {
|
||||
foreach(PluginInterface * iPlugin, m_loadedPlugins) {
|
||||
reply = iPlugin->createNetworkRequest(op, request, outgoingData);
|
||||
if (reply) {
|
||||
break;
|
||||
|
@ -28,14 +28,48 @@
|
||||
|
||||
Plugins::Plugins(QObject* parent)
|
||||
: QObject(parent)
|
||||
, m_pluginsLoaded(false)
|
||||
{
|
||||
loadSettings();
|
||||
}
|
||||
|
||||
void Plugins::loadPlugin(Plugins::Plugin* plugin)
|
||||
{
|
||||
if (plugin->isLoaded()) {
|
||||
return;
|
||||
}
|
||||
|
||||
plugin->pluginLoader->setFileName(plugin->fullPath);
|
||||
PluginInterface* iPlugin = qobject_cast<PluginInterface*>(plugin->pluginLoader->instance());
|
||||
if (!iPlugin) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_availablePlugins.removeOne(*plugin);
|
||||
plugin->instance = initPlugin(iPlugin, plugin->pluginLoader);
|
||||
m_availablePlugins.append(*plugin);
|
||||
|
||||
refreshLoadedPlugins();
|
||||
}
|
||||
|
||||
void Plugins::unloadPlugin(Plugins::Plugin *plugin)
|
||||
{
|
||||
if (!plugin->isLoaded()) {
|
||||
return;
|
||||
}
|
||||
|
||||
plugin->instance->unload();
|
||||
plugin->pluginLoader->unload();
|
||||
|
||||
m_availablePlugins.removeOne(*plugin);
|
||||
plugin->instance = 0;
|
||||
m_availablePlugins.append(*plugin);
|
||||
|
||||
refreshLoadedPlugins();
|
||||
}
|
||||
|
||||
void Plugins::loadSettings()
|
||||
{
|
||||
m_allowedPluginFileNames.clear();
|
||||
|
||||
Settings settings;
|
||||
settings.beginGroup("Plugin-Settings");
|
||||
m_pluginsEnabled = settings.value("EnablePlugins", DEFAULT_ENABLE_PLUGINS).toBool();
|
||||
@ -45,55 +79,76 @@ void Plugins::loadSettings()
|
||||
|
||||
void Plugins::loadPlugins()
|
||||
{
|
||||
if (!m_pluginsEnabled) {
|
||||
if (!m_pluginsEnabled || m_pluginsLoaded) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_availablePluginFileNames.clear();
|
||||
loadedPlugins.clear();
|
||||
m_pluginsLoaded = true;
|
||||
|
||||
QDir pluginsDir = QDir(mApp->PLUGINSDIR);
|
||||
QStringList dirs;
|
||||
dirs << mApp->PLUGINSDIR
|
||||
#ifdef Q_WS_X11
|
||||
<< "/usr/lib/qupzilla/"
|
||||
#endif
|
||||
<< mApp->PROFILEDIR + "plugins/";
|
||||
|
||||
foreach(const QString & fileName, pluginsDir.entryList(QDir::Files)) {
|
||||
m_availablePluginFileNames.append(fileName);
|
||||
|
||||
if (!m_allowedPluginFileNames.contains(fileName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
QPluginLoader loader(pluginsDir.absoluteFilePath(fileName));
|
||||
QObject* plugin = loader.instance();
|
||||
if (plugin) {
|
||||
PluginInterface* iPlugin = qobject_cast<PluginInterface*>(plugin);
|
||||
iPlugin->init(mApp->getActiveProfilPath() + "plugins.ini");
|
||||
if (!iPlugin->testPlugin()) {
|
||||
loader.unload();
|
||||
foreach(const QString & dir, dirs) {
|
||||
QDir pluginsDir = QDir(dir);
|
||||
foreach(const QString & fileName, pluginsDir.entryList(QDir::Files)) {
|
||||
QPluginLoader* loader = new QPluginLoader(pluginsDir.absoluteFilePath(fileName));
|
||||
PluginInterface* iPlugin = qobject_cast<PluginInterface*>(loader->instance());
|
||||
if (!iPlugin) {
|
||||
continue;
|
||||
}
|
||||
|
||||
qApp->installTranslator(iPlugin->getTranslator(mApp->getActiveLanguage()));
|
||||
loadedPlugins.append(iPlugin);
|
||||
m_loadedPluginFileNames.append(fileName);
|
||||
Plugin plugin;
|
||||
plugin.fileName = fileName;
|
||||
plugin.fullPath = pluginsDir.absoluteFilePath(fileName);
|
||||
plugin.pluginSpec = iPlugin->pluginSpec();
|
||||
plugin.pluginLoader = loader;
|
||||
plugin.instance = 0;
|
||||
|
||||
if (m_allowedPluginFileNames.contains(fileName)) {
|
||||
plugin.instance = initPlugin(iPlugin, loader);
|
||||
}
|
||||
else {
|
||||
loader->unload();
|
||||
}
|
||||
|
||||
m_availablePlugins.append(plugin);
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << loadedPlugins.count() << " plugins loaded" << std::endl;
|
||||
refreshLoadedPlugins();
|
||||
|
||||
std::cout << m_loadedPlugins.count() << " plugins loaded" << std::endl;
|
||||
}
|
||||
|
||||
PluginInterface* Plugins::getPlugin(QString pluginFileName)
|
||||
PluginInterface* Plugins::initPlugin(PluginInterface* interface, QPluginLoader* loader)
|
||||
{
|
||||
QString path = mApp->PLUGINSDIR + pluginFileName;
|
||||
if (!QFile::exists(path)) {
|
||||
if (!interface) {
|
||||
return 0;
|
||||
}
|
||||
QPluginLoader loader(path);
|
||||
QObject* plugin = loader.instance();
|
||||
|
||||
if (plugin) {
|
||||
PluginInterface* iPlugin = qobject_cast<PluginInterface*>(plugin);
|
||||
return iPlugin;
|
||||
}
|
||||
else {
|
||||
interface->init(mApp->getActiveProfilPath() + "plugins.ini");
|
||||
|
||||
if (!interface->testPlugin()) {
|
||||
interface->unload();
|
||||
loader->unload();
|
||||
return 0;
|
||||
}
|
||||
|
||||
qApp->installTranslator(interface->getTranslator(mApp->getActiveLanguage()));
|
||||
return interface;
|
||||
}
|
||||
|
||||
void Plugins::refreshLoadedPlugins()
|
||||
{
|
||||
m_loadedPlugins.clear();
|
||||
|
||||
foreach(const Plugin &plugin, m_availablePlugins) {
|
||||
if (plugin.isLoaded()) {
|
||||
m_loadedPlugins.append(plugin.instance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,34 +22,59 @@
|
||||
#include <QtPlugin>
|
||||
#include <QPluginLoader>
|
||||
#include <QDir>
|
||||
#include <QWeakPointer>
|
||||
|
||||
#include <QTimer>
|
||||
#include <iostream>
|
||||
#include "plugininterface.h"
|
||||
|
||||
class PluginInterface;
|
||||
class Plugins : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
struct Plugin {
|
||||
QString fileName;
|
||||
QString fullPath;
|
||||
PluginSpec pluginSpec;
|
||||
QPluginLoader* pluginLoader;
|
||||
PluginInterface* instance;
|
||||
|
||||
bool isLoaded() const {
|
||||
return instance;
|
||||
}
|
||||
|
||||
bool operator==(const Plugin &other) {
|
||||
return (this->fileName == other.fileName &&
|
||||
this->fullPath == other.fullPath &&
|
||||
this->pluginSpec == other.pluginSpec &&
|
||||
this->instance == other.instance);
|
||||
}
|
||||
};
|
||||
|
||||
explicit Plugins(QObject* parent = 0);
|
||||
|
||||
QStringList getAvailablePlugins() { return m_availablePluginFileNames; }
|
||||
QStringList getAllowedPlugins() { return m_allowedPluginFileNames; }
|
||||
PluginInterface* getPlugin(QString pluginFileName);
|
||||
//void setPluginsAllowed(bool state) { pluginsEnabled = state; qDebug() << state;}
|
||||
QList<Plugin> getAvailablePlugins() { return m_availablePlugins; }
|
||||
|
||||
void loadPlugin(Plugin* plugin);
|
||||
void unloadPlugin(Plugin *plugin);
|
||||
|
||||
public slots:
|
||||
void loadSettings();
|
||||
void loadPlugins();
|
||||
|
||||
protected:
|
||||
QList<PluginInterface* > loadedPlugins;
|
||||
QList<PluginInterface*> m_loadedPlugins;
|
||||
|
||||
private:
|
||||
QStringList m_availablePluginFileNames;
|
||||
PluginInterface* initPlugin(PluginInterface* interface, QPluginLoader* loader);
|
||||
void refreshLoadedPlugins();
|
||||
|
||||
QList<Plugin> m_availablePlugins;
|
||||
QStringList m_allowedPluginFileNames;
|
||||
QStringList m_loadedPluginFileNames;
|
||||
|
||||
bool m_pluginsEnabled;
|
||||
bool m_pluginsLoaded;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(Plugins::Plugin)
|
||||
|
||||
#endif // PLUGINLOADER_H
|
||||
|
@ -35,18 +35,17 @@ PluginsList::PluginsList(QWidget* parent)
|
||||
ui->setupUi(this);
|
||||
|
||||
//Application Extensions
|
||||
refresh();
|
||||
connect(ui->butSettings, SIGNAL(clicked()), this, SLOT(settingsClicked()));
|
||||
connect(ui->list, SIGNAL(currentItemChanged(QListWidgetItem*, QListWidgetItem*)), this, SLOT(currentChanged(QListWidgetItem*)));
|
||||
connect(ui->butLoad, SIGNAL(clicked()), this, SLOT(reloadPlugins()));
|
||||
connect(ui->allowAppPlugins, SIGNAL(clicked(bool)), this, SLOT(allowAppPluginsChanged(bool)));
|
||||
|
||||
Settings settings;
|
||||
settings.beginGroup("Plugin-Settings");
|
||||
ui->allowAppPlugins->setChecked(settings.value("EnablePlugins", DEFAULT_ENABLE_PLUGINS).toBool());
|
||||
settings.endGroup();
|
||||
allowAppPluginsChanged(ui->allowAppPlugins->isChecked());
|
||||
|
||||
connect(ui->butSettings, SIGNAL(clicked()), this, SLOT(settingsClicked()));
|
||||
connect(ui->list, SIGNAL(currentItemChanged(QListWidgetItem*, QListWidgetItem*)), this, SLOT(currentChanged(QListWidgetItem*)));
|
||||
connect(ui->list, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(itemChanged(QListWidgetItem*)));
|
||||
connect(ui->allowAppPlugins, SIGNAL(clicked(bool)), this, SLOT(allowAppPluginsChanged(bool)));
|
||||
|
||||
//WebKit Plugins
|
||||
connect(ui->add, SIGNAL(clicked()), this, SLOT(addWhitelist()));
|
||||
connect(ui->remove, SIGNAL(clicked()), this, SLOT(removeWhitelist()));
|
||||
@ -60,6 +59,7 @@ PluginsList::PluginsList(QWidget* parent)
|
||||
QTreeWidgetItem* item = new QTreeWidgetItem(ui->whitelist);
|
||||
item->setText(0, site);
|
||||
}
|
||||
|
||||
allowC2FChanged(ui->allowClick2Flash->isChecked());
|
||||
}
|
||||
|
||||
@ -87,12 +87,22 @@ void PluginsList::removeWhitelist()
|
||||
|
||||
void PluginsList::save()
|
||||
{
|
||||
QStringList allowedPlugins;
|
||||
for (int i = 0; i < ui->list->count(); i++) {
|
||||
QListWidgetItem* item = ui->list->item(i);
|
||||
|
||||
if (item->checkState() == Qt::Checked) {
|
||||
const Plugins::Plugin &plugin = item->data(Qt::UserRole + 10).value<Plugins::Plugin>();
|
||||
|
||||
allowedPlugins.append(plugin.fileName);
|
||||
}
|
||||
}
|
||||
|
||||
Settings settings;
|
||||
settings.beginGroup("Plugin-Settings");
|
||||
settings.setValue("EnablePlugins", ui->allowAppPlugins->isChecked());
|
||||
settings.setValue("AllowedPlugins", allowedPlugins);
|
||||
settings.endGroup();
|
||||
|
||||
reloadPlugins();
|
||||
}
|
||||
|
||||
void PluginsList::allowAppPluginsChanged(bool state)
|
||||
@ -102,7 +112,14 @@ void PluginsList::allowAppPluginsChanged(bool state)
|
||||
settings.setValue("EnablePlugins", state);
|
||||
settings.endGroup();
|
||||
|
||||
ui->verticalFrame->setEnabled(state);
|
||||
mApp->plugins()->loadSettings();
|
||||
mApp->plugins()->loadPlugins();
|
||||
|
||||
ui->list->setEnabled(state);
|
||||
|
||||
if (state) {
|
||||
refresh();
|
||||
}
|
||||
}
|
||||
|
||||
void PluginsList::allowC2FChanged(bool state)
|
||||
@ -123,32 +140,31 @@ void PluginsList::refresh()
|
||||
{
|
||||
ui->list->clear();
|
||||
ui->butSettings->setEnabled(false);
|
||||
disconnect(ui->list, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(itemChanged(QListWidgetItem*)));
|
||||
|
||||
QStringList availablePlugins = mApp->plugins()->getAvailablePlugins();
|
||||
QStringList allowedPlugins = mApp->plugins()->getAllowedPlugins();
|
||||
foreach(const QString & fileName, availablePlugins) {
|
||||
PluginInterface* plugin = mApp->plugins()->getPlugin(fileName);
|
||||
if (!plugin) {
|
||||
continue;
|
||||
}
|
||||
const QList<Plugins::Plugin> &allPlugins = mApp->plugins()->getAvailablePlugins();
|
||||
|
||||
foreach(const Plugins::Plugin & plugin, allPlugins) {
|
||||
PluginSpec spec = plugin.pluginSpec;
|
||||
|
||||
QListWidgetItem* item = new QListWidgetItem(ui->list);
|
||||
item->setText("" + plugin->pluginName() + " (" + plugin->pluginVersion() + ") by " + plugin->pluginAuthor() + "\n"
|
||||
+ plugin->pluginInfo() + "\n" + plugin->pluginDescription());
|
||||
QString pluginInfo = tr("%1 (%2)\nAuthor: %3\n%4\n%5").arg(spec.name, spec.version, spec.author, spec.info, spec.description);
|
||||
item->setText(pluginInfo);
|
||||
|
||||
QIcon icon = plugin->pluginIcon();
|
||||
QIcon icon = spec.icon;
|
||||
if (icon.isNull()) {
|
||||
icon = QIcon(":/icons/preferences/extension.png");
|
||||
}
|
||||
item->setIcon(icon);
|
||||
|
||||
item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
|
||||
item->setCheckState((allowedPlugins.contains(fileName)) ? Qt::Checked : Qt::Unchecked);
|
||||
item->setWhatsThis(plugin->hasSettings() ? "1" : "0");
|
||||
item->setToolTip(fileName);
|
||||
item->setCheckState(plugin.isLoaded() ? Qt::Checked : Qt::Unchecked);
|
||||
item->setData(Qt::UserRole + 10, qVariantFromValue(plugin));
|
||||
|
||||
ui->list->addItem(item);
|
||||
}
|
||||
|
||||
connect(ui->list, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(itemChanged(QListWidgetItem*)));
|
||||
}
|
||||
|
||||
void PluginsList::currentChanged(QListWidgetItem* item)
|
||||
@ -157,50 +173,64 @@ void PluginsList::currentChanged(QListWidgetItem* item)
|
||||
return;
|
||||
}
|
||||
|
||||
QString has = item->whatsThis();
|
||||
bool show;
|
||||
if (has == "1") {
|
||||
show = true;
|
||||
const Plugins::Plugin &plugin = item->data(Qt::UserRole + 10).value<Plugins::Plugin>();
|
||||
bool showSettings = plugin.pluginSpec.hasSettings;
|
||||
|
||||
if (!plugin.isLoaded()) {
|
||||
showSettings = false;
|
||||
}
|
||||
|
||||
ui->butSettings->setEnabled(showSettings);
|
||||
}
|
||||
|
||||
void PluginsList::itemChanged(QListWidgetItem *item)
|
||||
{
|
||||
if (!item) {
|
||||
return;
|
||||
}
|
||||
|
||||
Plugins::Plugin plugin = item->data(Qt::UserRole + 10).value<Plugins::Plugin>();
|
||||
|
||||
if (item->checkState() == Qt::Checked) {
|
||||
mApp->plugins()->loadPlugin(&plugin);
|
||||
}
|
||||
else {
|
||||
show = false;
|
||||
mApp->plugins()->unloadPlugin(&plugin);
|
||||
}
|
||||
|
||||
if (item->checkState() == Qt::Unchecked) {
|
||||
show = false;
|
||||
disconnect(ui->list, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(itemChanged(QListWidgetItem*)));
|
||||
|
||||
if (item->checkState() == Qt::Checked && !plugin.isLoaded()) {
|
||||
item->setCheckState(Qt::Unchecked);
|
||||
QMessageBox::critical(this, tr("Error!"), tr("Cannot load plugin!"));
|
||||
}
|
||||
|
||||
ui->butSettings->setEnabled(show);
|
||||
item->setData(Qt::UserRole + 10, qVariantFromValue(plugin));
|
||||
|
||||
connect(ui->list, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(itemChanged(QListWidgetItem*)));
|
||||
|
||||
|
||||
currentChanged(ui->list->currentItem());
|
||||
}
|
||||
|
||||
void PluginsList::settingsClicked()
|
||||
{
|
||||
if (!ui->list->currentItem()) {
|
||||
QListWidgetItem* item = ui->list->currentItem();
|
||||
if (!item) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString name = ui->list->currentItem()->toolTip();
|
||||
PluginInterface* plugin = mApp->plugins()->getPlugin(name);
|
||||
plugin->showSettings();
|
||||
}
|
||||
Plugins::Plugin plugin = item->data(Qt::UserRole + 10).value<Plugins::Plugin>();
|
||||
|
||||
void PluginsList::reloadPlugins()
|
||||
{
|
||||
QStringList allowedPlugins;
|
||||
for (int i = 0; i < ui->list->count(); i++) {
|
||||
if (ui->list->item(i)->checkState() == Qt::Checked) {
|
||||
allowedPlugins.append(ui->list->item(i)->toolTip());
|
||||
}
|
||||
if (!plugin.isLoaded()) {
|
||||
mApp->plugins()->loadPlugin(&plugin);
|
||||
|
||||
item->setData(Qt::UserRole + 10, qVariantFromValue(plugin));
|
||||
}
|
||||
Settings settings;
|
||||
settings.beginGroup("Plugin-Settings");
|
||||
settings.setValue("AllowedPlugins", allowedPlugins);
|
||||
settings.endGroup();
|
||||
|
||||
mApp->plugins()->loadSettings();
|
||||
mApp->plugins()->loadPlugins();
|
||||
|
||||
refresh();
|
||||
if (plugin.isLoaded()) {
|
||||
plugin.instance->showSettings(this);
|
||||
}
|
||||
}
|
||||
|
||||
PluginsList::~PluginsList()
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <QWidget>
|
||||
#include <QListWidgetItem>
|
||||
#include <QInputDialog>
|
||||
#include <QMessageBox>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
@ -36,14 +37,13 @@ public:
|
||||
~PluginsList();
|
||||
void save();
|
||||
|
||||
public slots:
|
||||
void reloadPlugins();
|
||||
|
||||
private slots:
|
||||
//App extension
|
||||
void settingsClicked();
|
||||
void currentChanged(QListWidgetItem* item);
|
||||
void itemChanged(QListWidgetItem* item);
|
||||
void allowAppPluginsChanged(bool state);
|
||||
|
||||
//WebKit plugins
|
||||
void addWhitelist();
|
||||
void removeWhitelist();
|
||||
@ -51,6 +51,7 @@ private slots:
|
||||
|
||||
private:
|
||||
void refresh();
|
||||
|
||||
Ui::PluginsList* ui;
|
||||
};
|
||||
|
||||
|
@ -79,23 +79,6 @@
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="butLoad">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Load Plugins</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../data/icons.qrc">
|
||||
<normaloff>:/icons/faenza/reload.png</normaloff>:/icons/faenza/reload.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
|
@ -1,13 +1,14 @@
|
||||
QT += core gui webkit sql network script
|
||||
unix:QT += dbus
|
||||
TARGET = qupzilla
|
||||
TEMPLATE = app
|
||||
TEMPLATE = lib
|
||||
|
||||
include(3rdparty/qtsingleapplication.pri)
|
||||
include(src.pri)
|
||||
include(../install.pri)
|
||||
include(../defines.pri)
|
||||
include(../translations.pri)
|
||||
|
||||
message(Using following defines)
|
||||
SOURCES -= main.cpp
|
||||
|
||||
message(========== Building libqupzilla ==========)
|
||||
message( Using following defines:)
|
||||
message($$DEFINES)
|
||||
|
Loading…
Reference in New Issue
Block a user