X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=lib%2FcpPlugins%2FInterface%2FPlugins.cxx;h=42ab2cc77ded0fd88249a1c6a8bf9f6b8b1b70d5;hb=77d3666adac324c796ec446fd21179bd8619b39a;hp=99aaebb012b0dbd5bc4d66027899f7a7fa89c99a;hpb=d6f15d4cb764982e2b09060a9c0f38636891590c;p=cpPlugins.git diff --git a/lib/cpPlugins/Interface/Plugins.cxx b/lib/cpPlugins/Interface/Plugins.cxx index 99aaebb..42ab2cc 100644 --- a/lib/cpPlugins/Interface/Plugins.cxx +++ b/lib/cpPlugins/Interface/Plugins.cxx @@ -1,1063 +1,488 @@ #include -#include - -#include -#include - -#ifdef cpPlugins_Interface_QT4 - -#include -#include -#include -#include -#include - -#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 +#include +#include // ------------------------------------------------------------------------- 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( ) -{ -#ifdef cpPlugins_Interface_QT4 - if( this->m_Widget != NULL ) - { - QApplication::restoreOverrideCursor( ); - this->m_Widget->setEnabled( true ); - - } // fi -#endif // cpPlugins_Interface_QT4 -} - -// ------------------------------------------------------------------------- -void cpPlugins::Interface::Plugins:: -DialogLoadPlugins( ) +cpPlugins::Interface::Plugins:: +TStrings cpPlugins::Interface::Plugins:: +GetFilters( const std::string& category ) const { -#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 + 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:: -AssociatePluginsToMenu( QMenu* menu, QObject* obj, const char* slot ) +AddEnvironments( const std::string& new_environment ) { -#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::vector< std::string > tokens; + cpExtensions::Tokenize( tokens, new_environment, cpPlugins_ENV_SEPARATOR ); + for( auto i = tokens.begin( ); i != tokens.end( ); ++i ) { - QMenu* newMenu = menu->addMenu( i->first.c_str( ) ); - for( j = i->second.begin( ); j != i->second.end( ); ++j ) - { - QAction* a = newMenu->addAction( j->c_str( ) ); - QObject::connect( a, SIGNAL( triggered( ) ), obj, slot ); - - } // rof + std::stringstream dir; + dir << cpExtensions::CanonicalPath( *i ); + if( dir.str( ) != "" ) + this->m_Paths.insert( dir.str( ) ); } // 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 ) +LoadEnvironments( ) { - this->BlockWidget( ); - - // Is it already loaded? - bool ret = true; - if( this->m_LoadedPlugins.find( fname ) == this->m_LoadedPlugins.end( ) ) + std::stringstream all_errors; + for( auto d = this->m_Paths.begin( ); d != this->m_Paths.end( ); ++d ) { - // Was it succesfully loaded? - ret = this->m_Interface.Load( fname ); - - // Update a simple track - if( ret ) + std::stringstream name; + name << *d << cpPlugins_CONFIG; + std::string buffer; + if( cpExtensions::Read( buffer, name.str( ) ) ) { - this->m_LoadedPlugins.insert( fname ); - this->m_LastLoadedPlugin = fname; - this->_UpdateLoadedPluginsInformation( ); + std::istringstream input( buffer ); + for( std::string line; std::getline( input, line ); ) + { + std::vector< std::string > tokens; + cpExtensions::Tokenize( tokens, line, "@" ); + std::string library_file = ""; + if( tokens[ 0 ] == "local" ) + library_file = + cpExtensions::CanonicalPath( + *d + std::string( cpPlugins_LIB_PREFIX ) + + tokens[ 1 ] + std::string( cpPlugins_LIB_EXT ) + ); + else if( tokens[ 0 ] == "global" ) + library_file = tokens[ 1 ]; + + if( library_file != "" ) + { + std::string error = ""; + void* hnd = cpPlugins::OS::DLLManager::Load( library_file, error ); + if( hnd != NULL ) + this->m_Libraries[ library_file ] = hnd; + else + all_errors << " ; " << error; + + } // fi + + } // rof } // fi - } // fi - - this->UnblockWidget( ); - return( ret ); -} - -// ------------------------------------------------------------------------- -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 ) - { - in_stream.getline( line, 4096 ); - this->LoadPlugins( line ); - - } // elihw - delete buffer; + } // rof - return( true ); + // Throw errors + if( all_errors.str( ) != "" ) + throw std::runtime_error( + std::string( "Loading environment libraries errors: " ) + + all_errors.str( ) + ); } // ------------------------------------------------------------------------- void cpPlugins::Interface::Plugins:: -AddInteractor( vtkRenderWindowInteractor* interactor ) +SaveEnvironments( 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 +OpenEnvironments( const std::string& dir ) { - 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 == "" ) + std::vector< std::string > tokens; + cpExtensions::Tokenize( tokens, dir, cpPlugins_ENV_SEPARATOR ); + for( auto tIt = tokens.begin( ); tIt != tokens.end( ); ++tIt ) { - TImage* image = this->m_ImageReader->GetOutput< TImage >( "Output" ); - this->m_ImageReader->DisconnectOutputs( ); - - // Add newly added data - if( this->_InsertNewData( image, parent ) ) - return( image->GetName( ) ); + std::stringstream fname; + fname << *tIt; + if( !cpExtensions::IsPathSeparator( dir.back( ) ) ) + fname << cpExtensions_PATH_SEPARATOR; + fname << cpPlugins_PATHS; + std::string buffer; + if( cpExtensions::Read( buffer, fname.str( ) ) ) + { + std::istringstream input( buffer ); + std::stringstream paths; + for( std::string line; std::getline( input, line ); ) + paths << line << cpPlugins_ENV_SEPARATOR; + this->AddEnvironments( paths.str( ) ); + } 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( ); + { + bool success = true; + try + { + this->LoadDirectory( dir ); + } + catch( ... ) + { + success = false; + + } // yrt + if( success ) + this->AddEnvironments( dir ); - // 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 - } // fi + } // rof } // ------------------------------------------------------------------------- -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( ); +void cpPlugins::Interface::Plugins:: +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 plugins_name = plugins_name_function( ); -// ------------------------------------------------------------------------- -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 == "" ) - { - 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 + // 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 mesh." ), - QMessageBox::tr( err.c_str( ) ) - ); -#else // cpPlugins_Interface_QT4 - std::cerr << "Error reading mesh: " << 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& 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 == "" ) + 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( ) ) - ); -#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 ); - - // Configure writer - this->m_ImageWriter->GetParameters( )->SetString( "FileName", fname ); - 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 != "" ) - { -#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:: -WriteImage( 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 ); - - // 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 != "" ) - { -#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( 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 ); - - // Configure writer - this->m_MeshWriter->GetParameters( )->SetString( "FileName", fname ); - this->m_MeshWriter->SetInput( "Input", mesh ); - // Execute filter - this->BlockWidget( ); - std::string err = this->m_MeshWriter->Update( ); - this->UnblockWidget( ); + } // fi - // 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( ) ) + // 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( false ); - } - else - return( true ); -} -// ------------------------------------------------------------------------- -bool cpPlugins::Interface::Plugins:: -WriteMesh( 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 ); - - // Configure writer - TProcessObject::DialogResult dret = - this->m_MeshWriter->ExecConfigurationDialog( this->m_Widget ); - if( dret == TProcessObject::DialogResult_Cancel ) - return( "" ); - this->m_MeshWriter->SetInput( "Input", mesh ); + } // fi - // Execute filter - this->BlockWidget( ); - std::string err = this->m_MeshWriter->Update( ); - this->UnblockWidget( ); + TCreatorData data; + data.PluginName = plugins_name; + data.LibraryHandle = hnd; + data.Creator = creator; + filters[ category ][ name ] = data; - // 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 ); -} + } // elihw -// ------------------------------------------------------------------------- -void cpPlugins::Interface::Plugins:: -ClearDataObjects( ) -{ - this->m_Objects.clear( ); + // 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; } // ------------------------------------------------------------------------- void cpPlugins::Interface::Plugins:: -DeleteDataObject( const std::string& name ) +LoadPlugin( const std::string& pname ) { - auto i = this->m_Objects.find( name ); - if( i != this->m_Objects.end( ) ) + 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 ) { - this->m_Objects.erase( i ); - - // 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 ); + std::stringstream dir; + dir << *i; + if( !cpExtensions::IsPathSeparator( i->back( ) ) ) + dir << cpExtensions_PATH_SEPARATOR; + dir << fname.str( ); + try + { + this->LoadFile( dir.str( ) ); + } + catch( ... ) + { + count++; - // Erase children - auto c = children.begin( ); - for( ; c != children.end( ); ++c ) - this->DeleteDataObject( *c ); - - } // fi -} + } // yrt -// ------------------------------------------------------------------------- -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 ); -} + } // rof -// ------------------------------------------------------------------------- -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( ) ) + // 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." ) ); - 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 ); -} - -// ------------------------------------------------------------------------- -cpPlugins::Interface::Plugins:: -TMesh* cpPlugins::Interface::Plugins:: -GetMesh( 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 ) +void cpPlugins::Interface::Plugins:: +LoadDirectory( const std::string& dirname ) { - this->m_ActiveFilter = this->m_Interface.CreateProcessObject( name ); - if( this->m_ActiveFilter.IsNotNull( ) ) + DIR* dir; + struct dirent* ent; + if( ( dir = opendir( dirname.c_str( ) ) ) != NULL ) { - 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 ); + while( ( ent = readdir( dir ) ) != NULL ) + { + try + { + std::stringstream fname; + fname << dirname << cpExtensions_PATH_SEPARATOR << ent->d_name; + this->LoadFile( fname.str( ) ); + } + catch( ... ) { } + + } // elihw + closedir( dir ); } else - return( false ); + throw std::runtime_error( + std::string( "Could not load directory " ) + + std::string( "\"" ) + dirname + std::string( "\"" ) + ); } // ------------------------------------------------------------------------- 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 +GuessPlugins( ) { - 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 >( ) ); -} + for( auto i = this->m_Paths.begin( ); i != this->m_Paths.end( ); ++i ) + { + try { this->LoadDirectory( *i ); } + catch( ... ) { } -// ------------------------------------------------------------------------- -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 >( ) ); + } // rof } // ------------------------------------------------------------------------- -void cpPlugins::Interface::Plugins:: -ConnectInputInActiveFilter( - const std::string& object_name, const std::string& input - ) +cpPlugins::Interface::Plugins::TProcess::Pointer +cpPlugins::Interface::Plugins:: +CreateProcessObject( const std::string& category, const std::string& 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( ) ) { - TDataObject* dobj = this->GetDataObject( object_name ); - if( dobj != NULL ) - this->m_ActiveFilter->SetInput( input, dobj ); + 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 ); - } // fi -} + } // fi -// ------------------------------------------------------------------------- -void cpPlugins::Interface::Plugins:: -SetOutputNameInActiveFilter( - const std::string& new_name, const std::string& output - ) -{ - this->m_ActiveFilterOutputs[ output ] = new_name; + } // fi + 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 -{ - if( this->m_ActiveFilter.IsNotNull( ) ) - return( this->m_ActiveFilter->GetParameters( ) ); - else - return( NULL ); +Plugins( ) + : Superclass( ) +{ +#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->OpenEnvironments( str.str( ) ); + + // Try to read locally defined paths + /* TODO + std::vector< std::string > tokens; + cpExtensions::Tokenize( tokens, str.str( ), cpPlugins_ENV_SEPARATOR ); + for( auto t = tokens.begin( ); t != tokens.end( ); ++t ) + { + try + { + this->OpenEnvironments( *t ); + } + catch( ... ) { } + + } // rof + */ } // ------------------------------------------------------------------------- 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$