]> Creatis software - cpPlugins.git/blob - appli/cpPipelineEditor/App_cpPipelineEditor.cxx
...
[cpPlugins.git] / appli / cpPipelineEditor / App_cpPipelineEditor.cxx
1 #include "App_cpPipelineEditor.h"
2 #include "ui_App_cpPipelineEditor.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/Interface/Workspace.h>
13 #include <cpPlugins/Interface/DataObject.h>
14
15 // -------------------------------------------------------------------------
16 #define App_cpPipelineEditor_ConnectAction( ACTION )    \
17   this->connect(                                        \
18     this->m_UI->Action##ACTION, SIGNAL( triggered( ) ), \
19     this, SLOT( _Action##ACTION( ) )                    \
20     )
21
22 // -------------------------------------------------------------------------
23 #define App_cpPipelineEditor_ConnectButton( BUTTON )    \
24   this->connect(                                        \
25     this->m_UI->Button##BUTTON, SIGNAL( clicked( ) ),   \
26     this, SLOT( _Button##BUTTON( ) )                    \
27     )
28
29 // -------------------------------------------------------------------------
30 App_cpPipelineEditor::
31 App_cpPipelineEditor( int argc, char* argv[], QWidget* parent )
32   : QMainWindow( parent ),
33     m_UI( new Ui::App_cpPipelineEditor ),
34     m_Workspace( NULL )
35 {
36   this->m_UI->setupUi( this );
37
38   // Prepare plugins interface
39   this->m_Plugins = new cpPlugins::Interface::Interface( );
40   QFileInfo info( argv[ 0 ] );
41   if( info.exists( ) )
42   {
43     std::string path = info.canonicalPath( ).toStdString( );
44     if( !( this->m_Plugins->LoadDefaultConfiguration( path ) ) )
45       if( this->m_Plugins->LoadFromFolder( path, false ) )
46         if( !( this->m_Plugins->SaveDefaultConfiguration( path ) ) )
47           QMessageBox::critical(
48             this,
49             "Error creating default plugins configuration",
50             "Could not save default plugins configuration"
51             );
52     this->_UpdateLoadedPlugins( );
53
54   } // fi
55
56   // Create an empty workspace
57   this->m_Workspace = new cpPlugins::Interface::Workspace( );
58   this->m_Workspace->SetPlugins( this->m_Plugins );
59   this->m_UI->Canvas->editor( )->setWorkspace( this->m_Workspace );
60   this->m_Workspace->AddInteractor( this->m_UI->Viewer->GetInteractor( 0 ) );
61   this->m_Workspace->AddInteractor( this->m_UI->Viewer->GetInteractor( 1 ) );
62   this->m_Workspace->AddInteractor( this->m_UI->Viewer->GetInteractor( 2 ) );
63   this->m_Workspace->AddInteractor( this->m_UI->Viewer->GetInteractor( 3 ) );
64
65   // Connect actions to slots
66   App_cpPipelineEditor_ConnectButton( LoadPluginsFile );
67   App_cpPipelineEditor_ConnectButton( LoadPluginsPath );
68   App_cpPipelineEditor_ConnectAction( OpenWorkspace );
69   App_cpPipelineEditor_ConnectAction( SaveWorkspace );
70   this->connect(
71     this->m_UI->Canvas->editor( ),
72     SIGNAL( execFilter( const std::string& ) ),
73     this,
74     SLOT( _ExecFilter( const std::string& ) )
75     );
76   this->connect(
77     this->m_UI->Canvas->editor( ),
78     SIGNAL( showFilterOutput( const std::string&, const std::string& ) ),
79     this,
80     SLOT( _ShowFilterOutput( const std::string&, const std::string& ) )
81     );
82 }
83
84 // -------------------------------------------------------------------------
85 App_cpPipelineEditor::
86 ~App_cpPipelineEditor( )
87 {
88   delete this->m_UI;
89   if( this->m_Workspace != NULL )
90     delete this->m_Workspace;
91   delete this->m_Plugins;
92 }
93
94 // -------------------------------------------------------------------------
95 void App_cpPipelineEditor::
96 _UpdateLoadedPlugins( )
97 {
98   auto& classes = this->m_Plugins->GetClasses( );
99
100   if( classes.size( ) == 0 )
101   {
102     QMessageBox::critical(
103       this,
104       "Error loading default plugins",
105       "No plugins loaded: remember to load some!!!"
106       );
107     return;
108
109   } // fi
110
111   auto catIt = classes.begin( );
112   for( ; catIt != classes.end( ); ++catIt )
113   {
114     // Create or get category
115     QList< QTreeWidgetItem* > cat_items =
116       this->m_UI->LoadedPlugins->findItems(
117         catIt->first.c_str( ), Qt::MatchExactly | Qt::MatchRecursive
118         );
119     QTreeWidgetItem* cat = NULL;
120     if( cat_items.size( ) == 0 )
121     {
122       cat = new QTreeWidgetItem(
123         ( QTreeWidgetItem* )( NULL ), QStringList( catIt->first.c_str( ) )
124         );
125       this->m_UI->LoadedPlugins->addTopLevelItem( cat );
126     }
127     else
128       cat = cat_items[ 0 ];
129
130     // Create filters
131     auto fIt = catIt->second.begin( );
132     for( ; fIt != catIt->second.end( ); ++fIt )
133     {
134       QList< QTreeWidgetItem* > filter_items =
135         this->m_UI->LoadedPlugins->findItems(
136           fIt->first.c_str( ), Qt::MatchExactly | Qt::MatchRecursive
137           );
138       auto fiIt = filter_items.begin( );
139       auto found_fiIt = filter_items.end( );
140       for( ; fiIt != filter_items.end( ); ++fiIt )
141         if( ( *fiIt )->parent( ) == cat )
142           found_fiIt = fiIt;
143
144       // Add filter
145       if( found_fiIt == filter_items.end( ) )
146         QTreeWidgetItem* filter = new QTreeWidgetItem(
147           cat, QStringList( fIt->first.c_str( ) )
148           );
149     } // rof
150
151   } // rof
152 }
153
154 // -------------------------------------------------------------------------
155 void App_cpPipelineEditor::
156 _ButtonLoadPluginsFile( )
157 {
158   QFileDialog dlg( this );
159   dlg.setFileMode( QFileDialog::ExistingFiles );
160   dlg.setDirectory( "." );
161 #ifdef _WIN32
162   dlg.setNameFilter( "Plugins file (*.dll);;All files (*)" );
163   dlg.setDefaultSuffix( "dll" );
164 #else // _WIN32
165   dlg.setNameFilter( "Plugins file (*.so);;All files (*)" );
166   dlg.setDefaultSuffix( "so" );
167 #endif // _WIN32
168   if( !( dlg.exec( ) ) )
169     return;
170
171   // Read
172   QStringList names = dlg.selectedFiles( );
173   std::stringstream err_str;
174   for( auto qIt = names.begin( ); qIt != names.end( ); ++qIt )
175     if( !( this->m_Plugins->Load( qIt->toStdString( ) ) ) )
176       err_str << qIt->toStdString( ) << std::endl;
177
178   // Show an error message
179   std::string err = err_str.str( );
180   if( err.size( ) > 0 )
181     QMessageBox::critical(
182       this,
183       "Error loading plugins",
184       err.c_str( )
185       );
186
187   // Update view
188   this->_UpdateLoadedPlugins( );
189 }
190
191 // -------------------------------------------------------------------------
192 void App_cpPipelineEditor::
193 _ButtonLoadPluginsPath( )
194 {
195   QFileDialog dlg( this );
196   dlg.setFileMode( QFileDialog::DirectoryOnly );
197   dlg.setDirectory( "." );
198   if( !( dlg.exec( ) ) )
199     return;
200
201   // Read
202   std::string dir = dlg.selectedFiles( ).begin( )->toStdString( );
203   if( !( this->m_Plugins->LoadFromFolder( dir, false ) ) )
204     QMessageBox::critical(
205       this,
206       "Error loading plugins directory",
207       dir.c_str( )
208       );
209
210   // Update view
211   this->_UpdateLoadedPlugins( );
212 }
213
214 // -------------------------------------------------------------------------
215 void App_cpPipelineEditor::
216 _ActionOpenWorkspace( )
217 {
218   QFileDialog dlg( this );
219   dlg.setFileMode( QFileDialog::ExistingFile );
220   dlg.setDirectory( "." );
221   dlg.setNameFilter(
222     QFileDialog::tr( "Workspace file (*.xml);;All files (*)" )
223     );
224   dlg.setDefaultSuffix( QFileDialog::tr( "xml" ) );
225   if( !( dlg.exec( ) ) )
226     return;
227   std::string fname = dlg.selectedFiles( ).at( 0 ).toStdString( );
228
229   if( this->m_Workspace != NULL )
230     delete this->m_Workspace;
231   this->m_Workspace = new cpPlugins::Interface::Workspace( );
232   this->m_Workspace->SetPlugins( this->m_Plugins );
233   std::string err = this->m_Workspace->LoadWorkspace( fname );
234   if( err != "" )
235   {
236     delete this->m_Workspace;
237     this->m_Workspace = NULL;
238     QMessageBox::critical(
239       this,
240       QMessageBox::tr( "Error loading workspace" ),
241       QMessageBox::tr( err.c_str( ) )
242       );
243   }
244   else
245     this->m_UI->Canvas->editor( )->setWorkspace( this->m_Workspace );
246 }
247
248 // -------------------------------------------------------------------------
249 void App_cpPipelineEditor::
250 _ActionSaveWorkspace( )
251 {
252   if( this->m_Workspace == NULL )
253     return;
254
255   QFileDialog dlg( this );
256   dlg.setFileMode( QFileDialog::AnyFile );
257   dlg.setDirectory( "." );
258   dlg.setAcceptMode( QFileDialog::AcceptSave );
259   dlg.setNameFilter(
260     QFileDialog::tr( "Workspace file (*.xml);;All files (*)" )
261     );
262   dlg.setDefaultSuffix( QFileDialog::tr( "xml" ) );
263   if( !( dlg.exec( ) ) )
264     return;
265   std::string fname = dlg.selectedFiles( ).at( 0 ).toStdString( );
266
267   std::string err = this->m_Workspace->SaveWorkspace( fname );
268   if( err != "" )
269     QMessageBox::critical(
270       this,
271       QMessageBox::tr( "Error saving workspace" ),
272       QMessageBox::tr( err.c_str( ) )
273       );
274 }
275
276
277 // -------------------------------------------------------------------------
278 void App_cpPipelineEditor::
279 _ExecFilter( const std::string& filter_name )
280 {
281   if( this->m_Workspace != NULL )
282   {
283     // Update filter, if needed
284     std::string err = this->m_Workspace->Execute( filter_name );
285     if( err != "" )
286       QMessageBox::critical(
287         this,
288         QMessageBox::tr( "Error executing filter" ),
289         QMessageBox::tr( err.c_str( ) )
290         );
291
292   } // fi
293 }
294
295 // -------------------------------------------------------------------------
296 void App_cpPipelineEditor::
297 _ShowFilterOutput(
298   const std::string& filter_name, const std::string& output_name
299   )
300 {
301   typedef cpPlugins::Interface::DataObject _TDataObject;
302
303   // Update filter, if needed
304   this->_ExecFilter( filter_name );
305
306   // Get output
307   auto filter = this->m_Workspace->GetFilter( filter_name );
308   if( filter != NULL )
309   {
310     auto output = filter->GetOutput< _TDataObject >( output_name );
311     if( output != NULL )
312     {
313       std::string data_name = output_name + "@" + filter_name;
314       if( this->m_UI->Viewer->AddData( output, data_name, "" ) )
315       {
316         if( this->m_UI->Viewer->GetNumberOfData( ) > 1 )
317           this->m_UI->Viewer->SetDataColor( data_name, 1, 0, 0 );
318         else
319           this->m_UI->Viewer->SetMainImage( data_name );
320         this->m_UI->Viewer->ShowData( data_name );
321       }
322       else
323         QMessageBox::critical(
324           this,
325           QMessageBox::tr( "Error showing data" ),
326           QMessageBox::tr( "No known VTK conversion!" )
327           );
328
329     } // fi
330
331   } // fi
332 }
333
334 // eof - $RCSfile$