mirror of
https://invent.kde.org/network/falkon.git
synced 2024-11-11 01:22:10 +01:00
added support to load/unload QML plugins
Following methods are exposed to qml 1) init 2) unload 3) testPlugin. Also logic to load QML plugins is implemented.
This commit is contained in:
parent
3760a9ffd1
commit
30cc7a8b89
|
@ -154,6 +154,8 @@ set(SRCS ${SRCS}
|
|||
plugins/pluginproxy.cpp
|
||||
plugins/plugins.cpp
|
||||
plugins/speeddial.cpp
|
||||
plugins/qml/qmlplugins.cpp
|
||||
plugins/qml/qmlplugininterface.cpp
|
||||
popupwindow/popuplocationbar.cpp
|
||||
popupwindow/popupstatusbarmessage.cpp
|
||||
popupwindow/popupwebview.cpp
|
||||
|
|
|
@ -24,10 +24,13 @@
|
|||
#include "adblock/adblockplugin.h"
|
||||
#include "../config.h"
|
||||
#include "desktopfile.h"
|
||||
#include "qml/qmlplugins.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <QPluginLoader>
|
||||
#include <QDir>
|
||||
#include <QQmlEngine>
|
||||
#include <QQmlComponent>
|
||||
|
||||
Plugins::Plugins(QObject* parent)
|
||||
: QObject(parent)
|
||||
|
@ -39,6 +42,8 @@ Plugins::Plugins(QObject* parent)
|
|||
if (!MainApplication::isTestModeEnabled()) {
|
||||
loadPythonSupport();
|
||||
}
|
||||
|
||||
loadQmlSupport();
|
||||
}
|
||||
|
||||
QList<Plugins::Plugin> Plugins::getAvailablePlugins()
|
||||
|
@ -113,6 +118,7 @@ PluginSpec Plugins::createSpec(const DesktopFile &metaData)
|
|||
spec.description = metaData.comment();
|
||||
spec.version = metaData.value(QSL("X-Falkon-Version")).toString();
|
||||
spec.author = QSL("%1 <%2>").arg(metaData.value(QSL("X-Falkon-Author")).toString(), metaData.value(QSL("X-Falkon-Email")).toString());
|
||||
spec.entryPoint = metaData.value(QSL("X-Falkon-EntryPoint")).toString();
|
||||
spec.hasSettings = metaData.value(QSL("X-Falkon-Settings")).toBool();
|
||||
|
||||
const QString iconName = metaData.icon();
|
||||
|
@ -204,6 +210,24 @@ void Plugins::loadAvailablePlugins()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// QmlPlugin
|
||||
for (QString dir: dirs) {
|
||||
// qml plugins will be loaded from subdirectory qml
|
||||
dir.append(QSL("/qml"));
|
||||
const auto qmlDirs = QDir(dir).entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
|
||||
for (const QFileInfo &info : qmlDirs) {
|
||||
Plugin plugin = loadQmlPlugin(info.absoluteFilePath());
|
||||
if (plugin.type == Plugin::Invalid) {
|
||||
continue;
|
||||
}
|
||||
if (plugin.pluginSpec.name.isEmpty()) {
|
||||
qWarning() << "Invalid plugin spec of" << info.absoluteFilePath() << "plugin";
|
||||
continue;
|
||||
}
|
||||
registerAvailablePlugin(plugin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Plugins::registerAvailablePlugin(const Plugin &plugin)
|
||||
|
@ -244,6 +268,11 @@ void Plugins::loadPythonSupport()
|
|||
}
|
||||
}
|
||||
|
||||
void Plugins::loadQmlSupport()
|
||||
{
|
||||
QmlPlugins::registerQmlTypes();
|
||||
}
|
||||
|
||||
Plugins::Plugin Plugins::loadPlugin(const QString &id)
|
||||
{
|
||||
QString name;
|
||||
|
@ -258,6 +287,8 @@ Plugins::Plugin Plugins::loadPlugin(const QString &id)
|
|||
type = Plugin::SharedLibraryPlugin;
|
||||
} else if (t == QL1S("python")) {
|
||||
type = Plugin::PythonPlugin;
|
||||
} else if (t == QL1S("qml")) {
|
||||
type = Plugin::QmlPlugin;
|
||||
}
|
||||
name = id.mid(colon + 1);
|
||||
} else {
|
||||
|
@ -275,6 +306,9 @@ Plugins::Plugin Plugins::loadPlugin(const QString &id)
|
|||
case Plugin::PythonPlugin:
|
||||
return loadPythonPlugin(name);
|
||||
|
||||
case Plugin::QmlPlugin:
|
||||
return loadQmlPlugin(name);
|
||||
|
||||
default:
|
||||
return Plugin();
|
||||
}
|
||||
|
@ -340,6 +374,36 @@ Plugins::Plugin Plugins::loadPythonPlugin(const QString &name)
|
|||
return f(name);
|
||||
}
|
||||
|
||||
Plugins::Plugin Plugins::loadQmlPlugin(const QString &name)
|
||||
{
|
||||
QString fullPath;
|
||||
if (QFileInfo(name).isAbsolute()) {
|
||||
fullPath = name;
|
||||
} else {
|
||||
fullPath = DataPaths::locate(DataPaths::Plugins, QSL("qml/") + name);
|
||||
if (fullPath.isEmpty()) {
|
||||
qWarning() << "Plugin" << name << "not found";
|
||||
return Plugin();
|
||||
}
|
||||
}
|
||||
|
||||
Plugin plugin;
|
||||
plugin.type = Plugin::QmlPlugin;
|
||||
plugin.pluginId = QSL("qml:%1").arg(QFileInfo(name).fileName());
|
||||
plugin.pluginSpec = createSpec(DesktopFile(fullPath + QSL("/metadata.desktop")));
|
||||
|
||||
QQmlEngine* engine = new QQmlEngine();
|
||||
QQmlComponent component(engine, QDir(fullPath).filePath(plugin.pluginSpec.entryPoint));
|
||||
plugin.qmlComponentInstance = qobject_cast<QmlPluginInterface*>(component.create());
|
||||
|
||||
if (!plugin.qmlComponentInstance) {
|
||||
qWarning() << "Loading" << fullPath << "failed:" << component.errorString();
|
||||
return Plugin();
|
||||
}
|
||||
|
||||
return plugin;
|
||||
}
|
||||
|
||||
bool Plugins::initPlugin(PluginInterface::InitState state, Plugin *plugin)
|
||||
{
|
||||
if (!plugin) {
|
||||
|
@ -359,6 +423,10 @@ bool Plugins::initPlugin(PluginInterface::InitState state, Plugin *plugin)
|
|||
initPythonPlugin(plugin);
|
||||
break;
|
||||
|
||||
case Plugin::QmlPlugin:
|
||||
initQmlPlugin(plugin);
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
@ -409,3 +477,11 @@ void Plugins::initPythonPlugin(Plugin *plugin)
|
|||
|
||||
f(plugin);
|
||||
}
|
||||
|
||||
void Plugins::initQmlPlugin(Plugin *plugin)
|
||||
{
|
||||
Q_ASSERT(plugin->type == Plugin::QmlPlugin);
|
||||
|
||||
plugin->qmlComponentInstance->setName(plugin->pluginSpec.name);
|
||||
plugin->instance = qobject_cast<PluginInterface*>(plugin->qmlComponentInstance);
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include "qzcommon.h"
|
||||
#include "plugininterface.h"
|
||||
#include "qml/qmlplugininterface.h"
|
||||
|
||||
class QLibrary;
|
||||
class QPluginLoader;
|
||||
|
@ -36,6 +37,7 @@ struct PluginSpec {
|
|||
QString author;
|
||||
QString version;
|
||||
QPixmap icon;
|
||||
QString entryPoint;
|
||||
bool hasSettings = false;
|
||||
|
||||
bool operator==(const PluginSpec &other) const {
|
||||
|
@ -55,7 +57,8 @@ public:
|
|||
Invalid = 0,
|
||||
InternalPlugin,
|
||||
SharedLibraryPlugin,
|
||||
PythonPlugin
|
||||
PythonPlugin,
|
||||
QmlPlugin
|
||||
};
|
||||
Type type = Invalid;
|
||||
QString pluginId;
|
||||
|
@ -69,6 +72,9 @@ public:
|
|||
QString libraryPath;
|
||||
QPluginLoader *pluginLoader = nullptr;
|
||||
|
||||
// QmlPlugin
|
||||
QmlPluginInterface *qmlComponentInstance = nullptr;
|
||||
|
||||
// Other
|
||||
QVariant data;
|
||||
|
||||
|
@ -109,14 +115,17 @@ Q_SIGNALS:
|
|||
|
||||
private:
|
||||
void loadPythonSupport();
|
||||
void loadQmlSupport();
|
||||
Plugin loadPlugin(const QString &id);
|
||||
Plugin loadInternalPlugin(const QString &name);
|
||||
Plugin loadSharedLibraryPlugin(const QString &name);
|
||||
Plugin loadPythonPlugin(const QString &name);
|
||||
Plugin loadQmlPlugin(const QString &name);
|
||||
bool initPlugin(PluginInterface::InitState state, Plugin *plugin);
|
||||
void initInternalPlugin(Plugin *plugin);
|
||||
void initSharedLibraryPlugin(Plugin *plugin);
|
||||
void initPythonPlugin(Plugin *plugin);
|
||||
void initQmlPlugin(Plugin *plugin);
|
||||
|
||||
void registerAvailablePlugin(const Plugin &plugin);
|
||||
|
||||
|
|
100
src/lib/plugins/qml/qmlplugininterface.cpp
Normal file
100
src/lib/plugins/qml/qmlplugininterface.cpp
Normal file
|
@ -0,0 +1,100 @@
|
|||
/* ============================================================
|
||||
* Falkon - Qt web browser
|
||||
* Copyright (C) 2018 Anmol Gautam <tarptaeya@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* ============================================================ */
|
||||
#include "qmlplugininterface.h"
|
||||
#include <QDebug>
|
||||
|
||||
QmlPluginInterface::QmlPluginInterface()
|
||||
{
|
||||
}
|
||||
|
||||
void QmlPluginInterface::init(InitState state, const QString &settingsPath)
|
||||
{
|
||||
if (m_jsInit.isCallable()) {
|
||||
QJSValueList args;
|
||||
args.append(state);
|
||||
args.append(settingsPath);
|
||||
m_jsInit.call(args);
|
||||
} else {
|
||||
qWarning() << "Unable to call init on" << m_name << "plugin";
|
||||
}
|
||||
}
|
||||
|
||||
DesktopFile QmlPluginInterface::metaData() const
|
||||
{
|
||||
return DesktopFile();
|
||||
}
|
||||
|
||||
void QmlPluginInterface::unload()
|
||||
{
|
||||
if (m_jsUnload.isCallable()) {
|
||||
m_jsUnload.call();
|
||||
} else {
|
||||
qWarning() << "Unable to call unload on" << m_name << "plugin";
|
||||
}
|
||||
}
|
||||
|
||||
bool QmlPluginInterface::testPlugin()
|
||||
{
|
||||
if (m_jsTestPlugin.isCallable()) {
|
||||
QJSValue ret = m_jsTestPlugin.call();
|
||||
return ret.toBool();
|
||||
} else {
|
||||
qWarning() << "Unable to call testPlugin on" << m_name << "plugin";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
QString QmlPluginInterface::name()
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
void QmlPluginInterface::setName(const QString &name)
|
||||
{
|
||||
m_name = name;
|
||||
}
|
||||
|
||||
QJSValue QmlPluginInterface::jsInit()
|
||||
{
|
||||
return m_jsInit;
|
||||
}
|
||||
|
||||
void QmlPluginInterface::setJsInit(const QJSValue &init)
|
||||
{
|
||||
m_jsInit = init;
|
||||
}
|
||||
|
||||
QJSValue QmlPluginInterface::jsUnload()
|
||||
{
|
||||
return m_jsUnload;
|
||||
}
|
||||
|
||||
void QmlPluginInterface::setJsUnload(const QJSValue &unload)
|
||||
{
|
||||
m_jsUnload = unload;
|
||||
}
|
||||
|
||||
QJSValue QmlPluginInterface::jsTestPlugin()
|
||||
{
|
||||
return m_jsTestPlugin;
|
||||
}
|
||||
|
||||
void QmlPluginInterface::setJsTestPlugin(const QJSValue &testPlugin)
|
||||
{
|
||||
m_jsTestPlugin = testPlugin;
|
||||
}
|
60
src/lib/plugins/qml/qmlplugininterface.h
Normal file
60
src/lib/plugins/qml/qmlplugininterface.h
Normal file
|
@ -0,0 +1,60 @@
|
|||
/* ============================================================
|
||||
* Falkon - Qt web browser
|
||||
* Copyright (C) 2018 Anmol Gautam <tarptaeya@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* ============================================================ */
|
||||
#ifndef QMLPLUGININTERFACE_H
|
||||
#define QMLPLUGININTERFACE_H
|
||||
|
||||
#include <QJSValue>
|
||||
#include <QObject>
|
||||
|
||||
#include "desktopfile.h"
|
||||
#include "plugininterface.h"
|
||||
|
||||
class QmlPluginInterface : public QObject, public PluginInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(PluginInterface)
|
||||
Q_ENUMS(InitState)
|
||||
Q_PROPERTY(QString __name__ READ name CONSTANT)
|
||||
Q_PROPERTY(QJSValue init READ jsInit WRITE setJsInit)
|
||||
Q_PROPERTY(QJSValue unload READ jsUnload WRITE setJsUnload)
|
||||
Q_PROPERTY(QJSValue testPlugin READ jsTestPlugin WRITE setJsTestPlugin)
|
||||
|
||||
public:
|
||||
explicit QmlPluginInterface();
|
||||
DesktopFile metaData() const;
|
||||
void init(InitState state, const QString &settingsPath);
|
||||
void unload();
|
||||
bool testPlugin();
|
||||
|
||||
QString name();
|
||||
void setName(const QString &name);
|
||||
QJSValue jsInit();
|
||||
void setJsInit(const QJSValue &init);
|
||||
QJSValue jsUnload();
|
||||
void setJsUnload(const QJSValue &unload);
|
||||
QJSValue jsTestPlugin();
|
||||
void setJsTestPlugin(const QJSValue &testPlugin);
|
||||
|
||||
private:
|
||||
QString m_name;
|
||||
QJSValue m_jsInit;
|
||||
QJSValue m_jsUnload;
|
||||
QJSValue m_jsTestPlugin;
|
||||
};
|
||||
|
||||
#endif // QMLPLUGININTERFACE_H
|
33
src/lib/plugins/qml/qmlplugins.cpp
Normal file
33
src/lib/plugins/qml/qmlplugins.cpp
Normal file
|
@ -0,0 +1,33 @@
|
|||
/* ============================================================
|
||||
* Falkon - Qt web browser
|
||||
* Copyright (C) 2018 Anmol Gautam <tarptaeya@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* ============================================================ */
|
||||
#include "qmlplugins.h"
|
||||
#include "qmlplugininterface.h"
|
||||
|
||||
#include <QQmlEngine>
|
||||
|
||||
// static
|
||||
void QmlPlugins::registerQmlTypes()
|
||||
{
|
||||
registerQmlPluginInterface();
|
||||
}
|
||||
|
||||
// private static
|
||||
void QmlPlugins::registerQmlPluginInterface()
|
||||
{
|
||||
qmlRegisterType<QmlPluginInterface>("org.kde.falkon", 1, 0, "PluginInterface");
|
||||
}
|
28
src/lib/plugins/qml/qmlplugins.h
Normal file
28
src/lib/plugins/qml/qmlplugins.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
/* ============================================================
|
||||
* Falkon - Qt web browser
|
||||
* Copyright (C) 2018 Anmol Gautam <tarptaeya@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* ============================================================ */
|
||||
#ifndef QMLPLUGINS_H
|
||||
#define QMLPLUGINS_H
|
||||
|
||||
class QmlPlugins
|
||||
{
|
||||
static void registerQmlPluginInterface();
|
||||
public:
|
||||
static void registerQmlTypes();
|
||||
};
|
||||
|
||||
#endif // QMLPLUGINS_H
|
Loading…
Reference in New Issue
Block a user