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