Subversion Repositories Scribus

Rev

Rev 3189 | Rev 3207 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2972 craig 1
#ifndef _SCPLUGIN_H
2
#define _SCPLUGIN_H
3
 
4
#include "qobject.h"
5
#include "qstring.h"
6
#include "qpixmap.h"
7
#include "qdatetime.h"
3193 craig 8
#include "qiconset.h"
2972 craig 9
#include "scribusapi.h"
10
 
11
class QWidget;
12
class ScribusApp;
13
class DeferredTask;
14
 
15
/*
16
 * The idea here is that a ScPlugin is an information class stored by the
17
 * plug-in and returned to callers. It is a singleton that is always owned
18
 * by the plugin implementation.
19
 *
20
 * Note that the implementation below really creates two quite different
21
 * kinds of plugins. One for import/export of data which is generally
22
 * loaded, run, and unloaded. A second for persistent plugins that are loaded
23
 * (generally when the app starts) and remain resident.
24
 *
25
 * More plugin classes - such as plugins for text import and document import
26
 * - may be added in future.
2975 craig 27
 *
28
 * In addition to the API described here, a plugin is expected to implement
29
 * the following "extern C" functions, where 'pluginname' is the base name
30
 * of the plug-in:
31
 *
32
 * int pluginname_pluginAPIVersion();
33
 *    Return an integer indicating the plug-in API version implemented.
34
 *    If the version does not exactly match the running plugin API version,
35
 *    the plugin will not be initialised.
36
 *
37
 * ScPlugin* pluginname_getPlugin();
38
 *    Create and return an instance of the plug-ins ScPlugin subclass.
39
 *    Nothing should be done here that's overly slow or uses much memory,
40
 *    and the plugin should not initialize its self here beyond what is
41
 *    required to return a ScPlugin instance.
42
 *
43
 * void pluginname_freePlugin(ScPlugin* plugin);
44
 *    Free the scplugin instance returned earlier.
45
 *
3193 craig 46
 * TODO: define "standard" plug-ins better
47
 * TODO: better discovery of what plug-ins can import / export what formats, file exts, names, etc.
48
 *
2972 craig 49
 */
50
 
51
class SCRIBUS_API ScPlugin : public QObject
52
{
53
        Q_OBJECT
54
 
55
        /**
56
         * @brief ScPlugin provides an interface to ask plugins for information
57
         * about themselves.
58
         *
59
         * Plugins return a pointer to their ScPlugin instance when
60
         * asked for it by the plugin manager. This class provides general
61
         * information about the plugin. It should not generally be inherited
62
         * directly by plugins - use one of the provided base classes instead.
63
         */
64
        public:
65
 
66
                /** \brief Human readable enumertion of the plugin types */
67
                enum PluginType {
2975 craig 68
                        PluginType_Persistent = 4,
69
                        PluginType_Import = 7,
70
                        PluginType_Export = 8,
2972 craig 71
                };
72
 
73
                // A struct providing the information returned by getAboutData(), for
74
                // the "About Plug-ins" menu item.
75
                struct AboutData
76
                {
77
                        // Author name(s) and email address(es)
78
                        QString authors;
79
                        // One-liner description of the function of the plugin
80
                        QString shortDescription;
81
                        // Longer description of the plugin
82
                        QString description;
83
                        // Text plug-in version string
84
                        QString version;
85
                        // Date of the release of this version
86
                        QDateTime releaseDate;
87
                        // Copyright string
88
                        QString copyright;
89
                        // License text / name / URL / whatever. Please don't include
90
                        // the GPL here, just reference it. Remember that Scribus is
91
                        // licensed under the GPL, so plug-in authors must take that
92
                        // into account.
93
                        QString license;
94
                };
95
 
2975 craig 96
                /**
97
                 * @brief ctor, returns a new ScPlugin instance
98
                 *
3193 craig 99
                 * @param id              Unique plugin ID, usually a static
2975 craig 100
                 *                        const int defined in the plugin.
3193 craig 101
                 * @param pluginType      plugin type enum, used by plugin
102
                 *                        manager to identify plugin.
2975 craig 103
                 *
104
                 * Only the actual plugin implmementation should call this, from
105
                 * its setup function.
106
                 */
3193 craig 107
                ScPlugin(int id, PluginType pluginType);
2975 craig 108
 
109
                /** @brief Pure virtual destructor - this is an abstract class */
110
                virtual ~ScPlugin() = 0;
111
 
2972 craig 112
                // Plug-in type, inited by ctor.
113
                const PluginType pluginType;
114
 
2975 craig 115
                // Plug-in ID, inited by ctor. This must be unique across all
116
                // plug-ins.
117
                const int id;
2972 craig 118
 
119
                // Plug-in's human-readable, translated name. Please don't use this for
3193 craig 120
                // anything except display to the user.
121
                virtual const QString fullTrName() = 0;
2972 craig 122
 
123
                // Methods to create and destroy the UI pane for the plugin
3189 craig 124
                // A plugin MUST reimplment destroyPrefsPanelWidget if it
2975 craig 125
                // reimplements newPrefsPanelWidget .
3189 craig 126
                // By default, returns 0 to indicate no prefs UI.
2975 craig 127
                virtual QWidget* newPrefsPanelWidget();
3189 craig 128
                virtual void destroyPrefsPanelWidget(QWidget* prefsPanelWidget);
2972 craig 129
 
3189 craig 130
                // Return icon and caption to use for preferences panel in the prefs
131
                // dialog. Unless overridden, returns QString::null and an empty pixmap.
132
                virtual const QPixmap prefsPanelIcon() const;
133
                virtual const QString prefsPanelName() const;
134
 
2972 craig 135
                // Returns a structure containing descriptive information about the
136
                // plug-in. This information is used in places like the Help->About
137
                // Plug-ins menu item. The stucture MUST be deleted using
138
                // deleteAboutData(AboutData* about) when finished with.
139
                //
2975 craig 140
                // Every plug-in must re-implment these.
3189 craig 141
                virtual const AboutData* getAboutData() const = 0;
142
                virtual void deleteAboutData(const AboutData* about) const = 0;
2972 craig 143
 
2975 craig 144
                // Return human readable, translated text of last error to be
145
                // encountered. DO NOT ATTEMPT TO USE THIS VALUE TO MAKE
146
                // DECISIONS IN PROGRAM CODE.
147
                const QString & lastError() const;
148
 
3193 craig 149
                // Updates the text on all widgets on the plug-in to reflect the new
150
                // language. You should generally use this method to set all the widget
151
                // text during construction.
152
                virtual void languageChange() = 0;
153
 
154
                /// Returns human readable plugin type from plug-in's pluginType
155
                const QString pluginTypeName() const;
156
 
2972 craig 157
        protected:
2975 craig 158
                // Human readable, translated version of last error to occur.
159
                QString m_lastError;
2972 craig 160
};
161
 
162
 
163
class SCRIBUS_API ScImportExportPlugin : public ScPlugin
164
{
165
        Q_OBJECT
166
 
167
        /*
168
         * @brief A plug-in that's loaded for data import/export duties
169
         *
170
         * ScImportExportPlugin describes a plug-in that is loaded on demand
171
         * to perform a data import/export task such as importing an SVG
172
         * image or exporting a page to EPS format. It'll generally by unloaded
173
         * after being queried, then loaded on demand when it needs to run.
174
         */
175
 
176
        public:
177
 
2975 craig 178
                /** @brief ctor
179
                 *
180
                 * @sa ScPlugin::ScPlugin()
181
                 */
3193 craig 182
                ScImportExportPlugin(int id, PluginType pluginType);
2975 craig 183
                // Pure virtual dtor - abstract class
184
                virtual ~ScImportExportPlugin() = 0;
185
 
3193 craig 186
                // Information about actions, to be returned by actionInfo()
187
                struct ActionInfo {
188
                        QString name;  // name of action
189
                        QString text;  // text to display to user
190
                        QString keySequence;
191
                        QString menu;
192
                        QString menuAfterName;
193
                        QIconSet iconSet;
194
                        bool enabledOnStartup;
195
                };
196
 
197
                // Return an ActionInfo instance to the caller
198
                virtual const ActionInfo & actionInfo() const = 0;
199
 
200
        public slots:
2972 craig 201
                /**
202
                 * @brief Run the plug-in's main action.
203
                 *
204
                 * Run the plug-in's default action. That usually means prompting the
2975 craig 205
                 * user for a target (file to save as / file to import) then
206
                 * performing the import/export action the plug-in is written for.
2972 craig 207
                 *
2975 craig 208
                 * It should generally call run(..., QIODevice* target) or run(...,
209
                 * QString target) to do the work. This is done by default, with the
210
                 * assumption that the target is a file. An open QFile with
211
                 * IO_ReadOnly or IO_WriteOnly mode, depending on plugin type,
212
                 * is supplied. Override this if you need more flexibility.
2972 craig 213
                 *
214
                 * The optional target argument is a plugin-defined string indicating
215
                 * what the plugin should operate on. It will typically be a filename
216
                 * to import from / export to. Nothing stops a plugin doing funky
217
                 * things like accepting a WebDAV URI, etc, however.
218
                 *
219
                 * Plug-in authors might want to consider implementing this using the
220
                 * DeferredTask subclass used in runAsync, if the plug-in supports it.
221
                 *
3193 craig 222
                 * @param QString target Optional target to operate on (see
223
                 *                above)
224
                 * @returns bool True for success.
2972 craig 225
                 *
226
                 */
3193 craig 227
                virtual bool run(QString target = QString::null);
2972 craig 228
 
229
                /**
230
                 * @brief Run the plugin on a QIODevice
231
                 *
232
                 * This method is essentially the same as the above, except that it
233
                 * accepts a QIODevice* to work with. This will generally be used for
234
                 * file I/O without the plugin having to know or care where from.
235
                 *
236
                 * A plug-in MUST return false if it cannot support this method or upon
237
                 * failure. A plug-in MUST supply a working version of this method if
238
                 * it accepts runWith(..., QString) on a local file, and should
239
                 * generally implement the former using this method.
240
                 *
241
                 * Remember that not all QIODevice*s are seekable, and try to write
242
                 * your code to handle a non-seekable stream.
243
                 */
3193 craig 244
                virtual bool run(QIODevice* target);
2972 craig 245
 
246
                /**
247
                 * @brief Run the plugin asynchronously
248
                 *
249
                 * This call is similar to the one above, but instead of doing all the
250
                 * work in one big batch, it creates an instance of a DeferredTask
251
                 * subclass to keep track of the job, does some setup, and returns
252
                 * immediately. The DeferredTask, a pointer to which is returned, has
253
                 * already been started when this method returns.
254
                 *
255
                 * The caller of this method is responsible for handling the aborted()
256
                 * and finished() signals from the DeferredTask, and (if necessary) for
257
                 * cleaning it up once it has finished. Remember that a DeferredTask is
258
                 * automatically deleted when its parent is, if it hasn't already been
259
                 * deleted.
260
                 *
261
                 * FIXME: The above is probably utterly broken on win32.
262
                 *
263
                 * See the DeferredTask documentation for details on how it works.
264
                 *
265
                 * If your plugin implementation does not support asynchronous
266
                 * operation, you must return null. This is the default implementation,
267
                 * so simply ignore this method unless you wish to support it. It is
268
                 * recommended that all new plugins support this interface where
269
                 * possible, even if they can only do part of their work progressively.
270
                 *
271
                 * If you implement this, you may want to implement run(...) using the
272
                 * same deferred operation and a modal dialog. That'll permit the event
273
                 * loop to continue running for redraws, permit you to update the
274
                 * progress bar, etc.
275
                 *
276
                 * NOTE: In current Scribus code (August 2005), callers of this method
277
                 * will generally create a modal dialog - possibly with progress meter
278
                 * - then attach signals from the DeferredTask, and exec() the dialog.
279
                 *   A caller is not required to do this, but with the current (August
280
                 *   2005) core code it's the only way to operate safely. This is
281
                 *   likely to change in future and you should avoid relying on it if
282
                 *   at all posssible.
283
                 *
284
                 * If this method is used, the plugin must not be unloaded until all
285
                 * DeferredTask instances have been deleted.
286
                 */
3193 craig 287
                virtual DeferredTask* runAsync(QString target = QString::null);
2972 craig 288
 
289
                /**
290
                 * @brief Run the plugin asynchronously
291
                 *
292
                 * This method is much the same as the above, but takes a QIODevice* as
293
                 * the target. Please see the documentation for run(..., QIODevice*
294
                 * target) and runAsync(..., QString target) for details.
295
                 */
3193 craig 296
                virtual DeferredTask* runAsync(QIODevice* target);
2972 craig 297
 
3193 craig 298
                // Compat kludge ... we store a QString result from any successful
299
                // run(...) call in m_runResult and let callers retrive it here.
300
                // DO NOT USE THIS INTERFACE FOR NEW PLUG-INS; you should
301
                // dynamic_cast<> to the plugin type then call a plug-in specific
302
                // method instead.
303
                const QString & runResult() const;
2972 craig 304
 
3189 craig 305
        protected:
306
                ActionInfo m_actionInfo;
3193 craig 307
                QString m_runResult;
2972 craig 308
};
309
 
310
class SCRIBUS_API ScPersistentPlugin : public ScPlugin
311
{
312
        Q_OBJECT
313
 
314
        /**
315
         * @brief A plug-in that is resident for the lifetime of the app
316
         *
317
         * ScPersistentPlugin describes a plugin that is to be kept resident
318
         * for the lifetime of the app (or until unloaded by a request to
319
         * the plug-in manager).
320
         *
321
         * Such plug-ins have an init method and a cleanup method; they have
322
         * no "run" method as such.
323
         */
324
        public:
325
 
2975 craig 326
                /** @brief ctor
327
                 *
328
                 * @sa ScPlugin::ScPlugin()
329
                 */
3193 craig 330
                ScPersistentPlugin(int id);
2975 craig 331
 
332
                // Pure virtual dtor for abstract class
333
                virtual ~ScPersistentPlugin() = 0;
334
 
2972 craig 335
                /**
336
                 * @brief Initialize the plugin
337
                 *
338
                 * This method must initialize the plugin. It is called at plug-in load
339
                 * time. This method will never be called twice without an intervening
340
                 * cleanupPlug call (but not necessarily unloading the plugin).
341
                 *
342
                 * It will usually instantiate a class and store a pointer to the
343
                 * instance in a static variable of the plugin or a member of its
344
                 * ScPersistentPlugin subclass, letting that class do the work of setup
345
                 * and integration into the app.
346
                 *
2975 craig 347
                 * Note that this is NOT the same as the init function of the plugin. That
348
                 * is always simple and lightweight, intended to just get an instance of this
349
                 * class back to the core app. This function is where any time-consuming or
350
                 * memory expensive init should be done.
351
                 *
3193 craig 352
                 * If this method returns failure, the plugin will be treated as dead and
353
                 * cleanupPlug() will not be called.
354
                 *
2975 craig 355
                 * @returns bool True for success.
2972 craig 356
                 */
3193 craig 357
                virtual bool initPlugin() = 0;
2972 craig 358
 
359
                /**
360
                 * @brief Cleans up the plugin so it can be safely unloaded.
361
                 *
362
                 * This method will be called when the plug-in is about to be unloaded,
363
                 * or if the plug-in manager has been asked to disable the plug-in.
364
                 * This method will never be called unless initPlug has been called
365
                 * first, but there is no guarantee the plugin will be unloaded after
366
                 * this is called, or before initPlug is called again.
367
                 *
368
                 * @returns bool True for success.
369
                 */
370
                virtual bool cleanupPlug() = 0;
371
};
372
 
373
#endif