]> Creatis software - cpPlugins.git/blob - lib/cpPlugins/Interface/Plugins.cxx
Getting ready for interactive initialization.
[cpPlugins.git] / lib / cpPlugins / Interface / Plugins.cxx
1 #include <cpPlugins/Interface/Plugins.h>
2 #include <cpPlugins/Interface/Config.h>
3
4 #include <fstream>
5 #include <sstream>
6
7 #ifdef cpPlugins_Interface_QT4
8
9 #include <QApplication>
10 #include <QFileDialog>
11 #include <QMenu>
12 #include <QMessageBox>
13 #include <QWidget>
14
15 #ifdef _WIN32
16 #  define PLUGIN_PREFIX ""
17 #  define PLUGIN_EXT "dll"
18 #  define PLUGIN_REGEX "Plugins file (*.dll);;All files (*)"
19 #else // Linux
20 #  define PLUGIN_PREFIX "lib"
21 #  define PLUGIN_EXT "so"
22 #  define PLUGIN_REGEX "Plugins file (*.so);;All files (*)"
23 #endif // _WIN32
24
25 #endif // cpPlugins_Interface_QT4
26
27 // -------------------------------------------------------------------------
28 cpPlugins::Interface::Plugins::
29 Plugins( QWidget* widget )
30   : m_Widget( widget ),
31     m_LastLoadedPlugin( "." )
32 {
33 }
34
35 // -------------------------------------------------------------------------
36 cpPlugins::Interface::Plugins::
37 ~Plugins( )
38 {
39   // TODO: this causes a segfault? this->m_Interface.UnloadAll( );
40 }
41
42 // -------------------------------------------------------------------------
43 QWidget* cpPlugins::Interface::Plugins::
44 GetWidget( )
45 {
46   return( this->m_Widget );
47 }
48
49 // -------------------------------------------------------------------------
50 const QWidget* cpPlugins::Interface::Plugins::
51 GetWidget( ) const
52 {
53   return( this->m_Widget );
54 }
55
56 // -------------------------------------------------------------------------
57 void cpPlugins::Interface::Plugins::
58 SetWidget( QWidget* widget )
59 {
60   this->m_Widget = widget;
61 }
62
63 // -------------------------------------------------------------------------
64 void cpPlugins::Interface::Plugins::
65 BlockWidget( )
66 {
67 #ifdef cpPlugins_Interface_QT4
68   if( this->m_Widget != NULL )
69   {
70     QApplication::setOverrideCursor( Qt::WaitCursor );
71     this->m_Widget->setEnabled( false );
72
73   } // fi
74 #endif // cpPlugins_Interface_QT4
75 }
76
77 // -------------------------------------------------------------------------
78 void cpPlugins::Interface::Plugins::
79 UnblockWidget( )
80 {
81 #ifdef cpPlugins_Interface_QT4
82   if( this->m_Widget != NULL )
83   {
84     QApplication::restoreOverrideCursor( );
85     this->m_Widget->setEnabled( true );
86
87   } // fi
88 #endif // cpPlugins_Interface_QT4
89 }
90
91 // -------------------------------------------------------------------------
92 void cpPlugins::Interface::Plugins::
93 DialogLoadPlugins( )
94 {
95 #ifdef cpPlugins_Interface_QT4
96   if( this->m_Widget != NULL )
97   {
98     QFileDialog dialog( this->m_Widget );
99     dialog.setFileMode( QFileDialog::ExistingFile );
100     dialog.setDirectory( this->m_LastLoadedPlugin.c_str( ) );
101     dialog.setNameFilter( QFileDialog::tr( PLUGIN_REGEX ) );
102     dialog.setDefaultSuffix( QFileDialog::tr( PLUGIN_EXT ) );
103     if( !( dialog.exec( ) ) )
104       return;
105
106     std::string fname = dialog.selectedFiles( ).at( 0 ).toStdString( );
107     if( !( this->LoadPlugins( fname ) ) )
108       QMessageBox::critical(
109         this->m_Widget,
110         QMessageBox::tr( "Ignoring plugin" ),
111         QMessageBox::tr( fname.c_str( ) )
112         );
113
114   } // fi
115 #endif // cpPlugins_Interface_QT4
116 }
117
118 // -------------------------------------------------------------------------
119 void cpPlugins::Interface::Plugins::
120 AssociatePluginsToMenu( QMenu* menu, QObject* obj, const char* slot )
121 {
122 #ifdef cpPlugins_Interface_QT4
123   std::map< std::string, std::set< std::string > >::const_iterator i;
124   std::set< std::string >::const_iterator j;
125
126   menu->clear( );
127   for( i = this->m_Filters.begin( ); i != this->m_Filters.end( ); i++ )
128   {
129     QMenu* newMenu = menu->addMenu( i->first.c_str( ) );
130     for( j = i->second.begin( ); j != i->second.end( ); ++j )
131     {
132       QAction* a = newMenu->addAction( j->c_str( ) );
133       QObject::connect( a, SIGNAL( triggered( ) ), obj, slot );
134
135     } // rof
136
137   } // rof
138 #endif // cpPlugins_Interface_QT4
139 }
140
141 // -------------------------------------------------------------------------
142 bool cpPlugins::Interface::Plugins::
143 LoadPlugins( const std::string& fname )
144 {
145   this->BlockWidget( );
146
147   // Is it already loaded?
148   bool ret = true;
149   if( this->m_LoadedPlugins.find( fname ) == this->m_LoadedPlugins.end( ) )
150   {
151     // Was it succesfully loaded?
152     ret = this->m_Interface.Load( fname );
153
154     // Update a simple track
155     if( ret )
156     {
157       this->m_LoadedPlugins.insert( fname );
158       this->m_LastLoadedPlugin = fname;
159       this->_Update( );
160
161     } // fi
162
163   } // fi
164
165   this->UnblockWidget( );
166   return( ret );
167 }
168
169 // -------------------------------------------------------------------------
170 bool cpPlugins::Interface::Plugins::
171 LoadPluginsConfigurationFile( const std::string& fname )
172 {
173   // Load file into a char buffer
174   std::ifstream in(
175     fname.c_str( ), std::ios::in | std::ios::binary | std::ios::ate
176     );
177   if( !in.is_open( ) )
178     return( false );
179
180   std::streampos size = in.tellg( );
181   char* buffer = new char[ size ];
182   in.seekg( 0, std::ios::beg );
183   in.read( buffer, size );
184   in.close( );
185
186   // Read stream
187   std::stringstream in_stream( buffer );
188   char line[ 4096 ];
189   while( in_stream )
190   {
191     in_stream.getline( line, 4096 );
192     this->LoadPlugins( line );
193
194   } // elihw
195   delete buffer;
196
197   return( true );
198 }
199
200 // -------------------------------------------------------------------------
201 cpPlugins::Interface::Plugins::
202 TParameters* cpPlugins::Interface::Plugins::
203 GetImageReaderParameters( )
204 {
205   return( this->m_ImageReader->GetParameters( ) );
206 }
207
208 // -------------------------------------------------------------------------
209 cpPlugins::Interface::Plugins::
210 TParameters* cpPlugins::Interface::Plugins::
211 GetMeshReaderParameters( )
212 {
213   return( this->m_MeshReader->GetParameters( ) );
214 }
215
216 // -------------------------------------------------------------------------
217 cpPlugins::Interface::Plugins::
218 TParameters* cpPlugins::Interface::Plugins::
219 GetImageWriterParameters( )
220 {
221   return( this->m_ImageWriter->GetParameters( ) );
222 }
223
224 // -------------------------------------------------------------------------
225 cpPlugins::Interface::Plugins::
226 TParameters* cpPlugins::Interface::Plugins::
227 GetMeshWriterParameters( )
228 {
229   return( this->m_MeshWriter->GetParameters( ) );
230 }
231
232 // -------------------------------------------------------------------------
233 const cpPlugins::Interface::Plugins::
234 TParameters* cpPlugins::Interface::Plugins::
235 GetImageReaderParameters( ) const
236 {
237   return( this->m_ImageReader->GetParameters( ) );
238 }
239
240 // -------------------------------------------------------------------------
241 const cpPlugins::Interface::Plugins::
242 TParameters* cpPlugins::Interface::Plugins::
243 GetMeshReaderParameters( ) const
244 {
245   return( this->m_MeshReader->GetParameters( ) );
246 }
247
248 // -------------------------------------------------------------------------
249 const cpPlugins::Interface::Plugins::
250 TParameters* cpPlugins::Interface::Plugins::
251 GetImageWriterParameters( ) const
252 {
253   return( this->m_ImageWriter->GetParameters( ) );
254 }
255
256 // -------------------------------------------------------------------------
257 const cpPlugins::Interface::Plugins::
258 TParameters* cpPlugins::Interface::Plugins::
259 GetMeshWriterParameters( ) const
260 {
261   return( this->m_MeshWriter->GetParameters( ) );
262 }
263
264 // -------------------------------------------------------------------------
265 bool cpPlugins::Interface::Plugins::
266 ReadImage( TImage::Pointer& image, bool exec_qt )
267 {
268   std::string ret = "";
269   if( this->m_ImageReader.IsNull( ) )
270     ret = "Plugins: No valid image reader. Please load a valid plugin.";
271
272   if( ret == "" )
273   {
274     TProcessObject::DialogResult dret = TProcessObject::DialogResult_NoModal;
275     if( exec_qt )
276       dret = this->m_ImageReader->ExecConfigurationDialog( this->m_Widget );
277     if( dret != TProcessObject::DialogResult_Cancel )
278     {
279       this->BlockWidget( );
280       ret = this->m_ImageReader->Update( );
281       this->UnblockWidget( );
282       if( ret == "" )
283       {
284         image = this->m_ImageReader->GetOutput< TImage >( "Output" );
285         this->m_ImageReader->DisconnectOutputs( );
286         this->m_ImageReader->GetParameters( )->ClearStringList( "FileNames" );
287       }
288       else
289         image = NULL;
290
291     } // fi
292
293   } // fi
294
295   // Show an error message and return
296   if( ret != "" )
297   {
298 #ifdef cpPlugins_Interface_QT4
299     if( this->m_Widget != NULL )
300       QMessageBox::critical(
301         this->m_Widget,
302         QMessageBox::tr( "Error reading image." ),
303         QMessageBox::tr( ret.c_str( ) )
304         );
305 #endif // cpPlugins_Interface_QT4
306     return( false );
307   }
308   else
309     return( true );
310 }
311
312 // -------------------------------------------------------------------------
313 bool cpPlugins::Interface::Plugins::
314 ReadDicomSeries( TImage::Pointer& image )
315 {
316   std::string ret = "";
317   if( this->m_DicomSeriesReader.IsNull( ) )
318     ret = "Plugins: No valid dicom series reader. Please load a valid plugin.";
319
320   if( ret == "" )
321   {
322     TProcessObject::DialogResult dret =
323       this->m_DicomSeriesReader->ExecConfigurationDialog( this->m_Widget );
324     if( dret != TProcessObject::DialogResult_Cancel )
325     {
326       this->BlockWidget( );
327       ret = this->m_DicomSeriesReader->Update( );
328       this->UnblockWidget( );
329       if( ret == "" )
330       {
331         image = this->m_DicomSeriesReader->GetOutput< TImage >( "Output" );
332         this->m_DicomSeriesReader->DisconnectOutputs( );
333         this->m_DicomSeriesReader->GetParameters( )->
334           ClearStringList( "FileNames" );
335       }
336       else
337         image = NULL;
338
339     } // fi
340
341   } // fi
342
343   // Show an error message and return
344   if( ret != "" )
345   {
346 #ifdef cpPlugins_Interface_QT4
347     if( this->m_Widget != NULL )
348       QMessageBox::critical(
349         this->m_Widget,
350         QMessageBox::tr( "Error reading dicom series." ),
351         QMessageBox::tr( ret.c_str( ) )
352         );
353 #endif // cpPlugins_Interface_QT4
354     return( false );
355   }
356   else
357     return( true );
358 }
359
360 // -------------------------------------------------------------------------
361 bool cpPlugins::Interface::Plugins::
362 ReadMesh( TMesh::Pointer& mesh, bool exec_qt )
363 {
364   std::string ret = "";
365   if( this->m_MeshReader.IsNull( ) )
366     ret = "Plugins: No valid mesh reader. Please load a valid plugin.";
367
368   if( ret == "" )
369   {
370     TProcessObject::DialogResult dret = TProcessObject::DialogResult_NoModal;
371     if( exec_qt )
372       dret = this->m_MeshReader->ExecConfigurationDialog( this->m_Widget );
373     if( dret != TProcessObject::DialogResult_Cancel )
374     {
375       this->BlockWidget( );
376       ret = this->m_MeshReader->Update( );
377       this->UnblockWidget( );
378       if( ret == "" )
379       {
380         mesh = this->m_MeshReader->GetOutput< TMesh >( "Output" );
381         this->m_MeshReader->DisconnectOutputs( );
382       }
383       else
384         mesh = NULL;
385
386     } // fi
387
388   } // fi
389
390   // Show an error message and return
391   if( ret != "" )
392   {
393 #ifdef cpPlugins_Interface_QT4
394     if( this->m_Widget != NULL )
395       QMessageBox::critical(
396         this->m_Widget,
397         QMessageBox::tr( "Error reading image." ),
398         QMessageBox::tr( ret.c_str( ) )
399         );
400 #endif // cpPlugins_Interface_QT4
401     return( false );
402   }
403   else
404     return( true );
405 }
406
407 // -------------------------------------------------------------------------
408 bool cpPlugins::Interface::Plugins::
409 WriteImage( TImage* image, bool exec_qt )
410 {
411   std::string ret = "";
412   if( this->m_ImageWriter.IsNull( ) )
413     ret = "Plugins: No valid image writer. Please load a valid plugin.";
414
415   if( ret == "" )
416   {
417     TProcessObject::DialogResult dret = TProcessObject::DialogResult_NoModal;
418     if( exec_qt )
419       dret = this->m_ImageWriter->ExecConfigurationDialog( this->m_Widget );
420     if( dret != TProcessObject::DialogResult_Cancel )
421     {
422       this->m_ImageWriter->SetInput( "Input", image );
423       this->BlockWidget( );
424       ret = this->m_ImageWriter->Update( );
425       this->UnblockWidget( );
426
427     } // fi
428
429   } // fi
430
431   // Show an error message and return
432   if( ret != "" )
433   {
434 #ifdef cpPlugins_Interface_QT4
435     if( this->m_Widget != NULL )
436       QMessageBox::critical(
437         this->m_Widget,
438         QMessageBox::tr( "Error reading image." ),
439         QMessageBox::tr( ret.c_str( ) )
440         );
441 #endif // cpPlugins_Interface_QT4
442     return( false );
443   }
444   else
445     return( true );
446 }
447
448 // -------------------------------------------------------------------------
449 bool cpPlugins::Interface::Plugins::
450 WriteMesh( TMesh* mesh, bool exec_qt )
451 {
452   std::string ret = "";
453   if( this->m_MeshWriter.IsNull( ) )
454     ret = "Plugins: No valid mesh writer. Please load a valid plugin.";
455
456   if( ret == "" )
457   {
458     TProcessObject::DialogResult dret = TProcessObject::DialogResult_NoModal;
459     if( exec_qt )
460       dret = this->m_MeshWriter->ExecConfigurationDialog( this->m_Widget );
461     if( dret != TProcessObject::DialogResult_Cancel )
462     {
463       this->m_MeshWriter->SetInput( "Input", mesh );
464       this->BlockWidget( );
465       ret = this->m_MeshWriter->Update( );
466       this->UnblockWidget( );
467
468     } // fi
469
470   } // fi
471
472   // Show an error message and return
473   if( ret != "" )
474   {
475 #ifdef cpPlugins_Interface_QT4
476     if( this->m_Widget != NULL )
477       QMessageBox::critical(
478         this->m_Widget,
479         QMessageBox::tr( "Error reading image." ),
480         QMessageBox::tr( ret.c_str( ) )
481         );
482 #endif // cpPlugins_Interface_QT4
483     return( false );
484   }
485   else
486     return( true );
487 }
488
489 // -------------------------------------------------------------------------
490 bool cpPlugins::Interface::Plugins::
491 CreateFilter( TProcessObject::Pointer& filter, const std::string& name )
492 {
493   filter = this->m_Interface.CreateProcessObject( name );
494   return( filter.IsNotNull( ) );
495 }
496
497 // -------------------------------------------------------------------------
498 void cpPlugins::Interface::Plugins::
499 _Update( )
500 {
501   typedef TInterface::TClasses _C;
502
503   this->m_Filters.clear( );
504   _C& classes = this->m_Interface.GetClasses( );
505   for( _C::const_iterator i = classes.begin( ); i != classes.end( ); ++i )
506   {
507     TProcessObject::Pointer o =
508       this->m_Interface.CreateProcessObject( i->first );
509     std::string name = o->GetClassName( );
510     std::string category = o->GetClassCategory( );
511     if( category == "ImageReader" )
512       this->m_ImageReader = o;
513     else if( category == "ImageWriter" )
514       this->m_ImageWriter = o;
515     else if( category == "MeshReader" )
516       this->m_MeshReader = o;
517     else if( category == "MeshWriter" )
518       this->m_MeshWriter = o;
519     else if( category == "DicomSeriesReader" )
520       this->m_DicomSeriesReader = o;
521     else
522       this->m_Filters[ category ].insert( name );
523
524   } // rof
525 }
526
527 // eof - $RCSfile$