From acdc20ec4afc95db1db29bf8d885a3b72c9c7ee0 Mon Sep 17 00:00:00 2001 From: Romulo Pinho Date: Tue, 25 Oct 2011 18:08:23 +0200 Subject: [PATCH] basic GUI state loading/saving functionality --- vv/CMakeLists.txt | 2 + vv/qt_ui/vvMainWindow.ui | 69 ++++++++++++------- vv/vv.cxx | 4 ++ vv/vvMainWindow.cxx | 57 ++++++++++++++++ vv/vvMainWindow.h | 6 ++ vv/vvReadState.cxx | 144 +++++++++++++++++++++++++++++++++++++++ vv/vvReadState.h | 34 +++++++++ vv/vvSaveState.cxx | 119 ++++++++++++++++++++++++++++++++ vv/vvSaveState.h | 35 ++++++++++ 9 files changed, 447 insertions(+), 23 deletions(-) create mode 100644 vv/vvReadState.cxx create mode 100644 vv/vvReadState.h create mode 100644 vv/vvSaveState.cxx create mode 100644 vv/vvSaveState.h diff --git a/vv/CMakeLists.txt b/vv/CMakeLists.txt index 3198e7e..84ffae0 100644 --- a/vv/CMakeLists.txt +++ b/vv/CMakeLists.txt @@ -94,6 +94,8 @@ SET(vv_SRCS vvImageContour.cxx vvBinaryImageOverlayActor.cxx vvStructureSetActor.cxx + vvSaveState.cxx + vvReadState.cxx vvROIActor.cxx vvBlendImageActor.cxx vvToolManager.cxx diff --git a/vv/qt_ui/vvMainWindow.ui b/vv/qt_ui/vvMainWindow.ui index e03cb23..88eddcf 100644 --- a/vv/qt_ui/vvMainWindow.ui +++ b/vv/qt_ui/vvMainWindow.ui @@ -626,7 +626,7 @@ 2 - + true @@ -666,7 +666,7 @@ 2 - + true @@ -708,7 +708,7 @@ 2 - + true @@ -745,7 +745,7 @@ 2 - + 0 @@ -791,25 +791,6 @@ false - - - File - - - - - - - - - - - - - - - - Help @@ -851,6 +832,27 @@ Tools + + + File + + + + + + + + + + + + + + + + + + @@ -1119,6 +1121,27 @@ Save all slices (Top-Left view) + + + + ../icons/filesave.png../icons/filesave.png + + + Save current state + + + Save current window and file states + + + + + + ../icons/filesave.png../icons/filesave.png + + + Read Saved State + + diff --git a/vv/vv.cxx b/vv/vv.cxx index 301521b..f7b95df 100644 --- 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) { diff --git a/vv/vvMainWindow.cxx b/vv/vvMainWindow.cxx index 7b83b70..8884cbb 100644 --- a/vv/vvMainWindow.cxx +++ b/vv/vvMainWindow.cxx @@ -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) diff --git a/vv/vvMainWindow.h b/vv/vvMainWindow.h index 8a2f036..dfcbca6 100644 --- a/vv/vvMainWindow.h +++ b/vv/vvMainWindow.h @@ -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 index 0000000..6ad544b --- /dev/null +++ b/vv/vvReadState.cxx @@ -0,0 +1,144 @@ +#include "vvReadState.h" +#include "vvMainWindow.h" + +#include + +#include +#include + +#include +#include + +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 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 index 0000000..f729d8c --- /dev/null +++ b/vv/vvReadState.h @@ -0,0 +1,34 @@ +#ifndef VVREADSTATE_H +#define VVREADSTATE_H + +#include +#include + +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 m_XmlReader; + std::auto_ptr 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 index 0000000..e573bb9 --- /dev/null +++ b/vv/vvSaveState.cxx @@ -0,0 +1,119 @@ +#include "vvSaveState.h" +#include "vvMainWindow.h" + +#include +#include +#include +#include +#include + +#include +#include + +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 index 0000000..7a7cda9 --- /dev/null +++ b/vv/vvSaveState.h @@ -0,0 +1,35 @@ +#ifndef VVSAVESTATE_H +#define VVSAVESTATE_H + +#include +#include + +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 m_XmlWriter; + std::auto_ptr m_File; + vvMainWindow* m_Window; +}; + +#endif // VVSAVESTATE_H -- 2.45.1