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