summaryrefslogtreecommitdiffstats
path: root/scribus/pluginmanager.h
blob: 67e15003df5a44ff8f08273c2c41d78c657b0338 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
/*
For general Scribus (>=1.3.2) copyright and licensing information please refer
to the COPYING file provided with the program. Following this notice may exist
a copyright and/or license notice that predates the release of Scribus 1.3.2
for which a new license (GPL+exception) is in place.
*/
#ifndef _PLUGIN_MANAGER_
#define _PLUGIN_MANAGER_

#include <QObject>
#include <QString>
#include <QMap>

class QEvent;

#include "scribusapi.h"

class ScribusDoc;
class ScribusMainWindow;
class ScPlugin;
class ScActionPlugin;
class ScPersistentPlugin;
class PrefsContext;

/**
 * \brief PluginManager handles plugin loading, unloading, and running.
		   *
		   * It contains methods and attributes for plugin running and its settings
		   * and returning values.
		   *
		   * Derived from Franz's ScribusMainWindow stuff (petr vanek)
		   *
 */
class SCRIBUS_API PluginManager : public QObject
{

	Q_OBJECT

public:

	PluginManager();
	~PluginManager();

	/*! \brief Static methods for loading, unloading plugins and resolving symbols
	 These methods are platform independent, but each platform uses a different
	 implementation. */
	static void* loadDLL( QString plugin );
	static void* resolveSym( void* plugin, const char* sym );
	static void  unloadDLL( void* plugin );

	/*! \brief Initalization of all plugins. It's called at scribus start.
	 *
	 * Walk through all plugins, try to init them and try to re-load failed
	 * ones then. See initPlugin for more info.
	 * Reload uses a "brute force" method - Repeat until there is something
	 * to load again. It's not elegant I know. But there are no additional
	 * dependancy relations addons (XML config, plugin classes change etc.).
	 */
	void initPlugs();

	/*! \brief Called at after initPlugs to hook the loaded plugin into the GUI.
	 * Run in main window startup
	 */
	bool setupPluginActions(ScribusMainWindow*);

	/*! \brief Called when the last doc is closed
	 */
	void enableOnlyStartupPluginActions(ScribusMainWindow*);
	/*! \brief Called when the last doc is closed
	 */
	void enablePluginActionsForSelection(ScribusMainWindow*);

	/*! \brief Checks if is the plugin is in the plugin map, is loaded, and is enabled.
	 *
	 * \param pluginName name of plugin to get
	 * \param includeDisabled return true if a plugin is loaded but not enabled
	 * \return bool
	 */
	bool DLLexists(QString pluginName, bool includeDisabled = false) const;

	/*! \brief Returns a pointer to the requested plugin, or 0 if not found.
	 *
	 * If includeDisabled is true, plugins that are loaded but not enabled
	 * are returned. If it is false, 0 is returned if the requested plugin
	 * is loaded but not enabled.
	 */
	ScPlugin* getPlugin(const QString & pluginName, bool includeDisabled) const;

	/*! \brief Shutdowns all plugins. Called at scribus quit */
	void cleanupPlugins();

	/** \brief Saves pluginManager preferences */
	void savePreferences();

	/*! \brief Return file extension used for shared libs on this platform */
	static QString platformDllExtension();

	/*! \brief Return file extension used for shared libs on this platform */
	static int platformDllSearchFlags();

	/*! \brief Return a pointer to this instance.
	 \note for now, returns a reference to (*ScMW->pluginManager); should
	 probably be turned into a singleton later. */
	static PluginManager & instance();

	/*! \brief Return the path to the file for the named plugin.
	An invalid plugin name is an error.*/
	const QString getPluginPath(const QString & pluginName) const;

	/*! \brief Whether the given plug-in will be enabled on start-up.
	Usable as an lvalue. An invalid plugin name is an error. */
	bool & enableOnStartup(const QString & pluginName);

	/*! \brief Whether the given plugin is currently enabled */
	bool enabled(const QString & pluginName);

	/** \brief Return a list of plugin names currently known.
	 *
	 * If includeNotLoaded is true, names are returned for plug-ins that are
	 * not loaded (ie we have no ScPlugin instance for them).
	 *
	 * \param includeDisabled  Should the names of plugins that are loaded, but
	 *                         disabled, be returned?
	 * \param inherits         Only return plugins that inherit from this parent
	 *                         (the text name of the type - uses QMetaObject).
	 * \return A list of internal plugin names suitable for use with getPlugin etc.
	 *
	 * \sa getPluginNamesT
	 * \sa getPlugin
	 */
	QStringList pluginNames(bool includeDisabled = false,
									 const char* inherits = 0) const;
	
	virtual void changeEvent(QEvent *e);

public slots:

	void languageChange();

protected:

	/**
	 * \brief PluginData is structure for plugin related informations.
	 * \param pluginFile path to the share library (with name).
	 * \param pluginName internal name of plug-in, used for prefix to dlsym() names
	 * \param pluginDLL reference to plug-in data for dynamic loading
	 * \param plugin is the pointer to the plugin instance
	 * \param enableOnStartup enable or disable plugin at app start-up
	 * \param enabled has the plug-in been set up and activated (gui connected, setup called, etc)?
	 *
	 * Note that there are some constraints on this structure.
	 * enabled == true depends on:
	 *     plugin != 0 which depends on:
	 *         pluginDLL != 0
	 *
	 * In other words, a plugin cannot be enabled unless we have an ScPlugin
	 * instance for it. We can't have an ScPlugin instance for a plugin unless
	 * it's linked.
	 */
	struct PluginData
	{
		QString pluginFile; // Datei;
		QString pluginName;
		void* pluginDLL;
		ScPlugin* plugin;
		bool enableOnStartup;
		bool enabled;
	};

	/*! \brief Init one plugin.
	 * This method loadDLL(...)'s each plug-in, creates a Plugin instance for
	 * them, stores a PluginData for the plugin, sets up the plug-in's
	 * actions, and connects them to any required signals.
	 * It doesn't ask plug-ins to do any time-consuming setup.
	 * It's called by initPlugs.
	\param fileName a filename of the plugin without path
	\retval int 0 init failed, 1 loaded.
	 */
	int initPlugin(const QString fileName);

	/*! \brief Reads available info and fills PluginData structure */
	bool loadPlugin(PluginData & pluginData);

	/*! \brief Determines the plugin name from the file name and returns it. */
	static QString getPluginName(QString fileName);

	/*! \brief Called by loadPlugin to hook the loaded plugin into the GUI,
	call its setup routine, etc. Not responsible for creating
	the ScPlugin instance or loading the plugin. */
	void enablePlugin(PluginData &);

	/*! \brief Called by finalizePlug when shutting down a plug-in. Unhooks
	 the plug-in from the GUI, calls its cleanup routine, etc.
	 DOES NOT destroy the ScPlugin instance or unload the plugin. */
	void disablePlugin(PluginData & pda);

	/*! \brief Runs plugin's languageChange() method, and returns main menu item text if one exists */
	QString callDLLForNewLanguage(const PluginData & pluginData);

	/*! \brief Shuts down one plug-in. The DLL may not be unloaded, but
	 *         it is cleaned up and its ScPlugin instance is destroyed.
	 *         The plug-in is marked unloaded in the map.
	 *  \param pda plugin data
	 */
	void finalizePlug(PluginData & pda);

	/** \brief Configuration structure */
	PrefsContext* prefs;

	/*! \brief Mapping of plugin names to plugin info structures. */
	typedef QMap<QString,PluginData> PluginMap;

	/*! \brief Plugin mapping.
	 * Each plugin has its record key() -> PluginData
	 */
	PluginMap pluginMap;
};

#endif