Subversion Repositories Scribus

Rev

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