Draft header file: Difference between revisions
Jump to navigation
Jump to search
No edit summary |
m (What is the status/fate of this page? Category:Future_Unknown) |
||
(One intermediate revision by one other user not shown) | |||
Line 1: | Line 1: | ||
[[Category: | [[Category:Development]][[Category:Future_Unknown]] | ||
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. | 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. | ||
Latest revision as of 13:09, 30 December 2013
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