Draft header file

From Scribus Wiki
Revision as of 15:47, 30 June 2005 by Ringerc (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

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