]> Creatis software - cpPlugins.git/blobdiff - lib/cpPlugins/Interface/Workspace.cxx
...
[cpPlugins.git] / lib / cpPlugins / Interface / Workspace.cxx
index a722908f168a0cafb535d40eb44e3437617efa5b..4fbcb2bbf3b154e11332f29b0a32cd7201630f95 100644 (file)
 #include <cpPlugins/Interface/Workspace.h>
+#include <cpPlugins/Pipeline/Widget.h>
 
 // -------------------------------------------------------------------------
-cpPlugins::Interface::Workspace::
-Workspace( )
-  : m_Interface( NULL )
+void cpPlugins::Interface::Workspace::
+Clear( )
+{
+  this->m_Filters.clear( );
+}
+
+// -------------------------------------------------------------------------
+std::vector< std::string > cpPlugins::Interface::Workspace::
+GetFiltersNames( ) const
 {
-  this->m_Graph = TGraph::New( );
+  std::vector< std::string > n;
+  for( auto i : this->m_Filters )
+    n.push_back( i.first );
+  return( n );
 }
 
 // -------------------------------------------------------------------------
 cpPlugins::Interface::Workspace::
-~Workspace( )
+TFilter* cpPlugins::Interface::Workspace::
+GetFilter( const std::string& name )
 {
+  auto i = this->m_Filters.find( name );
+  if( i != this->m_Filters.end( ) )
+    return( i->second.GetPointer( ) );
+  else
+    return( NULL );
+}
+
+// -------------------------------------------------------------------------
+const cpPlugins::Interface::Workspace::
+TFilter* cpPlugins::Interface::Workspace::
+GetFilter( const std::string& name ) const
+{
+  auto i = this->m_Filters.find( name );
+  if( i != this->m_Filters.end( ) )
+    return( i->second.GetPointer( ) );
+  else
+    return( NULL );
 }
 
 // -------------------------------------------------------------------------
 cpPlugins::Interface::Workspace::
-TInterface* cpPlugins::Interface::Workspace::
-GetInterface( )
+TWidget* cpPlugins::Interface::Workspace::
+GetWidget( const std::string& name )
 {
-  return( this->m_Interface );
+  TFilter* process = this->GetFilter( name );
+  return( dynamic_cast< TWidget* >( process ) );
 }
 
 // -------------------------------------------------------------------------
-void cpPlugins::Interface::Workspace::
-SetInterface( TInterface* i )
-{
-  if( this->m_Interface != i )
-    this->m_Interface = i;
-}
-
-/* TODO
-   bool cpPlugins::Interface::Workspace::
-   LoadPluginsPath( const std::string& path, bool r )
-   {
-   // Load all plugins from given folder
-   std::list< std::string > files =
-   this->m_Interface.LoadFromFolder( path, r );
-   
-   // Update a simple track
-   bool ret = false;
-   if( files.size( ) > 0 )
-   {
-   for( auto fIt = files.begin( ); fIt != files.end( ); ++fIt )
-   {
-   this->m_LoadedPlugins.insert( *fIt );
-   this->m_LastLoadedPlugin = *fIt;
-   
-   } // rof
-   this->_UpdateLoadedPluginsInformation( );
-   ret = true;
-   
-   } // fi
-   return( ret );
-   }
-
-   // -------------------------------------------------------------------------
-   bool cpPlugins::Interface::Workspace::
-   LoadPlugins( const std::string& fname )
-   {
-   // Is it already loaded?
-   bool ret = true;
-   if( this->m_LoadedPlugins.find( fname ) == this->m_LoadedPlugins.end( ) )
-   {
-   // Was it succesfully loaded?
-   ret = this->m_Interface.Load( fname );
-   
-   // Update a simple track
-   if( ret )
-   {
-   this->m_LoadedPlugins.insert( fname );
-   this->m_LastLoadedPlugin = fname;
-   this->_UpdateLoadedPluginsInformation( );
-   
-   } // fi
-   
-   } // fi
-   return( ret );
-   }
-   
-   // -------------------------------------------------------------------------
-   const cpPlugins::Interface::Workspace::
-   TStringContainer& cpPlugins::Interface::Workspace::
-   GetLoadedPlugins( ) const
-   {
-   return( this->m_LoadedPlugins );
-   }
-   
-   // -------------------------------------------------------------------------
-   void cpPlugins::Interface::Workspace::
-   GetLoadedPluginCategories( TStringContainer& categories ) const
-   {
-   categories.clear( );
-   auto fIt = this->m_LoadedFilters.begin( );
-   for( ; fIt != this->m_LoadedFilters.end( ); ++fIt )
-   categories.insert( fIt->first );
-   }
-   
-   // -------------------------------------------------------------------------
-   void cpPlugins::Interface::Workspace::
-   GetLoadedPluginFilters( TStringContainer& filters ) const
-   {
-   filters.clear( );
-   auto pIt = this->m_LoadedFilters.begin( );
-   for( ; pIt != this->m_LoadedFilters.end( ); ++pIt )
-   for( auto fIt = pIt->second.begin( ); fIt != pIt->second.end( ); ++fIt )
-   filters.insert( *fIt );
-   }
-   
-   // -------------------------------------------------------------------------
-   const cpPlugins::Interface::Workspace::
-   TStringContainer& cpPlugins::Interface::Workspace::
-   GetLoadedPluginFilters( const std::string& category ) const
-   {
-   static const TStringContainer EMPTY;
-   auto pIt = this->m_LoadedFilters.find( category );
-   if( pIt != this->m_LoadedFilters.end( ) )
-   return( pIt->second );
-   else
-   return( EMPTY );
-   }
-*/
+const cpPlugins::Interface::Workspace::
+TWidget* cpPlugins::Interface::Workspace::
+GetWidget( const std::string& name ) const
+{
+  const TFilter* process = this->GetFilter( name );
+  return( dynamic_cast< const TWidget* >( process ) );
+}
 
 // -------------------------------------------------------------------------
-void cpPlugins::Interface::Workspace::
-Clear( )
+bool cpPlugins::Interface::Workspace::
+HasFilter( const std::string& name ) const
+{
+  return( this->m_Filters.find( name ) != this->m_Filters.end( ) );
+}
+
+// -------------------------------------------------------------------------
+bool cpPlugins::Interface::Workspace::
+HasWidget( const std::string& name ) const
 {
-  if( this->m_Graph.IsNotNull( ) )
-    this->m_Graph->Clear( );
+  const TWidget* wdg = this->GetWidget( name );
+  return( wdg != NULL );
 }
 
 // -------------------------------------------------------------------------
 cpPlugins::Interface::Workspace::
-TGraph* cpPlugins::Interface::Workspace::
-GetGraph( )
+TFilter* cpPlugins::Interface::Workspace::
+CreateFilter(
+  const std::string& category, const std::string& filter,
+  const std::string& name
+  )
 {
-  return( this->m_Graph );
+  typedef cpPlugins::Pipeline::Widget _TWidget;
+
+  TFilter::Pointer o = this->m_Loader.CreateFilter( category, filter );
+  if( o.IsNotNull( ) )
+  {
+    // Choose a name
+    std::string real_name = name;
+    while( this->GetFilter( real_name ) != NULL )
+      real_name += std::string( "_" );
+    o->SetPrintExecution( this->m_PrintExecution );
+    o->SetName( real_name );
+
+    // Interactors
+    for(
+      auto i = this->m_Interactors.begin( );
+      i != this->m_Interactors.end( );
+      ++i
+      )
+      o->AddInteractor( *i );
+
+    // Finish association
+    this->m_Filters[ real_name ] = o;
+
+  } // fi
+  return( o.GetPointer( ) );
 }
 
 // -------------------------------------------------------------------------
-const cpPlugins::Interface::Workspace::
-TGraph* cpPlugins::Interface::Workspace::
-GetGraph( ) const
+cpPlugins::Interface::Workspace::
+TFilter* cpPlugins::Interface::Workspace::
+CreateFilter( const std::string& category, const std::string& filter )
 {
-  return( this->m_Graph );
+  return( this->CreateFilter( category, filter, filter ) );
 }
 
 // -------------------------------------------------------------------------
 bool cpPlugins::Interface::Workspace::
-CreateFilter( const std::string& filter, const std::string& name )
+RenameFilter( const std::string& old_name, const std::string& new_name )
 {
-  if( this->m_Interface == NULL )
+  auto o = this->m_Filters.find( old_name );
+  auto n = this->m_Filters.find( new_name );
+  if( o != this->m_Filters.end( ) && n == this->m_Filters.end( ) )
+  {
+    // Rename filter
+    o->second->SetName( new_name );
+    this->m_Filters[ new_name ] = o->second;
+    this->m_Filters.erase( o );
+
+    // Rename exposed ports
+    /* TODO
+       auto e = this->m_ExposedInputs.begin( );
+       for( ; e != this->m_ExposedInputs.end( ); ++e )
+       if( e->second.first == old_name )
+       e->second.first = new_name;
+       e = this->m_ExposedOutputs.begin( );
+       for( ; e != this->m_ExposedOutputs.end( ); ++e )
+       if( e->second.first == old_name )
+       e->second.first = new_name;
+    */
+
+    return( true );
+  }
+  else
     return( false );
+}
 
-  // Get or create new filter from name
-  if( !( this->m_Graph->HasVertexIndex( name ) ) )
+// -------------------------------------------------------------------------
+bool cpPlugins::Interface::Workspace::
+RemoveFilter( const std::string& name )
+{
+  auto i = this->m_Filters.find( name );
+  if( i != this->m_Filters.end( ) )
   {
-    TFilter::Pointer f = this->m_Interface->CreateObject( filter );
-    if( f.IsNotNull( ) )
-    {
-      f->SetName( name );
-      TObject::Pointer o = f.GetPointer( );
-      this->m_Graph->SetVertex( name, o );
-      return( true );
-    }
-    else
-      return( false );
+    i->second->Disconnect( );
+    this->m_Filters.erase( i );
+    return( true );
   }
   else
-    return( true );
+    return( false );
+}
+
+// -------------------------------------------------------------------------
+void cpPlugins::Interface::Workspace::
+SetPrintExecution( bool b )
+{
+  this->m_PrintExecution = b;
+  for( auto i = this->m_Filters.begin( ); i != this->m_Filters.end( ); ++i )
+    i->second->SetPrintExecution( b );
+}
+
+// -------------------------------------------------------------------------
+void cpPlugins::Interface::Workspace::
+PrintExecutionOn( )
+{
+  this->SetPrintExecution( true );
+}
+
+// -------------------------------------------------------------------------
+void cpPlugins::Interface::Workspace::
+PrintExecutionOff( )
+{
+  this->SetPrintExecution( true );
+}
+
+// -------------------------------------------------------------------------
+void cpPlugins::Interface::Workspace::
+AddInteractor( vtkRenderWindowInteractor* iren )
+{
+  if( iren != NULL )
+  {
+    this->m_Interactors.insert( iren );
+    for( auto f : this->m_Filters )
+      f.second->AddInteractor( iren );
+
+  } // fi
 }
 
 // -------------------------------------------------------------------------
 bool cpPlugins::Interface::Workspace::
 Connect(
-  const std::string& orig_filter, const std::string& dest_filter,
-  const std::string& output_name, const std::string& input_name
+  const std::string& origin_filter,
+  const std::string& origin_output,
+  const std::string& destination_filter,
+  const std::string& destination_input
   )
 {
-  // Get filters
-  TFilter* orig =
-    dynamic_cast< TFilter* >(
-      this->m_Graph->GetVertex( orig_filter ).GetPointer( )
-      );
-  TFilter* dest =
-    dynamic_cast< TFilter* >(
-      this->m_Graph->GetVertex( dest_filter ).GetPointer( )
-      );
-  if( orig == NULL || dest == NULL )
+  // Get filters and check pertinence
+  TFilter* origin = this->GetFilter( origin_filter );
+  TFilter* destination = this->GetFilter( destination_filter );
+  if( origin == NULL || destination == NULL )
+    return( false );
+  if( !( destination->HasInput( destination_input ) ) )
+    return( false );
+  if( !( origin->HasOutput( origin_output ) ) )
     return( false );
 
-  // Real connection
-  dest->SetInput( input_name, orig->GetOutput< TData >( output_name ) );
-  this->m_Graph->AddConnection(
-    orig_filter, dest_filter,
-    TConnection( output_name, input_name )
-    );
-  return( false );
+  // Check if there is room for a new connection
+  bool ok = true;
+  if( destination->IsInputMultiple( destination_input ) )
+  {
+    for(
+      unsigned int i = 0;
+      i < destination->GetInputSize( destination_input );
+      ++i
+      )
+      if(
+        destination->GetInput( destination_input, i )->GetSource( ) == origin
+        )
+        ok = false;
+  }
+  else
+    ok = ( destination->GetInput( destination_input ) == NULL );
+  if( ok )
+    destination->AddInput(
+      destination_input,
+      origin->GetOutput( origin_output )
+      );
+  return( ok );
 }
 
 // -------------------------------------------------------------------------
 bool cpPlugins::Interface::Workspace::
-Connect( const std::string& i, const std::string& o )
-{
-  auto ii = this->m_InputPorts.find( i );
-  auto oi = this->m_OutputPorts.find( o );
-  if( ii != this->m_InputPorts.end( ) && oi != this->m_OutputPorts.end( ) )
-    return(
-      this->Connect(
-        oi->second.first,
-        ii->second.first,
-        oi->second.second,
-        ii->second.second
+Connect(
+  TDataObject* input,
+  const std::string& destination_filter,
+  const std::string& destination_input
+  )
+{
+  // Get filters and check pertinence
+  if( input == NULL )
+    return( false );
+  TFilter* destination = this->GetFilter( destination_filter );
+  if( destination == NULL )
+    return( false );
+  if( !( destination->HasInput( destination_input ) ) )
+    return( false );
+
+  // Check if there is room for a new connection
+  bool ok = true;
+  if( destination->IsInputMultiple( destination_input ) )
+  {
+    for(
+      unsigned int i = 0;
+      i < destination->GetInputSize( destination_input );
+      ++i
+      )
+      if(
+        destination->GetInput( destination_input, i )->GetSource( ) ==
+        input->GetSource( )
         )
-      );
+        ok = false;
+  }
   else
+    ok = ( destination->GetInput( destination_input ) == NULL );
+  if( ok )
+    destination->AddInput(
+      destination_input,
+      input
+      );
+  return( ok );
+}
+
+// -------------------------------------------------------------------------
+bool cpPlugins::Interface::Workspace::
+Disconnect(
+  const std::string& origin_filter,
+  const std::string& origin_output,
+  const std::string& destination_filter,
+  const std::string& destination_input
+  )
+{
+  // Get filters and check pertinence
+  TFilter* origin = this->GetFilter( origin_filter );
+  TFilter* destination = this->GetFilter( destination_filter );
+  if( origin == NULL || destination == NULL )
+    return( false );
+  if( !( destination->HasInput( destination_input ) ) )
     return( false );
+  if( !( origin->HasOutput( origin_output ) ) )
+    return( false );
+
+  // Check if there is room for a new connection
+  bool ok = false;
+  unsigned int del_id = 0;
+  for(
+    unsigned int i = 0;
+    i < destination->GetInputSize( destination_input );
+    ++i
+    )
+    if(
+      destination->GetInput( destination_input, i )->GetSource( ) == origin
+      )
+    {
+      ok = true;
+      del_id = i;
+
+    } // fi
+  if( ok )
+    destination->DisconnectInput( destination_input, del_id );
+  return( ok );
 }
 
 // -------------------------------------------------------------------------
-cpPlugins::Interface::Workspace::
-TParameters* cpPlugins::Interface::Workspace::
-GetParameters( const std::string& name )
+/*
+const cpPlugins::Interface::Workspace::
+TExposedPorts& cpPlugins::Interface::Workspace::
+GetExposedInputs( ) const
 {
-  TFilter* f =
-    dynamic_cast< TFilter* >(
-      this->m_Graph->GetVertex( name ).GetPointer( )
-      );
-  if( f != NULL )
-    return( f->GetParameters( ) );
+  return( this->m_ExposedInputs );
+}
+
+// -------------------------------------------------------------------------
+const cpPlugins::Interface::Workspace::
+TExposedPorts& cpPlugins::Interface::Workspace::
+GetExposedOutputs( ) const
+{
+  return( this->m_ExposedOutputs );
+}
+
+// -------------------------------------------------------------------------
+cpPlugins::Pipeline::DataObject* cpPlugins::Interface::Workspace::
+GetExposedOutput( const std::string& name )
+{
+  auto i = this->m_ExposedOutputs.find( name );
+  if( i != this->m_ExposedOutputs.end( ) )
+  {
+    auto f = this->GetFilter( i->second.first );
+    if( f != NULL )
+      return( f->GetOutput( i->second.second ) );
+    else
+      return( NULL );
+  }
   else
     return( NULL );
 }
 
 // -------------------------------------------------------------------------
-const cpPlugins::Interface::Workspace::
-TParameters* cpPlugins::Interface::Workspace::
-GetParameters( const std::string& name ) const
+const cpPlugins::Pipeline::DataObject* cpPlugins::Interface::Workspace::
+GetExposedOutput( const std::string& name ) const
 {
-  const TFilter* f =
-    dynamic_cast< const TFilter* >(
-      this->m_Graph->GetVertex( name ).GetPointer( )
-      );
-  if( f != NULL )
-    return( f->GetParameters( ) );
+  auto i = this->m_ExposedOutputs.find( name );
+  if( i != this->m_ExposedOutputs.end( ) )
+  {
+    auto f = this->GetFilter( i->second.first );
+    if( f != NULL )
+      return( f->GetOutput( i->second.second ) );
+    else
+      return( NULL );
+  }
   else
     return( NULL );
 }
 
 // -------------------------------------------------------------------------
-cpPlugins::Interface::Workspace::
-TFilter* cpPlugins::Interface::Workspace::
-GetFilter( const std::string& name )
+bool cpPlugins::Interface::Workspace::
+ExposeInput(
+  const std::string& name,
+  const std::string& filter, const std::string& filter_input
+  )
 {
-  TFilter* f =
-    dynamic_cast< TFilter* >(
-      this->m_Graph->GetVertex( name ).GetPointer( )
-      );
-  return( f );
+  auto i = this->m_ExposedInputs.find( name );
+  if( i == this->m_ExposedInputs.end( ) )
+  {
+    this->m_ExposedInputs[ name ] =
+      std::pair< std::string, std::string >( filter, filter_input );
+    return( true );
+  }
+  else
+    return( false );
 }
 
 // -------------------------------------------------------------------------
-const cpPlugins::Interface::Workspace::
-TFilter* cpPlugins::Interface::Workspace::
-GetFilter( const std::string& name ) const
+bool cpPlugins::Interface::Workspace::
+ExposeOutput(
+  const std::string& name,
+  const std::string& filter, const std::string& filter_output
+  )
 {
-  const TFilter* f =
-    dynamic_cast< const TFilter* >(
-      this->m_Graph->GetVertex( name ).GetPointer( )
-      );
-  return( f );
+  auto i = this->m_ExposedOutputs.find( name );
+  if( i == this->m_ExposedOutputs.end( ) )
+  {
+    this->m_ExposedOutputs[ name ] =
+      std::pair< std::string, std::string >( filter, filter_output );
+    return( true );
+  }
+  else
+    return( false );
+}
+
+// -------------------------------------------------------------------------
+void cpPlugins::Interface::Workspace::
+HideInput( const std::string& name )
+{
+  auto i = this->m_ExposedInputs.find( name );
+  if( i != this->m_ExposedInputs.end( ) )
+    this->m_ExposedInputs.erase( i );
+}
+
+// -------------------------------------------------------------------------
+void cpPlugins::Interface::Workspace::
+HideOutput( const std::string& name )
+{
+  auto i = this->m_ExposedOutputs.find( name );
+  if( i != this->m_ExposedOutputs.end( ) )
+    this->m_ExposedOutputs.erase( i );
 }
 
 // -------------------------------------------------------------------------
 bool cpPlugins::Interface::Workspace::
-HasFilter( const std::string& name ) const
+RenameExposedInput(
+  const std::string& old_name, const std::string& new_name
+  )
 {
-  if( this->m_Graph->HasVertexIndex( name ) )
-    return( this->GetFilter( name ) != NULL );
+  auto o = this->m_ExposedInputs.find( old_name );
+  auto n = this->m_ExposedInputs.find( new_name );
+  if( o != this->m_ExposedInputs.end( ) && n == this->m_ExposedInputs.end( ) )
+  {
+    this->m_ExposedInputs[ new_name ] = o->second;
+    this->m_ExposedInputs.erase( o );
+    return( true );
+  }
   else
     return( false );
 }
 
 // -------------------------------------------------------------------------
 bool cpPlugins::Interface::Workspace::
-Reduce( const std::string& name )
+RenameExposedOutput(
+  const std::string& old_name, const std::string& new_name
+  )
 {
-  return( false );
+  auto o = this->m_ExposedOutputs.find( old_name );
+  auto n = this->m_ExposedOutputs.find( new_name );
+  if(
+    o != this->m_ExposedOutputs.end( ) && n == this->m_ExposedOutputs.end( )
+    )
+  {
+    this->m_ExposedOutputs[ new_name ] = o->second;
+    this->m_ExposedOutputs.erase( o );
+    return( true );
+  }
+  else
+    return( false );
+}
+
+// -------------------------------------------------------------------------
+std::vector< std::pair< std::string, std::string > >
+cpPlugins::Interface::Workspace::
+GetConnections(
+  const std::string& origin, const std::string& destination
+  ) const
+{
+  std::vector< std::pair< std::string, std::string > > conns;
+  auto orig = this->GetFilter( origin );
+  auto dest = this->GetFilter( destination );
+  if( orig != NULL && dest != NULL )
+  {
+    auto outs = orig->GetOutputsNames( );
+    auto ins = dest->GetInputsNames( );
+    for( auto o = outs.begin( ); o != outs.end( ); ++o )
+    {
+      for( auto i = ins.begin( ); i != ins.end( ); ++i )
+      {
+        unsigned int nInputs = dest->GetInputSize( *i );
+        for( unsigned j = 0; j < nInputs; ++j )
+        {
+          auto od = orig->GetOutput( *o );
+          auto id = dest->GetInput( *i, j );
+          if( od != NULL && od == id )
+            conns.push_back(
+              std::pair< std::string, std::string >( *o, *i )
+              );
+
+        } // rof
+
+      } // rof
+
+    } // rof
+
+  } // fi
+  return( conns );
 }
 
 // -------------------------------------------------------------------------
 void cpPlugins::Interface::Workspace::
-AddInputPort(
-  const std::string& name,
-  const std::string& filter, const std::string& filter_input
+Connect(
+  const std::string& orig_filter, const std::string& dest_filter,
+  const std::string& output_name, const std::string& input_name
   )
 {
-  this->m_InputPorts[ name ] = TGlobalPort( filter, filter_input );
+  auto o = this->GetFilter( orig_filter );
+  auto d = this->GetFilter( dest_filter );
+  if( o != NULL && d != NULL )
+  {
+    try
+    {
+      d->AddInput( input_name, o->GetOutput( output_name ) );
+    }
+    catch( std::exception& err )
+    {
+      throw std::logic_error(
+        std::string( "Error connecting \"" ) +
+        output_name + std::string( "@" ) + orig_filter +
+        std::string( "\" with \"" ) +
+        input_name + std::string( "@" ) + dest_filter +
+        std::string( "\": " ) +
+        err.what( )
+        );
+
+    } // yrt
+
+  } // fi
 }
 
 // -------------------------------------------------------------------------
 void cpPlugins::Interface::Workspace::
-AddOutputPort(
-  const std::string& name,
-  const std::string& filter, const std::string& filter_output
+Connect(
+  cpPlugins::Pipeline::DataObject* output,
+  const std::string& dest_filter, const std::string& input_name
   )
 {
-  this->m_OutputPorts[ name ] = TGlobalPort( filter, filter_output );
+  auto d = this->GetFilter( dest_filter );
+  if( d != NULL )
+    d->AddInput( input_name, output );
 }
 
 // -------------------------------------------------------------------------
 void cpPlugins::Interface::Workspace::
-ClearInputPorts( )
+Connect(
+  cpPlugins::Pipeline::DataObject* output,
+  const std::string& exposed_input_name
+  )
 {
-  this->m_InputPorts.clear( );
+  auto i = this->m_ExposedInputs.find( exposed_input_name );
+  if( i != this->m_ExposedInputs.end( ) )
+    this->Connect( output, i->second.first, i->second.second );
 }
 
 // -------------------------------------------------------------------------
 void cpPlugins::Interface::Workspace::
-ClearOutputPorts( )
+Disconnect(
+  const std::string& orig_filter, const std::string& dest_filter,
+  const std::string& output_name, const std::string& input_name
+  )
 {
-  this->m_OutputPorts.clear( );
+  auto orig = this->GetFilter( orig_filter );
+  auto dest = this->GetFilter( dest_filter );
+  if( orig != NULL && dest != NULL )
+  {
+    auto out = orig->GetOutput( output_name );
+    auto in = dest->GetInput( input_name );
+    if( out != NULL && out == in )
+      dest->SetInput(
+        input_name, ( cpPlugins::Pipeline::DataObject* )( NULL )
+        );
+
+  } // fi
 }
 
 // -------------------------------------------------------------------------
-std::string cpPlugins::Interface::Workspace::
-Execute( )
+void cpPlugins::Interface::Workspace::
+Disconnect(
+  const std::string& dest_filter, const std::string& input_name
+  )
 {
-  // Find sinks
-  std::set< std::string > sinks = this->m_Graph->GetSinks( );
+  throw std::logic_error( "Disconnect 1" );
+}
 
-  // Update sinks
-  std::string err = "";
-  for( auto sIt = sinks.begin( ); sIt != sinks.end( ); ++sIt )
-  {
-    std::string lerr = this->Execute( *sIt, NULL );
-    if( lerr != "" )
-      err += lerr + std::string( "\n" );
+// -------------------------------------------------------------------------
+void cpPlugins::Interface::Workspace::
+Disconnect( const std::string& dest_filter )
+{
+  throw std::logic_error( "Disconnect 2" );
+}
+*/
 
-  } // rof
-  return( err );
+// -------------------------------------------------------------------------
+void cpPlugins::Interface::Workspace::
+Update( )
+{
+  for( auto f = this->m_Filters.begin( ); f != this->m_Filters.end( ); ++f )
+    f->second->Update( );
 }
 
 // -------------------------------------------------------------------------
-std::string cpPlugins::Interface::Workspace::
-Execute( const std::string& name, QWidget* p )
+void cpPlugins::Interface::Workspace::
+Update( const std::string& name )
 {
-  // Get filter
-  TFilter* f =
-    dynamic_cast< TFilter* >(
-      this->m_Graph->GetVertex( name ).GetPointer( )
-      );
-  if( f == NULL )
-    return(
-      std::string( "cpPlugins::Interface::Workspace: Vertex \"" ) +
-      name + std::string( "\" is not a filter." )
-      );
+  auto filter = this->GetFilter( name );
+  if( filter != NULL )
+    filter->Update( );
+}
 
-  // Execute and return
-  if( p != NULL )
-  {
-    auto diag_res = f->ExecConfigurationDialog( p );
-    if( diag_res == TFilter::DialogResult_NoModal )
-      return( f->Update( ) );
-    else
-      return( "" );
-  }
-  else
-    return( f->Update( ) );
+// -------------------------------------------------------------------------
+cpPlugins::Interface::Workspace::
+Workspace( )
+  : Superclass( ),
+    m_PrintExecution( false )
+{
 }
 
 // -------------------------------------------------------------------------
-void cpPlugins::Interface::Workspace::
-_UpdateLoadedPluginsInformation( )
+cpPlugins::Interface::Workspace::
+~Workspace( )
 {
   /* TODO
-     if( this->m_Interface != NULL )
-     {
-     this->m_LoadedFilters.clear( );
-     const TInterface::TClasses& cls = this->m_Interface->GetClasses( );
-     for( auto i = cls.begin( ); i != cls.end( ); ++i )
-     {
-     TFilter::Pointer o = this->m_Interface->CreateObject( i->first );
-     std::string name = o->GetClassName( );
-     std::string category = o->GetClassCategory( );
-     this->m_LoadedFilters[ category ].insert( name );
-
-     } // rof
-
-     } // fi
+     this->m_ExposedOutputs.clear( );
+     this->m_ExposedInputs.clear( );
   */
+  this->m_Filters.clear( );
 }
 
 // eof - $RCSfile$