Draft header file

From Scribus Wiki
Jump to navigation Jump to search

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