Draft header file
From Scribus Public Wiki
This is the draft scplugin.h . Plugins will need to provide a subclass of ScPersistentPlugin or ScInputOutputPlugin and return an instance of it when their getPlugin() function is called. See Plugin API for an overview of the plugin interface design.
#ifndef PLUGIN_H
#define PLUGIN_H
#include "qstring.h"
class QWidget;
class ScribusApp;
/*
* TODO: Error code lookup functions
* TODO: Interfaces for getting help data a-la Acrobat Reader 7's
* "about plugins" display. Should be as simple as a series
* of getter methods, some static virtual data, or a method
* to return a simple struct/class with the info in it.
* TODO: Prefs GUI API. Scripts need to be able to register so they can
* have their own prefs pane displayed in the prefs, with a callback
* to save the prefs when the panel is OK'd. The general idea is to
* have two functions on the plugin - one a simple flag that reports
* whether or not the plugin will want to provide a prefs pane. The
* second would return some sort of QWidget containing all the prefs
* UI. That widget could have slots to be connected up to signals
* from the dialog like saveprefs(), defaults(), etc.
*
* Open question:
* What's the relationship between these objects and the plug-ins?
* Are they fairly disposable, cheap "info" objects, or are they
* more complete? Should they store any state for the plug-in?
*
* Proposed usage: lightweight, no state, info objects. The creation
* and deletion of these objects has no relationship with the loading and
* unloading of the plug-in - these objects provide access to the plug-in
* but do not in any way embody the plugin.
*
* Plug-ins should never keep these around. They must be instantiated,
* set up, and returned by reference to the caller. They may be deleted
* then, or stored for an indefinite period - the plugin must not care.
*
* Another issue:
* What's the best way to make per-plugin info data availible to this class?
* virtual method to be overridden like in the current sample below?
* members initialized by constructor? Members initialized by setter later
* (I don't like this one)? Virtual static data to be overridden?
* I'm currently favouring using constructor arguments and const members.
* This question is mostly about the various action info for import/export
* plugins.
*
* Third issue:
* Should some of the pure virtual methods below actually have default
* implementations?
*
* Note that the implementation below really creates two quite different
* kinds of plugins. One for import/export of data which is generally
* loaded, run, and unloaded. A second for persistent plugins that are loaded
* (generally when the app starts) and remain resident.
*/
class ScPlugin
{
/**
* @brief ScPlugin provides an interface to ask plugins for information
* about themselves.
*
* Plugins return an instance of a derived class based on ScPlugin when
* asked for it by the plugin manager. This class provides general
* information about the plugin. It should not generally be inherited
* directly by plugins - use one of the provided base classes instead.
*/
public:
/** \brief Human readable enumertion of the plugin types */
// FIXME: duplicated in pluginmanager
// FIXME: probably not needed when we can just use QMetaObject::inherits() but might simplify things anyway
enum PluginType {
Persistent = 4,
Import = 7,
Standard = 6,
};
/**
* @brief ctor, returns a new ScPlugin instance
*
* @param int iD Unique plugin ID, usually a static
* const int defined in the plugin.
* @param PluginType type Plugin type code
* @param QString name Name of the plugin as shown in the
* Start-up dialog and plugin mgr. This is
* the "friendly" human-readable name.
* PluginManager should already know the
* internal name.
*/
ScPlugin(int id, PluginType type, QString& name);
/** @brief Uninteresting dtor */
virtual ~ScPlugin();
// Public methods
// Accessors
protected:
const int m_id; // Plugin ID as passed to ctor
const PluginType m_type; // Plugin type as passed to ctor
const QString m_name; // Plugin name as passed to ctor
};
class ScImportExportPlugin : public ScPlugin
{
/*
* @brief A plug-in that's loaded for data import/export duties
*
* ScImportExportPlugin describes a plug-in that is loaded on demand
* to perform a data import/export task such as importing an SVG
* image or exporting a page to EPS format. It'll generally by unloaded
* after being queried, then loaded on demand when it needs to run.
*/
public:
ScImportExportPlugin(int id, PluginType type, QString& name);
virtual ~ScImportExportPlugin();
/**
* @brief Run the plug-in's main action.
*
* Run the plug-in's default action. That usually means prompting the user for
* a target (file to save as / file to import) then performing the import/export
* action the plug-in is written for.
*
* The plug-in should clean up neatly after this method completes as it may
* be immediately unloaded. It should not assume it will be unloaded however
* - this method may be called multiple times. Some platforms may
* also not permit plugins to be unloaded.
*
* @param QWidget& parent Parent widget to this plugin. Usually the main window.
* @param ScribusApp& mainWindow The main application window.
* @returns bool True for success.
*
*/
virtual bool run(QWidget& parent, ScribusApp& mainWindow) = 0;
/**
* @brief Run the plug-in on a target, specified as a string
*
* This method is essentially the same as the above, except that it takes
* an additional argument - a target string. The meaning of this string
* is plug-in specific, but in most cases it will refer to a file path
* (save target, file to import, etc).
*
* Nothing stops a plug-in doing funky things like accepting a WebDAV
* URI via this argument, assuming it knows how to handle it. The form
* of the argument is up to the plugin. Plugins MUST handle invalid
* input by returning false (failure).
*
* @sa ScImportExportPlugin::run()
*/
virtual bool runWith(QWidget& parent, ScribusApp& mainWindow, QString target) = 0;
/**
* @brief Run the plugin on a QIODevice
*
* This method is essentially the same as the above, except that
* it accepts a QIODevice to work with. This will generally be used
* for file I/O without the plugin having to know or care where from.
*
* A plug-in MUST return false if it cannot support this method or
* upon failure. A plug-in MUST supply a working version of this method
* if it accepts runWith(..., QString) on a local file, and should
* generally implement the former using this method.
*/
virtual bool runWith(QWidget& parent, ScribusApp& mainWindow, QIODevice& target) = 0;
/** @brief Return action name
*
* This method is used to get the name to give the QAction that will be created
* for this plug-in. It is usually called when the plug-in is initially loaded.
* (the plug-in is often subsequently unloaded until needed).
*
* Return the name of the action associated with this plug-in.
*
* Rather than having these virtual and overriding them, it might be
* better to make them use const member data initilized in the ctor.
*
* @returns action name
*/
virtual QString actionName() const = 0;
/** @brief return action key sequence
* @sa scplugin::actionname() */
virtual QString actionKeySequence() const = 0;
/** @brief return action menu identifier string
* @sa scplugin::actionname() */
virtual QString actionMenu() const = 0;
/** @brief er...
* @sa scplugin::actionname() */
virtual QString actionMenuAfterName() const = 0;
/** @brief return true if action should be enabled on startup
* @sa scplugin::actionname() */
virtual bool actionEnabledOnStartup() const = 0;
};
class ScPersistentPlugin : public ScPlugin
{
/**
* @brief A plug-in that is resident for the lifetime of the app
*
* ScPersistentPlugin describes a plugin that is to be kept resident
* for the lifetime of the app (or until unloaded by a request to
* the plug-in manager).
*
* Such plug-ins have an init method and a cleanup method; they have
* no "run" method as such.
*/
public:
ScPersistentPlugin(int id, PluginType type, QString& name);
virtual ~ScPersistentPlugin();
/**
* @brief Initialize the plugin
*
* This method must initialize the plugin. It is called at plug-in load
* time. This method will never be called twice without an intervening
* cleanupPlug call.
*
* It will usually instantiate a class and store the instance in a static
* variable in the plugin, letting that class do the work of setup and
* integration into the app.
*
* @param QWidget& parent Parent widget to this plugin. Usually the main window.
* @parem ScribusApp& mainWindow The main application window.
* @returns bool True for success.
*/
virtual bool initPlug(QWidget& parent, ScribusApp& mainWindow) = 0;
/**
* @brief Cleans up the plugin so it can be safely unloaded.
*
* This method will be called when the plug-in is about to be unloaded,
* or if the plug-in manager has been asked to disable the plug-in. This method
* will never be called unless initPlug has been called first.
*
* @returns bool True for success.
*/
virtual bool cleanupPlug() = 0;
};
#endif

