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