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