From b5417af22a8c30e05961789f4758c10e0cc1b926 Mon Sep 17 00:00:00 2001
From: Leonardo Florez-Valencia <florez-l@javeriana.edu.co>
Date: Tue, 28 Jun 2016 18:30:10 -0500
Subject: [PATCH] ...

---
 lib/cpBaseQtApplication/Editor.cxx        | 52 +++++++++++--------
 lib/cpBaseQtApplication/Editor.h          |  6 +--
 lib/cpBaseQtApplication/MainWindow.cxx    |  6 +--
 lib/cpExtensions/DataStructures/Graph.hxx |  9 +++-
 lib/cpPlugins/ProcessObject.h             |  3 ++
 lib/cpPlugins/ProcessObject.hxx           | 16 ++++++
 lib/cpPlugins/Workspace.cxx               | 63 ++++++++++++++++++++++-
 lib/cpPlugins/Workspace.h                 | 21 ++++----
 8 files changed, 133 insertions(+), 43 deletions(-)

diff --git a/lib/cpBaseQtApplication/Editor.cxx b/lib/cpBaseQtApplication/Editor.cxx
index 35b8a61..fb911c3 100644
--- a/lib/cpBaseQtApplication/Editor.cxx
+++ b/lib/cpBaseQtApplication/Editor.cxx
@@ -68,9 +68,18 @@ void cpBaseQtApplication::Editor::
 setWorkspace( TWorkspace* ws )
 {
   this->m_Workspace = ws;
-  this->m_Graph = TGraph::New( );
+  this->redrawWorkspace( );
+}
 
+// -------------------------------------------------------------------------
+void cpBaseQtApplication::Editor::
+redrawWorkspace( )
+{
+  if( this->m_Workspace == NULL )
+    return;
+  
   // Create blocks
+  std::map< std::string, Block* > blocks;
   auto vIt = this->m_Workspace->GetGraph( )->BeginVertices( );
   auto vIt_end = this->m_Workspace->GetGraph( )->EndVertices( );
   for( ; vIt != vIt_end; ++vIt )
@@ -80,8 +89,7 @@ setWorkspace( TWorkspace* ws )
       vIt->first.c_str( ),
       QPointF( vIt->second->GetViewX( ), vIt->second->GetViewY( ) )
       );
-    if( b != NULL )
-      this->m_Graph->SetVertex( vIt->first, b );
+    blocks[ vIt->first ] = b;
 
   } // rof
 
@@ -90,11 +98,11 @@ setWorkspace( TWorkspace* ws )
   auto rIt_end = this->m_Workspace->GetGraph( )->EndEdgesRows( );
   for( ; rIt != rIt_end; ++rIt )
   {
-    Block* orig = this->m_Graph->GetVertex( rIt->first );
+    Block* orig = blocks[ rIt->first ];
     auto cIt = rIt->second.begin( );
     for( ; cIt != rIt->second.end( ); ++cIt )
     {
-      Block* dest = this->m_Graph->GetVertex( cIt->first );
+      Block* dest = blocks[ cIt->first ];
       auto eIt = cIt->second.begin( );
       for( ; eIt != cIt->second.end( ); ++eIt )
       {
@@ -108,7 +116,6 @@ setWorkspace( TWorkspace* ws )
         c->setPort2( ip );
         c->updatePosFromPorts( );
         c->updatePath( );
-        this->m_Graph->AddEdge( rIt->first, cIt->first, c );
 
       } // rof
 
@@ -145,8 +152,10 @@ createFilter(
 bool cpBaseQtApplication::Editor::
 deleteFilter( const std::string& name )
 {
-  std::cout << name << std::endl;
-  return( false );
+  if( this->m_Workspace != NULL )
+    return( this->m_Workspace->RemoveFilter( name ) );
+  else
+    return( false );
 }
 
 // -------------------------------------------------------------------------
@@ -156,19 +165,23 @@ deleteConnection(
   const std::string& in, const std::string& out
   )
 {
-  std::cout
-    << src << " "
-    << des << " "
-    << in << " "
-    << out << std::endl;
-  return( false );
+  if( this->m_Workspace != NULL )
+    return( this->m_Workspace->Disconnect( src, des, in, out ) );
+  else
+    return( false );
 }
 
 // -------------------------------------------------------------------------
 void cpBaseQtApplication::Editor::
 clear( )
 {
-  std::cout << "Editor::clear" << std::endl;
+  std::cout << "Editor: clear" << std::endl;
+  /* TODO
+     auto vIt = this->m_Graph.BeginVertices( );
+     for( ; vIt != this->m_Graph.EndVertices( ); ++vIt )
+     {
+     } // rof
+  */
 }
 
 // -------------------------------------------------------------------------
@@ -356,6 +369,7 @@ cpBaseQtApplication_Editor_Callback_CODE( HoverMove )
 // -------------------------------------------------------------------------
 cpBaseQtApplication_Editor_Callback_CODE( MouseDoubleClick )
 {
+  /* TODO
   QGraphicsItem* item = this->itemAt( evt->scenePos( ) );
   if( item == NULL )
     return;
@@ -481,7 +495,6 @@ cpBaseQtApplication_Editor_Callback_CODE( MouseDoubleClick )
     } // fi
   }
   break;
-  /* TODO:
      case Qt::RightButton:
      {
      }
@@ -490,10 +503,10 @@ cpBaseQtApplication_Editor_Callback_CODE( MouseDoubleClick )
      {
      }
      break;
-  */
   default:
     break;
   } // hctiws
+  */
 }
 
 // -------------------------------------------------------------------------
@@ -583,11 +596,6 @@ cpBaseQtApplication_Editor_Callback_CODE( MouseRelease )
             port1->name( ).toStdString( ),
             port2->name( ).toStdString( )
             );
-          this->m_Graph->AddEdge(
-            port1->block( )->namePort( ).toStdString( ),
-            port2->block( )->namePort( ).toStdString( ),
-            this->m_ActualConnection
-            );
         }
         else
           delete this->m_ActualConnection;
diff --git a/lib/cpBaseQtApplication/Editor.h b/lib/cpBaseQtApplication/Editor.h
index 073de08..5eab4bf 100644
--- a/lib/cpBaseQtApplication/Editor.h
+++ b/lib/cpBaseQtApplication/Editor.h
@@ -2,7 +2,6 @@
 #define __CPBASEQTAPPLICATION__EDITOR__H__
 
 #include <cpBaseQtApplication_Export.h>
-#include <cpExtensions/DataStructures/Graph.h>
 #include <cpPlugins/Workspace.h>
 #include <QObject>
 #include <QPointF>
@@ -41,9 +40,6 @@ namespace cpBaseQtApplication
 
     typedef cpPlugins::Workspace     TWorkspace;
     typedef cpPlugins::ProcessObject TFilter;
-    typedef
-      cpExtensions::DataStructures::
-      Graph< Block*, Connection*, std::string > TGraph;
 
   public:
     explicit Editor( QObject* parent = 0 );
@@ -52,6 +48,7 @@ namespace cpBaseQtApplication
     TWorkspace* workspace( );
     const TWorkspace* workspace( ) const;
     void setWorkspace( TWorkspace* ws );
+    void redrawWorkspace( );
 
     std::string createFilter(
       const std::string& category, const std::string& filter,
@@ -138,7 +135,6 @@ namespace cpBaseQtApplication
     Connection* m_ActualConnection;
 
     TWorkspace* m_Workspace;
-    TGraph::Pointer m_Graph;
   };
 
 } // ecapseman
diff --git a/lib/cpBaseQtApplication/MainWindow.cxx b/lib/cpBaseQtApplication/MainWindow.cxx
index 830508f..41f2df5 100644
--- a/lib/cpBaseQtApplication/MainWindow.cxx
+++ b/lib/cpBaseQtApplication/MainWindow.cxx
@@ -297,10 +297,8 @@ _LoadWorkspace( const std::string& filename )
   }
   else
   {
-    /* TODO
-       if( this->m_Editor != NULL )
-       this->m_Editor->setWorkspace( this->m_Workspace );
-    */
+    if( this->m_Editor != NULL )
+      this->m_Editor->redrawWorkspace( );
 
   } // fi
 }
diff --git a/lib/cpExtensions/DataStructures/Graph.hxx b/lib/cpExtensions/DataStructures/Graph.hxx
index d2d2d23..8470099 100644
--- a/lib/cpExtensions/DataStructures/Graph.hxx
+++ b/lib/cpExtensions/DataStructures/Graph.hxx
@@ -131,7 +131,14 @@ RemoveEdge( const I& orig, const I& dest, const C& cost )
     auto r = m->second.find( dest );
     if( r != m->second.end( ) )
     {
-      auto e = std::find( r->second.begin( ), r->second.end( ), cost );
+      auto e = r->second.end( );
+      for(
+        auto i = r->second.begin( );
+        i != r->second.end( ) && e == r->second.end( );
+        ++i
+        )
+        if( *i == cost )
+          e = i;
       if( e != r->second.end( ) )
       {
         r->second.erase( e );
diff --git a/lib/cpPlugins/ProcessObject.h b/lib/cpPlugins/ProcessObject.h
index d161e77..ca5700a 100644
--- a/lib/cpPlugins/ProcessObject.h
+++ b/lib/cpPlugins/ProcessObject.h
@@ -78,6 +78,9 @@ namespace cpPlugins
 
     bool SetInputPort( const std::string& id, const OutputPort& port );
 
+    template< class _TType >
+      inline bool SetInput( const std::string& id, _TType* obj );
+
     void DisconnectInputs( );
     void DisconnectOutputs( );
     void Disconnect( );
diff --git a/lib/cpPlugins/ProcessObject.hxx b/lib/cpPlugins/ProcessObject.hxx
index 9be2675..99954d4 100644
--- a/lib/cpPlugins/ProcessObject.hxx
+++ b/lib/cpPlugins/ProcessObject.hxx
@@ -85,6 +85,22 @@ GetOutputData( const std::string& name )
     return( NULL );
 }
 
+// -------------------------------------------------------------------------
+template< class _TType >
+bool cpPlugins::ProcessObject::
+SetInput( const std::string& id, _TType* obj )
+{
+  auto i = this->m_Inputs.find( id );
+  if( i != this->m_Inputs.end( ) )
+  {
+    i->second = obj;
+    this->Modified( );
+    return( true );
+  }
+  else
+    return( false );
+}
+
 // -------------------------------------------------------------------------
 template< class O >
 void cpPlugins::ProcessObject::
diff --git a/lib/cpPlugins/Workspace.cxx b/lib/cpPlugins/Workspace.cxx
index dd4ade8..b3f6af7 100644
--- a/lib/cpPlugins/Workspace.cxx
+++ b/lib/cpPlugins/Workspace.cxx
@@ -172,9 +172,42 @@ RenameFilter( const std::string& old_name, const std::string& new_name )
 }
 
 // -------------------------------------------------------------------------
-void cpPlugins::Workspace::
+bool cpPlugins::Workspace::
 RemoveFilter( const std::string& name )
 {
+  auto filter = this->GetFilter( name );
+  if( filter != NULL )
+  {
+    auto vIt = this->m_Graph->BeginVertices( );
+    for( ; vIt != this->m_Graph->EndVertices( ); ++vIt )
+    {
+      if( vIt->first != name )
+      {
+        if( this->m_Graph->HasEdge( name, vIt->first ) )
+        {
+          auto edges = this->m_Graph->GetEdges( name, vIt->first );
+          auto other = this->GetFilter( vIt->first );
+          for( auto eIt = edges.begin( ); eIt != edges.end( ); ++eIt )
+            other->SetInput( eIt->first, ( DataObject* )( NULL ) );
+
+        } // fi
+
+        if( this->m_Graph->HasEdge( vIt->first, name ) )
+        {
+          auto edges = this->m_Graph->GetEdges( vIt->first, name );
+          for( auto eIt = edges.begin( ); eIt != edges.end( ); ++eIt )
+            filter->SetInput( eIt->first, ( DataObject* )( NULL ) );
+
+        } // fi
+
+      } // fi
+
+    } // rof
+    this->m_Graph->RemoveVertex( name );
+    return( true );
+  }
+  else
+    return( false );
 }
 
 // -------------------------------------------------------------------------
@@ -306,6 +339,32 @@ Connect( const OutputPort& port, const std::string& exposed_port )
     return( false );
 }
 
+// -------------------------------------------------------------------------
+bool cpPlugins::Workspace::
+Disconnect(
+  const std::string& orig_filter, const std::string& dest_filter,
+  const std::string& output_name, const std::string& input_name
+  )
+{
+  // Get filters
+  ProcessObject* orig = this->GetFilter( orig_filter );
+  ProcessObject* dest = this->GetFilter( dest_filter );
+  if( orig == NULL || dest == NULL )
+    return( false );
+
+  // Real disconnection
+  if( dest->SetInput( input_name, ( DataObject* )( NULL ) ) )
+  {
+    this->m_Graph->RemoveEdge(
+      orig_filter, dest_filter,
+      TConnection( output_name, input_name )
+      );
+    return( true );
+  }
+  else
+    return( false );
+}
+
 // -------------------------------------------------------------------------
 bool cpPlugins::Workspace::
 Reduce( const std::string& name )
@@ -467,7 +526,7 @@ Execute( const std::string& name )
   ProcessObject* f = this->GetFilter( name );
   if( f == NULL )
   {
-    itkGenericExceptionMacro( 
+    itkGenericExceptionMacro(
       "cpPlugins::Workspace: Vertex \"" << name << "\" is not a filter."
       );
 
diff --git a/lib/cpPlugins/Workspace.h b/lib/cpPlugins/Workspace.h
index eb14690..f22b283 100644
--- a/lib/cpPlugins/Workspace.h
+++ b/lib/cpPlugins/Workspace.h
@@ -16,11 +16,7 @@ namespace cpExtensions
 {
   namespace QT
   {
-// TODO: #ifdef cpPlugins_QT4
     class SimpleMPRWidget;
-// TODO: #else // cpPlugins_QT4
-// TODO:     typedef char SimpleMPRWidget;
-// TODO: #endif // cpPlugins_QT4
   }
 }
 
@@ -83,7 +79,7 @@ namespace cpPlugins
     bool RenameFilter(
       const std::string& old_name, const std::string& new_name
       );
-    void RemoveFilter( const std::string& name );
+    bool RemoveFilter( const std::string& name );
     void SetParameter( const std::string& name, const std::string& value );
 
     void SetPrintExecution( bool b );
@@ -105,11 +101,18 @@ namespace cpPlugins
       const std::string& output_name, const std::string& input_name
       );
     bool Connect( const OutputPort& port, const std::string& exposed_port );
-    void RemoveConnection(
-      const std::string& dest_filter, const std::string& input_name
+
+    bool Disconnect(
+      const std::string& orig_filter, const std::string& dest_filter,
+      const std::string& output_name, const std::string& input_name
       );
-    void RemoveConnection( const std::string& exposed_port );
-    void RemoveConnections( const std::string& dest_filter );
+    /* TODO
+       void RemoveConnection(
+       const std::string& dest_filter, const std::string& input_name
+       );
+       void RemoveConnection( const std::string& exposed_port );
+       void RemoveConnections( const std::string& dest_filter );
+    */
 
     // Graph reduction
     bool Reduce( const std::string& name );
-- 
2.49.0