Introduce PluginFactory class

This singleton class handles management of plugin search paths and plugin
discovery. Search paths are (if they exist):
  * <lmms-exe-dir>/../lib/lmms: This is the common location on Unixoids
    (Not included in Windows builds)
  * <lmms-exe-dir>/plugins: For portable and Windows installations
  * The path given by the compile define LMMS_PLUGIN_DIR
  * Environment variable LMMS_PLUGIN_DIR if given

This commit also tweaks the build script to output built plugins to
"${CMAKE_BINARY_DIR}/plugins". This way lmms can find plugins during
development without the need to use `make install`.

Plugin::getDescriptorsOfAvailPlugins and ConfigManager::pluginDir were
removed.
This commit is contained in:
Lukas W
2015-01-29 13:48:52 +01:00
parent d569015273
commit 7be47230e3
21 changed files with 321 additions and 138 deletions

View File

@@ -120,11 +120,6 @@ public:
return m_dataDir + LOCALE_PATH;
}
const QString & pluginDir() const
{
return m_pluginDir;
}
const QString & vstDir() const
{
return m_vstDir;
@@ -202,7 +197,6 @@ private:
QString m_workingDir;
QString m_dataDir;
QString m_artworkDir;
QString m_pluginDir;
QString m_vstDir;
QString m_flDir;
QString m_ladDir;

View File

@@ -55,7 +55,6 @@ protected slots:
private:
Ui::EffectSelectDialog * ui;
Plugin::DescriptorList m_pluginDescriptors;
EffectKeyList m_effectKeys;
EffectKey m_currentSelection;

View File

@@ -137,9 +137,8 @@ public:
SubPluginFeatures *subPluginFeatures;
} ;
// typedef a list so we can easily work with list of plugin descriptors
typedef QList<Descriptor> DescriptorList;
typedef QList<Descriptor*> DescriptorList;
// contructor of a plugin
Plugin( const Descriptor* descriptor, Model* parent );
@@ -177,9 +176,6 @@ public:
// if specified plugin couldn't be loaded, it creates a dummy-plugin
static Plugin * instantiate( const QString& pluginName, Model *parent, void * data );
// fills given list with descriptors of all available plugins
static void getDescriptorsOfAvailPlugins( DescriptorList& pluginDescriptors );
// create a view for the model
PluginView* createView( QWidget* parent );

View File

@@ -55,9 +55,6 @@ class PluginDescList : public QWidget
Q_OBJECT
public:
PluginDescList(QWidget* parent);
private:
Plugin::DescriptorList m_pluginDescriptors;
};

84
include/PluginFactory.h Normal file
View File

@@ -0,0 +1,84 @@
/*
* PluginFactory.h
*
* Copyright (c) 2015 Lukas W <lukaswhl/at/gmail.com>
*
* This file is part of LMMS - http://lmms.io
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program (see COPYING); if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
*/
#ifndef PLUGINFACTORY_H
#define PLUGINFACTORY_H
#include <QtCore/QFileInfo>
#include <QtCore/QList>
#include "Plugin.h"
class QLibrary;
class PluginFactory
{
public:
struct PluginInfo
{
QFileInfo file;
QLibrary* library;
Plugin::Descriptor* descriptor;
bool isNull() const {return library == 0;}
};
typedef QList<PluginInfo> PluginInfoList;
PluginFactory();
~PluginFactory();
/// Returns the singleton instance of PluginFactory. You won't need to call
/// this directly, use pluginFactory instead.
static PluginFactory* instance();
/// Returns a list of all found plugins' descriptors.
const Plugin::DescriptorList descriptors() const;
/// Returns a list of all found plugins' PluginFactory::PluginInfo objects.
const PluginInfoList& pluginInfos() const;
/// Returns the PluginInfo object of the plugin with the given name.
/// If the plugin is not found, an empty PluginInfo is returned (use
/// PluginInfo::isNull() to check this).
const PluginInfo pluginInfo(const char* name) const;
/// When loading a library fails during discovery, the error string is saved.
/// It can be retrieved by calling this function.
QString errorString(QString pluginName) const;
public slots:
void discoverPlugins();
private:
Plugin::DescriptorList m_descriptorList;
PluginInfoList m_pluginInfos;
QHash<QString, QString> m_errors;
static PluginFactory* s_instance;
};
#define pluginFactory PluginFactory::instance()
#endif // PLUGINFACTORY_H

View File

@@ -1,3 +1,6 @@
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
ADD_SUBDIRECTORY(Amplifier)
ADD_SUBDIRECTORY(audio_file_processor)
ADD_SUBDIRECTORY(BassBooster)

View File

@@ -1,3 +1,5 @@
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/ladspa")
IF(WANT_CAPS)
ADD_SUBDIRECTORY(caps)
ENDIF(WANT_CAPS)

View File

@@ -2,4 +2,5 @@ INCLUDE(BuildPlugin)
INCLUDE_DIRECTORIES(unrtf)
ADD_DEFINITIONS(--std=c++0x)
BUILD_PLUGIN(flpimport FlpImport.cpp unrtf.cpp FlpImport.h)

View File

@@ -51,6 +51,7 @@
#include "Oscillator.h"
#include "Pattern.h"
#include "Piano.h"
#include "PluginFactory.h"
#include "ProjectJournal.h"
#include "ProjectNotes.h"
#include "Song.h"
@@ -1637,22 +1638,19 @@ p->putValue( jt->pos, value, false );
// process all effects
EffectKeyList effKeys;
Plugin::DescriptorList pluginDescs;
Plugin::getDescriptorsOfAvailPlugins( pluginDescs );
for( Plugin::DescriptorList::ConstIterator it = pluginDescs.begin();
it != pluginDescs.end(); ++it )
for (const Plugin::Descriptor* desc : pluginFactory->descriptors())
{
if( it->type != Plugin::Effect )
if( desc->type != Plugin::Effect )
{
continue;
}
if( it->subPluginFeatures )
if( desc->subPluginFeatures )
{
it->subPluginFeatures->listSubPluginKeys( &( *it ), effKeys );
desc->subPluginFeatures->listSubPluginKeys( desc, effKeys );
}
else
{
effKeys << EffectKey( &( *it ), it->name );
effKeys << EffectKey( desc, desc->name );
}
}

View File

@@ -45,6 +45,7 @@ set(LMMS_SRCS
core/Piano.cpp
core/PlayHandle.cpp
core/Plugin.cpp
core/PluginFactory.cpp
core/PresetPreviewPlayHandle.cpp
core/ProjectJournal.cpp
core/ProjectRenderer.cpp

View File

@@ -59,12 +59,6 @@ ConfigManager::ConfigManager() :
#endif
),
m_artworkDir( defaultArtworkDir() ),
#ifdef LMMS_BUILD_WIN32
m_pluginDir( qApp->applicationDirPath()
+ QDir::separator() + "plugins" + QDir::separator() ),
#else
m_pluginDir( qApp->applicationDirPath() + '/' + PLUGIN_DIR ),
#endif
m_vstDir( m_workingDir + "vst" + QDir::separator() ),
m_flDir( QDir::home().absolutePath() ),
m_recoveryFile( QDir(m_workingDir).absoluteFilePath("recover.mmp") )

View File

@@ -57,17 +57,17 @@ void EffectChain::saveSettings( QDomDocument & _doc, QDomElement & _this )
_this.setAttribute( "enabled", m_enabledModel.value() );
_this.setAttribute( "numofeffects", m_effects.count() );
for( EffectList::Iterator it = m_effects.begin(); it != m_effects.end(); it++ )
for( Effect* effect : m_effects)
{
if( dynamic_cast<DummyEffect *>( *it ) )
if( DummyEffect* dummy = dynamic_cast<DummyEffect*>(effect) )
{
_this.appendChild( dynamic_cast<DummyEffect *>( *it )->originalPluginData() );
_this.appendChild( dummy->originalPluginData() );
}
else
{
QDomElement ef = ( *it )->saveState( _doc, _this );
ef.setAttribute( "name", ( *it )->descriptor()->name );
ef.appendChild( ( *it )->key().saveXML( _doc ) );
QDomElement ef = effect->saveState( _doc, _this );
ef.setAttribute( "name", QString::fromUtf8( effect->descriptor()->name ) );
ef.appendChild( effect->key().saveXML( _doc ) );
}
}
}
@@ -94,7 +94,7 @@ void EffectChain::loadSettings( const QDomElement & _this )
const QString name = effectData.attribute( "name" );
EffectKey key( effectData.elementsByTagName( "key" ).item( 0 ).toElement() );
Effect* e = Effect::instantiate( name, this, &key );
Effect* e = Effect::instantiate( name.toUtf8(), this, &key );
if( e != NULL && e->isOkay() && e->nodeName() == node.nodeName() )
{

View File

@@ -32,6 +32,7 @@
#include "PresetPreviewPlayHandle.h"
#include "ProjectJournal.h"
#include "Plugin.h"
#include "PluginFactory.h"
#include "Song.h"
#include "BandLimitedWave.h"
@@ -122,20 +123,13 @@ void Engine::updateFramesPerTick()
void Engine::initPluginFileHandling()
{
Plugin::DescriptorList pluginDescriptors;
Plugin::getDescriptorsOfAvailPlugins( pluginDescriptors );
for( Plugin::DescriptorList::ConstIterator it = pluginDescriptors.begin();
it != pluginDescriptors.end(); ++it )
for (const Plugin::Descriptor* desc : pluginFactory->descriptors())
{
if( it->type == Plugin::Instrument )
if( desc->type == Plugin::Instrument )
{
const QStringList & ext =
QString( it->supportedFileTypes ).
split( QChar( ',' ) );
for( QStringList::const_iterator itExt = ext.begin();
itExt != ext.end(); ++itExt )
for(const QString& ext : QString(desc->supportedFileTypes).split(','))
{
s_pluginFileHandling[*itExt] = it->name;
s_pluginFileHandling[ext] = desc->name;
}
}
}

View File

@@ -2,7 +2,7 @@
* ImportFilter.cpp - base-class for all import-filters (MIDI, FLP etc)
*
* Copyright (c) 2006-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
*
* This file is part of LMMS - http://lmms.io
*
* This program is free software; you can redistribute it and/or
@@ -28,10 +28,10 @@
#include "ImportFilter.h"
#include "Engine.h"
#include "TrackContainer.h"
#include "PluginFactory.h"
#include "ProjectJournal.h"
ImportFilter::ImportFilter( const QString & _file_name,
const Descriptor * _descriptor ) :
Plugin( _descriptor, NULL ),
@@ -52,9 +52,6 @@ ImportFilter::~ImportFilter()
void ImportFilter::import( const QString & _file_to_import,
TrackContainer* tc )
{
DescriptorList d;
Plugin::getDescriptorsOfAvailPlugins( d );
bool successful = false;
char * s = qstrdup( _file_to_import.toUtf8().constData() );
@@ -63,12 +60,11 @@ void ImportFilter::import( const QString & _file_to_import,
const bool j = Engine::projectJournal()->isJournalling();
Engine::projectJournal()->setJournalling( false );
for( Plugin::DescriptorList::ConstIterator it = d.begin();
it != d.end(); ++it )
for (const Plugin::Descriptor* desc : pluginFactory->descriptors())
{
if( it->type == Plugin::ImportFilter )
if( desc->type == Plugin::ImportFilter )
{
Plugin * p = Plugin::instantiate( it->name, NULL, s );
Plugin * p = Plugin::instantiate( desc->name, NULL, s );
if( dynamic_cast<ImportFilter *>( p ) != NULL &&
dynamic_cast<ImportFilter *>( p )->tryImport( tc ) == true )
{

View File

@@ -43,7 +43,7 @@ LadspaManager::LadspaManager()
split( LADSPA_PATH_SEPERATOR );
ladspaDirectories += ConfigManager::inst()->ladspaDir().split( ',' );
ladspaDirectories.push_back( ConfigManager::inst()->pluginDir() + "ladspa" );
ladspaDirectories.push_back( "plugins:ladspa" );
#ifndef LMMS_BUILD_WIN32
ladspaDirectories.push_back( qApp->applicationDirPath() + '/' + LIB_DIR + "ladspa" );
ladspaDirectories.push_back( "/usr/lib/ladspa" );

View File

@@ -91,25 +91,25 @@ AutomatableModel * Plugin::childModel( const QString & )
Plugin * Plugin::instantiate( const QString & pluginName, Model * parent,
#include "PluginFactory.h"
Plugin * Plugin::instantiate( const QString& pluginName, Model * parent,
void * data )
{
QLibrary pluginLibrary( ConfigManager::inst()->pluginDir() + pluginName );
if( pluginLibrary.load() == false )
const PluginFactory::PluginInfo& pi = pluginFactory->pluginInfo(pluginName.toUtf8());
if( pi.isNull() )
{
if( Engine::hasGUI() )
{
QMessageBox::information( NULL,
tr( "Plugin not found" ),
tr( "The plugin \"%1\" wasn't found or could not be loaded!\nReason: \"%2\"" ).
arg( pluginName ).arg( pluginLibrary.errorString() ),
arg( pluginName ).arg( pluginFactory->errorString(pluginName) ),
QMessageBox::Ok | QMessageBox::Default );
}
return new DummyPlugin();
}
InstantiationHook instantiationHook = ( InstantiationHook ) pluginLibrary.resolve( "lmms_plugin_main" );
InstantiationHook instantiationHook = ( InstantiationHook ) pi.library->resolve( "lmms_plugin_main" );
if( instantiationHook == NULL )
{
if( Engine::hasGUI() )
@@ -133,50 +133,6 @@ void Plugin::collectErrorForUI( QString err_msg )
void Plugin::getDescriptorsOfAvailPlugins( DescriptorList& pluginDescriptors )
{
QDir directory( ConfigManager::inst()->pluginDir() );
#ifdef LMMS_BUILD_WIN32
QFileInfoList list = directory.entryInfoList( QStringList( "*.dll" ) );
#else
QFileInfoList list = directory.entryInfoList( QStringList( "lib*.so" ) );
#endif
foreach( const QFileInfo& f, list )
{
QLibrary( f.absoluteFilePath() ).load();
}
foreach( const QFileInfo& f, list )
{
QLibrary pluginLibrary( f.absoluteFilePath() );
if( pluginLibrary.load() == false ||
pluginLibrary.resolve( "lmms_plugin_main" ) == NULL )
{
continue;
}
QString descriptorName = f.baseName() + "_plugin_descriptor";
if( descriptorName.left( 3 ) == "lib" )
{
descriptorName = descriptorName.mid( 3 );
}
Descriptor* pluginDescriptor = (Descriptor *) pluginLibrary.resolve( descriptorName.toUtf8().constData() );
if( pluginDescriptor == NULL )
{
qWarning() << tr( "LMMS plugin %1 does not have a plugin descriptor named %2!" ).
arg( f.absoluteFilePath() ).arg( descriptorName );
continue;
}
pluginDescriptors += *pluginDescriptor;
}
}
PluginView * Plugin::createView( QWidget * parent )
{
PluginView * pv = instantiateView( parent );

173
src/core/PluginFactory.cpp Normal file
View File

@@ -0,0 +1,173 @@
/*
* PluginFactory.cpp
*
* Copyright (c) 2015 Lukas W <lukaswhl/at/gmail.com>
*
* This file is part of LMMS - http://lmms.io
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program (see COPYING); if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
*/
#include "PluginFactory.h"
#include <QtCore/QCoreApplication>
#include <QtCore/QDebug>
#include <QtCore/QDir>
#include <QtCore/QFileInfo>
#include <QtCore/QLibrary>
#include "Plugin.h"
#ifdef LMMS_BUILD_WIN32
QStringList nameFilters("*.dll");
#else
QStringList nameFilters("lib*.so");
#endif
PluginFactory* PluginFactory::s_instance = nullptr;
PluginFactory::PluginFactory()
{
// Adds a search path relative to the main executable to if the path exists.
auto addRelativeIfExists = [this] (const QString& path) {
QDir dir(qApp->applicationDirPath());
if (!path.isEmpty() && dir.cd(path)) {
QDir::addSearchPath("plugins", dir.absolutePath());
}
};
// We're either running LMMS installed on an Unixoid or we're running a
// portable version like we do on Windows.
// We want to find our plugins in both cases:
// (a) Installed (Unix):
// e.g. binary at /usr/bin/lmms - plugin dir at /usr/lib/lmms/
// (b) Portable:
// e.g. binary at "C:/Program Files/LMMS/lmms.exe"
// plugins at "C:/Program Files/LMMS/plugins/"
#ifndef LMMS_BUILD_WIN32
addRelativeIfExists("../lib/lmms"); // Installed
#endif
addRelativeIfExists("plugins"); // Portable
#ifdef PLUGIN_DIR // We may also have received a relative directory via a define
addRelativeIfExists(PLUGIN_DIR);
#endif
// Or via an environment variable:
QString env_path;
if (!(env_path = qgetenv("LMMS_PLUGIN_DIR")).isEmpty())
QDir::addSearchPath("plugins", env_path);
discoverPlugins();
}
PluginFactory::~PluginFactory()
{
}
PluginFactory* PluginFactory::instance()
{
if (s_instance == nullptr)
s_instance = new PluginFactory();
return s_instance;
}
const Plugin::DescriptorList PluginFactory::descriptors() const
{
return m_descriptorList;
}
const QList<PluginFactory::PluginInfo>& PluginFactory::pluginInfos() const
{
return m_pluginInfos;
}
const PluginFactory::PluginInfo PluginFactory::pluginInfo(const char* name) const
{
for (const PluginInfo& info : m_pluginInfos)
{
if (qstrcmp(info.descriptor->name, name) == 0)
return info;
}
return PluginInfo();
}
QString PluginFactory::errorString(QString pluginName) const
{
static QString notfound = qApp->translate("PluginFactory", "Plugin not found.");
return m_errors.value(pluginName, notfound);
}
void PluginFactory::discoverPlugins()
{
Plugin::DescriptorList descriptors;
PluginInfoList pluginInfos;
const QFileInfoList& files = QDir("plugins:").entryInfoList(nameFilters);
// Cheap dependency handling: zynaddsubfx needs ZynAddSubFxCore. By loading
// all libraries twice we ensure that libZynAddSubFxCore is found.
for (const QFileInfo& file : files)
{
QLibrary(file.absoluteFilePath()).load();
}
for (const QFileInfo& file : files)
{
QLibrary* library = new QLibrary(file.absoluteFilePath());
if (! library->load()) {
m_errors[file.baseName()] = library->errorString();
continue;
}
if (library->resolve("lmms_plugin_main") == nullptr) {
continue;
}
QString descriptorName = file.baseName() + "_plugin_descriptor";
if( descriptorName.left(3) == "lib" )
{
descriptorName = descriptorName.mid(3);
}
Plugin::Descriptor* pluginDescriptor = (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;
}
PluginInfo info;
info.file = file;
info.library = library;
info.descriptor = pluginDescriptor;
pluginInfos << info;
descriptors << pluginDescriptor;
}
for (PluginInfo& info : m_pluginInfos)
{
delete info.library;
}
m_pluginInfos = pluginInfos;
m_descriptorList = descriptors;
}

View File

@@ -130,8 +130,7 @@ bool RemotePlugin::init( const QString &pluginExecutable,
reset( new shmFifo(), new shmFifo() );
m_failed = false;
}
QString exec = ConfigManager::inst()->pluginDir() +
pluginExecutable;
QString exec = QFileInfo(QDir("plugins:"), pluginExecutable).absoluteFilePath();
QStringList args;
// swap in and out for bidirectional communication

View File

@@ -28,6 +28,7 @@
#include "gui_templates.h"
#include "embed.h"
#include "PluginFactory.h"
EffectSelectDialog::EffectSelectDialog( QWidget * _parent ) :
@@ -42,31 +43,29 @@ EffectSelectDialog::EffectSelectDialog( QWidget * _parent ) :
setWindowIcon( embed::getIconPixmap( "setup_audio" ) );
// query effects
Plugin::getDescriptorsOfAvailPlugins( m_pluginDescriptors );
EffectKeyList subPluginEffectKeys;
for( Plugin::DescriptorList::ConstIterator it = m_pluginDescriptors.begin();
it != m_pluginDescriptors.end(); ++it )
for (const Plugin::Descriptor* desc: pluginFactory->descriptors())
{
if( it->type != Plugin::Effect )
if( desc->type != Plugin::Effect )
{
continue;
}
if( it->subPluginFeatures )
if( desc->subPluginFeatures )
{
it->subPluginFeatures->listSubPluginKeys(
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"
&( *it ),
desc,
subPluginEffectKeys );
}
else
{
m_effectKeys << EffectKey( &( *it ), it->name );
m_effectKeys << EffectKey( desc, desc->name );
}
}

View File

@@ -54,6 +54,7 @@
#include "SideBar.h"
#include "ConfigManager.h"
#include "Mixer.h"
#include "PluginFactory.h"
#include "PluginView.h"
#include "ProjectNotes.h"
#include "SetupDialog.h"
@@ -296,17 +297,13 @@ void MainWindow::finalize()
m_toolsMenu = new QMenu( this );
Plugin::DescriptorList pluginDescriptors;
Plugin::getDescriptorsOfAvailPlugins( pluginDescriptors );
for( Plugin::DescriptorList::ConstIterator it = pluginDescriptors.begin();
it != pluginDescriptors.end(); ++it )
for( const Plugin::Descriptor* desc : pluginFactory->descriptors() )
{
if( it->type == Plugin::Tool )
if( desc->type == Plugin::Tool )
{
m_toolsMenu->addAction( it->logo->pixmap(),
it->displayName );
m_tools.push_back( ToolPlugin::instantiate( it->name,
/*this*/NULL )->createView( this ) );
m_toolsMenu->addAction( desc->logo->pixmap(), desc->displayName );
m_tools.push_back( ToolPlugin::instantiate( desc->name, /*this*/NULL )
->createView(this) );
}
}
if( !m_toolsMenu->isEmpty() )

View File

@@ -22,25 +22,27 @@
*
*/
#include "PluginBrowser.h"
#include <algorithm> // for std::sort
#include <QLabel>
#include <QPainter>
#include <QCursor>
#include <QMouseEvent>
#include <QScrollArea>
#include "PluginBrowser.h"
#include <algorithm> // for std::sort
#include "embed.h"
#include "debug.h"
#include "templates.h"
#include "gui_templates.h"
#include "StringPairDrag.h"
#include "PluginFactory.h"
bool pluginBefore( const Plugin::Descriptor& d1, const Plugin::Descriptor& d2 )
bool pluginBefore( const Plugin::Descriptor* d1, const Plugin::Descriptor* d2 )
{
return qstricmp( d1.displayName, d2.displayName ) < 0 ? true : false;
return qstricmp( d1->displayName, d2->displayName ) < 0 ? true : false;
}
@@ -93,15 +95,13 @@ PluginDescList::PluginDescList(QWidget *parent) :
{
QVBoxLayout* layout = new QVBoxLayout(this);
Plugin::getDescriptorsOfAvailPlugins( m_pluginDescriptors );
std::sort(m_pluginDescriptors.begin(), m_pluginDescriptors.end(), pluginBefore);
for( Plugin::DescriptorList::const_iterator it = m_pluginDescriptors.constBegin();
it != m_pluginDescriptors.constEnd(); ++it )
QList<Plugin::Descriptor*> descs = pluginFactory->descriptors();
std::sort(descs.begin(), descs.end(), pluginBefore);
for (const Plugin::Descriptor* desc : descs)
{
if( it->type == Plugin::Instrument )
if( desc->type == Plugin::Instrument )
{
PluginDescWidget* p = new PluginDescWidget( *it, this );
PluginDescWidget* p = new PluginDescWidget( *desc, this );
p->show();
layout->addWidget(p);
}