]> Creatis software - clitk.git/blob - vv/vvToolROIManager.cxx
Merge branch 'master' of git.creatis.insa-lyon.fr:clitk
[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 "vvROIActor.h"
26 #include "vvMeshReader.h"
27 #include "vvStructSelector.h"
28 #include "vvToolManager.h"
29 #include "vvProgressDialog.h"
30
31 // clitk
32 #include "clitkDicomRTStruct2ImageFilter.h"
33 #include "clitkDicomRT_StructureSet.h"
34
35 // Qt
36 #include <QFileDialog>
37 #include <QMessageBox>
38 #include <QColorDialog>
39 #include <QAbstractEventDispatcher>
40 #include <QXmlStreamReader>
41  
42 // vtk
43 #include <vtkLookupTable.h>
44 #include <vtkRenderWindow.h>
45
46 //------------------------------------------------------------------------------
47 // Create the tool and automagically (I like this word) insert it in
48 // the main window menu.
49 ADD_TOOL(vvToolROIManager);
50 //------------------------------------------------------------------------------
51
52 //------------------------------------------------------------------------------
53 vvToolROIManager::vvToolROIManager(vvMainWindowBase * parent, Qt::WindowFlags f):
54   QWidget(parent->GetTab()), 
55   vvToolBase<vvToolROIManager>(parent),
56   Ui::vvToolROIManager()
57 {
58   // Store parent
59   mMainWindow = parent;
60   
61   // Assume the initial tab ROI index is 2
62   mIndexFirstTab = 2;
63
64   // Build the UI
65   Ui_vvToolROIManager::setupUi(this);
66   setAttribute(Qt::WA_DeleteOnClose);
67   mTree->clear();
68   mTree->header()->resizeSection(0, 30);
69   mGroupBoxROI->setEnabled(false);
70   
71   // Disable "Load dicom" button -> not useful
72   frame_4->hide();
73
74   // Set default LUT
75   mDefaultLUTColor = vtkSmartPointer<vtkLookupTable>::New();
76   for(int i=0; i<mDefaultLUTColor->GetNumberOfTableValues(); i++) {
77     double r = (rand()/(RAND_MAX+1.0));
78     double v = (rand()/(RAND_MAX+1.0));
79     double b = (rand()/(RAND_MAX+1.0));
80     mDefaultLUTColor->SetTableValue(i, r, v, b);
81   }
82 #include "vvDefaultLut.h"
83
84   // Initialization
85   mCurrentSlicerManager = NULL;
86   mNumberOfVisibleROI = 0;
87   mNumberOfVisibleContourROI = 0;
88   mOpenFileBrowserFlag = true; // by default, open the file browser when the tool is launched
89
90   // InitializeNewTool must be called to start
91 }
92 //------------------------------------------------------------------------------
93
94
95 //------------------------------------------------------------------------------
96 vvToolROIManager::~vvToolROIManager()
97 {
98   mROIActorsList.clear();
99 }
100 //------------------------------------------------------------------------------
101
102
103 //------------------------------------------------------------------------------
104 // STATIC
105 void vvToolROIManager::Initialize() {
106   SetToolName("ROIManager");
107   SetToolMenuName("Display ROI (binary image)");
108   SetToolIconFilename(":/common/icons/tool-roi.png");
109   SetToolTip("Display ROI from a binary image.");
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 = qFindChild<QWidget*>(mMainWindow->GetTab(), "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   // Refuse if non 3D image
230   if (mCurrentImage->GetNumberOfDimensions() != 3) {
231     QMessageBox::information(this,tr("Sorry only 3D yet"), tr("Sorry only 3D yet"));
232     close();
233     return;
234   }
235
236   // Change gui
237   mLabelInputInfo->setText(QString("%1").arg(m->GetFileName().c_str()));
238
239   // Auto display browser to select new contours 
240   if (mOpenFileBrowserFlag) Open();
241 }
242 //------------------------------------------------------------------------------
243
244
245 //------------------------------------------------------------------------------
246 void vvToolROIManager::AnImageIsBeingClosed(vvSlicerManager * m)
247 {
248   if (m == mCurrentSlicerManager) { 
249     close();
250     return;
251   }
252 }
253 //------------------------------------------------------------------------------
254
255
256 //------------------------------------------------------------------------------
257 void vvToolROIManager::close()
258 {
259   disconnect(mTree, SIGNAL(itemSelectionChanged()), this, SLOT(SelectedItemChangedInTree()));
260   disconnect(mCheckBoxShow, SIGNAL(toggled(bool)), this, SLOT(VisibleROIToggled(bool)));
261   disconnect(mOpacitySlider, SIGNAL(valueChanged(int)), this, SLOT(OpacityChanged(int)));
262   disconnect(mChangeColorButton, SIGNAL(clicked()), this, SLOT(ChangeColor()));
263   disconnect(mContourCheckBoxShow, SIGNAL(toggled(bool)), this, SLOT(VisibleContourROIToggled(bool)));  
264   disconnect(mChangeContourColorButton, SIGNAL(clicked()), this, SLOT(ChangeContourColor()));
265   disconnect(mContourWidthSpinBox, SIGNAL(valueChanged(int)), this, SLOT(ChangeContourWidth(int)));
266   disconnect(mDepthSpinBox, SIGNAL(valueChanged(int)), this, SLOT(ChangeDepth(int)));
267
268   // Remove actors
269   for (unsigned int i = 0; i < mROIActorsList.size(); i++) {
270     mROIActorsList[i]->RemoveActors();
271   }
272   mROIActorsList.clear();
273
274   QWidget::close();
275   for(int i=0; i<mCurrentSlicerManager->GetNumberOfSlicers(); i++) {
276     mCurrentSlicerManager->GetSlicer(i)->Render();
277   }
278 }
279 //------------------------------------------------------------------------------
280
281
282 //------------------------------------------------------------------------------
283 void vvToolROIManager::SelectedImageHasChanged(vvSlicerManager * m) {
284
285   if (mCurrentSlicerManager == NULL) return;
286   if (m == NULL) return;
287   if (m != mCurrentSlicerManager) hide(); 
288   else {
289     show();
290   }
291 }
292 //------------------------------------------------------------------------------
293
294
295 //------------------------------------------------------------------------------
296 void vvToolROIManager::Open() 
297 {
298   // Open images
299   QString Extensions = "Images or Dicom-Struct files ( *.mha *.mhd *.hdr *.his *.dcm RS*)";
300   Extensions += ";;All Files (*)";
301   QStringList filename =
302     QFileDialog::getOpenFileNames(this,tr("Open binary image or DICOM RT Struct"),
303                                   mMainWindowBase->GetInputPathName(),Extensions);
304   if (filename.size() == 0) return;
305   if (filename.size() > 1) { OpenBinaryImage(filename); return; }
306
307   // Try to read dicom rt ?
308   clitk::DicomRT_StructureSet::Pointer s = clitk::DicomRT_StructureSet::New();
309   if (s->IsDicomRTStruct(filename[0].toStdString())) OpenDicomImage(filename[0].toStdString());
310   else OpenBinaryImage(filename);
311
312 }
313 //------------------------------------------------------------------------------
314
315
316 //------------------------------------------------------------------------------
317 void vvToolROIManager::OpenBinaryImage(QStringList & filename) 
318 {
319   if (filename.size() == 0) return;
320   
321   vvProgressDialog p("Reading ROI ...", true);
322   p.SetCancelButtonEnabled(false);
323   QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
324   
325   // For each selected file, open the image
326   for(int i=0; i<filename.size(); i++) { 
327     p.SetProgress(i, filename.size());
328
329     // Open Image
330     vvImageReader::Pointer reader = vvImageReader::New();
331     std::vector<std::string> filenames;
332     filenames.push_back(filename[i].toStdString());
333     reader->SetInputFilenames(filenames);
334     reader->Update(vvImageReader::IMAGE);
335   
336     if (reader->GetLastError().size() != 0) {
337       std::cerr << "Error while reading " << filename[i].toStdString() << std::endl;
338       QString error = "Cannot open file \n";
339       error += reader->GetLastError().c_str();
340       QMessageBox::information(this,tr("Reading problem"),error);
341       return;
342     }
343     vvImage::Pointer binaryImage = reader->GetOutput();
344     AddImage(binaryImage, filename[i].toStdString(), mBackgroundValueSpinBox->value(),
345              (!mBGModeCheckBox->isChecked()));
346     mOpenedBinaryImageFilenames.push_back(filename[i]);
347   }
348   QApplication::restoreOverrideCursor();
349
350   // Update the contours
351   UpdateAllContours(); 
352 }
353 //------------------------------------------------------------------------------
354
355
356 //------------------------------------------------------------------------------
357 void vvToolROIManager::OpenDicomImage(std::string filename) 
358 {
359   // GUI selector of roi
360   vvMeshReader reader;
361   reader.SetFilename(filename);
362   vvStructSelector selector;
363   selector.SetStructures(reader.GetROINames());
364   selector.SetPropagationCheckBoxFlag(false);
365   
366   if (selector.exec()) { 
367     vvProgressDialog p("Reading ROI...", true);
368     p.SetCancelButtonEnabled(false);
369     QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
370
371     // Read information
372     clitk::DicomRT_StructureSet::Pointer s = clitk::DicomRT_StructureSet::New();
373     s->Read(filename);
374
375     // Loop on selected struct
376     std::vector<int> list = selector.getSelectedItems();
377     for (uint i=0; i<list.size(); i++) {
378       p.SetProgress(i, list.size());
379       
380       clitk::DicomRTStruct2ImageFilter filter;
381       filter.SetCropMaskEnabled(true);
382       filter.SetImage(mCurrentImage);
383       filter.SetROI(s->GetROIFromROINumber(list[i])); 
384       filter.SetWriteOutputFlag(false);
385       filter.Update();  
386
387       // Get image
388       vvImage::Pointer binaryImage = vvImage::New();
389       binaryImage->AddVtkImage(filter.GetOutput());
390     
391       // Add to gui
392       AddImage(binaryImage, s->GetROIFromROINumber(list[i])->GetName(), 0, true);
393       mOpenedBinaryImageFilenames.push_back(filename.c_str());
394     }
395
396     QApplication::restoreOverrideCursor();
397   }
398   // Update the contours
399   UpdateAllContours(); 
400 }
401 //------------------------------------------------------------------------------
402
403
404 //------------------------------------------------------------------------------
405 void vvToolROIManager::AddImage(vvImage * binaryImage, 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   
464   // Add ROI in tree
465   mTreeWidgetList.push_back(QSharedPointer<QTreeWidgetItem>(new QTreeWidgetItem(mTree)));
466   QTreeWidgetItem * w = mTreeWidgetList.back().data();
467   w->setText(0, QString("%1").arg(roi->GetROINumber()));
468   w->setText(1, QString("%1").arg(roi->GetName().c_str()));
469   w->setText(3, QString("%1").arg(actor->GetDepth()));  
470   QBrush brush(QColor(roi->GetDisplayColor()[0]*255, 
471                       roi->GetDisplayColor()[1]*255, 
472                       roi->GetDisplayColor()[2]*255));
473   brush.setStyle(Qt::SolidPattern);
474   w->setBackground(2, brush);
475   mMapROIToTreeWidget[roi] = w;
476   mMapTreeWidgetToROI[w] = roi;
477   mTree->resizeColumnToContents(0);
478   mTree->resizeColumnToContents(1);
479
480   // Update 
481   UpdateAllROIStatus(); 
482 }
483 //------------------------------------------------------------------------------
484
485
486 //------------------------------------------------------------------------------
487 void vvToolROIManager::UpdateAllContours() 
488 {
489   if (mCurrentSlicerManager == NULL) return;
490   // Render loaded ROIs (the first is sufficient)
491   for(unsigned int i=0; i<mROIList.size(); i++) {
492     mROIActorsList[i]->Update();
493   }
494   mCurrentSlicerManager->Render();
495 }
496 //------------------------------------------------------------------------------
497
498
499 //------------------------------------------------------------------------------
500 void vvToolROIManager::UpdateAllROIStatus() {
501   int nbVisible = 0;
502   int nb = mROIList.size();
503   for(int i=0; i<nb; i++) {
504     if (mROIActorsList[i]->IsVisible()) {
505       nbVisible++;
506     }
507   }
508
509   // change the states
510   disconnect(mCheckBoxShowAll, SIGNAL(stateChanged(int)), this, SLOT(AllVisibleROIToggled(int)));  
511   disconnect(mContourCheckBoxShowAll, SIGNAL(toggled(bool)), this, SLOT(AllVisibleContourROIToggled(bool)));
512   if (nbVisible == nb) mCheckBoxShowAll->setCheckState(Qt::Checked);
513   else {
514     if (nbVisible == 0) mCheckBoxShowAll->setCheckState(Qt::Unchecked);
515     else mCheckBoxShowAll->setCheckState(Qt::PartiallyChecked);
516   }
517   connect(mContourCheckBoxShowAll, SIGNAL(toggled(bool)), this, SLOT(AllVisibleContourROIToggled(bool)));
518   connect(mCheckBoxShowAll, SIGNAL(stateChanged(int)), this, SLOT(AllVisibleROIToggled(int)));
519 }
520 //------------------------------------------------------------------------------
521
522
523 //------------------------------------------------------------------------------
524 void vvToolROIManager::SelectedItemChangedInTree() {
525   // Search which roi is selected
526   QList<QTreeWidgetItem *> l = mTree->selectedItems();
527   if (l.size() == 0) {
528     //    mCurrentROIActor = 0;
529     mCurrentROI = NULL;
530     mGroupBoxROI->setEnabled(false);
531     return;
532   }
533   QTreeWidgetItem * w = l[0];
534   if (w == NULL) return;
535   if (w == 0) return;
536   if (mMapTreeWidgetToROI.find(w) == mMapTreeWidgetToROI.end()) {
537     //    mCurrentROIActor = 0;
538     mCurrentROI = NULL;
539     mGroupBoxROI->setEnabled(false);
540     return;
541   }
542   if (w == NULL) return;
543   clitk::DicomRT_ROI * roi = mMapTreeWidgetToROI[w];
544   if (roi == NULL) return; // sometimes it is called while there is no roi anymore
545
546   // Get selected roi actor
547   int n = roi->GetROINumber();
548   QSharedPointer<vvROIActor> actor = mROIActorsList[n];
549   mCurrentROI = roi;
550   mCurrentROIActor = actor;
551
552   // Warning -> avoid unuseful Render here by disconnect slider 
553   // Update GUI
554   disconnect(mTree, SIGNAL(itemSelectionChanged()), this, SLOT(SelectedItemChangedInTree()));
555   disconnect(mCheckBoxShow, SIGNAL(toggled(bool)), this, SLOT(VisibleROIToggled(bool)));
556   disconnect(mOpacitySlider, SIGNAL(valueChanged(int)), this, SLOT(OpacityChanged(int)));
557   disconnect(mChangeColorButton, SIGNAL(clicked()), this, SLOT(ChangeColor()));
558   disconnect(mContourCheckBoxShow, SIGNAL(toggled(bool)), this, SLOT(VisibleContourROIToggled(bool)));  
559   disconnect(mChangeContourColorButton, SIGNAL(clicked()), this, SLOT(ChangeContourColor()));
560   disconnect(mContourWidthSpinBox, SIGNAL(valueChanged(int)), this, SLOT(ChangeContourWidth(int)));
561   disconnect(mDepthSpinBox, SIGNAL(valueChanged(int)), this, SLOT(ChangeDepth(int)));
562
563   mROInameLabel->setText(roi->GetName().c_str());
564   mCheckBoxShow->setChecked(actor->IsVisible());
565   mContourCheckBoxShow->setChecked(actor->IsContourVisible());
566   mContourWidthSpinBox->setValue(actor->GetContourWidth());
567   mDepthSpinBox->setValue(actor->GetDepth());
568   w->setText(3, QString("%1").arg(actor->GetDepth()));
569   mOpacitySlider->setValue((int)lrint(actor->GetOpacity()*100));
570   mOpacitySpinBox->setValue((int)lrint(actor->GetOpacity()*100));
571
572   connect(mTree, SIGNAL(itemSelectionChanged()), this, SLOT(SelectedItemChangedInTree()));
573   connect(mCheckBoxShow, SIGNAL(toggled(bool)), this, SLOT(VisibleROIToggled(bool)));
574   connect(mOpacitySlider, SIGNAL(valueChanged(int)), this, SLOT(OpacityChanged(int)));
575   connect(mChangeColorButton, SIGNAL(clicked()), this, SLOT(ChangeColor()));
576   connect(mContourCheckBoxShow, SIGNAL(toggled(bool)), this, SLOT(VisibleContourROIToggled(bool)));  
577   connect(mChangeContourColorButton, SIGNAL(clicked()), this, SLOT(ChangeContourColor()));
578   connect(mContourWidthSpinBox, SIGNAL(valueChanged(int)), this, SLOT(ChangeContourWidth(int)));
579   connect(mDepthSpinBox, SIGNAL(valueChanged(int)), this, SLOT(ChangeDepth(int)));
580
581   
582   // Set the current color to the selected ROI name
583   mROInameLabel->setAutoFillBackground(true);// # This is important!!
584   // mROInameLabel->setStyleSheet("QLabel { background-color : red; color : blue; }");
585   QColor color = QColor(mCurrentROI->GetDisplayColor()[0]*255,
586                         mCurrentROI->GetDisplayColor()[1]*255,
587                         mCurrentROI->GetDisplayColor()[2]*255);
588   // QString values = QString("%1, %2, %3").arg(color.red()).arg(color.green()).arg(color.blue());
589   // mROInameLabel->setStyleSheet("QLabel { background-color: rgb("+values+"); }");
590
591   QPalette* palette = new QPalette();
592   QColor colorFG = QColor((1-mCurrentROI->GetDisplayColor()[0])*255,
593                           (1-mCurrentROI->GetDisplayColor()[1])*255,
594                           (1-mCurrentROI->GetDisplayColor()[2])*255);
595   palette->setColor(QPalette::WindowText,colorFG);
596   palette->setColor(QPalette::Background, color);
597   mROInameLabel->setPalette(*palette);  
598
599   // Enable the group box (in case no selection before)
600   mGroupBoxROI->setEnabled(true);
601 }
602 //------------------------------------------------------------------------------
603
604
605 //------------------------------------------------------------------------------
606 void vvToolROIManager::VisibleROIToggled(bool b) {
607   if (mCurrentROIActor == NULL) return;
608   if (b == mCurrentROIActor->IsVisible()) return; // nothing to do
609   mCurrentROIActor->SetVisible(b);
610   UpdateAllROIStatus();
611   mCurrentSlicerManager->Render(); 
612 }
613 //------------------------------------------------------------------------------
614
615
616 //------------------------------------------------------------------------------
617 void vvToolROIManager::VisibleContourROIToggled(bool b) {
618   if (mCurrentROIActor == NULL) return;
619   if (mCurrentROIActor->IsContourVisible() == b) return; // nothing to do
620   mCurrentROIActor->SetContourVisible(b);
621   mCurrentROIActor->UpdateColor();
622   mCurrentSlicerManager->Render(); 
623 }
624 //------------------------------------------------------------------------------
625
626
627 //------------------------------------------------------------------------------
628 void vvToolROIManager::OpacityChanged(int v) {
629   if (mCurrentROIActor == NULL) return;
630   mCurrentROIActor->SetOpacity((double)v/100.0);
631   mCurrentROIActor->UpdateColor();
632   mCurrentSlicerManager->Render(); 
633 }
634 //------------------------------------------------------------------------------
635
636
637 //------------------------------------------------------------------------------
638 void vvToolROIManager::AllVisibleROIToggled(int b) {
639   bool status = false;
640   if ((mCheckBoxShowAll->checkState() == Qt::Checked) ||
641       (mCheckBoxShowAll->checkState() == Qt::PartiallyChecked))  status = true;
642
643   for(uint i=0; i<mROIList.size(); i++) {
644     mROIActorsList[i]->SetVisible(status);
645   }
646   if (status) mCheckBoxShowAll->setCheckState(Qt::Checked);
647   else  mCheckBoxShowAll->setCheckState(Qt::Unchecked);
648   mCheckBoxShow->setChecked(status);
649   mCurrentSlicerManager->Render(); 
650 }
651 //------------------------------------------------------------------------------
652
653
654 //------------------------------------------------------------------------------
655 void vvToolROIManager::AllVisibleContourROIToggled(bool b) {
656   bool status = false;
657   if ((mContourCheckBoxShowAll->checkState() == Qt::Checked) ||
658       (mContourCheckBoxShowAll->checkState() == Qt::PartiallyChecked))  status = true;
659   // Update current 
660   for(uint i=0; i<mROIActorsList.size(); i++) {
661     mROIActorsList[i]->SetContourVisible(status);
662   }
663   // Update current selection
664   if (status) mContourCheckBoxShowAll->setCheckState(Qt::Checked);
665   else  mContourCheckBoxShowAll->setCheckState(Qt::Unchecked);
666   mContourCheckBoxShow->setChecked(status);
667   mCurrentSlicerManager->Render(); 
668 }
669 //------------------------------------------------------------------------------
670
671
672 //------------------------------------------------------------------------------
673 void vvToolROIManager::ChangeColor() {
674   if (mCurrentROIActor == NULL) return;
675   QColor color;
676   color.setRgbF(mCurrentROIActor->GetROI()->GetDisplayColor()[0],
677                 mCurrentROIActor->GetROI()->GetDisplayColor()[1],
678                 mCurrentROIActor->GetROI()->GetDisplayColor()[2]);
679   QColor c = QColorDialog::getColor(color, this, "Choose the ROI color");
680   if (!c.isValid()) return;// User cancel
681
682   mCurrentROIActor->GetROI()->SetDisplayColor(c.redF(), c.greenF(), c.blueF());
683   mCurrentROIActor->UpdateColor();
684
685   QTreeWidgetItem * w = mMapROIToTreeWidget[mCurrentROI];
686   QBrush brush(QColor(mCurrentROI->GetDisplayColor()[0]*255,
687                       mCurrentROI->GetDisplayColor()[1]*255,
688                       mCurrentROI->GetDisplayColor()[2]*255));
689   brush.setStyle(Qt::SolidPattern);
690   w->setBackground(2, brush);
691   // Render
692   mCurrentSlicerManager->Render();
693 }
694 //------------------------------------------------------------------------------
695
696
697 //------------------------------------------------------------------------------
698 void vvToolROIManager::ChangeContourColor() {
699   if (mCurrentROIActor == NULL) return;
700   QColor color;
701   color.setRgbF(mCurrentROIActor->GetContourColor()[0], 
702                 mCurrentROIActor->GetContourColor()[1], 
703                 mCurrentROIActor->GetContourColor()[2]);
704   //  QColorDialog d(color);
705   QColor c = QColorDialog::getColor(color, this, "Choose the contour color");
706   if (!c.isValid()) return; // User cancel
707   mCurrentROIActor->SetContourColor(c.redF(), c.greenF(), c.blueF());
708   mCurrentROIActor->UpdateColor();
709   mCurrentSlicerManager->Render();
710 }
711 //------------------------------------------------------------------------------
712
713
714 //------------------------------------------------------------------------------
715 void vvToolROIManager::ChangeContourWidth(int n) {
716   if (mCurrentROIActor == NULL) return;
717   mCurrentROIActor->SetContourWidth(n);
718   mCurrentROIActor->UpdateColor();
719   mCurrentSlicerManager->Render();
720 }
721 //------------------------------------------------------------------------------
722
723
724 //------------------------------------------------------------------------------
725 void vvToolROIManager::ChangeDepth(int n) {
726   if (mCurrentROIActor == NULL) return;
727   mCurrentROIActor->SetDepth(n);
728   // mCurrentROIActor->UpdateImage(); // FIXME  
729   mCurrentSlicerManager->Render();
730   QList<QTreeWidgetItem *> l = mTree->selectedItems();
731   QTreeWidgetItem * w = l[0];
732   w->setText(3, QString("%1").arg(mCurrentROIActor->GetDepth()));
733 }
734 //------------------------------------------------------------------------------
735
736
737 //------------------------------------------------------------------------------
738 void vvToolROIManager::ReloadCurrentROI() {
739
740   // Remove all contours/overlay first
741   bool visible = mCurrentROIActor->IsVisible();
742   bool cvisible = mCurrentROIActor->IsContourVisible();
743   mCurrentROIActor->SetVisible(false);
744   mCurrentROIActor->SetContourVisible(false);
745   mCurrentSlicerManager->Render();
746   
747   // Reload image
748   vvImageReader::Pointer reader = vvImageReader::New();
749   reader->SetInputFilename(mCurrentROI->GetFilename());
750   reader->Update(vvImageReader::IMAGE);
751   if (reader->GetLastError() != "") {
752     // No message just ignore (because can be from dicom)
753     // QMessageBox::information(mMainWindowBase, tr("Sorry, error. Could not reload"), 
754     //                          reader->GetLastError().c_str());
755     return;
756   }
757
758   // Free the previous image
759   mCurrentROI->GetImage()->GetFirstVTKImageData()->ReleaseData(); // Needed to free
760   mCurrentROI->GetImage()->Reset();
761   mCurrentROI->SetImage(reader->GetOutput());
762
763   mCurrentROIActor->RemoveActors();
764
765   // Update visu
766   mCurrentROIActor->UpdateImage();
767   mCurrentROIActor->SetVisible(visible);
768   mCurrentROIActor->SetContourVisible(cvisible);
769   mCurrentSlicerManager->Render();    
770 }
771 //------------------------------------------------------------------------------
772
773
774 //------------------------------------------------------------------------------
775 void  vvToolROIManager::SaveState(std::auto_ptr<QXmlStreamWriter> & m_XmlWriter)
776 {
777   // Get index of the image
778   int n = mMainWindow->GetSlicerManagers().size();
779   int index=-1;
780   for(int i=0; i<n; i++) {
781     if (mCurrentSlicerManager == mMainWindow->GetSlicerManagers()[i]) index = i;
782   }
783   if (index == -1) {
784     std::cerr << "Error while writing state for ROIManager tool no currentimage founded." << std::endl;
785     return;
786   }
787   m_XmlWriter->writeTextElement("Image_Index", QString::number(index));
788
789
790   // Write ROI
791   for(uint i=0; i<mROIActorsList.size(); i++) {
792     QSharedPointer<vvROIActor> roi = mROIActorsList[i];
793
794     m_XmlWriter->writeStartElement("ROI");
795     m_XmlWriter->writeTextElement("Image", mOpenedBinaryImageFilenames[i]);
796
797     m_XmlWriter->writeStartElement("Overlay");
798     m_XmlWriter->writeAttribute("Red",  QString("%1").arg(roi->GetOverlayColor()[0]));
799     m_XmlWriter->writeAttribute("Green",QString("%1").arg(roi->GetOverlayColor()[1]));
800     m_XmlWriter->writeAttribute("Blue", QString("%1").arg(roi->GetOverlayColor()[2]));
801     m_XmlWriter->writeAttribute("Visible", QString("%1").arg(roi->IsVisible()));
802     m_XmlWriter->writeAttribute("Opacity", QString("%1").arg(roi->GetOpacity()));
803     m_XmlWriter->writeAttribute("Depth", QString("%1").arg(roi->GetDepth()));
804     m_XmlWriter->writeEndElement();
805    
806     m_XmlWriter->writeStartElement("Contour");
807     m_XmlWriter->writeAttribute("Red",  QString("%1").arg(roi->GetContourColor()[0]));
808     m_XmlWriter->writeAttribute("Green",QString("%1").arg(roi->GetContourColor()[1]));
809     m_XmlWriter->writeAttribute("Blue", QString("%1").arg(roi->GetContourColor()[2]));
810     m_XmlWriter->writeAttribute("Visible", QString("%1").arg(roi->IsContourVisible()));
811     m_XmlWriter->writeAttribute("Width", QString("%1").arg(roi->GetContourWidth()));
812     m_XmlWriter->writeEndElement();
813
814     m_XmlWriter->writeEndElement();
815   }
816 }
817 //------------------------------------------------------------------------------
818
819
820 //------------------------------------------------------------------------------
821 void vvToolROIManager::ReadXMLInformation() 
822 {
823   std::string value="";
824   mInitialImageIndex = -1;
825   while (!(m_XmlReader->isEndElement() && value == GetToolName().toStdString())) { 
826     m_XmlReader->readNext();
827     value = m_XmlReader->qualifiedName().toString().toStdString();
828     
829     if (value == "Image_Index") 
830       mInitialImageIndex = m_XmlReader->readElementText().toInt();
831     
832     if (m_XmlReader->isStartElement()) {
833       if (value == "ROI") {
834         ReadXMLInformation_ROI();
835       }      
836     }
837   }
838 }
839 //------------------------------------------------------------------------------
840
841
842 //------------------------------------------------------------------------------
843 void vvToolROIManager::ReadXMLInformation_ROI() 
844 {
845   QString s;
846   std::string value="";
847   QSharedPointer<vvROIActor> param = QSharedPointer<vvROIActor>(new vvROIActor);
848   param->SetVisible(true);
849   clitk::DicomRT_ROI::Pointer roi = clitk::DicomRT_ROI::New();
850   // r->SetDisplayColor(1,1,1);
851   param->SetROI(roi);
852
853   float r=1.0,g=1.0,b=1.0;
854   float cr=1.0,cg=1.0,cb=1.0;
855   float opacity = 0.7;
856   bool visible = true;
857   bool cvisible = true;
858   int width = 1;
859   int depth=1;
860
861   while (!(m_XmlReader->isEndElement() && value == "ROI")) { 
862     m_XmlReader->readNext();
863     value = m_XmlReader->qualifiedName().toString().toStdString();
864     if (value == "Image") {
865       s = m_XmlReader->readElementText();
866     }
867     
868     if (value == "Overlay" && m_XmlReader->isStartElement()) {
869       QXmlStreamAttributes attributes = m_XmlReader->attributes();
870       if (!m_XmlReader->hasError())
871         r = attributes.value("Red").toString().toFloat();
872       if (!m_XmlReader->hasError())
873         g = attributes.value("Green").toString().toFloat();
874       if (!m_XmlReader->hasError())
875         b = attributes.value("Blue").toString().toFloat();
876       if (!m_XmlReader->hasError())
877         visible = attributes.value("Visible").toString().toInt();
878       if (!m_XmlReader->hasError())
879         opacity = attributes.value("Opacity").toString().toFloat();
880       if (!m_XmlReader->hasError())
881         depth = attributes.value("Depth").toString().toFloat();
882     }
883
884
885     if (value == "Contour" && m_XmlReader->isStartElement()) {
886       QXmlStreamAttributes attributes = m_XmlReader->attributes();
887       if (!m_XmlReader->hasError())
888         cr = attributes.value("Red").toString().toFloat();
889       if (!m_XmlReader->hasError())
890         cg = attributes.value("Green").toString().toFloat();
891       if (!m_XmlReader->hasError())
892         cb = attributes.value("Blue").toString().toFloat();
893       if (!m_XmlReader->hasError())
894         cvisible = attributes.value("Visible").toString().toInt();
895       if (!m_XmlReader->hasError())
896         width = attributes.value("Width").toString().toFloat();
897     }
898     param->SetOverlayColor(r,g,b);
899     param->SetVisible(visible);
900     param->SetOpacity(opacity); 
901     param->SetDepth(depth); 
902
903     param->SetContourColor(cr,cg,cb);
904     param->SetContourVisible(cvisible);
905     param->SetContourWidth(width);
906   }
907   mROIFilenames.push_back(s);
908   mROIActorsParamList.push_back(param);
909 }
910 //------------------------------------------------------------------------------