Allow sub plugins for instruments aswell
This allows sub plugins for instruments. They had been working for effects only, previously. This is a requirement for many plugin APIs, like Lv2.
This commit is contained in:
@@ -148,11 +148,6 @@ public:
|
||||
m_noRun = _state;
|
||||
}
|
||||
|
||||
inline const Descriptor::SubPluginFeatures::Key & key() const
|
||||
{
|
||||
return m_key;
|
||||
}
|
||||
|
||||
EffectChain * effectChain() const
|
||||
{
|
||||
return m_parent;
|
||||
@@ -201,8 +196,6 @@ private:
|
||||
sampleFrame * _dst_buf, sample_rate_t _dst_sr,
|
||||
const f_cnt_t _frames );
|
||||
|
||||
Descriptor::SubPluginFeatures::Key m_key;
|
||||
|
||||
ch_cnt_t m_processors;
|
||||
|
||||
bool m_okay;
|
||||
|
||||
@@ -111,6 +111,9 @@ public:
|
||||
return s_instanceOfMe;
|
||||
}
|
||||
|
||||
static void setDndPluginKey(void* newKey);
|
||||
static void* pickDndPluginKey();
|
||||
|
||||
signals:
|
||||
void initProgress(const QString &msg);
|
||||
|
||||
@@ -137,6 +140,7 @@ private:
|
||||
static DummyTrackContainer * s_dummyTC;
|
||||
|
||||
static Ladspa2LMMS * s_ladspaManager;
|
||||
static void* s_dndPluginKey;
|
||||
|
||||
// even though most methods are static, an instance is needed for Qt slots/signals
|
||||
static LmmsCore * s_instanceOfMe;
|
||||
|
||||
@@ -55,8 +55,9 @@ public:
|
||||
|
||||
Q_DECLARE_FLAGS(Flags, Flag);
|
||||
|
||||
Instrument( InstrumentTrack * _instrument_track,
|
||||
const Descriptor * _descriptor );
|
||||
Instrument(InstrumentTrack * _instrument_track,
|
||||
const Descriptor * _descriptor,
|
||||
const Descriptor::SubPluginFeatures::Key * key = nullptr);
|
||||
virtual ~Instrument() = default;
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
@@ -115,10 +116,12 @@ public:
|
||||
// provided functions:
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
// instantiate instrument-plugin with given name or return NULL
|
||||
// on failure
|
||||
static Instrument * instantiate( const QString & _plugin_name,
|
||||
InstrumentTrack * _instrument_track );
|
||||
//! instantiate instrument-plugin with given name or return NULL
|
||||
//! on failure
|
||||
static Instrument * instantiate(const QString & _plugin_name,
|
||||
InstrumentTrack * _instrument_track,
|
||||
const Plugin::Descriptor::SubPluginFeatures::Key* key,
|
||||
bool keyFromDnd = false);
|
||||
|
||||
virtual bool isFromTrack( const Track * _track ) const;
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "Piano.h"
|
||||
#include "PianoView.h"
|
||||
#include "Pitch.h"
|
||||
#include "Plugin.h"
|
||||
#include "Track.h"
|
||||
|
||||
|
||||
@@ -147,7 +148,9 @@ public:
|
||||
|
||||
|
||||
// load instrument whose name matches given one
|
||||
Instrument * loadInstrument( const QString & _instrument_name );
|
||||
Instrument * loadInstrument(const QString & _instrument_name,
|
||||
const Plugin::Descriptor::SubPluginFeatures::Key* key = nullptr,
|
||||
bool keyFromDnd = false);
|
||||
|
||||
AudioPort * audioPort()
|
||||
{
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
#include "LadspaManager.h"
|
||||
|
||||
|
||||
//! Class responsible for sorting found plugins (by LadspaManager)
|
||||
//! into categories
|
||||
class LMMS_EXPORT Ladspa2LMMS : public LadspaManager
|
||||
{
|
||||
public:
|
||||
|
||||
167
include/Plugin.h
167
include/Plugin.h
@@ -40,7 +40,27 @@ class PixmapLoader;
|
||||
class PluginView;
|
||||
class AutomatableModel;
|
||||
|
||||
/**
|
||||
Abstract representation of a plugin
|
||||
|
||||
Such a plugin can be an Instrument, Effect, Tool plugin etc.
|
||||
|
||||
Plugins have descriptors, containing meta info, which is used especially
|
||||
by PluginFactory and friends.
|
||||
|
||||
There are also Plugin keys (class Key, confusingly under
|
||||
SubPluginFeatures), which contain pointers to the plugin descriptor.
|
||||
|
||||
Some plugins have sub plugins, e.g. there is one CALF Plugin and for
|
||||
each CALF effect, there is a CALF sub plugin. For those plugins, there
|
||||
are keys for each sub plugin. These keys also link to the superior
|
||||
Plugin::Descriptor. Additionally, they contain attributes that help the
|
||||
superior Plugin saving them and recognizing them when loading.
|
||||
|
||||
In case of sub plugins, the Descriptor has SubPluginFeatures. Those
|
||||
are a bit like values to the sub plugins' keys (in terms of a key-value-
|
||||
map).
|
||||
*/
|
||||
class LMMS_EXPORT Plugin : public Model, public JournallingObject
|
||||
{
|
||||
MM_OPERATORS
|
||||
@@ -59,9 +79,9 @@ public:
|
||||
Undefined = 255
|
||||
} ;
|
||||
|
||||
// descriptor holds information about a plugin - every external plugin
|
||||
// has to instantiate such a descriptor in an extern "C"-section so that
|
||||
// the plugin-loader is able to access information about the plugin
|
||||
//! Descriptor holds information about a plugin - every external plugin
|
||||
//! has to instantiate such a Descriptor in an extern "C"-section so that
|
||||
//! the plugin-loader is able to access information about the plugin
|
||||
struct Descriptor
|
||||
{
|
||||
const char * name;
|
||||
@@ -71,23 +91,49 @@ public:
|
||||
int version;
|
||||
PluginTypes type;
|
||||
const PixmapLoader * logo;
|
||||
const char * supportedFileTypes;
|
||||
const char * supportedFileTypes; //!< csv list of extensions
|
||||
|
||||
inline bool supportsFileType( const QString& extension ) const
|
||||
{
|
||||
return QString( supportedFileTypes ).split( QChar( ',' ) ).contains( extension );
|
||||
}
|
||||
|
||||
/**
|
||||
Access to non-key-data of a sub plugin
|
||||
|
||||
If you consider sub plugin keys as keys in a
|
||||
key-value-map, this is the lookup for the corresponding
|
||||
values. In order to have flexibility between different
|
||||
plugin APIs, this is rather an array of fixed data,
|
||||
but a bunch of virtual functions taking the key and
|
||||
returning some values (or modifying objects of other
|
||||
classes).
|
||||
*/
|
||||
class LMMS_EXPORT SubPluginFeatures
|
||||
{
|
||||
public:
|
||||
/**
|
||||
Key reference a Plugin::Descriptor, and,
|
||||
if the plugin has sub plugins, also reference
|
||||
its sub plugin (using the attributes).
|
||||
When keys are saved, those attributes are
|
||||
written to XML in order to find the right sub
|
||||
plugin when realoading.
|
||||
|
||||
@note Any data that is not required to reference
|
||||
the right Plugin or sub plugin should
|
||||
not be here (but rather in
|
||||
SubPluginFeatures, which are like values
|
||||
in a key-value map).
|
||||
*/
|
||||
struct Key
|
||||
{
|
||||
typedef QMap<QString, QString> AttributeMap;
|
||||
|
||||
inline Key( const Plugin::Descriptor * desc = NULL,
|
||||
const QString & name = QString(),
|
||||
const AttributeMap & am = AttributeMap() )
|
||||
const QString & name = QString(),
|
||||
const AttributeMap & am = AttributeMap()
|
||||
)
|
||||
:
|
||||
desc( desc ),
|
||||
name( name ),
|
||||
@@ -101,12 +147,28 @@ public:
|
||||
|
||||
inline bool isValid() const
|
||||
{
|
||||
return desc != NULL && name.isNull() == false;
|
||||
return desc != nullptr;
|
||||
}
|
||||
|
||||
//! Key to subplugin: reference to parent descriptor
|
||||
//! Key to plugin: reference to its descriptor
|
||||
const Plugin::Descriptor* desc;
|
||||
//! Descriptive name like "Calf Phaser".
|
||||
//! Not required for key lookup and not saved
|
||||
//! only used sometimes to temporary store descriptive names
|
||||
//! @todo This is a bug, there should be a function
|
||||
//! in SubPluginFeatures (to get the name) instead
|
||||
QString name;
|
||||
//! Attributes that make up the key and identify
|
||||
//! the sub plugin. They are being loaded and saved
|
||||
AttributeMap attributes;
|
||||
|
||||
// helper functions to retrieve data that is
|
||||
// not part of the key, but mapped via desc->subPluginFeatures
|
||||
QString additionalFileExtensions() const;
|
||||
QString displayName() const;
|
||||
QString description() const;
|
||||
const PixmapLoader* logo() const;
|
||||
} ;
|
||||
|
||||
typedef QList<Key> KeyList;
|
||||
@@ -125,11 +187,40 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
//! While PluginFactory only collects the plugins,
|
||||
//! this function is used by widgets like EffectSelectDialog
|
||||
//! to find all possible sub plugins
|
||||
virtual void listSubPluginKeys( const Plugin::Descriptor *, KeyList & ) const
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
// You can add values mapped by "Key" below
|
||||
// The defaults are sane, i.e. redirect to sub plugin's
|
||||
// supererior descriptor
|
||||
|
||||
virtual QString additionalFileExtensions(const Key&) const
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
|
||||
virtual QString displayName(const Key& k) const
|
||||
{
|
||||
return k.isValid() ? k.name : QString();
|
||||
}
|
||||
|
||||
virtual QString description(const Key& k) const
|
||||
{
|
||||
return k.isValid() ? k.desc->description : QString();
|
||||
}
|
||||
|
||||
virtual const PixmapLoader* logo(const Key& k) const
|
||||
{
|
||||
Q_ASSERT(k.desc);
|
||||
return k.desc->logo;
|
||||
}
|
||||
|
||||
protected:
|
||||
const Plugin::PluginTypes m_type;
|
||||
} ;
|
||||
@@ -140,48 +231,66 @@ public:
|
||||
// typedef a list so we can easily work with list of plugin descriptors
|
||||
typedef QList<Descriptor*> DescriptorList;
|
||||
|
||||
// contructor of a plugin
|
||||
Plugin( const Descriptor * descriptor, Model * parent );
|
||||
//! Constructor of a plugin
|
||||
//! @param key Sub plugins must pass a key here, optional otherwise.
|
||||
//! See the key() function
|
||||
Plugin(const Descriptor * descriptor, Model * parent,
|
||||
const Descriptor::SubPluginFeatures::Key *key = nullptr);
|
||||
virtual ~Plugin();
|
||||
|
||||
// returns display-name out of descriptor
|
||||
virtual QString displayName() const
|
||||
{
|
||||
return Model::displayName().isEmpty()
|
||||
? m_descriptor->displayName
|
||||
: Model::displayName();
|
||||
}
|
||||
//! Return display-name out of sub plugin or descriptor
|
||||
virtual QString displayName() const;
|
||||
|
||||
// return plugin-type
|
||||
//! Return logo out of sub plugin or descriptor
|
||||
const PixmapLoader *logo() const;
|
||||
|
||||
//! Return plugin type
|
||||
inline PluginTypes type( void ) const
|
||||
{
|
||||
return m_descriptor->type;
|
||||
}
|
||||
|
||||
// return plugin-descriptor for further information
|
||||
//! Return plugin Descriptor
|
||||
inline const Descriptor * descriptor() const
|
||||
{
|
||||
return m_descriptor;
|
||||
}
|
||||
|
||||
// can be called if a file matching supportedFileTypes should be
|
||||
// loaded/processed with the help of this plugin
|
||||
//! Return the key referencing this plugin. If the Plugin has no
|
||||
//! sub plugin features, the key is pretty useless. If it has,
|
||||
//! this key will also contain the sub plugin attributes, and will be
|
||||
//! a key to those SubPluginFeatures.
|
||||
inline const Descriptor::SubPluginFeatures::Key & key() const
|
||||
{
|
||||
return m_key;
|
||||
}
|
||||
|
||||
//! Can be called if a file matching supportedFileTypes should be
|
||||
//! loaded/processed with the help of this plugin
|
||||
virtual void loadFile( const QString & file );
|
||||
|
||||
// Called if external source needs to change something but we cannot
|
||||
// reference the class header. Should return null if not key not found.
|
||||
//! Called if external source needs to change something but we cannot
|
||||
//! reference the class header. Should return null if not key not found.
|
||||
virtual AutomatableModel* childModel( const QString & modelName );
|
||||
|
||||
// returns an instance of a plugin whose name matches to given one
|
||||
// if specified plugin couldn't be loaded, it creates a dummy-plugin
|
||||
static Plugin * instantiate( const QString& pluginName, Model * parent, void * data );
|
||||
//! Overload if the argument passed to the plugin is a subPluginKey
|
||||
//! If you can not pass the key and are aware that it's stored in
|
||||
//! Engine::pickDndPluginKey(), use this function, too
|
||||
static Plugin * instantiateWithKey(const QString& pluginName, Model * parent,
|
||||
const Descriptor::SubPluginFeatures::Key *key,
|
||||
bool keyFromDnd = false);
|
||||
|
||||
// create a view for the model
|
||||
//! Return an instance of a plugin whose name matches to given one
|
||||
//! if specified plugin couldn't be loaded, it creates a dummy-plugin
|
||||
//! @param data Anything the plugin expects. If this is a pointer to a sub plugin key,
|
||||
//! use instantiateWithKey instead
|
||||
static Plugin * instantiate(const QString& pluginName, Model * parent, void *data);
|
||||
|
||||
//! Create a view for the model
|
||||
PluginView * createView( QWidget * parent );
|
||||
|
||||
|
||||
protected:
|
||||
// create a view for the model
|
||||
//! Create a view for the model
|
||||
virtual PluginView* instantiateView( QWidget * ) = 0;
|
||||
void collectErrorForUI( QString errMsg );
|
||||
|
||||
@@ -189,6 +298,8 @@ protected:
|
||||
private:
|
||||
const Descriptor * m_descriptor;
|
||||
|
||||
Descriptor::SubPluginFeatures::Key m_key;
|
||||
|
||||
// pointer to instantiation-function in plugin
|
||||
typedef Plugin * ( * InstantiationHook )( Model * , void * );
|
||||
|
||||
|
||||
@@ -60,7 +60,8 @@ class PluginDescWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
PluginDescWidget( const Plugin::Descriptor & _pd, QWidget * _parent );
|
||||
typedef Plugin::Descriptor::SubPluginFeatures::Key PluginKey;
|
||||
PluginDescWidget( const PluginKey & _pk, QWidget * _parent );
|
||||
|
||||
|
||||
protected:
|
||||
@@ -72,7 +73,7 @@ protected:
|
||||
private:
|
||||
constexpr static int DEFAULT_HEIGHT{24};
|
||||
|
||||
const Plugin::Descriptor & m_pluginDescriptor;
|
||||
PluginKey m_pluginKey;
|
||||
QPixmap m_logo;
|
||||
|
||||
bool m_mouseOver;
|
||||
|
||||
@@ -26,10 +26,13 @@
|
||||
#define PLUGINFACTORY_H
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include <QtCore/QFileInfo>
|
||||
#include <QtCore/QHash>
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QVector>
|
||||
|
||||
#include "lmms_export.h"
|
||||
#include "Plugin.h"
|
||||
@@ -41,12 +44,10 @@ class LMMS_EXPORT PluginFactory
|
||||
public:
|
||||
struct PluginInfo
|
||||
{
|
||||
PluginInfo() : library(nullptr), descriptor(nullptr) {}
|
||||
|
||||
const QString name() const;
|
||||
QFileInfo file;
|
||||
std::shared_ptr<QLibrary> library;
|
||||
Plugin::Descriptor* descriptor;
|
||||
std::shared_ptr<QLibrary> library = nullptr;
|
||||
Plugin::Descriptor* descriptor = nullptr;
|
||||
|
||||
bool isNull() const {return ! library;}
|
||||
};
|
||||
@@ -56,6 +57,8 @@ public:
|
||||
PluginFactory();
|
||||
~PluginFactory();
|
||||
|
||||
static void setupSearchPaths();
|
||||
|
||||
/// Returns the singleton instance of PluginFactory. You won't need to call
|
||||
/// this directly, use pluginFactory instead.
|
||||
static PluginFactory* instance();
|
||||
@@ -64,10 +67,17 @@ public:
|
||||
const Plugin::DescriptorList descriptors() const;
|
||||
const Plugin::DescriptorList descriptors(Plugin::PluginTypes type) const;
|
||||
|
||||
struct PluginInfoAndKey
|
||||
{
|
||||
PluginInfo info;
|
||||
Plugin::Descriptor::SubPluginFeatures::Key key;
|
||||
bool isNull() const { return info.isNull(); }
|
||||
};
|
||||
|
||||
/// Returns a list of all found plugins' PluginFactory::PluginInfo objects.
|
||||
const PluginInfoList& pluginInfos() const;
|
||||
/// Returns a plugin that support the given file extension
|
||||
const PluginInfo pluginSupportingExtension(const QString& ext);
|
||||
const PluginInfoAndKey pluginSupportingExtension(const QString& ext);
|
||||
|
||||
/// Returns the PluginInfo object of the plugin with the given name.
|
||||
/// If the plugin is not found, an empty PluginInfo is returned (use
|
||||
@@ -84,7 +94,9 @@ public slots:
|
||||
private:
|
||||
DescriptorMap m_descriptors;
|
||||
PluginInfoList m_pluginInfos;
|
||||
QMap<QString, PluginInfo> m_pluginByExt;
|
||||
|
||||
QMap<QString, PluginInfoAndKey> m_pluginByExt;
|
||||
QVector<std::string> m_garbage; //!< cleaned up at destruction
|
||||
|
||||
QHash<QString, QString> m_errors;
|
||||
|
||||
|
||||
@@ -728,10 +728,10 @@ extern "C"
|
||||
{
|
||||
|
||||
// necessary for getting instance out of shared lib
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *m, void * )
|
||||
{
|
||||
return( new FreeBoyInstrument(
|
||||
static_cast<InstrumentTrack *>( _data ) ) );
|
||||
static_cast<InstrumentTrack *>( m ) ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1390,9 +1390,9 @@ extern "C"
|
||||
{
|
||||
|
||||
// necessary for getting instance out of shared lib
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *m, void * )
|
||||
{
|
||||
return new GigInstrument( static_cast<InstrumentTrack *>( _data ) );
|
||||
return new GigInstrument( static_cast<InstrumentTrack *>( m ) );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -44,6 +44,16 @@ LadspaSubPluginFeatures::LadspaSubPluginFeatures( Plugin::PluginTypes _type ) :
|
||||
|
||||
|
||||
|
||||
QString LadspaSubPluginFeatures::displayName(const Plugin::Descriptor::SubPluginFeatures::Key &k) const
|
||||
{
|
||||
const ladspa_key_t & lkey = subPluginKeyToLadspaKey(&k);
|
||||
Ladspa2LMMS * lm = Engine::getLADSPAManager();
|
||||
return lm->getName(lkey);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void LadspaSubPluginFeatures::fillDescriptionWidget( QWidget * _parent,
|
||||
const Key * _key ) const
|
||||
{
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _LADSPA_SUBPLUGIN_FEATURES_H
|
||||
#define _LADSPA_SUBPLUGIN_FEATURES_H
|
||||
#ifndef LADSPA_SUBPLUGIN_FEATURES_H
|
||||
#define LADSPA_SUBPLUGIN_FEATURES_H
|
||||
|
||||
#include "LadspaManager.h"
|
||||
#include "Plugin.h"
|
||||
@@ -37,11 +37,13 @@ class LadspaSubPluginFeatures : public Plugin::Descriptor::SubPluginFeatures
|
||||
public:
|
||||
LadspaSubPluginFeatures( Plugin::PluginTypes _type );
|
||||
|
||||
virtual void fillDescriptionWidget( QWidget * _parent,
|
||||
const Key * _key ) const;
|
||||
QString displayName(const Key& k) const override;
|
||||
void fillDescriptionWidget( QWidget * _parent,
|
||||
const Key * _key ) const override;
|
||||
|
||||
virtual void listSubPluginKeys( const Plugin::Descriptor * _desc,
|
||||
KeyList & _kl ) const;
|
||||
KeyList & _kl ) const override;
|
||||
|
||||
|
||||
static ladspa_key_t subPluginKeyToLadspaKey( const Key * _key );
|
||||
|
||||
|
||||
@@ -79,9 +79,9 @@ Plugin::Descriptor PLUGIN_EXPORT opulenz_plugin_descriptor =
|
||||
};
|
||||
|
||||
// necessary for getting instance out of shared lib
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *m, void * )
|
||||
{
|
||||
return( new OpulenzInstrument( static_cast<InstrumentTrack *>( _data ) ) );
|
||||
return( new OpulenzInstrument( static_cast<InstrumentTrack *>( m ) ) );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -877,8 +877,8 @@ void XpressiveView::helpClicked() {
|
||||
extern "C" {
|
||||
|
||||
// necessary for getting instance out of shared lib
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main(Model *, void * _data) {
|
||||
return (new Xpressive(static_cast<InstrumentTrack *>(_data)));
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main(Model *m, void *) {
|
||||
return (new Xpressive(static_cast<InstrumentTrack *>(m)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1277,10 +1277,9 @@ extern "C"
|
||||
{
|
||||
|
||||
// necessary for getting instance out of shared lib
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main(Model * model, void *)
|
||||
{
|
||||
return new audioFileProcessor(
|
||||
static_cast<InstrumentTrack *>( _data ) );
|
||||
return new audioFileProcessor(static_cast<InstrumentTrack *>(model));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -566,9 +566,9 @@ extern "C"
|
||||
{
|
||||
|
||||
// necessary for getting instance out of shared lib
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *m, void * )
|
||||
{
|
||||
return( new bitInvader( static_cast<InstrumentTrack *>( _data ) ) );
|
||||
return( new bitInvader( static_cast<InstrumentTrack *>( m ) ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "carla.h"
|
||||
|
||||
#include "embed.h"
|
||||
#include "InstrumentTrack.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
@@ -43,9 +44,9 @@ Plugin::Descriptor PLUGIN_EXPORT carlapatchbay_plugin_descriptor =
|
||||
NULL
|
||||
} ;
|
||||
|
||||
PLUGIN_EXPORT Plugin* lmms_plugin_main(Model*, void* data)
|
||||
PLUGIN_EXPORT Plugin* lmms_plugin_main(Model* m, void*)
|
||||
{
|
||||
return new CarlaInstrument(static_cast<InstrumentTrack*>(data), &carlapatchbay_plugin_descriptor, true);
|
||||
return new CarlaInstrument(static_cast<InstrumentTrack*>(m), &carlapatchbay_plugin_descriptor, true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "carla.h"
|
||||
|
||||
#include "embed.h"
|
||||
#include "InstrumentTrack.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
@@ -43,9 +44,9 @@ Plugin::Descriptor PLUGIN_EXPORT carlarack_plugin_descriptor =
|
||||
NULL
|
||||
} ;
|
||||
|
||||
PLUGIN_EXPORT Plugin* lmms_plugin_main(Model*, void* data)
|
||||
PLUGIN_EXPORT Plugin* lmms_plugin_main(Model* m, void*)
|
||||
{
|
||||
return new CarlaInstrument(static_cast<InstrumentTrack*>(data), &carlarack_plugin_descriptor, false);
|
||||
return new CarlaInstrument(static_cast<InstrumentTrack*>(m), &carlarack_plugin_descriptor, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -367,9 +367,9 @@ extern "C"
|
||||
{
|
||||
|
||||
// necessary for getting instance out of shared lib
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model * m, void * )
|
||||
{
|
||||
return new kickerInstrument( static_cast<InstrumentTrack *>( _data ) );
|
||||
return new kickerInstrument( static_cast<InstrumentTrack *>( m ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1029,11 +1029,11 @@ extern "C"
|
||||
{
|
||||
|
||||
// necessary for getting instance out of shared lib
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model * m, void * )
|
||||
{
|
||||
|
||||
return( new lb302Synth(
|
||||
static_cast<InstrumentTrack *>( _data ) ) );
|
||||
static_cast<InstrumentTrack *>( m ) ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1828,9 +1828,9 @@ extern "C"
|
||||
{
|
||||
|
||||
// necessary for getting instance out of shared lib
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *m, void * )
|
||||
{
|
||||
return new MonstroInstrument( static_cast<InstrumentTrack *>( _data ) );
|
||||
return new MonstroInstrument( static_cast<InstrumentTrack *>( m ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -918,9 +918,9 @@ extern "C"
|
||||
{
|
||||
|
||||
// necessary for getting instance out of shared lib
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *m, void * _data )
|
||||
{
|
||||
return( new NesInstrument( static_cast<InstrumentTrack *>( _data ) ) );
|
||||
return( new NesInstrument( static_cast<InstrumentTrack *>( m ) ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -636,9 +636,9 @@ extern "C"
|
||||
{
|
||||
|
||||
// necessary for getting instance out of shared lib
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *m, void * )
|
||||
{
|
||||
return( new organicInstrument( static_cast<InstrumentTrack *>( _data ) ) );
|
||||
return( new organicInstrument( static_cast<InstrumentTrack *>( m ) ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -66,9 +66,9 @@ Plugin::Descriptor PLUGIN_EXPORT patman_plugin_descriptor =
|
||||
|
||||
|
||||
// necessary for getting instance out of shared lib
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *m, void * )
|
||||
{
|
||||
return new patmanInstrument( static_cast<InstrumentTrack *>( _data ) );
|
||||
return new patmanInstrument( static_cast<InstrumentTrack *>( m ) );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1150,9 +1150,9 @@ extern "C"
|
||||
{
|
||||
|
||||
// necessary for getting instance out of shared lib
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *m, void * )
|
||||
{
|
||||
return new sf2Instrument( static_cast<InstrumentTrack *>( _data ) );
|
||||
return new sf2Instrument( static_cast<InstrumentTrack *>( m ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1122,9 +1122,9 @@ extern "C"
|
||||
{
|
||||
|
||||
// necessary for getting instance out of shared lib
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model*, void* data )
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model* m, void* )
|
||||
{
|
||||
return new sfxrInstrument( static_cast<InstrumentTrack *>( data ) );
|
||||
return new sfxrInstrument( static_cast<InstrumentTrack *>( m ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -794,10 +794,9 @@ extern "C"
|
||||
{
|
||||
|
||||
// necessary for getting instance out of shared lib
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *m, void * )
|
||||
{
|
||||
return( new sidInstrument(
|
||||
static_cast<InstrumentTrack *>( _data ) ) );
|
||||
return( new sidInstrument( static_cast<InstrumentTrack *>( m ) ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -756,9 +756,9 @@ extern "C"
|
||||
{
|
||||
|
||||
// necessary for getting instance out of shared lib
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model * m, void * )
|
||||
{
|
||||
return new malletsInstrument( static_cast<InstrumentTrack *>( _data ) );
|
||||
return new malletsInstrument( static_cast<InstrumentTrack *>( m ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -723,9 +723,9 @@ extern "C"
|
||||
{
|
||||
|
||||
// necessary for getting instance out of shared lib
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model* model, void * )
|
||||
{
|
||||
return new TripleOscillator( static_cast<InstrumentTrack *>( _data ) );
|
||||
return new TripleOscillator( static_cast<InstrumentTrack *>( model ) );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1180,9 +1180,9 @@ extern "C"
|
||||
{
|
||||
|
||||
// necessary for getting instance out of shared lib
|
||||
Q_DECL_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
|
||||
Q_DECL_EXPORT Plugin * lmms_plugin_main( Model *m, void * )
|
||||
{
|
||||
return new vestigeInstrument( static_cast<InstrumentTrack *>( _data ) );
|
||||
return new vestigeInstrument( static_cast<InstrumentTrack *>( m ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -682,9 +682,9 @@ extern "C"
|
||||
{
|
||||
|
||||
// necessary for getting instance out of shared lib
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *m, void * )
|
||||
{
|
||||
return( new vibed( static_cast<InstrumentTrack *>( _data ) ) );
|
||||
return( new vibed( static_cast<InstrumentTrack *>( m ) ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1279,9 +1279,9 @@ extern "C"
|
||||
{
|
||||
|
||||
// necessary for getting instance out of shared lib
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *m, void * )
|
||||
{
|
||||
return( new WatsynInstrument( static_cast<InstrumentTrack *>( _data ) ) );
|
||||
return( new WatsynInstrument( static_cast<InstrumentTrack *>( m ) ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -659,10 +659,9 @@ extern "C"
|
||||
{
|
||||
|
||||
// necessary for getting instance out of shared lib
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main(Model * m, void *)
|
||||
{
|
||||
|
||||
return new ZynAddSubFxInstrument( static_cast<InstrumentTrack *>( _data ) );
|
||||
return new ZynAddSubFxInstrument(static_cast<InstrumentTrack *>(m));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -36,9 +36,8 @@
|
||||
Effect::Effect( const Plugin::Descriptor * _desc,
|
||||
Model * _parent,
|
||||
const Descriptor::SubPluginFeatures::Key * _key ) :
|
||||
Plugin( _desc, _parent ),
|
||||
Plugin( _desc, _parent, _key ),
|
||||
m_parent( NULL ),
|
||||
m_key( _key ? *_key : Descriptor::SubPluginFeatures::Key() ),
|
||||
m_processors( 1 ),
|
||||
m_okay( true ),
|
||||
m_noRun( false ),
|
||||
@@ -117,7 +116,7 @@ Effect * Effect::instantiate( const QString& pluginName,
|
||||
Model * _parent,
|
||||
Descriptor::SubPluginFeatures::Key * _key )
|
||||
{
|
||||
Plugin * p = Plugin::instantiate( pluginName, _parent, _key );
|
||||
Plugin * p = Plugin::instantiateWithKey( pluginName, _parent, _key );
|
||||
// check whether instantiated plugin is an effect
|
||||
if( dynamic_cast<Effect *>( p ) != NULL )
|
||||
{
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "FxMixer.h"
|
||||
#include "Ladspa2LMMS.h"
|
||||
#include "Mixer.h"
|
||||
#include "Plugin.h"
|
||||
#include "PresetPreviewPlayHandle.h"
|
||||
#include "ProjectJournal.h"
|
||||
#include "Song.h"
|
||||
@@ -41,6 +42,7 @@ BBTrackContainer * LmmsCore::s_bbTrackContainer = NULL;
|
||||
Song * LmmsCore::s_song = NULL;
|
||||
ProjectJournal * LmmsCore::s_projectJournal = NULL;
|
||||
Ladspa2LMMS * LmmsCore::s_ladspaManager = NULL;
|
||||
void* LmmsCore::s_dndPluginKey = nullptr;
|
||||
DummyTrackContainer * LmmsCore::s_dummyTC = NULL;
|
||||
|
||||
|
||||
@@ -112,4 +114,24 @@ void LmmsCore::updateFramesPerTick()
|
||||
DefaultTicksPerTact / s_song->getTempo();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void LmmsCore::setDndPluginKey(void *newKey)
|
||||
{
|
||||
Q_ASSERT(static_cast<Plugin::Descriptor::SubPluginFeatures::Key*>(newKey));
|
||||
s_dndPluginKey = newKey;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void *LmmsCore::pickDndPluginKey()
|
||||
{
|
||||
return s_dndPluginKey;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
LmmsCore * LmmsCore::s_instanceOfMe = NULL;
|
||||
|
||||
@@ -27,9 +27,10 @@
|
||||
#include "DummyInstrument.h"
|
||||
|
||||
|
||||
Instrument::Instrument( InstrumentTrack * _instrument_track,
|
||||
const Descriptor * _descriptor ) :
|
||||
Plugin( _descriptor, NULL/* _instrument_track*/ ),
|
||||
Instrument::Instrument(InstrumentTrack * _instrument_track,
|
||||
const Descriptor * _descriptor,
|
||||
const Descriptor::SubPluginFeatures::Key *key) :
|
||||
Plugin(_descriptor, NULL/* _instrument_track*/, key),
|
||||
m_instrumentTrack( _instrument_track )
|
||||
{
|
||||
}
|
||||
@@ -56,19 +57,15 @@ f_cnt_t Instrument::beatLen( NotePlayHandle * ) const
|
||||
|
||||
|
||||
|
||||
Instrument * Instrument::instantiate( const QString & _plugin_name,
|
||||
InstrumentTrack * _instrument_track )
|
||||
Instrument *Instrument::instantiate(const QString &_plugin_name,
|
||||
InstrumentTrack *_instrument_track, const Descriptor::SubPluginFeatures::Key *key, bool keyFromDnd)
|
||||
{
|
||||
Plugin * p = Plugin::instantiate( _plugin_name, _instrument_track,
|
||||
_instrument_track );
|
||||
// check whether instantiated plugin is an instrument
|
||||
if( dynamic_cast<Instrument *>( p ) != NULL )
|
||||
{
|
||||
// everything ok, so return pointer
|
||||
return dynamic_cast<Instrument *>( p );
|
||||
}
|
||||
|
||||
// not quite... so delete plugin and return dummy instrument
|
||||
if(keyFromDnd)
|
||||
Q_ASSERT(!key);
|
||||
// copy from above // TODO! common cleaner func
|
||||
Plugin * p = Plugin::instantiateWithKey(_plugin_name, _instrument_track, key, keyFromDnd);
|
||||
if(dynamic_cast<Instrument *>(p))
|
||||
return dynamic_cast<Instrument *>(p);
|
||||
delete p;
|
||||
return( new DummyInstrument( _instrument_track ) );
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
LadspaManager::LadspaManager()
|
||||
{
|
||||
// Make sure plugin search paths are set up
|
||||
PluginFactory::instance();
|
||||
PluginFactory::setupSearchPaths();
|
||||
|
||||
QStringList ladspaDirectories = QString( getenv( "LADSPA_PATH" ) ).
|
||||
split( LADSPA_PATH_SEPERATOR );
|
||||
|
||||
@@ -22,12 +22,14 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Plugin.h"
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QLibrary>
|
||||
#include <QMessageBox>
|
||||
|
||||
#include "Plugin.h"
|
||||
#include "embed.h"
|
||||
#include "Engine.h"
|
||||
#include "GuiApplication.h"
|
||||
@@ -53,10 +55,12 @@ static Plugin::Descriptor dummyPluginDescriptor =
|
||||
|
||||
|
||||
|
||||
Plugin::Plugin( const Descriptor * descriptor, Model * parent ) :
|
||||
Model( parent ),
|
||||
Plugin::Plugin(const Descriptor * descriptor, Model * parent, const
|
||||
Descriptor::SubPluginFeatures::Key* key) :
|
||||
Model(parent),
|
||||
JournallingObject(),
|
||||
m_descriptor( descriptor )
|
||||
m_descriptor(descriptor),
|
||||
m_key(key ? *key : Descriptor::SubPluginFeatures::Key(m_descriptor))
|
||||
{
|
||||
if( m_descriptor == NULL )
|
||||
{
|
||||
@@ -74,6 +78,97 @@ Plugin::~Plugin()
|
||||
|
||||
|
||||
|
||||
template<class T>
|
||||
T use_this_or(T this_param, T or_param)
|
||||
{
|
||||
return this_param ? this_param : or_param;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
QString use_this_or(QString this_param, QString or_param)
|
||||
{
|
||||
return this_param.isNull() ? or_param : this_param;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
QString Plugin::displayName() const
|
||||
{
|
||||
return Model::displayName().isEmpty() // currently always empty
|
||||
? (m_descriptor->subPluginFeatures && m_key.isValid())
|
||||
// get from sub plugin
|
||||
? m_key.displayName()
|
||||
// get from plugin
|
||||
: m_descriptor->displayName
|
||||
: Model::displayName();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
const PixmapLoader* Plugin::logo() const
|
||||
{
|
||||
return (m_descriptor->subPluginFeatures && m_key.isValid())
|
||||
? m_key.logo()
|
||||
: m_descriptor->logo;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
QString Plugin::Descriptor::SubPluginFeatures::Key::additionalFileExtensions() const
|
||||
{
|
||||
Q_ASSERT(isValid());
|
||||
return desc->subPluginFeatures
|
||||
// get from sub plugin
|
||||
? desc->subPluginFeatures->additionalFileExtensions(*this)
|
||||
// no sub plugin, so no *additional* file extensions
|
||||
: QString();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
QString Plugin::Descriptor::SubPluginFeatures::Key::displayName() const
|
||||
{
|
||||
Q_ASSERT(isValid());
|
||||
return desc->subPluginFeatures
|
||||
// get from sub plugin
|
||||
? use_this_or(desc->subPluginFeatures->displayName(*this),
|
||||
QString::fromUtf8(desc->displayName))
|
||||
// get from plugin
|
||||
: desc->displayName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
const PixmapLoader* Plugin::Descriptor::SubPluginFeatures::Key::logo() const
|
||||
{
|
||||
Q_ASSERT(isValid());
|
||||
return desc->subPluginFeatures
|
||||
? use_this_or(desc->subPluginFeatures->logo(*this), desc->logo)
|
||||
: desc->logo;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
QString Plugin::Descriptor::SubPluginFeatures::Key::description() const
|
||||
{
|
||||
Q_ASSERT(isValid());
|
||||
return desc->subPluginFeatures
|
||||
? use_this_or(desc->subPluginFeatures->description(*this),
|
||||
QString::fromUtf8(desc->description))
|
||||
: desc->description;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Plugin::loadFile( const QString & )
|
||||
{
|
||||
}
|
||||
@@ -90,6 +185,32 @@ AutomatableModel * Plugin::childModel( const QString & )
|
||||
|
||||
|
||||
#include "PluginFactory.h"
|
||||
Plugin * Plugin::instantiateWithKey(const QString& pluginName, Model * parent,
|
||||
const Descriptor::SubPluginFeatures::Key *key,
|
||||
bool keyFromDnd)
|
||||
{
|
||||
if(keyFromDnd)
|
||||
Q_ASSERT(!key);
|
||||
const Descriptor::SubPluginFeatures::Key *keyPtr = keyFromDnd
|
||||
? static_cast<Plugin::Descriptor::SubPluginFeatures::Key*>(Engine::pickDndPluginKey())
|
||||
: key;
|
||||
const PluginFactory::PluginInfo& pi = pluginFactory->pluginInfo(pluginName.toUtf8());
|
||||
if(keyPtr)
|
||||
{
|
||||
// descriptor is not yet set when loading - set it now
|
||||
Descriptor::SubPluginFeatures::Key keyCopy = *keyPtr;
|
||||
keyCopy.desc = pi.descriptor;
|
||||
return Plugin::instantiate(pluginName, parent, &keyCopy);
|
||||
}
|
||||
else
|
||||
return Plugin::instantiate(pluginName, parent,
|
||||
// the keys are never touched anywhere
|
||||
const_cast<Descriptor::SubPluginFeatures::Key *>(keyPtr));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Plugin * Plugin::instantiate(const QString& pluginName, Model * parent,
|
||||
void *data)
|
||||
{
|
||||
|
||||
@@ -28,8 +28,11 @@
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QLibrary>
|
||||
#include "lmmsconfig.h"
|
||||
|
||||
#include "ConfigManager.h"
|
||||
#include "Plugin.h"
|
||||
#include "embed.h"
|
||||
|
||||
#ifdef LMMS_BUILD_WIN32
|
||||
QStringList nameFilters("*.dll");
|
||||
@@ -45,6 +48,16 @@ qint64 qHash(const QFileInfo& fi)
|
||||
std::unique_ptr<PluginFactory> PluginFactory::s_instance;
|
||||
|
||||
PluginFactory::PluginFactory()
|
||||
{
|
||||
setupSearchPaths();
|
||||
discoverPlugins();
|
||||
}
|
||||
|
||||
PluginFactory::~PluginFactory()
|
||||
{
|
||||
}
|
||||
|
||||
void PluginFactory::setupSearchPaths()
|
||||
{
|
||||
// Adds a search path relative to the main executable if the path exists.
|
||||
auto addRelativeIfExists = [](const QString & path) {
|
||||
@@ -76,12 +89,6 @@ PluginFactory::PluginFactory()
|
||||
QDir::addSearchPath("plugins", env_path);
|
||||
|
||||
QDir::addSearchPath("plugins", ConfigManager::inst()->workingDir() + "plugins");
|
||||
|
||||
discoverPlugins();
|
||||
}
|
||||
|
||||
PluginFactory::~PluginFactory()
|
||||
{
|
||||
}
|
||||
|
||||
PluginFactory* PluginFactory::instance()
|
||||
@@ -107,9 +114,9 @@ const PluginFactory::PluginInfoList& PluginFactory::pluginInfos() const
|
||||
return m_pluginInfos;
|
||||
}
|
||||
|
||||
const PluginFactory::PluginInfo PluginFactory::pluginSupportingExtension(const QString& ext)
|
||||
const PluginFactory::PluginInfoAndKey PluginFactory::pluginSupportingExtension(const QString& ext)
|
||||
{
|
||||
return m_pluginByExt.value(ext, PluginInfo());
|
||||
return m_pluginByExt.value(ext, PluginInfoAndKey());
|
||||
}
|
||||
|
||||
const PluginFactory::PluginInfo PluginFactory::pluginInfo(const char* name) const
|
||||
@@ -150,42 +157,78 @@ void PluginFactory::discoverPlugins()
|
||||
for (const QFileInfo& file : files)
|
||||
{
|
||||
auto library = std::make_shared<QLibrary>(file.absoluteFilePath());
|
||||
|
||||
if (! library->load()) {
|
||||
m_errors[file.baseName()] = library->errorString();
|
||||
qWarning("%s", library->errorString().toLocal8Bit().data());
|
||||
continue;
|
||||
}
|
||||
if (library->resolve("lmms_plugin_main") == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
QString descriptorName = file.baseName() + "_plugin_descriptor";
|
||||
if( descriptorName.left(3) == "lib" )
|
||||
Plugin::Descriptor* pluginDescriptor = nullptr;
|
||||
if (library->resolve("lmms_plugin_main"))
|
||||
{
|
||||
descriptorName = descriptorName.mid(3);
|
||||
QString descriptorName = file.baseName() + "_plugin_descriptor";
|
||||
if( descriptorName.left(3) == "lib" )
|
||||
{
|
||||
descriptorName = descriptorName.mid(3);
|
||||
}
|
||||
|
||||
pluginDescriptor = reinterpret_cast<Plugin::Descriptor*>(library->resolve(descriptorName.toUtf8().constData()));
|
||||
if(pluginDescriptor == nullptr)
|
||||
{
|
||||
qWarning() << qApp->translate("PluginFactory", "LMMS plugin %1 does not have a plugin descriptor named %2!").
|
||||
arg(file.absoluteFilePath()).arg(descriptorName);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
Plugin::Descriptor* pluginDescriptor = reinterpret_cast<Plugin::Descriptor*>(library->resolve(descriptorName.toUtf8().constData()));
|
||||
if(pluginDescriptor == nullptr)
|
||||
if(pluginDescriptor)
|
||||
{
|
||||
qWarning() << qApp->translate("PluginFactory", "LMMS plugin %1 does not have a plugin descriptor named %2!").
|
||||
arg(file.absoluteFilePath()).arg(descriptorName);
|
||||
continue;
|
||||
PluginInfo info;
|
||||
info.file = file;
|
||||
info.library = library;
|
||||
info.descriptor = pluginDescriptor;
|
||||
pluginInfos << info;
|
||||
|
||||
auto addSupportedFileTypes =
|
||||
[this](QString supportedFileTypes,
|
||||
const PluginInfo& info,
|
||||
const Plugin::Descriptor::SubPluginFeatures::Key* key = nullptr)
|
||||
{
|
||||
if(!supportedFileTypes.isNull())
|
||||
{
|
||||
for (const QString& ext : supportedFileTypes.split(','))
|
||||
{
|
||||
//qDebug() << "Plugin " << info.name()
|
||||
// << "supports" << ext;
|
||||
PluginInfoAndKey infoAndKey;
|
||||
infoAndKey.info = info;
|
||||
infoAndKey.key = key
|
||||
? *key
|
||||
: Plugin::Descriptor::SubPluginFeatures::Key();
|
||||
m_pluginByExt.insert(ext, infoAndKey);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (info.descriptor->supportedFileTypes)
|
||||
addSupportedFileTypes(QString(info.descriptor->supportedFileTypes), info);
|
||||
|
||||
if (info.descriptor->subPluginFeatures)
|
||||
{
|
||||
Plugin::Descriptor::SubPluginFeatures::KeyList
|
||||
subPluginKeys;
|
||||
info.descriptor->subPluginFeatures->listSubPluginKeys(
|
||||
info.descriptor,
|
||||
subPluginKeys);
|
||||
for(const Plugin::Descriptor::SubPluginFeatures::Key& key
|
||||
: subPluginKeys)
|
||||
{
|
||||
addSupportedFileTypes(key.additionalFileExtensions(), info, &key);
|
||||
}
|
||||
}
|
||||
|
||||
descriptors.insert(info.descriptor->type, info.descriptor);
|
||||
}
|
||||
|
||||
PluginInfo info;
|
||||
info.file = file;
|
||||
info.library = library;
|
||||
info.descriptor = pluginDescriptor;
|
||||
pluginInfos << info;
|
||||
|
||||
for (const QString& ext : QString(info.descriptor->supportedFileTypes).split(','))
|
||||
{
|
||||
m_pluginByExt.insert(ext, info);
|
||||
}
|
||||
|
||||
descriptors.insert(info.descriptor->type, info.descriptor);
|
||||
}
|
||||
|
||||
m_pluginInfos = pluginInfos;
|
||||
|
||||
@@ -137,8 +137,10 @@ PresetPreviewPlayHandle::PresetPreviewPlayHandle( const QString & _preset_file,
|
||||
suffix().toLower();
|
||||
if( i == NULL || !i->descriptor()->supportsFileType( ext ) )
|
||||
{
|
||||
const PluginFactory::PluginInfoAndKey& infoAndKey =
|
||||
pluginFactory->pluginSupportingExtension(ext);
|
||||
i = s_previewTC->previewInstrumentTrack()->
|
||||
loadInstrument(pluginFactory->pluginSupportingExtension(ext).name());
|
||||
loadInstrument(infoAndKey.info.name(), &infoAndKey.key);
|
||||
}
|
||||
if( i != NULL )
|
||||
{
|
||||
|
||||
@@ -54,11 +54,6 @@ EffectSelectDialog::EffectSelectDialog( QWidget * _parent ) :
|
||||
if( desc->subPluginFeatures )
|
||||
{
|
||||
desc->subPluginFeatures->listSubPluginKeys(
|
||||
// as iterators are always stated to be not
|
||||
// equal with pointers, we dereference the
|
||||
// iterator and take the address of the item,
|
||||
// so we're on the safe side and the compiler
|
||||
// likely will reduce that to just "it"
|
||||
desc,
|
||||
subPluginEffectKeys );
|
||||
}
|
||||
@@ -80,14 +75,14 @@ EffectSelectDialog::EffectSelectDialog( QWidget * _parent ) :
|
||||
{
|
||||
QString name;
|
||||
QString type;
|
||||
if( ( *it ).desc->subPluginFeatures )
|
||||
if( it->desc->subPluginFeatures )
|
||||
{
|
||||
name = ( *it ).name;
|
||||
type = ( *it ).desc->displayName;
|
||||
name = it->displayName();
|
||||
type = it->desc->displayName;
|
||||
}
|
||||
else
|
||||
{
|
||||
name = ( *it ).desc->displayName;
|
||||
name = it->desc->displayName;
|
||||
type = "LMMS";
|
||||
}
|
||||
m_sourceModel.setItem( row, 0, new QStandardItem( name ) );
|
||||
@@ -190,62 +185,63 @@ void EffectSelectDialog::rowChanged( const QModelIndex & _idx,
|
||||
{
|
||||
m_currentSelection = m_effectKeys[m_model.mapToSource( _idx ).row()];
|
||||
}
|
||||
if( m_currentSelection.desc )
|
||||
if( m_currentSelection.desc )
|
||||
{
|
||||
m_descriptionWidget = new QWidget;
|
||||
|
||||
QHBoxLayout *hbox = new QHBoxLayout( m_descriptionWidget );
|
||||
QHBoxLayout *hbox = new QHBoxLayout( m_descriptionWidget );
|
||||
|
||||
Plugin::Descriptor const & descriptor = *( m_currentSelection.desc );
|
||||
Plugin::Descriptor const & descriptor = *( m_currentSelection.desc );
|
||||
|
||||
if ( descriptor.logo )
|
||||
{
|
||||
QLabel *logoLabel = new QLabel( m_descriptionWidget );
|
||||
logoLabel->setPixmap( descriptor.logo->pixmap() );
|
||||
logoLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||
const PixmapLoader* pixLoa = m_currentSelection.logo();
|
||||
if (pixLoa)
|
||||
{
|
||||
QLabel *logoLabel = new QLabel( m_descriptionWidget );
|
||||
logoLabel->setPixmap(pixLoa->pixmap());
|
||||
logoLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||
|
||||
hbox->addWidget( logoLabel );
|
||||
hbox->setAlignment( logoLabel, Qt::AlignTop);
|
||||
}
|
||||
hbox->addWidget( logoLabel );
|
||||
hbox->setAlignment( logoLabel, Qt::AlignTop);
|
||||
}
|
||||
|
||||
QWidget *textualInfoWidget = new QWidget( m_descriptionWidget );
|
||||
QWidget *textualInfoWidget = new QWidget( m_descriptionWidget );
|
||||
|
||||
hbox->addWidget(textualInfoWidget);
|
||||
hbox->addWidget(textualInfoWidget);
|
||||
|
||||
QVBoxLayout * textWidgetLayout = new QVBoxLayout( textualInfoWidget);
|
||||
textWidgetLayout->setMargin( 4 );
|
||||
textWidgetLayout->setSpacing( 0 );
|
||||
QVBoxLayout * textWidgetLayout = new QVBoxLayout( textualInfoWidget);
|
||||
textWidgetLayout->setMargin( 4 );
|
||||
textWidgetLayout->setSpacing( 0 );
|
||||
|
||||
if ( m_currentSelection.desc->subPluginFeatures )
|
||||
{
|
||||
QWidget *subWidget = new QWidget(textualInfoWidget);
|
||||
QVBoxLayout * subLayout = new QVBoxLayout( subWidget );
|
||||
subLayout->setMargin( 4 );
|
||||
subLayout->setSpacing( 0 );
|
||||
m_currentSelection.desc->subPluginFeatures->
|
||||
fillDescriptionWidget( subWidget, &m_currentSelection );
|
||||
for( QWidget * w : subWidget->findChildren<QWidget *>() )
|
||||
{
|
||||
if( w->parent() == subWidget )
|
||||
{
|
||||
subLayout->addWidget( w );
|
||||
}
|
||||
}
|
||||
if ( m_currentSelection.desc->subPluginFeatures )
|
||||
{
|
||||
QWidget *subWidget = new QWidget(textualInfoWidget);
|
||||
QVBoxLayout * subLayout = new QVBoxLayout( subWidget );
|
||||
subLayout->setMargin( 4 );
|
||||
subLayout->setSpacing( 0 );
|
||||
m_currentSelection.desc->subPluginFeatures->
|
||||
fillDescriptionWidget( subWidget, &m_currentSelection );
|
||||
for( QWidget * w : subWidget->findChildren<QWidget *>() )
|
||||
{
|
||||
if( w->parent() == subWidget )
|
||||
{
|
||||
subLayout->addWidget( w );
|
||||
}
|
||||
}
|
||||
|
||||
textWidgetLayout->addWidget(subWidget);
|
||||
}
|
||||
else
|
||||
{
|
||||
QLabel *label = new QLabel(m_descriptionWidget);
|
||||
QString labelText = "<p><b>" + tr("Name") + ":</b> " + QString::fromUtf8(descriptor.displayName) + "</p>";
|
||||
labelText += "<p><b>" + tr("Description") + ":</b> " + qApp->translate( "pluginBrowser", descriptor.description ) + "</p>";
|
||||
labelText += "<p><b>" + tr("Author") + ":</b> " + QString::fromUtf8(descriptor.author) + "</p>";
|
||||
textWidgetLayout->addWidget(subWidget);
|
||||
}
|
||||
else
|
||||
{
|
||||
QLabel *label = new QLabel(m_descriptionWidget);
|
||||
QString labelText = "<p><b>" + tr("Name") + ":</b> " + QString::fromUtf8(descriptor.displayName) + "</p>";
|
||||
labelText += "<p><b>" + tr("Description") + ":</b> " + qApp->translate( "pluginBrowser", descriptor.description ) + "</p>";
|
||||
labelText += "<p><b>" + tr("Author") + ":</b> " + QString::fromUtf8(descriptor.author) + "</p>";
|
||||
|
||||
label->setText(labelText);
|
||||
textWidgetLayout->addWidget(label);
|
||||
}
|
||||
label->setText(labelText);
|
||||
textWidgetLayout->addWidget(label);
|
||||
}
|
||||
|
||||
ui->scrollArea->setWidget( m_descriptionWidget );
|
||||
ui->scrollArea->setWidget( m_descriptionWidget );
|
||||
m_descriptionWidget->show();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,7 +180,7 @@ void FileBrowser::reloadTree( void )
|
||||
|
||||
void FileBrowser::expandItems( QTreeWidgetItem * item )
|
||||
{
|
||||
int numChildren = item ? item->childCount() : m_fileBrowserTreeWidget->topLevelItemCount();
|
||||
int numChildren = item ? item->childCount() : m_fileBrowserTreeWidget->topLevelItemCount();
|
||||
for( int i = 0; i < numChildren; ++i )
|
||||
{
|
||||
QTreeWidgetItem * it = item ? item->child( i ) : m_fileBrowserTreeWidget->topLevelItem(i);
|
||||
@@ -241,7 +241,7 @@ void FileBrowser::addItems(const QString & path )
|
||||
Directory *dd = new Directory( cur_file, path,
|
||||
m_filter );
|
||||
m_fileBrowserTreeWidget->insertTopLevelItem( i,dd );
|
||||
dd->update();
|
||||
dd->update(); // add files to the directory
|
||||
orphan = false;
|
||||
break;
|
||||
}
|
||||
@@ -406,7 +406,7 @@ void FileBrowserTreeWidget::mousePressEvent(QMouseEvent * me )
|
||||
delete tf;
|
||||
}
|
||||
else if( ( f->extension ()== "xiz" || f->extension() == "sf2" || f->extension() == "sf3" || f->extension() == "gig" || f->extension() == "pat" ) &&
|
||||
! pluginFactory->pluginSupportingExtension(f->extension()).isNull() )
|
||||
! pluginFactory->pluginSupportingExtension(f->extension()).info.isNull() )
|
||||
{
|
||||
m_previewPlayHandle = new PresetPreviewPlayHandle( f->fullName(), f->handling() == FileItem::LoadByPlugin );
|
||||
}
|
||||
@@ -549,8 +549,9 @@ void FileBrowserTreeWidget::handleFile(FileItem * f, InstrumentTrack * it )
|
||||
if( i == NULL ||
|
||||
!i->descriptor()->supportsFileType( e ) )
|
||||
{
|
||||
i = it->loadInstrument(
|
||||
pluginFactory->pluginSupportingExtension(e).name() );
|
||||
PluginFactory::PluginInfoAndKey piakn =
|
||||
pluginFactory->pluginSupportingExtension(e);
|
||||
i = it->loadInstrument(piakn.info.name(), &piakn.key);
|
||||
}
|
||||
i->loadFile( f->fullName() );
|
||||
break;
|
||||
|
||||
@@ -57,7 +57,7 @@ void InstrumentView::setModel( Model * _model, bool )
|
||||
if( dynamic_cast<Instrument *>( _model ) != NULL )
|
||||
{
|
||||
ModelView::setModel( _model );
|
||||
instrumentTrackWindow()->setWindowIcon( model()->descriptor()->logo->pixmap() );
|
||||
instrumentTrackWindow()->setWindowIcon( model()->logo()->pixmap() );
|
||||
connect( model(), SIGNAL( destroyed( QObject * ) ), this, SLOT( close() ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <QStyleOption>
|
||||
|
||||
#include "embed.h"
|
||||
#include "Engine.h"
|
||||
#include "templates.h"
|
||||
#include "gui_templates.h"
|
||||
#include "StringPairDrag.h"
|
||||
@@ -85,9 +86,30 @@ PluginDescList::PluginDescList(QWidget *parent) :
|
||||
return qstricmp( d1->displayName, d2->displayName ) < 0 ? true : false;
|
||||
}
|
||||
);
|
||||
for (const Plugin::Descriptor* desc : descs)
|
||||
|
||||
typedef Plugin::Descriptor::SubPluginFeatures::KeyList PluginKeyList;
|
||||
typedef Plugin::Descriptor::SubPluginFeatures::Key PluginKey;
|
||||
PluginKeyList subPluginKeys, pluginKeys;
|
||||
|
||||
for (const Plugin::Descriptor* desc: descs)
|
||||
{
|
||||
PluginDescWidget* p = new PluginDescWidget( *desc, this );
|
||||
if( desc->subPluginFeatures )
|
||||
{
|
||||
desc->subPluginFeatures->listSubPluginKeys(
|
||||
desc,
|
||||
subPluginKeys );
|
||||
}
|
||||
else
|
||||
{
|
||||
pluginKeys << PluginKey( desc, desc->name );
|
||||
}
|
||||
}
|
||||
|
||||
pluginKeys += subPluginKeys;
|
||||
|
||||
for (const PluginKey& key : pluginKeys)
|
||||
{
|
||||
PluginDescWidget* p = new PluginDescWidget( key, this );
|
||||
p->show();
|
||||
layout->addWidget(p);
|
||||
}
|
||||
@@ -99,23 +121,23 @@ PluginDescList::PluginDescList(QWidget *parent) :
|
||||
|
||||
|
||||
|
||||
PluginDescWidget::PluginDescWidget( const Plugin::Descriptor & _pd,
|
||||
PluginDescWidget::PluginDescWidget(const PluginKey &_pk,
|
||||
QWidget * _parent ) :
|
||||
QWidget( _parent ),
|
||||
m_pluginDescriptor( _pd ),
|
||||
m_logo( _pd.logo->pixmap() ),
|
||||
m_pluginKey( _pk ),
|
||||
m_logo( _pk.logo()->pixmap() ),
|
||||
m_mouseOver( false )
|
||||
{
|
||||
setFixedHeight( DEFAULT_HEIGHT );
|
||||
setMouseTracking( true );
|
||||
setCursor( Qt::PointingHandCursor );
|
||||
setToolTip(_pd.description);
|
||||
setToolTip(_pk.description());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void PluginDescWidget::paintEvent( QPaintEvent * e )
|
||||
void PluginDescWidget::paintEvent( QPaintEvent * )
|
||||
{
|
||||
|
||||
QPainter p( this );
|
||||
@@ -140,8 +162,7 @@ void PluginDescWidget::paintEvent( QPaintEvent * e )
|
||||
}
|
||||
|
||||
p.setFont( f );
|
||||
p.drawText( 10 + logo_size.width(), 15,
|
||||
m_pluginDescriptor.displayName );
|
||||
p.drawText( 10 + logo_size.width(), 15, m_pluginKey.displayName());
|
||||
}
|
||||
|
||||
|
||||
@@ -171,8 +192,9 @@ void PluginDescWidget::mousePressEvent( QMouseEvent * _me )
|
||||
{
|
||||
if( _me->button() == Qt::LeftButton )
|
||||
{
|
||||
new StringPairDrag( "instrument", m_pluginDescriptor.name,
|
||||
m_logo, this );
|
||||
Engine::setDndPluginKey(&m_pluginKey);
|
||||
new StringPairDrag("instrument",
|
||||
QString::fromUtf8(m_pluginKey.desc->name), m_logo, this);
|
||||
leaveEvent( _me );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -384,8 +384,9 @@ void TrackContainerView::dropEvent( QDropEvent * _de )
|
||||
InstrumentTrack * it = dynamic_cast<InstrumentTrack *>(
|
||||
Track::create( Track::InstrumentTrack,
|
||||
m_tc ) );
|
||||
Instrument * i = it->loadInstrument(
|
||||
pluginFactory->pluginSupportingExtension(FileItem::extension(value)).name());
|
||||
PluginFactory::PluginInfoAndKey piakn =
|
||||
pluginFactory->pluginSupportingExtension(FileItem::extension(value));
|
||||
Instrument * i = it->loadInstrument(piakn.info.name(), &piakn.key);
|
||||
i->loadFile( value );
|
||||
//it->toggledInstrumentTrackButton( true );
|
||||
_de->accept();
|
||||
@@ -529,7 +530,8 @@ InstrumentLoaderThread::InstrumentLoaderThread( QObject *parent, InstrumentTrack
|
||||
|
||||
void InstrumentLoaderThread::run()
|
||||
{
|
||||
Instrument *i = m_it->loadInstrument( m_name );
|
||||
Instrument *i = m_it->loadInstrument(m_name, nullptr,
|
||||
true /*always DnD*/);
|
||||
QObject *parent = i->parent();
|
||||
i->setParent( 0 );
|
||||
i->moveToThread( m_containerThread );
|
||||
|
||||
@@ -195,9 +195,15 @@ void TrackLabelButton::paintEvent( QPaintEvent * _pe )
|
||||
InstrumentTrack * it =
|
||||
dynamic_cast<InstrumentTrack *>( m_trackView->getTrack() );
|
||||
const PixmapLoader * pl;
|
||||
auto get_logo = [](InstrumentTrack* it) -> const PixmapLoader*
|
||||
{
|
||||
return it->instrument()->key().isValid()
|
||||
? it->instrument()->key().logo()
|
||||
: it->instrument()->descriptor()->logo;
|
||||
};
|
||||
if( it && it->instrument() &&
|
||||
it->instrument()->descriptor() &&
|
||||
( pl = it->instrument()->descriptor()->logo ) )
|
||||
( pl = get_logo(it) ) )
|
||||
{
|
||||
if( pl->pixmapName() != m_iconName )
|
||||
{
|
||||
|
||||
@@ -740,7 +740,10 @@ void InstrumentTrack::saveTrackSpecificSettings( QDomDocument& doc, QDomElement
|
||||
{
|
||||
QDomElement i = doc.createElement( "instrument" );
|
||||
i.setAttribute( "name", m_instrument->descriptor()->name );
|
||||
m_instrument->saveState( doc, i );
|
||||
QDomElement ins = m_instrument->saveState( doc, i );
|
||||
if(m_instrument->key().isValid()) {
|
||||
ins.appendChild( m_instrument->key().saveXML( doc ) );
|
||||
}
|
||||
thisElement.appendChild( i );
|
||||
}
|
||||
m_soundShaping.saveState( doc, thisElement );
|
||||
@@ -801,9 +804,13 @@ void InstrumentTrack::loadTrackSpecificSettings( const QDomElement & thisElement
|
||||
}
|
||||
else if( node.nodeName() == "instrument" )
|
||||
{
|
||||
typedef Plugin::Descriptor::SubPluginFeatures::Key PluginKey;
|
||||
PluginKey key( node.toElement().elementsByTagName( "key" ).item( 0 ).toElement() );
|
||||
|
||||
delete m_instrument;
|
||||
m_instrument = NULL;
|
||||
m_instrument = Instrument::instantiate( node.toElement().attribute( "name" ), this );
|
||||
m_instrument = Instrument::instantiate(
|
||||
node.toElement().attribute( "name" ), this, &key);
|
||||
m_instrument->restoreState( node.firstChildElement() );
|
||||
|
||||
emit instrumentChanged();
|
||||
@@ -817,7 +824,8 @@ void InstrumentTrack::loadTrackSpecificSettings( const QDomElement & thisElement
|
||||
{
|
||||
delete m_instrument;
|
||||
m_instrument = NULL;
|
||||
m_instrument = Instrument::instantiate( node.nodeName(), this );
|
||||
m_instrument = Instrument::instantiate(
|
||||
node.nodeName(), this, nullptr, true);
|
||||
if( m_instrument->nodeName() == node.nodeName() )
|
||||
{
|
||||
m_instrument->restoreState( node.toElement() );
|
||||
@@ -842,15 +850,20 @@ void InstrumentTrack::setPreviewMode( const bool value )
|
||||
|
||||
|
||||
|
||||
Instrument * InstrumentTrack::loadInstrument( const QString & _plugin_name )
|
||||
Instrument * InstrumentTrack::loadInstrument(const QString & _plugin_name,
|
||||
const Plugin::Descriptor::SubPluginFeatures::Key *key, bool keyFromDnd)
|
||||
{
|
||||
if(keyFromDnd)
|
||||
Q_ASSERT(!key);
|
||||
|
||||
silenceAllNotes( true );
|
||||
|
||||
lock();
|
||||
delete m_instrument;
|
||||
m_instrument = Instrument::instantiate( _plugin_name, this );
|
||||
m_instrument = Instrument::instantiate(_plugin_name, this,
|
||||
key, keyFromDnd);
|
||||
unlock();
|
||||
setName( m_instrument->displayName() );
|
||||
setName(m_instrument->displayName());
|
||||
|
||||
emit instrumentChanged();
|
||||
|
||||
@@ -1697,7 +1710,7 @@ void InstrumentTrackWindow::dropEvent( QDropEvent* event )
|
||||
|
||||
if( type == "instrument" )
|
||||
{
|
||||
m_track->loadInstrument( value );
|
||||
m_track->loadInstrument( value, nullptr, true /* DnD */ );
|
||||
|
||||
Engine::getSong()->setModified();
|
||||
|
||||
@@ -1723,7 +1736,9 @@ void InstrumentTrackWindow::dropEvent( QDropEvent* event )
|
||||
|
||||
if( !i->descriptor()->supportsFileType( ext ) )
|
||||
{
|
||||
i = m_track->loadInstrument( pluginFactory->pluginSupportingExtension(ext).name() );
|
||||
PluginFactory::PluginInfoAndKey piakn =
|
||||
pluginFactory->pluginSupportingExtension(ext);
|
||||
i = m_track->loadInstrument(piakn.info.name(), &piakn.key);
|
||||
}
|
||||
|
||||
i->loadFile( value );
|
||||
|
||||
Reference in New Issue
Block a user