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