Subversion Repositories Scribus

Rev

Rev 3256 | Rev 3487 | 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"
3214 craig 5
#include "qwidget.h"
2972 craig 6
#include "qstring.h"
7
#include "qpixmap.h"
8
#include "qdatetime.h"
3193 craig 9
#include "qiconset.h"
2972 craig 10
#include "scribusapi.h"
11
 
12
class QWidget;
13
class ScribusApp;
14
class DeferredTask;
3213 craig 15
class PrefsPanel;
2972 craig 16
 
3214 craig 17
/**
18
 * \brief Abstract super class for all Scribus plug-ins
2972 craig 19
 *
3214 craig 20
 * ScPlugin is a class that provides information about a plug-in, and a gateway
21
 * into any plugin-specific functionality.  It should not generally be
3486 craig 22
 * inherited directly by actual plugin implementations - use one of the
23
 * provided base classes instead. See below for info on the creation of
24
 * new types of plugin.
2972 craig 25
 *
3486 craig 26
 * Plugins create and return a instance of a subclass of ScPlugin when asked
27
 * for it by the plugin manager. The plugin manager is responsible for tracking
28
 * these instances. The ScPlugin instance is used by the plugin manager for
29
 * tasks such as hooking the plugin up to the UI where appropriate. It's also
30
 * used by other code that talks to plugins, usually by dynamic_cast<>ing it to
31
 * a more specific subclass and working with that. The file loader system will
32
 * provide an example of this.
3214 craig 33
 *
3486 craig 34
 * A given plugin implementation's ScPlugin subclass is *not* the best place
35
 * to implement the bulk of the plugin's functionality. It must be lightweight
36
 * and maintain as little state as possible. Most functionality should be
37
 * implemented in a private subclass that is not exposed in the header of the
38
 * scplugin subclass defined by the plugin. That helps keep the plugin's
39
 * implementation separate from its inteface to Scribus.
3214 craig 40
 *
3486 craig 41
 * Note that the two subclases ScActionPlugin and ScPersistentPlugin, defined
42
 * below, create two quite different kinds of plugins. One is for import/export
43
 * of data and for single function actions (like providing a particular dialog
44
 * or function) which generally do nothing when not in active use. A second for
45
 * persistent plugins that are loaded (generally when the app starts) and
46
 * remain resident, possibly active in the background or hooked into many
47
 * parts of the user interface.
48
 *
2972 craig 49
 * More plugin classes - such as plugins for text import and document import
50
 * - may be added in future.
2975 craig 51
 *
3486 craig 52
 * New types of plugin can be created by subclassing ScPlugin or one of its
53
 * subclasses and adding the additional interfaces required. The two existing
54
 * subclasses provide examples of how this can work. Of course, once you have
55
 * the plugin interface, you still need to actually use the plugins. You'll need
56
 * to extend pluginmanager.cpp a little to handle any low-level init required by
57
 * the new plugin type (please keep this minimal!). You'll then need to extend
58
 * the appropriate classes to make use of the new plugin type where required.
59
 * The new file loader mechanism will provide a good example of this.
60
 *
2975 craig 61
 * In addition to the API described here, a plugin is expected to implement
62
 * the following "extern C" functions, where 'pluginname' is the base name
3214 craig 63
 * of the plug-in (where the filename is libpluginname.so on UNIX):
2975 craig 64
 *
3207 craig 65
 * int pluginname_getPluginAPIVersion();
2975 craig 66
 *    Return an integer indicating the plug-in API version implemented.
67
 *    If the version does not exactly match the running plugin API version,
68
 *    the plugin will not be initialised.
69
 *
70
 * ScPlugin* pluginname_getPlugin();
71
 *    Create and return an instance of the plug-ins ScPlugin subclass.
72
 *    Nothing should be done here that's overly slow or uses much memory,
73
 *    and the plugin should not initialize its self here beyond what is
74
 *    required to return a ScPlugin instance.
75
 *
76
 * void pluginname_freePlugin(ScPlugin* plugin);
77
 *    Free the scplugin instance returned earlier.
78
 *
3193 craig 79
 * TODO: better discovery of what plug-ins can import / export what formats, file exts, names, etc.
80
 *
2972 craig 81
 */
82
 
83
class SCRIBUS_API ScPlugin : public QObject
84
{
85
        Q_OBJECT
86
 
87
        /**
88
         * @brief ScPlugin provides an interface to ask plugins for information
89
         * about themselves.
90
         *
91
         */
92
        public:
93
 
3207 craig 94
                /** \brief Human readable enumertion of the plugin types
95
                 *
96
                 * This might get replaced with checking inheritance
97
                 * with QObject.
98
                 *
99
                 * PluginType_Persistent:
100
                 *    The plug-in is loaded and initialised on app startup. No
101
                 *    automatic connection to the GUI is made, and the plugin
102
                 *    essentially becomes part of the application, maintaining
103
                 *    its state as long as it's loaded.
104
                 *
105
                 * PluginType_Import:
106
                 *    The plug-in provides the facility to import file type(s).
107
                 *    It keeps no state.
108
                 *
109
                 * PluginType_Export:
110
                 *    The plugin provides a facility to export file type(s).
111
                 *    It keeps no state.
112
                 *
113
                 * PluginType_Action:
114
                 *    The plugin has a single specific action it can take that
115
                 *    is not import or export. It's automatically hooked into
116
                 *    the GUI and keeps no state.
117
                 */
2972 craig 118
                enum PluginType {
2975 craig 119
                        PluginType_Persistent = 4,
120
                        PluginType_Import = 7,
121
                        PluginType_Export = 8,
3207 craig 122
                        PluginType_Action = 9
2972 craig 123
                };
124
 
125
                // A struct providing the information returned by getAboutData(), for
126
                // the "About Plug-ins" menu item.
127
                struct AboutData
128
                {
129
                        // Author name(s) and email address(es)
130
                        QString authors;
131
                        // One-liner description of the function of the plugin
132
                        QString shortDescription;
133
                        // Longer description of the plugin
134
                        QString description;
135
                        // Text plug-in version string
136
                        QString version;
137
                        // Date of the release of this version
138
                        QDateTime releaseDate;
139
                        // Copyright string
140
                        QString copyright;
141
                        // License text / name / URL / whatever. Please don't include
142
                        // the GPL here, just reference it. Remember that Scribus is
143
                        // licensed under the GPL, so plug-in authors must take that
144
                        // into account.
145
                        QString license;
146
                };
147
 
2975 craig 148
                /**
149
                 * @brief ctor, returns a new ScPlugin instance
150
                 *
3193 craig 151
                 * @param pluginType      plugin type enum, used by plugin
152
                 *                        manager to identify plugin.
2975 craig 153
                 *
3486 craig 154
                 * Only pluginname_getPlugin(...) may call this. Calls by other code
155
                 * will have undefined results.
2975 craig 156
                 */
3207 craig 157
                ScPlugin(PluginType pluginType);
2975 craig 158
 
3486 craig 159
                /** @brief Destroy the ScPlugin instance
160
                 *
161
                 * Pure virtual destructor - this is an abstract class.
162
                 *
163
                 * Only pluginname_freePlugin(...) may call this. Calls by other code
164
                 * will have undefined results.
165
                 */
2975 craig 166
                virtual ~ScPlugin() = 0;
167
 
3486 craig 168
                /** @brief Plug-in type, inited by ctor.
169
                 *
170
                 * @sa ScPlugin::PluginType
171
                 */
2972 craig 172
                const PluginType pluginType;
173
 
3486 craig 174
                /** @brief Plug-in's human-readable, translated name.
175
                 *
176
                 * Please don't use this for anything except display to the user.
177
                 * The results of testing the value of this can not be guaranteed,
178
                 * as its value may change depending on locale and change at runtime.
179
                 */
3207 craig 180
                virtual const QString fullTrName() const = 0;
2972 craig 181
 
3214 craig 182
                /**
183
                 * \brief Create and return a prefs UI panel for the plugin.
184
                 *
185
                 * Override this method if you want to provide a panel for the
186
                 * preferences dialog.
187
                 *
188
                 * The caller takes ownership of the panel. Qt is responsible for
3486 craig 189
                 * deleting it when it's parent is deleted. `parent' must be the dialog
3214 craig 190
                 * the widget will be added to or a child of it, otherwise the panel
191
                 * won't be deleted correctly when the dialog is.
192
                 *
193
                 * See prefspanel.h for info on implementing the panel.
194
                 *
195
                 * This method must return false (the default) if the plugin does
196
                 * not provide a prefs panel. If true is returned, caption, panel,
197
                 * and icon MUST have been assigned.
198
                 *
199
                 * \param parent Parent widget, to be passed to panel ctor
200
                 * \param panel (out) the panel created
201
                 * \param caption (out) caption for icon in panel list
202
                 * \param icon (out) icon for use in panel list
203
                 * \return true if panel was created, false if not.
204
                 *
205
                 * By default, returns 0 to indicate no prefs UI.
206
                */
207
                virtual bool newPrefsPanelWidget(QWidget* parent, PrefsPanel*& panel,
208
                                                                                 QString& caption, QPixmap& icon);
2972 craig 209
 
3189 craig 210
                // Return icon and caption to use for preferences panel in the prefs
211
                // dialog. Unless overridden, returns QString::null and an empty pixmap.
3486 craig 212
                /// TODO: OBSOLETE: Delete these next time the plugin API version is bumped.
3189 craig 213
                virtual const QPixmap prefsPanelIcon() const;
214
                virtual const QString prefsPanelName() const;
215
 
3486 craig 216
                /* @brief Return descriptive information about the plug-in
217
                 *
218
                 * Returns a structure containing descriptive information about the
219
                 * plug-in. This information is used in places like the Help->About
220
                 * Plug-ins menu item. The stucture MUST be deleted using
221
                 * deleteAboutData(AboutData* about) when finished with.
222
                 *
223
                 * Every plugin MUST reimplement getAboutData(...) and deleteAboutData(...).
224
                 *
225
                 * @sa ScPlugin::deleteAboutData
226
                 */
3189 craig 227
                virtual const AboutData* getAboutData() const = 0;
228
                virtual void deleteAboutData(const AboutData* about) const = 0;
2972 craig 229
 
3486 craig 230
                /* @brief Text summary of last error encountered
231
                 *
232
                 * Return the human readable, translated text of last error to be
233
                 * encountered by this plugin. DO NOT ATTEMPT TO USE THIS VALUE TO MAKE
234
                 * DECISIONS IN PROGRAM CODE. The value returned for a given error
235
                 * may change depending on locale, and may change at runtime.
236
                 */
2975 craig 237
                const QString & lastError() const;
238
 
3486 craig 239
                /* @brief Update all user-visible text to reflect current UI language
240
                 *
241
                 * Updates the text on all widgets on the plug-in to reflect the new
242
                 * language. You should generally use this method to set all the widget
243
                 * text during construction. That ensures that text is not duplicated,
244
                 * and that when this method is called the text of all persistent
245
                 * widgets is correctly changed.
246
                 *
247
                 * This method only needs to affect text in widgets that currently
248
                 * exists (displayed or otherwise).
249
                 */
3193 craig 250
                virtual void languageChange() = 0;
251
 
252
                /// Returns human readable plugin type from plug-in's pluginType
253
                const QString pluginTypeName() const;
254
 
2972 craig 255
        protected:
2975 craig 256
                // Human readable, translated version of last error to occur.
257
                QString m_lastError;
2972 craig 258
};
259
 
260
 
3486 craig 261
/*
262
 * @brief A plug-in that performs a single action
263
 *
264
 * ScActionPlugin describes a plug-in that is used to perform a single well
265
 * defined action. Uses include data import/export, displaying a dialog, or
266
 * doing a single batch task. It is automatically connected to the user
267
 * interface and has simple methods to trigger the plug-in's supported action.
268
 *
269
 * If you need more complex user interface integration, persistent operation,
270
 * etc, you may be better off with ScPersistentPlugin.
271
 */
3207 craig 272
class SCRIBUS_API ScActionPlugin : public ScPlugin
2972 craig 273
{
274
        Q_OBJECT
275
 
276
        public:
277
 
2975 craig 278
                /** @brief ctor
279
                 *
280
                 * @sa ScPlugin::ScPlugin()
281
                 */
3207 craig 282
                ScActionPlugin(PluginType pluginType);
283
 
2975 craig 284
                // Pure virtual dtor - abstract class
3207 craig 285
                virtual ~ScActionPlugin() = 0;
2975 craig 286
 
3193 craig 287
                // Information about actions, to be returned by actionInfo()
288
                struct ActionInfo {
289
                        QString name;  // name of action
290
                        QString text;  // text to display to user
291
                        QString keySequence;
292
                        QString menu;
293
                        QString menuAfterName;
294
                        QIconSet iconSet;
295
                        bool enabledOnStartup;
296
                };
297
 
298
                // Return an ActionInfo instance to the caller
3207 craig 299
                const ActionInfo & actionInfo() const;
3193 craig 300
 
301
        public slots:
2972 craig 302
                /**
303
                 * @brief Run the plug-in's main action.
304
                 *
3486 craig 305
                 * Run the plug-in's default action synchronously, blocking the rest of
306
                 * the application until this method returns.
2972 craig 307
                 *
3486 craig 308
                 * This method should generally call run(..., QIODevice* target) or
309
                 * run(..., QString target) to do the work. This is done by default,
310
                 * with the assumption that the target is a file. The argument is
311
                 * opened as QFile with IO_ReadOnly or IO_WriteOnly mode, depending on
312
                 * plugin type, and passed to run(..., QIODevice*). Override this if
313
                 * you need more flexibility.
2972 craig 314
                 *
315
                 * The optional target argument is a plugin-defined string indicating
316
                 * what the plugin should operate on. It will typically be a filename
317
                 * to import from / export to. Nothing stops a plugin doing funky
318
                 * things like accepting a WebDAV URI, etc, however.
319
                 *
320
                 * Plug-in authors might want to consider implementing this using the
321
                 * DeferredTask subclass used in runAsync, if the plug-in supports it.
322
                 *
3193 craig 323
                 * @param QString target Optional target to operate on (see
324
                 *                above)
325
                 * @returns bool True for success.
2972 craig 326
                 *
327
                 */
3193 craig 328
                virtual bool run(QString target = QString::null);
2972 craig 329
 
330
                /**
331
                 * @brief Run the plugin on a QIODevice
332
                 *
333
                 * This method is essentially the same as the above, except that it
334
                 * accepts a QIODevice* to work with. This will generally be used for
335
                 * file I/O without the plugin having to know or care where from.
336
                 *
337
                 * A plug-in MUST return false if it cannot support this method or upon
338
                 * failure. A plug-in MUST supply a working version of this method if
339
                 * it accepts runWith(..., QString) on a local file, and should
340
                 * generally implement the former using this method.
341
                 *
342
                 * Remember that not all QIODevice*s are seekable, and try to write
343
                 * your code to handle a non-seekable stream.
344
                 */
3193 craig 345
                virtual bool run(QIODevice* target);
2972 craig 346
 
347
                /**
348
                 * @brief Run the plugin asynchronously
349
                 *
350
                 * This call is similar to the one above, but instead of doing all the
351
                 * work in one big batch, it creates an instance of a DeferredTask
352
                 * subclass to keep track of the job, does some setup, and returns
353
                 * immediately. The DeferredTask, a pointer to which is returned, has
354
                 * already been started when this method returns.
355
                 *
356
                 * The caller of this method is responsible for handling the aborted()
357
                 * and finished() signals from the DeferredTask, and (if necessary) for
3486 craig 358
                 * cleaning it up using deleteLater(...) once it has finished. Remember
359
                 * that a DeferredTask is automatically deleted when its parent is, if
360
                 * it hasn't already been deleted. This approach is preferred where
361
                 * possible.
2972 craig 362
                 *
363
                 * See the DeferredTask documentation for details on how it works.
364
                 *
365
                 * If your plugin implementation does not support asynchronous
366
                 * operation, you must return null. This is the default implementation,
367
                 * so simply ignore this method unless you wish to support it. It is
368
                 * recommended that all new plugins support this interface where
369
                 * possible, even if they can only do part of their work progressively.
370
                 *
371
                 * If you implement this, you may want to implement run(...) using the
372
                 * same deferred operation and a modal dialog. That'll permit the event
373
                 * loop to continue running for redraws, permit you to update the
374
                 * progress bar, etc.
375
                 *
376
                 * NOTE: In current Scribus code (August 2005), callers of this method
377
                 * will generally create a modal dialog - possibly with progress meter
378
                 * - then attach signals from the DeferredTask, and exec() the dialog.
379
                 *   A caller is not required to do this, but with the current (August
380
                 *   2005) core code it's the only way to operate safely. This is
381
                 *   likely to change in future and you should avoid relying on it if
382
                 *   at all posssible.
383
                 *
384
                 * If this method is used, the plugin must not be unloaded until all
385
                 * DeferredTask instances have been deleted.
386
                 */
3193 craig 387
                virtual DeferredTask* runAsync(QString target = QString::null);
2972 craig 388
 
389
                /**
390
                 * @brief Run the plugin asynchronously
391
                 *
392
                 * This method is much the same as the above, but takes a QIODevice* as
393
                 * the target. Please see the documentation for run(..., QIODevice*
394
                 * target) and runAsync(..., QString target) for details.
395
                 */
3193 craig 396
                virtual DeferredTask* runAsync(QIODevice* target);
2972 craig 397
 
3193 craig 398
                // Compat kludge ... we store a QString result from any successful
399
                // run(...) call in m_runResult and let callers retrive it here.
400
                // DO NOT USE THIS INTERFACE FOR NEW PLUG-INS; you should
401
                // dynamic_cast<> to the plugin type then call a plug-in specific
402
                // method instead.
3486 craig 403
                /// Obsolete method - do not use this or rely on it in new code.
3193 craig 404
                const QString & runResult() const;
2972 craig 405
 
3189 craig 406
        protected:
3207 craig 407
                // Action info. To be set up by ctor.
3189 craig 408
                ActionInfo m_actionInfo;
3486 craig 409
                // Obsolete - see runResult()
3193 craig 410
                QString m_runResult;
2972 craig 411
};
412
 
3486 craig 413
/**
414
 * @brief A plug-in that is resident for the lifetime of the app
415
 *
416
 * ScPersistentPlugin describes a plugin that is to be kept resident for the
417
 * lifetime of the app (or until unloaded by a request to the plug-in manager).
418
 * Persistent plugins are useful where the plugin author needs to retain state,
419
 * needs more control of how they integrate with the Scribus user interface,
420
 * and/or wants to perform tasks in the background.
421
 *
422
 * Such plug-ins have an init method and a cleanup method; they have
423
 * no "run" method as such. It is up to the plugin to determine how
424
 * best to interfact with the user.
425
 */
2972 craig 426
class SCRIBUS_API ScPersistentPlugin : public ScPlugin
427
{
428
        Q_OBJECT
429
 
430
        public:
431
 
2975 craig 432
                /** @brief ctor
433
                 *
434
                 * @sa ScPlugin::ScPlugin()
435
                 */
3207 craig 436
                ScPersistentPlugin();
2975 craig 437
 
438
                // Pure virtual dtor for abstract class
439
                virtual ~ScPersistentPlugin() = 0;
440
 
2972 craig 441
                /**
442
                 * @brief Initialize the plugin
443
                 *
444
                 * This method must initialize the plugin. It is called at plug-in load
445
                 * time. This method will never be called twice without an intervening
3486 craig 446
                 * cleanupPlugin call, but there is no guarantee the plugin will actually
447
                 * be unloaded between initPlugin() and cleanupPlugin().
2972 craig 448
                 *
449
                 * It will usually instantiate a class and store a pointer to the
450
                 * instance in a static variable of the plugin or a member of its
451
                 * ScPersistentPlugin subclass, letting that class do the work of setup
452
                 * and integration into the app.
453
                 *
2975 craig 454
                 * Note that this is NOT the same as the init function of the plugin. That
455
                 * is always simple and lightweight, intended to just get an instance of this
456
                 * class back to the core app. This function is where any time-consuming or
3486 craig 457
                 * memory expensive init should be triggered, generally by the instantiation
458
                 * of the class that does the real work for the plugin.
2975 craig 459
                 *
3193 craig 460
                 * If this method returns failure, the plugin will be treated as dead and
461
                 * cleanupPlug() will not be called.
462
                 *
2975 craig 463
                 * @returns bool True for success.
2972 craig 464
                 */
3193 craig 465
                virtual bool initPlugin() = 0;
2972 craig 466
 
467
                /**
3486 craig 468
                 * @brief Deactivates the plugin for unloading / program quit
2972 craig 469
                 *
470
                 * This method will be called when the plug-in is about to be unloaded,
471
                 * or if the plug-in manager has been asked to disable the plug-in.
3486 craig 472
                 * This method will never be called unless initPlugin has been called
473
                 * first, but there is no guarantee the plugin will actually be
474
                 * unloaded after this is called, or before initPlugin is called again.
2972 craig 475
                 *
476
                 * @returns bool True for success.
477
                 */
3207 craig 478
                virtual bool cleanupPlugin() = 0;
2972 craig 479
};
480
 
3256 craig 481
// Plug-in API version used to check if we can load the plug-in. This
482
// does *NOT* ensure that the plug-in will be compatible with the internal
483
// Scribus APIs, only that the ScPlugin class and its standard subclasses
484
// will be compatible with what we expect, and that "extern C" functions
485
// we need will be present and work as expected. It's a preprocessor directive
486
// to make sure that it's compiled into each plugin rather than referenced
487
// from the main code.
488
//
489
// The API version is currently simply incremented with each incompatible
490
// change. Future versions may introduce a minor/major scheme if necessary.
491
#define PLUGIN_API_VERSION 0x00000002
492
 
493
 
2972 craig 494
#endif