1
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:
nowrep 2012-02-19 16:01:51 +01:00
parent d47927feff
commit b6615f409f
20 changed files with 356 additions and 212 deletions

3
.gitignore vendored
View File

@ -15,7 +15,8 @@ TestPlugin-build
search_*
src-*
bin/qupzilla
bin/plugins/libExamplePlugin.so
*.so
libqupzilla.*
bin/core
qupzilla.sh
git_revision

View File

@ -11,5 +11,6 @@ lessThan(QT_VERSION, 4.7) {
}
TEMPLATE = subdirs
SUBDIRS = src
SUBDIRS = src main
build_plugins: SUBDIRS += plugins
CONFIG += ordered

View File

@ -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"\\\""
}

View File

@ -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
View 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 ==========)

View File

@ -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

View File

@ -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;

View File

@ -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;
};

View File

@ -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 =

View 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

View File

@ -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);

View File

@ -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()) {

View File

@ -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

View File

@ -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;

View File

@ -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);
}
}
}

View File

@ -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

View File

@ -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()

View File

@ -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;
};

View File

@ -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>

View File

@ -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)