]> Creatis software - clitk.git/blob - vv/vvQDicomSeriesSelector.cxx
34c8e2192873eb61b8a91657ed09e87c9d53fdb3
[clitk.git] / vv / vvQDicomSeriesSelector.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://oncora1.lyon.fnclcc.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 #ifndef VVDICOMSERIESSELECTOR_CXX
19 #define VVDICOMSERIESSELECTOR_CXX
20 #include <itkGDCMImageIO.h>
21 #include <itkGDCMSeriesFileNames.h>
22 #include <gdcmFile.h>
23 #if GDCM_MAJOR_VERSION == 2
24 #include <gdcmImageReader.h>
25 #include <gdcmDataSetHelper.h>
26 #include <gdcmStringFilter.h>
27 #include <gdcmImageHelper.h>
28 #else
29 #include <gdcmDocEntry.h>
30 #endif
31
32 #include "vvQDicomSeriesSelector.h"
33 //#include "vvUserConfig.h"
34
35 //====================================================================
36 vvDicomSeriesSelector::vvDicomSeriesSelector(QWidget* parent)
37   :QDialog(parent)
38 {
39   // Set GUI
40   ui.setupUi(this);
41   // Correct GUI for splitter ...
42   //   QSplitter * splitter = new QSplitter(this);
43   //   splitter->setOrientation(Qt::Horizontal);
44   //   ui.gridLayout1->addWidget(splitter, 0, 0, 1, 1);
45   //   ui.mFrameLeft->setParent(splitter);
46   //   ui.mFrameRight->setParent(splitter);
47   //  ui.toolBox->setCurrentIndex(0);
48
49
50
51   ui.mButtonBox->button(QDialogButtonBox::Open)->setEnabled(false);
52
53   connect(ui.mBrowseButton, SIGNAL(released()),
54           this, SLOT(BrowseButtonRelease()));
55   connect(ui.mSearchButton, SIGNAL(released()),
56           this, SLOT(SearchButtonRelease()));
57   connect(ui.mListWidget, SIGNAL(itemSelectionChanged()),
58           this, SLOT(itemSelectionChanged()));
59   connect(ui.mDicomDetailsListWidget, SIGNAL(itemSelectionChanged()),
60           this, SLOT(itemDetailsSelectionChanged()));
61
62   // Initialization
63   /*    if (config::get_current_path() != QString(0))
64     mFoldername = config::get_current_path();
65     else*/
66   mFoldername = QFileInfo("./").absolutePath();
67
68   mPreviousPath = mFoldername;
69   ui.mFolderLineEdit->setText(mFoldername);
70   //  ui.mTableWidget->setRowCount(0);
71 }
72 //====================================================================
73
74 //====================================================================
75 void vvDicomSeriesSelector::show()
76 {
77   QDialog::show();
78   //grabKeyboard();
79   // ui.mListWidget->grabKeyboard();
80   //  ui.mDicomDetailsListWidget->grabKeyboard();
81 }
82 //====================================================================
83
84 //====================================================================
85 void vvDicomSeriesSelector::close()
86 {
87   QDialog::close();
88   // ui.mListWidget->releaseKeyboard()
89   //releaseKeyboard();
90 }
91 //====================================================================
92
93 //====================================================================
94 void vvDicomSeriesSelector::BrowseButtonRelease()
95 {
96   QFileDialog dialog(this);
97   dialog.setFileMode(QFileDialog::AnyFile);
98   dialog.setFilter("DICOM files (*.dcm); All files (*)");
99   mFoldername = dialog.getExistingDirectory(this,
100                 "Select a folder to find DICOM image",
101                 mPreviousPath);
102   ui.mFolderLineEdit->setText(mFoldername);
103   mPreviousPath = QFileInfo(mFoldername).absolutePath();
104   //    config::set_current_path(mPreviousPath);
105 }
106 //====================================================================
107
108 //====================================================================
109 void vvDicomSeriesSelector::SearchButtonRelease()
110 {
111   typedef itk::GDCMSeriesFileNames NamesGeneratorType;
112   NamesGeneratorType::Pointer nameGenerator = NamesGeneratorType::New();
113   nameGenerator->SetUseSeriesDetails(true);
114   //nameGenerator->SetDirectory(mFoldername.toStdString());
115   nameGenerator->SetRecursive(ui.mIsRecursiveCheckBox->checkState() == Qt::Checked);
116
117   //ds gérer recursive moi-meme pour progress ...
118   nameGenerator->SetInputDirectory(mFoldername.toStdString());
119
120   // insert in table
121   typedef std::vector<std::string> SeriesIdContainer;
122   const SeriesIdContainer & seriesUID = nameGenerator->GetSeriesUIDs();
123
124   for (unsigned int i=0; i<seriesUID.size(); i++) {
125     // std::cout << seriesUID[i] << std::endl; //ds verif existe pas déja
126
127     if (mListOfSeriesFilenames[seriesUID[i]]) {
128       std::cout << seriesUID[i] << " exist" << std::endl;
129     } else {
130       // store filenames
131       std::vector<std::string> * filenames = new std::vector<std::string>;
132       const std::vector<std::string> & temp = nameGenerator->GetFileNames(seriesUID[i]);
133       for (unsigned int j=0; j<temp.size(); j++) {
134         filenames->push_back(temp[j]);
135       }
136       mListOfSeriesFilenames[seriesUID[i]] = filenames;
137
138       // store first header
139 #if GDCM_MAJOR_VERSION == 2
140       gdcm::ImageReader reader;
141       reader.SetFileName( (*filenames)[0].c_str() );
142       reader.Read();
143       mDicomHeader[seriesUID[i]] = &reader.GetFile();
144 #else
145       gdcm::File *header = new gdcm::File();
146       header->SetFileName((*filenames)[0]);
147       header->SetMaxSizeLoadEntry(16384);
148       header->SetLoadMode(gdcm::LD_NOSHADOW);// don't load shadow tags (in order to save memory)
149       header->Load();
150
151
152       //
153       DD(header->GetEntryValue(0x0028,0x0030).c_str());
154
155       //DS TEST DAVID
156       DD(header->GetXSize());
157       DD(header->GetYSize());
158       DD(header->GetZSize());
159       DD(header->GetXSpacing());
160       DD(header->GetYSpacing());
161       DD(header->GetZSpacing());
162       DD(header->GetXOrigin());
163       DD(header->GetYOrigin());
164       DD(header->GetZOrigin());
165       DD("\n");
166       /*
167         QString size = QString("%1x%2x%3")
168         .arg(header->GetXSize())
169         .arg(header->GetYSize())
170         .arg(header->GetZSize());
171         QString spacing = QString("%1x%2x%3")
172         .arg(header->GetXSpacing())
173         .arg(header->GetYSpacing())
174         .arg(header->GetZSpacing());
175         QString origin = QString("%1x%2x%3")
176         .arg(header->GetXOrigin())
177         .arg(header->GetYOrigin())
178         .arg(header->GetZOrigin());
179       */
180
181
182       mDicomHeader[seriesUID[i]] = header;
183 #endif
184
185       // new item
186       QListWidgetItem *newItem = new QListWidgetItem;
187       newItem->setText(seriesUID[i].c_str());
188       ui.mListWidget->insertItem(i, newItem);
189
190       //AddSerieToTheTable(i, *filenames);
191     }
192   }
193 }
194 //====================================================================
195
196 //====================================================================
197 void vvDicomSeriesSelector::itemSelectionChanged()
198 {
199   //  mLabelSelected.setText(
200   mCurrentSerie = ui.mListWidget->selectedItems()[0]->text().toStdString();
201   mFilenames = mListOfSeriesFilenames[mCurrentSerie];
202   ui.mButtonBox->button(QDialogButtonBox::Open)->setEnabled(true);
203
204   if (mDicomInfo[mCurrentSerie] == "") {
205     //  QString m;
206     //  m = QString("Patient : <font color=\"blue\">%1</font><br>").arg(mDicomHeader[s]->GetEntryValue(0x0010,0x0010).c_str()); // Patient's name
207     DD(mCurrentSerie)
208     mDicomInfo[mCurrentSerie] = MakeDicomInfo(mCurrentSerie, mDicomHeader[mCurrentSerie]);
209   }
210   ui.mDicomInfoPanel->setText(mDicomInfo[mCurrentSerie]);
211
212   // Detail tab
213   ui.mDicomDetailsListWidget->clear();
214   for (unsigned int i=0; i<mFilenames->size(); i++) {
215     QListWidgetItem * newItem = new QListWidgetItem;
216     newItem->setText(QFileInfo((*mFilenames)[i].c_str()).fileName());
217     ui.mDicomDetailsListWidget->insertItem(i, newItem);
218   }
219
220 }
221 //====================================================================
222
223 //====================================================================
224 void vvDicomSeriesSelector::itemDetailsSelectionChanged()
225 {
226   unsigned int i = ui.mDicomDetailsListWidget->currentRow();
227   if (i<mFilenames->size()) {
228     if (mDicomDetails[(*mFilenames)[i]] == "") {
229       std::ostringstream s;
230       mDicomHeader[mCurrentSerie]->Print(s);
231
232       QString l;
233       gdcm::File * header = mDicomHeader[mCurrentSerie];
234 #if GDCM_MAJOR_VERSION == 2
235       gdcm::StringFilter sf;
236       sf.SetFile( *header );
237       gdcm::DataSet &ds = header->GetDataSet();
238       gdcm::DataSet::ConstIterator it = ds.Begin();
239       for (; it != ds.End(); ++it )
240         {
241         const gdcm::DataElement & ref = *it;
242         const gdcm::Tag &         tag = ref.GetTag();
243         gdcm::VR vr = gdcm::DataSetHelper::ComputeVR(*header, ds, tag);
244         if ( vr & ( gdcm::VR::OB | gdcm::VR::OF | gdcm::VR::OW | gdcm::VR::SQ | gdcm::VR::UN ) )
245           {
246           // What is the behavior for binary stuff ?
247           }
248         else /* if ( vr & gdcm::VR::VRASCII ) */
249           {
250           if ( tag.IsPublic() )
251             {
252             std::pair<std::string, std::string> p = sf.ToStringPair(tag);
253             l += QString("%1 : %2\n")
254               .arg( p.first.c_str() )
255               .arg( p.second.c_str() );
256             }
257           }
258         }
259 #else
260       gdcm::DocEntry * e = header->GetFirstEntry();
261       while (e) {
262         if (e->GetName() != "gdcm::Unknown") {
263           l += QString("%1 : %2\n")
264                .arg(e->GetName().c_str())
265                .arg((header->GetEntryValue(e->GetGroup(), e->GetElement())).c_str());
266         }
267         e = header->GetNextEntry();
268       }
269 #endif
270
271       mDicomDetails[(*mFilenames)[i]] = l.toStdString();
272     }
273     ui.mDicomDetailsLabel->setText(mDicomDetails[(*mFilenames)[i]].c_str());
274   }
275 }
276 //====================================================================
277
278 //====================================================================
279 QString vvDicomSeriesSelector::MakeDicomInfo(std::string & s, gdcm::File *header)
280 {
281   QString n = QString("%1").arg(mListOfSeriesFilenames[s]->size());
282 #if GDCM_MAJOR_VERSION == 2
283   const gdcm::File &f = *header;
284   std::vector<double> thespacing = gdcm::ImageHelper::GetSpacingValue(f);
285   std::vector<double> theorigin = gdcm::ImageHelper::GetOriginValue(f);
286
287   QString size = QString("%1x%2x%3")
288                  .arg(0)
289                  .arg(0)
290                  .arg(0);
291   QString spacing = QString("%1x%2x%3")
292                     .arg(thespacing[0])
293                     .arg(thespacing[1])
294                     .arg(thespacing[2]);
295   QString origin = QString("%1x%2x%3")
296                    .arg(theorigin[0])
297                    .arg(theorigin[1])
298                    .arg(theorigin[2]);
299
300   QString ss =
301     //AddInfo(        "Serie ID   : ", s)+
302     AddInfo(header, "Patient : ", 0x0010,0x0010)+
303     AddInfo(        "Folder : ", QFileInfo((*mFilenames)[0].c_str()).canonicalPath().toStdString())+
304     AddInfo(header, "Series Description : ", 0x0008,0x103e)+
305     AddInfo(header, "Modality : ", 0x0008,0x0060)+
306     AddInfo(header, "# images : ", 0x0020,0x0013)+
307     AddInfo(        "# files : ", n.toStdString())+
308     AddInfo(        "Size : ", size.toStdString())+
309     AddInfo(        "Spacing : ", spacing.toStdString())+
310     AddInfo(        "Origin : ", origin.toStdString())+
311     AddInfo(header, "Pixel size : ", 0x0028,0x0100)+
312     AddInfo(        "Pixel type : ", 0);
313 #else
314   QString size = QString("%1x%2x%3")
315                  .arg(header->GetXSize())
316                  .arg(header->GetYSize())
317                  .arg(header->GetZSize());
318   QString spacing = QString("%1x%2x%3")
319                     .arg(header->GetXSpacing())
320                     .arg(header->GetYSpacing())
321                     .arg(header->GetZSpacing());
322   QString origin = QString("%1x%2x%3")
323                    .arg(header->GetXOrigin())
324                    .arg(header->GetYOrigin())
325                    .arg(header->GetZOrigin());
326   QString ss =
327     //AddInfo(        "Serie ID   : ", s)+
328     AddInfo(header, "Patient : ", 0x0010,0x0010)+
329     AddInfo(        "Folder : ", QFileInfo((*mFilenames)[0].c_str()).canonicalPath().toStdString())+
330     AddInfo(header, "Series Description : ", 0x0008,0x103e)+
331     AddInfo(header, "Modality : ", 0x0008,0x0060)+
332     AddInfo(header, "# images : ", 0x0020,0x0013)+
333     AddInfo(        "# files : ", n.toStdString())+
334     AddInfo(        "Size : ", size.toStdString())+
335     AddInfo(        "Spacing : ", spacing.toStdString())+
336     AddInfo(        "Origin : ", origin.toStdString())+
337     AddInfo(header, "Pixel size : ", 0x0028,0x0100)+
338     AddInfo(        "Pixel type : ", header->GetPixelType());
339 #endif
340   return ss;
341 }
342 //====================================================================
343
344 //====================================================================
345 QString vvDicomSeriesSelector::AddInfo(gdcm::File *header, QString n, uint16_t group, uint16_t elem)
346 {
347 #if GDCM_MAJOR_VERSION == 2
348   gdcm::StringFilter sf;
349   sf.SetFile( *header );
350   gdcm::Tag t( group, elem );
351   std::string s = sf.ToString( t );
352   return AddInfo(n.toStdString(), s);
353 #else
354   return AddInfo(n.toStdString(), header->GetEntryValue(group, elem));
355 #endif
356 }
357 //====================================================================
358
359 //====================================================================
360 QString vvDicomSeriesSelector::AddInfo(std::string n, std::string m)
361 {
362   QString s = QString("%1 <font color=\"blue\">%2</font><br>").
363               arg(n.c_str()).arg(m.c_str());
364   return s;
365 }
366 //====================================================================
367
368 //====================================================================
369 void vvDicomSeriesSelector::AddSerieToTheTable(int i, std::vector<std::string> & filenames)
370 {
371 #if GDCM_MAJOR_VERSION == 2
372 #else
373   gdcm::File *header = new gdcm::File();
374   header->SetFileName(filenames[0]);
375   header->SetMaxSizeLoadEntry(16384);
376   header->SetLoadMode(gdcm::LD_NOSHADOW);// don't load shadow tags (in order to save memory)
377   header->Load();
378   //header->Print(cout);
379   // ->GetValEntry
380   //  mDicomHeader[] = header;
381
382   /*
383
384   QTableWidgetItem *newItem = new
385   QTableWidgetItem(QString("# images = %1").arg(header->GetImageNumber()));
386   //  newItem->setCheckState(Qt::Checked);
387   //newItem->setFlags(!Qt::ItemIsEditable);
388   DD(ui.mTableWidget->rowCount());
389   ui.mTableWidget->setItem(i, 0, newItem);
390   */
391 #endif
392 }
393 //====================================================================
394
395 #endif // VVDICOMSERIESSELECTOR_CXX