1 /*************************************************************************** 2 PluginManager.h - manager class for kwave's plugins 3 ------------------- 4 begin : Sun Aug 27 2000 5 copyright : (C) 2000 by Thomas Eschenbacher 6 email : Thomas.Eschenbacher@gmx.de 7 ***************************************************************************/ 8 9 /*************************************************************************** 10 * * 11 * This program is free software; you can redistribute it and/or modify * 12 * it under the terms of the GNU General Public License as published by * 13 * the Free Software Foundation; either version 2 of the License, or * 14 * (at your option) any later version. * 15 * * 16 ***************************************************************************/ 17 18 #ifndef PLUGIN_MANAGER_H 19 #define PLUGIN_MANAGER_H 20 21 #include "config.h" 22 23 #include <QtGlobal> 24 #include <QList> 25 #include <QListIterator> 26 #include <QMap> 27 #include <QMutableListIterator> 28 #include <QObject> 29 #include <QPointer> 30 #include <QWidget> 31 32 #include "libkwave/InsertMode.h" 33 #include "libkwave/Sample.h" 34 #include "libkwave/ViewManager.h" 35 36 class QLibrary; 37 class QString; 38 class QStringList; 39 40 class KPluginFactory; 41 42 namespace Kwave 43 { 44 class PlaybackController; 45 class PlaybackDeviceFactory; 46 class PlayBackParam; 47 class Plugin; 48 class PluginContext; 49 class SampleSink; 50 class SignalManager; 51 class Writer; 52 53 /** 54 * Manages the loading, initializing, starting, running and closing 55 * of the plugins of kwave. Each instance of a TopWidget creates a 56 * new instance of the PluginManager to be independent from other 57 * toplevel widgets. 58 */ 59 class Q_DECL_EXPORT PluginManager: public QObject 60 { 61 Q_OBJECT 62 63 public: 64 65 /** 66 * Constructor. 67 * @param parent reference to the toplevel widget (our parent) 68 * @param signal_manager reference to a SignalManager 69 */ 70 PluginManager(QWidget *parent, Kwave::SignalManager &signal_manager); 71 72 /** 73 * Default destructor 74 */ 75 virtual ~PluginManager(); 76 77 /** 78 * Tries to load all plugins. If a pesistent plugin is found, 79 * it will stay loaded in memory, all other (non-persistent) 80 * plugins will be unloaded afterwards. This also filters out 81 * all plugins that do not correctly load. 82 * @internal used once by each toplevel window at startup 83 * @return true if at least one plugin was loaded, false if none 84 */ 85 bool loadAllPlugins(); 86 87 /** 88 * Stops all currently running plugins 89 */ 90 void stopAllPlugins(); 91 92 /** 93 * Executes a plugin in the context of a given parent widget. 94 * @param name the name of the plugin 95 * @param params pointer to a parameter list 96 * or null if defaults should be used 97 * @return zero on success or negative error code 98 */ 99 int executePlugin(const QString &name, QStringList *params); 100 101 /** 102 * Returns true if there is no running plugin that blocks 103 * a "close" operation. 104 */ 105 bool canClose(); 106 107 /** Returns true if at least one plugin is currently running */ 108 bool onePluginRunning(); 109 110 /** 111 * Waits until all currently running actions have completed. 112 */ 113 void sync(); 114 115 /** 116 * Loads a plugin, calls it's setup function and then closes 117 * it again. The parameters will be loaded before the setup 118 * and saved if the setup has not been aborted. 119 * @param name the name of the plugin 120 * @param params pointer to a parameter list 121 * or null if defaults should be used 122 * @retval 0 if succeeded and accepted 123 * @retval 1 if canceled 124 * @retval -1 if failed 125 */ 126 int setupPlugin(const QString &name, const QStringList ¶ms); 127 128 /** 129 * loads a plugin's default parameters from the user's 130 * configuration file. If nothing is found in the config file, 131 * the return value will be 0. If the current version number of 132 * the plugin does not match the version number in the config file, 133 * the return value will also be 0. 134 * @param name the name of the plugin 135 * @return list of strings 136 */ 137 QStringList defaultParams(const QString &name); 138 139 /** 140 * Returns the length of the current signal in samples. 141 * If no signal is present the return value will be 0. 142 */ 143 sample_index_t signalLength(); 144 145 /** 146 * Returns the current sample rate in samples per second. 147 * If no signal is present the return value will be 0. 148 */ 149 double signalRate(); 150 151 /** 152 * Returns the start of the selection. If nothing is currently 153 * selected this will be the first sample (0). 154 */ 155 sample_index_t selectionStart(); 156 157 /** 158 * Returns the end of the selection. If nothing is currently 159 * selected this will be the last sample (length-1). 160 */ 161 sample_index_t selectionEnd(); 162 163 /** 164 * Sets the current start and length of the selection to new values. 165 * @param offset index of the first sample 166 * @param length number of samples 167 */ 168 void selectRange(sample_index_t offset, sample_index_t length); 169 170 /** 171 * Opens a Kwave::MultiTrackSink for playback purposes. 172 * @param tracks number of tracks 173 * @param playback_params points to a class that holds all playback 174 * parameters. If null, the default parameters 175 * of the current signal will be used 176 * @return a multitrack sink that receives the playback stream 177 */ 178 Kwave::SampleSink *openMultiTrackPlayback( 179 unsigned int tracks, 180 const Kwave::PlayBackParam *playback_params = Q_NULLPTR 181 ); 182 183 /** 184 * Returns a reference to the current playback controller. This is 185 * only needed for plugins doing playback. 186 */ 187 Kwave::PlaybackController &playbackController(); 188 189 /** 190 * assigns a new parent widget, to be used for messages 191 * @param new_parent pointer to a QWidget 192 */ setParentWidget(QWidget * new_parent)193 inline void setParentWidget(QWidget *new_parent) { 194 m_parent_widget = new_parent; 195 } 196 197 /** returns a pointer to the parent widget */ parentWidget()198 inline QPointer<QWidget> parentWidget() 199 { 200 return m_parent_widget; 201 } 202 203 /** returns a reference to our signal manager */ signalManager()204 inline Kwave::SignalManager &signalManager() 205 { 206 return m_signal_manager; 207 } 208 209 /** 210 * Insert a new signal view into this widget (or the upper/lower 211 * dock area. 212 * @param view the signal view, must not be a null pointer 213 * @param controls a widget with controls, optionally, can be null 214 */ 215 void insertView(Kwave::SignalView *view, QWidget *controls); 216 217 /** 218 * registers a view manager, must only be called once! 219 */ 220 void registerViewManager(Kwave::ViewManager *view_manager); 221 222 /** 223 * Enqueues a command that will be processed threadsafe in the X11 224 * thread. 225 */ 226 void enqueueCommand(const QString &command); 227 228 /** 229 * Searches the standard KDE data directories for plugins (through 230 * the KDE's standard search algorithm) and creates a map of 231 * plugin names and file names. First it collects a list of 232 * filenames and then filters it to sort out invalid entries. 233 */ 234 void searchPluginModules(); 235 236 /** structure with information about a plugin */ 237 typedef struct { 238 QString m_name; /**< name of the plugin */ 239 QString m_author; /**< name of the author */ 240 QString m_description; /**< short description */ 241 QString m_version; /**< settings version */ 242 KPluginFactory *m_factory; /**< plugin factory */ 243 int m_use_count; /**< usage counter */ 244 } PluginModule; 245 246 /** 247 * returns a list with info of all known plugins 248 * @todo rename to pluginModuleList 249 */ 250 const QList<PluginModule> pluginInfoList() const; 251 252 /** 253 * Migrate a plugin to the currently active file context (which 254 * might be different from the one that is currently executing 255 * the plugin). The plugin will be removed from our lists and 256 * inserted into the currently active plugin manager instance. 257 * @param plugin the plugin to migrate 258 */ 259 void migratePluginToActiveContext(Kwave::Plugin *plugin); 260 261 /** Let this instance be the active one */ setActive()262 void setActive() { m_active_instance = this; } 263 264 signals: 265 266 /** 267 * Forwards commands to the parent TopWidget execute a command 268 */ 269 void sigCommand(const QString &command); 270 271 /** 272 * Informs all plugins and client windows that we close down 273 */ 274 void sigClosed(); 275 276 /** 277 * Informs the plugins that the name of the signal has changed. 278 * This might be used to update the caption of a window. 279 */ 280 void sigSignalNameChanged(const QString &name); 281 282 /** 283 * informs about progress, e.g. for showing a message in 284 * a splash screen or status bar. 285 */ 286 void sigProgress(const QString &message); 287 288 public slots: 289 290 /** 291 * Notify all plugins that the signal or file is to be closed 292 */ 293 void signalClosed(); 294 295 /** 296 * Called if the name of the current signal has changed. This will be 297 * forwarded to all plugins by emitting the signal sigSignalNameChanged. 298 * @see sigSignalNameChanged() 299 */ 300 void setSignalName(const QString &name); 301 302 private slots: 303 304 /** 305 * Will be connected to the plugin's "closed" signal. 306 * @param p pointer to the plugin to be closed 307 */ 308 void pluginClosed(Kwave::Plugin *p); 309 310 /** called when a plugin has started (running) it's worker thread */ 311 void pluginStarted(Kwave::Plugin *p); 312 313 /** called when a plugin has finished it's worker thread */ 314 void pluginDone(Kwave::Plugin *p); 315 316 private: 317 318 /** typedef: QPointer to a Kwave::Plugin */ 319 typedef QPointer<Kwave::Plugin> KwavePluginPointer; 320 321 /** typedef: list of pointers to kwave plugins */ 322 typedef QList< KwavePluginPointer > PluginList; 323 324 /** typedef: mutable iterator for PluginList */ 325 typedef QMutableListIterator< KwavePluginPointer > 326 PluginListMutableIterator; 327 328 /** typedef: const iterator for PluginList */ 329 typedef QListIterator< KwavePluginPointer > 330 PluginListIterator; 331 332 private: 333 334 /** 335 * Creates an instance of a plugin. 336 * @param name the name of the plugin (filename) 337 * @return pointer to the loaded plugin or zero if the 338 * plugin was not found or invalid 339 */ 340 Kwave::Plugin *createPluginInstance(const QString &name); 341 342 /** 343 * Saves a plugin's default parameters to the user's configuration 344 * file. The whole section in the configuration file will be deleted 345 * before saving the new settings in order to wipe out invalid 346 * entries and settings that belong to an older version. 347 * @param name the name of the plugin 348 * @param params a list of configuration strings 349 */ 350 void savePluginDefaults(const QString &name, 351 QStringList ¶ms); 352 353 /** connects all signals of and for a plugin */ 354 void connectPlugin(Kwave::Plugin *plugin); 355 356 /** connects all signals from and to a plugin */ 357 void disconnectPlugin(Kwave::Plugin *plugin); 358 359 private: 360 361 /** pointer to the currently active instance */ 362 static Kwave::PluginManager *m_active_instance; 363 364 /** 365 * map with plugin information: key = short name of the plugin, 366 * data = plugin info (description, author, version etc...) 367 */ 368 static QMap<QString, PluginModule> m_plugin_modules; 369 370 /** list of all plugins that were loaded by this instance */ 371 PluginList m_plugin_instances; 372 373 /** list of currently running plugins */ 374 PluginList m_running_plugins; 375 376 /** reference to our parent toplevel widget */ 377 QPointer<QWidget> m_parent_widget; 378 379 /** reference to our signal manager */ 380 Kwave::SignalManager &m_signal_manager; 381 382 /** interface for registering a SignalView */ 383 ViewManager *m_view_manager; 384 385 }; 386 } 387 388 #endif /* PLUGIN_MANAGER_H */ 389 390 //*************************************************************************** 391 //*************************************************************************** 392