]> Creatis software - clitk.git/blob - vv/vvMainWindow.cxx
improved the FusionSequence visualization mode, by linking to the 2nd sequence (US).
[clitk.git] / vv / vvMainWindow.cxx
1 /*=========================================================================
2   Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
3
4   Authors belong to:
5   - University of LYON              http://www.universite-lyon.fr/
6   - Léon Bérard cancer center       http://www.centreleonberard.fr
7   - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
8
9   This software is distributed WITHOUT ANY WARRANTY; without even
10   the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11   PURPOSE.  See the copyright notices for more information.
12
13   It is distributed under dual licence
14
15   - BSD        See included LICENSE.txt file
16   - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
17 ===========================================================================**/
18
19 #include <algorithm>
20 #include <QMessageBox>
21 #include <QInputDialog>
22 #include <QTimer>
23 #include "QTreePushButton.h"
24 #include <QUrl>
25 #include <QSettings>
26
27 // VV include
28 #include "vvMainWindow.h"
29 #include "vvHelpDialog.h"
30 #include "vvRegisterForm.h"
31 #include "vvDocumentation.h"
32 #include "vvProgressDialog.h"
33 #include "vvQDicomSeriesSelector.h"
34 #include "vvSlicerManager.h"
35 #include "clitkImageCommon.h"
36 #include "vvSlicer.h"
37 #include "vvInteractorStyleNavigator.h"
38 #include "vvImageWriter.h"
39 #include "vvSegmentationDialog.h"
40 #include "vvSurfaceViewerDialog.h"
41 #include "vvDeformationDialog.h"
42 #include "vvImageWarp.h"
43 #include "vvUtils.h"
44 #include "vvMidPosition.h"
45 #include "vvMesh.h"
46 #include "vvStructSelector.h"
47 #include "vvMeshReader.h"
48 #include "vvSaveState.h"
49 #include "vvReadState.h"
50 #include "clitkConfiguration.h"
51
52 // ITK include
53 #include <itkImage.h>
54 #include <itkImageFileReader.h>
55 #include <itkByteSwapper.h>
56 #include <itkCommand.h>
57 #include <itkNumericSeriesFileNames.h>
58
59 // VTK include
60 #include <vtkImageData.h>
61 #include <vtkImageActor.h>
62 #include <vtkCornerAnnotation.h>
63 #include <vtkRenderWindow.h>
64 #include <vtkRenderWindowInteractor.h>
65 #include <vtkRenderer.h>
66 #include <vtkRendererCollection.h>
67 #include <vtkWindowToImageFilter.h>
68 #include <vtkBMPWriter.h>
69 #include <vtkTIFFWriter.h>
70 #include <vtkPNMWriter.h>
71 #include <vtkPNGWriter.h>
72 #include <vtkJPEGWriter.h>
73 #include <vtkGenericMovieWriter.h>
74 #ifdef CLITK_EXPERIMENTAL
75 #  include <vvAnimatedGIFWriter.h>
76 #endif
77 #ifdef VTK_USE_VIDEO_FOR_WINDOWS
78 #  include <vtkAVIWriter.h>
79 #endif
80 #ifdef VTK_USE_FFMPEG_ENCODER
81 #  include <vtkFFMPEGWriter.h>
82 #endif
83 #ifdef VTK_USE_MPEG2_ENCODER
84 #  include <vtkMPEG2Writer.h>
85 #endif
86 #include <vtkMatrix4x4.h>
87 #include <vtkTransform.h>
88
89 // Standard includes
90 #include <iostream>
91 #include <sstream>
92 #include <iomanip>
93
94 #define COLUMN_TREE 0
95 #define COLUMN_UL_VIEW 1
96 #define COLUMN_UR_VIEW 2
97 #define COLUMN_DL_VIEW 3
98 #define COLUMN_DR_VIEW 4
99 #define COLUMN_CLOSE_IMAGE 5
100 #define COLUMN_RELOAD_IMAGE 6
101 #define COLUMN_IMAGE_NAME 7
102
103 #ifdef CLITK_PRIVATE_FEATURES
104 #define EXTENSIONS "Images ( *.bmp *.png *.jpeg *.jpg *.tif *.mhd *.mha *.hdr *.vox *.his *.xdr *.SCAN *.nii *.nrrd *.nhdr *.refscan *.nii.gz *.usf)"
105 #else
106 #define EXTENSIONS "Images ( *.bmp *.png *.jpeg *.jpg *.tif *.mhd *.mha *.hdr *.vox *.his *.xdr *.SCAN *.nii *.nrrd *.nhdr *.refscan *.nii.gz)"
107 #endif
108
109
110 /*Data Tree values
111   0,Qt::UserRole full filename
112   1,Qt::CheckStateRole checkbutton UL View
113   1,Qt::UserRole overlay, fusion or vector
114   2,Qt::CheckStateRole checkbutton UR View
115   3,Qt::CheckStateRole checkbutton DL View
116   4,Qt::CheckStateRole checkbutton DR View
117   5,0  short filename
118   5,Qt::UserRole mSlicerManager id*/
119
120 //------------------------------------------------------------------------------
121 vvMainWindow::vvMainWindow():vvMainWindowBase()
122 {
123   setupUi(this); // this sets up the GUI
124
125   mInputPathName = "";
126   mMenuTools = menuTools;
127   //  mMenuSegmentation = menuSegmentation;
128   mContextMenu = &contextMenu;
129   mMenuExperimentalTools = menuExperimental;
130   mMainWidget = this;
131   mCurrentTime = -1;
132   mCurrentSelectedImageId = "";
133   mCurrentPickedImageId = "";
134   mCurrentPickedImageIndex = 0;
135
136   //Init the contextMenu
137   this->setContextMenuPolicy(Qt::CustomContextMenu);
138   contextActions.resize(0);
139   QAction* actionOpen_new_image = contextMenu.addAction(QIcon(QString::fromUtf8(":/common/icons/fileopen.png")),
140                                   tr("O&pen new Image"));
141   actionOpen_new_image->setShortcut(QKeySequence(tr("Ctrl+O")));
142   connect(actionOpen_new_image,SIGNAL(triggered()),this,SLOT(OpenImages()));
143   contextActions.push_back(actionOpen_new_image);
144   contextMenu.addSeparator();
145
146   QAction* actionClose_Image = contextMenu.addAction(QIcon(QString::fromUtf8(":/common/icons/exit.png")),
147                                tr("Close Current Image"));
148   connect(actionClose_Image,SIGNAL(triggered()),this,SLOT(CloseImage()));
149   contextActions.push_back(actionClose_Image);
150
151   QAction* actionReload_image = contextMenu.addAction(QIcon(QString::fromUtf8(":/common/icons/rotateright.png")),
152                                 tr("Reload Current Image"));
153   connect(actionReload_image,SIGNAL(triggered()),this,SLOT(ReloadImage()));
154   contextActions.push_back(actionReload_image);
155
156   QAction* actionSave_image = contextMenu.addAction(QIcon(QString::fromUtf8(":/common/icons/filesave.png")),
157                               tr("Save Current Image"));
158   connect(actionSave_image,SIGNAL(triggered()),this,SLOT(SaveAs()));
159   contextActions.push_back(actionSave_image);
160
161   QAction* actionSave_state = contextMenu.addAction(QIcon(QString::fromUtf8(":/common/icons/filesave.png")),
162                               tr("Save Current State"));
163   connect(actionSave_state,SIGNAL(triggered()),this,SLOT(SaveCurrentState()));
164   contextActions.push_back(actionSave_state);
165
166   QAction* actionRead_state = contextMenu.addAction(QIcon(QString::fromUtf8(":/common/icons/filesave.png")),
167                               tr("Read Saved State"));
168   connect(actionRead_state,SIGNAL(triggered()),this,SLOT(ReadSavedState()));
169   contextActions.push_back(actionRead_state);
170
171   contextMenu.addSeparator();
172
173   contextMenu.addAction(actionAdd_VF_to_current_Image);
174   contextActions.push_back(actionAdd_VF_to_current_Image);
175
176   //QAction* actionAdd_Overlay_to_current_Image = menuOverlay->addAction(QIcon(QString::fromUtf8(":/common/icons/GPSup.png")),
177   //    tr("Add overlay image to current image"));
178   contextMenu.addAction(actionAdd_overlay_image_to_current_image);
179   contextActions.push_back(actionAdd_overlay_image_to_current_image);
180
181   contextMenu.addAction(actionAdd_fusion_image);
182   contextActions.push_back(actionAdd_fusion_image);
183
184   contextMenu.addAction(actionAdd_USSequence_toCT);
185   contextActions.push_back(actionAdd_USSequence_toCT);
186
187
188   contextMenu.addSeparator();
189   QAction* actionResetMatrix = contextMenu.addAction(QIcon(QString::fromUtf8(":/common/icons/identity.png")),
190                                                       tr("Reset transformation to identity"));
191   connect(actionResetMatrix, SIGNAL(triggered()), this,SLOT(ResetTransformationToIdentity()));
192
193   // TRIAL DS
194   /*
195   QMenu * m = new QMenu(menubar);
196   m->setTitle("TOTO");
197   //  m->setObjectName(QString::fromUtf8("TOTOTO"));
198   contextMenu.addMenu(m);
199   QAction * a = m->addAction(QIcon(QString::fromUtf8(":/common/icons/GPSup.png")),
200                      tr("BIDON"));
201   QAction * b = m->addAction(QIcon(QString::fromUtf8(":/common/icons/GPSup.png")),
202                      tr("BIDON2"));
203   m->addAction(a);
204   m->addAction(b);
205   connect(a,SIGNAL(triggered()),this,SLOT(AddFusionImage()));
206   */
207
208   //init the DataTree
209   mSlicerManagers.resize(0);
210
211   QStringList header;
212   header.append("");
213   header.append("TL");
214   header.append("TR");
215   header.append("BL");
216   header.append("BR");
217   header.append("");
218   header.append("");
219   header.append("Name");
220
221   DataTree->setHeaderLabels(header);
222   DataTree->resizeColumnToContents(COLUMN_TREE);
223   DataTree->resizeColumnToContents(COLUMN_UL_VIEW);
224   DataTree->resizeColumnToContents(COLUMN_UR_VIEW);
225   DataTree->resizeColumnToContents(COLUMN_DL_VIEW);
226   DataTree->resizeColumnToContents(COLUMN_DR_VIEW);
227   DataTree->resizeColumnToContents(COLUMN_CLOSE_IMAGE);
228   DataTree->resizeColumnToContents(COLUMN_RELOAD_IMAGE);
229   DataTree->resizeColumnToContents(COLUMN_IMAGE_NAME);
230
231   viewMode = 1;
232   documentation = new vvDocumentation();
233   help_dialog = new vvHelpDialog();
234   dicomSeriesSelector = new vvDicomSeriesSelector();
235
236   inverseButton->setEnabled(0);
237   actionAdd_overlay_image_to_current_image->setEnabled(0);
238   actionSave_As->setEnabled(0);
239   actionAdd_VF_to_current_Image->setEnabled(0);
240   actionAdd_fusion_image->setEnabled(0);
241   actionAdd_USSequence_toCT->setEnabled(0);
242
243   //init the sliders
244   verticalSliders.push_back(NOVerticalSlider);
245   verticalSliders.push_back(NEVerticalSlider);
246   verticalSliders.push_back(SOVerticalSlider);
247   verticalSliders.push_back(SEVerticalSlider);
248
249   for (int i =0; i < 4; i++)
250     verticalSliders[i]->hide();
251
252   horizontalSliders.push_back(NOHorizontalSlider);
253   horizontalSliders.push_back(NEHorizontalSlider);
254   horizontalSliders.push_back(SOHorizontalSlider);
255   horizontalSliders.push_back(SEHorizontalSlider);
256
257   for (int i =0; i < 4; i++)
258     horizontalSliders[i]->hide();
259
260
261   connect(NOVerticalSlider,SIGNAL(valueChanged(int)),this,SLOT(NOVerticalSliderChanged()));
262   connect(NEVerticalSlider,SIGNAL(valueChanged(int)),this,SLOT(NEVerticalSliderChanged()));
263   connect(SOVerticalSlider,SIGNAL(valueChanged(int)),this,SLOT(SOVerticalSliderChanged()));
264   connect(SEVerticalSlider,SIGNAL(valueChanged(int)),this,SLOT(SEVerticalSliderChanged()));
265
266   connect(NOHorizontalSlider,SIGNAL(valueChanged(int)),this,SLOT(NOHorizontalSliderMoved()));
267   connect(NEHorizontalSlider,SIGNAL(valueChanged(int)),this,SLOT(NEHorizontalSliderMoved()));
268   connect(SOHorizontalSlider,SIGNAL(valueChanged(int)),this,SLOT(SOHorizontalSliderMoved()));
269   connect(SEHorizontalSlider,SIGNAL(valueChanged(int)),this,SLOT(SEHorizontalSliderMoved()));
270
271   //connect everything
272   connect(actionCompute_mid_position_image,SIGNAL(triggered()),this,SLOT(ComputeMidPosition()));
273   connect(actionDeformable_Registration,SIGNAL(triggered()),this,SLOT(ComputeDeformableRegistration()));
274   connect(actionWarp_image_with_vector_field,SIGNAL(triggered()),this,SLOT(WarpImage()));
275   connect(actionLoad_images,SIGNAL(triggered()),this,SLOT(OpenImages()));
276   connect(actionOpen_Dicom,SIGNAL(triggered()),this,SLOT(OpenDicom()));
277   connect(actionOpen_Dicom_Struct,SIGNAL(triggered()),this,SLOT(OpenDCStructContour()));
278   connect(actionOpen_VTK_contour,SIGNAL(triggered()),this,SLOT(OpenVTKContour()));
279   connect(actionOpen_Multiple_Images_As_One,SIGNAL(triggered()),this,SLOT(MergeImages()));
280   connect(actionSlice_Image_As_Multiple_Images,SIGNAL(triggered()),this,SLOT(SliceImages()));
281   connect(actionOpen_Image_With_Time,SIGNAL(triggered()),this,SLOT(OpenImageWithTime()));
282   connect(actionMerge_images_as_n_dim_t, SIGNAL(triggered()), this, SLOT(MergeImagesWithTime()));
283   connect(actionSave_As,SIGNAL(triggered()),this,SLOT(SaveAs()));
284   connect(actionSave_current_state,SIGNAL(triggered()),this,SLOT(SaveCurrentState()));
285   connect(actionRead_saved_state,SIGNAL(triggered()),this,SLOT(ReadSavedState()));
286   connect(actionExit,SIGNAL(triggered()),this,SLOT(close()));
287   connect(actionAdd_VF_to_current_Image,SIGNAL(triggered()),this,SLOT(OpenField()));
288   connect(actionAdd_fusion_image,SIGNAL(triggered()),this,SLOT(SelectFusionImage()));
289   connect(actionAdd_overlay_image_to_current_image,SIGNAL(triggered()), this,SLOT(SelectOverlayImage()));
290   connect(actionAdd_USSequence_toCT,SIGNAL(triggered()), this,SLOT(SelectFusionSequence()));
291   connect(actionNavigation_Help,SIGNAL(triggered()),this,SLOT(ShowHelpDialog()));
292   connect(actionDocumentation,SIGNAL(triggered()),this,SLOT(ShowDocumentation()));
293   connect(actionRegister_vv,SIGNAL(triggered()),this,SLOT(PopupRegisterForm()));
294
295
296   ///////////////////////////////////////////////
297   connect(actionSegmentation,SIGNAL(triggered()),this,SLOT(SegmentationOnCurrentImage()));
298   connect(actionSurface_Viewer,SIGNAL(triggered()),this,SLOT(SurfaceViewerLaunch()));
299   ///////////////////////////////////////////////
300
301   actionNorth_East_Window->setEnabled(0);
302   actionNorth_West_Window->setEnabled(0);
303   actionSouth_East_Window->setEnabled(0);
304   actionSouth_West_Window->setEnabled(0);
305
306   connect(actionNorth_East_Window,SIGNAL(triggered()),this,SLOT(SaveNEScreenshot()));
307   connect(actionNorth_West_Window,SIGNAL(triggered()),this,SLOT(SaveNOScreenshot()));
308   connect(actionSouth_East_Window,SIGNAL(triggered()),this,SLOT(SaveSEScreenshot()));
309   connect(actionSouth_West_Window,SIGNAL(triggered()),this,SLOT(SaveSOScreenshot()));
310   connect(actionSave_all_slices,SIGNAL(triggered()),this,SLOT(SaveScreenshotAllSlices()));
311
312   connect(DataTree,SIGNAL(itemSelectionChanged()),this,SLOT(ImageInfoChanged()));
313   connect(DataTree,SIGNAL(itemClicked(QTreeWidgetItem*, int)),this,
314           SLOT(DisplayChanged(QTreeWidgetItem*, int)));
315
316   connect(viewButton,SIGNAL(clicked()),this, SLOT(ChangeViewMode()) );
317   connect(windowSpinBox,SIGNAL(editingFinished()),this,SLOT(WindowLevelEdited()));
318   connect(levelSpinBox,SIGNAL(editingFinished()),this,SLOT(WindowLevelEdited()));
319   connect(colorMapComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(UpdateColorMap()));
320   connect(presetComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(UpdateWindowLevel()));
321   connect(slicingPresetComboBox, SIGNAL(currentIndexChanged(int)),this,SLOT(UpdateSlicingPreset()));
322   connect(inverseButton,SIGNAL(clicked()),this,SLOT(SwitchWindowLevel()));
323   connect(applyWindowLevelToAllButton,SIGNAL(clicked()),this,SLOT(ApplyWindowLevelToAllImages()));
324
325   connect(this,SIGNAL(customContextMenuRequested(QPoint)),this,SLOT(ShowContextMenu(QPoint)));
326
327   connect(linkPanel,SIGNAL(addLink(QString,QString,bool)),this,SLOT(AddLink(QString,QString,bool)));
328   connect(linkPanel,SIGNAL(removeLink(QString,QString)),this,SLOT(RemoveLink(QString,QString)));
329   connect(overlayPanel,SIGNAL(VFPropertyUpdated(int,int,int,int,double,double,double)),this,SLOT(SetVFProperty(int,int,int,int,double,double,double)));
330   connect(overlayPanel,SIGNAL(OverlayPropertyUpdated(int,int,double,double)),
331           this,SLOT(SetOverlayProperty(int,int,double,double)));
332   connect(overlayPanel,SIGNAL(FusionPropertyUpdated(int,int,int,double,double, bool)),
333           this,SLOT(SetFusionProperty(int,int,int,double,double, bool)));
334   connect(landmarksPanel,SIGNAL(UpdateRenderWindows()),this,SLOT(UpdateRenderWindows()));
335
336   connect(overlayPanel,SIGNAL(FusionSequencePropertyUpdated(int, bool, unsigned int)),
337           this,SLOT(SetFusionSequenceProperty(int, bool,unsigned int)));
338
339
340   playMode = 0;//pause
341   mFrameRate = 10;
342   playButton->setEnabled(0);
343   frameRateLabel->setEnabled(0);
344   frameRateSpinBox->setEnabled(0);
345   connect(playButton, SIGNAL(clicked()),this,SLOT(PlayPause()));
346   connect(frameRateSpinBox, SIGNAL(valueChanged(int)),this,SLOT(ChangeFrameRate(int)));
347
348   goToCursorPushButton->setEnabled(0);
349   connect(goToCursorPushButton, SIGNAL(clicked()),this,SLOT(GoToCursor()));
350
351   NOViewWidget->hide();
352   NEViewWidget->hide();
353   SOViewWidget->hide();
354   SEViewWidget->hide();
355
356   //Recently opened files
357   std::list<std::string> recent_files = GetRecentlyOpenedImages();
358   recentlyOpenedFilesMenu=NULL;
359   if ( !recent_files.empty() ) {
360     createRecentlyOpenedFilesMenu();
361     updateRecentlyOpenedFilesMenu(recent_files);
362   }
363
364   // Adding all new tools (insertion in the menu)
365   vvToolManager::GetInstance()->InsertToolsInMenu(this);
366   vvToolManager::GetInstance()->EnableToolsInMenu(this, false);
367
368   if (!CLITK_EXPERIMENTAL)
369     menuExperimental->menuAction()->setVisible(false);
370
371
372   QTimer * timerMemory = new QTimer(this);
373   //timerMemory->setInterval(5);
374   connect(timerMemory, SIGNAL(timeout()), this, SLOT(UpdateMemoryUsage()));
375   timerMemory->start(2000);
376
377 }
378 //------------------------------------------------------------------------------
379 void vvMainWindow::show()
380 {
381   vvMainWindowBase::show();
382   PopupRegisterForm(true);
383 }
384 //------------------------------------------------------------------------------
385 void vvMainWindow::UpdateMemoryUsage()
386 {
387   //  clitk::PrintMemory(true);
388   if (clitk::GetMemoryUsageInMb() == 0) infoPanel->setMemoryInMb("NA");
389   else infoPanel->setMemoryInMb(QString::number(clitk::GetMemoryUsageInMb())+" MiB");
390 }
391 //------------------------------------------------------------------------------
392
393
394 //------------------------------------------------------------------------------
395 void vvMainWindow::createRecentlyOpenedFilesMenu()
396 {
397   recentlyOpenedFilesMenu = new QMenu("Recently opened files...");
398   recentlyOpenedFilesMenu->setIcon(QIcon(QString::fromUtf8(":/common/icons/open.png")));
399   menuFile->insertMenu(actionOpen_Image_With_Time,recentlyOpenedFilesMenu);
400   menuFile->insertSeparator(actionOpen_Image_With_Time);
401 }
402 //------------------------------------------------------------------------------
403
404
405 //------------------------------------------------------------------------------
406
407 void vvMainWindow::updateRecentlyOpenedFilesMenu(const std::list<std::string> &recent_files)
408 {
409   if(recentlyOpenedFilesMenu==NULL) {
410     createRecentlyOpenedFilesMenu();
411   } else {
412     recentlyOpenedFilesMenu->clear();
413   }
414   for (std::list<std::string>::const_iterator i = recent_files.begin(); i!=recent_files.end(); i++) {
415     QAction* current=new QAction(QIcon(QString::fromUtf8(":/common/icons/open.png")), i->c_str(),this);
416     recentlyOpenedFilesMenu->addAction(current);
417     connect(current,SIGNAL(triggered()),this,SLOT(OpenRecentImage()));
418   }
419 }
420 //------------------------------------------------------------------------------
421
422
423 //------------------------------------------------------------------------------
424 void vvMainWindow::ComputeMidPosition()
425 {
426   bool ok;
427   int index=GetSlicerIndexFromItem(DataTree->selectedItems()[0]);
428   int ref = QInputDialog::getInteger(this,"Chose reference phase","Reference phase",0,0,\
429                                      mSlicerManagers[index]->GetImage()->GetVTKImages().size()-1,1,&ok);
430   if (ok) {
431     vvMidPosition midp;
432     midp.slicer_manager = mSlicerManagers[index];
433     midp.reference_image_index = ref;
434     QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
435     midp.Update();
436     if (midp.error)
437       QMessageBox::warning(this, "Error computing midposition image",midp.error_message.c_str());
438     else {
439       QFileInfo info(midp.slicer_manager->GetFileName().c_str());
440       AddImage(midp.output,info.path().toStdString()+"/"+info.completeBaseName().toStdString()+"_midposition.mhd");
441     }
442     QApplication::restoreOverrideCursor();
443   }
444 }
445 //------------------------------------------------------------------------------
446
447
448 //------------------------------------------------------------------------------
449 void vvMainWindow::AddContour(int image_index, vvMesh::Pointer contour, bool propagation)
450 {
451   QTreeWidgetItem *item = new QTreeWidgetItem();
452   item->setData(0,Qt::UserRole,"filename.vtk");
453   item->setData(1,Qt::UserRole,tr("contour"));
454   QBrush brush;
455   brush.setColor(QColor(contour->r*255,contour->g*255,contour->b*255));
456   brush.setStyle(Qt::SolidPattern);
457   item->setData(COLUMN_IMAGE_NAME,Qt::BackgroundRole,brush);
458   item->setData(COLUMN_IMAGE_NAME,Qt::DisplayRole,contour->structure_name.c_str());
459
460   for (int j = 1; j <= 4; j++)
461     item->setData(j,Qt::CheckStateRole,DataTree->topLevelItem(image_index)->data(j,Qt::CheckStateRole));
462
463   QTreePushButton* cButton = new QTreePushButton;
464   cButton->setItem(item);
465   cButton->setColumn(COLUMN_CLOSE_IMAGE);
466   cButton->setToolTip(tr("close image"));
467   cButton->setIcon(QIcon(QString::fromUtf8(":/common/icons/exit.png")));
468   connect(cButton,SIGNAL(clickedInto(QTreeWidgetItem*, int)),
469           this,SLOT(CloseImage(QTreeWidgetItem*, int)));
470
471   QTreePushButton* rButton = new QTreePushButton;
472   rButton->setItem(item);
473   rButton->setColumn(COLUMN_RELOAD_IMAGE);
474   rButton->setToolTip(tr("reload image"));
475   rButton->setIcon(QIcon(QString::fromUtf8(":/common/icons/rotateright.png")));
476   rButton->setEnabled(false);
477   //Not implemented
478   //connect(rButton,SIGNAL(clickedInto(QTreeWidgetItem*, int)),
479   //this,SLOT(ReloadImage(QTreeWidgetItem*, int)));
480
481   DataTree->topLevelItem(image_index)->setExpanded(1);
482   DataTree->topLevelItem(image_index)->addChild(item);
483   DataTree->setItemWidget(item, COLUMN_CLOSE_IMAGE, cButton);
484   DataTree->setItemWidget(item, COLUMN_RELOAD_IMAGE, rButton);
485   QString id = DataTree->topLevelItem(image_index)->data(COLUMN_IMAGE_NAME,Qt::UserRole).toString();
486   item->setData(COLUMN_IMAGE_NAME,Qt::UserRole,id.toStdString().c_str());
487
488   UpdateTree();
489   mSlicerManagers[image_index]->AddContour(contour,propagation);
490   mSlicerManagers[image_index]->Render();
491 }
492 //------------------------------------------------------------------------------
493
494
495 //------------------------------------------------------------------------------
496 void vvMainWindow::OpenVTKContour()
497 {
498   if (mSlicerManagers.size() > 0) {
499     QString Extensions = "Images ( *.vtk *.obj)";
500     Extensions += ";;All Files (*)";
501     QString file = QFileDialog::getOpenFileName(this,tr("Open vtkPolyData"),mInputPathName,Extensions);
502     if (file.isNull())
503       return;
504     QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
505     int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]);
506     vvMeshReader reader;
507     reader.SetImage(mSlicerManagers[index]->GetImage());
508     reader.SetModeToVTK();
509     reader.SetFilename(file.toStdString());
510     reader.Update();
511     AddContour(index,reader.GetOutput()[0],false);
512     QApplication::restoreOverrideCursor();
513   }
514 }
515 //------------------------------------------------------------------------------
516
517
518 //------------------------------------------------------------------------------
519 void vvMainWindow::AddDCStructContour(int index, QString file)
520 {
521     vvMeshReader reader;
522     reader.SetFilename(file.toStdString());
523     vvStructSelector selector;
524     selector.SetStructures(reader.GetROINames());
525     if (!mSlicerManagers[index]->GetVF().IsNull())
526       selector.EnablePropagationCheckBox();
527     if (selector.exec()) {
528       QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
529       reader.SetSelectedItems(selector.getSelectedItems());
530       reader.SetImage(mSlicerManagers[index]->GetImage());
531       if (selector.PropagationEnabled())
532         reader.SetPropagationVF(mSlicerManagers[index]->GetVF());
533       reader.Update();
534       std::vector<vvMesh::Pointer> contours=reader.GetOutput();
535       for (std::vector<vvMesh::Pointer>::iterator i=contours.begin();
536            i!=contours.end(); i++)
537         AddContour(index,*i,selector.PropagationEnabled());
538       QApplication::restoreOverrideCursor();
539     }
540 }
541
542 //------------------------------------------------------------------------------
543 void vvMainWindow::OpenDCStructContour()
544 {
545   if (mSlicerManagers.size() > 0) {
546     QString Extensions = "Dicom Files ( *.dcm RS*)";
547     Extensions += ";;All Files (*)";
548     QString file = QFileDialog::getOpenFileName(this,tr("Merge Images"),mInputPathName,Extensions);
549     if (file.isNull())
550       return;
551     int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]);
552     AddDCStructContour(index, file);
553   }
554 }
555 //------------------------------------------------------------------------------
556
557
558 //------------------------------------------------------------------------------
559 void vvMainWindow::ComputeDeformableRegistration()
560 {
561   if (mSlicerManagers.size() > 0) {
562     int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]);
563     vvDeformationDialog dialog(index,mSlicerManagers);
564     if (dialog.exec()) {
565       std::string base_name=itksys::SystemTools::GetFilenameWithoutExtension(mSlicerManagers[dialog.GetInputFileIndex()]->GetFileName());
566       AddField(dialog.GetOutput(),dialog.getFieldFile(),dialog.GetInputFileIndex());
567       WarpImage(dialog.GetSelectedSlicer(),dialog.GetReferenceFrameIndex());
568     } else
569       std::cout << "Error or user cancellation while computing deformation field..." << std::endl;
570   } else QMessageBox::information(this, "Need to open image","You must open an image first.");
571 }
572 //------------------------------------------------------------------------------
573
574
575 //------------------------------------------------------------------------------
576 void vvMainWindow::WarpImage()
577 {
578   int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]);
579   if (!mSlicerManagers[index]->GetVF().IsNull()) {
580     bool ok;
581     int ref = QInputDialog::getInteger(this,"Chose reference phase","Reference phase",0,0,\
582                                        mSlicerManagers[index]->GetImage()->GetVTKImages().size()-1,1,&ok);
583     if (ok) {
584       WarpImage(mSlicerManagers[index],ref);
585     }
586   } else
587     QMessageBox::warning(this,tr("No vector field"),tr("Sorry, can't warp without a vector field"));
588 }
589 //------------------------------------------------------------------------------
590
591
592 //------------------------------------------------------------------------------
593 void vvMainWindow::WarpImage(vvSlicerManager* selected_slicer,int reference_phase)
594 {
595   if (!selected_slicer->GetVF().IsNull()) {
596     QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
597     QFileInfo info(selected_slicer->GetFileName().c_str());
598     vvImageWarp warp(selected_slicer->GetImage(),selected_slicer->GetVF(),
599                      reference_phase,this);
600     if (warp.ComputeWarpedImage()) {
601       AddImage(warp.GetWarpedImage(),info.path().toStdString()+"/"+info.completeBaseName().toStdString()+"_warped.mhd");
602       AddImage(warp.GetDiffImage()  ,info.path().toStdString()+"/"+info.completeBaseName().toStdString()+"_diff.mhd");
603       AddImage(warp.GetJacobianImage()  ,info.path().toStdString()+"/"+info.completeBaseName().toStdString()+"_jacobian.mhd");
604       QApplication::restoreOverrideCursor();
605     } else {
606       QApplication::restoreOverrideCursor();
607       QMessageBox::warning(this,tr("Different spacings"),tr("The vector field and image spacings must be the same in order to warp."));
608     }
609   } else
610     QMessageBox::warning(this,tr("No vector field"),tr("Sorry, can't warp without a vector field."));
611 }
612 //------------------------------------------------------------------------------
613
614
615 //------------------------------------------------------------------------------
616 vvMainWindow::~vvMainWindow()
617 {
618   for (unsigned int i = 0; i < mSlicerManagers.size(); i++) {
619     if (mSlicerManagers[i] != NULL)
620       delete mSlicerManagers[i];
621   }
622 }
623 //------------------------------------------------------------------------------
624
625 //------------------------------------------------------------------------------
626 QTabWidget * vvMainWindow::GetTab()
627 {
628   return tabWidget;
629 }
630 //------------------------------------------------------------------------------
631
632
633 //------------------------------------------------------------------------------
634 void vvMainWindow::MergeImages()
635 {
636   QString Extensions = EXTENSIONS;
637   Extensions += ";;All Files (*)";
638   QStringList files = QFileDialog::getOpenFileNames(this,tr("Merge Images"),mInputPathName,Extensions);
639   if (files.isEmpty())
640     return;
641   mInputPathName = itksys::SystemTools::GetFilenamePath(files[0].toStdString()).c_str();
642   std::vector<std::string> vector;
643
644   unsigned int currentDim = 0;
645   std::vector<double> currentSpacing;
646   std::vector<int> currentSize;
647   std::vector<double> currentOrigin;
648
649   for (int i = 0; i < files.size(); i++) {
650     itk::ImageIOBase::Pointer reader = itk::ImageIOFactory::CreateImageIO(
651                                          files[i].toStdString().c_str(), itk::ImageIOFactory::ReadMode);
652     reader->SetFileName(files[i].toStdString().c_str());
653     reader->ReadImageInformation();
654     if (reader)        {
655       //NOViewWidget->hide();
656       //NEViewWidget->hide();
657       //SOViewWidget->hide();
658       //SEViewWidget->hide();
659       if (i == 0)
660         currentDim = reader->GetNumberOfDimensions();
661       bool IsOk = true;
662       for (unsigned int j = 0; j < currentDim; j++) {
663         if (i == 0) {
664           if (j == 0) {
665             currentSpacing.resize(currentDim);
666             currentSize.resize(currentDim);
667             currentOrigin.resize(currentDim);
668           }
669           currentOrigin[j] = reader->GetOrigin(j);
670           currentSpacing[j] = reader->GetSpacing(j);
671           currentSize[j] = reader->GetDimensions(j);
672         } else if (currentDim != reader->GetNumberOfDimensions()
673                    || currentSpacing[j] != reader->GetSpacing(j)
674                    || currentSize[j] != (int)reader->GetDimensions(j)
675                    || currentOrigin[j] != reader->GetOrigin(j)) {
676           QString error = "Cannot read file (too different from others ";
677           error += files[i].toStdString().c_str();
678           QMessageBox::information(this,tr("Reading problem"),error);
679           IsOk = false;
680           break;
681         }
682       }
683       if (IsOk)
684         vector.push_back(files[i].toStdString());
685     }
686   }
687   if (vector.size() > 0)
688     LoadImages(vector, vvImageReader::MERGED);
689 }
690 //------------------------------------------------------------------------------
691
692 //------------------------------------------------------------------------------
693 void vvMainWindow::SliceImages()
694 {
695   QString Extensions = EXTENSIONS;
696   Extensions += ";;All Files (*)";
697
698   QStringList files = QFileDialog::getOpenFileNames(this,tr("Slice Images"),mInputPathName,Extensions);
699   if (files.isEmpty())
700     return;
701   mInputPathName = itksys::SystemTools::GetFilenamePath(files[0].toStdString()).c_str();
702   std::vector<std::string> vector;
703   for (int i = 0; i < files.size(); i++)
704     vector.push_back(files[i].toStdString());
705   LoadImages(vector, vvImageReader::SLICED);
706 }
707 //------------------------------------------------------------------------------
708
709 //------------------------------------------------------------------------------
710 void vvMainWindow::MergeImagesWithTime()
711 {
712   QString Extensions = EXTENSIONS;
713   Extensions += ";;All Files (*)";
714   QStringList files = QFileDialog::getOpenFileNames(this,tr("Merge Images With Time"),mInputPathName,Extensions);
715   if (files.isEmpty())
716     return;
717   mInputPathName = itksys::SystemTools::GetFilenamePath(files[0].toStdString()).c_str();
718   std::vector<std::string> vector;
719
720   for (int i = 0; i < files.size(); i++)
721     vector.push_back(files[i].toStdString());
722   sort(vector.begin(),vector.end());
723   if (vector.size() > 1)
724     LoadImages(vector, vvImageReader::MERGEDWITHTIME);
725   else
726     QMessageBox::warning(this,tr("Reading problem"),"You need to select at least two images to merge images with time.\nIf you only want to open one image, please use the \"Open Image\" function.");
727 }
728 //------------------------------------------------------------------------------
729
730
731 //------------------------------------------------------------------------------
732 void vvMainWindow::OpenDicom()
733 {
734   std::vector<std::string> files;
735
736   std::cout << "dicomSeriesSelector " << std::endl;
737   if (dicomSeriesSelector->exec() == QDialog::Accepted) {
738     files = *(dicomSeriesSelector->GetFilenames());
739     LoadImages(files, vvImageReader::DICOM);
740   }
741 }
742 //------------------------------------------------------------------------------
743
744 //------------------------------------------------------------------------------
745 void vvMainWindow::OpenImages()
746 {
747   QString Extensions = EXTENSIONS;
748   Extensions += ";;All Files (*)";
749
750   QStringList files = QFileDialog::getOpenFileNames(this,tr("Load Images"),mInputPathName,Extensions);
751   if (files.isEmpty())
752     return;
753   mInputPathName = itksys::SystemTools::GetFilenamePath(files[0].toStdString()).c_str();
754   std::vector<std::string> vector;
755   for (int i = 0; i < files.size(); i++)
756     vector.push_back(files[i].toStdString());
757   LoadImages(vector, vvImageReader::IMAGE);
758 }
759 //------------------------------------------------------------------------------
760 void vvMainWindow::OpenRecentImage()
761 {
762   QAction * caller = qobject_cast<QAction*>(sender());
763   std::vector<std::string> images;
764   images.push_back(caller->text().toStdString());
765   mInputPathName = itksys::SystemTools::GetFilenamePath(images[0]).c_str();
766   LoadImages(images, vvImageReader::IMAGE);
767 }
768 //------------------------------------------------------------------------------
769
770
771 //------------------------------------------------------------------------------
772 void vvMainWindow::OpenImageWithTime()
773 {
774   QString Extensions = EXTENSIONS;
775   Extensions += ";;All Files (*)";
776
777   QStringList files = QFileDialog::getOpenFileNames(this,tr("Load Images With Time"),mInputPathName,Extensions);
778   if (files.isEmpty())
779     return;
780   mInputPathName = itksys::SystemTools::GetFilenamePath(files[0].toStdString()).c_str();
781   std::vector<std::string> vector;
782   for (int i = 0; i < files.size(); i++) {
783     vector.push_back(files[i].toStdString());
784   }
785   LoadImages(vector, vvImageReader::IMAGEWITHTIME);
786 }
787 //------------------------------------------------------------------------------
788
789
790 //------------------------------------------------------------------------------
791 void vvMainWindow::LoadImages(std::vector<std::string> files, vvImageReader::LoadedImageType filetype)
792 {
793   //Separate the way to open images and dicoms
794   int fileSize;
795   if (filetype == vvImageReader::IMAGE || filetype == vvImageReader::IMAGEWITHTIME)
796     fileSize = files.size();
797   else
798     fileSize = 1;
799
800   // For SLICED, we need the number of slices (ndim and #slices)
801   std::vector<unsigned int> nSlices;
802   nSlices.resize(files.size());
803   std::fill(nSlices.begin(), nSlices.end(), 1);
804   if (filetype == vvImageReader::SLICED) {
805     for (int i = 0; i < fileSize; i++) {
806       itk::ImageIOBase::Pointer header = clitk::readImageHeader(files[i]);
807       QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
808       if (!header) {
809         nSlices[i] = 0;
810         QString error = "Cannot open file \n";
811         error += files[i].c_str();
812         QMessageBox::information(this,tr("Reading problem"),error);
813         return;
814       }
815       if (header->GetNumberOfDimensions() < 3) {
816         nSlices[i] = 0;
817         QString error = "Dimension problem. Cannot slice \n";
818         error += files[i].c_str();
819         QMessageBox::information(this,tr("Reading problem"),error);
820         return;
821       }
822       nSlices[i] = header->GetDimensions( header->GetNumberOfDimensions()-1 );
823     }
824   }
825
826   //Only add to the list of recently opened files when a single file is opened,
827   //to avoid polluting the list of recently opened files
828   if (files.size() == 1) {
829     QFileInfo finfo=tr(files[0].c_str());
830     AddToRecentlyOpenedImages(finfo.absoluteFilePath().toStdString());
831     updateRecentlyOpenedFilesMenu(GetRecentlyOpenedImages());
832   }
833   //init the progress events
834   QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
835   vvProgressDialog progress("Opening " + files[0],fileSize>1);
836   qApp->processEvents();
837
838   int numberofsuccesulreads=0;
839   //open images as 1 or multiples
840   for (int i = 0; i < fileSize; i++) {
841
842     progress.SetText("Opening " + files[i]);
843     progress.SetProgress(i,fileSize);
844     qApp->processEvents();
845
846     for (unsigned int j = 0; j < nSlices[i]; j++) {
847       //read the image and put it in mSlicerManagers
848       vvSlicerManager* imageManager = new vvSlicerManager(4);
849       qApp->processEvents();
850
851       bool SetImageSucceed=false;
852
853       // Change filename if an image with the same already exist
854       int number = GetImageDuplicateFilenameNumber(files[i] + std::string("_slice"));
855
856       if (filetype == vvImageReader::IMAGE || filetype == vvImageReader::IMAGEWITHTIME || filetype == vvImageReader::SLICED)
857         SetImageSucceed = imageManager->SetImage(files[i],filetype, number, j);
858       else {
859         SetImageSucceed = imageManager->SetImages(files,filetype, number);
860       }
861       if (!SetImageSucceed) {
862         QApplication::restoreOverrideCursor();
863         QString error = "Cannot open file \n";
864         error += imageManager->GetLastError().c_str();
865         QMessageBox::information(this,tr("Reading problem"),error);
866         delete imageManager;
867       } else {
868         mSlicerManagers.push_back(imageManager);
869
870         //create an item in the tree with good settings
871         QTreeWidgetItem *item = new QTreeWidgetItem();
872         item->setData(0,Qt::UserRole,files[i].c_str());
873         QFileInfo fileinfo(imageManager->GetFileName().c_str()); //Do not show the path
874         item->setData(COLUMN_IMAGE_NAME,Qt::DisplayRole,fileinfo.fileName());
875         item->setData(1,Qt::UserRole,tr("image"));
876         item->setToolTip(COLUMN_IMAGE_NAME, imageManager->GetListOfAbsoluteFilePathInOneString("image").c_str());
877         qApp->processEvents();
878
879         //Create the buttons for reload and close
880         qApp->processEvents();
881         QTreePushButton* cButton = new QTreePushButton;
882         cButton->setItem(item);
883         cButton->setColumn(COLUMN_CLOSE_IMAGE);
884         cButton->setToolTip(tr("close image"));
885         cButton->setIcon(QIcon(QString::fromUtf8(":/common/icons/exit.png")));
886         connect(cButton,SIGNAL(clickedInto(QTreeWidgetItem*, int)),
887                 this,SLOT(CloseImage(QTreeWidgetItem*, int)));
888
889         QTreePushButton* rButton = new QTreePushButton;
890         rButton->setItem(item);
891         rButton->setColumn(COLUMN_RELOAD_IMAGE);
892         rButton->setToolTip(tr("reload image"));
893         rButton->setIcon(QIcon(QString::fromUtf8(":/common/icons/rotateright.png")));
894         connect(rButton,SIGNAL(clickedInto(QTreeWidgetItem*, int)),
895                 this,SLOT(ReloadImage(QTreeWidgetItem*, int)));
896
897         DataTree->addTopLevelItem(item);
898         DataTree->setItemWidget(item, COLUMN_CLOSE_IMAGE, cButton);
899         DataTree->setItemWidget(item, COLUMN_RELOAD_IMAGE, rButton);
900
901         //set the id of the image
902         QString id = QDir::current().absoluteFilePath(files[i].c_str()) + QString::number(mSlicerManagers.size()-1);
903         item->setData(COLUMN_IMAGE_NAME,Qt::UserRole,id.toStdString().c_str());
904         mSlicerManagers.back()->SetId(id.toStdString());
905
906         linkPanel->addImage(imageManager->GetFileName(), id.toStdString());
907
908         connect(mSlicerManagers.back(), SIGNAL(currentImageChanged(std::string)),
909                 this,SLOT(CurrentImageChanged(std::string)));
910         connect(mSlicerManagers.back(), SIGNAL(currentPickedImageChanged(std::string)),
911                 this, SLOT(CurrentPickedImageChanged(std::string)));
912         connect(mSlicerManagers.back(), SIGNAL(UpdatePosition(int, double, double, double, double, double, double, double)),
913                 this,SLOT(MousePositionChanged(int,double, double, double, double, double, double, double)));
914         connect(mSlicerManagers.back(), SIGNAL(UpdateVector(int, double, double, double, double)),
915                 this, SLOT(VectorChanged(int,double,double,double, double)));
916         connect(mSlicerManagers.back(), SIGNAL(UpdateOverlay(int, double, double)),
917                 this, SLOT(OverlayChanged(int,double,double)));
918         connect(mSlicerManagers.back(), SIGNAL(UpdateFusion(int, double)),
919                 this, SLOT(FusionChanged(int,double)));
920         //connect(mSlicerManagers.back(), SIGNAL(UpdateFusionSequence(int, bool, unsigned int)),
921         //        this, SLOT(FusionSequenceChanged(int, bool, unsigned int)));
922         connect(mSlicerManagers.back(), SIGNAL(WindowLevelChanged()),
923                 this,SLOT(WindowLevelChanged()));
924         connect(mSlicerManagers.back(), SIGNAL(UpdateSlice(int,int)),
925                 this,SLOT(UpdateSlice(int,int)));
926         connect(mSlicerManagers.back(), SIGNAL(UpdateTSlice(int, int)),
927                 this,SLOT(UpdateTSlice(int, int)));
928         connect(mSlicerManagers.back(), SIGNAL(UpdateTSlice(int, int)),
929                 this,SLOT(ImageInfoChanged()));
930         connect(mSlicerManagers.back(), SIGNAL(UpdateSliceRange(int,int,int,int,int)),
931                 this,SLOT(UpdateSliceRange(int,int,int,int,int)));
932         connect(mSlicerManagers.back(), SIGNAL(UpdateLinkManager(std::string,int,double,double,double,int)),
933                 this,SLOT(UpdateLinkManager(std::string,int,double,double,double,int)));
934         connect(mSlicerManagers.back(), SIGNAL(UpdateLinkedNavigation(std::string,vvSlicerManager*,vvSlicer*)),
935                 this,SLOT(UpdateLinkedNavigation(std::string,vvSlicerManager*,vvSlicer*)));
936         connect(mSlicerManagers.back(), SIGNAL(ChangeImageWithIndexOffset(vvSlicerManager*,int,int)),
937                 this,SLOT(ChangeImageWithIndexOffset(vvSlicerManager*,int,int)));
938         connect(mSlicerManagers.back(),SIGNAL(LandmarkAdded()),landmarksPanel,SLOT(AddPoint()));
939         InitSlicers();
940         numberofsuccesulreads++;
941       }
942     }
943   }
944   if (numberofsuccesulreads) {
945     NOViewWidget->show();
946     NEViewWidget->show();
947     SOViewWidget->show();
948     SEViewWidget->show();
949     UpdateTree();
950     InitDisplay();
951     ShowLastImage();
952
953     // Try to guess default WindowLevel
954     double range[2];
955     mSlicerManagers.back()->GetImage()->GetFirstVTKImageData()->GetScalarRange(range);
956     if ((range[0] == 0) && (range[1] == 1)) {
957       presetComboBox->setCurrentIndex(5);// binary
958     } else {
959       // TODO
960     }
961   }
962   QApplication::restoreOverrideCursor();
963 }
964 //------------------------------------------------------------------------------
965
966 //------------------------------------------------------------------------------
967 void vvMainWindow::UpdateTree()
968 {
969   DataTree->resizeColumnToContents(COLUMN_TREE);
970   DataTree->resizeColumnToContents(COLUMN_UL_VIEW);
971   DataTree->resizeColumnToContents(COLUMN_UR_VIEW);
972   DataTree->resizeColumnToContents(COLUMN_DL_VIEW);
973   DataTree->resizeColumnToContents(COLUMN_DR_VIEW);
974   DataTree->resizeColumnToContents(COLUMN_IMAGE_NAME);
975   DataTree->resizeColumnToContents(COLUMN_CLOSE_IMAGE);
976   DataTree->resizeColumnToContents(COLUMN_RELOAD_IMAGE);
977 }
978 //------------------------------------------------------------------------------
979
980 //------------------------------------------------------------------------------
981 void vvMainWindow::CurrentImageChanged(std::string id)
982 {
983   if (id == mCurrentSelectedImageId) return; // Do nothing
984   int selected = 0;
985   for (int i = 0; i < DataTree->topLevelItemCount(); i++) {
986     if (DataTree->topLevelItem(i)->data(COLUMN_IMAGE_NAME,Qt::UserRole).toString().toStdString() == id) {
987       selected = i;
988     } else {
989       DataTree->topLevelItem(i)->setSelected(0);
990     }
991     for (int child = 0; child < DataTree->topLevelItem(i)->childCount(); child++)
992       DataTree->topLevelItem(i)->child(child)->setSelected(0);
993
994   }
995   DataTree->topLevelItem(selected)->setSelected(1);
996   mCurrentSelectedImageId = id;
997   emit SelectedImageHasChanged(mSlicerManagers[selected]);
998 }
999 //------------------------------------------------------------------------------
1000
1001 //------------------------------------------------------------------------------
1002 void vvMainWindow::CurrentPickedImageChanged(std::string id)
1003 {
1004   if (id == mCurrentPickedImageId) return; // Do nothing
1005   int selected = 0;
1006   for (int i = 0; i < DataTree->topLevelItemCount(); i++) {
1007     if (DataTree->topLevelItem(i)->data(COLUMN_IMAGE_NAME,Qt::UserRole).toString().toStdString() == id) {
1008       selected = i;
1009     } else {
1010       DataTree->topLevelItem(i)->setSelected(0);
1011     }
1012     for (int child = 0; child < DataTree->topLevelItem(i)->childCount(); child++)
1013       DataTree->topLevelItem(i)->child(child)->setSelected(0);
1014
1015   }
1016   DataTree->topLevelItem(selected)->setSelected(1);
1017   mCurrentPickedImageId = id;
1018   mCurrentPickedImageIndex = selected;
1019 }
1020 //------------------------------------------------------------------------------
1021
1022 //------------------------------------------------------------------------------
1023 void vvMainWindow::ImageInfoChanged()
1024 {
1025   contextActions[6]->setEnabled(1);
1026   contextActions[5]->setEnabled(1);
1027   actionSave_As->setEnabled(1);
1028   actionAdd_VF_to_current_Image->setEnabled(1);
1029   actionAdd_fusion_image->setEnabled(1);
1030   actionAdd_overlay_image_to_current_image->setEnabled(1);
1031   actionAdd_USSequence_toCT->setEnabled(1);
1032   actionNorth_East_Window->setEnabled(1);
1033   actionNorth_West_Window->setEnabled(1);
1034   actionSouth_East_Window->setEnabled(1);
1035   actionSouth_West_Window->setEnabled(1);
1036   vvToolManager::GetInstance()->EnableToolsInMenu(this, true);
1037   inverseButton->setEnabled(1);
1038
1039   goToCursorPushButton->setEnabled(1);
1040
1041   if (DataTree->selectedItems().size()) {
1042     int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]);
1043
1044     colorMapComboBox->setEnabled(1);
1045     for (int i = 0; i < DataTree->topLevelItem(index)->childCount(); i++) {
1046       if (DataTree->topLevelItem(index)->child(i)->data(1,Qt::UserRole).toString() == "overlay" ||
1047           DataTree->topLevelItem(index)->child(i)->data(1,Qt::UserRole).toString() == "fusion" ||
1048           DataTree->topLevelItem(index)->child(i)->data(1,Qt::UserRole).toString() == "fusionSequence") {
1049         colorMapComboBox->setEnabled(0);
1050         break;
1051       }
1052     }
1053
1054         std::vector<double> origin;
1055     std::vector<double> inputSpacing;
1056     std::vector<int> inputSize;
1057     std::vector<double> sizeMM;
1058     vtkSmartPointer<vtkMatrix4x4> transformation;
1059     int dimension=0;
1060     QString pixelType;
1061     QString inputSizeInBytes;
1062     QString image = DataTree->selectedItems()[0]->data(COLUMN_IMAGE_NAME,Qt::DisplayRole).toString();
1063
1064         int nframes = mSlicerManagers[index]->GetSlicer(0)->GetTMax();
1065
1066         if (nframes > 1 || playMode == 1) {
1067       playButton->setEnabled(1);
1068       frameRateLabel->setEnabled(1);
1069       frameRateSpinBox->setEnabled(1);
1070     } else {
1071       playButton->setEnabled(0);
1072       frameRateLabel->setEnabled(0);
1073       frameRateSpinBox->setEnabled(0);
1074     }
1075
1076     //read image header
1077     int NPixel = 1;
1078
1079         int tSlice = 0;
1080     vvImage::Pointer imageSelected;
1081     if (DataTree->topLevelItem(index) == DataTree->selectedItems()[0]) {
1082       imageSelected = mSlicerManagers[index]->GetSlicer(0)->GetImage();
1083       tSlice = mSlicerManagers[index]->GetSlicer(0)->GetTSlice();
1084     } else if (DataTree->selectedItems()[0]->data(1,Qt::UserRole).toString() == "vector") {
1085       imageSelected = mSlicerManagers[index]->GetSlicer(0)->GetVF();
1086       tSlice = mSlicerManagers[index]->GetSlicer(0)->GetOverlayTSlice();
1087     } else if (DataTree->selectedItems()[0]->data(1,Qt::UserRole).toString() == "overlay") {
1088       imageSelected = mSlicerManagers[index]->GetSlicer(0)->GetOverlay();
1089       tSlice = mSlicerManagers[index]->GetSlicer(0)->GetOverlayTSlice();
1090     } else if (DataTree->selectedItems()[0]->data(1,Qt::UserRole).toString() == "fusion") {
1091         imageSelected = mSlicerManagers[index]->GetSlicer(0)->GetFusion();
1092         tSlice = mSlicerManagers[index]->GetSlicer(0)->GetFusionTSlice();
1093     }
1094     else if (DataTree->selectedItems()[0]->data(1,Qt::UserRole).toString() == "fusionSequence") {
1095         imageSelected = mSlicerManagers[index]->GetSlicer(0)->GetFusion();
1096         tSlice = mSlicerManagers[index]->GetSlicer(0)->GetFusionTSlice();
1097         }
1098     else if (DataTree->selectedItems()[0]->data(1,Qt::UserRole).toString() == "contour") {
1099         imageSelected = mSlicerManagers[index]->GetSlicer(0)->GetImage();
1100         tSlice = mSlicerManagers[index]->GetSlicer(0)->GetTSlice();
1101     }
1102     else {
1103         imageSelected = mSlicerManagers[index]->GetSlicer(0)->GetImage();
1104         tSlice = mSlicerManagers[index]->GetSlicer(0)->GetTSlice();
1105     }
1106
1107         dimension = imageSelected->GetNumberOfDimensions();
1108     origin.resize(dimension);
1109     inputSpacing.resize(dimension);
1110     inputSize.resize(dimension);
1111     sizeMM.resize(dimension);
1112     pixelType = mSlicerManagers[index]->GetImage()->GetScalarTypeAsITKString().c_str();
1113     for (int i = 0; i < dimension; i++) {
1114       origin[i] = imageSelected->GetOrigin()[i];
1115       inputSpacing[i] = imageSelected->GetSpacing()[i];
1116       inputSize[i] = imageSelected->GetSize()[i];
1117       sizeMM[i] = inputSize[i]*inputSpacing[i];
1118       NPixel *= inputSize[i];
1119     }
1120     inputSizeInBytes = GetSizeInBytes(imageSelected->GetActualMemorySize()*1000);
1121
1122     QString dim = QString::number(dimension) + " (";
1123     dim += pixelType + ")";
1124
1125     infoPanel->setFileName(image);
1126     infoPanel->setDimension(dim);
1127     infoPanel->setSizePixel(GetVectorIntAsString(inputSize));
1128     infoPanel->setSizeMM(GetVectorDoubleAsString(sizeMM));
1129     infoPanel->setOrigin(GetVectorDoubleAsString(origin));
1130     infoPanel->setSpacing(GetVectorDoubleAsString(inputSpacing));
1131     infoPanel->setNPixel(QString::number(NPixel)+" ("+inputSizeInBytes+")");
1132
1133         transformation = imageSelected->GetTransform()[tSlice]->GetMatrix();
1134     infoPanel->setTransformation(Get4x4MatrixDoubleAsString(transformation));
1135
1136         landmarksPanel->SetCurrentLandmarks(mSlicerManagers[index]->GetLandmarks(),
1137                                         mSlicerManagers[index]->GetSlicer(0)->GetImage()->GetVTKImages().size());
1138     landmarksPanel->SetCurrentPath(mInputPathName.toStdString());
1139     landmarksPanel->SetCurrentImage(mSlicerManagers[index]->GetFileName().c_str());
1140
1141     overlayPanel->getCurrentImageName(mSlicerManagers[index]->GetFileName().c_str());
1142     for (int i = 0; i < 4; i++) {
1143       if (DataTree->selectedItems()[0]->data(i+1,Qt::CheckStateRole).toInt() > 0 || i == 3) {
1144         mSlicerManagers[index]->UpdateInfoOnCursorPosition(i);
1145         break;
1146       }
1147     }
1148
1149         infoPanel->setFileName(image);
1150     infoPanel->setDimension(dim);
1151     infoPanel->setSizePixel(GetVectorIntAsString(inputSize));
1152     infoPanel->setSizeMM(GetVectorDoubleAsString(sizeMM));
1153     infoPanel->setOrigin(GetVectorDoubleAsString(origin));
1154     infoPanel->setSpacing(GetVectorDoubleAsString(inputSpacing));
1155     infoPanel->setNPixel(QString::number(NPixel)+" ("+inputSizeInBytes+")");
1156
1157     landmarksPanel->SetCurrentLandmarks(mSlicerManagers[index]->GetLandmarks(),
1158                                         mSlicerManagers[index]->GetSlicer(0)->GetImage()->GetVTKImages().size());
1159     landmarksPanel->SetCurrentPath(mInputPathName.toStdString());
1160     landmarksPanel->SetCurrentImage(mSlicerManagers[index]->GetFileName().c_str());
1161
1162     overlayPanel->getCurrentImageName(mSlicerManagers[index]->GetFileName().c_str());
1163     for (int i = 0; i < 4; i++) {
1164       if (DataTree->selectedItems()[0]->data(i+1,Qt::CheckStateRole).toInt() > 0 || i == 3) {
1165         mSlicerManagers[index]->UpdateInfoOnCursorPosition(i);
1166         break;
1167       }
1168     }
1169         WindowLevelChanged();
1170
1171         slicingPresetComboBox->setCurrentIndex(mSlicerManagers[index]->GetSlicingPreset());
1172
1173         if (mSlicerManagers[index]->GetSlicer(0)->GetVF()) {
1174       overlayPanel->getVFName(mSlicerManagers[index]->GetVFName().c_str());
1175       overlayPanel->getVFProperty(mSlicerManagers[index]->GetSlicer(0)->GetVFSubSampling(),
1176                                   mSlicerManagers[index]->GetSlicer(0)->GetVFScale(),
1177                                   mSlicerManagers[index]->GetSlicer(0)->GetVFLog());
1178     } else {
1179       overlayPanel->getVFName(mSlicerManagers[index]->GetVFName().c_str());
1180       overlayPanel->getVFProperty(-1,-1,-1);
1181     }
1182     if (mSlicerManagers[index]->GetSlicer(0)->GetOverlay()) {
1183       overlayPanel->getOverlayName(mSlicerManagers[index]->GetOverlayName().c_str());
1184     } else {
1185       overlayPanel->getOverlayName(mSlicerManagers[index]->GetOverlayName().c_str());
1186     }
1187  
1188         if (mSlicerManagers[index]->GetSlicer(0)->GetFusion()) {
1189       overlayPanel->getFusionName(mSlicerManagers[index]->GetFusionName().c_str());
1190     } else {
1191       overlayPanel->getFusionName(mSlicerManagers[index]->GetFusionName().c_str());
1192     }
1193   }
1194 }
1195 //------------------------------------------------------------------------------
1196
1197 //------------------------------------------------------------------------------
1198 void vvMainWindow::ShowDocumentation()
1199 {
1200   documentation->show();
1201 }
1202 //------------------------------------------------------------------------------
1203
1204 //------------------------------------------------------------------------------
1205 void vvMainWindow::PopupRegisterForm(bool checkCanPush)
1206 {
1207   vvRegisterForm* registerForm = new vvRegisterForm(QUrl("http://www.creatis.insa-lyon.fr/~dsarrut/vvregister/write.php"), getVVSettingsPath(), getSettingsOptionFormat());
1208   if(!checkCanPush) {
1209     registerForm->show();
1210   } else {
1211     if(registerForm->canPush()) {
1212       registerForm->show();
1213       registerForm->acquitPushed();//too bad if there is not internet connection anymore.
1214     }
1215   }
1216 }
1217 //------------------------------------------------------------------------------
1218
1219 //------------------------------------------------------------------------------
1220 void vvMainWindow::ShowHelpDialog()
1221 {
1222   help_dialog->show();
1223 }
1224 //------------------------------------------------------------------------------
1225
1226 //------------------------------------------------------------------------------
1227 void vvMainWindow::ChangeViewMode()
1228 {
1229   typedef struct _SIZE{
1230     QSplitter* splitter;
1231     QList<int> size1, size2;
1232     int cols[3];
1233   }SplitterSize;
1234   SplitterSize sizes[4];
1235   sizes[0].splitter = OSplitter;
1236   sizes[0].size1.push_back(1);
1237   sizes[0].size1.push_back(0);
1238   sizes[0].size2.push_back(1);
1239   sizes[0].size2.push_back(0);
1240   sizes[0].cols[0] = 2;
1241   sizes[0].cols[1] = 3;
1242   sizes[0].cols[2] = 4;
1243
1244   sizes[1].splitter = ESplitter;
1245   sizes[1].size1.push_back(0);
1246   sizes[1].size1.push_back(1);
1247   sizes[1].size2.push_back(1);
1248   sizes[1].size2.push_back(0);
1249   sizes[1].cols[0] = 1;
1250   sizes[1].cols[1] = 3;
1251   sizes[1].cols[2] = 4;
1252
1253   sizes[2].splitter = OSplitter;
1254   sizes[2].size1.push_back(1);
1255   sizes[2].size1.push_back(0);
1256   sizes[2].size2.push_back(0);
1257   sizes[2].size2.push_back(1);
1258   sizes[2].cols[0] = 1;
1259   sizes[2].cols[1] = 2;
1260   sizes[2].cols[2] = 4;
1261
1262   sizes[3].splitter = ESplitter;
1263   sizes[3].size1.push_back(0);
1264   sizes[3].size1.push_back(1);
1265   sizes[3].size2.push_back(0);
1266   sizes[3].size2.push_back(1);
1267   sizes[3].cols[0] = 1;
1268   sizes[3].cols[1] = 2;
1269   sizes[3].cols[2] = 3;
1270   
1271   int slicer = mSlicerManagers[mCurrentPickedImageIndex]->GetSelectedSlicer();
1272   if (viewMode == 1) {
1273     if (slicer >= 0) {
1274       viewMode = 0;
1275       splitter_3->setSizes(sizes[slicer].size1);
1276       sizes[slicer].splitter->setSizes(sizes[slicer].size2);
1277       DataTree->setColumnHidden(sizes[slicer].cols[0],1);
1278       DataTree->setColumnHidden(sizes[slicer].cols[1],1);
1279       DataTree->setColumnHidden(sizes[slicer].cols[2],1);
1280     }
1281   } else {
1282     QList<int> size;
1283     if (slicer >= 0) {
1284       viewMode = 1;
1285       size.push_back(1);
1286       size.push_back(1);
1287       splitter_3->setSizes(size);
1288       sizes[slicer].splitter->setSizes(size);
1289       DataTree->setColumnHidden(sizes[slicer].cols[0],0);
1290       DataTree->setColumnHidden(sizes[slicer].cols[1],0);
1291       DataTree->setColumnHidden(sizes[slicer].cols[2],0);
1292     }
1293   }
1294   UpdateRenderWindows();
1295   /*
1296   ** I don't know why but for both resized QVTKWidget we also need to render
1297   ** the associated Slicer to redraw crosses.
1298   */
1299   for (unsigned int i = 0; i < mSlicerManagers.size(); i++) {
1300 //     if (DataTree->topLevelItem(i)->data(COLUMN_UL_VIEW,Qt::CheckStateRole).toInt() > 1)
1301       mSlicerManagers[i]->GetSlicer(0)->Render();
1302       mSlicerManagers[i]->GetSlicer(1)->Render();
1303 //     if (DataTree->topLevelItem(i)->data(COLUMN_DL_VIEW,Qt::CheckStateRole).toInt() > 1)
1304       mSlicerManagers[i]->GetSlicer(2)->Render();
1305       mSlicerManagers[i]->GetSlicer(3)->Render();
1306   }
1307 }
1308 //------------------------------------------------------------------------------
1309
1310 //------------------------------------------------------------------------------
1311 QString vvMainWindow::GetSizeInBytes(unsigned long size)
1312 {
1313   QString result = "";// QString::number(size);
1314   //result += " bytes (";
1315   if (size > 1000000000) {
1316     size /= 1000000000;
1317     result += QString::number(size);
1318     result += "Gb";//)";
1319   } else if (size > 1000000) {
1320     size /= 1000000;
1321     result += QString::number(size);
1322     result += "Mb";//)";
1323   } else if (size > 1000) {
1324     size /= 1000;
1325     result += QString::number(size);
1326     result += "kb";//)";
1327   }
1328   return result;
1329 }
1330 //------------------------------------------------------------------------------
1331
1332 //------------------------------------------------------------------------------
1333 QString vvMainWindow::Get4x4MatrixDoubleAsString(vtkSmartPointer<vtkMatrix4x4> matrix, const int precision)
1334 {
1335   std::ostringstream strmatrix;
1336
1337   // Figure out the number of digits of the integer part of the largest absolute value
1338   // for each column
1339   unsigned width[4];
1340   for (unsigned int j = 0; j < 4; j++){
1341     double absmax = 0.;
1342     for (unsigned int i = 0; i < 4; i++)
1343       absmax = std::max(absmax, vnl_math_abs(matrix->GetElement(i, j)));
1344     unsigned ndigits = (unsigned)std::max(0.,std::log10(absmax))+1;
1345     width[j] = precision+ndigits+3;
1346   }
1347
1348   // Output with correct width, aligned to the right
1349   for (unsigned int i = 0; i < 4; i++) {
1350     for (unsigned int j = 0; j < 4; j++) {
1351       strmatrix.setf(ios::fixed,ios::floatfield);
1352       strmatrix.precision(precision);
1353       strmatrix.fill(' ');
1354       strmatrix.width(width[j]);
1355       strmatrix << std::right << matrix->GetElement(i, j);
1356     }
1357     strmatrix << std::endl;
1358   }
1359   QString result = strmatrix.str().c_str();
1360   return result;
1361 }
1362 //------------------------------------------------------------------------------
1363
1364 //------------------------------------------------------------------------------
1365 QString vvMainWindow::GetVectorDoubleAsString(std::vector<double> vectorDouble)
1366 {
1367   QString result;
1368   for (unsigned int i= 0; i < vectorDouble.size(); i++) {
1369     if (i != 0)
1370       result += " ";
1371     result += QString::number(vectorDouble[i]);
1372   }
1373   return result;
1374 }
1375 //------------------------------------------------------------------------------
1376
1377 //------------------------------------------------------------------------------
1378 QString vvMainWindow::GetVectorIntAsString(std::vector<int> vectorInt)
1379 {
1380   QString result;
1381   for (unsigned int i= 0; i < vectorInt.size(); i++) {
1382     if (i != 0)
1383       result += " ";
1384     result += QString::number(vectorInt[i]);
1385   }
1386   return result;
1387 }
1388 //------------------------------------------------------------------------------
1389
1390 //------------------------------------------------------------------------------
1391 int vvMainWindow::GetSlicerIndexFromItem(QTreeWidgetItem* item)
1392 {
1393   QString id = item->data(COLUMN_IMAGE_NAME,Qt::UserRole).toString();
1394   for (int i = 0; i < DataTree->topLevelItemCount(); i++) {
1395     if (DataTree->topLevelItem(i)->data(COLUMN_IMAGE_NAME,Qt::UserRole).toString() == id)
1396       return i;
1397   }
1398   return -1;
1399 }
1400 //------------------------------------------------------------------------------
1401
1402 //------------------------------------------------------------------------------
1403 QTreeWidgetItem* vvMainWindow::GetItemFromSlicerManager(vvSlicerManager* sm)
1404 {
1405   QString id = sm->GetId().c_str();
1406   for (int i = 0; i < DataTree->topLevelItemCount(); i++) {
1407     if (DataTree->topLevelItem(i)->data(COLUMN_IMAGE_NAME,Qt::UserRole).toString() == id)
1408       return DataTree->topLevelItem(i);
1409   }
1410   return NULL;
1411 }
1412 //------------------------------------------------------------------------------
1413
1414 //------------------------------------------------------------------------------
1415 void vvMainWindow::DisplayChanged(QTreeWidgetItem *clickedItem, int column)
1416 {
1417   if ( column >= COLUMN_CLOSE_IMAGE || column <= 0)
1418     return;
1419
1420   // Get parent information (might be the same item)
1421   int slicerManagerIndex = GetSlicerIndexFromItem(clickedItem);
1422   QTreeWidgetItem* clickedParentItem = DataTree->topLevelItem(slicerManagerIndex);
1423   vvSlicer* clickedSlicer = mSlicerManagers[slicerManagerIndex]->GetSlicer(column-1);
1424
1425   // Go over the complete item tree (only 2 levels, parents and children)
1426   for (unsigned int i = 0; i < mSlicerManagers.size(); i++) {
1427     // Trick to avoid redoing twice the job for a key (sr)
1428     mSlicerManagers[i]->GetSlicer(column-1)->GetRenderWindow()->GetInteractor()->SetKeySym("Crap");
1429
1430     QTreeWidgetItem* currentParentItem = DataTree->topLevelItem(i);
1431     if(currentParentItem != clickedParentItem) {
1432       // Not the branch of the clicked item, uncheck all
1433
1434       // Parent
1435       currentParentItem->setData(column,Qt::CheckStateRole, 0);
1436       mSlicerManagers[i]->UpdateSlicer(column-1, false);
1437
1438       // Children
1439       for (int iChild = 0; iChild < currentParentItem->childCount(); iChild++) {
1440         currentParentItem->child(iChild)->setData(column,Qt::CheckStateRole, 0);
1441       }
1442     }
1443     else {
1444       // Branch of the clicked one: get check status from actor visibility in slicer
1445       // and toggle the clicked one
1446
1447       // Parent
1448       bool vis = clickedSlicer->GetActorVisibility("image", 0);
1449       bool draw = clickedSlicer->GetRenderer()->GetDraw();
1450
1451       // Update slicer (after getting visibility)
1452       mSlicerManagers[slicerManagerIndex]->UpdateSlicer(column-1, true);
1453       mSlicerManagers[slicerManagerIndex]->UpdateInfoOnCursorPosition(column-1);
1454       DisplaySliders(slicerManagerIndex, column-1);
1455       if(clickedParentItem == clickedItem) {
1456         // Toggle
1457         vis = !draw || !vis;
1458       }
1459       clickedSlicer->SetActorVisibility("image", 0, vis);
1460       clickedParentItem->setData(column, Qt::CheckStateRole, vis?2:0);
1461
1462       // Children
1463       std::map<std::string, int> actorTypeCounts;      
1464       for (int iChild = 0; iChild < clickedParentItem->childCount(); iChild++) {
1465         QTreeWidgetItem* currentChildItem = clickedParentItem->child(iChild);
1466         std::string actorType = currentChildItem->data(1,Qt::UserRole).toString().toStdString();
1467         vis = clickedSlicer->GetActorVisibility(actorType, actorTypeCounts[actorType]);
1468         if(currentChildItem == clickedItem) {
1469           // Toggle or force visibility if it was not on this branch so far
1470           vis = !draw || !vis;
1471           clickedSlicer->SetActorVisibility(actorType, actorTypeCounts[actorType], vis);
1472         }
1473         currentChildItem->setData(column, Qt::CheckStateRole, vis?2:0);
1474         actorTypeCounts[actorType]++;
1475       }
1476     }
1477   }
1478
1479   clickedSlicer->Render();
1480 }
1481 //------------------------------------------------------------------------------
1482
1483 void vvMainWindow::InitSlicers()
1484 {
1485   if (mSlicerManagers.size()) {
1486     mSlicerManagers.back()->GenerateDefaultLookupTable();
1487
1488     mSlicerManagers.back()->SetSlicerWindow(0,NOViewWidget->GetRenderWindow());
1489     mSlicerManagers.back()->SetSlicerWindow(1,NEViewWidget->GetRenderWindow());
1490     mSlicerManagers.back()->SetSlicerWindow(2,SOViewWidget->GetRenderWindow());
1491     mSlicerManagers.back()->SetSlicerWindow(3,SEViewWidget->GetRenderWindow());
1492   }
1493 }
1494
1495 //------------------------------------------------------------------------------
1496 void vvMainWindow::InitDisplay()
1497 {
1498   if (mSlicerManagers.size()) {
1499     //BE CAREFUL : this is absolutely necessary to set the interactor style
1500     //in order to have the same style instanciation for all SlicerManagers in
1501     // a same window
1502     for (int j = 0; j < 4; j++) {
1503       vvInteractorStyleNavigator* style = vvInteractorStyleNavigator::New();
1504       style->SetAutoAdjustCameraClippingRange(1);
1505       bool AlreadySelected = false;
1506       for (int i = 0; i < DataTree->topLevelItemCount(); i++) {
1507         mSlicerManagers[i]->SetInteractorStyleNavigator(j,style);
1508
1509         //select the image only if previous are not selected
1510         if (DataTree->topLevelItem(i)->data(j+1,Qt::CheckStateRole).toInt() > 1) {
1511           mSlicerManagers[i]->UpdateSlicer(j,1);
1512           AlreadySelected = true;
1513         } else if (i == DataTree->topLevelItemCount()-1 && !AlreadySelected) {
1514           if (DataTree->selectedItems().size() == 0)
1515             DataTree->topLevelItem(i)->setSelected(1);
1516           DataTree->topLevelItem(i)->setData(j+1,Qt::CheckStateRole,2);
1517           mSlicerManagers[i]->UpdateSlicer(j,1);
1518           DisplaySliders(i,j);
1519         } else {
1520           DataTree->topLevelItem(i)->setData(j+1,Qt::CheckStateRole,0);
1521           mSlicerManagers[i]->UpdateSlicer(j,0);
1522         }
1523       }
1524       style->Delete();
1525     }
1526   }
1527 }
1528 //------------------------------------------------------------------------------
1529
1530 //------------------------------------------------------------------------------
1531 void vvMainWindow::DisplaySliders(int slicer, int window)
1532 {
1533   if(!mSlicerManagers[slicer]->GetSlicer(window)->GetRenderer()->GetDraw())
1534     return;
1535
1536   int range[2];
1537   mSlicerManagers[slicer]->GetSlicer(window)->GetSliceRange(range);
1538   int position = mSlicerManagers[slicer]->GetSlicer(window)->GetSlice();
1539   if (range[1]>0)
1540     verticalSliders[window]->show();
1541   else
1542     verticalSliders[window]->hide();
1543   verticalSliders[window]->setRange(range[0],range[1]);
1544   verticalSliders[window]->setValue(position);
1545
1546   int tRange[2];
1547   tRange[0] = 0;
1548   tRange[1] = mSlicerManagers[slicer]->GetSlicer(window)->GetTMax();
1549   if (tRange[1]>0)
1550     horizontalSliders[window]->show();
1551   else
1552     horizontalSliders[window]->hide();
1553   horizontalSliders[window]->setRange(tRange[0],tRange[1]);
1554   int tPosition = mSlicerManagers[slicer]->GetSlicer(window)->GetMaxCurrentTSlice();
1555   horizontalSliders[window]->setValue(tPosition);
1556 }
1557 //------------------------------------------------------------------------------
1558
1559 //------------------------------------------------------------------------------
1560 void vvMainWindow::CloseImage(QTreeWidgetItem* item, int column)
1561 {
1562   int index = GetSlicerIndexFromItem(item);
1563
1564   if (DataTree->topLevelItem(index) != item) {
1565     QString warning = "Do you really want to close the overlay : ";
1566     warning += item->data(COLUMN_IMAGE_NAME,Qt::DisplayRole).toString();
1567     QMessageBox msgBox(QMessageBox::Warning, tr("Close Overlay"),
1568                        warning, 0, this);
1569     msgBox.addButton(tr("Close"), QMessageBox::AcceptRole);
1570     msgBox.addButton(tr("Cancel"), QMessageBox::RejectRole);
1571     if (msgBox.exec() == QMessageBox::AcceptRole) {
1572       std::string overlay_type=item->data(1,Qt::UserRole).toString().toStdString();
1573       int overlay_index=0;
1574       for (int child = 0; child < DataTree->topLevelItem(index)->childCount(); child++) {
1575         if (DataTree->topLevelItem(index)->\
1576             child(child)->data(1,Qt::UserRole).toString().toStdString() == overlay_type)
1577           overlay_index++;
1578         if (DataTree->topLevelItem(index)->child(child) == item) break;
1579       }
1580       mSlicerManagers[index]->RemoveActor(overlay_type, overlay_index-1);
1581       mSlicerManagers[index]->SetColorMap(0);
1582       DataTree->topLevelItem(index)->takeChild(DataTree->topLevelItem(index)->indexOfChild(item));
1583       mSlicerManagers[index]->Render();
1584     }
1585   } else if (DataTree->topLevelItemCount() <= 1) {
1586     QString warning = "Do you really want to close the image : ";
1587     warning += item->data(COLUMN_IMAGE_NAME,Qt::DisplayRole).toString();
1588     warning += "\nThis is the last image, you're about to close vv !!!";
1589     QMessageBox msgBox(QMessageBox::Warning, tr("Close Image"),
1590                        warning, 0, this);
1591     msgBox.addButton(tr("Close vv"), QMessageBox::AcceptRole);
1592     msgBox.addButton(tr("Cancel"), QMessageBox::RejectRole);
1593     if (msgBox.exec() == QMessageBox::AcceptRole) {
1594       this->close();
1595     }
1596   } else {
1597     QString warning = "Do you really want to close the image : ";
1598     warning += item->data(COLUMN_IMAGE_NAME,Qt::DisplayRole).toString();
1599     QMessageBox msgBox(QMessageBox::Warning, tr("Close Image"),
1600                        warning, 0, this);
1601     msgBox.addButton(tr("Close"), QMessageBox::AcceptRole);
1602     msgBox.addButton(tr("Cancel"), QMessageBox::RejectRole);
1603     if (msgBox.exec() == QMessageBox::AcceptRole) {
1604
1605       // Tell tools that we close an image
1606       emit AnImageIsBeingClosed(mSlicerManagers[index]);
1607
1608       std::vector<vvSlicerManager*>::iterator Manageriter = mSlicerManagers.begin();
1609       DataTree->takeTopLevelItem(index);
1610       for (int i = 0; i < index; i++) {
1611         Manageriter++;
1612       }
1613       linkPanel->removeImage(index);
1614       mSlicerManagers[index]->RemoveActors();
1615       delete mSlicerManagers[index];
1616       mSlicerManagers.erase(Manageriter);
1617
1618       //
1619       InitDisplay();
1620     }
1621   }
1622   ImageInfoChanged();
1623 }
1624 //------------------------------------------------------------------------------
1625
1626 //------------------------------------------------------------------------------
1627 void vvMainWindow::ReloadImage(QTreeWidgetItem* item, int column)
1628 {
1629   // int index = GetSlicerIndexFromItem(item);
1630   //   QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
1631   //   if (item->data(1,Qt::UserRole).toString() == "vector")
1632   //     mSlicerManagers[index]->ReloadVF();
1633   //   else
1634   //     mSlicerManagers[index]->Reload();
1635
1636   //   QApplication::restoreOverrideCursor();
1637   int index = GetSlicerIndexFromItem(item);
1638   QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
1639   QString role=item->data(1,Qt::UserRole).toString();
1640   if ( role == "vector"){
1641     mSlicerManagers[index]->ReloadVF();
1642   }
1643   else if (role == "overlay"){
1644     mSlicerManagers[index]->ReloadOverlay();
1645   }
1646   else if (role == "fusion"){
1647     mSlicerManagers[index]->ReloadFusion();
1648   }
1649   else if (role == "fusionSequence"){
1650     mSlicerManagers[index]->ReloadFusionSequence(); //same as for standard fusion
1651   }
1652   else{
1653     mSlicerManagers[index]->Reload();
1654   }
1655   // Update view and info
1656   ImageInfoChanged();
1657   mSlicerManagers[index]->Render();
1658   QApplication::restoreOverrideCursor();
1659 }
1660 //------------------------------------------------------------------------------
1661
1662 //------------------------------------------------------------------------------
1663 void vvMainWindow::MousePositionChanged(int visibility,double x, double y, double z, double X, double Y, double Z , double value)
1664 {
1665   infoPanel->setCurrentInfo(visibility,x,y,z,X,Y,Z,value);
1666 }
1667 //------------------------------------------------------------------------------
1668
1669 //------------------------------------------------------------------------------
1670 void vvMainWindow::VectorChanged(int visibility,double x, double y, double z, double value)
1671 {
1672   overlayPanel->getCurrentVectorInfo(visibility,x,y,z,value);
1673 }
1674 //------------------------------------------------------------------------------
1675
1676 //------------------------------------------------------------------------------
1677 void vvMainWindow::OverlayChanged(int visibility, double valueOver, double valueRef)
1678 {
1679   overlayPanel->getCurrentOverlayInfo(visibility,valueOver, valueRef);
1680 }
1681 //------------------------------------------------------------------------------
1682
1683 //------------------------------------------------------------------------------
1684 void vvMainWindow::FusionChanged(int visibility, double value)
1685 {
1686   overlayPanel->getCurrentFusionInfo(visibility,value);
1687 }
1688 //------------------------------------------------------------------------------
1689
1690 //------------------------------------------------------------------------------
1691 void vvMainWindow::WindowLevelChanged()
1692 {
1693   // Base image
1694   int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]);
1695   if(index==-1) return;
1696   windowSpinBox->setValue(mSlicerManagers[index]->GetColorWindow());
1697   levelSpinBox->setValue(mSlicerManagers[index]->GetColorLevel());
1698   colorMapComboBox->setCurrentIndex(mSlicerManagers[index]->GetColorMap());
1699   presetComboBox->setCurrentIndex(mSlicerManagers[index]->GetPreset());
1700
1701   // Overlay image
1702   if (mSlicerManagers[index]->GetSlicer(0)->GetOverlay())
1703     overlayPanel->getOverlayProperty(mSlicerManagers[index]->GetOverlayColor(),
1704                                      mSlicerManagers[index]->GetLinkOverlayWindowLevel(),
1705                                      mSlicerManagers[index]->GetOverlayColorWindow(),
1706                                      mSlicerManagers[index]->GetOverlayColorLevel());
1707   else
1708     overlayPanel->getOverlayProperty(-1,0,0.,0.);
1709
1710   // Fusion & SequenceFusion image
1711   if (mSlicerManagers[index]->GetSlicer(0)->GetFusion()) {
1712           overlayPanel->getFusionProperty(mSlicerManagers[index]->GetFusionOpacity(),
1713                   mSlicerManagers[index]->GetFusionThresholdOpacity(),
1714                   mSlicerManagers[index]->GetFusionColorMap(),
1715                   mSlicerManagers[index]->GetFusionWindow(),
1716                   mSlicerManagers[index]->GetFusionLevel());
1717           overlayPanel->getFusionSequenceProperty(mSlicerManagers[index]->GetFusionSequenceFrameIndex(),
1718                   mSlicerManagers[index]->GetFusionSequenceSpatialSyncFlag(), 
1719                   mSlicerManagers[index]->GetFusionSequenceNbFrames());
1720   }
1721   else if ( mSlicerManagers[index]->GetFusionSequenceIndexOfLinkedManager()>=0 ) {
1722           //if the image is involved in a fusion sequence, preserve the overlay panel!
1723           int ind = mSlicerManagers[index]->GetFusionSequenceIndexOfLinkedManager();
1724           overlayPanel->getFusionProperty(mSlicerManagers[index]->GetFusionOpacity(),
1725                   mSlicerManagers[ind]->GetFusionThresholdOpacity(),
1726                   mSlicerManagers[ind]->GetFusionColorMap(),
1727                   mSlicerManagers[ind]->GetFusionWindow(),
1728                   mSlicerManagers[ind]->GetFusionLevel());
1729           overlayPanel->getFusionSequenceProperty(mSlicerManagers[ind]->GetFusionSequenceFrameIndex(),
1730                   mSlicerManagers[ind]->GetFusionSequenceSpatialSyncFlag(), 
1731                   mSlicerManagers[ind]->GetFusionSequenceNbFrames());
1732   }
1733   else
1734   {
1735           overlayPanel->getFusionProperty(-1, -1, -1, -1, -1);
1736           overlayPanel->getFusionSequenceProperty(-1, false, 0);
1737   }
1738 }
1739 //------------------------------------------------------------------------------
1740
1741 //------------------------------------------------------------------------------
1742 void vvMainWindow::WindowLevelEdited()
1743 {
1744   presetComboBox->setCurrentIndex(6);
1745   UpdateWindowLevel();
1746 }
1747 //------------------------------------------------------------------------------
1748
1749 //------------------------------------------------------------------------------
1750 void vvMainWindow::SetWindowLevel(double w, double l)
1751 {
1752   windowSpinBox->setValue(w);
1753   levelSpinBox->setValue(l);
1754   presetComboBox->setCurrentIndex(6);
1755   colorMapComboBox->setCurrentIndex(0);
1756   UpdateWindowLevel();
1757 }
1758 //------------------------------------------------------------------------------
1759
1760 //------------------------------------------------------------------------------
1761 void vvMainWindow::UpdateWindowLevel()
1762 {
1763   if (DataTree->selectedItems().size()) {
1764     if (presetComboBox->currentIndex() == 7) //For ventilation
1765       colorMapComboBox->setCurrentIndex(5);
1766     int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]);
1767     mSlicerManagers[index]->SetColorWindow(windowSpinBox->value());
1768     mSlicerManagers[index]->SetColorLevel(levelSpinBox->value());
1769     mSlicerManagers[index]->SetPreset(presetComboBox->currentIndex());
1770     mSlicerManagers[index]->Render();
1771     WindowLevelChanged();
1772   }
1773 }
1774 //------------------------------------------------------------------------------
1775
1776 //------------------------------------------------------------------------------
1777 void vvMainWindow::UpdateSlicingPreset()
1778 {
1779   if (DataTree->selectedItems().size()) {
1780     int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]);
1781     mSlicerManagers[index]->SetSlicingPreset(vvSlicerManager::SlicingPresetType(slicingPresetComboBox->currentIndex()));
1782   }
1783 }
1784 //------------------------------------------------------------------------------
1785
1786 //------------------------------------------------------------------------------
1787 void vvMainWindow::UpdateColorMap()
1788 {
1789   if (DataTree->selectedItems().size()) {
1790     int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]);
1791     mSlicerManagers[index]->SetColorMap(colorMapComboBox->currentIndex());
1792     mSlicerManagers[index]->Render();
1793   }
1794 }
1795 //------------------------------------------------------------------------------
1796 void vvMainWindow::SwitchWindowLevel()
1797 {
1798   int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]);
1799   int window = mSlicerManagers[index]->GetColorWindow();
1800   presetComboBox->setCurrentIndex(6);
1801   windowSpinBox->setValue(-window);
1802   UpdateWindowLevel();
1803 }
1804 //------------------------------------------------------------------------------
1805
1806 //------------------------------------------------------------------------------
1807 void vvMainWindow::ApplyWindowLevelToAllImages()
1808 {
1809   int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]);
1810   if(index==-1) return;
1811   double window = mSlicerManagers[index]->GetColorWindow();
1812   double level = mSlicerManagers[index]->GetColorLevel();
1813
1814   for (unsigned int i = 0; i < mSlicerManagers.size(); i++) {
1815     if (mSlicerManagers[i] == NULL)
1816       continue;
1817     mSlicerManagers[i]->SetColorWindow(window);
1818     mSlicerManagers[i]->SetColorLevel(level);
1819     mSlicerManagers[i]->SetPreset(6);
1820     mSlicerManagers[i]->Render();
1821   }
1822 }
1823 //------------------------------------------------------------------------------
1824
1825 //------------------------------------------------------------------------------
1826 void vvMainWindow::ApplyWindowToSetOfImages(double window, unsigned int indexMin, unsigned int indexMax)
1827 {
1828   for (unsigned int i = indexMin; i <= indexMax && i < mSlicerManagers.size(); i++) {
1829     if (mSlicerManagers[i] == NULL)
1830       continue;
1831     mSlicerManagers[i]->SetColorWindow(window);
1832     mSlicerManagers[i]->SetPreset(6);
1833     mSlicerManagers[i]->Render();
1834   }
1835 }
1836 //------------------------------------------------------------------------------
1837
1838 //------------------------------------------------------------------------------
1839 void vvMainWindow::ApplyLevelToSetOfImages(double level, unsigned int indexMin, unsigned int indexMax)
1840 {
1841   for (unsigned int i = indexMin; i <= indexMax && i < mSlicerManagers.size(); i++) {
1842     if (mSlicerManagers[i] == NULL)
1843       continue;
1844     mSlicerManagers[i]->SetColorLevel(level);
1845     mSlicerManagers[i]->SetPreset(6);
1846     mSlicerManagers[i]->Render();
1847   }
1848 }
1849 //------------------------------------------------------------------------------
1850
1851 //------------------------------------------------------------------------------
1852 void vvMainWindow::UpdateLinkManager(std::string id, int slicer, double x, double y, double z, int temps)
1853 {
1854   for (unsigned int i = 0; i < mSlicerManagers.size(); i++) {
1855     if (mSlicerManagers[i]->GetId() == id) {
1856       //mSlicerManagers[i]->SetTSlice(temps);
1857                 if (temps<0) { //for fusionSequence, special input used to avoid any automatic time synchronization...
1858                         mSlicerManagers[i]->GetSlicer(slicer)->SetCurrentPosition( x,y,z, mSlicerManagers[i]->GetSlicer(slicer)->GetTSlice() );
1859                 }
1860         else mSlicerManagers[i]->GetSlicer(slicer)->SetCurrentPosition(x,y,z,temps);
1861       mSlicerManagers[i]->UpdateViews(0,slicer);
1862       break;
1863     }
1864   }
1865 }
1866 //------------------------------------------------------------------------------
1867
1868 //------------------------------------------------------------------------------
1869 void vvMainWindow::UpdateLinkedNavigation(std::string id, vvSlicerManager * sm, vvSlicer* refSlicer)
1870 {
1871   for (unsigned int i = 0; i < mSlicerManagers.size(); i++) {
1872     if (id == mSlicerManagers[i]->GetId()) {
1873       mSlicerManagers[i]->UpdateLinkedNavigation(refSlicer);
1874     }
1875   }
1876 }
1877 //------------------------------------------------------------------------------
1878
1879 //------------------------------------------------------------------------------
1880 void vvMainWindow::ShowContextMenu(QPoint point)
1881 {
1882   if (!DataTree->selectedItems().size()) {
1883     contextActions[1]->setEnabled(0);
1884     contextActions[2]->setEnabled(0);
1885     contextActions[3]->setEnabled(0);
1886     contextActions[4]->setEnabled(0);
1887     contextActions[5]->setEnabled(0);
1888     contextActions[6]->setEnabled(0);
1889   } else {
1890     int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]);
1891     contextActions[1]->setEnabled(1);
1892     contextActions[2]->setEnabled(
1893       DataTree->itemWidget(DataTree->selectedItems()[0],
1894                            COLUMN_RELOAD_IMAGE)->isEnabled());
1895     contextActions[3]->setEnabled(1);
1896     contextActions[5]->setEnabled(1);
1897     contextActions[6]->setEnabled(1);
1898
1899     if (mSlicerManagers[index]->GetDimension() < 3)
1900       contextActions[4]->setEnabled(0);
1901     else
1902       contextActions[4]->setEnabled(1);
1903   }
1904   contextMenu.exec(QCursor::pos());
1905 }
1906 //------------------------------------------------------------------------------
1907
1908 //------------------------------------------------------------------------------
1909 void vvMainWindow::CloseImage()
1910 {
1911   CloseImage(DataTree->selectedItems()[0],0);
1912 }
1913 //------------------------------------------------------------------------------
1914
1915 //------------------------------------------------------------------------------
1916 void vvMainWindow::ReloadImage()
1917 {
1918   ReloadImage(DataTree->selectedItems()[0],0);
1919 }
1920 //------------------------------------------------------------------------------
1921
1922 //------------------------------------------------------------------------------
1923 void vvMainWindow::SelectOverlayImage()
1924 {
1925   int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]);
1926
1927   //check if one overlay image is added
1928   for (int child = 0; child < DataTree->topLevelItem(index)->childCount(); child++)
1929     if (DataTree->topLevelItem(index)->child(child)->data(1,Qt::UserRole).toString() == "overlay") {
1930       QString error = "Cannot add more than one compared image\n";
1931       error += "Please remove first ";
1932       error += DataTree->topLevelItem(index)->child(child)->data(COLUMN_IMAGE_NAME,Qt::DisplayRole).toString();
1933       QMessageBox::information(this,tr("Problem adding compared image !"),error);
1934       return;
1935     }
1936
1937   QString Extensions = EXTENSIONS;
1938   Extensions += ";;All Files (*)";
1939   QStringList files = QFileDialog::getOpenFileNames(this,tr("Load Overlay image"),mInputPathName,Extensions);
1940   if (files.isEmpty())
1941     return;
1942
1943   std::vector<std::string> vecFileNames;
1944   for (int i = 0; i < files.size(); i++) {
1945     vecFileNames.push_back(files[i].toStdString());
1946   }
1947   AddOverlayImage(index,vecFileNames,vvImageReader::IMAGE);
1948 }
1949 //------------------------------------------------------------------------------
1950
1951 //------------------------------------------------------------------------------
1952 void vvMainWindow::AddOverlayImage(int index, std::vector<std::string> fileNames, vvImageReader::LoadedImageType type)
1953 {
1954   QString file(fileNames[0].c_str());
1955   if (QFile::exists(file))
1956   {
1957     mInputPathName = itksys::SystemTools::GetFilenamePath(file.toStdString()).c_str();
1958     itk::ImageIOBase::Pointer reader = itk::ImageIOFactory::CreateImageIO(
1959         file.toStdString().c_str(), itk::ImageIOFactory::ReadMode);
1960     reader->SetFileName(fileNames[0].c_str());
1961     reader->ReadImageInformation();
1962     std::string component = reader->GetComponentTypeAsString(reader->GetComponentType());
1963     int dimension = reader->GetNumberOfDimensions();
1964     QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
1965     vvProgressDialog progress("Opening " + file.toStdString());
1966     qApp->processEvents();
1967
1968     std::string filename = itksys::SystemTools::GetFilenameWithoutExtension(file.toStdString()).c_str();
1969     if (mSlicerManagers[index]->SetOverlay(fileNames,dimension, component,type)) {
1970       //create an item in the tree with good settings
1971       QTreeWidgetItem *item = new QTreeWidgetItem();
1972       item->setData(0,Qt::UserRole,file.toStdString().c_str());
1973       item->setData(1,Qt::UserRole,tr("overlay"));
1974       QFileInfo fileinfo(file); //Do not show the path
1975       item->setData(COLUMN_IMAGE_NAME,Qt::DisplayRole,fileinfo.fileName());
1976       item->setToolTip(COLUMN_IMAGE_NAME, mSlicerManagers[index]->GetListOfAbsoluteFilePathInOneString("overlay").c_str());
1977       qApp->processEvents();
1978
1979       for (int j = 1; j <= 4; j++) {
1980         item->setData(j,Qt::CheckStateRole,DataTree->topLevelItem(index)->data(j,Qt::CheckStateRole));
1981       }
1982
1983       //Create the buttons for reload and close
1984       qApp->processEvents();
1985       QTreePushButton* cButton = new QTreePushButton;
1986       cButton->setItem(item);
1987       cButton->setColumn(COLUMN_CLOSE_IMAGE);
1988       cButton->setToolTip(tr("close image"));
1989       cButton->setIcon(QIcon(QString::fromUtf8(":/common/icons/exit.png")));
1990       connect(cButton,SIGNAL(clickedInto(QTreeWidgetItem*, int)),
1991           this,SLOT(CloseImage(QTreeWidgetItem*, int)));
1992
1993       QTreePushButton* rButton = new QTreePushButton;
1994       rButton->setItem(item);
1995       rButton->setColumn(COLUMN_RELOAD_IMAGE);
1996       rButton->setToolTip(tr("reload image"));
1997       rButton->setIcon(QIcon(QString::fromUtf8(":/common/icons/rotateright.png")));
1998       connect(rButton,SIGNAL(clickedInto(QTreeWidgetItem*, int)),
1999           this,SLOT(ReloadImage(QTreeWidgetItem*, int)));
2000
2001       DataTree->topLevelItem(index)->setExpanded(1);
2002       DataTree->topLevelItem(index)->addChild(item);
2003       DataTree->setItemWidget(item, COLUMN_CLOSE_IMAGE, cButton);
2004       DataTree->setItemWidget(item, COLUMN_RELOAD_IMAGE, rButton);
2005
2006       //set the id of the image
2007       QString id = DataTree->topLevelItem(index)->data(COLUMN_IMAGE_NAME,Qt::UserRole).toString();
2008       item->setData(COLUMN_IMAGE_NAME,Qt::UserRole,id.toStdString().c_str());
2009       UpdateTree();
2010       qApp->processEvents();
2011       ImageInfoChanged();
2012       QApplication::restoreOverrideCursor();
2013
2014       // Update the display to update, e.g., the sliders
2015       for(int i=0; i<4; i++)
2016         DisplaySliders(index, i);
2017     } else {
2018       QApplication::restoreOverrideCursor();
2019       QString error = "Cannot import the new image.\n";
2020       error += mSlicerManagers[index]->GetLastError().c_str();
2021       QMessageBox::information(this,tr("Problem reading image !"),error);
2022     }
2023     WindowLevelChanged();
2024   }
2025   else
2026     QMessageBox::information(this,tr("Problem reading Overlay !"),"File doesn't exist!");
2027 }
2028 //------------------------------------------------------------------------------
2029
2030
2031 //------------------------------------------------------------------------------
2032 void vvMainWindow::AddROI(int index, QString file)
2033 {
2034   /*
2035   // Get slice manager
2036
2037   // Load image
2038
2039   vvImageReader * mReader = new vvImageReader;
2040   mReader->SetInputFilename(filename.toStdString());
2041   mReader->Update(IMAGE);
2042   if (mReader->GetLastError().size() != 0) {
2043     std::cerr << "Error while reading " << filename.toStdString() << std::endl;
2044     QString error = "Cannot open file \n";
2045     error += mReader->GetLastError().c_str();
2046     QMessageBox::information(this,tr("Reading problem"),error);
2047     delete mReader;
2048     return;
2049   }
2050   vvImage::Pointer roi = mReader->GetOutput();
2051
2052   // Create roi in new tool
2053   vvToolStructureSetManager::AddImage(mCurrentSlicerManager, roi);
2054   */
2055 }
2056 //------------------------------------------------------------------------------
2057
2058 //------------------------------------------------------------------------------
2059 void vvMainWindow::SelectFusionImage()
2060 {
2061   int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]);
2062
2063   //check if one fusion image is added
2064   for (int child = 0; child < DataTree->topLevelItem(index)->childCount(); child++)
2065     if ( (DataTree->topLevelItem(index)->child(child)->data(1,Qt::UserRole).toString() == "fusion") ||
2066         (DataTree->topLevelItem(index)->child(child)->data(1,Qt::UserRole).toString() == "fusionSequence") ) {
2067       QString error = "Cannot add more than one fusion image\n";
2068       error += "Please remove first ";
2069       error += DataTree->topLevelItem(index)->child(child)->data(COLUMN_IMAGE_NAME,Qt::DisplayRole).toString();
2070       QMessageBox::information(this,tr("Problem adding fusion image !"),error);
2071       return;
2072     }
2073
2074   QString Extensions = EXTENSIONS;
2075   Extensions += ";;All Files (*)";
2076   QString file = QFileDialog::getOpenFileName(this,tr("Load Fusion image"),mInputPathName,Extensions);
2077   if (!file.isEmpty())
2078     AddFusionImage(index,file);
2079 }
2080 //------------------------------------------------------------------------------
2081
2082 //------------------------------------------------------------------------------
2083 void vvMainWindow::ResetTransformationToIdentity()
2084 {
2085   std::string actorType = DataTree->selectedItems()[0]->data(1,Qt::UserRole).toString().toStdString();
2086   int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]);
2087   mSlicerManagers[index]->ResetTransformationToIdentity(actorType);
2088   ImageInfoChanged();
2089 }
2090 //------------------------------------------------------------------------------
2091
2092 //------------------------------------------------------------------------------
2093 void vvMainWindow::AddFusionImage(int index, QString file)
2094 {
2095   if (QFile::exists(file))
2096   {
2097     mInputPathName = itksys::SystemTools::GetFilenamePath(file.toStdString()).c_str();
2098     itk::ImageIOBase::Pointer reader = itk::ImageIOFactory::CreateImageIO(
2099         file.toStdString().c_str(), itk::ImageIOFactory::ReadMode);
2100     reader->SetFileName(file.toStdString().c_str());
2101     reader->ReadImageInformation();
2102     std::string component = reader->GetComponentTypeAsString(reader->GetComponentType());
2103     if (reader) {
2104       QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
2105       vvProgressDialog progress("Opening fusion");
2106       qApp->processEvents();
2107
2108       std::string filename = itksys::SystemTools::GetFilenameWithoutExtension(file.toStdString()).c_str();
2109       if (mSlicerManagers[index]->SetFusion(file.toStdString(),
2110             reader->GetNumberOfDimensions(), component)) {
2111         //create an item in the tree with good settings
2112         QTreeWidgetItem *item = new QTreeWidgetItem();
2113         item->setData(0,Qt::UserRole,file.toStdString().c_str());
2114         item->setData(1,Qt::UserRole,tr("fusion"));
2115         QFileInfo fileinfo(filename.c_str()); //Do not show the path
2116         item->setData(COLUMN_IMAGE_NAME,Qt::DisplayRole,fileinfo.fileName());
2117         item->setToolTip(COLUMN_IMAGE_NAME, mSlicerManagers[index]->GetListOfAbsoluteFilePathInOneString("fusion").c_str());
2118         qApp->processEvents();
2119
2120         for (int j = 1; j <= 4; j++) {
2121           item->setData(j,Qt::CheckStateRole,DataTree->topLevelItem(index)->data(j,Qt::CheckStateRole));
2122         }
2123
2124         //Create the buttons for reload and close
2125         qApp->processEvents();
2126         QTreePushButton* cButton = new QTreePushButton;
2127         cButton->setItem(item);
2128         cButton->setColumn(COLUMN_CLOSE_IMAGE);
2129         cButton->setToolTip(tr("close image"));
2130         cButton->setIcon(QIcon(QString::fromUtf8(":/common/icons/exit.png")));
2131         connect(cButton,SIGNAL(clickedInto(QTreeWidgetItem*, int)),
2132             this,SLOT(CloseImage(QTreeWidgetItem*, int)));
2133
2134         QTreePushButton* rButton = new QTreePushButton;
2135         rButton->setItem(item);
2136         rButton->setColumn(COLUMN_RELOAD_IMAGE);
2137         rButton->setToolTip(tr("reload image"));
2138         rButton->setIcon(QIcon(QString::fromUtf8(":/common/icons/rotateright.png")));
2139         connect(rButton,SIGNAL(clickedInto(QTreeWidgetItem*, int)),
2140             this,SLOT(ReloadImage(QTreeWidgetItem*, int)));
2141
2142         DataTree->topLevelItem(index)->setExpanded(1);
2143         DataTree->topLevelItem(index)->addChild(item);
2144         DataTree->setItemWidget(item, COLUMN_CLOSE_IMAGE, cButton);
2145         DataTree->setItemWidget(item, COLUMN_RELOAD_IMAGE, rButton);
2146
2147         //set the id of the image
2148         QString id = DataTree->topLevelItem(index)->data(COLUMN_IMAGE_NAME,Qt::UserRole).toString();
2149         item->setData(COLUMN_IMAGE_NAME,Qt::UserRole,id.toStdString().c_str());
2150         UpdateTree();
2151         qApp->processEvents();
2152         ImageInfoChanged();
2153         QApplication::restoreOverrideCursor();
2154       } else {
2155         QApplication::restoreOverrideCursor();
2156         QString error = "Cannot import the new image.\n";
2157         error += mSlicerManagers[index]->GetLastError().c_str();
2158         QMessageBox::information(this,tr("Problem reading image !"),error);
2159       }
2160     } else {
2161       QString error = "Cannot import the new image.\n";
2162       QMessageBox::information(this,tr("Problem reading image !"),error);
2163     }
2164   }
2165   else
2166     QMessageBox::information(this,tr("Problem reading Fusion !"),"File doesn't exist!");
2167 }
2168 //------------------------------------------------------------------------------
2169
2170
2171 //------------------------------------------------------------------------------
2172 void vvMainWindow::OpenField()
2173 {
2174   int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]);
2175   //check if a vector field has already been added
2176   for (int child = 0; child < DataTree->topLevelItem(index)->childCount(); child++)
2177     if (DataTree->topLevelItem(index)->child(child)->data(1,Qt::UserRole).toString() == "vector") {
2178       QString error = "Cannot add more than one vector field\n";
2179       error += "Please remove first ";
2180       error += DataTree->topLevelItem(index)->child(child)->data(COLUMN_IMAGE_NAME,Qt::DisplayRole).toString();
2181       QMessageBox::information(this,tr("Problem adding vector field!"),error);
2182       return;
2183     }
2184
2185   QString Extensions = "Images ( *.mhd)";
2186   Extensions += ";;Images ( *.mha)";
2187   Extensions += ";;VF Images ( *.vf)";
2188   Extensions += ";;nii Images ( *.nii)";
2189   Extensions += ";;nrrd Images ( *.nrrd)";
2190   Extensions += ";;nhdr Images ( *.nhdr)";
2191   Extensions += ";;All Files (*)";
2192   QString file = QFileDialog::getOpenFileName(this,tr("Load deformation field"),mInputPathName,Extensions);
2193   if (!file.isEmpty())
2194     AddField(file,index);
2195 }
2196 //------------------------------------------------------------------------------
2197
2198
2199 //------------------------------------------------------------------------------
2200 void vvMainWindow::AddFieldEntry(QString filename,int index,bool from_disk)
2201 {
2202   //create an item in the tree with good settings
2203   QTreeWidgetItem *item = new QTreeWidgetItem();
2204   item->setData(0,Qt::UserRole,filename.toStdString().c_str());
2205   item->setData(1,Qt::UserRole,tr("vector"));
2206   QFileInfo fileinfo(filename); //Do not show the path
2207   item->setData(COLUMN_IMAGE_NAME,Qt::DisplayRole,fileinfo.fileName());
2208   item->setToolTip(COLUMN_IMAGE_NAME, mSlicerManagers[index]->GetListOfAbsoluteFilePathInOneString("vector").c_str());
2209   qApp->processEvents();
2210
2211   for (int j = 1; j <= 4; j++) {
2212     item->setData(j,Qt::CheckStateRole,DataTree->topLevelItem(index)->data(j,Qt::CheckStateRole));
2213   }
2214
2215   //Create the buttons for reload and close
2216   qApp->processEvents();
2217   QTreePushButton* cButton = new QTreePushButton;
2218   cButton->setItem(item);
2219   cButton->setColumn(COLUMN_CLOSE_IMAGE);
2220   cButton->setToolTip(tr("close vector field"));
2221   cButton->setIcon(QIcon(QString::fromUtf8(":/common/icons/exit.png")));
2222   connect(cButton,SIGNAL(clickedInto(QTreeWidgetItem*, int)),
2223           this,SLOT(CloseImage(QTreeWidgetItem*, int)));
2224
2225   QTreePushButton* rButton = new QTreePushButton;
2226   rButton->setItem(item);
2227   rButton->setColumn(COLUMN_RELOAD_IMAGE);
2228   rButton->setToolTip(tr("reload vector field"));
2229   rButton->setEnabled(from_disk);
2230   rButton->setIcon(QIcon(QString::fromUtf8(":/common/icons/rotateright.png")));
2231   connect(rButton,SIGNAL(clickedInto(QTreeWidgetItem*, int)),
2232           this,SLOT(ReloadImage(QTreeWidgetItem*, int)));
2233
2234   DataTree->topLevelItem(index)->setExpanded(1);
2235   DataTree->topLevelItem(index)->addChild(item);
2236   DataTree->setItemWidget(item, COLUMN_RELOAD_IMAGE, rButton);
2237   DataTree->setItemWidget(item, COLUMN_CLOSE_IMAGE, cButton);
2238
2239   //set the id of the image
2240   QString id = DataTree->topLevelItem(index)->data(COLUMN_IMAGE_NAME,Qt::UserRole).toString();
2241   item->setData(COLUMN_IMAGE_NAME,Qt::UserRole,id.toStdString().c_str());
2242   UpdateTree();
2243   qApp->processEvents();
2244   ImageInfoChanged();
2245   QApplication::restoreOverrideCursor();
2246 }
2247 //------------------------------------------------------------------------------
2248
2249
2250 //------------------------------------------------------------------------------
2251 void vvMainWindow::AddField(vvImage::Pointer vf,QString file,int index)
2252 {
2253   QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
2254   vvSlicerManager* imageManager = mSlicerManagers[index];
2255   if (imageManager->SetVF(vf,file.toStdString())) {
2256     AddFieldEntry(file,index,false);
2257   } else {
2258     QString error = "Cannot import the vector field for this image.\n";
2259     error += imageManager->GetLastError().c_str();
2260     QMessageBox::information(this,tr("Problem reading VF !"),error);
2261   }
2262   QApplication::restoreOverrideCursor();
2263 }
2264 //------------------------------------------------------------------------------
2265
2266
2267 //------------------------------------------------------------------------------
2268 void vvMainWindow::AddField(QString file,int index)
2269 {
2270   if (QFile::exists(file)) {
2271     mInputPathName = itksys::SystemTools::GetFilenamePath(file.toStdString()).c_str();
2272
2273     //init the progress events
2274     QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
2275     vvProgressDialog progress("Opening " + file.toStdString());
2276     qApp->processEvents();
2277
2278     //read the vector and put it in the current mSlicerManager
2279     vvSlicerManager* imageManager = mSlicerManagers[index];
2280     qApp->processEvents();
2281
2282     std::string filename = itksys::SystemTools::GetFilenameWithoutExtension(file.toStdString()).c_str();
2283     if (imageManager->SetVF(file.toStdString())) {
2284       imageManager->Render();
2285       AddFieldEntry(file,index,true);
2286     } else {
2287       QApplication::restoreOverrideCursor();
2288       QString error = "Cannot import the vector field for this image.\n";
2289       error += imageManager->GetLastError().c_str();
2290       QMessageBox::information(this,tr("Problem reading VF !"),error);
2291     }
2292   } else
2293     QMessageBox::information(this,tr("Problem reading VF !"),"File doesn't exist!");
2294
2295 }
2296 //------------------------------------------------------------------------------
2297
2298
2299 //------------------------------------------------------------------------------
2300 void vvMainWindow::SetVFProperty(int subsampling, int scale, int log, int width, double r, double g, double b)
2301 {
2302   int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]);
2303   if (mSlicerManagers[index]->GetSlicer(0)->GetVF()) {
2304     for (int i = 0; i < 4; i++) {
2305       mSlicerManagers[index]->GetSlicer(i)->SetVFSubSampling(subsampling);
2306       mSlicerManagers[index]->GetSlicer(i)->SetVFScale(scale);
2307       mSlicerManagers[index]->GetSlicer(i)->SetVFWidth(width);
2308       mSlicerManagers[index]->GetSlicer(i)->SetVFColor(r,g,b);
2309       if (log > 0)
2310         mSlicerManagers[index]->GetSlicer(i)->SetVFLog(1);
2311       else
2312         mSlicerManagers[index]->GetSlicer(i)->SetVFLog(0);
2313     }
2314   }
2315 }
2316 //------------------------------------------------------------------------------
2317
2318
2319 //------------------------------------------------------------------------------
2320 void vvMainWindow::SetOverlayProperty(int color, int linked, double window, double level)
2321 {
2322   int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]);
2323   if (mSlicerManagers[index]->GetSlicer(0)->GetOverlay()) {
2324     mSlicerManagers[index]->SetOverlayColor(color);
2325     mSlicerManagers[index]->SetColorMap(0);
2326     mSlicerManagers[index]->SetLinkOverlayWindowLevel(linked);
2327     mSlicerManagers[index]->SetOverlayColorWindow(window);
2328     mSlicerManagers[index]->SetOverlayColorLevel(level);
2329     mSlicerManagers[index]->Render();
2330   }
2331 }
2332 //------------------------------------------------------------------------------
2333
2334 //------------------------------------------------------------------------------
2335 void vvMainWindow::SetFusionProperty(int opacity, int thresOpacity, int colormap,double window, double level, bool showLegend)
2336 {
2337   int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]);
2338   if (mSlicerManagers[index]->GetSlicer(0)->GetFusion()) {
2339     mSlicerManagers[index]->SetFusionColorMap(colormap);
2340     mSlicerManagers[index]->SetFusionOpacity(opacity);
2341     mSlicerManagers[index]->SetFusionThresholdOpacity(thresOpacity);
2342     mSlicerManagers[index]->SetFusionWindow(window);
2343     mSlicerManagers[index]->SetFusionLevel(level);
2344     mSlicerManagers[index]->SetFusionShowLegend(showLegend);
2345     mSlicerManagers[index]->SetColorMap(0);
2346         mSlicerManagers[index]->Render();
2347   }
2348 }
2349 //------------------------------------------------------------------------------
2350
2351
2352 //------------------------------------------------------------------------------
2353 void vvMainWindow::SelectFusionSequence()
2354 {
2355   int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]);
2356   //check if one overlay image is added
2357   for (int child = 0; child < DataTree->topLevelItem(index)->childCount(); child++)
2358     if ( (DataTree->topLevelItem(index)->child(child)->data(1,Qt::UserRole).toString() == "fusion") ||
2359         (DataTree->topLevelItem(index)->child(child)->data(1,Qt::UserRole).toString() == "fusionSequence") ) {
2360       QString error = "Cannot add more than one compared image\n";
2361       error += "Please remove first ";
2362       error += DataTree->topLevelItem(index)->child(child)->data(COLUMN_IMAGE_NAME,Qt::DisplayRole).toString();
2363       QMessageBox::information(this,tr("Problem adding compared image !"),error);
2364       return;
2365     }
2366
2367   QString Extensions = EXTENSIONS;
2368   Extensions += ";;All Files (*)";
2369   QStringList files = QFileDialog::getOpenFileNames(this,tr("Load Overlay image sequence"),mInputPathName,Extensions);
2370   if (files.isEmpty())
2371     return;
2372
2373   std::vector<std::string> vecFileNames;
2374   for (int i = 0; i < files.size(); i++) {
2375     vecFileNames.push_back(files[i].toStdString());
2376   }
2377  
2378   AddFusionSequence(index,vecFileNames,vvImageReader::MERGEDWITHTIME);
2379 }
2380 //------------------------------------------------------------------------------
2381
2382 //------------------------------------------------------------------------------
2383 void vvMainWindow::AddFusionSequence(int index, std::vector<std::string> fileNames, vvImageReader::LoadedImageType type)
2384 {
2385         QString file(fileNames[0].c_str());
2386         if (QFile::exists(file))
2387         {
2388                 mInputPathName = itksys::SystemTools::GetFilenamePath(file.toStdString()).c_str();
2389                 itk::ImageIOBase::Pointer reader = itk::ImageIOFactory::CreateImageIO(
2390                                 file.toStdString().c_str(), itk::ImageIOFactory::ReadMode);
2391                 reader->SetFileName(fileNames[0].c_str());
2392                 reader->ReadImageInformation();
2393                 std::string component = reader->GetComponentTypeAsString(reader->GetComponentType());
2394                 int dimension = reader->GetNumberOfDimensions();
2395                 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
2396                 vvProgressDialog progress("Opening " + file.toStdString());
2397                 qApp->processEvents();
2398
2399                 std::string filename = itksys::SystemTools::GetFilenameWithoutExtension(file.toStdString()).c_str();
2400
2401                 if (mSlicerManagers[index]->SetFusionSequence(fileNames,dimension, component,type)) {
2402                         //create an item in the tree with good settings
2403                         QTreeWidgetItem *item = new QTreeWidgetItem();
2404                         item->setData(0,Qt::UserRole,file.toStdString().c_str());
2405                         item->setData(1,Qt::UserRole,tr("fusionSequence"));
2406
2407                         QFileInfo fileinfo(file); //Do not show the path
2408                         item->setData(COLUMN_IMAGE_NAME,Qt::DisplayRole,fileinfo.fileName());
2409                         item->setToolTip(COLUMN_IMAGE_NAME, mSlicerManagers[index]->GetListOfAbsoluteFilePathInOneString("fusionSequence").c_str());
2410                         qApp->processEvents();
2411                         for (int j = 1; j <= 4; j++) {
2412                                 item->setData(j,Qt::CheckStateRole,DataTree->topLevelItem(index)->data(j,Qt::CheckStateRole));
2413                         }
2414
2415                         //Create the buttons for reload and close
2416                         qApp->processEvents();
2417                         QTreePushButton* cButton = new QTreePushButton;
2418                         cButton->setItem(item);
2419                         cButton->setColumn(COLUMN_CLOSE_IMAGE);
2420                         cButton->setToolTip(tr("close image"));
2421                         cButton->setIcon(QIcon(QString::fromUtf8(":/common/icons/exit.png")));
2422                         connect(cButton,SIGNAL(clickedInto(QTreeWidgetItem*, int)),
2423                                         this,SLOT(CloseImage(QTreeWidgetItem*, int)));
2424
2425                         QTreePushButton* rButton = new QTreePushButton;
2426                         rButton->setItem(item);
2427                         rButton->setColumn(COLUMN_RELOAD_IMAGE);
2428                         rButton->setToolTip(tr("reload image"));
2429                         rButton->setIcon(QIcon(QString::fromUtf8(":/common/icons/rotateright.png")));
2430                         connect(rButton,SIGNAL(clickedInto(QTreeWidgetItem*, int)),
2431                                         this,SLOT(ReloadImage(QTreeWidgetItem*, int)));
2432
2433                         DataTree->topLevelItem(index)->setExpanded(1);
2434                         DataTree->topLevelItem(index)->addChild(item);
2435                         DataTree->setItemWidget(item, COLUMN_CLOSE_IMAGE, cButton);
2436                         DataTree->setItemWidget(item, COLUMN_RELOAD_IMAGE, rButton);
2437
2438                         //store the original transform matrix
2439                         int indexParent = GetSlicerIndexFromItem( DataTree->topLevelItem(index) );
2440                         mSlicerManagers[indexParent]->SetFusionSequenceMainTransformMatrix( mSlicerManagers[indexParent]->GetSlicer(0)->GetImage()->GetTransform()[0]->GetMatrix() );
2441
2442                         //set the id of the image
2443                         QString id = DataTree->topLevelItem(index)->data(COLUMN_IMAGE_NAME,Qt::UserRole).toString();
2444                         item->setData(COLUMN_IMAGE_NAME,Qt::UserRole,id.toStdString().c_str());
2445                         UpdateTree();
2446                         qApp->processEvents();
2447
2448                         ImageInfoChanged();
2449
2450                         QApplication::restoreOverrideCursor();
2451                         // Update the display to update, e.g., the sliders
2452                         for(int i=0; i<4; i++)
2453                                 DisplaySliders(index, i);
2454
2455
2456                         //TEST: also add the image as normal image, link it, and store its index in the SlicerManagersArray for tying it to the fusionSequence
2457                         LoadImages(fileNames, type);
2458                         //reset the transforms to identiy
2459                         for (unsigned i=0 ; i<mSlicerManagers.back()->GetImage()->GetTransform().size() ; i++) {
2460                                 mSlicerManagers.back()->GetImage()->GetTransform()[i]->Identity();
2461                                 mSlicerManagers.back()->GetImage()->GetTransform()[i]->Update();
2462                         }
2463
2464                         //automatically link both images...
2465                         AddLink(mSlicerManagers[indexParent]->GetId().c_str(), mSlicerManagers.back()->GetId().c_str(), false);
2466
2467                         //store the index ; this is also used as a flag to indicate that the images are involved in a fusionSequence...
2468                         //TODO: reset these when exiting the visualization mode (unloading one of the images)
2469                         mSlicerManagers[indexParent]->SetFusionSequenceIndexOfLinkedManager(mSlicerManagers.size()-1);
2470                         mSlicerManagers.back()->SetFusionSequenceIndexOfLinkedManager(indexParent);
2471
2472                 } else {
2473                         QApplication::restoreOverrideCursor();
2474                         QString error = "Cannot import the new image.\n";
2475                         error += mSlicerManagers[index]->GetLastError().c_str();
2476                         QMessageBox::information(this,tr("Problem reading image !"),error);
2477                 }
2478                 WindowLevelChanged();
2479         }
2480         else {
2481                 QMessageBox::information(this,tr("Problem reading fusion sequence !"),"File doesn't exist!");
2482                 return;
2483         }
2484
2485 }
2486 //------------------------------------------------------------------------------
2487
2488
2489 //------------------------------------------------------------------------------
2490 void vvMainWindow::SetFusionSequenceProperty(int fusionSequenceFrameIndex, bool spatialSyncFlag, unsigned int fusionSequenceNbFrames)
2491 {
2492         int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]);
2493
2494         //check if the focus moved to the linked sequence, and in this case, select the master sequence instead
2495         if ( (!mSlicerManagers[index]->GetSlicer(0)->GetFusion()) && mSlicerManagers[index]->GetFusionSequenceIndexOfLinkedManager()>=0 ) {
2496                 index = mSlicerManagers[index]->GetFusionSequenceIndexOfLinkedManager();
2497         }
2498
2499         if (mSlicerManagers[index]->GetSlicer(0)->GetFusion()) {
2500                 int indexParent = GetSlicerIndexFromItem( DataTree->topLevelItem(index) );
2501
2502                 //if the button is unchecked, then reposition the parent sequence (CT) in its original coordinate frame
2503                 if ( (!spatialSyncFlag) && (mSlicerManagers[index]->GetFusionSequenceSpatialSyncFlag()) ) {
2504                         for ( unsigned i=0 ; i<mSlicerManagers[indexParent]->GetSlicer(0)->GetImage()->GetTransform().size() ; i++ ) {
2505                                 mSlicerManagers[indexParent]->GetSlicer(0)->GetImage()->GetTransform()[i]->SetMatrix( mSlicerManagers[index]->GetFusionSequenceMainTransformMatrix() );
2506                                 mSlicerManagers[indexParent]->GetSlicer(0)->GetImage()->GetTransform()[i]->Update();
2507                         }
2508
2509                         for (int i=0; i<mSlicerManagers[indexParent]->GetNumberOfSlicers(); i++) {
2510                                 mSlicerManagers[indexParent]->GetSlicer(i)->ForceUpdateDisplayExtent();
2511                                 mSlicerManagers[indexParent]->GetSlicer(i)->Render();
2512                         }
2513                 }
2514
2515                 //update the property values in the slicer manager
2516                 mSlicerManagers[index]->SetFusionSequenceLength(fusionSequenceNbFrames);
2517                 mSlicerManagers[index]->SetFusionSequenceSpatialSyncFlag(spatialSyncFlag);
2518                 mSlicerManagers[index]->SetFusionSequenceFrameIndex(fusionSequenceFrameIndex);
2519
2520                 //show the right frame of the US sequence
2521                 mSlicerManagers[index]->SetFusionSequenceTSlice(fusionSequenceFrameIndex);
2522                 //update the linked sequence if possible
2523                 if (mSlicerManagers[index]->GetFusionSequenceIndexOfLinkedManager()>0) {
2524                         mSlicerManagers[ mSlicerManagers[index]->GetFusionSequenceIndexOfLinkedManager() ]->SetTSlice(fusionSequenceFrameIndex, false);
2525                 }
2526
2527                 if (spatialSyncFlag) { //reslice the CT
2528
2529                         //Set the transform matrix of the parent sequence (typically CT / 4DCT)
2530                         vtkSmartPointer<vtkMatrix4x4> tmpMat = vtkSmartPointer<vtkMatrix4x4>::New();
2531                         vtkMatrix4x4::Invert( mSlicerManagers[index]->GetFusionSequenceInitialTransformMatrixAtFrame(fusionSequenceFrameIndex), tmpMat );
2532                         for ( unsigned i=0 ; i<mSlicerManagers[indexParent]->GetSlicer(0)->GetImage()->GetTransform().size() ; i++ ) {
2533                                 mSlicerManagers[indexParent]->GetSlicer(0)->GetImage()->GetTransform()[i]->SetMatrix( mSlicerManagers[index]->GetFusionSequenceMainTransformMatrix() );
2534                                 mSlicerManagers[indexParent]->GetSlicer(0)->GetImage()->GetTransform()[i]->PreMultiply();
2535                                 mSlicerManagers[indexParent]->GetSlicer(0)->GetImage()->GetTransform()[i]->Concatenate( tmpMat );
2536                                 mSlicerManagers[indexParent]->GetSlicer(0)->GetImage()->GetTransform()[i]->Update();
2537                         }
2538
2539                         for (int i=0; i<mSlicerManagers[indexParent]->GetNumberOfSlicers(); i++) {
2540                                 mSlicerManagers[indexParent]->GetSlicer(i)->ForceUpdateDisplayExtent();
2541                                 mSlicerManagers[indexParent]->GetSlicer(i)->Render();
2542                         }
2543                 }
2544
2545         }
2546 }
2547 //------------------------------------------------------------------------------
2548
2549
2550 //------------------------------------------------------------------------------
2551 void vvMainWindow::SaveAs()
2552 {
2553   if (DataTree->selectedItems()[0]->data(1,Qt::UserRole).toString() == "vector") {
2554     QMessageBox::warning(this,tr("Unsupported type"),tr("Sorry, saving a vector field is unsupported for the moment"));
2555     return;
2556   }
2557
2558   int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]);
2559   int dimension = mSlicerManagers[index]->GetDimension();
2560   QStringList OutputListeFormat;
2561   OutputListeFormat.clear();
2562   if (dimension == 1) {
2563     OutputListeFormat.push_back(".mhd");
2564     OutputListeFormat.push_back(".mha");
2565   }
2566   if (dimension == 2) {
2567     OutputListeFormat.push_back(".bmp");
2568     OutputListeFormat.push_back(".png");
2569     OutputListeFormat.push_back(".jpeg");
2570     OutputListeFormat.push_back(".tif");
2571     OutputListeFormat.push_back(".mhd");
2572     OutputListeFormat.push_back(".mha");
2573     OutputListeFormat.push_back(".hdr");
2574     OutputListeFormat.push_back(".vox");
2575   } else if (dimension == 3) {
2576     OutputListeFormat.push_back(".mhd");
2577     OutputListeFormat.push_back(".mha");
2578     OutputListeFormat.push_back(".nii");
2579     OutputListeFormat.push_back(".nrrd");
2580     OutputListeFormat.push_back(".nhdr");
2581     OutputListeFormat.push_back(".hdr");
2582     OutputListeFormat.push_back(".vox");
2583   } else if (dimension == 4) {
2584     OutputListeFormat.push_back(".mhd");
2585     OutputListeFormat.push_back(".mha");
2586     OutputListeFormat.push_back(".nii");
2587     OutputListeFormat.push_back(".nrrd");
2588     OutputListeFormat.push_back(".nhdr");
2589   }
2590   QString Extensions = "AllFiles(*.*)";
2591   for (int i = 0; i < OutputListeFormat.count(); i++) {
2592     Extensions += ";;Images ( *";
2593     Extensions += OutputListeFormat[i];
2594     Extensions += ")";
2595   }
2596   QString fileName = QFileDialog::getSaveFileName(this,
2597                      tr("Save As"),
2598                      mSlicerManagers[index]->GetFileName().c_str(),
2599                      Extensions);
2600   if (!fileName.isEmpty()) {
2601     std::string fileformat = itksys::SystemTools::GetFilenameLastExtension(fileName.toStdString());
2602     if (OutputListeFormat.contains(
2603           fileformat.c_str())) {
2604       QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
2605       std::string action = "Saving";
2606       vvProgressDialog progress("Saving "+fileName.toStdString());
2607       qApp->processEvents();
2608       vvImageWriter::Pointer writer = vvImageWriter::New();
2609       writer->SetOutputFileName(fileName.toStdString());
2610       writer->SetInput(mSlicerManagers[index]->GetImage());
2611
2612       // Check on transform and prompt user
2613       writer->SetSaveTransform(false);
2614       bool bId = true;
2615       for(int i=0; i<4; i++)
2616         for(int j=0; j<4; j++) {
2617           // TODO SR and BP: check on the list of transforms and not the first only
2618           double elt = mSlicerManagers[index]->GetImage()->GetTransform()[0]->GetMatrix()->GetElement(i,j);
2619           if(i==j && elt!=1.)
2620             bId = false;
2621           if(i!=j && elt!=0.)
2622             bId = false;
2623         }
2624       if( !bId ) {
2625         QString warning = "The image has an associated linear transform. Do you want to save it along?";
2626         QMessageBox msgBox(QMessageBox::Warning, tr("Save transform"), warning, 0, this);
2627         msgBox.addButton(tr("Yes"), QMessageBox::AcceptRole);
2628         msgBox.addButton(tr("No"), QMessageBox::RejectRole);
2629         if (msgBox.exec() == QMessageBox::AcceptRole)
2630           writer->SetSaveTransform(true);
2631       }
2632
2633       writer->Update();
2634       QApplication::restoreOverrideCursor();
2635       if (writer->GetLastError().size()) {
2636         QString error = "Saving did not succeed\n";
2637         error += writer->GetLastError().c_str();
2638         QMessageBox::information(this,tr("Saving Problem"),error);
2639         SaveAs();
2640       }
2641     } else {
2642       QString error = fileformat.c_str();
2643       if (error.isEmpty())
2644         error += "no file format specified !";
2645       else
2646         error += " format unknown !!!\n";
2647       QMessageBox::information(this,tr("Saving Problem"),error);
2648       SaveAs();
2649     }
2650   }
2651 }
2652 //------------------------------------------------------------------------------
2653
2654 //------------------------------------------------------------------------------
2655 void vvMainWindow::SaveCurrentState()
2656 {
2657   QString Extensions = "XML Files(*.xml)";
2658   QString fileName = QFileDialog::getSaveFileName(this,
2659                      tr("Save Current Window State"),
2660                      "",
2661                      Extensions);
2662                      
2663   SaveCurrentStateAs(fileName.toStdString());
2664 }
2665 //------------------------------------------------------------------------------
2666
2667 //------------------------------------------------------------------------------
2668 void vvMainWindow::SaveCurrentStateAs(const std::string& stateFile)
2669 {
2670   vvSaveState save_state;
2671   save_state.Run(this, stateFile);
2672 }
2673
2674 //------------------------------------------------------------------------------
2675 void vvMainWindow::ReadSavedState()
2676 {
2677   QString Extensions = "XML Files(*.xml)";
2678   QString fileName = QFileDialog::getOpenFileName(this,
2679                      tr("Load Window State"),
2680                      "",
2681                      Extensions);
2682                      
2683   ReadSavedStateFile(fileName.toStdString());
2684 }
2685 //------------------------------------------------------------------------------
2686
2687 //------------------------------------------------------------------------------
2688 void vvMainWindow::ReadSavedStateFile(const std::string& stateFile)
2689 {
2690   vvReadState read_state;
2691   read_state.Run(this, stateFile);
2692 }
2693 //------------------------------------------------------------------------------
2694
2695 //------------------------------------------------------------------------------
2696 void vvMainWindow::LinkAllImages()
2697 {
2698         linkPanel->linkAll();
2699 }
2700
2701 //------------------------------------------------------------------------------
2702 void vvMainWindow::AddLink(QString image1,QString image2,bool fromPanel)
2703 {
2704   if (!fromPanel) {
2705     // delegate to linkPanel if call came from elsewhere...
2706     linkPanel->addLinkFromIds(image1, image2);
2707     return;
2708   }
2709   
2710   unsigned int sm1 = 0;
2711   unsigned int sm2 = 0;
2712
2713   for (unsigned int i = 0; i < mSlicerManagers.size(); i++) {
2714     if (image1.toStdString() == mSlicerManagers[i]->GetId()) {
2715       mSlicerManagers[i]->AddLink(image2.toStdString());
2716       sm1 = i;
2717     }
2718     if (image2.toStdString() == mSlicerManagers[i]->GetId()) {
2719       mSlicerManagers[i]->AddLink(image1.toStdString());
2720       sm2 = i;
2721     }
2722   }
2723
2724   if (linkPanel->isLinkAll())   {
2725     emit UpdateLinkedNavigation(mSlicerManagers[sm1]->GetId(), mSlicerManagers[mCurrentPickedImageIndex], mSlicerManagers[mCurrentPickedImageIndex]->GetSlicer(0));
2726     emit UpdateLinkedNavigation(mSlicerManagers[sm2]->GetId(), mSlicerManagers[mCurrentPickedImageIndex], mSlicerManagers[mCurrentPickedImageIndex]->GetSlicer(0));
2727   } else {
2728     emit UpdateLinkedNavigation(mSlicerManagers[sm2]->GetId(), mSlicerManagers[sm1], mSlicerManagers[sm1]->GetSlicer(0));
2729   }
2730 }
2731
2732 //------------------------------------------------------------------------------
2733
2734
2735 //------------------------------------------------------------------------------
2736 void vvMainWindow::RemoveLink(QString image1,QString image2)
2737 {
2738   for (unsigned int i = 0; i < mSlicerManagers.size(); i++) {
2739     if (image1.toStdString() == mSlicerManagers[i]->GetId()) {
2740       mSlicerManagers[i]->RemoveLink(image2.toStdString());
2741     }
2742     if (image2.toStdString() == mSlicerManagers[i]->GetId()) {
2743       mSlicerManagers[i]->RemoveLink(image1.toStdString());
2744     }
2745   }
2746 }
2747 //------------------------------------------------------------------------------
2748
2749 //------------------------------------------------------------------------------
2750 void vvMainWindow::ChangeImageWithIndexOffset(vvSlicerManager *sm, int slicer, int offset)
2751 {
2752   if(mSlicerManagers.size()==1)
2753     return;
2754
2755   int index = 0;
2756   while(sm != mSlicerManagers[index])
2757     index++;
2758   index = (index+offset+mSlicerManagers.size()) % mSlicerManagers.size();
2759
2760   QTreeWidgetItem* item = GetItemFromSlicerManager(mSlicerManagers[index]);
2761   item->setData(slicer+1,Qt::CheckStateRole,2);         //change checkbox
2762   CurrentImageChanged(mSlicerManagers[index]->GetId()); //select new image
2763   DisplayChanged(item,slicer+1);
2764 }
2765 //------------------------------------------------------------------------------
2766
2767 void vvMainWindow::HorizontalSliderMoved(int value,int column, int slicer_index)
2768 {
2769   for (unsigned int i = 0; i < mSlicerManagers.size(); i++) {
2770     if (DataTree->topLevelItem(i)->data(column,Qt::CheckStateRole).toInt() > 1) {
2771       for (int j = 0; j < 4; j++) {
2772         mSlicerManagers[i]->SetTSliceInSlicer(value,j);
2773         //if (mSlicerManagers[i]->GetSlicer(j)->GetImageActor()->GetVisibility())
2774         //UpdateTSlice(j,value);
2775       }
2776       mSlicerManagers[i]->GetSlicer(slicer_index)->Render();
2777       break;
2778     }
2779   }
2780 }
2781 //------------------------------------------------------------------------------
2782
2783
2784 //------------------------------------------------------------------------------
2785 void vvMainWindow::NOHorizontalSliderMoved()
2786 {
2787   // if (mCurrentTime == NOHorizontalSlider->value()) return;
2788   HorizontalSliderMoved(NOHorizontalSlider->value(),COLUMN_UL_VIEW,0);
2789 //  mCurrentTime = NOHorizontalSlider->value();
2790 }
2791 //------------------------------------------------------------------------------
2792
2793
2794 //------------------------------------------------------------------------------
2795 void vvMainWindow::NEHorizontalSliderMoved()
2796 {
2797   // if (mCurrentTime == NEHorizontalSlider->value()) return;
2798   HorizontalSliderMoved(NEHorizontalSlider->value(),COLUMN_UR_VIEW,1);
2799 //  mCurrentTime = NEHorizontalSlider->value();
2800 }
2801 //------------------------------------------------------------------------------
2802
2803
2804 //------------------------------------------------------------------------------
2805 void vvMainWindow::SOHorizontalSliderMoved()
2806 {
2807   // if (mCurrentTime == SOHorizontalSlider->value()) return;
2808   HorizontalSliderMoved(SOHorizontalSlider->value(),COLUMN_DL_VIEW,2);
2809   // mCurrentTime = SOHorizontalSlider->value();
2810 }
2811 //------------------------------------------------------------------------------
2812
2813
2814 //------------------------------------------------------------------------------
2815 void vvMainWindow::SEHorizontalSliderMoved()
2816 {
2817   // if (mCurrentTime == SEHorizontalSlider->value()) return;
2818   HorizontalSliderMoved(SEHorizontalSlider->value(),COLUMN_DR_VIEW,3);
2819   // mCurrentTime = SEHorizontalSlider->value();
2820 }
2821 //------------------------------------------------------------------------------
2822
2823 //------------------------------------------------------------------------------
2824 void vvMainWindow::NOVerticalSliderChanged()
2825 {
2826   static int value=-1;
2827   if (value == NOVerticalSlider->value()) return;
2828   else value = NOVerticalSlider->value();
2829   //  int value = NOVerticalSlider->value();
2830   for (unsigned int i = 0; i < mSlicerManagers.size(); i++) {
2831     if (DataTree->topLevelItem(i)->data(COLUMN_UL_VIEW,Qt::CheckStateRole).toInt() > 1) {
2832       if (mSlicerManagers[i]->GetSlicer(0)->GetSlice() != value) {
2833         mSlicerManagers[i]->GetSlicer(0)->SetSlice(value);
2834         mSlicerManagers[i]->VerticalSliderHasChanged(0, value);
2835
2836         // If nor Update/Render -> slider not work
2837         // only render = ok navigation, but for contour Update needed but slower ?
2838
2839         mSlicerManagers[i]->UpdateSlice(0);  // <-- DS add this. Not too much update ? YES. but needed for ImageContour ...
2840         //mSlicerManagers[i]->GetSlicer(0)->Render(); // <-- DS add this, needed for contour, seems ok ? not too slow ?
2841       }
2842       break;
2843     }
2844   }
2845 }
2846 //------------------------------------------------------------------------------
2847
2848
2849 //------------------------------------------------------------------------------
2850 void vvMainWindow::NEVerticalSliderChanged()
2851 {
2852   static int value=-1;
2853   if (value == NEVerticalSlider->value()) return;
2854   else value = NEVerticalSlider->value();
2855   //  int value = NEVerticalSlider->value();
2856   for (unsigned int i = 0; i < mSlicerManagers.size(); i++) {
2857     if (DataTree->topLevelItem(i)->data(COLUMN_UR_VIEW,Qt::CheckStateRole).toInt() > 1) {
2858       if (mSlicerManagers[i]->GetSlicer(1)->GetSlice() != value) {
2859         mSlicerManagers[i]->GetSlicer(1)->SetSlice(value);
2860         mSlicerManagers[i]->VerticalSliderHasChanged(1, value);
2861         mSlicerManagers[i]->UpdateSlice(1);
2862         //mSlicerManagers[i]->GetSlicer(1)->Render(); // <-- DS add this, needed for contour, seems ok ? not too slow ?
2863       }
2864       break;
2865     }
2866   }
2867 }
2868 //------------------------------------------------------------------------------
2869
2870
2871 //------------------------------------------------------------------------------
2872 void vvMainWindow::SOVerticalSliderChanged()
2873 {
2874   static int value=-1;
2875   if (value == SOVerticalSlider->value()) return;
2876   else value = SOVerticalSlider->value();
2877   //int value = SOVerticalSlider->value();
2878   for (unsigned int i = 0; i < mSlicerManagers.size(); i++) {
2879     if (DataTree->topLevelItem(i)->data(COLUMN_DL_VIEW,Qt::CheckStateRole).toInt() > 1) {
2880       if (mSlicerManagers[i]->GetSlicer(2)->GetSlice() != value) {
2881         mSlicerManagers[i]->GetSlicer(2)->SetSlice(value);
2882         mSlicerManagers[i]->VerticalSliderHasChanged(2, value);
2883         mSlicerManagers[i]->UpdateSlice(2);
2884         //mSlicerManagers[i]->GetSlicer(2)->Render(); // <-- DS add this, needed for contour, seems ok ? not too slow ?
2885       }
2886       // else { DD("avoid SOVerticalSlider slicer update"); }
2887       break;
2888     }
2889   }
2890 }
2891 //------------------------------------------------------------------------------
2892
2893
2894 //------------------------------------------------------------------------------
2895 void vvMainWindow::SEVerticalSliderChanged()
2896 {
2897   static int value=-1;
2898   if (value == SEVerticalSlider->value()) return;
2899   else value = SEVerticalSlider->value();
2900   // int value = SEVerticalSlider->value();
2901   for (unsigned int i = 0; i < mSlicerManagers.size(); i++) {
2902     if (DataTree->topLevelItem(i)->data(COLUMN_DR_VIEW,Qt::CheckStateRole).toInt() > 1) {
2903       if (mSlicerManagers[i]->GetSlicer(3)->GetSlice() != value) {
2904         mSlicerManagers[i]->GetSlicer(3)->SetSlice(value);
2905         mSlicerManagers[i]->VerticalSliderHasChanged(3, value);
2906         mSlicerManagers[i]->UpdateSlice(3);
2907         //mSlicerManagers[i]->GetSlicer(3)->Render(); // <-- DS add this, needed for contour, seems ok ? not too slow ?
2908       }
2909       break;
2910     }
2911   }
2912 }
2913 //------------------------------------------------------------------------------
2914
2915
2916 //------------------------------------------------------------------------------
2917 void vvMainWindow::UpdateSlice(int slicer, int slice)
2918 {
2919   // DD("vvMainWindow::UpdateSlice");
2920 //   DD(slicer);
2921 //   DD(slice);
2922   if (slicer == 0) {
2923     //    if (slice != NOVerticalSlider->value())
2924     NOVerticalSlider->setValue(slice);
2925   } else {
2926     if (slicer == 1)
2927       NEVerticalSlider->setValue(slice);
2928     else {
2929       if (slicer == 2)
2930         SOVerticalSlider->setValue(slice);
2931       else {
2932         if (slicer == 3)
2933           SEVerticalSlider->setValue(slice);
2934       }
2935     }
2936   }
2937   // DD("vvMainWindow:UpdateSlice END");
2938 }
2939 //------------------------------------------------------------------------------
2940
2941
2942 //------------------------------------------------------------------------------
2943 void vvMainWindow::UpdateTSlice(int slicer, int slice)
2944 {
2945   switch (slicer) {
2946   case 0:
2947     NOHorizontalSlider->setValue(slice);
2948     break;
2949   case 1:
2950     NEHorizontalSlider->setValue(slice);
2951     break;
2952   case 2:
2953     SOHorizontalSlider->setValue(slice);
2954     break;
2955   case 3:
2956     SEHorizontalSlider->setValue(slice);
2957     break;
2958   }
2959 }
2960 //------------------------------------------------------------------------------
2961
2962
2963 //------------------------------------------------------------------------------
2964 void vvMainWindow::UpdateSliceRange(int slicer, int min, int max, int tmin, int tmax)
2965 {
2966   //int position = int((min+max)/2);
2967   int position = mSlicerManagers[mCurrentPickedImageIndex]->GetSlicer(slicer)->GetSlice();
2968   if (slicer == 0) {
2969     NOVerticalSlider->setRange(min,max);
2970     NOHorizontalSlider->setRange(tmin,tmax);
2971     NOVerticalSlider->setValue(position);
2972   } else if (slicer == 1) {
2973     NEVerticalSlider->setRange(min,max);
2974     NEHorizontalSlider->setRange(tmin,tmax);
2975     NEVerticalSlider->setValue(position);
2976   } else if (slicer == 2) {
2977     SOVerticalSlider->setRange(min,max);
2978     SOHorizontalSlider->setRange(tmin,tmax);
2979     SOVerticalSlider->setValue(position);
2980   } else if (slicer == 3) {
2981     SEVerticalSlider->setRange(min,max);
2982     SEHorizontalSlider->setRange(tmin,tmax);
2983     SEVerticalSlider->setValue(position);
2984   }
2985 }
2986 //------------------------------------------------------------------------------
2987
2988
2989 //------------------------------------------------------------------------------
2990 void vvMainWindow::SaveNOScreenshot()
2991 {
2992   SaveScreenshot(NOViewWidget);
2993 }
2994 //------------------------------------------------------------------------------
2995
2996
2997 //------------------------------------------------------------------------------
2998 void vvMainWindow::SaveNEScreenshot()
2999 {
3000   SaveScreenshot(NEViewWidget);
3001 }
3002 //------------------------------------------------------------------------------
3003
3004
3005 //------------------------------------------------------------------------------
3006 void vvMainWindow::SaveSOScreenshot()
3007 {
3008   SaveScreenshot(SOViewWidget);
3009 }
3010 //------------------------------------------------------------------------------
3011
3012
3013 //------------------------------------------------------------------------------
3014 void vvMainWindow::SaveSEScreenshot()
3015 {
3016   SaveScreenshot(SEViewWidget);
3017 }
3018 //------------------------------------------------------------------------------
3019
3020
3021 //------------------------------------------------------------------------------
3022 void vvMainWindow::SaveScreenshotAllSlices()
3023 {
3024   QVTKWidget *widget = NOViewWidget;
3025
3026   int index = 0;// GetSlicerIndexFromItem(DataTree->selectedItems()[0]);
3027   vvSlicerManager * SM = mSlicerManagers[index];
3028   vvImage * image = SM->GetImage();
3029   vvSlicer * slicer = SM->GetSlicer(0);
3030   int orientation = slicer->GetOrientation();
3031   int nbSlices = image->GetSize()[orientation];
3032   vtkSmartPointer<vtkRenderWindow>  renderWindow = widget->GetRenderWindow();
3033
3034   // Select filename base
3035   QString filename = QFileDialog::getSaveFileName(this,
3036                                                   tr("Save As (filename will be completed by slice number)"),
3037                                                   itksys::SystemTools::GetFilenamePath(mSlicerManagers[index]->GetFileName()).c_str(),
3038                                                   "Images( *.png);;Images( *.jpg)");
3039
3040   // Loop on slices
3041   for(int i=0; i<nbSlices; i++) {
3042     // Change the slice
3043     slicer->SetSlice(i); // -> change the slice of the current slicer
3044     SM->UpdateSlice(0); // --> this one emit UpdateSlice
3045     QCoreApplication::flush(); // -> needed to force display of contours 
3046
3047     // Screenshot  
3048     vtkSmartPointer<vtkWindowToImageFilter> windowToImageFilter = vtkSmartPointer<vtkWindowToImageFilter>::New();
3049     windowToImageFilter->SetInput(renderWindow);
3050     windowToImageFilter->SetMagnification(1);
3051     windowToImageFilter->SetInputBufferTypeToRGBA(); //also record the alpha (transparency) channel
3052     windowToImageFilter->Update();
3053     
3054     vtkSmartPointer<vtkPNGWriter> writer = vtkSmartPointer<vtkPNGWriter>::New();
3055     std::string fn = itksys::SystemTools::GetFilenameWithoutLastExtension(filename.toStdString());
3056     std::string num = clitk::toString(i);
3057     if (i<10) num = "0"+num;
3058     if (i<100) num = "0"+num;
3059     if (i<1000) num = "0"+num;
3060
3061     fn = itksys::SystemTools::GetFilenamePath(filename.toStdString()) + "/"+ fn 
3062       + "_" + num + itksys::SystemTools::GetFilenameLastExtension(filename.toStdString());
3063     writer->SetFileName(fn.c_str());
3064     writer->SetInput(windowToImageFilter->GetOutput());
3065     writer->Write();
3066   }
3067 }
3068 //------------------------------------------------------------------------------
3069
3070
3071 //------------------------------------------------------------------------------
3072 void vvMainWindow::SaveScreenshot(QVTKWidget *widget)
3073 {
3074   QString Extensions = "Images( *.png);;";
3075   Extensions += "Images( *.jpg);;";
3076   Extensions += "Images( *.bmp);;";
3077   Extensions += "Images( *.tif);;";
3078   Extensions += "Images( *.ppm)";
3079 #if defined(VTK_USE_FFMPEG_ENCODER) || defined(VTK_USE_VIDEO_FOR_WINDOWS)
3080   Extensions += ";;Video( *.avi)";
3081 #endif
3082 #ifdef VTK_USE_MPEG2_ENCODER
3083   Extensions += ";;Video( *.mpg)";
3084 #endif
3085 #ifdef CLITK_EXPERIMENTAL
3086   Extensions += ";;Video( *.gif)";
3087 #endif
3088
3089   int smIndex=GetSlicerIndexFromItem(DataTree->selectedItems()[0]);
3090   QString fileName = QFileDialog::getSaveFileName(this,
3091                      tr("Save As"),
3092                      itksys::SystemTools::GetFilenamePath(mSlicerManagers[smIndex]->GetFileName()).c_str(),
3093                      Extensions);
3094
3095   if (!fileName.isEmpty()) {
3096     vtkSmartPointer<vtkWindowToImageFilter> w2i = vtkSmartPointer<vtkWindowToImageFilter>::New();
3097     w2i->SetInput(widget->GetRenderWindow());
3098     w2i->Update();
3099     vtkImageData *image = w2i->GetOutput();
3100
3101     std::string ext(itksys::SystemTools::GetFilenameLastExtension(fileName.toStdString()));
3102
3103     // Image
3104     vtkImageWriter *imgwriter = NULL;
3105     if (ext==".bmp")
3106       imgwriter = vtkBMPWriter::New();
3107     else if (ext==".tif")
3108       imgwriter = vtkTIFFWriter::New();
3109     else if (ext==".ppm")
3110       imgwriter = vtkPNMWriter::New();
3111     else if (ext==".png")
3112       imgwriter = vtkPNGWriter::New();
3113     else if (ext==".jpg")
3114       imgwriter = vtkJPEGWriter::New();
3115
3116     // Snapshot image if not null
3117     if(imgwriter!=NULL) {
3118       imgwriter->SetInput(image);
3119       imgwriter->SetFileName(fileName.toStdString().c_str());
3120       imgwriter->Write();
3121       return;
3122     }
3123
3124     // Video
3125     vtkGenericMovieWriter *vidwriter = NULL;
3126 #if CLITK_EXPERIMENTAL == 1
3127     if (ext==".gif") {
3128       vvAnimatedGIFWriter *gif = vvAnimatedGIFWriter::New();
3129       vidwriter = gif;
3130
3131       // FPS
3132       bool ok;
3133       int fps = QInputDialog::getInteger(this, tr("Number of frames per second"),
3134                                      tr("FPS:"), 5, 0, 1000, 1, &ok);
3135       if(ok)
3136         gif->SetRate(fps);
3137
3138       // Loops
3139       int loops = QInputDialog::getInteger(this, tr("Loops"),
3140                                      tr("Number of loops (0 means infinite):"), 0, 0, 1000000000, 1, &ok);
3141       if(ok)
3142         gif->SetLoops(loops);
3143
3144       // Dithering
3145       QString msg = "Would you like to activate dithering?";
3146       QMessageBox msgBox(QMessageBox::Question, tr("Dithering"),msg, 0, this);
3147       msgBox.addButton(tr("Yes"), QMessageBox::AcceptRole);
3148       msgBox.addButton(tr("No"), QMessageBox::RejectRole);
3149       gif->SetDither(msgBox.exec() == QMessageBox::AcceptRole);
3150     }
3151 #endif
3152 #ifdef VTK_USE_VIDEO_FOR_WINDOWS
3153     if (ext==".avi") {
3154       vtkAVIWriter *mpg = vtkAVIWriter::New();
3155       vidwriter = mpg;
3156       mpg->SetQuality(2);
3157       bool ok;
3158       int fps = QInputDialog::getInteger(this, tr("Number of frames per second"),
3159                                      tr("FPS:"), 5, 0, 1024, 1, &ok);
3160       if(!ok)
3161         fps = 5;
3162       mpg->SetRate(fps);
3163     }
3164 #endif
3165 #ifdef VTK_USE_FFMPEG_ENCODER
3166     if (ext==".avi") {
3167       vtkFFMPEGWriter *mpg = vtkFFMPEGWriter::New();
3168       vidwriter = mpg;
3169       mpg->SetQuality(2);
3170       bool ok;
3171       int fps = QInputDialog::getInteger(this, tr("Number of frames per second"),
3172                                      tr("FPS:"), 5, 0, 1024, 1, &ok);
3173       if(!ok)
3174         fps = 5;
3175       mpg->SetRate(fps);
3176       mpg->SetBitRateTolerance(int(ceil(12.0*1024*1024/fps)));
3177     }
3178 #endif
3179 #ifdef VTK_USE_MPEG2_ENCODER
3180     if (ext==".mpg") {
3181       vtkMPEG2Writer *mpg = vtkMPEG2Writer::New();
3182       vidwriter = mpg;
3183     }
3184 #endif
3185
3186     // Take video if not null
3187     if(vidwriter!=NULL){
3188       vidwriter->SetInput(image);
3189       vidwriter->SetFileName(fileName.toStdString().c_str());
3190       vidwriter->Start();
3191       int nSlice = mSlicerManagers[smIndex]->GetSlicer(0)->GetTMax();
3192       for(int i=0; i<=nSlice; i++) {
3193         mSlicerManagers[smIndex]->SetNextTSlice(0);
3194         vtkSmartPointer<vtkWindowToImageFilter> w2i = vtkSmartPointer<vtkWindowToImageFilter>::New();
3195         w2i->SetInput(widget->GetRenderWindow());
3196         w2i->Update();
3197         vidwriter->SetInput(w2i->GetOutput());
3198         vidwriter->Write();
3199       }
3200       vidwriter->End();
3201       vidwriter->Delete();
3202       return;
3203     }
3204
3205     QMessageBox::information(this,tr("Problem saving screenshot !"),tr("Cannot save image.\nPlease set a file extension !!!"));
3206   }
3207 }
3208 //------------------------------------------------------------------------------
3209
3210
3211 //------------------------------------------------------------------------------
3212 void vvMainWindow::GoToCursor()
3213 {
3214   int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]);
3215   for (int column = 1; column < 5; column++) {
3216     if (DataTree->selectedItems()[0]->data(column,Qt::CheckStateRole).toInt() > 1) {
3217       double* cursorPos = mSlicerManagers[index]->GetSlicer(column-1)->GetCursorPosition();
3218       mSlicerManagers[index]->GetSlicer(column-1)->SetCurrentPosition(
3219         cursorPos[0],cursorPos[1],cursorPos[2],cursorPos[3]);
3220       mSlicerManagers[index]->UpdateViews(1,column-1);
3221       mSlicerManagers[index]->UpdateLinked(column-1);
3222       break;
3223     }
3224   }
3225 }
3226 //------------------------------------------------------------------------------
3227
3228 //------------------------------------------------------------------------------
3229 void vvMainWindow::PlayPause()
3230 {
3231   if (playMode) {
3232     playMode = 0;
3233     playButton->setIcon(QIcon(QString::fromUtf8(":/common/icons/player_play.png")));
3234     ImageInfoChanged();
3235     return;
3236   } else {
3237     int image_number=DataTree->topLevelItemCount();
3238     bool has_temporal;
3239     for (int i=0; i<image_number; i++)
3240       if (mSlicerManagers[i]->GetSlicer(0)->GetTMax() > 0) {
3241         has_temporal=true;
3242         break;
3243       }
3244     if (has_temporal) {
3245       playMode = 1;
3246       playButton->setIcon(QIcon(QString::fromUtf8(":/common/icons/player_pause.png")));
3247       QTimer::singleShot(1000/mFrameRate, this, SLOT(PlayNext()));
3248     }
3249   }
3250 }
3251 //------------------------------------------------------------------------------
3252
3253 //------------------------------------------------------------------------------
3254 void vvMainWindow::PlayNext()
3255 {
3256   if (playMode && !this->isHidden()) {
3257     int image_number=DataTree->topLevelItemCount();
3258     ///Only play one slicer per SM, and only if the SM is being displayed
3259     for (int i=0; i<image_number; i++)
3260       for (int j=0; j<4; j++)
3261         if (mSlicerManagers[i]->GetSlicer(0)->GetTMax() > 0 &&
3262             DataTree->topLevelItem(i)->data(j+1,Qt::CheckStateRole).toInt() > 0) {
3263           mSlicerManagers[i]->SetNextTSlice(j);
3264           break;
3265         }
3266     QTimer::singleShot(1000/mFrameRate, this, SLOT(PlayNext()));
3267   }
3268 }
3269 //------------------------------------------------------------------------------
3270
3271 void vvMainWindow::ShowLastImage()
3272 {
3273   if (mSlicerManagers.size() > 1) {
3274     QTreeWidgetItem * item=DataTree->topLevelItem(DataTree->topLevelItemCount()-1);
3275     CurrentImageChanged(mSlicerManagers.back()->GetId()); //select new image
3276     item->setData(1,Qt::CheckStateRole,2); //show the new image in the first panel
3277     DisplayChanged(item,1);
3278   }
3279 }
3280
3281 //------------------------------------------------------------------------------
3282 void vvMainWindow::UpdateRenderWindows()
3283 {
3284   for (unsigned int i = 0; i < mSlicerManagers.size(); i++) {
3285     mSlicerManagers[i]->GetSlicer(0)->UpdateLandmarks();
3286     mSlicerManagers[i]->GetSlicer(1)->UpdateLandmarks();
3287     mSlicerManagers[i]->GetSlicer(2)->UpdateLandmarks();
3288     mSlicerManagers[i]->GetSlicer(3)->UpdateLandmarks();
3289   }
3290   if (NOViewWidget->GetRenderWindow()) NOViewWidget->GetRenderWindow()->Render();
3291   if (NEViewWidget->GetRenderWindow()) NEViewWidget->GetRenderWindow()->Render();
3292   if (SOViewWidget->GetRenderWindow()) SOViewWidget->GetRenderWindow()->Render();
3293   if (SEViewWidget->GetRenderWindow()) SEViewWidget->GetRenderWindow()->Render();
3294 }
3295 //------------------------------------------------------------------------------
3296
3297 //------------------------------------------------------------------------------
3298 void vvMainWindow::SegmentationOnCurrentImage()
3299 {
3300   int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]);
3301
3302   vvSegmentationDialog segmentation;
3303   segmentation.SetImage(mSlicerManagers[index]->GetSlicer(0)->GetImage());
3304   segmentation.exec();
3305 }
3306 //------------------------------------------------------------------------------
3307
3308 void vvMainWindow::SurfaceViewerLaunch()
3309 {
3310   vvSurfaceViewerDialog surfaceViewer;
3311   surfaceViewer.exec();
3312 }
3313 //------------------------------------------------------------------------------
3314
3315
3316 //------------------------------------------------------------------------------
3317 int vvMainWindow::GetImageDuplicateFilenameNumber(std::string filename)
3318 {
3319   int number=0;
3320   for(unsigned int l=0; l<mSlicerManagers.size(); l++) {
3321     vvSlicerManager * v = mSlicerManagers[l];
3322     if (v->GetBaseFileName() ==
3323         vtksys::SystemTools::GetFilenameName(vtksys::SystemTools::GetFilenameWithoutLastExtension(filename))) {
3324       number = std::max(number, v->GetBaseFileNameNumber()+1);
3325     }
3326   }
3327   return number;
3328 }
3329 //------------------------------------------------------------------------------
3330
3331
3332 //------------------------------------------------------------------------------
3333 vvSlicerManager* vvMainWindow::AddImage(vvImage::Pointer image,std::string filename)
3334 {
3335   // Change filename if another image exist with the same name
3336   int number = GetImageDuplicateFilenameNumber(filename);
3337
3338   // Create new SliceManager
3339   vvSlicerManager* slicer_manager = new vvSlicerManager(4);
3340   slicer_manager->SetImage(image);//, IMAGE, number);
3341   //  filename = filename+"_"+clitk::toString(number);
3342   slicer_manager->SetFilename(filename, number);
3343   mSlicerManagers.push_back(slicer_manager);
3344
3345   //create an item in the tree with good settings
3346   QTreeWidgetItem *item = new QTreeWidgetItem();
3347   item->setData(0,Qt::UserRole,slicer_manager->GetFileName().c_str());//files[i].c_str());
3348   item->setData(1,Qt::UserRole,tr("image"));
3349   item->setData(COLUMN_IMAGE_NAME,Qt::DisplayRole,slicer_manager->GetFileName().c_str());//filename.c_str());
3350   qApp->processEvents();
3351
3352   for (int j = 1; j <= 4; j++) item->setData(j,Qt::CheckStateRole,1);
3353
3354   //Create the buttons for reload and close
3355   qApp->processEvents();
3356   QTreePushButton* cButton = new QTreePushButton;
3357   cButton->setItem(item);
3358   cButton->setColumn(COLUMN_CLOSE_IMAGE);
3359   cButton->setIcon(QIcon(QString::fromUtf8(":/common/icons/exit.png")));
3360   connect(cButton,SIGNAL(clickedInto(QTreeWidgetItem*, int)),
3361           this,SLOT(CloseImage(QTreeWidgetItem*, int)));
3362
3363   QTreePushButton* rButton = new QTreePushButton;
3364   rButton->setItem(item);
3365   rButton->setColumn(COLUMN_RELOAD_IMAGE);
3366   rButton->setIcon(QIcon(QString::fromUtf8(":/common/icons/rotateright.png")));
3367   rButton->setEnabled(0);
3368   connect(rButton,SIGNAL(clickedInto(QTreeWidgetItem*, int)),
3369           this,SLOT(ReloadImage(QTreeWidgetItem*, int)));
3370
3371   DataTree->addTopLevelItem(item);
3372   DataTree->setItemWidget(item, COLUMN_CLOSE_IMAGE, cButton);
3373   DataTree->setItemWidget(item, COLUMN_RELOAD_IMAGE, rButton);
3374
3375   //set the id of the image
3376   QString id = QDir::current().absoluteFilePath(slicer_manager->GetFileName().c_str()) + QString::number(mSlicerManagers.size()-1);
3377   item->setData(COLUMN_IMAGE_NAME,Qt::UserRole,id.toStdString().c_str());
3378   mSlicerManagers.back()->SetId(id.toStdString());
3379
3380   linkPanel->addImage(slicer_manager->GetFileName().c_str()// filename
3381                       , id.toStdString());
3382
3383   connect(mSlicerManagers.back(), SIGNAL(currentImageChanged(std::string)),
3384           this, SLOT(CurrentImageChanged(std::string)));
3385   connect(mSlicerManagers.back(), SIGNAL(currentPickedImageChanged(std::string)),
3386           this, SLOT(CurrentPickedImageChanged(std::string)));
3387   connect(mSlicerManagers.back(), SIGNAL(UpdatePosition(int, double, double, double, double, double, double, double)),
3388           this, SLOT(MousePositionChanged(int,double, double, double, double, double, double, double)));
3389   connect(mSlicerManagers.back(), SIGNAL(UpdateVector(int, double, double, double, double)),
3390           this, SLOT(VectorChanged(int,double,double,double, double)));
3391   connect(mSlicerManagers.back(), SIGNAL(UpdateOverlay(int, double, double)),
3392           this, SLOT(OverlayChanged(int,double,double)));
3393   connect(mSlicerManagers.back(), SIGNAL(UpdateFusion(int, double)),
3394                   this, SLOT(FusionChanged(int,double)));
3395   //connect(mSlicerManagers.back(), SIGNAL(UpdateFusionSequence(int, bool, unsigned int)),
3396                 //  this, SLOT(FusionSequenceChanged(int, bool, unsigned int)));
3397   connect(mSlicerManagers.back(), SIGNAL(WindowLevelChanged()),
3398           this,SLOT(WindowLevelChanged()));
3399   connect(mSlicerManagers.back(), SIGNAL(UpdateSlice(int,int)),
3400           this,SLOT(UpdateSlice(int,int)));
3401   connect(mSlicerManagers.back(), SIGNAL(UpdateTSlice(int, int)),
3402           this,SLOT(UpdateTSlice(int, int)));
3403   connect(mSlicerManagers.back(), SIGNAL(UpdateTSlice(int, int)),
3404           this,SLOT(ImageInfoChanged()));
3405   connect(mSlicerManagers.back(), SIGNAL(UpdateSliceRange(int,int,int,int,int)),
3406           this,SLOT(UpdateSliceRange(int,int,int,int,int)));
3407   connect(mSlicerManagers.back(), SIGNAL(UpdateLinkManager(std::string,int,double,double,double,int)),
3408           this,SLOT(UpdateLinkManager(std::string,int,double,double,double,int)));
3409   connect(mSlicerManagers.back(), SIGNAL(UpdateLinkedNavigation(std::string,vvSlicerManager*,vvSlicer*)),
3410           this,SLOT(UpdateLinkedNavigation(std::string,vvSlicerManager*,vvSlicer*)));
3411   connect(mSlicerManagers.back(), SIGNAL(ChangeImageWithIndexOffset(vvSlicerManager*,int,int)),
3412           this,SLOT(ChangeImageWithIndexOffset(vvSlicerManager*,int,int)));
3413   connect(mSlicerManagers.back(), SIGNAL(LandmarkAdded()),landmarksPanel,SLOT(AddPoint()));
3414   UpdateTree();
3415   qApp->processEvents();
3416   InitSlicers();
3417   ShowLastImage();
3418   InitDisplay();
3419   qApp->processEvents();
3420
3421   // End
3422   ImageInfoChanged();
3423   return slicer_manager;
3424 }
3425 //------------------------------------------------------------------------------
3426
3427
3428 //------------------------------------------------------------------------------
3429 void vvMainWindow::UpdateCurrentSlicer()
3430 {
3431   int index = -1;
3432   if (DataTree->selectedItems().size() > 0) {
3433     index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]);
3434   }
3435   mSlicerManagerCurrentIndex = index;
3436 }
3437 //------------------------------------------------------------------------------
3438