Subversion Repositories Scribus

Rev

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