]> Creatis software - cpPlugins.git/blob - appli/PipelineEditor/PipelineEditor.cxx
...
[cpPlugins.git] / appli / PipelineEditor / PipelineEditor.cxx
1 #include "PipelineEditor.h"
2 #include "ui_PipelineEditor.h"
3
4 #include <cpPipelineEditor/Editor.h>
5
6 #include <QFileDialog>
7 #include <QMessageBox>
8
9 #include <vtkImageData.h>
10 #include <vtkPolyData.h>
11
12 #include <cpPlugins/DataObject.h>
13
14 // -------------------------------------------------------------------------
15 #define PipelineEditor_ConnectAction( ACTION )          \
16   this->connect(                                        \
17     this->m_UI->Action##ACTION, SIGNAL( triggered( ) ), \
18     this, SLOT( _Action##ACTION( ) )                    \
19     )
20
21 // -------------------------------------------------------------------------
22 #define PipelineEditor_ConnectButton( BUTTON )          \
23   this->connect(                                        \
24     this->m_UI->Button##BUTTON, SIGNAL( clicked( ) ),   \
25     this, SLOT( _Button##BUTTON( ) )                    \
26     )
27
28 // -------------------------------------------------------------------------
29 bool PipelineEditor_Blocker::
30 eventFilter( QObject* obj, QEvent* event )
31 {
32   return( true ); // -> Block all events
33   /* NOTE: correct implementation:
34      switch( event->type( ) )
35      {
36      //list event you want to prevent here ...
37      case QEvent::KeyPress:
38      case QEvent::KeyRelease:
39      case QEvent::MouseButtonRelease:
40      case QEvent::MouseButtonPress:
41      case QEvent::MouseButtonDblClick:
42      //...
43      return( true );
44      } // hctiws
45      return( this->QObject::eventFilter( obj, event ) );
46   */
47 }
48
49 // -------------------------------------------------------------------------
50 PipelineEditor::
51 PipelineEditor( int argc, char* argv[], QApplication* app, QWidget* parent )
52   : QMainWindow( parent ),
53     m_UI( new Ui::PipelineEditor ),
54     m_Application( app ),
55     m_Workspace( NULL ),
56     m_PluginsPath( "." )
57 {
58   this->m_UI->setupUi( this );
59
60   // Prepare plugins interface
61   QFileInfo info( argv[ 0 ] );
62   if( info.exists( ) )
63   {
64     if( !( this->m_Interface.LoadConfiguration( cpPlugins_CONFIG_FILE ) ) )
65     {
66       this->m_PluginsPath = info.canonicalPath( ).toStdString( );
67       this->_LoadPluginsFromPath( this->m_PluginsPath );
68     }
69     /*
70       else
71       this->_UpdateLoadedPlugins( );
72     */
73
74   } // fi
75   QDir exec_dir( "." );
76   if( exec_dir.exists( ) )
77     this->_LoadPluginsFromPath( exec_dir.canonicalPath( ).toStdString( ) );
78
79   /* TODO
80      this->m_Interface = new cpPlugins::Interface( );
81      this->m_PluginsPath = info.canonicalPath( ).toStdString( );
82      if( !( this->m_Interface->LoadDefaultConfiguration( this->m_PluginsPath ) ) )
83      if( this->m_Interface->LoadFromFolder( this->m_PluginsPath, false ) != "" )
84      if( !( this->m_Interface->SaveDefaultConfiguration( this->m_PluginsPath ) ) )
85      QMessageBox::critical(
86      this,
87      "Error creating default plugins configuration",
88      "Could not save default plugins configuration"
89      );
90      this->_UpdateLoadedPlugins( );
91
92      } // fi
93   */
94
95   // Create an empty workspace
96   this->m_Workspace = new cpPlugins::Workspace( );
97   this->m_Workspace->SetInterface( &( this->m_Interface ) );
98   this->m_UI->Canvas->editor( )->setWorkspace( this->m_Workspace );
99   this->m_Workspace->SetMPRViewer( this->m_UI->Viewer );
100
101   // Connect actions to slots
102   PipelineEditor_ConnectButton( LoadPluginsFile );
103   PipelineEditor_ConnectButton( LoadPluginsPath );
104   PipelineEditor_ConnectAction( OpenWorkspace );
105   PipelineEditor_ConnectAction( SaveWorkspace );
106   this->connect(
107     this->m_UI->Canvas->editor( ),
108     SIGNAL( execFilter( const std::string& ) ),
109     this,
110     SLOT( _ExecFilter( const std::string& ) )
111     );
112   this->connect(
113     this->m_UI->Canvas->editor( ),
114     SIGNAL( showFilterOutput( const std::string&, const std::string& ) ),
115     this,
116     SLOT( _ShowFilterOutput( const std::string&, const std::string& ) )
117     );
118 }
119
120 // -------------------------------------------------------------------------
121 PipelineEditor::
122 ~PipelineEditor( )
123 {
124   if( this->m_Workspace != NULL )
125     delete this->m_Workspace;
126   delete this->m_UI;
127 }
128
129 // -------------------------------------------------------------------------
130 void PipelineEditor::
131 _LoadPluginsFromPath( const std::string& path )
132 {
133   QDir dir( path.c_str( ) );
134   std::stringstream filters_str;
135   filters_str << "*." << cpPlugins_PLUGIN_EXT;
136   QStringList filters;
137   filters << filters_str.str( ).c_str( );
138   auto files = dir.entryList( filters );
139   for( auto fIt = files.begin( ); fIt != files.end( ); ++fIt )
140   {
141     try
142     {
143       this->m_Interface.LoadPluginFile(
144         ( dir.absolutePath( ) + QDir::separator( ) + *fIt ).toStdString( )
145         );
146     }
147     catch( std::exception& err )
148     {
149       // Just ignore un-loadable libraries
150     } // yrt
151
152   } // rof
153   this->_UpdateLoadedPlugins( );
154 }
155
156 // -------------------------------------------------------------------------
157 void PipelineEditor::
158 _UpdateLoadedPlugins( )
159 {
160   this->_Block( );
161   auto filters = this->m_Interface.GetFilters( );
162   if( filters.size( ) == 0 )
163   {
164     QMessageBox::critical(
165       this,
166       "Error loading default plugins",
167       "No plugins loaded: remember to load some!!!"
168       );
169     this->_UnBlock( );
170     return;
171
172   } // fi
173
174   for( auto cIt = filters.begin( ); cIt != filters.end( ); ++cIt )
175   {
176     // Create or get category
177     QList< QTreeWidgetItem* > cat_items =
178       this->m_UI->LoadedPlugins->findItems(
179         cIt->first.c_str( ), Qt::MatchExactly | Qt::MatchRecursive
180         );
181     QTreeWidgetItem* cat = NULL;
182     if( cat_items.size( ) == 0 )
183     {
184       cat = new QTreeWidgetItem(
185         ( QTreeWidgetItem* )( NULL ), QStringList( cIt->first.c_str( ) )
186         );
187       this->m_UI->LoadedPlugins->addTopLevelItem( cat );
188     }
189     else
190       cat = cat_items[ 0 ];
191
192     // Create filters
193     auto fIt = cIt->second.begin( );
194     for( ; fIt != cIt->second.end( ); ++fIt )
195     {
196       QList< QTreeWidgetItem* > filter_items =
197         this->m_UI->LoadedPlugins->findItems(
198           fIt->c_str( ), Qt::MatchExactly | Qt::MatchRecursive
199           );
200       auto fiIt = filter_items.begin( );
201       auto found_fiIt = filter_items.end( );
202       for( ; fiIt != filter_items.end( ); ++fiIt )
203         if( ( *fiIt )->parent( ) == cat )
204           found_fiIt = fiIt;
205
206       // Add filter
207       if( found_fiIt == filter_items.end( ) )
208         QTreeWidgetItem* filter = new QTreeWidgetItem(
209           cat, QStringList( fIt->c_str( ) )
210           );
211
212     } // rof
213
214   } // rof
215   this->_UnBlock( );
216   this->m_Interface.SaveConfiguration( cpPlugins_CONFIG_FILE );
217 }
218
219 // -------------------------------------------------------------------------
220 void PipelineEditor::
221 _Block( )
222 {
223   this->m_Application->setOverrideCursor( Qt::WaitCursor );
224   this->m_Application->installEventFilter( &( this->m_Blocker ) );
225 }
226
227 // -------------------------------------------------------------------------
228 void PipelineEditor::
229 _UnBlock( )
230 {
231   while( this->m_Application->overrideCursor( ) )
232     this->m_Application->restoreOverrideCursor( );
233   this->m_Application->removeEventFilter( &( this->m_Blocker ) );
234 }
235
236 // -------------------------------------------------------------------------
237 void PipelineEditor::
238 _ButtonLoadPluginsFile( )
239 {
240   QFileDialog dlg( this );
241   dlg.setFileMode( QFileDialog::ExistingFiles );
242   dlg.setDirectory( "." );
243
244   std::stringstream name_filter;
245   std::string suffix = std::string( cpPlugins_PLUGIN_EXT );
246   name_filter
247     << "Plugins file (*." << cpPlugins_PLUGIN_EXT << ");;All files (*)";
248   dlg.setNameFilter( name_filter.str( ).c_str( ) );
249   dlg.setDefaultSuffix( suffix.c_str( ) );
250
251   if( !( dlg.exec( ) ) )
252     return;
253
254   // Read
255   QStringList names = dlg.selectedFiles( );
256   std::stringstream err_str;
257   for( auto qIt = names.begin( ); qIt != names.end( ); ++qIt )
258   {
259     try
260     {
261       this->m_Interface.LoadPluginFile( qIt->toStdString( ) );
262     }
263     catch( std::exception& err )
264     {
265       err_str << err.what( ) << std::endl;
266
267     } // yrt
268
269   } // rof
270
271   // Show an error message
272   std::string err = err_str.str( );
273   if( err.size( ) > 0 )
274     QMessageBox::critical(
275       this,
276       "Error loading plugins",
277       err.c_str( )
278       );
279
280   // Update view
281   // TODO: this->m_Interface.SaveDefaultConfiguration( this->m_PluginsPath );
282   this->_UpdateLoadedPlugins( );
283 }
284
285 // -------------------------------------------------------------------------
286 void PipelineEditor::
287 _ButtonLoadPluginsPath( )
288 {
289   /*
290     QFileDialog dlg( this );
291     dlg.setFileMode( QFileDialog::DirectoryOnly );
292     dlg.setDirectory( "." );
293     if( !( dlg.exec( ) ) )
294     return;
295
296     // Read
297     std::string dir = dlg.selectedFiles( ).begin( )->toStdString( );
298     std::string err = this->m_Interface->LoadFromFolder( dir, false );
299     if( err != "" )
300     QMessageBox::critical(
301     this,
302     "Error loading plugins directory",
303     err.c_str( )
304     );
305
306     // Update view
307     this->m_Interface->SaveDefaultConfiguration( this->m_PluginsPath );
308     this->_UpdateLoadedPlugins( );
309   */
310 }
311
312 // -------------------------------------------------------------------------
313 void PipelineEditor::
314 _ActionOpenWorkspace( )
315 {
316   QFileDialog dlg( this );
317   dlg.setFileMode( QFileDialog::ExistingFile );
318   dlg.setDirectory( "." );
319   dlg.setNameFilter(
320     QFileDialog::tr( "Workspace file (*.wxml);;All files (*)" )
321     );
322   dlg.setDefaultSuffix( QFileDialog::tr( "wxml" ) );
323   if( !( dlg.exec( ) ) )
324     return;
325
326   std::string fname = dlg.selectedFiles( ).at( 0 ).toStdString( );
327   if( this->m_Workspace != NULL )
328     delete this->m_Workspace;
329   this->m_Workspace = new cpPlugins::Workspace( );
330   this->m_Workspace->SetInterface( &( this->m_Interface ) );
331   this->m_Workspace->SetMPRViewer( this->m_UI->Viewer );
332   std::string err = this->m_Workspace->LoadWorkspace( fname );
333   if( err != "" )
334   {
335     delete this->m_Workspace;
336     this->m_Workspace = NULL;
337     QMessageBox::critical(
338       this,
339       QMessageBox::tr( "Error loading workspace" ),
340       QMessageBox::tr( err.c_str( ) )
341       );
342   }
343   else
344     this->m_UI->Canvas->editor( )->setWorkspace( this->m_Workspace );
345 }
346
347 // -------------------------------------------------------------------------
348 void PipelineEditor::
349 _ActionSaveWorkspace( )
350 {
351   if( this->m_Workspace == NULL )
352     return;
353
354   QFileDialog dlg( this );
355   dlg.setFileMode( QFileDialog::AnyFile );
356   dlg.setDirectory( "." );
357   dlg.setAcceptMode( QFileDialog::AcceptSave );
358   dlg.setNameFilter(
359     QFileDialog::tr( "Workspace file (*.wxml);;All files (*)" )
360     );
361   dlg.setDefaultSuffix( QFileDialog::tr( "wxml" ) );
362   if( !( dlg.exec( ) ) )
363     return;
364   std::string fname = dlg.selectedFiles( ).at( 0 ).toStdString( );
365
366   std::string err = this->m_Workspace->SaveWorkspace( fname );
367   if( err != "" )
368     QMessageBox::critical(
369       this,
370       QMessageBox::tr( "Error saving workspace" ),
371       QMessageBox::tr( err.c_str( ) )
372       );
373 }
374
375
376 // -------------------------------------------------------------------------
377 void PipelineEditor::
378 _ExecFilter( const std::string& filter_name )
379 {
380   if( this->m_Workspace != NULL )
381   {
382     // Update filter, if needed
383     this->_Block( );
384     std::string err = this->m_Workspace->Execute( filter_name );
385     this->_UnBlock( );
386     if( err != "" )
387       QMessageBox::critical(
388         this,
389         QMessageBox::tr( "Error executing filter" ),
390         QMessageBox::tr( err.c_str( ) )
391         );
392
393   } // fi
394 }
395
396 // -------------------------------------------------------------------------
397 void PipelineEditor::
398 _ShowFilterOutput(
399   const std::string& filter_name, const std::string& output_name
400   )
401 {
402   typedef cpPlugins::DataObject _TDataObject;
403
404   // Update filter, if needed
405   this->_ExecFilter( filter_name );
406
407   // Get output
408   auto filter = this->m_Workspace->GetFilter( filter_name );
409   if( filter != NULL )
410   {
411     auto output = filter->GetOutputData( output_name );
412     if( output != NULL )
413     {
414       std::string data_name = output_name + "@" + filter_name;
415       auto idata = output->GetVTK< vtkImageData >( );
416       auto mdata = output->GetVTK< vtkPolyData >( );
417       if( idata != NULL )
418       {
419         if( this->m_UI->Viewer->AddData( idata, data_name, "" ) )
420         {
421           if( this->m_UI->Viewer->GetNumberOfData( ) > 1 )
422             this->m_UI->Viewer->SetDataColor( data_name, 1, 0, 0 );
423           else
424             this->m_UI->Viewer->SetMainImage( data_name );
425           this->_Block( );
426           this->m_UI->Viewer->ShowData( data_name );
427           this->_UnBlock( );
428
429         } // fi
430       }
431       else if( mdata != NULL )
432       {
433         if( this->m_UI->Viewer->AddData( mdata, data_name ) )
434         {
435           this->m_UI->Viewer->SetDataColor( data_name, 1, 0, 0 );
436           this->_Block( );
437           this->m_UI->Viewer->ShowData( data_name );
438           this->_UnBlock( );
439
440         } // fi
441       }
442       else
443         QMessageBox::critical(
444           this,
445           QMessageBox::tr( "Error showing data" ),
446           QMessageBox::tr( "No known VTK conversion!" )
447           );
448
449       /* TODO
450          if( this->m_UI->Viewer->AddData( output, data_name, "" ) )
451          {
452          if( this->m_UI->Viewer->GetNumberOfData( ) > 1 )
453          this->m_UI->Viewer->SetDataColor( data_name, 1, 0, 0 );
454          else
455          this->m_UI->Viewer->SetMainImage( data_name );
456          this->m_UI->Viewer->ShowData( data_name );
457          }
458          else
459       */
460
461     } // fi
462
463   } // fi
464 }
465
466 // eof - $RCSfile$