]> Creatis software - clitk.git/commitdiff
basic GUI state loading/saving functionality
authorRomulo Pinho <pinho@lyon.fnclcc.fr>
Tue, 25 Oct 2011 16:08:23 +0000 (18:08 +0200)
committerRomulo Pinho <pinho@lyon.fnclcc.fr>
Tue, 25 Oct 2011 16:08:23 +0000 (18:08 +0200)
vv/CMakeLists.txt
vv/qt_ui/vvMainWindow.ui
vv/vv.cxx
vv/vvMainWindow.cxx
vv/vvMainWindow.h
vv/vvReadState.cxx [new file with mode: 0644]
vv/vvReadState.h [new file with mode: 0644]
vv/vvSaveState.cxx [new file with mode: 0644]
vv/vvSaveState.h [new file with mode: 0644]

index 3198e7edbbf147c6e44d2b055b3ff872c5d6e8eb..84ffae065db79a01b961670ff500f14ab79e9c43 100644 (file)
@@ -94,6 +94,8 @@ SET(vv_SRCS
   vvImageContour.cxx
   vvBinaryImageOverlayActor.cxx
   vvStructureSetActor.cxx
+  vvSaveState.cxx
+  vvReadState.cxx
   vvROIActor.cxx
   vvBlendImageActor.cxx
   vvToolManager.cxx
index e03cb231421f775fc2fc93c03ea5e447cce40b32..88eddcf87d9aef92a1a510ef23c8ece1fdf94e24 100644 (file)
            <number>2</number>
           </property>
           <item row="0" column="0">
-           <widget class="QVTKWidget" name="NOViewWidget" native="true">
+           <widget class="QVTKWidget" name="NOViewWidget">
             <property name="mouseTracking">
              <bool>true</bool>
             </property>
            <number>2</number>
           </property>
           <item row="0" column="0">
-           <widget class="QVTKWidget" name="SOViewWidget" native="true">
+           <widget class="QVTKWidget" name="SOViewWidget">
             <property name="mouseTracking">
              <bool>true</bool>
             </property>
            <number>2</number>
           </property>
           <item row="0" column="0">
-           <widget class="QVTKWidget" name="NEViewWidget" native="true">
+           <widget class="QVTKWidget" name="NEViewWidget">
             <property name="mouseTracking">
              <bool>true</bool>
             </property>
            <number>2</number>
           </property>
           <item row="0" column="0">
-           <widget class="QVTKWidget" name="SEViewWidget" native="true">
+           <widget class="QVTKWidget" name="SEViewWidget">
             <property name="sizePolicy">
              <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
               <horstretch>0</horstretch>
    <property name="defaultUp">
     <bool>false</bool>
    </property>
-   <widget class="QMenu" name="menuFile">
-    <property name="title">
-     <string>File</string>
-    </property>
-    <addaction name="actionLoad_images"/>
-    <addaction name="actionOpen_Image_With_Time"/>
-    <addaction name="actionMerge_images_as_n_dim_t"/>
-    <addaction name="separator"/>
-    <addaction name="actionSlice_Image_As_Multiple_Images"/>
-    <addaction name="actionOpen_Multiple_Images_As_One"/>
-    <addaction name="separator"/>
-    <addaction name="actionOpen_Dicom"/>
-    <addaction name="actionOpen_Dicom_Struct"/>
-    <addaction name="actionOpen_VTK_contour"/>
-    <addaction name="separator"/>
-    <addaction name="actionSave_As"/>
-    <addaction name="separator"/>
-    <addaction name="actionExit"/>
-   </widget>
    <widget class="QMenu" name="menuHelp">
     <property name="title">
      <string>Help</string>
      <string>Tools</string>
     </property>
    </widget>
+   <widget class="QMenu" name="menuFile">
+    <property name="title">
+     <string>File</string>
+    </property>
+    <addaction name="actionLoad_images"/>
+    <addaction name="actionOpen_Image_With_Time"/>
+    <addaction name="actionMerge_images_as_n_dim_t"/>
+    <addaction name="separator"/>
+    <addaction name="actionSlice_Image_As_Multiple_Images"/>
+    <addaction name="actionOpen_Multiple_Images_As_One"/>
+    <addaction name="separator"/>
+    <addaction name="actionOpen_Dicom"/>
+    <addaction name="actionOpen_Dicom_Struct"/>
+    <addaction name="actionOpen_VTK_contour"/>
+    <addaction name="separator"/>
+    <addaction name="actionSave_As"/>
+    <addaction name="separator"/>
+    <addaction name="actionExit"/>
+    <addaction name="actionSave_current_state"/>
+    <addaction name="actionRead_saved_state"/>
+   </widget>
    <addaction name="menuFile"/>
    <addaction name="menuOverlay"/>
    <addaction name="menuScreenshots"/>
     <string>Save all slices (Top-Left view)</string>
    </property>
   </action>
+  <action name="actionSave_current_state">
+   <property name="icon">
+    <iconset>
+     <normaloff>../icons/filesave.png</normaloff>../icons/filesave.png</iconset>
+   </property>
+   <property name="text">
+    <string>Save current state</string>
+   </property>
+   <property name="toolTip">
+    <string>Save current window and file states</string>
+   </property>
+  </action>
+  <action name="actionRead_saved_state">
+   <property name="icon">
+    <iconset>
+     <normaloff>../icons/filesave.png</normaloff>../icons/filesave.png</iconset>
+   </property>
+   <property name="text">
+    <string>Read Saved State</string>
+   </property>
+  </action>
  </widget>
  <customwidgets>
   <customwidget>
index 301521b4662a8509197d81174b348964b4e5e140..f7b95df3139c056667d8bb622df95263a4f25e05 100644 (file)
--- a/vv/vv.cxx
+++ b/vv/vv.cxx
@@ -168,7 +168,11 @@ int main( int argc, char** argv )
           vtk_log->FlushOn();
           vtk_log->AppendOn();
           vtkOutputWindow::SetInstance(vtk_log);
+        } else if (current == "--state") {
+          window.ReadSavedStateFile(argv[i+1]);
+          i++;
         }
+        
       } else if (parse_mode == P_SEQUENCE) {
         sequence_filenames.push_back(current);
       } else if (parse_mode == P_WINDOW) {
index 7b83b7005b6e4debcc39be72531d4493c70cbd52..8884cbbb95bc3b040b4e093d80016ae84c5caf94 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,6 +146,16 @@ 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);
@@ -255,6 +267,8 @@ 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()));
@@ -292,6 +306,7 @@ vvMainWindow::vvMainWindow():vvMainWindowBase()
 
   connect(this,SIGNAL(customContextMenuRequested(QPoint)),this,SLOT(ShowContextMenu(QPoint)));
 
+#include "vvSaveState.h"
   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)));
@@ -2263,6 +2278,48 @@ 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::AddLink(QString image1,QString image2)
index 8a2f0365ae6361f9a8d31e36edc6d22277292a3c..dfcbca6d40319fff99f8a23e1dd0edd5b6012240 100644 (file)
@@ -40,6 +40,7 @@ class vtkRenderer;
 class vtkMatrix4x4;
 class vvDicomSeriesSelector;
 class vvSlicer;
+class QTreeWidget;
 
 //------------------------------------------------------------------------------
 class vvMainWindow: public vvMainWindowBase,
@@ -60,9 +61,12 @@ class vvMainWindow: public vvMainWindowBase,
   void AddContour(int image_index, vvMesh::Pointer contour, bool propagation);
   ///This is used to show an image when opened or computed
   void ShowLastImage();
+  void SaveCurrentStateAs(const std::string& stateFile);
+  void ReadSavedStateFile(const std::string& stateFile);
 
   virtual void UpdateCurrentSlicer();
   virtual QTabWidget * GetTab();
+  QTreeWidget* GetTree() { return DataTree; }
   //vvMainWindowToolInfo * GetInfoForTool();
 //   void AddRunningTool(vvToolCreatorBase * tool);
 
@@ -82,6 +86,8 @@ public slots:
   ///Open a vtkPolyData surface mesh and display it over the current image
   void OpenVTKContour();
   void SaveAs();
+  void SaveCurrentState();
+  void ReadSavedState();
   void CurrentImageChanged(std::string id);
   void CurrentPickedImageChanged(std::string id);
   void ImageInfoChanged();
diff --git a/vv/vvReadState.cxx b/vv/vvReadState.cxx
new file mode 100644 (file)
index 0000000..6ad544b
--- /dev/null
@@ -0,0 +1,144 @@
+#include "vvReadState.h"
+#include "vvMainWindow.h"
+
+#include <qtreewidget.h>
+
+#include <QFile>
+#include <QXmlStreamReader>
+
+#include <cassert>
+#include <string>
+
+vvReadState::vvReadState() : m_XmlReader(new QXmlStreamReader), m_File(new QFile)
+{
+}
+
+vvReadState::~vvReadState()
+{
+}
+
+void vvReadState::Run(vvMainWindow* vvWindow, const std::string& file)
+{
+  assert(vvWindow);
+
+  m_File->setFileName(file.c_str());
+  m_File->open(QIODevice::ReadOnly);
+  m_XmlReader->setDevice(m_File.get());
+  m_Window = vvWindow;
+  QTreeWidget* tree = m_Window->GetTree();
+  m_TreeItemCount = tree->topLevelItemCount();
+
+  ReadGUI();
+  ReadTree();
+}
+
+void vvReadState::ReadTree()
+{
+  std::string value;
+  
+  while (!m_XmlReader->atEnd()) {
+    m_XmlReader->readNext();
+    value = m_XmlReader->qualifiedName().toString().toStdString();
+    if (m_XmlReader->isStartElement()) {
+      if (value == "Image") 
+        value = ReadImage();
+    } 
+  }
+  
+  if (m_XmlReader->hasError())
+    std::cout << "Error " << m_XmlReader->error() << " XML " << std::endl;
+}
+
+std::string  vvReadState::ReadImage()
+{
+  std::string value;
+  int current_index = -1;
+  std::vector<std::string> files(1);
+
+  QXmlStreamAttributes attributes = m_XmlReader->attributes();
+  if (!m_XmlReader->hasError())
+    current_index = attributes.value("Index").toString().toInt();
+
+  current_index += m_TreeItemCount;
+  
+  while (!m_XmlReader->isEndElement() || value != "Image") { 
+    m_XmlReader->readNext();
+    value = m_XmlReader->qualifiedName().toString().toStdString();
+    //std::cout << "Value = " << value << std::endl;
+    if (m_XmlReader->isStartElement()) {
+      if (value == "FileName") {
+        files[0] = m_XmlReader->readElementText().toStdString();
+        if (!m_XmlReader->hasError()) {
+          m_Window->LoadImages(files, vvImageReader::IMAGE);
+        }
+      }
+      else if (current_index >= 0) {
+        if (value == "Fusion") 
+          value = ReadFusion(current_index);
+        else if (value == "Overlay")
+          value = ReadOverlay(current_index);
+        else if (value == "Vector")
+          value = ReadVector(current_index);
+      }
+    }
+  }
+
+  return value;
+}
+
+std::string vvReadState::ReadFusion(int index)
+{
+  std::string file, value;
+  while (!m_XmlReader->isEndElement() || value != "Fusion") {
+    m_XmlReader->readNext();
+    value = m_XmlReader->qualifiedName().toString().toStdString();
+    if (m_XmlReader->isStartElement()) {
+      if (value == "FileName") {
+        file = m_XmlReader->readElementText().toStdString();
+        if (!m_XmlReader->hasError())
+          m_Window->AddFusionImage(index, file.c_str());
+      }
+    }
+  }
+  return value;
+}
+
+std::string vvReadState::ReadOverlay(int index)
+{
+  std::string file, value;
+  while (!m_XmlReader->isEndElement() || value != "Overlay") {
+    m_XmlReader->readNext();
+    value = m_XmlReader->qualifiedName().toString().toStdString();
+    if (m_XmlReader->isStartElement()) {
+      if (value == "FileName") {
+        file = m_XmlReader->readElementText().toStdString();
+        if (!m_XmlReader->hasError())
+          m_Window->AddOverlayImage(index, file.c_str());
+      }
+    }
+  }
+  return value;
+}
+
+std::string vvReadState::ReadVector(int index)
+{
+  std::string file, value;
+  while (!m_XmlReader->isEndElement() || value != "Vector") {
+    m_XmlReader->readNext();
+    value = m_XmlReader->qualifiedName().toString().toStdString();
+    if (m_XmlReader->isStartElement()) {
+      if (value == "FileName") {
+        file = m_XmlReader->readElementText().toStdString();
+        if (!m_XmlReader->hasError())
+          m_Window->AddField(file.c_str(), index);
+      }
+    }
+  }
+  return value;
+}
+
+void vvReadState::ReadGUI()
+{
+
+}
+
diff --git a/vv/vvReadState.h b/vv/vvReadState.h
new file mode 100644 (file)
index 0000000..f729d8c
--- /dev/null
@@ -0,0 +1,34 @@
+#ifndef VVREADSTATE_H
+#define VVREADSTATE_H
+
+#include <string>
+#include <memory>
+
+class vvMainWindow;
+class QXmlStreamReader;
+class QFile;
+
+class vvReadState
+{
+public:
+  vvReadState();
+  virtual ~vvReadState();
+  
+  virtual void Run(vvMainWindow* vvWindow, const std::string& file);
+    
+protected:
+  
+  void ReadGUI();
+  void ReadTree();
+  std::string  ReadImage();
+  std::string  ReadFusion(int index);
+  std::string  ReadOverlay(int index);
+  std::string  ReadVector(int index);
+
+  std::auto_ptr<QXmlStreamReader> m_XmlReader;
+  std::auto_ptr<QFile> m_File;
+  vvMainWindow* m_Window;
+  int m_TreeItemCount;
+};
+
+#endif // VVREADSTATE_H
diff --git a/vv/vvSaveState.cxx b/vv/vvSaveState.cxx
new file mode 100644 (file)
index 0000000..e573bb9
--- /dev/null
@@ -0,0 +1,119 @@
+#include "vvSaveState.h"
+#include "vvMainWindow.h"
+
+#include <QDir>
+#include <QFile>
+#include <QTreeWidget>
+#include <QTreeWidgetItem>
+#include <QXmlStreamWriter>
+
+#include <cassert>
+#include <string>
+
+vvSaveState::vvSaveState() : m_XmlWriter(new QXmlStreamWriter), m_File(new QFile)
+{
+}
+
+vvSaveState::~vvSaveState()
+{
+}
+
+void vvSaveState::Run(vvMainWindow* vvWindow, const std::string& file)
+{
+  assert(vvWindow);
+
+  m_File->setFileName(file.c_str());
+  m_File->remove();
+  m_File->open(QIODevice::Text | QIODevice::ReadWrite);
+  
+  m_Window = vvWindow;
+
+  m_XmlWriter->setDevice(m_File.get());
+  m_XmlWriter->setAutoFormatting(true);
+  m_XmlWriter->setAutoFormattingIndent(2);
+  m_XmlWriter->writeStartDocument();
+  m_XmlWriter->writeStartElement("VVState");
+  SaveGlobals();
+  SaveGUI();
+  SaveTree();
+  m_XmlWriter->writeEndDocument();
+  m_XmlWriter->writeEndElement();
+}
+
+void vvSaveState::SaveGlobals()
+{
+  m_XmlWriter->writeStartElement("Globals");
+  m_XmlWriter->writeEndElement();
+}
+
+void vvSaveState::SaveTree()
+{
+  QTreeWidget* tree = m_Window->GetTree();
+  QTreeWidgetItem* item;
+  
+  m_XmlWriter->writeStartElement("Images");
+  for (int i = 0; i < tree->topLevelItemCount(); i++) {
+    item = tree->topLevelItem(i);
+    SaveImage(item, i);
+  }
+  m_XmlWriter->writeEndElement();
+}
+
+void vvSaveState::SaveImage(QTreeWidgetItem* item, int index)
+{
+  m_XmlWriter->writeStartElement("Image");
+  
+  std::ostringstream indexStr;
+  indexStr.str("");
+  indexStr << index;
+  m_XmlWriter->writeAttribute("Index", indexStr.str().c_str());
+
+  std::string filename = item->data(0, Qt::UserRole).toString().toStdString();
+  m_XmlWriter->writeTextElement("FileName", QDir::current().absoluteFilePath(filename.c_str()));
+  
+  QTreeWidgetItem* item_child;
+  std::string role;
+  for (int i = 0; i < item->childCount(); i++) {
+    item_child = item->child(i);
+    role = item_child->data(1,Qt::UserRole).toString().toStdString();
+    if (role == "fusion")
+      SaveFusion(item_child);
+    else if (role == "overlay")
+      SaveOverlay(item_child);
+    else if (role == "vector")
+      SaveVector(item_child);
+  }
+  
+  m_XmlWriter->writeEndElement();
+}
+
+void vvSaveState::SaveFusion(QTreeWidgetItem* item)
+{
+  m_XmlWriter->writeStartElement("Fusion");
+  std::string filename = item->data(0, Qt::UserRole).toString().toStdString();
+  m_XmlWriter->writeTextElement("FileName", QDir::current().absoluteFilePath(filename.c_str()));
+  m_XmlWriter->writeEndElement();
+}
+
+void vvSaveState::SaveOverlay(QTreeWidgetItem* item)
+{
+  m_XmlWriter->writeStartElement("Overlay");
+  std::string filename = item->data(0, Qt::UserRole).toString().toStdString();
+  m_XmlWriter->writeTextElement("FileName", QDir::current().absoluteFilePath(filename.c_str()));
+  m_XmlWriter->writeEndElement();
+}
+
+void vvSaveState::SaveVector(QTreeWidgetItem* item)
+{
+  m_XmlWriter->writeStartElement("Vector");
+  std::string filename = item->data(0, Qt::UserRole).toString().toStdString();
+  m_XmlWriter->writeTextElement("FileName", QDir::current().absoluteFilePath(filename.c_str()));
+  m_XmlWriter->writeEndElement();
+}
+
+void vvSaveState::SaveGUI()
+{
+  m_XmlWriter->writeStartElement("GUI");
+  m_XmlWriter->writeEndElement();
+}
+
diff --git a/vv/vvSaveState.h b/vv/vvSaveState.h
new file mode 100644 (file)
index 0000000..7a7cda9
--- /dev/null
@@ -0,0 +1,35 @@
+#ifndef VVSAVESTATE_H
+#define VVSAVESTATE_H
+
+#include <string>
+#include <memory>
+
+class vvMainWindow;
+class QXmlStreamWriter;
+class QFile;
+class QTreeWidgetItem;
+
+class vvSaveState
+{
+public:
+  vvSaveState();
+  virtual ~vvSaveState();
+  
+  virtual void Run(vvMainWindow* vvWindow, const std::string& file);
+    
+protected:
+  
+  void SaveGlobals();
+  void SaveGUI();
+  void SaveTree();
+  void SaveImage(QTreeWidgetItem* item, int index);
+  void SaveFusion(QTreeWidgetItem* item);
+  void SaveOverlay(QTreeWidgetItem* item);
+  void SaveVector(QTreeWidgetItem* item);
+
+  std::auto_ptr<QXmlStreamWriter> m_XmlWriter;
+  std::auto_ptr<QFile> m_File;
+  vvMainWindow* m_Window;
+};
+
+#endif // VVSAVESTATE_H