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