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