How to: Create an NCL Composer Plugin
What is a Plugin?
A plugin is a piece of software distributed separated from other software (the main or host) aiming to extend its functionalities. In order to allow extensions and customizations NCL Composer architecture is based on plugins.
A common way to extend the NCL Composer functionalities is creating new Views to documents being developed. A View is a plugin that brings out a representation of this document (e.g. showing its entities in a tree, or showing how this document is represented in a timeline, etc.).
NCL Composer Plugins
Since version 0.2.x NCL Composer plugins are based on Qt5 plug-in system. A plug-in is composed of one C++ interface (IPlug-in) implementation and a .json file that describe this plug-in.
An example: Debug Plugin
As a simple example, let's create a Debug Plugin. This plugin will print all the messages that it receives from NCL Composer core.
First of all, let's create our DebugConsolePlugin.h:
#ifndef DEBUGCONSOLEPLUGIN_H #define DEBUGCONSOLEPLUGIN_H #include <QObject> #include <core/extensions/IPlugin.h> using namespace composer::extension; class DebugConsolePlugin : public IPlugin { Q_OBJECT private: QWidget *window; public: explicit DebugConsolePlugin(); ~DebugConsolePlugin(); void init(); QWidget* getWidget(); public slots: void onEntityAdded(QString pluginID, Entity *); void onEntityChanged(QString pluginID, Entity *); void onEntityRemoved(QString pluginID, QString entityID); void errorMessage(QString error); }; #endif // DEBUGCONSOLEPLUGIN_H
And the DebugConsole.cpp:
#include "DebugConsolePlugin.h" DebugConsolePlugin::DebugConsolePlugin() { // Do nothing } DebugConsolePlugin::~DebugConsolePlugin() { // Do nothing } void DebugConsolePlugin::init() { qDebug() << "DEBUG MESSAGE:IT STARTED" ; } QWidget* DebugConsolePlugin::getWidget() { return NULL;/*No window to return, This tells to NCL Composer that our plugin doesn't have a GUI*/ } void DebugConsolePlugin::onEntityAdded(QString pluginID, Entity *entity) { QString line = "DEBUG MESSAGE:PLUGIN (" + pluginID + ") added the Entity (" + entity->getType() + " - " + entity->getUniqueId() +")"; qDebug() << line; } void DebugConsolePlugin::errorMessage(QString error) { qDebug() << "DEBUG MESSAGE:ERROR - " << error; } void DebugConsolePlugin::onEntityChanged(QString pluginID, Entity * entity) { QString line = "DEBUG MESSAGE: PLUGIN (" + pluginID + ") changed the Entity (" + entity->getType() + " - " + entity->getUniqueId() +")"; qDebug() << line; } void DebugConsolePlugin::onEntityRemoved(QString pluginID, QString entityID) { QString line = "DEBUG MESSAGE: (" + pluginID + ") removed Entity (" + entityID + ")"; qDebug() << line ; }
In order to NCL Composer know how to create new instances of our DebugPlugin, we have to provide a Factory class: a DebugConsoleFactory.h
#ifndef DEBUGCONSOLE_H #define DEBUGCONSOLE_H #include "DebugConsole_global.h" #include "DebugConsolePlugin.h" #include <core/extensions/IPluginFactory.h> using namespace composer::extension; class DebugConsoleFactory : public QObject, public IPluginFactory { Q_OBJECT Q_INTERFACES(IPluginFactory) #if QT_VERSION >= 0x050000 Q_PLUGIN_METADATA(IID IPluginFactory_iid FILE "DebugConsole.json") #endif public: DebugConsoleFactory(); ~DebugConsoleFactory(); IPlugin* createPluginInstance(); void releasePluginInstance(IPlugin *); QList<LanguageType> getSupportedLanguages(); QString id() const ; QIcon icon() const; QWidget* getPreferencePageWidget(); #if QT_VERSION < 0x050000 QString name() { return tr("Debug Console"); } QString version() { return NCLCOMPOSER_PLUGINS_VERSION; } QString compatVersion() {return "0.1";} QString vendor() {return "Telemidia Lab";} QString copyright() {return "Telemidia/PUC-Rio";} QString license() {return "LGPL";} QString description() {return tr("Debug Console View prints all the " " messages send by composer-core to plugins.");} QString url() {return "http://composer.telemidia.puc-rio.br/debug";} QString category() {return tr("General");} #endif }; #endif // DEBUGCONSOLE_H
and its DebugConsoleFactory.cpp
#include "DebugConsoleFactory.h" DebugConsoleFactory::DebugConsoleFactory() { //Do nothing } DebugConsoleFactory::~DebugConsoleFactory() { //Do nothing } IPlugin* DebugConsoleFactory::createPluginInstance() { return new DebugConsolePlugin(); } void DebugConsoleFactory::releasePluginInstance(IPlugin *plugin) { DebugConsolePlugin *debug = qobject_cast<DebugConsolePlugin*>(plugin); if (debug) { delete debug; debug = NULL; } } QList<LanguageType> DebugConsoleFactory::getSupportedLanguages() { QList<LanguageType> lTypes; lTypes.append(NCL); return lTypes; } QString DebugConsoleFactory::id() const { return "br.puc-rio.telemidia.DebugConsole"; } QIcon DebugConsoleFactory::icon() const { return QIcon(":/images/icon.png"); } QWidget* DebugConsoleFactory::getPreferencePageWidget() { return NULL; } #if QT_VERSION < 0x050000 Q_EXPORT_PLUGIN2(DebugConsole,DebugConsoleFactory) #endif
the DebugConsole_global.h used by the factory file:
#ifndef DEBUGCONSOLE_GLOBAL_H #define DEBUGCONSOLE_GLOBAL_H #include <QtCore/qglobal.h> #if defined(DEBUGCONSOLE_LIBRARY) # define DEBUGCONSOLESHARED_EXPORT Q_DECL_EXPORT #else # define DEBUGCONSOLESHARED_EXPORT Q_DECL_IMPORT #endif #endif // DEBUGCONSOLE_GLOBAL_H
Additionally, you will also need to define the debugplugin.json file describing your plug-in:
{ "name" : "Debug Console Plug-in", "version" : "0.2.0", "compatVersion" : "0.2.0", "vendor" : "TeleMidia Lab", "description" : "Debug Console View prints all the messages sent by NCL Composer to plugins.", "url" : "http://composer.telemidia.puc-rio.br/plugin/debug", "category" : "Debug" "dependencies" : [] }