]> Creatis software - clitk.git/blob - vv/vvToolROIManager.cxx
Merge branch 'VTK6_Qt5_4DROI' into VTK6_Qt5
[clitk.git] / vv / vvToolROIManager.cxx
1 /*=========================================================================
2   Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
3
4   Authors belong to:
5   - University of LYON              http://www.universite-lyon.fr/
6   - Léon Bérard cancer center       http://www.centreleonberard.fr
7   - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
8
9   This software is distributed WITHOUT ANY WARRANTY; without even
10   the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11   PURPOSE.  See the copyright notices for more information.
12
13   It is distributed under dual licence
14
15   - BSD        See included LICENSE.txt file
16   - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
17   ===========================================================================**/
18
19 // vv
20 #include "vvToolROIManager.h"
21 #include "vvImageReader.h"
22 #include "vvImageWriter.h"
23 #include "vvROIActor.h"
24 #include "vvSlicer.h"
25 #include "vvMeshReader.h"
26 #include "vvStructSelector.h"
27 #include "vvToolManager.h"
28 #include "vvProgressDialog.h"
29
30 // clitk
31 #include "clitkDicomRTStruct2ImageFilter.h"
32 #include "clitkDicomRT_StructureSet.h"
33
34 // Qt
35 #include <QFileDialog>
36 #include <QMessageBox>
37 #include <QColorDialog>
38 #include <QAbstractEventDispatcher>
39 #include <QXmlStreamReader>
40
41 // vtk
42 #include <vtkLookupTable.h>
43 #include <vtkRenderWindow.h>
44
45 //------------------------------------------------------------------------------
46 // Create the tool and automagically (I like this word) insert it in
47 // the main window menu.
48 ADD_TOOL(vvToolROIManager);
49 //------------------------------------------------------------------------------
50
51 //------------------------------------------------------------------------------
52 vvToolROIManager::vvToolROIManager(vvMainWindowBase * parent, Qt::WindowFlags f):
53   QWidget(parent->GetTab()),
54   vvToolBase<vvToolROIManager>(parent),
55   Ui::vvToolROIManager()
56
57   // Store parent
58   mMainWindow = parent;
59
60   // Assume the initial tab ROI index is 2
61   mIndexFirstTab = 2;
62
63   // Build the UI
64   Ui_vvToolROIManager::setupUi(this);
65   setAttribute(Qt::WA_DeleteOnClose);
66   mTree->clear();
67   mTree->header()->resizeSection(0, 30);
68   mGroupBoxROI->setEnabled(false);
69
70   // Disable "Load dicom" button -> not useful
71   frame_4->hide();
72
73   // Set default LUT
74   mDefaultLUTColor = vtkSmartPointer<vtkLookupTable>::New();
75   for(int i=0; i<mDefaultLUTColor->GetNumberOfTableValues(); i++) {
76     double r = (rand()/(RAND_MAX+1.0));
77     double v = (rand()/(RAND_MAX+1.0));
78     double b = (rand()/(RAND_MAX+1.0));
79     mDefaultLUTColor->SetTableValue(i, r, v, b);
80   }
81 #include "vvDefaultLut.h"
82
83   // Initialization
84   mCurrentSlicerManager = NULL;
85   mNumberOfVisibleROI = 0;
86   mNumberOfVisibleContourROI = 0;
87   mOpenFileBrowserFlag = true; // by default, open the file browser when the tool is launched
88
89   // InitializeNewTool must be called to start
90 }
91 //------------------------------------------------------------------------------
92
93
94 //------------------------------------------------------------------------------
95 vvToolROIManager::~vvToolROIManager()
96
97   mROIActorsList.clear();
98 }
99 //------------------------------------------------------------------------------
100
101
102 //------------------------------------------------------------------------------
103 // STATIC
104 void vvToolROIManager::Initialize()
105
106   SetToolName("ROIManager");
107   SetToolMenuName("Open ROI (binary image or RT-STRUCT)");
108   SetToolIconFilename(":/common/icons/tool-roi.png");
109   SetToolTip("Display ROI from a binary image or a RT-struct file.");
110   SetToolExperimental(false);
111 }
112 //------------------------------------------------------------------------------
113
114
115
116 //------------------------------------------------------------------------------
117 void  vvToolROIManager::InitializeNewTool(bool ReadStateFlag)
118
119   // Check if we need to start a new tool or read in the state file to load
120   if (ReadStateFlag == false) {
121     // Select the current image as the target
122     int i = mMainWindow->GetSlicerManagerCurrentIndex();
123     mCurrentSlicerManager = mMainWindow->GetSlicerManagers()[i];
124     // Set it as current (only if not ReadStateFlag)
125     mMainWindow->GetTab()->setCurrentIndex(mIndexFirstTab);
126   }
127   else {
128     // Set the first tab in front to avoid displaying two roimanager
129     // in the same tab. Because toolcreatorBase do show() and I am too
130     // lazy to find another solution now.
131     mMainWindow->GetTab()->setCurrentIndex(0);
132
133     // Read all information in the XML
134     ReadXMLInformation();
135
136     // Check that a ROI is not already present
137     mInitialImageIndex += mImageIndex;
138     if (mInitialImageIndex >= mMainWindow->GetSlicerManagers().size()) {
139       QMessageBox::warning(this, "ROIManager tool", QString("Image index %1 not found, abort.").arg(mInitialImageIndex));
140       close();
141       return;
142     }
143
144     // Set the attached image
145     mCurrentSlicerManager = mMainWindow->GetSlicerManagers()[mInitialImageIndex];
146   }
147
148   // Tab insertion, check that another tool does not already exist for this image
149   std::vector<vvToolBaseBase*> & tools =
150     vvToolManager::GetInstance()->GetToolCreatorFromName(GetToolName())->GetListOfTool();
151   if (tools.size() > 0) {
152     for(uint i=0; i<tools.size()-1; i++) { // current tool is last
153       vvToolROIManager * t = dynamic_cast<vvToolROIManager*>(tools[i]);
154       if (mCurrentSlicerManager == t->GetCurrentSlicerManager()) {
155         QMessageBox::warning(this, "ROIManager tool", "Already a ROI for this image, abort.");
156         close();
157         return;
158       }
159     }
160   }
161
162   // Display tool in the correct tab
163   QWidget * tab = mMainWindow->GetTab()->findChild<QWidget*>("ROItab");
164   tab->layout()->addWidget(this);
165
166   // If not read in a file we start automatically the browser to load
167   // a roi file (binary image)
168   if (ReadStateFlag) {
169     mOpenFileBrowserFlag = false;
170     InputIsSelected(mCurrentSlicerManager);
171     mOpenFileBrowserFlag = true;
172   }
173   else InputIsSelected(mCurrentSlicerManager);
174
175   // Load ROI (if read in the XML files, empty otherwise)
176   OpenBinaryImage(mROIFilenames);
177
178   // Set the options to the open roi
179   for(uint i=0; i<mROIActorsParamList.size(); i++) {
180     QSharedPointer<vvROIActor> roi = mROIActorsList[i];
181     QSharedPointer<vvROIActor> roi_param = mROIActorsParamList[i];
182     roi->CopyParameters(roi_param);
183
184     // Update Tree
185     QTreeWidgetItem * w = mMapROIToTreeWidget[roi->GetROI()];
186     QBrush brush(QColor(roi->GetROI()->GetDisplayColor()[0]*255,
187                         roi->GetROI()->GetDisplayColor()[1]*255,
188                         roi->GetROI()->GetDisplayColor()[2]*255));
189     brush.setStyle(Qt::SolidPattern);
190     w->setBackground(2, brush);
191     w->setText(3, QString("%1").arg(roi->GetDepth()));
192     roi->UpdateColor();
193   }
194
195   // Display the ROI
196   UpdateAllContours();
197   UpdateAllROIStatus();
198
199   // Connect event from mainwindow to this widget
200   connect(mMainWindow, SIGNAL(AnImageIsBeingClosed(vvSlicerManager *)),
201           this, SLOT(AnImageIsBeingClosed(vvSlicerManager *)));
202   connect(mMainWindow, SIGNAL(SelectedImageHasChanged(vvSlicerManager *)),
203           this, SLOT(SelectedImageHasChanged(vvSlicerManager *)));
204   connect(mOpenBinaryButton, SIGNAL(clicked()), this, SLOT(Open()));
205   //  connect(mOpenDicomButton, SIGNAL(clicked()), this, SLOT(OpenDicomImage()));
206   connect(mTree, SIGNAL(itemSelectionChanged()), this, SLOT(SelectedItemChangedInTree()));
207   connect(mCheckBoxShow, SIGNAL(toggled(bool)), this, SLOT(VisibleROIToggled(bool)));
208   connect(mOpacitySlider, SIGNAL(valueChanged(int)), this, SLOT(OpacityChanged(int)));
209   connect(mChangeColorButton, SIGNAL(clicked()), this, SLOT(ChangeColor()));
210   connect(mContourCheckBoxShow, SIGNAL(toggled(bool)), this, SLOT(VisibleContourROIToggled(bool)));
211   connect(mChangeContourColorButton, SIGNAL(clicked()), this, SLOT(ChangeContourColor()));
212   connect(mContourWidthSpinBox, SIGNAL(valueChanged(int)), this, SLOT(ChangeContourWidth(int)));
213   connect(mDepthSpinBox, SIGNAL(valueChanged(int)), this, SLOT(ChangeDepth(int)));
214   connect(mReloadButton, SIGNAL(clicked()), this, SLOT(ReloadCurrentROI()));
215   connect(mCheckBoxShowAll, SIGNAL(stateChanged(int)), this, SLOT(AllVisibleROIToggled(int)));
216   connect(mContourCheckBoxShowAll, SIGNAL(toggled(bool)), this, SLOT(AllVisibleContourROIToggled(bool)));
217   connect(mCloseButton, SIGNAL(clicked()), this, SLOT(close()));
218 }
219 //------------------------------------------------------------------------------
220
221
222 //------------------------------------------------------------------------------
223 void vvToolROIManager::InputIsSelected(vvSlicerManager *m)
224
225   // Initialization
226   mCurrentSlicerManager = m;
227   mCurrentImage = mCurrentSlicerManager->GetImage();
228
229   // Change gui
230   mLabelInputInfo->setText(QString("%1").arg(m->GetFileName().c_str()));
231
232   // Auto display browser to select new contours
233   if (mOpenFileBrowserFlag) Open();
234 }
235 //------------------------------------------------------------------------------
236
237
238 //------------------------------------------------------------------------------
239 void vvToolROIManager::AnImageIsBeingClosed(vvSlicerManager * m)
240
241   if (m == mCurrentSlicerManager) {
242     close();
243     return;
244   }
245 }
246 //------------------------------------------------------------------------------
247
248
249 //------------------------------------------------------------------------------
250 void vvToolROIManager::close()
251
252   disconnect(mTree, SIGNAL(itemSelectionChanged()), this, SLOT(SelectedItemChangedInTree()));
253   disconnect(mCheckBoxShow, SIGNAL(toggled(bool)), this, SLOT(VisibleROIToggled(bool)));
254   disconnect(mOpacitySlider, SIGNAL(valueChanged(int)), this, SLOT(OpacityChanged(int)));
255   disconnect(mChangeColorButton, SIGNAL(clicked()), this, SLOT(ChangeColor()));
256   disconnect(mContourCheckBoxShow, SIGNAL(toggled(bool)), this, SLOT(VisibleContourROIToggled(bool)));
257   disconnect(mChangeContourColorButton, SIGNAL(clicked()), this, SLOT(ChangeContourColor()));
258   disconnect(mContourWidthSpinBox, SIGNAL(valueChanged(int)), this, SLOT(ChangeContourWidth(int)));
259   disconnect(mDepthSpinBox, SIGNAL(valueChanged(int)), this, SLOT(ChangeDepth(int)));
260
261   // Remove actors
262   for (unsigned int i = 0; i < mROIActorsList.size(); i++) {
263     mROIActorsList[i]->RemoveActors();
264   }
265   mROIActorsList.clear();
266
267   QWidget::close();
268   for(int i=0; i<mCurrentSlicerManager->GetNumberOfSlicers(); i++) {
269     mCurrentSlicerManager->GetSlicer(i)->Render();
270   }
271 }
272 //------------------------------------------------------------------------------
273
274
275 //------------------------------------------------------------------------------
276 void vvToolROIManager::SelectedImageHasChanged(vvSlicerManager * m)
277
278   if (mCurrentSlicerManager == NULL) return;
279   if (m == NULL) return;
280   if (m != mCurrentSlicerManager) hide();
281   else {
282     show();
283   }
284 }
285 //------------------------------------------------------------------------------
286
287
288 //------------------------------------------------------------------------------
289 void vvToolROIManager::Open()
290
291   // Open images
292   QString Extensions = "Images or Dicom-Struct files ( *.mha *.mhd *.hdr *.his *.dcm RS*)";
293   Extensions += ";;All Files (*)";
294   QStringList filename =
295     QFileDialog::getOpenFileNames(this,tr("Open binary image or DICOM RT Struct"),
296                                   mMainWindowBase->GetInputPathName(),Extensions);
297   if (filename.size() == 0) return;
298   if (filename.size() > 1) { OpenBinaryImage(filename); return; }
299
300   // Try to read dicom rt ?
301   clitk::DicomRT_StructureSet::Pointer s = clitk::DicomRT_StructureSet::New();
302   if (s->IsDicomRTStruct(filename[0].toStdString())) OpenDicomImage(filename[0].toStdString());
303   else OpenBinaryImage(filename);
304
305 }
306 //------------------------------------------------------------------------------
307
308
309 //------------------------------------------------------------------------------
310 void vvToolROIManager::OpenBinaryImage(QStringList & filename)
311
312   if (filename.size() == 0) return;
313
314   vvProgressDialog p("Reading ROI ...", true);
315   p.SetCancelButtonEnabled(false);
316   QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
317
318   // For each selected file, open the image
319   for(int i=0; i<filename.size(); i++) {
320     p.SetProgress(i, filename.size());
321
322     // Open Image
323     vvImageReader::Pointer reader = vvImageReader::New();
324     std::vector<std::string> filenames;
325     filenames.push_back(filename[i].toStdString());
326     reader->SetInputFilenames(filenames);
327     reader->Update(vvImageReader::IMAGE);
328
329     if (reader->GetLastError().size() != 0) {
330       std::cerr << "Error while reading " << filename[i].toStdString() << std::endl;
331       QString error = "Cannot open file \n";
332       error += reader->GetLastError().c_str();
333       QMessageBox::information(this,tr("Reading problem"),error);
334       return;
335     }
336     vvImage::Pointer binaryImage = reader->GetOutput();
337     std::ostringstream oss;
338     oss << vtksys::SystemTools::
339       GetFilenameName(vtksys::SystemTools::GetFilenameWithoutLastExtension(filename[i].toStdString()));
340     std::string name = oss.str();
341     AddImage(binaryImage, name, filename[i].toStdString(), mBackgroundValueSpinBox->value(),
342              (!mBGModeCheckBox->isChecked()));
343     mOpenedBinaryImageFilenames.push_back(filename[i]);
344   }
345   QApplication::restoreOverrideCursor();
346
347   // Update the contours
348   UpdateAllContours();
349 }
350 //------------------------------------------------------------------------------
351
352
353 //------------------------------------------------------------------------------
354 void vvToolROIManager::OpenDicomImage(std::string filename)
355
356   // GUI selector of roi
357   vvMeshReader reader;
358   reader.SetFilename(filename);
359
360   vvStructSelector selector;
361   selector.SetStructures(reader.GetROINames());
362   selector.SetPropagationCheckBoxFlag(false);
363
364   if (selector.exec()) {
365     vvProgressDialog p("Reading ROI...", true);
366     p.SetCancelButtonEnabled(false);
367     QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
368
369     // Read information
370     clitk::DicomRT_StructureSet::Pointer s = clitk::DicomRT_StructureSet::New();
371     s->Read(filename);
372
373     // Loop on selected struct
374     std::vector<int> list = selector.getSelectedItems();
375     for (uint i=0; i<list.size(); i++) {
376       p.SetProgress(i, list.size());
377
378       clitk::DicomRTStruct2ImageFilter filter;
379       filter.SetCropMaskEnabled(true);
380       filter.SetImage(mCurrentImage);
381       filter.SetROI(s->GetROIFromROINumber(list[i]));
382       filter.SetWriteOutputFlag(false);
383       filter.Update();
384
385       // Get image
386       vvImage::Pointer binaryImage = vvImage::New();
387       binaryImage->AddVtkImage(filter.GetOutput());
388
389       // Add to gui
390       AddImage(binaryImage, s->GetROIFromROINumber(list[i])->GetName(), "", 0, true); // "" = no filename
391       mOpenedBinaryImageFilenames.push_back(filename.c_str());
392     }
393
394     QApplication::restoreOverrideCursor();
395   }
396   // Update the contours
397   UpdateAllContours();
398 }
399 //------------------------------------------------------------------------------
400
401
402 //------------------------------------------------------------------------------
403 void vvToolROIManager::AddImage(vvImage * binaryImage,
404                                 std::string name,
405                                 std::string filename,
406                                 double BG, bool modeBG)
407
408   // Check Dimension
409   int dim = mCurrentImage->GetNumberOfDimensions();
410   int bin_dim = binaryImage->GetNumberOfDimensions();
411   if (dim < bin_dim) {
412     std::ostringstream os;
413     os << "Error. Loaded binary image is " << bin_dim
414        << "D while selected image is " << dim << "D" << std::endl;
415     QMessageBox::information(this,tr("Reading problem"),os.str().c_str());
416     return;
417   }
418
419   // Compute roi index
420   int n = mROIList.size();
421
422   // Compute the name of the new ROI
423   // std::ostringstream oss;
424   // oss << vtksys::SystemTools::GetFilenameName(vtksys::SystemTools::GetFilenameWithoutLastExtension(filename));
425   // std::string name = oss.str();
426
427   // Set color
428   std::vector<double> color;
429   color.push_back(1);
430   color.push_back(0);
431   color.push_back(0);
432
433   // Create ROI
434   clitk::DicomRT_ROI::Pointer roi = clitk::DicomRT_ROI::New();
435   roi->SetFromBinaryImage(binaryImage, n, name, color, filename);
436
437   // Add a new roi to the list
438   mROIList.push_back(roi);
439
440   // Set BG or FG mode
441   if (modeBG)
442     roi->SetBackgroundValueLabelImage(BG);
443   else
444     roi->SetForegroundValueLabelImage(BG);
445
446   // Change color
447   if (n<mDefaultLUTColor->GetNumberOfTableValues ()) {
448     double * color = mDefaultLUTColor->GetTableValue(n % mDefaultLUTColor->GetNumberOfTableValues ());
449     roi->SetDisplayColor(color[0], color[1], color[2]);
450   }
451
452   // Add a new roi actor
453   QSharedPointer<vvROIActor> actor = QSharedPointer<vvROIActor>(new vvROIActor);
454   actor->SetBGMode(modeBG);
455   actor->SetROI(roi);
456   actor->SetSlicerManager(mCurrentSlicerManager);
457   actor->Initialize(n+1); // depth is n+1 to start at 1
458   mROIActorsList.push_back(actor);
459
460   // CheckBox for "All"
461   if (actor->IsVisible()) mNumberOfVisibleROI++;
462   if (actor->IsContourVisible()) mNumberOfVisibleContourROI++;
463   AllVisibleContourROIToggled(true);
464   
465   // Add ROI in tree
466   mTreeWidgetList.push_back(QSharedPointer<QTreeWidgetItem>(new QTreeWidgetItem(mTree)));
467   QTreeWidgetItem * w = mTreeWidgetList.back().data();
468   w->setText(0, QString("%1").arg(roi->GetROINumber()));
469   w->setText(1, QString("%1").arg(roi->GetName().c_str()));
470   w->setText(3, QString("%1").arg(actor->GetDepth()));
471   QBrush brush(QColor(roi->GetDisplayColor()[0]*255,
472                       roi->GetDisplayColor()[1]*255,
473                       roi->GetDisplayColor()[2]*255));
474   brush.setStyle(Qt::SolidPattern);
475   w->setBackground(2, brush);
476   mMapROIToTreeWidget[roi] = w;
477   mMapTreeWidgetToROI[w] = roi;
478   mTree->resizeColumnToContents(0);
479   mTree->resizeColumnToContents(1);
480
481   // Update
482   UpdateAllROIStatus();
483   
484   if (mCurrentImage->GetNumberOfDimensions() != 3) {
485       
486     //Modifications to avoid display bug with a 4D image
487     QSharedPointer<vvROIActor> CurrentROIActorTemp;
488     CurrentROIActorTemp = mCurrentROIActor;
489     mCurrentROIActor = actor;
490   
491     int VisibleInWindow(0);
492     mCurrentSlicerManager->GetSlicer(VisibleInWindow)->SetCurrentPosition(-VTK_DOUBLE_MAX,-VTK_DOUBLE_MAX,-VTK_DOUBLE_MAX,mCurrentSlicerManager->GetSlicer(VisibleInWindow)->GetMaxCurrentTSlice());
493     mCurrentSlicerManager->GetSlicer(VisibleInWindow)->Render();
494   
495     VisibleROIToggled(false);
496     VisibleROIToggled(true);
497   
498     mCurrentROIActor = CurrentROIActorTemp;
499   
500   }
501   
502 }
503 //------------------------------------------------------------------------------
504
505
506 //------------------------------------------------------------------------------
507 void vvToolROIManager::UpdateAllContours()
508
509   if (mCurrentSlicerManager == NULL) return;
510   // Render loaded ROIs (the first is sufficient)
511   for(unsigned int i=0; i<mROIList.size(); i++) {
512     mROIActorsList[i]->Update();
513   }
514   mCurrentSlicerManager->Render();
515 }
516 //------------------------------------------------------------------------------
517
518
519 //------------------------------------------------------------------------------
520 void vvToolROIManager::UpdateAllROIStatus()
521
522   int nbVisible = 0;
523   int nb = mROIList.size();
524   for(int i=0; i<nb; i++) {
525     if (mROIActorsList[i]->IsVisible()) {
526       nbVisible++;
527     }
528   }
529
530   // change the states
531   disconnect(mCheckBoxShowAll, SIGNAL(stateChanged(int)), this, SLOT(AllVisibleROIToggled(int)));
532   disconnect(mContourCheckBoxShowAll, SIGNAL(toggled(bool)), this, SLOT(AllVisibleContourROIToggled(bool)));
533   if (nbVisible == nb) mCheckBoxShowAll->setCheckState(Qt::Checked);
534   else {
535     if (nbVisible == 0) mCheckBoxShowAll->setCheckState(Qt::Unchecked);
536     else mCheckBoxShowAll->setCheckState(Qt::PartiallyChecked);
537   }
538   connect(mContourCheckBoxShowAll, SIGNAL(toggled(bool)), this, SLOT(AllVisibleContourROIToggled(bool)));
539   connect(mCheckBoxShowAll, SIGNAL(stateChanged(int)), this, SLOT(AllVisibleROIToggled(int)));
540 }
541 //------------------------------------------------------------------------------
542
543
544 //------------------------------------------------------------------------------
545 void vvToolROIManager::SelectedItemChangedInTree()
546
547   // Search which roi is selected
548   QList<QTreeWidgetItem *> l = mTree->selectedItems();
549   if (l.size() == 0) {
550     //    mCurrentROIActor = 0;
551     mCurrentROI = NULL;
552     mGroupBoxROI->setEnabled(false);
553     return;
554   }
555   QTreeWidgetItem * w = l[0];
556   if (w == NULL) return;
557   if (w == 0) return;
558   if (mMapTreeWidgetToROI.find(w) == mMapTreeWidgetToROI.end()) {
559     //    mCurrentROIActor = 0;
560     mCurrentROI = NULL;
561     mGroupBoxROI->setEnabled(false);
562     return;
563   }
564   if (w == NULL) return;
565   clitk::DicomRT_ROI * roi = mMapTreeWidgetToROI[w];
566   if (roi == NULL) return; // sometimes it is called while there is no roi anymore
567
568   // Get selected roi actor
569   int n = roi->GetROINumber();
570   QSharedPointer<vvROIActor> actor = mROIActorsList[n];
571   mCurrentROI = roi;
572   mCurrentROIActor = actor;
573
574   // Warning -> avoid unuseful Render here by disconnect slider
575   // Update GUI
576   disconnect(mTree, SIGNAL(itemSelectionChanged()), this, SLOT(SelectedItemChangedInTree()));
577   disconnect(mCheckBoxShow, SIGNAL(toggled(bool)), this, SLOT(VisibleROIToggled(bool)));
578   disconnect(mOpacitySlider, SIGNAL(valueChanged(int)), this, SLOT(OpacityChanged(int)));
579   disconnect(mChangeColorButton, SIGNAL(clicked()), this, SLOT(ChangeColor()));
580   disconnect(mContourCheckBoxShow, SIGNAL(toggled(bool)), this, SLOT(VisibleContourROIToggled(bool)));
581   disconnect(mChangeContourColorButton, SIGNAL(clicked()), this, SLOT(ChangeContourColor()));
582   disconnect(mContourWidthSpinBox, SIGNAL(valueChanged(int)), this, SLOT(ChangeContourWidth(int)));
583   disconnect(mDepthSpinBox, SIGNAL(valueChanged(int)), this, SLOT(ChangeDepth(int)));
584
585   mROInameLabel->setText(roi->GetName().c_str());
586   mCheckBoxShow->setChecked(actor->IsVisible());
587   mContourCheckBoxShow->setChecked(actor->IsContourVisible());
588   mContourWidthSpinBox->setValue(actor->GetContourWidth());
589   mDepthSpinBox->setValue(actor->GetDepth());
590   w->setText(3, QString("%1").arg(actor->GetDepth()));
591   mOpacitySlider->setValue((int)lrint(actor->GetOpacity()*100));
592   mOpacitySpinBox->setValue((int)lrint(actor->GetOpacity()*100));
593
594   connect(mTree, SIGNAL(itemSelectionChanged()), this, SLOT(SelectedItemChangedInTree()));
595   connect(mCheckBoxShow, SIGNAL(toggled(bool)), this, SLOT(VisibleROIToggled(bool)));
596   connect(mOpacitySlider, SIGNAL(valueChanged(int)), this, SLOT(OpacityChanged(int)));
597   connect(mChangeColorButton, SIGNAL(clicked()), this, SLOT(ChangeColor()));
598   connect(mContourCheckBoxShow, SIGNAL(toggled(bool)), this, SLOT(VisibleContourROIToggled(bool)));
599   connect(mChangeContourColorButton, SIGNAL(clicked()), this, SLOT(ChangeContourColor()));
600   connect(mContourWidthSpinBox, SIGNAL(valueChanged(int)), this, SLOT(ChangeContourWidth(int)));
601   connect(mDepthSpinBox, SIGNAL(valueChanged(int)), this, SLOT(ChangeDepth(int)));
602
603
604   // Set the current color to the selected ROI name
605   mROInameLabel->setAutoFillBackground(true);// # This is important!!
606   // mROInameLabel->setStyleSheet("QLabel { background-color : red; color : blue; }");
607   QColor color = QColor(mCurrentROI->GetDisplayColor()[0]*255,
608                         mCurrentROI->GetDisplayColor()[1]*255,
609                         mCurrentROI->GetDisplayColor()[2]*255);
610   // QString values = QString("%1, %2, %3").arg(color.red()).arg(color.green()).arg(color.blue());
611   // mROInameLabel->setStyleSheet("QLabel { background-color: rgb("+values+"); }");
612
613   QPalette* palette = new QPalette();
614   QColor colorFG = QColor((1-mCurrentROI->GetDisplayColor()[0])*255,
615                           (1-mCurrentROI->GetDisplayColor()[1])*255,
616                           (1-mCurrentROI->GetDisplayColor()[2])*255);
617   palette->setColor(QPalette::WindowText,colorFG);
618   palette->setColor(QPalette::Background, color);
619   mROInameLabel->setPalette(*palette);
620
621   // Enable the group box (in case no selection before)
622   mGroupBoxROI->setEnabled(true);
623 }
624 //------------------------------------------------------------------------------
625
626
627 //------------------------------------------------------------------------------
628 void vvToolROIManager::VisibleROIToggled(bool b)
629
630   if (mCurrentROIActor == NULL) return;
631   if (b == mCurrentROIActor->IsVisible()) return; // nothing to do
632   mCurrentROIActor->SetVisible(b);
633   UpdateAllROIStatus();
634   mCurrentSlicerManager->Render();
635 }
636 //------------------------------------------------------------------------------
637
638
639 //------------------------------------------------------------------------------
640 void vvToolROIManager::VisibleContourROIToggled(bool b)
641
642   if (mCurrentROIActor == NULL) return;
643   if (mCurrentROIActor->IsContourVisible() == b) return; // nothing to do
644   mCurrentROIActor->SetContourVisible(b);
645   mCurrentROIActor->UpdateColor();
646   mCurrentSlicerManager->Render();
647 }
648 //------------------------------------------------------------------------------
649
650
651 //------------------------------------------------------------------------------
652 void vvToolROIManager::OpacityChanged(int v)
653
654   if (mCurrentROIActor == NULL) return;
655   mCurrentROIActor->SetOpacity((double)v/100.0);
656   mCurrentROIActor->UpdateColor();
657   mCurrentSlicerManager->Render();
658 }
659 //------------------------------------------------------------------------------
660
661
662 //------------------------------------------------------------------------------
663 void vvToolROIManager::AllVisibleROIToggled(int b)
664
665   bool status = false;
666   if ((mCheckBoxShowAll->checkState() == Qt::Checked) ||
667       (mCheckBoxShowAll->checkState() == Qt::PartiallyChecked))  status = true;
668
669   for(uint i=0; i<mROIList.size(); i++) {
670     mROIActorsList[i]->SetVisible(status);
671   }
672   if (status) mCheckBoxShowAll->setCheckState(Qt::Checked);
673   else  mCheckBoxShowAll->setCheckState(Qt::Unchecked);
674   mCheckBoxShow->setChecked(status);
675   mCurrentSlicerManager->Render();
676 }
677 //------------------------------------------------------------------------------
678
679
680 //------------------------------------------------------------------------------
681 void vvToolROIManager::AllVisibleContourROIToggled(bool b)
682
683   bool status = false;
684   if ((mContourCheckBoxShowAll->checkState() == Qt::Checked) ||
685       (mContourCheckBoxShowAll->checkState() == Qt::PartiallyChecked))  status = true;
686   // Update current
687   for(uint i=0; i<mROIActorsList.size(); i++) {
688     mROIActorsList[i]->SetContourVisible(status);
689   }
690   // Update current selection
691   if (status) mContourCheckBoxShowAll->setCheckState(Qt::Checked);
692   else  mContourCheckBoxShowAll->setCheckState(Qt::Unchecked);
693   mContourCheckBoxShow->setChecked(status);
694   mCurrentSlicerManager->Render();
695 }
696 //------------------------------------------------------------------------------
697
698
699 //------------------------------------------------------------------------------
700 void vvToolROIManager::ChangeColor()
701
702   if (mCurrentROIActor == NULL) return;
703   QColor color;
704   color.setRgbF(mCurrentROIActor->GetROI()->GetDisplayColor()[0],
705                 mCurrentROIActor->GetROI()->GetDisplayColor()[1],
706                 mCurrentROIActor->GetROI()->GetDisplayColor()[2]);
707   QColor c = QColorDialog::getColor(color, this, "Choose the ROI color");
708   if (!c.isValid()) return;// User cancel
709
710   mCurrentROIActor->GetROI()->SetDisplayColor(c.redF(), c.greenF(), c.blueF());
711   mCurrentROIActor->UpdateColor();
712
713   QTreeWidgetItem * w = mMapROIToTreeWidget[mCurrentROI];
714   QBrush brush(QColor(mCurrentROI->GetDisplayColor()[0]*255,
715                       mCurrentROI->GetDisplayColor()[1]*255,
716                       mCurrentROI->GetDisplayColor()[2]*255));
717   brush.setStyle(Qt::SolidPattern);
718   w->setBackground(2, brush);
719   // Render
720   mCurrentSlicerManager->Render();
721 }
722 //------------------------------------------------------------------------------
723
724
725 //------------------------------------------------------------------------------
726 void vvToolROIManager::ChangeContourColor()
727
728   if (mCurrentROIActor == NULL) return;
729   QColor color;
730   color.setRgbF(mCurrentROIActor->GetContourColor()[0],
731                 mCurrentROIActor->GetContourColor()[1],
732                 mCurrentROIActor->GetContourColor()[2]);
733   //  QColorDialog d(color);
734   QColor c = QColorDialog::getColor(color, this, "Choose the contour color");
735   if (!c.isValid()) return; // User cancel
736   mCurrentROIActor->SetContourColor(c.redF(), c.greenF(), c.blueF());
737   mCurrentROIActor->UpdateColor();
738   mCurrentSlicerManager->Render();
739 }
740 //------------------------------------------------------------------------------
741
742
743 //------------------------------------------------------------------------------
744 void vvToolROIManager::ChangeContourWidth(int n)
745
746   if (mCurrentROIActor == NULL) return;
747   mCurrentROIActor->SetContourWidth(n);
748   mCurrentROIActor->UpdateColor();
749   mCurrentSlicerManager->Render();
750 }
751 //------------------------------------------------------------------------------
752
753
754 //------------------------------------------------------------------------------
755 void vvToolROIManager::ChangeDepth(int n)
756
757   if (mCurrentROIActor == NULL) return;
758   mCurrentROIActor->SetDepth(n);
759   // mCurrentROIActor->UpdateImage(); // FIXME
760   mCurrentSlicerManager->Render();
761   QList<QTreeWidgetItem *> l = mTree->selectedItems();
762   QTreeWidgetItem * w = l[0];
763   w->setText(3, QString("%1").arg(mCurrentROIActor->GetDepth()));
764 }
765 //------------------------------------------------------------------------------
766
767
768 //------------------------------------------------------------------------------
769 void vvToolROIManager::ReloadCurrentROI()
770
771   if (mCurrentROI->GetFilename() == "") {
772     return; // do nothing (contour from rt struct do not reload)
773   }
774
775   // Remove all contours/overlay first
776   bool visible = mCurrentROIActor->IsVisible();
777   bool cvisible = mCurrentROIActor->IsContourVisible();
778   mCurrentROIActor->SetVisible(false);
779   mCurrentROIActor->SetContourVisible(false);
780   mCurrentSlicerManager->Render();
781
782   // Reload image
783   vvImageReader::Pointer reader = vvImageReader::New();
784   reader->SetInputFilename(mCurrentROI->GetFilename());
785   reader->Update(vvImageReader::IMAGE);
786   if (reader->GetLastError() != "") {
787     // No message just ignore (because can be from dicom)
788     // QMessageBox::information(mMainWindowBase, tr("Sorry, error. Could not reload"),
789     //                          reader->GetLastError().c_str());
790     return;
791   }
792
793   // Free the previous image
794   mCurrentROI->GetImage()->GetFirstVTKImageData()->ReleaseData(); // Needed to free
795   mCurrentROI->GetImage()->Reset();
796   mCurrentROI->SetImage(reader->GetOutput());
797
798   mCurrentROIActor->RemoveActors();
799
800   // Update visu
801   mCurrentROIActor->UpdateImage();
802   mCurrentROIActor->SetVisible(visible);
803   mCurrentROIActor->SetContourVisible(cvisible);
804   mCurrentSlicerManager->Render();
805 }
806 //------------------------------------------------------------------------------
807
808
809 //------------------------------------------------------------------------------
810 void  vvToolROIManager::SaveState(std::auto_ptr<QXmlStreamWriter> & m_XmlWriter)
811
812   // Get index of the image
813   int n = mMainWindow->GetSlicerManagers().size();
814   int index=-1;
815   for(int i=0; i<n; i++) {
816     if (mCurrentSlicerManager == mMainWindow->GetSlicerManagers()[i]) index = i;
817   }
818   if (index == -1) {
819     std::cerr << "Error while writing state for ROIManager tool no currentimage founded." << std::endl;
820     return;
821   }
822   m_XmlWriter->writeTextElement("Image_Index", QString::number(index));
823
824
825   // Write ROI
826   for(uint i=0; i<mROIActorsList.size(); i++) {
827     QSharedPointer<vvROIActor> roi = mROIActorsList[i];
828
829     m_XmlWriter->writeStartElement("ROI");
830     m_XmlWriter->writeTextElement("Image", mOpenedBinaryImageFilenames[i]);
831
832     m_XmlWriter->writeStartElement("Overlay");
833     m_XmlWriter->writeAttribute("Red",  QString("%1").arg(roi->GetOverlayColor()[0]));
834     m_XmlWriter->writeAttribute("Green",QString("%1").arg(roi->GetOverlayColor()[1]));
835     m_XmlWriter->writeAttribute("Blue", QString("%1").arg(roi->GetOverlayColor()[2]));
836     m_XmlWriter->writeAttribute("Visible", QString("%1").arg(roi->IsVisible()));
837     m_XmlWriter->writeAttribute("Opacity", QString("%1").arg(roi->GetOpacity()));
838     m_XmlWriter->writeAttribute("Depth", QString("%1").arg(roi->GetDepth()));
839     m_XmlWriter->writeEndElement();
840
841     m_XmlWriter->writeStartElement("Contour");
842     m_XmlWriter->writeAttribute("Red",  QString("%1").arg(roi->GetContourColor()[0]));
843     m_XmlWriter->writeAttribute("Green",QString("%1").arg(roi->GetContourColor()[1]));
844     m_XmlWriter->writeAttribute("Blue", QString("%1").arg(roi->GetContourColor()[2]));
845     m_XmlWriter->writeAttribute("Visible", QString("%1").arg(roi->IsContourVisible()));
846     m_XmlWriter->writeAttribute("Width", QString("%1").arg(roi->GetContourWidth()));
847     m_XmlWriter->writeEndElement();
848
849     m_XmlWriter->writeEndElement();
850   }
851 }
852 //------------------------------------------------------------------------------
853
854
855 //------------------------------------------------------------------------------
856 void vvToolROIManager::ReadXMLInformation()
857
858   std::string value="";
859   mInitialImageIndex = -1;
860   while (!(m_XmlReader->isEndElement() && value == GetToolName().toStdString())) {
861     m_XmlReader->readNext();
862     value = m_XmlReader->qualifiedName().toString().toStdString();
863
864     if (value == "Image_Index")
865       mInitialImageIndex = m_XmlReader->readElementText().toInt();
866
867     if (m_XmlReader->isStartElement()) {
868       if (value == "ROI") {
869         ReadXMLInformation_ROI();
870       }
871     }
872   }
873 }
874 //------------------------------------------------------------------------------
875
876
877 //------------------------------------------------------------------------------
878 void vvToolROIManager::ReadXMLInformation_ROI()
879
880   QString s;
881   std::string value="";
882   QSharedPointer<vvROIActor> param = QSharedPointer<vvROIActor>(new vvROIActor);
883   param->SetVisible(true);
884   clitk::DicomRT_ROI::Pointer roi = clitk::DicomRT_ROI::New();
885   // r->SetDisplayColor(1,1,1);
886   param->SetROI(roi);
887
888   float r=1.0,g=1.0,b=1.0;
889   float cr=1.0,cg=1.0,cb=1.0;
890   float opacity = 0.7;
891   bool visible = true;
892   bool cvisible = true;
893   int width = 1;
894   int depth=1;
895
896   while (!(m_XmlReader->isEndElement() && value == "ROI")) {
897     m_XmlReader->readNext();
898     value = m_XmlReader->qualifiedName().toString().toStdString();
899     if (value == "Image") {
900       s = m_XmlReader->readElementText();
901     }
902
903     if (value == "Overlay" && m_XmlReader->isStartElement()) {
904       QXmlStreamAttributes attributes = m_XmlReader->attributes();
905       if (!m_XmlReader->hasError())
906         r = attributes.value("Red").toString().toFloat();
907       if (!m_XmlReader->hasError())
908         g = attributes.value("Green").toString().toFloat();
909       if (!m_XmlReader->hasError())
910         b = attributes.value("Blue").toString().toFloat();
911       if (!m_XmlReader->hasError())
912         visible = attributes.value("Visible").toString().toInt();
913       if (!m_XmlReader->hasError())
914         opacity = attributes.value("Opacity").toString().toFloat();
915       if (!m_XmlReader->hasError())
916         depth = attributes.value("Depth").toString().toFloat();
917     }
918
919
920     if (value == "Contour" && m_XmlReader->isStartElement()) {
921       QXmlStreamAttributes attributes = m_XmlReader->attributes();
922       if (!m_XmlReader->hasError())
923         cr = attributes.value("Red").toString().toFloat();
924       if (!m_XmlReader->hasError())
925         cg = attributes.value("Green").toString().toFloat();
926       if (!m_XmlReader->hasError())
927         cb = attributes.value("Blue").toString().toFloat();
928       if (!m_XmlReader->hasError())
929         cvisible = attributes.value("Visible").toString().toInt();
930       if (!m_XmlReader->hasError())
931         width = attributes.value("Width").toString().toFloat();
932     }
933     param->SetOverlayColor(r,g,b);
934     param->SetVisible(visible);
935     param->SetOpacity(opacity);
936     param->SetDepth(depth);
937
938     param->SetContourColor(cr,cg,cb);
939     param->SetContourVisible(cvisible);
940     param->SetContourWidth(width);
941   }
942   mROIFilenames.push_back(s);
943   mROIActorsParamList.push_back(param);
944 }
945 //------------------------------------------------------------------------------