]> Creatis software - clitk.git/blobdiff - vv/vvMainWindow.cxx
dicom structure in cmd line
[clitk.git] / vv / vvMainWindow.cxx
index 8842b2d2343e0739ca204e3b7fe4435e8ff8466d..b102e6234c62fee01ba7f9c683bce3f07d9c998a 100644 (file)
@@ -45,6 +45,8 @@
 #include "vvMesh.h"
 #include "vvStructSelector.h"
 #include "vvMeshReader.h"
+#include "vvSaveState.h"
+#include "vvReadState.h"
 #include "clitkConfiguration.h"
 
 // ITK include
@@ -144,22 +146,34 @@ vvMainWindow::vvMainWindow():vvMainWindowBase()
   connect(actionSave_image,SIGNAL(triggered()),this,SLOT(SaveAs()));
   contextActions.push_back(actionSave_image);
 
+  QAction* actionSave_state = contextMenu.addAction(QIcon(QString::fromUtf8(":/common/icons/filesave.png")),
+                              tr("Save Current State"));
+  connect(actionSave_state,SIGNAL(triggered()),this,SLOT(SaveCurrentState()));
+  contextActions.push_back(actionSave_state);
+
+  QAction* actionRead_state = contextMenu.addAction(QIcon(QString::fromUtf8(":/common/icons/filesave.png")),
+                              tr("Read Saved State"));
+  connect(actionRead_state,SIGNAL(triggered()),this,SLOT(ReadSavedState()));
+  contextActions.push_back(actionRead_state);
+
   contextMenu.addSeparator();
 
   contextMenu.addAction(actionAdd_VF_to_current_Image);
   contextActions.push_back(actionAdd_VF_to_current_Image);
 
-  QAction* actionAdd_Overlay_to_current_Image = menuOverlay->addAction(QIcon(QString::fromUtf8(":/common/icons/GPSup.png")),
-      tr("Add overlay image to current image"));
-  contextMenu.addAction(actionAdd_Overlay_to_current_Image);
-  contextActions.push_back(actionAdd_Overlay_to_current_Image);
-
-  connect(actionAdd_Overlay_to_current_Image,SIGNAL(triggered()), this,SLOT(SelectOverlayImage()));
+  //QAction* actionAdd_Overlay_to_current_Image = menuOverlay->addAction(QIcon(QString::fromUtf8(":/common/icons/GPSup.png")),
+  //    tr("Add overlay image to current image"));
+  contextMenu.addAction(actionAdd_overlay_image_to_current_image);
+  contextActions.push_back(actionAdd_overlay_image_to_current_image);
 
   contextMenu.addAction(actionAdd_fusion_image);
-  connect(actionAdd_fusion_image,SIGNAL(triggered()),this,SLOT(SelectFusionImage()));
   contextActions.push_back(actionAdd_fusion_image);
 
+  contextMenu.addSeparator();
+  QAction* actionResetMatrix = contextMenu.addAction(QIcon(QString::fromUtf8(":/common/icons/identity.png")),
+                                                      tr("Reset transformation to identity"));
+  connect(actionResetMatrix, SIGNAL(triggered()), this,SLOT(ResetTransformationToIdentity()));
+
   // TRIAL DS
   /*
   QMenu * m = new QMenu(menubar);
@@ -204,7 +218,7 @@ vvMainWindow::vvMainWindow():vvMainWindowBase()
   dicomSeriesSelector = new vvDicomSeriesSelector();
 
   inverseButton->setEnabled(0);
-  actionAdd_Overlay_to_current_Image->setEnabled(0);
+  actionAdd_overlay_image_to_current_image->setEnabled(0);
   actionSave_As->setEnabled(0);
   actionAdd_VF_to_current_Image->setEnabled(0);
   actionAdd_fusion_image->setEnabled(0);
@@ -250,9 +264,12 @@ vvMainWindow::vvMainWindow():vvMainWindowBase()
   connect(actionOpen_Image_With_Time,SIGNAL(triggered()),this,SLOT(OpenImageWithTime()));
   connect(actionMerge_images_as_n_dim_t, SIGNAL(triggered()), this, SLOT(MergeImagesWithTime()));
   connect(actionSave_As,SIGNAL(triggered()),this,SLOT(SaveAs()));
+  connect(actionSave_current_state,SIGNAL(triggered()),this,SLOT(SaveCurrentState()));
+  connect(actionRead_saved_state,SIGNAL(triggered()),this,SLOT(ReadSavedState()));
   connect(actionExit,SIGNAL(triggered()),this,SLOT(close()));
   connect(actionAdd_VF_to_current_Image,SIGNAL(triggered()),this,SLOT(OpenField()));
-  connect(actionNavigation_Help,SIGNAL(triggered()),this,SLOT(ShowHelpDialog()));
+  connect(actionAdd_fusion_image,SIGNAL(triggered()),this,SLOT(SelectFusionImage()));
+  connect(actionAdd_overlay_image_to_current_image,SIGNAL(triggered()), this,SLOT(SelectOverlayImage()));  connect(actionNavigation_Help,SIGNAL(triggered()),this,SLOT(ShowHelpDialog()));
   connect(actionDocumentation,SIGNAL(triggered()),this,SLOT(ShowDocumentation()));
   connect(actionRegister_vv,SIGNAL(triggered()),this,SLOT(PopupRegisterForm()));
 
@@ -270,6 +287,7 @@ vvMainWindow::vvMainWindow():vvMainWindowBase()
   connect(actionNorth_West_Window,SIGNAL(triggered()),this,SLOT(SaveNOScreenshot()));
   connect(actionSouth_East_Window,SIGNAL(triggered()),this,SLOT(SaveSEScreenshot()));
   connect(actionSouth_West_Window,SIGNAL(triggered()),this,SLOT(SaveSOScreenshot()));
+  connect(actionSave_all_slices,SIGNAL(triggered()),this,SLOT(SaveScreenshotAllSlices()));
 
   connect(DataTree,SIGNAL(itemSelectionChanged()),this,SLOT(ImageInfoChanged()));
   connect(DataTree,SIGNAL(itemClicked(QTreeWidgetItem*, int)),this,
@@ -289,9 +307,10 @@ vvMainWindow::vvMainWindow():vvMainWindowBase()
   connect(linkPanel,SIGNAL(addLink(QString,QString)),this,SLOT(AddLink(QString,QString)));
   connect(linkPanel,SIGNAL(removeLink(QString,QString)),this,SLOT(RemoveLink(QString,QString)));
   connect(overlayPanel,SIGNAL(VFPropertyUpdated(int,int,int,int,double,double,double)),this,SLOT(SetVFProperty(int,int,int,int,double,double,double)));
-  connect(overlayPanel,SIGNAL(OverlayPropertyUpdated(int)),this,SLOT(SetOverlayProperty(int)));
-  connect(overlayPanel,SIGNAL(FusionPropertyUpdated(int,int,double,double)),
-          this,SLOT(SetFusionProperty(int,int,double,double)));
+  connect(overlayPanel,SIGNAL(OverlayPropertyUpdated(int,int,double,double)),
+          this,SLOT(SetOverlayProperty(int,int,double,double)));
+  connect(overlayPanel,SIGNAL(FusionPropertyUpdated(int,int,int,double,double)),
+          this,SLOT(SetFusionProperty(int,int,int,double,double)));
   connect(landmarksPanel,SIGNAL(UpdateRenderWindows()),this,SLOT(UpdateRenderWindows()));
 
   playMode = 0;//pause
@@ -472,15 +491,8 @@ void vvMainWindow::OpenVTKContour()
 
 
 //------------------------------------------------------------------------------
-void vvMainWindow::OpenDCStructContour()
+void vvMainWindow::AddDCStructContour(int index, QString file)
 {
-  if (mSlicerManagers.size() > 0) {
-    QString Extensions = "Dicom Files ( *.dcm RS*)";
-    Extensions += ";;All Files (*)";
-    QString file = QFileDialog::getOpenFileName(this,tr("Merge Images"),mInputPathName,Extensions);
-    if (file.isNull())
-      return;
-    int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]);
     vvMeshReader reader;
     reader.SetFilename(file.toStdString());
     vvStructSelector selector;
@@ -500,6 +512,19 @@ void vvMainWindow::OpenDCStructContour()
         AddContour(index,*i,selector.PropagationEnabled());
       QApplication::restoreOverrideCursor();
     }
+}
+
+//------------------------------------------------------------------------------
+void vvMainWindow::OpenDCStructContour()
+{
+  if (mSlicerManagers.size() > 0) {
+    QString Extensions = "Dicom Files ( *.dcm RS*)";
+    Extensions += ";;All Files (*)";
+    QString file = QFileDialog::getOpenFileName(this,tr("Merge Images"),mInputPathName,Extensions);
+    if (file.isNull())
+      return;
+    int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]);
+    AddDCStructContour(index, file);
   }
 }
 //------------------------------------------------------------------------------
@@ -910,10 +935,8 @@ void vvMainWindow::LoadImages(std::vector<std::string> files, vvImageReader::Loa
                 this, SLOT(OverlayChanged(int,double,double)));
         connect(mSlicerManagers.back(), SIGNAL(UpdateFusion(int, double)),
                 this, SLOT(FusionChanged(int,double)));
-        connect(mSlicerManagers.back(), SIGNAL(UpdateWindows(int, int, int)),
-                this,SLOT(WindowsChanged(int, int, int)));
-        connect(mSlicerManagers.back(), SIGNAL(WindowLevelChanged(double, double,int, int)),
-                this,SLOT(WindowLevelChanged(double, double, int, int)));
+        connect(mSlicerManagers.back(), SIGNAL(WindowLevelChanged()),
+                this,SLOT(WindowLevelChanged()));
         connect(mSlicerManagers.back(), SIGNAL(UpdateSlice(int,int)),
                 this,SLOT(UpdateSlice(int,int)));
         connect(mSlicerManagers.back(), SIGNAL(UpdateTSlice(int, int)),
@@ -1018,6 +1041,7 @@ void vvMainWindow::ImageInfoChanged()
   actionSave_As->setEnabled(1);
   actionAdd_VF_to_current_Image->setEnabled(1);
   actionAdd_fusion_image->setEnabled(1);
+  actionAdd_overlay_image_to_current_image->setEnabled(1);
   actionNorth_East_Window->setEnabled(1);
   actionNorth_West_Window->setEnabled(1);
   actionSouth_East_Window->setEnabled(1);
@@ -1119,10 +1143,6 @@ void vvMainWindow::ImageInfoChanged()
         break;
       }
     }
-    windowSpinBox->setValue(mSlicerManagers[index]->GetColorWindow());
-    levelSpinBox->setValue(mSlicerManagers[index]->GetColorLevel());
-    presetComboBox->setCurrentIndex(mSlicerManagers[index]->GetPreset());
-    colorMapComboBox->setCurrentIndex(mSlicerManagers[index]->GetColorMap());
 
     infoPanel->setFileName(image);
     infoPanel->setDimension(dim);
@@ -1144,10 +1164,7 @@ void vvMainWindow::ImageInfoChanged()
         break;
       }
     }
-    windowSpinBox->setValue(mSlicerManagers[index]->GetColorWindow());
-    levelSpinBox->setValue(mSlicerManagers[index]->GetColorLevel());
-    presetComboBox->setCurrentIndex(mSlicerManagers[index]->GetPreset());
-    colorMapComboBox->setCurrentIndex(mSlicerManagers[index]->GetColorMap());
+    WindowLevelChanged();
 
     if (mSlicerManagers[index]->GetSlicer(0)->GetVF()) {
       overlayPanel->getVFName(mSlicerManagers[index]->GetVFName().c_str());
@@ -1160,20 +1177,14 @@ void vvMainWindow::ImageInfoChanged()
     }
     if (mSlicerManagers[index]->GetSlicer(0)->GetOverlay()) {
       overlayPanel->getOverlayName(mSlicerManagers[index]->GetOverlayName().c_str());
-      overlayPanel->getOverlayProperty(mSlicerManagers[index]->GetOverlayColor());
     } else {
       overlayPanel->getOverlayName(mSlicerManagers[index]->GetOverlayName().c_str());
-      overlayPanel->getOverlayProperty(-1);
     }
+    
     if (mSlicerManagers[index]->GetSlicer(0)->GetFusion()) {
       overlayPanel->getFusionName(mSlicerManagers[index]->GetFusionName().c_str());
-      overlayPanel->getFusionProperty(mSlicerManagers[index]->GetFusionOpacity(),
-                                      mSlicerManagers[index]->GetFusionColorMap(),
-                                      mSlicerManagers[index]->GetFusionWindow(),
-                                      mSlicerManagers[index]->GetFusionLevel());
     } else {
       overlayPanel->getFusionName(mSlicerManagers[index]->GetFusionName().c_str());
-      overlayPanel->getFusionProperty(-1, -1,-1,-1);
     }
   }
 }
@@ -1382,7 +1393,7 @@ void vvMainWindow::DisplayChanged(QTreeWidgetItem *clickedItem, int column)
       mSlicerManagers[slicerManagerIndex]->UpdateInfoOnCursorPosition(column-1);
       DisplaySliders(slicerManagerIndex, column-1);
       if(clickedParentItem == clickedItem) {
-        // Toggle or force visibility if it was not on this branch so far
+        // Toggle
         vis = !draw || !vis;
       }
       clickedSlicer->SetActorVisibility("image", 0, vis);
@@ -1624,26 +1635,52 @@ void vvMainWindow::FusionChanged(int visibility, double value)
 //------------------------------------------------------------------------------
 
 //------------------------------------------------------------------------------
-void vvMainWindow::WindowsChanged(int window, int view, int slice)
+void vvMainWindow::WindowLevelChanged()
 {
-  infoPanel->setViews(window, view, slice);
+  // Base image
+  int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]);
+  if(index==-1) return;
+  windowSpinBox->setValue(mSlicerManagers[index]->GetColorWindow());
+  levelSpinBox->setValue(mSlicerManagers[index]->GetColorLevel());
+  colorMapComboBox->setCurrentIndex(mSlicerManagers[index]->GetColorMap());
+  presetComboBox->setCurrentIndex(mSlicerManagers[index]->GetPreset());
+
+  // Overlay image
+  if (mSlicerManagers[index]->GetSlicer(0)->GetOverlay())
+    overlayPanel->getOverlayProperty(mSlicerManagers[index]->GetOverlayColor(),
+                                     mSlicerManagers[index]->GetLinkOverlayWindowLevel(),
+                                     mSlicerManagers[index]->GetOverlayColorWindow(),
+                                     mSlicerManagers[index]->GetOverlayColorLevel());
+  else
+    overlayPanel->getOverlayProperty(-1,0,0.,0.);
+
+  // Fusion image
+  if (mSlicerManagers[index]->GetSlicer(0)->GetFusion())
+    overlayPanel->getFusionProperty(mSlicerManagers[index]->GetFusionOpacity(),
+                                    mSlicerManagers[index]->GetFusionThresholdOpacity(),
+                                    mSlicerManagers[index]->GetFusionColorMap(),
+                                    mSlicerManagers[index]->GetFusionWindow(),
+                                    mSlicerManagers[index]->GetFusionLevel());
+  else
+    overlayPanel->getFusionProperty(-1, -1, -1, -1, -1);
 }
 //------------------------------------------------------------------------------
 
 //------------------------------------------------------------------------------
-void vvMainWindow::WindowLevelChanged(double window, double level,int preset,int colormap)
+void vvMainWindow::WindowLevelEdited()
 {
-  windowSpinBox->setValue(window);
-  levelSpinBox->setValue(level);
-  colorMapComboBox->setCurrentIndex(colormap);
-  presetComboBox->setCurrentIndex(preset);
+  presetComboBox->setCurrentIndex(6);
+  UpdateWindowLevel();
 }
 //------------------------------------------------------------------------------
 
 //------------------------------------------------------------------------------
-void vvMainWindow::WindowLevelEdited()
+void vvMainWindow::SetWindowLevel(double w, double l)
 {
+  windowSpinBox->setValue(w);
+  levelSpinBox->setValue(l);
   presetComboBox->setCurrentIndex(6);
+  colorMapComboBox->setCurrentIndex(0);
   UpdateWindowLevel();
 }
 //------------------------------------------------------------------------------
@@ -1659,8 +1696,7 @@ void vvMainWindow::UpdateWindowLevel()
     mSlicerManagers[index]->SetColorLevel(levelSpinBox->value());
     mSlicerManagers[index]->SetPreset(presetComboBox->currentIndex());
     mSlicerManagers[index]->Render();
-    windowSpinBox->setValue(mSlicerManagers[index]->GetColorWindow());
-    levelSpinBox->setValue(mSlicerManagers[index]->GetColorLevel());
+    WindowLevelChanged();
   }
 }
 //------------------------------------------------------------------------------
@@ -1688,11 +1724,16 @@ void vvMainWindow::SwitchWindowLevel()
 //------------------------------------------------------------------------------
 void vvMainWindow::ApplyWindowLevelToAllImages()
 {
+  int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]);
+  if(index==-1) return;
+  double window = mSlicerManagers[index]->GetColorWindow();
+  double level = mSlicerManagers[index]->GetColorLevel();
+
   for (unsigned int i = 0; i < mSlicerManagers.size(); i++) {
     if (mSlicerManagers[i] == NULL)
       continue;
-    mSlicerManagers[i]->SetColorWindow(windowSpinBox->value());
-    mSlicerManagers[i]->SetColorLevel(levelSpinBox->value());
+    mSlicerManagers[i]->SetColorWindow(window);
+    mSlicerManagers[i]->SetColorLevel(level);
     mSlicerManagers[i]->SetPreset(6);
     mSlicerManagers[i]->Render();
   }
@@ -1793,69 +1834,74 @@ void vvMainWindow::SelectOverlayImage()
 //------------------------------------------------------------------------------
 void vvMainWindow::AddOverlayImage(int index, QString file)
 {
-
-  mInputPathName = itksys::SystemTools::GetFilenamePath(file.toStdString()).c_str();
-  itk::ImageIOBase::Pointer reader = itk::ImageIOFactory::CreateImageIO(
-                                       file.toStdString().c_str(), itk::ImageIOFactory::ReadMode);
-  reader->SetFileName(file.toStdString().c_str());
-  reader->ReadImageInformation();
-  std::string component = reader->GetComponentTypeAsString(reader->GetComponentType());
-  int dimension = reader->GetNumberOfDimensions();
-  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
-  vvProgressDialog progress("Opening " + file.toStdString());
-  qApp->processEvents();
-
-  std::string filename = itksys::SystemTools::GetFilenameWithoutExtension(file.toStdString()).c_str();
-  if (mSlicerManagers[index]->SetOverlay(file.toStdString(),dimension, component)) {
-    //create an item in the tree with good settings
-    QTreeWidgetItem *item = new QTreeWidgetItem();
-    item->setData(0,Qt::UserRole,file.toStdString().c_str());
-    item->setData(1,Qt::UserRole,tr("overlay"));
-    QFileInfo fileinfo(file); //Do not show the path
-    item->setData(COLUMN_IMAGE_NAME,Qt::DisplayRole,fileinfo.fileName());
-    item->setToolTip(COLUMN_IMAGE_NAME, mSlicerManagers[index]->GetListOfAbsoluteFilePathInOneString("overlay").c_str());
+  if (QFile::exists(file))
+  {
+    mInputPathName = itksys::SystemTools::GetFilenamePath(file.toStdString()).c_str();
+    itk::ImageIOBase::Pointer reader = itk::ImageIOFactory::CreateImageIO(
+        file.toStdString().c_str(), itk::ImageIOFactory::ReadMode);
+    reader->SetFileName(file.toStdString().c_str());
+    reader->ReadImageInformation();
+    std::string component = reader->GetComponentTypeAsString(reader->GetComponentType());
+    int dimension = reader->GetNumberOfDimensions();
+    QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
+    vvProgressDialog progress("Opening " + file.toStdString());
     qApp->processEvents();
 
-    for (int j = 1; j <= 4; j++) {
-      item->setData(j,Qt::CheckStateRole,DataTree->topLevelItem(index)->data(j,Qt::CheckStateRole));
-    }
+    std::string filename = itksys::SystemTools::GetFilenameWithoutExtension(file.toStdString()).c_str();
+    if (mSlicerManagers[index]->SetOverlay(file.toStdString(),dimension, component)) {
+      //create an item in the tree with good settings
+      QTreeWidgetItem *item = new QTreeWidgetItem();
+      item->setData(0,Qt::UserRole,file.toStdString().c_str());
+      item->setData(1,Qt::UserRole,tr("overlay"));
+      QFileInfo fileinfo(file); //Do not show the path
+      item->setData(COLUMN_IMAGE_NAME,Qt::DisplayRole,fileinfo.fileName());
+      item->setToolTip(COLUMN_IMAGE_NAME, mSlicerManagers[index]->GetListOfAbsoluteFilePathInOneString("overlay").c_str());
+      qApp->processEvents();
 
-    //Create the buttons for reload and close
-    qApp->processEvents();
-    QTreePushButton* cButton = new QTreePushButton;
-    cButton->setItem(item);
-    cButton->setColumn(COLUMN_CLOSE_IMAGE);
-    cButton->setToolTip(tr("close image"));
-    cButton->setIcon(QIcon(QString::fromUtf8(":/common/icons/exit.png")));
-    connect(cButton,SIGNAL(clickedInto(QTreeWidgetItem*, int)),
-            this,SLOT(CloseImage(QTreeWidgetItem*, int)));
+      for (int j = 1; j <= 4; j++) {
+        item->setData(j,Qt::CheckStateRole,DataTree->topLevelItem(index)->data(j,Qt::CheckStateRole));
+      }
 
-    QTreePushButton* rButton = new QTreePushButton;
-    rButton->setItem(item);
-    rButton->setColumn(COLUMN_RELOAD_IMAGE);
-    rButton->setToolTip(tr("reload image"));
-    rButton->setIcon(QIcon(QString::fromUtf8(":/common/icons/rotateright.png")));
-    connect(rButton,SIGNAL(clickedInto(QTreeWidgetItem*, int)),
-            this,SLOT(ReloadImage(QTreeWidgetItem*, int)));
+      //Create the buttons for reload and close
+      qApp->processEvents();
+      QTreePushButton* cButton = new QTreePushButton;
+      cButton->setItem(item);
+      cButton->setColumn(COLUMN_CLOSE_IMAGE);
+      cButton->setToolTip(tr("close image"));
+      cButton->setIcon(QIcon(QString::fromUtf8(":/common/icons/exit.png")));
+      connect(cButton,SIGNAL(clickedInto(QTreeWidgetItem*, int)),
+          this,SLOT(CloseImage(QTreeWidgetItem*, int)));
 
-    DataTree->topLevelItem(index)->setExpanded(1);
-    DataTree->topLevelItem(index)->addChild(item);
-    DataTree->setItemWidget(item, COLUMN_CLOSE_IMAGE, cButton);
-    DataTree->setItemWidget(item, COLUMN_RELOAD_IMAGE, rButton);
+      QTreePushButton* rButton = new QTreePushButton;
+      rButton->setItem(item);
+      rButton->setColumn(COLUMN_RELOAD_IMAGE);
+      rButton->setToolTip(tr("reload image"));
+      rButton->setIcon(QIcon(QString::fromUtf8(":/common/icons/rotateright.png")));
+      connect(rButton,SIGNAL(clickedInto(QTreeWidgetItem*, int)),
+          this,SLOT(ReloadImage(QTreeWidgetItem*, int)));
 
-    //set the id of the image
-    QString id = DataTree->topLevelItem(index)->data(COLUMN_IMAGE_NAME,Qt::UserRole).toString();
-    item->setData(COLUMN_IMAGE_NAME,Qt::UserRole,id.toStdString().c_str());
-    UpdateTree();
-    qApp->processEvents();
-    ImageInfoChanged();
-    QApplication::restoreOverrideCursor();
-  } else {
-    QApplication::restoreOverrideCursor();
-    QString error = "Cannot import the new image.\n";
-    error += mSlicerManagers[index]->GetLastError().c_str();
-    QMessageBox::information(this,tr("Problem reading image !"),error);
+      DataTree->topLevelItem(index)->setExpanded(1);
+      DataTree->topLevelItem(index)->addChild(item);
+      DataTree->setItemWidget(item, COLUMN_CLOSE_IMAGE, cButton);
+      DataTree->setItemWidget(item, COLUMN_RELOAD_IMAGE, rButton);
+
+      //set the id of the image
+      QString id = DataTree->topLevelItem(index)->data(COLUMN_IMAGE_NAME,Qt::UserRole).toString();
+      item->setData(COLUMN_IMAGE_NAME,Qt::UserRole,id.toStdString().c_str());
+      UpdateTree();
+      qApp->processEvents();
+      ImageInfoChanged();
+      QApplication::restoreOverrideCursor();
+    } else {
+      QApplication::restoreOverrideCursor();
+      QString error = "Cannot import the new image.\n";
+      error += mSlicerManagers[index]->GetLastError().c_str();
+      QMessageBox::information(this,tr("Problem reading image !"),error);
+    }
+    WindowLevelChanged();
   }
+  else
+    QMessageBox::information(this,tr("Problem reading Overlay !"),"File doesn't exist!");
 }
 //------------------------------------------------------------------------------
 
@@ -1911,75 +1957,90 @@ void vvMainWindow::SelectFusionImage()
 //------------------------------------------------------------------------------
 
 //------------------------------------------------------------------------------
-void vvMainWindow::AddFusionImage(int index, QString file)
+void vvMainWindow::ResetTransformationToIdentity()
 {
-  mInputPathName = itksys::SystemTools::GetFilenamePath(file.toStdString()).c_str();
-  itk::ImageIOBase::Pointer reader = itk::ImageIOFactory::CreateImageIO(
-                                       file.toStdString().c_str(), itk::ImageIOFactory::ReadMode);
-  reader->SetFileName(file.toStdString().c_str());
-  reader->ReadImageInformation();
-  std::string component = reader->GetComponentTypeAsString(reader->GetComponentType());
-  if (reader) {
-    QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
-    vvProgressDialog progress("Opening fusion");
-    qApp->processEvents();
+  std::string actorType = DataTree->selectedItems()[0]->data(1,Qt::UserRole).toString().toStdString();
+  int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]);
+  mSlicerManagers[index]->ResetTransformationToIdentity(actorType);
+  ImageInfoChanged();
+}
+//------------------------------------------------------------------------------
 
-    std::string filename = itksys::SystemTools::GetFilenameWithoutExtension(file.toStdString()).c_str();
-    if (mSlicerManagers[index]->SetFusion(file.toStdString(),
-                                          reader->GetNumberOfDimensions(), component)) {
-      //create an item in the tree with good settings
-      QTreeWidgetItem *item = new QTreeWidgetItem();
-      item->setData(0,Qt::UserRole,file.toStdString().c_str());
-      item->setData(1,Qt::UserRole,tr("fusion"));
-      QFileInfo fileinfo(filename.c_str()); //Do not show the path
-      item->setData(COLUMN_IMAGE_NAME,Qt::DisplayRole,fileinfo.fileName());
-      item->setToolTip(COLUMN_IMAGE_NAME, mSlicerManagers[index]->GetListOfAbsoluteFilePathInOneString("fusion").c_str());
+//------------------------------------------------------------------------------
+void vvMainWindow::AddFusionImage(int index, QString file)
+{
+  if (QFile::exists(file))
+  {
+    mInputPathName = itksys::SystemTools::GetFilenamePath(file.toStdString()).c_str();
+    itk::ImageIOBase::Pointer reader = itk::ImageIOFactory::CreateImageIO(
+        file.toStdString().c_str(), itk::ImageIOFactory::ReadMode);
+    reader->SetFileName(file.toStdString().c_str());
+    reader->ReadImageInformation();
+    std::string component = reader->GetComponentTypeAsString(reader->GetComponentType());
+    if (reader) {
+      QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
+      vvProgressDialog progress("Opening fusion");
       qApp->processEvents();
 
-      for (int j = 1; j <= 4; j++) {
-        item->setData(j,Qt::CheckStateRole,DataTree->topLevelItem(index)->data(j,Qt::CheckStateRole));
-      }
+      std::string filename = itksys::SystemTools::GetFilenameWithoutExtension(file.toStdString()).c_str();
+      if (mSlicerManagers[index]->SetFusion(file.toStdString(),
+            reader->GetNumberOfDimensions(), component)) {
+        //create an item in the tree with good settings
+        QTreeWidgetItem *item = new QTreeWidgetItem();
+        item->setData(0,Qt::UserRole,file.toStdString().c_str());
+        item->setData(1,Qt::UserRole,tr("fusion"));
+        QFileInfo fileinfo(filename.c_str()); //Do not show the path
+        item->setData(COLUMN_IMAGE_NAME,Qt::DisplayRole,fileinfo.fileName());
+        item->setToolTip(COLUMN_IMAGE_NAME, mSlicerManagers[index]->GetListOfAbsoluteFilePathInOneString("fusion").c_str());
+        qApp->processEvents();
 
-      //Create the buttons for reload and close
-      qApp->processEvents();
-      QTreePushButton* cButton = new QTreePushButton;
-      cButton->setItem(item);
-      cButton->setColumn(COLUMN_CLOSE_IMAGE);
-      cButton->setToolTip(tr("close image"));
-      cButton->setIcon(QIcon(QString::fromUtf8(":/common/icons/exit.png")));
-      connect(cButton,SIGNAL(clickedInto(QTreeWidgetItem*, int)),
-              this,SLOT(CloseImage(QTreeWidgetItem*, int)));
+        for (int j = 1; j <= 4; j++) {
+          item->setData(j,Qt::CheckStateRole,DataTree->topLevelItem(index)->data(j,Qt::CheckStateRole));
+        }
 
-      QTreePushButton* rButton = new QTreePushButton;
-      rButton->setItem(item);
-      rButton->setColumn(COLUMN_RELOAD_IMAGE);
-      rButton->setToolTip(tr("reload image"));
-      rButton->setIcon(QIcon(QString::fromUtf8(":/common/icons/rotateright.png")));
-      connect(rButton,SIGNAL(clickedInto(QTreeWidgetItem*, int)),
-              this,SLOT(ReloadImage(QTreeWidgetItem*, int)));
+        //Create the buttons for reload and close
+        qApp->processEvents();
+        QTreePushButton* cButton = new QTreePushButton;
+        cButton->setItem(item);
+        cButton->setColumn(COLUMN_CLOSE_IMAGE);
+        cButton->setToolTip(tr("close image"));
+        cButton->setIcon(QIcon(QString::fromUtf8(":/common/icons/exit.png")));
+        connect(cButton,SIGNAL(clickedInto(QTreeWidgetItem*, int)),
+            this,SLOT(CloseImage(QTreeWidgetItem*, int)));
 
-      DataTree->topLevelItem(index)->setExpanded(1);
-      DataTree->topLevelItem(index)->addChild(item);
-      DataTree->setItemWidget(item, COLUMN_CLOSE_IMAGE, cButton);
-      DataTree->setItemWidget(item, COLUMN_RELOAD_IMAGE, rButton);
+        QTreePushButton* rButton = new QTreePushButton;
+        rButton->setItem(item);
+        rButton->setColumn(COLUMN_RELOAD_IMAGE);
+        rButton->setToolTip(tr("reload image"));
+        rButton->setIcon(QIcon(QString::fromUtf8(":/common/icons/rotateright.png")));
+        connect(rButton,SIGNAL(clickedInto(QTreeWidgetItem*, int)),
+            this,SLOT(ReloadImage(QTreeWidgetItem*, int)));
 
-      //set the id of the image
-      QString id = DataTree->topLevelItem(index)->data(COLUMN_IMAGE_NAME,Qt::UserRole).toString();
-      item->setData(COLUMN_IMAGE_NAME,Qt::UserRole,id.toStdString().c_str());
-      UpdateTree();
-      qApp->processEvents();
-      ImageInfoChanged();
-      QApplication::restoreOverrideCursor();
+        DataTree->topLevelItem(index)->setExpanded(1);
+        DataTree->topLevelItem(index)->addChild(item);
+        DataTree->setItemWidget(item, COLUMN_CLOSE_IMAGE, cButton);
+        DataTree->setItemWidget(item, COLUMN_RELOAD_IMAGE, rButton);
+
+        //set the id of the image
+        QString id = DataTree->topLevelItem(index)->data(COLUMN_IMAGE_NAME,Qt::UserRole).toString();
+        item->setData(COLUMN_IMAGE_NAME,Qt::UserRole,id.toStdString().c_str());
+        UpdateTree();
+        qApp->processEvents();
+        ImageInfoChanged();
+        QApplication::restoreOverrideCursor();
+      } else {
+        QApplication::restoreOverrideCursor();
+        QString error = "Cannot import the new image.\n";
+        error += mSlicerManagers[index]->GetLastError().c_str();
+        QMessageBox::information(this,tr("Problem reading image !"),error);
+      }
     } else {
-      QApplication::restoreOverrideCursor();
       QString error = "Cannot import the new image.\n";
-      error += mSlicerManagers[index]->GetLastError().c_str();
       QMessageBox::information(this,tr("Problem reading image !"),error);
     }
-  } else {
-    QString error = "Cannot import the new image.\n";
-    QMessageBox::information(this,tr("Problem reading image !"),error);
   }
+  else
+    QMessageBox::information(this,tr("Problem reading Fusion !"),"File doesn't exist!");
 }
 //------------------------------------------------------------------------------
 
@@ -1999,6 +2060,7 @@ void vvMainWindow::OpenField()
     }
 
   QString Extensions = "Images ( *.mhd)";
+  Extensions += ";;Images ( *.mha)";
   Extensions += ";;Images ( *.vf)";
   QString file = QFileDialog::getOpenFileName(this,tr("Load deformation field"),mInputPathName,Extensions);
   if (!file.isEmpty())
@@ -2128,24 +2190,28 @@ void vvMainWindow::SetVFProperty(int subsampling, int scale, int log, int width,
 
 
 //------------------------------------------------------------------------------
-void vvMainWindow::SetOverlayProperty(int color)
+void vvMainWindow::SetOverlayProperty(int color, int linked, double window, double level)
 {
   int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]);
   if (mSlicerManagers[index]->GetSlicer(0)->GetOverlay()) {
     mSlicerManagers[index]->SetOverlayColor(color);
     mSlicerManagers[index]->SetColorMap(0);
+    mSlicerManagers[index]->SetLinkOverlayWindowLevel(linked);
+    mSlicerManagers[index]->SetOverlayColorWindow(window);
+    mSlicerManagers[index]->SetOverlayColorLevel(level);
     mSlicerManagers[index]->Render();
   }
 }
 //------------------------------------------------------------------------------
 
 //------------------------------------------------------------------------------
-void vvMainWindow::SetFusionProperty(int opacity, int colormap,double window, double level)
+void vvMainWindow::SetFusionProperty(int opacity, int thresOpacity, int colormap,double window, double level)
 {
   int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]);
   if (mSlicerManagers[index]->GetSlicer(0)->GetFusion()) {
-    mSlicerManagers[index]->SetFusionOpacity(opacity);
     mSlicerManagers[index]->SetFusionColorMap(colormap);
+    mSlicerManagers[index]->SetFusionOpacity(opacity);
+    mSlicerManagers[index]->SetFusionThresholdOpacity(thresOpacity);
     mSlicerManagers[index]->SetFusionWindow(window);
     mSlicerManagers[index]->SetFusionLevel(level);
     mSlicerManagers[index]->SetColorMap(0);
@@ -2168,6 +2234,7 @@ void vvMainWindow::SaveAs()
   OutputListeFormat.clear();
   if (dimension == 1) {
     OutputListeFormat.push_back(".mhd");
+    OutputListeFormat.push_back(".mha");
   }
   if (dimension == 2) {
     OutputListeFormat.push_back(".bmp");
@@ -2175,14 +2242,17 @@ void vvMainWindow::SaveAs()
     OutputListeFormat.push_back(".jpeg");
     OutputListeFormat.push_back(".tif");
     OutputListeFormat.push_back(".mhd");
+    OutputListeFormat.push_back(".mha");
     OutputListeFormat.push_back(".hdr");
     OutputListeFormat.push_back(".vox");
   } else if (dimension == 3) {
     OutputListeFormat.push_back(".mhd");
+    OutputListeFormat.push_back(".mha");
     OutputListeFormat.push_back(".hdr");
     OutputListeFormat.push_back(".vox");
   } else if (dimension == 4) {
     OutputListeFormat.push_back(".mhd");
+    OutputListeFormat.push_back(".mha");
   }
   QString Extensions = "AllFiles(*.*)";
   for (int i = 0; i < OutputListeFormat.count(); i++) {
@@ -2226,6 +2296,54 @@ void vvMainWindow::SaveAs()
 }
 //------------------------------------------------------------------------------
 
+//------------------------------------------------------------------------------
+void vvMainWindow::SaveCurrentState()
+{
+  QString Extensions = "XML Files(*.xml)";
+  QString fileName = QFileDialog::getSaveFileName(this,
+                     tr("Save Current Window State"),
+                     "",
+                     Extensions);
+                     
+  SaveCurrentStateAs(fileName.toStdString());
+}
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+void vvMainWindow::SaveCurrentStateAs(const std::string& stateFile)
+{
+  vvSaveState save_state;
+  save_state.Run(this, stateFile);
+  
+  std::cout << "void vvMainWindow::SaveCurrentState()" << std::endl;
+}
+
+//------------------------------------------------------------------------------
+void vvMainWindow::ReadSavedState()
+{
+  QString Extensions = "XML Files(*.xml)";
+  QString fileName = QFileDialog::getOpenFileName(this,
+                     tr("Load Window State"),
+                     "",
+                     Extensions);
+                     
+  ReadSavedStateFile(fileName.toStdString());
+}
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+void vvMainWindow::ReadSavedStateFile(const std::string& stateFile)
+{
+  vvReadState read_state;
+  read_state.Run(this, stateFile);
+}
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+void vvMainWindow::LinkAllImages()
+{
+       linkPanel->linkAll();
+}
 
 //------------------------------------------------------------------------------
 void vvMainWindow::AddLink(QString image1,QString image2)
@@ -2272,10 +2390,13 @@ void vvMainWindow::RemoveLink(QString image1,QString image2)
 //------------------------------------------------------------------------------
 void vvMainWindow::ChangeImageWithIndexOffset(vvSlicerManager *sm, int slicer, int offset)
 {
+  if(mSlicerManagers.size()==1)
+    return;
+
   int index = 0;
   while(sm != mSlicerManagers[index])
     index++;
-  index = (index+offset) % mSlicerManagers.size();
+  index = (index+offset+mSlicerManagers.size()) % mSlicerManagers.size();
 
   QTreeWidgetItem* item = GetItemFromSlicerManager(mSlicerManagers[index]);
   item->setData(slicer+1,Qt::CheckStateRole,2);         //change checkbox
@@ -2484,27 +2605,22 @@ void vvMainWindow::UpdateTSlice(int slicer, int slice)
 void vvMainWindow::UpdateSliceRange(int slicer, int min, int max, int tmin, int tmax)
 {
   int position = int((min+max)/2);
-  int tPosition = int((tmin+tmax)/2);
   if (slicer == 0) {
     NOVerticalSlider->setValue(position);
     NOVerticalSlider->setRange(min,max);
     NOHorizontalSlider->setRange(tmin,tmax);
-    NOHorizontalSlider->setValue(tPosition);
   } else if (slicer == 1) {
     NEVerticalSlider->setValue(position);
     NEVerticalSlider->setRange(min,max);
     NEHorizontalSlider->setRange(tmin,tmax);
-    NEHorizontalSlider->setValue(tPosition);
   } else if (slicer == 2) {
     SOVerticalSlider->setValue(position);
     SOVerticalSlider->setRange(min,max);
     SOHorizontalSlider->setRange(tmin,tmax);
-    SOHorizontalSlider->setValue(tPosition);
   } else if (slicer == 3) {
     SEVerticalSlider->setValue(position);
     SEVerticalSlider->setRange(min,max);
     SEHorizontalSlider->setRange(tmin,tmax);
-    SEHorizontalSlider->setValue(tPosition);
   }
 }
 //------------------------------------------------------------------------------
@@ -2542,6 +2658,56 @@ void vvMainWindow::SaveSEScreenshot()
 //------------------------------------------------------------------------------
 
 
+//------------------------------------------------------------------------------
+void vvMainWindow::SaveScreenshotAllSlices()
+{
+  QVTKWidget *widget = NOViewWidget;
+
+  int index = 0;// GetSlicerIndexFromItem(DataTree->selectedItems()[0]);
+  vvSlicerManager * SM = mSlicerManagers[index];
+  vvImage * image = SM->GetImage();
+  vvSlicer * slicer = SM->GetSlicer(0);
+  int orientation = slicer->GetOrientation();
+  int nbSlices = image->GetSize()[orientation];
+  vtkSmartPointer<vtkRenderWindow>  renderWindow = widget->GetRenderWindow();
+
+  // Select filename base
+  QString filename = QFileDialog::getSaveFileName(this,
+                                                  tr("Save As (filename will be completed by slice number)"),
+                                                  itksys::SystemTools::GetFilenamePath(mSlicerManagers[index]->GetFileName()).c_str(),
+                                                  "Images( *.png);;Images( *.jpg)");
+
+  // Loop on slices
+  for(int i=0; i<nbSlices; i++) {
+    // Change the slice
+    slicer->SetSlice(i); // -> change the slice of the current slicer
+    SM->UpdateSlice(0); // --> this one emit UpdateSlice
+    QCoreApplication::flush(); // -> needed to force display of contours 
+
+    // Screenshot  
+    vtkSmartPointer<vtkWindowToImageFilter> windowToImageFilter = vtkSmartPointer<vtkWindowToImageFilter>::New();
+    windowToImageFilter->SetInput(renderWindow);
+    windowToImageFilter->SetMagnification(1);
+    windowToImageFilter->SetInputBufferTypeToRGBA(); //also record the alpha (transparency) channel
+    windowToImageFilter->Update();
+    
+    vtkSmartPointer<vtkPNGWriter> writer = vtkSmartPointer<vtkPNGWriter>::New();
+    std::string fn = itksys::SystemTools::GetFilenameWithoutLastExtension(filename.toStdString());
+    std::string num = clitk::toString(i);
+    if (i<10) num = "0"+num;
+    if (i<100) num = "0"+num;
+    if (i<1000) num = "0"+num;
+
+    fn = itksys::SystemTools::GetFilenamePath(filename.toStdString()) + "/"+ fn 
+      + "_" + num + itksys::SystemTools::GetFilenameLastExtension(filename.toStdString());
+    writer->SetFileName(fn.c_str());
+    writer->SetInput(windowToImageFilter->GetOutput());
+    writer->Write();
+  }
+}
+//------------------------------------------------------------------------------
+
+
 //------------------------------------------------------------------------------
 void vvMainWindow::SaveScreenshot(QVTKWidget *widget)
 {
@@ -2828,10 +2994,8 @@ vvSlicerManager* vvMainWindow::AddImage(vvImage::Pointer image,std::string filen
           this, SLOT(OverlayChanged(int,double,double)));
   connect(mSlicerManagers.back(), SIGNAL(UpdateFusion(int, double)),
           this, SLOT(FusionChanged(int,double)));
-  connect(mSlicerManagers.back(), SIGNAL(UpdateWindows(int, int, int)),
-          this,SLOT(WindowsChanged(int, int, int)));
-  connect(mSlicerManagers.back(), SIGNAL(WindowLevelChanged(double, double,int, int)),
-          this,SLOT(WindowLevelChanged(double, double, int, int)));
+  connect(mSlicerManagers.back(), SIGNAL(WindowLevelChanged()),
+          this,SLOT(WindowLevelChanged()));
   connect(mSlicerManagers.back(), SIGNAL(UpdateSlice(int,int)),
           this,SLOT(UpdateSlice(int,int)));
   connect(mSlicerManagers.back(), SIGNAL(UpdateTSlice(int, int)),