]> Creatis software - cpPlugins.git/blob - lib/cpBaseQtApplication/MainWindow.cxx
830508fb18d58a60ef0f14106d746735ff2314e0
[cpPlugins.git] / lib / cpBaseQtApplication / MainWindow.cxx
1 #include <cpBaseQtApplication/MainWindow.h>
2
3 #include <cpExtensions/QT/SimpleMPRWidget.h>
4 #include <cpBaseQtApplication/ActorPropertiesQDialog.h>
5 #include <cpBaseQtApplication/Editor.h>
6 #include <cpBaseQtApplication/PathsDialog.h>
7 #include <vtkRenderer.h>
8 #include <QApplication>
9 #include <QColorDialog>
10 #include <QDir>
11 #include <QFileDialog>
12 #include <QFileInfo>
13 #include <QMessageBox>
14 #include <QTreeWidget>
15
16 // -------------------------------------------------------------------------
17 bool cpBaseQtApplication::MainWindow::_TBlocker::
18 eventFilter( QObject* obj, QEvent* event )
19 {
20   return( true ); // -> Block all events
21   /* NOTE: this should be the correct implementation:
22      switch( event->type( ) )
23      {
24      //list event you want to prevent here ...
25      case QEvent::KeyPress:
26      case QEvent::KeyRelease:
27      case QEvent::MouseButtonRelease:
28      case QEvent::MouseButtonPress:
29      case QEvent::MouseButtonDblClick:
30      //...
31      return( true );
32      } // hctiws
33      return( this->QObject::eventFilter( obj, event ) );
34   */
35 }
36
37 // -------------------------------------------------------------------------
38 cpBaseQtApplication::MainWindow::
39 MainWindow(
40   int argc, char* argv[],
41   QApplication* app,
42   QWidget* parent
43   )
44   : Superclass( parent ),
45     m_Application( app ),
46     m_PluginsPath( "." ),
47     m_TreeWidget( NULL ),
48     m_Editor( NULL ),
49     m_MPR( NULL )
50 {
51   QFileInfo e_path( argv[ 0 ] );
52   QDir r_path( "." );
53   this->m_RunPath = r_path.canonicalPath( ).toStdString( );
54   std::stringstream paths;
55   paths
56     << e_path.canonicalPath( ).toStdString( )
57     << cpPlugins_SEPARATOR
58     << this->m_RunPath;
59
60   try { this->m_Interface.AddEnvironments( this->m_RunPath ); }
61   catch( ... ) { }
62   try { this->m_Interface.OpenEnvironments( this->m_RunPath ); }
63   catch( ... ) { }
64   try { this->m_Interface.SaveEnvironments( this->m_RunPath ); }
65   catch( ... ) { }
66   this->UpdateEnvironment( );
67   this->m_Workspace.SetInterface( &( this->m_Interface ) );
68 }
69
70 // -------------------------------------------------------------------------
71 cpBaseQtApplication::MainWindow::
72 ~MainWindow( )
73 {
74 }
75
76 // -------------------------------------------------------------------------
77 void cpBaseQtApplication::MainWindow::
78 UpdateEnvironment( )
79 {
80   try
81   {
82     this->m_Interface.LoadEnvironments( );
83     this->m_Interface.GuessPlugins( );
84   }
85   catch( std::exception& err )
86   {
87     QMessageBox::critical(
88       this, "Error loading required libraries", err.what( )
89       );
90     return;
91
92   } // yrt
93 }
94
95 // -------------------------------------------------------------------------
96 void cpBaseQtApplication::MainWindow::
97 _Configure(
98   QTreeWidget* tree,
99   cpExtensions::QT::SimpleMPRWidget* mpr,
100   cpBaseQtApplication::Editor* editor
101   )
102 {
103   this->m_TreeWidget = tree;
104   this->_UpdateLoadedPlugins( );
105   this->m_Editor = editor;
106   this->m_MPR = mpr;
107   if( this->m_Editor != NULL )
108   {
109     this->m_Editor->setWorkspace( &( this->m_Workspace ) );
110
111     // Slots <-> signals
112     this->connect(
113       this->m_Editor,
114       SIGNAL( execFilter( const std::string& ) ),
115       this,
116       SLOT( _ExecFilter( const std::string& ) )
117       );
118     this->connect(
119       this->m_Editor,
120       SIGNAL( showFilterOutput( const std::string&, const std::string& ) ),
121       this,
122       SLOT( _ShowData( const std::string&, const std::string& ) )
123       );
124     this->connect(
125       this->m_Editor,
126       SIGNAL( hideFilterOutput( const std::string&, const std::string& ) ),
127       this,
128       SLOT( _HideData( const std::string&, const std::string& ) )
129       );
130     this->connect(
131       this->m_Editor,
132       SIGNAL( visualPropertiesFilterOutput( const std::string&, const std::string& ) ),
133       this,
134       SLOT( _DataProperties( const std::string&, const std::string& ) )
135       );
136
137   } // fi
138   if( this->m_MPR != NULL )
139     this->m_Workspace.SetMPRViewer( this->m_MPR );
140   this->_ClearWorkspace( );
141 }
142
143 // -------------------------------------------------------------------------
144 void cpBaseQtApplication::MainWindow::
145 _ClearWorkspace( )
146 {
147   if( this->m_Editor != NULL )
148     this->m_Editor->clear( );
149   if( this->m_MPR != NULL )
150     this->m_MPR->Clear( );
151   this->m_Workspace.Clear( );
152 }
153
154 // -------------------------------------------------------------------------
155 void cpBaseQtApplication::MainWindow::
156 _AddEnvironments( const std::string& environments )
157 {
158   try { this->m_Interface.AddEnvironments( environments ); }
159   catch( ... ) { }
160   try { this->m_Interface.SaveEnvironments( this->m_RunPath ); }
161   catch( ... ) { }
162   this->UpdateEnvironment( );
163 }
164
165 // -------------------------------------------------------------------------
166 void cpBaseQtApplication::MainWindow::
167 _LoadPlugins( const std::string& filename )
168 {
169   try
170   {
171     this->m_Interface.LoadFile( filename );
172     this->_UpdateLoadedPlugins( );
173   }
174   catch( std::exception& err )
175   {
176     QMessageBox::critical(
177       this,
178       "Error loading plugins path",
179       err.what( )
180       );
181
182   } // yrt
183 }
184
185 // -------------------------------------------------------------------------
186 void cpBaseQtApplication::MainWindow::
187 _LoadPluginsFromPath( const std::string& path )
188 {
189   try
190   {
191     this->m_Interface.LoadDirectory( path );
192     this->_UpdateLoadedPlugins( );
193   }
194   catch( std::exception& err )
195   {
196     QMessageBox::critical(
197       this,
198       "Error loading plugins path",
199       err.what( )
200       );
201
202   } // yrt
203 }
204
205 // -------------------------------------------------------------------------
206 void cpBaseQtApplication::MainWindow::
207 _UpdateLoadedPlugins( )
208 {
209   if( this->m_TreeWidget == NULL )
210     return;
211   this->_Block( );
212   auto categories = this->m_Interface.GetCategories( );
213   unsigned int filter_count = 0;
214   for( auto cIt = categories.begin( ); cIt != categories.end( ); ++cIt )
215   {
216     // Create or get category
217     QList< QTreeWidgetItem* > cat_items =
218       this->m_TreeWidget->findItems(
219         cIt->c_str( ), Qt::MatchExactly | Qt::MatchRecursive
220         );
221     QTreeWidgetItem* cat = NULL;
222     if( cat_items.size( ) == 0 )
223     {
224       cat = new QTreeWidgetItem(
225         ( QTreeWidgetItem* )( NULL ), QStringList( cIt->c_str( ) )
226         );
227       this->m_TreeWidget->addTopLevelItem( cat );
228     }
229     else
230       cat = cat_items[ 0 ];
231
232     // Create filters
233     auto filters = this->m_Interface.GetFilters( *cIt );
234     filter_count += filters.size( );
235     for( auto fIt = filters.begin( ); fIt != filters.end( ); ++fIt )
236     {
237       QList< QTreeWidgetItem* > filter_items =
238         this->m_TreeWidget->findItems(
239           fIt->c_str( ), Qt::MatchExactly | Qt::MatchRecursive
240           );
241       auto fiIt = filter_items.begin( );
242       auto found_fiIt = filter_items.end( );
243       for( ; fiIt != filter_items.end( ); ++fiIt )
244         if( ( *fiIt )->parent( ) == cat )
245           found_fiIt = fiIt;
246
247       // Add filter
248       if( found_fiIt == filter_items.end( ) )
249         QTreeWidgetItem* filter = new QTreeWidgetItem(
250           cat, QStringList( fIt->c_str( ) )
251           );
252
253     } // rof
254
255   } // rof
256   this->m_TreeWidget->expandAll( );
257   this->_UnBlock( );
258
259   if( filter_count == 0 )
260     QMessageBox::critical(
261       this,
262       "Error loading default plugins",
263       "No plugins loaded: remember to load some!!!"
264       );
265 }
266
267 // -------------------------------------------------------------------------
268 void cpBaseQtApplication::MainWindow::
269 _Block( )
270 {
271   this->m_Application->setOverrideCursor( Qt::WaitCursor );
272   this->m_Application->installEventFilter( &( this->m_Blocker ) );
273 }
274
275 // -------------------------------------------------------------------------
276 void cpBaseQtApplication::MainWindow::
277 _UnBlock( )
278 {
279   while( this->m_Application->overrideCursor( ) )
280     this->m_Application->restoreOverrideCursor( );
281   this->m_Application->removeEventFilter( &( this->m_Blocker ) );
282 }
283
284 // -------------------------------------------------------------------------
285 void cpBaseQtApplication::MainWindow::
286 _LoadWorkspace( const std::string& filename )
287 {
288   this->_ClearWorkspace( );
289   std::string err = this->m_Workspace.LoadWorkspace( filename );
290   if( err != "" )
291   {
292     QMessageBox::critical(
293       this,
294       QMessageBox::tr( "Error loading workspace" ),
295       QMessageBox::tr( err.c_str( ) )
296       );
297   }
298   else
299   {
300     /* TODO
301        if( this->m_Editor != NULL )
302        this->m_Editor->setWorkspace( this->m_Workspace );
303     */
304
305   } // fi
306 }
307
308 // -------------------------------------------------------------------------
309 void cpBaseQtApplication::MainWindow::
310 _SaveWorkspace( const std::string& filename )
311 {
312   std::string err = this->m_Workspace.SaveWorkspace( filename );
313   if( err != "" )
314     QMessageBox::critical(
315       this,
316       QMessageBox::tr( "Error saving workspace" ),
317       QMessageBox::tr( err.c_str( ) )
318       );
319 }
320
321 // -------------------------------------------------------------------------
322 void cpBaseQtApplication::MainWindow::
323 _BackgroundProperties( unsigned int i )
324 {
325   if( this->m_MPR == NULL )
326     return;
327
328   QColor color =
329     QColorDialog::getColor(
330       QColor( 0, 0, 0 ),
331       this,
332       "Select Color",
333       QColorDialog::DontUseNativeDialog
334       );
335   if( color.isValid( ) )
336   {
337     double r = double( color.red( ) ) / double( 255 );
338     double g = double( color.green( ) ) / double( 255 );
339     double b = double( color.blue( ) ) / double( 255 );
340     if( i >= 4 )
341     {
342       unsigned int maxId = ( i == 4 )? 3: 4;
343       for( unsigned int j = 0; j < maxId; ++j )
344       {
345         auto ren = this->m_MPR->GetRenderer( j );
346         if( ren != NULL )
347         {
348           ren->SetBackground( r, g, b );
349           ren->Render( );
350
351         } // fi
352
353       } // rof
354     }
355     else
356     {
357       auto ren = this->m_MPR->GetRenderer( i );
358       if( ren != NULL )
359       {
360         ren->SetBackground( r, g, b );
361         ren->Render( );
362
363       } // fi
364
365     } // fi
366
367   } // fi
368 }
369
370 // -------------------------------------------------------------------------
371 void cpBaseQtApplication::MainWindow::
372 _ShowData( const std::string& filter_name, const std::string& output_name )
373 {
374   if( this->m_MPR == NULL )
375     return;
376
377   auto output = this->m_Workspace.GetOutput( filter_name, output_name );
378   if( output != NULL )
379   {
380     this->_Block( );
381     auto actor = output->GetVTKActor( );
382     if( actor != NULL )
383     {
384       this->m_MPR->AddActor(
385         actor, output_name + std::string( "@" ) + filter_name
386         );
387       this->_UnBlock( );
388     }
389     else
390     {
391       this->_UnBlock( );
392       QMessageBox::critical(
393         this,
394         QMessageBox::tr( "Error showing data" ),
395         QMessageBox::tr( "Unknown VTK conversion." )
396         );
397
398     } // fi
399   }
400   else
401     QMessageBox::critical(
402       this,
403       QMessageBox::tr( "Error showing data" ),
404       QMessageBox::tr( "Unknown port name." )
405       );
406 }
407
408 // -------------------------------------------------------------------------
409 void cpBaseQtApplication::MainWindow::
410 _HideData( const std::string& filter, const std::string& output )
411 {
412   std::cout << "MainWindow::HideData" << std::endl;
413   /* TODO
414    */
415 }
416
417 // -------------------------------------------------------------------------
418 void cpBaseQtApplication::MainWindow::
419 _DataProperties(
420   const std::string& filter_name, const std::string& output_name
421   )
422 {
423   if( this->m_MPR == NULL )
424     return;
425
426   auto output = this->m_Workspace.GetOutput( filter_name, output_name );
427   if( output != NULL )
428   {
429     this->_Block( );
430     auto actors = this->m_MPR->GetActors(
431       output_name + std::string( "@" ) + filter_name
432       );
433     auto dlg = new ActorPropertiesQDialog( NULL );
434     for( auto i = actors.begin( ); i != actors.end( ); ++i )
435       dlg->addActor( *i );
436     dlg->addRenderWindow( this->m_MPR->GetRenderWindow( 0 ) );
437     dlg->addRenderWindow( this->m_MPR->GetRenderWindow( 1 ) );
438     dlg->addRenderWindow( this->m_MPR->GetRenderWindow( 2 ) );
439     dlg->addRenderWindow( this->m_MPR->GetRenderWindow( 3 ) );
440     this->_UnBlock( );
441     dlg->exec( );
442   }
443   else
444     QMessageBox::critical(
445       this,
446       QMessageBox::tr( "Error showing data" ),
447       QMessageBox::tr( "Unknown port name." )
448       );
449 }
450
451 // -------------------------------------------------------------------------
452 void cpBaseQtApplication::MainWindow::
453 _InteractiveLoadPlugins( )
454 {
455   QFileDialog dlg( this );
456   dlg.setFileMode( QFileDialog::ExistingFiles );
457   dlg.setDirectory( this->m_PluginsPath.c_str( ) );
458
459   std::stringstream filter;
460   std::string suffix = std::string( cpPlugins_LIB_EXT );
461   filter << "Plugins file (*." << cpPlugins_LIB_EXT << ");;All files (*)";
462   dlg.setNameFilter( filter.str( ).c_str( ) );
463   dlg.setDefaultSuffix( suffix.c_str( ) );
464   if( !( dlg.exec( ) ) )
465     return;
466   QStringList names = dlg.selectedFiles( );
467   for( auto qIt = names.begin( ); qIt != names.end( ); ++qIt )
468     this->_LoadPlugins( qIt->toStdString( ) );
469 }
470
471 // -------------------------------------------------------------------------
472 void cpBaseQtApplication::MainWindow::
473 _InteractiveLoadPluginsFromPath( )
474 {
475   QFileDialog d( this );
476   d.setFileMode( QFileDialog::DirectoryOnly );
477   d.setDirectory( this->m_PluginsPath.c_str( ) );
478   if( !( d.exec( ) ) )
479     return;
480   this->_LoadPluginsFromPath( d.selectedFiles( ).begin( )->toStdString( ) );
481 }
482
483 // -------------------------------------------------------------------------
484 void cpBaseQtApplication::MainWindow::
485 _ShowPlugins( )
486 {
487   auto paths = this->m_Interface.GetPaths( );
488   auto plugins = this->m_Interface.GetPlugins( );
489   std::stringstream info;
490   info << "-----   PATHS   -----" << std::endl;
491   for( auto i = paths.begin( ); i != paths.end( ); ++i )
492     info << "   " << *i << std::endl;
493   info << std::endl << "-----  PLUGINS  -----" << std::endl;
494   for( auto i = plugins.begin( ); i != plugins.end( ); ++i )
495     info << "   " << *i << std::endl;
496   QMessageBox::information(
497     this,
498     "Loaded libraries and plugins information",
499     info.str( ).c_str( )
500     );
501 }
502
503 // -------------------------------------------------------------------------
504 void cpBaseQtApplication::MainWindow::
505 _InteractiveLoadWorkspace( )
506 {
507   QFileDialog dlg( this );
508   dlg.setFileMode( QFileDialog::ExistingFile );
509   dlg.setDirectory( "." );
510   dlg.setNameFilter(
511     QFileDialog::tr( "Workspace file (*.wxml);;All files (*)" )
512     );
513   dlg.setDefaultSuffix( QFileDialog::tr( "wxml" ) );
514   if( !( dlg.exec( ) ) )
515     return;
516   this->_LoadWorkspace( dlg.selectedFiles( ).begin( )->toStdString( ) );
517 }
518
519 // -------------------------------------------------------------------------
520 void cpBaseQtApplication::MainWindow::
521 _InteractiveSaveWorkspace( )
522 {
523   QFileDialog dlg( this );
524   dlg.setFileMode( QFileDialog::AnyFile );
525   dlg.setDirectory( "." );
526   dlg.setAcceptMode( QFileDialog::AcceptSave );
527   dlg.setNameFilter(
528     QFileDialog::tr( "Workspace file (*.wxml);;All files (*)" )
529     );
530   dlg.setDefaultSuffix( QFileDialog::tr( "wxml" ) );
531   if( !( dlg.exec( ) ) )
532     return;
533   this->_SaveWorkspace( dlg.selectedFiles( ).begin( )->toStdString( ) );
534 }
535
536 // -------------------------------------------------------------------------
537 void cpBaseQtApplication::MainWindow::
538 _InteractiveAddEnviromentPaths( )
539 {
540   PathsDialog dlg( this );
541   dlg.addPaths( this->m_Interface.GetPaths( ) );
542   if( dlg.exec( ) )
543   {
544     auto paths = dlg.getPaths( );
545     std::stringstream envs;
546     for( auto p = paths.begin( ); p != paths.end( ); ++p )
547       envs << *p << cpPlugins_SEPARATOR;
548     this->_AddEnvironments( envs.str( ) );
549     this->UpdateEnvironment( );
550
551   } // fi
552 }
553
554 // -------------------------------------------------------------------------
555 void cpBaseQtApplication::MainWindow::
556 _ExecFilter( const std::string& filter_name )
557 {
558   this->_Block( );
559   try
560   {
561     this->m_Workspace.Execute( filter_name );
562     this->_UnBlock( );
563   }
564   catch( itk::ExceptionObject& err1 )
565   {
566     this->_UnBlock( );
567     QMessageBox::critical(
568       this,
569       QMessageBox::tr( "Error executing filter" ),
570       QMessageBox::tr( err1.GetDescription( ) )
571       );
572   }
573   catch( std::exception& err2 )
574   {
575     this->_UnBlock( );
576     QMessageBox::critical(
577       this,
578       QMessageBox::tr( "Error executing filter" ),
579       QMessageBox::tr( err2.what( ) )
580       );
581   }
582   catch( ... )
583   {
584     this->_UnBlock( );
585     QMessageBox::critical(
586       this,
587       QMessageBox::tr( "Error executing filter" ),
588       QMessageBox::tr( "Unknown error" )
589       );
590
591   } // yrt
592 }
593
594 // eof - $RCSfile$