]> Creatis software - cpPlugins.git/blobdiff - lib/cpPlugins/Interface/Plugins.cxx
...
[cpPlugins.git] / lib / cpPlugins / Interface / Plugins.cxx
index 99aaebb012b0dbd5bc4d66027899f7a7fa89c99a..eabd53ef905e45048dd4530530b360b014a2bb43 100644 (file)
 #include <cpPlugins/Interface/Plugins.h>
-#include <cpPlugins/Interface/Config.h>
-
-#include <fstream>
-#include <sstream>
-
-#ifdef cpPlugins_Interface_QT4
-
-#include <QApplication>
-#include <QFileDialog>
-#include <QMenu>
-#include <QMessageBox>
-#include <QWidget>
-
-#ifdef _WIN32
-#  define PLUGIN_PREFIX ""
-#  define PLUGIN_EXT "dll"
-#  define PLUGIN_REGEX "Plugins file (*.dll);;All files (*)"
-#else // Linux
-#  define PLUGIN_PREFIX "lib"
-#  define PLUGIN_EXT "so"
-#  define PLUGIN_REGEX "Plugins file (*.so);;All files (*)"
-#endif // _WIN32
-
-#endif // cpPlugins_Interface_QT4
+#include <cpPlugins/OS/DLLManager.h>
+#include <cpPlugins/OS/DirContents.h>
+#include <cpExtensions/Utility.h>
 
 // -------------------------------------------------------------------------
 cpPlugins::Interface::Plugins::
-Plugins( QWidget* widget )
-  : m_Widget( widget ),
-    m_Application( NULL ),
-    m_LastLoadedPlugin( "." )
+Pointer cpPlugins::Interface::Plugins::
+New( )
 {
+  static Pointer singleton = NULL;
+  if( singleton.IsNull( ) )
+    singleton = new Self( );
+  return( singleton );
 }
 
 // -------------------------------------------------------------------------
-cpPlugins::Interface::Plugins::
-~Plugins( )
+itk::LightObject::Pointer cpPlugins::Interface::Plugins::
+CreateAnother( ) const
 {
-  // TODO: this causes a segfault? this->m_Interface.UnloadAll( );
+  itk::LightObject::Pointer smartPtr;
+  smartPtr = NULL;
+  return( smartPtr );
 }
 
 // -------------------------------------------------------------------------
-QWidget* cpPlugins::Interface::Plugins::
-GetWidget( )
+cpPlugins::Interface::Plugins::
+Pointer cpPlugins::Interface::Plugins::
+Clone( ) const
 {
-  return( this->m_Widget );
+  Pointer r = NULL;
+  return( r );
 }
 
 // -------------------------------------------------------------------------
-const QWidget* cpPlugins::Interface::Plugins::
-GetWidget( ) const
+cpPlugins::Interface::Plugins::
+TStrings cpPlugins::Interface::Plugins::
+GetLibraries( ) const
 {
-  return( this->m_Widget );
+  TStrings res;
+  for(
+    auto i = this->m_Libraries.begin( ); i != this->m_Libraries.end( ); ++i
+    )
+    res.insert( i->first );
+  return( res );
 }
 
 // -------------------------------------------------------------------------
-void cpPlugins::Interface::Plugins::
-SetWidget( QWidget* widget )
+cpPlugins::Interface::Plugins::
+TStrings cpPlugins::Interface::Plugins::
+GetPlugins( ) const
 {
-  this->m_Widget = widget;
+  TStrings res;
+  for( auto i = this->m_Plugins.begin( ); i != this->m_Plugins.end( ); ++i )
+    res.insert( i->first );
+  return( res );
 }
 
 // -------------------------------------------------------------------------
-void cpPlugins::Interface::Plugins::
-BlockWidget( )
+cpPlugins::Interface::Plugins::
+TStrings cpPlugins::Interface::Plugins::
+GetCategories( ) const
 {
-#ifdef cpPlugins_Interface_QT4
-  if( this->m_Widget != NULL )
-  {
-    QApplication::setOverrideCursor( Qt::WaitCursor );
-    this->m_Widget->setEnabled( false );
-
-  } // fi
-#endif // cpPlugins_Interface_QT4
+  TStrings res;
+  for( auto i = this->m_Filters.begin( ); i != this->m_Filters.end( ); ++i )
+    res.insert( i->first );
+  return( res );
 }
 
 // -------------------------------------------------------------------------
-void cpPlugins::Interface::Plugins::
-UnblockWidget( )
+cpPlugins::Interface::Plugins::
+TStrings cpPlugins::Interface::Plugins::
+GetFilters( const std::string& category ) const
 {
-#ifdef cpPlugins_Interface_QT4
-  if( this->m_Widget != NULL )
-  {
-    QApplication::restoreOverrideCursor( );
-    this->m_Widget->setEnabled( true );
-
-  } // fi
-#endif // cpPlugins_Interface_QT4
+  TStrings res;
+  auto cIt = this->m_Filters.find( category );
+  if( cIt != this->m_Filters.end( ) )
+    for( auto i = cIt->second.begin( ); i != cIt->second.end( ); ++i )
+      res.insert( i->first );
+  return( res );
 }
 
 // -------------------------------------------------------------------------
 void cpPlugins::Interface::Plugins::
-DialogLoadPlugins( )
+AddEnvironments( const std::string& env )
 {
-#ifdef cpPlugins_Interface_QT4
-  if( this->m_Widget != NULL )
-  {
-    QFileDialog dialog( this->m_Widget );
-    dialog.setFileMode( QFileDialog::ExistingFile );
-    dialog.setDirectory( this->m_LastLoadedPlugin.c_str( ) );
-    dialog.setNameFilter( QFileDialog::tr( PLUGIN_REGEX ) );
-    dialog.setDefaultSuffix( QFileDialog::tr( PLUGIN_EXT ) );
-    if( !( dialog.exec( ) ) )
-      return;
-
-    std::string fname = dialog.selectedFiles( ).at( 0 ).toStdString( );
-    if( !( this->LoadPlugins( fname ) ) )
-      QMessageBox::critical(
-        this->m_Widget,
-        QMessageBox::tr( "Ignoring plugin" ),
-        QMessageBox::tr( fname.c_str( ) )
-        );
-
-  } // fi
-#endif // cpPlugins_Interface_QT4
+  std::vector< std::string > directories;
+  cpExtensions::Tokenize( directories, env, cpPlugins_ENV_SEPARATOR );
+  for( auto dir = directories.begin( ); dir != directories.end( ); ++dir )
+    this->m_Paths.insert( cpExtensions::CanonicalPath( *dir ) );
 }
 
 // -------------------------------------------------------------------------
 void cpPlugins::Interface::Plugins::
-AssociatePluginsToMenu( QMenu* menu, QObject* obj, const char* slot )
+LoadEnvironments( )
 {
-#ifdef cpPlugins_Interface_QT4
-  std::map< std::string, std::set< std::string > >::const_iterator i;
-  std::set< std::string >::const_iterator j;
-
-  menu->clear( );
-  for( i = this->m_Filters.begin( ); i != this->m_Filters.end( ); i++ )
+  std::set< std::string > libs;
+  for( auto d = this->m_Paths.begin( ); d != this->m_Paths.end( ); ++d )
   {
-    QMenu* newMenu = menu->addMenu( i->first.c_str( ) );
-    for( j = i->second.begin( ); j != i->second.end( ); ++j )
+    std::stringstream fname;
+    fname << *d << cpPlugins_PATH_SEPARATOR << cpPlugins_CONFIG;
+    std::string buffer;
+    if( cpExtensions::Read( buffer, fname.str( ) ) )
     {
-      QAction* a = newMenu->addAction( j->c_str( ) );
-      QObject::connect( a, SIGNAL( triggered( ) ), obj, slot );
+      std::istringstream input( buffer );
+      for( std::string line; std::getline( input, line ); )
+      {
+        auto pos = line.find( "*" );
+        if( pos != std::string::npos )
+        {
+          std::string dname, fname;
+          cpPlugins::OS::SplitPath( dname, fname, line );
+          auto files = cpPlugins::OS::LoadDirContents( dname, false, fname );
+          for( auto fIt = files.begin( ); fIt != files.end( ); ++fIt )
+            libs.insert( *fIt );
+        }
+        else
+          libs.insert( line );
+
+      } // rof
 
-    } // rof
+    } // fi
 
   } // rof
-#endif // cpPlugins_Interface_QT4
-}
-
-// -------------------------------------------------------------------------
-cpPlugins::Interface::
-BasePluginsApplication* cpPlugins::Interface::Plugins::
-GetApplication( )
-{
-  return( this->m_Application );
-}
-
-// -------------------------------------------------------------------------
-const cpPlugins::Interface::
-BasePluginsApplication* cpPlugins::Interface::Plugins::
-GetApplication( ) const
-{
-  return( this->m_Application );
-}
 
-// -------------------------------------------------------------------------
-void cpPlugins::Interface::Plugins::
-SetApplication( cpPlugins::Interface::BasePluginsApplication* a )
-{
-  this->m_Application = a;
-}
-
-// -------------------------------------------------------------------------
-bool cpPlugins::Interface::Plugins::
-LoadPlugins( const std::string& fname )
-{
-  this->BlockWidget( );
-
-  // Is it already loaded?
-  bool ret = true;
-  if( this->m_LoadedPlugins.find( fname ) == this->m_LoadedPlugins.end( ) )
+  for( auto l = libs.begin( ); l != libs.end( ); ++l )
   {
-    // Was it succesfully loaded?
-    ret = this->m_Interface.Load( fname );
-
-    // Update a simple track
-    if( ret )
+    std::string lib = cpExtensions::CanonicalPath( *l );
+    if( lib != "" )
     {
-      this->m_LoadedPlugins.insert( fname );
-      this->m_LastLoadedPlugin = fname;
-      this->_UpdateLoadedPluginsInformation( );
+      if( this->m_Libraries.find( lib ) == this->m_Libraries.end( ) )
+      {
+        std::string error = "";
+        void* hnd = cpPlugins::OS::DLLManager::Load( lib, error );
+        if( hnd != NULL )
+          this->m_Libraries[ lib ] = hnd;
 
-    } // fi
+      } // fi
 
-  } // fi
+    } // fi
 
-  this->UnblockWidget( );
-  return( ret );
+  } // rof
 }
 
 // -------------------------------------------------------------------------
-bool cpPlugins::Interface::Plugins::
-LoadPluginsConfigurationFile( const std::string& fname )
-{
-  // Load file into a char buffer
-  std::ifstream in(
-    fname.c_str( ), std::ios::in | std::ios::binary | std::ios::ate
-    );
-  if( !in.is_open( ) )
-    return( false );
-
-  std::streampos size = in.tellg( );
-  char* buffer = new char[ size ];
-  in.seekg( 0, std::ios::beg );
-  in.read( buffer, size );
-  in.close( );
-
-  // Read stream
-  std::stringstream in_stream( buffer );
-  char line[ 4096 ];
-  while( in_stream )
+void cpPlugins::Interface::Plugins::
+LoadPaths( const std::string& dir )
+{
+  std::stringstream fname, envs;
+  fname << dir;
+  if( !cpExtensions::IsPathSeparator( dir.back( ) ) )
+    fname << cpExtensions_PATH_SEPARATOR;
+  fname << cpPlugins_PATHS;
+  std::string buffer;
+  if( cpExtensions::Read( buffer, fname.str( ) ) )
   {
-    in_stream.getline( line, 4096 );
-    this->LoadPlugins( line );
+    std::istringstream input( buffer );
+    for( std::string line; std::getline( input, line ); )
+      envs << line << cpPlugins_ENV_SEPARATOR;
 
-  } // elihw
-  delete buffer;
-
-  return( true );
+  } // fi
+  if( envs.str( ).size( ) > 0 )
+    this->AddEnvironments( envs.str( ) );
 }
 
 // -------------------------------------------------------------------------
 void cpPlugins::Interface::Plugins::
-AddInteractor( vtkRenderWindowInteractor* interactor )
+SavePaths( const std::string& dir ) const
 {
-  this->m_Interactors.insert( interactor );
-}
+  std::stringstream buffer;
+  for( auto i = this->m_Paths.begin( ); i != this->m_Paths.end( ); ++i )
+    buffer << *i << std::endl;
 
-// -------------------------------------------------------------------------
-void cpPlugins::Interface::Plugins::
-RemoveInteractor( vtkRenderWindowInteractor* interactor )
-{
-  this->m_Interactors.erase( interactor );
+  std::stringstream fname;
+  fname << dir;
+  if( !cpExtensions::IsPathSeparator( dir.back( ) ) )
+    fname << cpExtensions_PATH_SEPARATOR;
+  fname << cpPlugins_PATHS;
+  if( !cpExtensions::Write( buffer.str( ), fname.str( ) ) )
+    throw std::runtime_error( "Error writing environment file." );
 }
 
 // -------------------------------------------------------------------------
 void cpPlugins::Interface::Plugins::
-ClearInteractors( )
-{
-  this->m_Interactors.clear( );
-}
-
-// -------------------------------------------------------------------------
-bool cpPlugins::Interface::Plugins::
-HasImageReader( ) const
-{
-  return( this->m_ImageReader.IsNotNull( ) );
-}
-
-// -------------------------------------------------------------------------
-bool cpPlugins::Interface::Plugins::
-HasDicomSeriesReader( ) const
-{
-  return( this->m_DicomSeriesReader.IsNotNull( ) );
-}
-
-// -------------------------------------------------------------------------
-bool cpPlugins::Interface::Plugins::
-HasMeshReader( ) const
-{
-  return( this->m_MeshReader.IsNotNull( ) );
-}
-
-// -------------------------------------------------------------------------
-bool cpPlugins::Interface::Plugins::
-HasImageWriter( ) const
-{
-  return( this->m_ImageWriter.IsNotNull( ) );
-}
-
-// -------------------------------------------------------------------------
-bool cpPlugins::Interface::Plugins::
-HasMeshWriter( ) const
-{
-  return( this->m_MeshWriter.IsNotNull( ) );
-}
-
-// -------------------------------------------------------------------------
-std::string cpPlugins::Interface::Plugins::
-ReadImage( const std::string& fname, const std::string& parent )
-{
-  std::vector< std::string > fnames;
-  fnames.push_back( fname );
-  return( this->ReadImage( fnames, parent ) );
-}
-
-// -------------------------------------------------------------------------
-std::string cpPlugins::Interface::Plugins::
-ReadImage(
-  const std::vector< std::string >& fnames, const std::string& parent
-  )
-{
-  // Check if object exists
-  if( this->m_ImageReader.IsNull( ) )
-    return( "" );
-
-  // Configure object
-  TParameters* params = this->m_ImageReader->GetParameters( );
-  params->ClearStringList( "FileNames" );
-  auto i = fnames.begin( );
-  for( ; i != fnames.end( ); ++i )
-    params->AddToStringList( "FileNames", *i );
-
-  // Execute filter
-  this->BlockWidget( );
-  std::string err = this->m_ImageReader->Update( );
-  this->UnblockWidget( );
-
-  // Get result, if any
-  if( err == "" )
-  {
-    TImage* image = this->m_ImageReader->GetOutput< TImage >( "Output" );
-    this->m_ImageReader->DisconnectOutputs( );
-
-    // Add newly added data
-    if( this->_InsertNewData( image, parent ) )
-      return( image->GetName( ) );
-    else
-      return( "" );
-  }
-  else
-  {
-#ifdef cpPlugins_Interface_QT4
-    if( this->m_Widget != NULL )
-      QMessageBox::critical(
-        this->m_Widget,
-        QMessageBox::tr( "Error reading image." ),
-        QMessageBox::tr( err.c_str( ) )
-        );
-#else // cpPlugins_Interface_QT4
-    std::cerr << "Error reading image: " << err << std::endl;
-#endif // cpPlugins_Interface_QT4
-    return( "" );
-
-  } // fi
-}
-
-// -------------------------------------------------------------------------
-std::string cpPlugins::Interface::Plugins::
-ReadImage( const std::string& parent )
-{
-  // Check if object exists
-  if( this->m_ImageReader.IsNull( ) )
-    return( "" );
-
-  // Configure object
-  TProcessObject::DialogResult dret =
-    this->m_ImageReader->ExecConfigurationDialog( this->m_Widget );
-  if( dret == TProcessObject::DialogResult_Cancel )
-    return( "" );
-
-  // Execute filter
-  this->BlockWidget( );
-  std::string err = this->m_ImageReader->Update( );
-  this->UnblockWidget( );
-
-  // Get result, if any
-  if( err == "" )
-  {
-    TImage* image = this->m_ImageReader->GetOutput< TImage >( "Output" );
-    this->m_ImageReader->DisconnectOutputs( );
+LoadFile( const std::string& fname )
+{
+  // Resolve canonical filename
+  std::string can_name = cpExtensions::CanonicalPath( fname );
+  if( can_name == "" )
+    throw std::runtime_error(
+      std::string( "Loading file: can't find library \"" ) +
+      fname +
+      std::string( "\"" )
+      );
+  if( this->m_Plugins.find( can_name ) != this->m_Plugins.end( ) )
+    return;
+
+  // Load the library
+  std::string error = "";
+  void* hnd = cpPlugins::OS::DLLManager::Load( can_name, error );
+  if( hnd == NULL )
+    throw std::runtime_error(
+      std::string( "Loading plugin library: " ) + error
+      );
 
-    // Add newly added data
-    if( this->_InsertNewData( image, parent ) )
-      return( image->GetName( ) );
-    else
-      return( "" );
-  }
-  else
+  // Get plugins name
+  typedef const char* ( *_TFunction )( );
+  _TFunction plugins_name_function = ( _TFunction )(
+    cpPlugins::OS::DLLManager::GetFunctionHandle( hnd, "cpPlugins_Name" )
+    );
+  if( plugins_name_function == NULL )
   {
-#ifdef cpPlugins_Interface_QT4
-    if( this->m_Widget != NULL )
-      QMessageBox::critical(
-        this->m_Widget,
-        QMessageBox::tr( "Error reading image." ),
-        QMessageBox::tr( err.c_str( ) )
-        );
-#else // cpPlugins_Interface_QT4
-    std::cerr << "Error reading image: " << err << std::endl;
-#endif // cpPlugins_Interface_QT4
-    return( "" );
+    cpPlugins::OS::DLLManager::UnLoad( hnd );
+    throw std::runtime_error(
+      std::string( "Library \"" ) +
+      can_name +
+      std::string( "\" not recognized as a cpPlugins library" )
+      );
 
   } // fi
-}
-
-// -------------------------------------------------------------------------
-std::string cpPlugins::Interface::Plugins::
-ReadDicomSeries( const std::string& parent )
-{
-  // Check if object exists
-  if( this->m_DicomSeriesReader.IsNull( ) )
-    return( "" );
-
-  // Configure object
-  TProcessObject::DialogResult dret =
-    this->m_DicomSeriesReader->ExecConfigurationDialog( this->m_Widget );
-  if( dret == TProcessObject::DialogResult_Cancel )
-    return( "" );
-
-  // Execute filter
-  this->BlockWidget( );
-  std::string err = this->m_DicomSeriesReader->Update( );
-  this->UnblockWidget( );
-
-  // Get result, if any
-  if( err == "" )
-  {
-    TImage* image =
-      this->m_DicomSeriesReader->GetOutput< TImage >( "Output" );
-    this->m_DicomSeriesReader->DisconnectOutputs( );
+  std::string plugins_name = plugins_name_function( );
 
-    // Add newly added data
-    if( this->_InsertNewData( image, parent ) )
-      return( image->GetName( ) );
-    else
-      return( "" );
-  }
-  else
+  // Get loaded filters
+  _TFunction function = ( _TFunction )(
+    cpPlugins::OS::DLLManager::GetFunctionHandle( hnd, "cpPlugins_LoadedFilters" )
+    );
+  if( function == NULL )
   {
-#ifdef cpPlugins_Interface_QT4
-    if( this->m_Widget != NULL )
-      QMessageBox::critical(
-        this->m_Widget,
-        QMessageBox::tr( "Error reading image." ),
-        QMessageBox::tr( err.c_str( ) )
-        );
-#else // cpPlugins_Interface_QT4
-    std::cerr << "Error reading image: " << err << std::endl;
-#endif // cpPlugins_Interface_QT4
-    return( "" );
+    cpPlugins::OS::DLLManager::UnLoad( hnd );
+    throw std::runtime_error(
+      std::string( "Library \"" ) +
+      can_name +
+      std::string( "\" not recognized as a cpPlugins library" )
+      );
 
   } // fi
-}
-
-// -------------------------------------------------------------------------
-std::string cpPlugins::Interface::Plugins::
-ReadMesh( const std::string& fname, const std::string& parent )
-{
-  // Check if object exists
-  if( this->m_MeshReader.IsNull( ) )
-    return( "" );
-
-  // Configure object
-  TParameters* params = this->m_MeshReader->GetParameters( );
-  params->SetString( "FileName", fname );
-
-  // Execute filter
-  this->BlockWidget( );
-  std::string err = this->m_MeshReader->Update( );
-  this->UnblockWidget( );
-
-  // Get result, if any
-  if( err == "" )
+  std::string descriptors = function( );
+  std::replace( descriptors.begin( ), descriptors.end( ), ';', ' ' );
+  std::istringstream str( descriptors );
+  TFilters filters;
+  while( str )
   {
-    TMesh* mesh = this->m_MeshReader->GetOutput< TMesh >( "Output" );
-    this->m_MeshReader->DisconnectOutputs( );
-
-    // Add newly added data
-    if( this->_InsertNewData( mesh, parent ) )
-      return( mesh->GetName( ) );
-    else
-      return( "" );
-  }
-  else
-  {
-#ifdef cpPlugins_Interface_QT4
-    if( this->m_Widget != NULL )
-      QMessageBox::critical(
-        this->m_Widget,
-        QMessageBox::tr( "Error reading mesh." ),
-        QMessageBox::tr( err.c_str( ) )
+    std::string value, category, name;
+    str >> value;
+    if( value == "" )
+      continue;
+    std::replace( value.begin( ), value.end( ), ':', ' ' );
+    std::istringstream value_str( value );
+    value_str >> category >> name;
+
+    // Check if the filter has been already loaded
+    bool found = false;
+    auto fIt = this->m_Filters.find( category );
+    if( fIt != this->m_Filters.end( ) )
+      found = fIt->second.find( name ) != fIt->second.end( );
+    if( found )
+    {
+      cpPlugins::OS::DLLManager::UnLoad( hnd );
+      throw std::runtime_error(
+        std::string( "Filter \"" ) +
+        category + std::string( "::" ) + name +
+        std::string( "\" already exists." )
         );
-#else // cpPlugins_Interface_QT4
-    std::cerr << "Error reading mesh: " << err << std::endl;
-#endif // cpPlugins_Interface_QT4
-    return( "" );
-
-  } // fi
-}
-
-// -------------------------------------------------------------------------
-std::string cpPlugins::Interface::Plugins::
-ReadMesh( const std::string& parent )
-{
-  // Check if object exists
-  if( this->m_MeshReader.IsNull( ) )
-    return( "" );
-
-  // Configure object
-  TProcessObject::DialogResult dret =
-    this->m_MeshReader->ExecConfigurationDialog( this->m_Widget );
-  if( dret == TProcessObject::DialogResult_Cancel )
-    return( "" );
 
-  // Execute filter
-  this->BlockWidget( );
-  std::string err = this->m_MeshReader->Update( );
-  this->UnblockWidget( );
-
-  // Get result, if any
-  if( err == "" )
-  {
-    TMesh* mesh = this->m_MeshReader->GetOutput< TMesh >( "Output" );
-    this->m_MeshReader->DisconnectOutputs( );
+    } // fi
 
-    // Add newly added data
-    if( this->_InsertNewData( mesh, parent ) )
-      return( mesh->GetName( ) );
-    else
-      return( "" );
-  }
-  else
-  {
-#ifdef cpPlugins_Interface_QT4
-    if( this->m_Widget != NULL )
-      QMessageBox::critical(
-        this->m_Widget,
-        QMessageBox::tr( "Error reading mesh." ),
-        QMessageBox::tr( err.c_str( ) )
+    // Get filter creator
+    TCreator creator = ( TCreator )(
+      cpPlugins::OS::DLLManager::GetFunctionHandle(
+        hnd, category + "_" + name
+        )
+      );
+    if( creator == NULL )
+    {
+      cpPlugins::OS::DLLManager::UnLoad( hnd );
+      throw std::runtime_error(
+        std::string( "Filter \"" ) +
+        category + std::string( "::" ) + name +
+        std::string( "\" does not have a valid creator." )
         );
-#else // cpPlugins_Interface_QT4
-    std::cerr << "Error reading mesh: " << err << std::endl;
-#endif // cpPlugins_Interface_QT4
-    return( "" );
 
-  } // fi
-}
-
-// -------------------------------------------------------------------------
-bool cpPlugins::Interface::Plugins::
-WriteImage( const std::string& fname, const std::string& name )
-{
-  // Check if objects exist
-  if( this->m_ImageWriter.IsNull( ) )
-    return( false );
-  TImage* image = this->GetImage( name );
-  if( image == NULL )
-    return( false );
+    } // fi
 
-  // Configure writer
-  this->m_ImageWriter->GetParameters( )->SetString( "FileName", fname );
-  this->m_ImageWriter->SetInput( "Input", image );
+    TCreatorData data;
+    data.PluginName = plugins_name;
+    data.LibraryHandle = hnd;
+    data.Creator = creator;
+    filters[ category ][ name ] = data;
 
-  // Execute filter
-  this->BlockWidget( );
-  std::string err = this->m_ImageWriter->Update( );
-  this->UnblockWidget( );
+  } // elihw
 
-  // Get result, if any
-  if( err != "" )
-  {
-#ifdef cpPlugins_Interface_QT4
-    if( this->m_Widget != NULL )
-      QMessageBox::critical(
-        this->m_Widget,
-        QMessageBox::tr( "Error reading mesh." ),
-        QMessageBox::tr( err.c_str( ) )
-        );
-#else // cpPlugins_Interface_QT4
-    std::cerr << "Error reading mesh: " << err << std::endl;
-#endif // cpPlugins_Interface_QT4
-    return( false );
-  }
-  else
-    return( true );
+  // Keep track of all loaded handlers
+  for( auto cIt = filters.begin( ); cIt != filters.end( ); ++cIt )
+    for( auto nIt = cIt->second.begin( ); nIt != cIt->second.end( ); ++nIt )
+      this->m_Filters[ cIt->first ][ nIt->first ] = nIt->second;
+  this->m_Plugins[ can_name ] = hnd;
 }
 
 // -------------------------------------------------------------------------
-bool cpPlugins::Interface::Plugins::
-WriteImage( const std::string& name )
+void cpPlugins::Interface::Plugins::
+LoadPlugin( const std::string& pname )
 {
-  // Check if objects exist
-  if( this->m_ImageWriter.IsNull( ) )
-    return( false );
-  TImage* image = this->GetImage( name );
-  if( image == NULL )
-    return( false );
-
-  // Configure writer
-  TProcessObject::DialogResult dret = 
-    this->m_ImageWriter->ExecConfigurationDialog( this->m_Widget );
-  if( dret == TProcessObject::DialogResult_Cancel )
-    return( "" );
-  this->m_ImageWriter->SetInput( "Input", image );
-
-  // Execute filter
-  this->BlockWidget( );
-  std::string err = this->m_ImageWriter->Update( );
-  this->UnblockWidget( );
-
-  // Get result, if any
-  if( err != "" )
+  std::stringstream fname;
+  fname << cpPlugins_LIB_PREFIX << pname << cpPlugins_LIB_EXT;
+  unsigned int count = 0;
+  for( auto i = this->m_Paths.begin( ); i != this->m_Paths.end( ); ++i )
   {
-#ifdef cpPlugins_Interface_QT4
-    if( this->m_Widget != NULL )
-      QMessageBox::critical(
-        this->m_Widget,
-        QMessageBox::tr( "Error reading mesh." ),
-        QMessageBox::tr( err.c_str( ) )
-        );
-#else // cpPlugins_Interface_QT4
-    std::cerr << "Error reading mesh: " << err << std::endl;
-#endif // cpPlugins_Interface_QT4
-    return( false );
-  }
-  else
-    return( true );
-}
-
-// -------------------------------------------------------------------------
-bool cpPlugins::Interface::Plugins::
-WriteMesh( const std::string& fname, const std::string& name )
-{
-  // Check if objects exist
-  if( this->m_MeshWriter.IsNull( ) )
-    return( false );
-  TMesh* mesh = this->GetMesh( name );
-  if( mesh == NULL )
-    return( false );
+    std::stringstream dir;
+    dir << *i;
+    if( !cpExtensions::IsPathSeparator( i->back( ) ) )
+      dir << cpExtensions_PATH_SEPARATOR;
+    dir << fname.str( );
+    try
+    {
+      this->LoadFile( dir.str( ) );
+    }
+    catch( ... )
+    {
+      count++;
 
-  // Configure writer
-  this->m_MeshWriter->GetParameters( )->SetString( "FileName", fname );
-  this->m_MeshWriter->SetInput( "Input", mesh );
+    } // yrt
 
-  // Execute filter
-  this->BlockWidget( );
-  std::string err = this->m_MeshWriter->Update( );
-  this->UnblockWidget( );
+  } // rof
 
-  // Get result, if any
-  if( err != "" )
-  {
-#ifdef cpPlugins_Interface_QT4
-    if( this->m_Widget != NULL )
-      QMessageBox::critical(
-        this->m_Widget,
-        QMessageBox::tr( "Error reading mesh." ),
-        QMessageBox::tr( err.c_str( ) )
-        );
-#else // cpPlugins_Interface_QT4
-    std::cerr << "Error reading mesh: " << err << std::endl;
-#endif // cpPlugins_Interface_QT4
-    return( false );
-  }
-  else
-    return( true );
+  // Throw error, if any
+  if( count == this->m_Paths.size( ) )
+    throw std::runtime_error(
+      std::string( "Could not load plugin " ) +
+      std::string( "\"" ) + pname +
+      std::string( "\" from any registered path." )
+      );
 }
 
 // -------------------------------------------------------------------------
-bool cpPlugins::Interface::Plugins::
-WriteMesh( const std::string& name )
+void cpPlugins::Interface::Plugins::
+LoadDirectory( const std::string& dirname )
 {
-  // Check if objects exist
-  if( this->m_MeshWriter.IsNull( ) )
-    return( false );
-  TMesh* mesh = this->GetMesh( name );
-  if( mesh == NULL )
-    return( false );
-
-  // Configure writer
-  TProcessObject::DialogResult dret = 
-    this->m_MeshWriter->ExecConfigurationDialog( this->m_Widget );
-  if( dret == TProcessObject::DialogResult_Cancel )
-    return( "" );
-  this->m_MeshWriter->SetInput( "Input", mesh );
-
-  // Execute filter
-  this->BlockWidget( );
-  std::string err = this->m_MeshWriter->Update( );
-  this->UnblockWidget( );
-
-  // Get result, if any
-  if( err != "" )
+  std::stringstream pat;
+  pat << "*" << cpPlugins_LIB_EXT;
+  auto libs = cpPlugins::OS::LoadDirContents( dirname, false, pat.str( ) );
+  for( auto lIt = libs.begin( ); lIt != libs.end( ); ++lIt )
   {
-#ifdef cpPlugins_Interface_QT4
-    if( this->m_Widget != NULL )
-      QMessageBox::critical(
-        this->m_Widget,
-        QMessageBox::tr( "Error reading mesh." ),
-        QMessageBox::tr( err.c_str( ) )
-        );
-#else // cpPlugins_Interface_QT4
-    std::cerr << "Error reading mesh: " << err << std::endl;
-#endif // cpPlugins_Interface_QT4
-    return( false );
-  }
-  else
-    return( true );
-}
+    try
+    {
+      this->LoadFile( *lIt );
+    }
+    catch( ... ) { }
 
-// -------------------------------------------------------------------------
-void cpPlugins::Interface::Plugins::
-ClearDataObjects( )
-{
-  this->m_Objects.clear( );
+  } // rof
 }
 
 // -------------------------------------------------------------------------
 void cpPlugins::Interface::Plugins::
-DeleteDataObject( const std::string& name )
+GuessPlugins( )
 {
-  auto i = this->m_Objects.find( name );
-  if( i != this->m_Objects.end( ) )
+  for( auto i = this->m_Paths.begin( ); i != this->m_Paths.end( ); ++i )
   {
-    this->m_Objects.erase( i );
+    try { this->LoadDirectory( *i ); }
+    catch( ... ) { }
 
-    // Get children
-    std::vector< std::string > children;
-    for( i = this->m_Objects.begin( ); i != this->m_Objects.end( ); ++i )
-      if( i->second.first == name )
-        children.push_back( i->first );
-
-    // Erase children
-    auto c = children.begin( );
-    for( ; c != children.end( ); ++c )
-      this->DeleteDataObject( *c );
-    
-  } // fi
-}
-
-// -------------------------------------------------------------------------
-std::string cpPlugins::Interface::Plugins::
-GetParent( const std::string& name ) const
-{
-  auto i = this->m_Objects.find( name );
-  if( i != this->m_Objects.end( ) )
-    return( i->second.first );
-  else
-    return( "" );
-}
-
-// -------------------------------------------------------------------------
-const cpPlugins::Interface::Plugins::
-TTree& cpPlugins::Interface::Plugins::
-GetDataObjects( ) const
-{
-  return( this->m_Objects );
-}
-
-// -------------------------------------------------------------------------
-cpPlugins::Interface::Plugins::
-TDataObject* cpPlugins::Interface::Plugins::
-GetDataObject( const std::string& name )
-{
-  auto i = this->m_Objects.find( name );
-  if( i != this->m_Objects.end( ) )
-    return( dynamic_cast< TDataObject* >( i->second.second.GetPointer( ) ) );
-  else
-    return( NULL );
-}
-
-// -------------------------------------------------------------------------
-const cpPlugins::Interface::Plugins::
-TDataObject* cpPlugins::Interface::Plugins::
-GetDataObject( const std::string& name ) const
-{
-  auto i = this->m_Objects.find( name );
-  if( i != this->m_Objects.end( ) )
-    return(
-      dynamic_cast< const TDataObject* >( i->second.second.GetPointer( ) )
-      );
-  else
-    return( NULL );
-}
-
-// -------------------------------------------------------------------------
-cpPlugins::Interface::Plugins::
-TImage* cpPlugins::Interface::Plugins::
-GetImage( const std::string& name )
-{
-  auto i = this->m_Objects.find( name );
-  if( i != this->m_Objects.end( ) )
-    return( dynamic_cast< TImage* >( i->second.second.GetPointer( ) ) );
-  else
-    return( NULL );
-}
-
-// -------------------------------------------------------------------------
-const cpPlugins::Interface::Plugins::
-TImage* cpPlugins::Interface::Plugins::
-GetImage( const std::string& name ) const
-{
-  auto i = this->m_Objects.find( name );
-  if( i != this->m_Objects.end( ) )
-    return( dynamic_cast< const TImage* >( i->second.second.GetPointer( ) ) );
-  else
-    return( NULL );
+  } // rof
 }
 
 // -------------------------------------------------------------------------
+cpPlugins::Interface::Plugins::TProcess::Pointer
 cpPlugins::Interface::Plugins::
-TMesh* cpPlugins::Interface::Plugins::
-GetMesh( const std::string& name )
+CreateProcessObject( const std::string& category, const std::string& name )
 {
-  auto i = this->m_Objects.find( name );
-  if( i != this->m_Objects.end( ) )
-    return( dynamic_cast< TMesh* >( i->second.second.GetPointer( ) ) );
-  else
-    return( NULL );
-}
-
-// -------------------------------------------------------------------------
-const cpPlugins::Interface::Plugins::
-TMesh* cpPlugins::Interface::Plugins::
-GetMesh( const std::string& name ) const
-{
-  auto i = this->m_Objects.find( name );
-  if( i != this->m_Objects.end( ) )
-    return( dynamic_cast< const TMesh* >( i->second.second.GetPointer( ) ) );
-  else
-    return( NULL );
-}
-
-// -------------------------------------------------------------------------
-bool cpPlugins::Interface::Plugins::
-ActivateFilter( const std::string& name )
-{
-  this->m_ActiveFilter = this->m_Interface.CreateProcessObject( name );
-  if( this->m_ActiveFilter.IsNotNull( ) )
+  typedef cpPlugins::BaseObjects::ProcessObject::Pointer _Ptr;
+  _Ptr o = NULL;
+  auto cIt = this->m_Filters.find( category );
+  if( cIt != this->m_Filters.end( ) )
   {
-    this->m_ActiveFilter->SetPlugins( this );
-    this->m_ActiveFilterOutputs.clear( );
-    auto i = this->m_Interactors.begin( );
-    for( ; i != this->m_Interactors.end( ); ++i )
-      this->m_ActiveFilter->AddInteractor( *i );
-    return( true );
-  }
-  else
-    return( false );
-}
-
-// -------------------------------------------------------------------------
-void cpPlugins::Interface::Plugins::
-DeactivateFilter( )
-{
-  this->m_ActiveFilter = NULL;
-}
-
-// -------------------------------------------------------------------------
-bool cpPlugins::Interface::Plugins::
-HasActiveFilter( ) const
-{
-  return( this->m_ActiveFilter.IsNotNull( ) );
-}
-
-// -------------------------------------------------------------------------
-bool cpPlugins::Interface::Plugins::
-IsActiveFilterInteractive( ) const
-{
-  if( this->m_ActiveFilter.IsNotNull( ) )
-    return( this->m_ActiveFilter->IsInteractive( ) );
-  else
-    return( false );
-}
-
-// -------------------------------------------------------------------------
-unsigned int cpPlugins::Interface::Plugins::
-GetNumberOfInputsInActiveFilter( ) const
-{
-  if( this->m_ActiveFilter.IsNotNull( ) )
-    return( this->m_ActiveFilter->GetNumberOfInputs( ) );
-  else
-    return( 0 );
-}
-
-// -------------------------------------------------------------------------
-unsigned int cpPlugins::Interface::Plugins::
-GetNumberOfOutputsInActiveFilter( ) const
-{
-  if( this->m_ActiveFilter.IsNotNull( ) )
-    return( this->m_ActiveFilter->GetNumberOfOutputs( ) );
-  else
-    return( 0 );
-}
-
-// -------------------------------------------------------------------------
-std::vector< std::string > cpPlugins::Interface::Plugins::
-GetActiveFilterInputsNames( ) const
-{
-  if( this->m_ActiveFilter.IsNotNull( ) )
-    return( this->m_ActiveFilter->GetInputsNames( ) );
-  else
-    return( std::vector< std::string >( ) );
-}
-
-// -------------------------------------------------------------------------
-std::vector< std::string > cpPlugins::Interface::Plugins::
-GetActiveFilterOutputsNames( ) const
-{
-  if( this->m_ActiveFilter.IsNotNull( ) )
-    return( this->m_ActiveFilter->GetOutputsNames( ) );
-  else
-    return( std::vector< std::string >( ) );
-}
+    auto nIt = cIt->second.find( name );
+    if( nIt != cIt->second.end( ) )
+    {
+      o = reinterpret_cast< _Ptr* >( nIt->second.Creator( ) )->GetPointer( );
+      o->SetName( name );
+      o->SetPluginName( nIt->second.PluginName );
 
-// -------------------------------------------------------------------------
-void cpPlugins::Interface::Plugins::
-ConnectInputInActiveFilter(
-  const std::string& object_name, const std::string& input
-  )
-{
-  if( this->m_ActiveFilter.IsNotNull( ) )
-  {
-    TDataObject* dobj = this->GetDataObject( object_name );
-    if( dobj != NULL )
-      this->m_ActiveFilter->SetInput( input, dobj );
+    } // fi
 
   } // fi
-}
-
-// -------------------------------------------------------------------------
-void cpPlugins::Interface::Plugins::
-SetOutputNameInActiveFilter(
-  const std::string& new_name, const std::string& output
-  )
-{
-  this->m_ActiveFilterOutputs[ output ] = new_name;
+  return( o );
 }
 
 // -------------------------------------------------------------------------
 cpPlugins::Interface::Plugins::
-TParameters* cpPlugins::Interface::Plugins::
-GetActiveFilterParameters( )
-{
-  if( this->m_ActiveFilter.IsNotNull( ) )
-    return( this->m_ActiveFilter->GetParameters( ) );
-  else
-    return( NULL );
-}
-
-// -------------------------------------------------------------------------
-const cpPlugins::Interface::Plugins::
-TParameters* cpPlugins::Interface::Plugins::
-GetActiveFilterParameters( ) const
+Plugins( )
+  : Superclass( )
 {
-  if( this->m_ActiveFilter.IsNotNull( ) )
-    return( this->m_ActiveFilter->GetParameters( ) );
-  else
-    return( NULL );
+#ifdef cpPlugins_OS_Windows
+  char* p;
+  size_t size;
+  _dupenv_s( &p, &size, cpPlugins_PATHS );
+#else // cpPlugins_OS_Windows
+  char* p = std::getenv( cpPlugins_PATHS );
+#endif // cpPlugins_OS_Windows
+  std::stringstream str;
+  if( p != NULL )
+    str << p << cpPlugins_ENV_SEPARATOR;
+  str << ".";
+  this->AddEnvironments( str.str( ) );
 }
 
 // -------------------------------------------------------------------------
 cpPlugins::Interface::Plugins::
-TProcessObject::DialogResult cpPlugins::Interface::Plugins::
-ConfigureActiveFilter( )
-{
-  if( this->m_ActiveFilter.IsNotNull( ) )
-    return( this->m_ActiveFilter->ExecConfigurationDialog( this->m_Widget ) );
-  else
-    return( TProcessObject::DialogResult_Cancel );
-}
-
-// -------------------------------------------------------------------------
-std::string cpPlugins::Interface::Plugins::
-UpdateActiveFilter( std::vector< std::string >& outputs )
+~Plugins( )
 {
-  // Execute filter
-  this->BlockWidget( );
-  std::string err = this->m_ActiveFilter->Update( );
-  this->UnblockWidget( );
-
-  // Associate outputs
-  outputs.clear( );
-  if( err == "" )
-  {
-    std::string parent = "";
-    if( this->GetNumberOfInputsInActiveFilter( ) > 0 )
-    {
-      std::string input = this->m_ActiveFilter->GetInputsNames( )[ 0 ];
-      parent =
-        this->m_ActiveFilter->GetInput< TDataObject >( input )->GetName( );
-
-    } // fi
-
-    auto i = this->m_ActiveFilterOutputs.begin( );
-    for( ; i != this->m_ActiveFilterOutputs.end( ); ++i )
-    {
-      TDataObject* out =
-        this->m_ActiveFilter->GetOutput< TDataObject >( i->first );
-      out->SetName( i->second );
-      outputs.push_back( out->GetName( ) );
-      this->_InsertNewData( out, parent );
-
-    } // rof
-
-  } // fi
-  return( err );
 }
 
 // -------------------------------------------------------------------------
 void cpPlugins::Interface::Plugins::
-_UpdateLoadedPluginsInformation( )
-{
-  typedef TInterface::TClasses _C;
-
-  this->m_Filters.clear( );
-  _C& classes = this->m_Interface.GetClasses( );
-  for( _C::const_iterator i = classes.begin( ); i != classes.end( ); ++i )
+PrintSelf( std::ostream& os, itk::Indent indent ) const
+{
+  // Show data
+  os << indent << "----- PATHS -----" << std::endl;
+  auto paths = this->GetPaths( );
+  for( auto paIt = paths.begin( ); paIt != paths.end( ); ++paIt )
+    os << indent << *paIt << std::endl;
+  os << indent << std::endl << indent << "----- PLUGINS -----" << std::endl;
+  auto plugins = this->GetPlugins( );
+  for( auto plIt = plugins.begin( ); plIt != plugins.end( ); ++plIt )
+    os << indent << *plIt << std::endl;
+  os << indent << std::endl << indent << "----- FILTERS -----" << std::endl;
+  auto categories = this->GetCategories( );
+  for( auto cIt = categories.begin( ); cIt != categories.end( ); ++cIt )
   {
-    TProcessObject::Pointer o =
-      this->m_Interface.CreateProcessObject( i->first );
-    std::string name = o->GetClassName( );
-    std::string category = o->GetClassCategory( );
-    if( category == "ImageReader" )
-      this->m_ImageReader = o;
-    else if( category == "ImageWriter" )
-      this->m_ImageWriter = o;
-    else if( category == "MeshReader" )
-      this->m_MeshReader = o;
-    else if( category == "MeshWriter" )
-      this->m_MeshWriter = o;
-    else if( category == "DicomSeriesReader" )
-      this->m_DicomSeriesReader = o;
-    else
-      this->m_Filters[ category ].insert( name );
+    os << indent << "** Category: " << *cIt << " **" << std::endl;
+    auto filters = this->GetFilters( *cIt );
+    for( auto fIt = filters.begin( ); fIt != filters.end( ); ++fIt )
+      os << indent << indent << indent << "Filter: " << *fIt << std::endl;
 
   } // rof
-}
 
-// -------------------------------------------------------------------------
-bool cpPlugins::Interface::Plugins::
-_InsertNewData( TDataObject* dobj, const std::string& parent )
-{
-  std::string name = dobj->GetName( );
-  auto i = this->m_Objects.find( name );
-  bool ret = true;
-  if( i == this->m_Objects.end( ) )
-  {
-    if( parent != "" )
-    {
-      auto j = this->m_Objects.find( parent );
-      if( j != this->m_Objects.end( ) )
-        this->m_Objects[ name ] = TTreeNode( parent, dobj );
-      else
-        ret = false;
-    }
-    else
-      this->m_Objects[ name ] = TTreeNode( "", dobj );
-  }
-  else
-    i->second.second = dobj;
-
-  if( !ret )
-  {
-#ifdef cpPlugins_Interface_QT4
-    if( this->m_Widget != NULL )
-      QMessageBox::critical(
-        this->m_Widget,
-        QMessageBox::tr( "Error inserting data." ),
-        QMessageBox::tr( "Given parent does not exists." )
-        );
-#else // cpPlugins_Interface_QT4
-    std::cerr
-      << "Error inserting data: Given parent does not exists."
-      << std::endl;
-#endif // cpPlugins_Interface_QT4
-  } // fi
-  return( ret );
 }
 
 // eof - $RCSfile$