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