Plugin.h 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. /*
  2. * Plugin.h - class plugin, the base-class and generic interface for all plugins
  3. *
  4. * Copyright (c) 2005-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
  5. *
  6. * This file is part of LMMS - https://lmms.io
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public
  10. * License as published by the Free Software Foundation; either
  11. * version 2 of the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public
  19. * License along with this program (see COPYING); if not, write to the
  20. * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  21. * Boston, MA 02110-1301 USA.
  22. *
  23. */
  24. #ifndef PLUGIN_H
  25. #define PLUGIN_H
  26. #include <QtCore/QStringList>
  27. #include <QtCore/QMap>
  28. #include <QtXml/QDomDocument>
  29. #include "JournallingObject.h"
  30. #include "Model.h"
  31. #include "MemoryManager.h"
  32. class QWidget;
  33. class PixmapLoader;
  34. class PluginView;
  35. class AutomatableModel;
  36. /**
  37. Abstract representation of a plugin
  38. Such a plugin can be an Instrument, Effect, Tool plugin etc.
  39. Plugins have descriptors, containing meta info, which is used especially
  40. by PluginFactory and friends.
  41. There are also Plugin keys (class Key, confusingly under
  42. SubPluginFeatures), which contain pointers to the plugin descriptor.
  43. Some plugins have sub plugins, e.g. there is one CALF Plugin and for
  44. each CALF effect, there is a CALF sub plugin. For those plugins, there
  45. are keys for each sub plugin. These keys also link to the superior
  46. Plugin::Descriptor. Additionally, they contain attributes that help the
  47. superior Plugin saving them and recognizing them when loading.
  48. In case of sub plugins, the Descriptor has SubPluginFeatures. Those
  49. are a bit like values to the sub plugins' keys (in terms of a key-value-
  50. map).
  51. */
  52. class LMMS_EXPORT Plugin : public Model, public JournallingObject
  53. {
  54. MM_OPERATORS
  55. Q_OBJECT
  56. public:
  57. enum PluginTypes
  58. {
  59. Instrument, // instrument being used in channel-track
  60. Effect, // effect-plugin for effect-board
  61. ImportFilter, // filter for importing a file
  62. ExportFilter, // filter for exporting a file
  63. Tool, // additional tool (level-meter etc)
  64. Library, // simple library holding a code-base for
  65. // several other plugins (e.g. VST-support)
  66. Other,
  67. Undefined = 255
  68. } ;
  69. //! Descriptor holds information about a plugin - every external plugin
  70. //! has to instantiate such a Descriptor in an extern "C"-section so that
  71. //! the plugin-loader is able to access information about the plugin
  72. struct Descriptor
  73. {
  74. const char * name;
  75. const char * displayName;
  76. const char * description;
  77. const char * author;
  78. int version;
  79. PluginTypes type;
  80. const PixmapLoader * logo;
  81. const char * supportedFileTypes; //!< csv list of extensions
  82. inline bool supportsFileType( const QString& extension ) const
  83. {
  84. return QString( supportedFileTypes ).split( QChar( ',' ) ).contains( extension );
  85. }
  86. /**
  87. Access to non-key-data of a sub plugin
  88. If you consider sub plugin keys as keys in a
  89. key-value-map, this is the lookup for the corresponding
  90. values. In order to have flexibility between different
  91. plugin APIs, this is rather an array of fixed data,
  92. but a bunch of virtual functions taking the key and
  93. returning some values (or modifying objects of other
  94. classes).
  95. */
  96. class LMMS_EXPORT SubPluginFeatures
  97. {
  98. public:
  99. /**
  100. Key reference a Plugin::Descriptor, and,
  101. if the plugin has sub plugins, also reference
  102. its sub plugin (using the attributes).
  103. When keys are saved, those attributes are
  104. written to XML in order to find the right sub
  105. plugin when realoading.
  106. @note Any data that is not required to reference
  107. the right Plugin or sub plugin should
  108. not be here (but rather in
  109. SubPluginFeatures, which are like values
  110. in a key-value map).
  111. */
  112. struct Key
  113. {
  114. typedef QMap<QString, QString> AttributeMap;
  115. inline Key( const Plugin::Descriptor * desc = nullptr,
  116. const QString & name = QString(),
  117. const AttributeMap & am = AttributeMap()
  118. )
  119. :
  120. desc( desc ),
  121. name( name ),
  122. attributes( am )
  123. {
  124. }
  125. Key( const QDomElement & key );
  126. QDomElement saveXML( QDomDocument & doc ) const;
  127. inline bool isValid() const
  128. {
  129. return desc != nullptr;
  130. }
  131. //! Key to subplugin: reference to parent descriptor
  132. //! Key to plugin: reference to its descriptor
  133. const Plugin::Descriptor* desc;
  134. //! Descriptive name like "Calf Phaser".
  135. //! Not required for key lookup and not saved
  136. //! only used sometimes to temporary store descriptive names
  137. //! @todo This is a bug, there should be a function
  138. //! in SubPluginFeatures (to get the name) instead
  139. QString name;
  140. //! Attributes that make up the key and identify
  141. //! the sub plugin. They are being loaded and saved
  142. AttributeMap attributes;
  143. // helper functions to retrieve data that is
  144. // not part of the key, but mapped via desc->subPluginFeatures
  145. QString additionalFileExtensions() const;
  146. QString displayName() const;
  147. QString description() const;
  148. const PixmapLoader* logo() const;
  149. } ;
  150. typedef QList<Key> KeyList;
  151. SubPluginFeatures( Plugin::PluginTypes type ) :
  152. m_type( type )
  153. {
  154. }
  155. virtual ~SubPluginFeatures()
  156. {
  157. }
  158. virtual void fillDescriptionWidget( QWidget *, const Key * ) const
  159. {
  160. }
  161. //! While PluginFactory only collects the plugins,
  162. //! this function is used by widgets like EffectSelectDialog
  163. //! to find all possible sub plugins
  164. virtual void listSubPluginKeys( const Plugin::Descriptor *, KeyList & ) const
  165. {
  166. }
  167. private:
  168. // You can add values mapped by "Key" below
  169. // The defaults are sane, i.e. redirect to sub plugin's
  170. // supererior descriptor
  171. virtual QString additionalFileExtensions(const Key&) const
  172. {
  173. return QString();
  174. }
  175. virtual QString displayName(const Key& k) const
  176. {
  177. return k.isValid() ? k.name : QString();
  178. }
  179. virtual QString description(const Key& k) const
  180. {
  181. return k.isValid() ? k.desc->description : QString();
  182. }
  183. virtual const PixmapLoader* logo(const Key& k) const
  184. {
  185. Q_ASSERT(k.desc);
  186. return k.desc->logo;
  187. }
  188. protected:
  189. const Plugin::PluginTypes m_type;
  190. } ;
  191. SubPluginFeatures * subPluginFeatures;
  192. } ;
  193. // typedef a list so we can easily work with list of plugin descriptors
  194. typedef QList<Descriptor*> DescriptorList;
  195. //! Constructor of a plugin
  196. //! @param key Sub plugins must pass a key here, optional otherwise.
  197. //! See the key() function
  198. Plugin(const Descriptor * descriptor, Model * parent,
  199. const Descriptor::SubPluginFeatures::Key *key = nullptr);
  200. virtual ~Plugin();
  201. //! Return display-name out of sub plugin or descriptor
  202. QString displayName() const override;
  203. //! Return logo out of sub plugin or descriptor
  204. const PixmapLoader *logo() const;
  205. //! Return plugin type
  206. inline PluginTypes type( void ) const
  207. {
  208. return m_descriptor->type;
  209. }
  210. //! Return plugin Descriptor
  211. inline const Descriptor * descriptor() const
  212. {
  213. return m_descriptor;
  214. }
  215. //! Return the key referencing this plugin. If the Plugin has no
  216. //! sub plugin features, the key is pretty useless. If it has,
  217. //! this key will also contain the sub plugin attributes, and will be
  218. //! a key to those SubPluginFeatures.
  219. inline const Descriptor::SubPluginFeatures::Key & key() const
  220. {
  221. return m_key;
  222. }
  223. //! Can be called if a file matching supportedFileTypes should be
  224. //! loaded/processed with the help of this plugin
  225. virtual void loadFile( const QString & file );
  226. //! Called if external source needs to change something but we cannot
  227. //! reference the class header. Should return null if not key not found.
  228. virtual AutomatableModel* childModel( const QString & modelName );
  229. //! Overload if the argument passed to the plugin is a subPluginKey
  230. //! If you can not pass the key and are aware that it's stored in
  231. //! Engine::pickDndPluginKey(), use this function, too
  232. static Plugin * instantiateWithKey(const QString& pluginName, Model * parent,
  233. const Descriptor::SubPluginFeatures::Key *key,
  234. bool keyFromDnd = false);
  235. //! Return an instance of a plugin whose name matches to given one
  236. //! if specified plugin couldn't be loaded, it creates a dummy-plugin
  237. //! @param data Anything the plugin expects. If this is a pointer to a sub plugin key,
  238. //! use instantiateWithKey instead
  239. static Plugin * instantiate(const QString& pluginName, Model * parent, void *data);
  240. //! Create a view for the model
  241. PluginView * createView( QWidget * parent );
  242. protected:
  243. //! Create a view for the model
  244. virtual PluginView* instantiateView( QWidget * ) = 0;
  245. void collectErrorForUI( QString errMsg );
  246. private:
  247. const Descriptor * m_descriptor;
  248. Descriptor::SubPluginFeatures::Key m_key;
  249. // pointer to instantiation-function in plugin
  250. typedef Plugin * ( * InstantiationHook )( Model * , void * );
  251. } ;
  252. #endif