1 /*=========================================================================
2 Program: vv http://www.creatis.insa-lyon.fr/rio/vv
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
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.
13 It is distributed under dual licence
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>
23 #if GDCM_MAJOR_VERSION == 2
24 #include <gdcmImageReader.h>
25 #include <gdcmDataSetHelper.h>
26 #include <gdcmStringFilter.h>
28 #include <gdcmDocEntry.h>
31 #include "vvQDicomSeriesSelector.h"
32 //#include "vvUserConfig.h"
34 //====================================================================
35 vvDicomSeriesSelector::vvDicomSeriesSelector(QWidget* parent)
40 // Correct GUI for splitter ...
41 // QSplitter * splitter = new QSplitter(this);
42 // splitter->setOrientation(Qt::Horizontal);
43 // ui.gridLayout1->addWidget(splitter, 0, 0, 1, 1);
44 // ui.mFrameLeft->setParent(splitter);
45 // ui.mFrameRight->setParent(splitter);
46 // ui.toolBox->setCurrentIndex(0);
50 ui.mButtonBox->button(QDialogButtonBox::Open)->setEnabled(false);
52 connect(ui.mBrowseButton, SIGNAL(released()),
53 this, SLOT(BrowseButtonRelease()));
54 connect(ui.mSearchButton, SIGNAL(released()),
55 this, SLOT(SearchButtonRelease()));
56 connect(ui.mListWidget, SIGNAL(itemSelectionChanged()),
57 this, SLOT(itemSelectionChanged()));
58 connect(ui.mDicomDetailsListWidget, SIGNAL(itemSelectionChanged()),
59 this, SLOT(itemDetailsSelectionChanged()));
62 /* if (config::get_current_path() != QString(0))
63 mFoldername = config::get_current_path();
65 mFoldername = QFileInfo("./").absolutePath();
67 mPreviousPath = mFoldername;
68 ui.mFolderLineEdit->setText(mFoldername);
69 // ui.mTableWidget->setRowCount(0);
71 //====================================================================
73 //====================================================================
74 void vvDicomSeriesSelector::show()
78 // ui.mListWidget->grabKeyboard();
79 // ui.mDicomDetailsListWidget->grabKeyboard();
81 //====================================================================
83 //====================================================================
84 void vvDicomSeriesSelector::close()
87 // ui.mListWidget->releaseKeyboard()
90 //====================================================================
92 //====================================================================
93 void vvDicomSeriesSelector::BrowseButtonRelease()
95 QFileDialog dialog(this);
96 dialog.setFileMode(QFileDialog::AnyFile);
97 dialog.setFilter("DICOM files (*.dcm); All files (*)");
98 mFoldername = dialog.getExistingDirectory(this,
99 "Select a folder to find DICOM image",
101 ui.mFolderLineEdit->setText(mFoldername);
102 mPreviousPath = QFileInfo(mFoldername).absolutePath();
103 // config::set_current_path(mPreviousPath);
105 //====================================================================
107 //====================================================================
108 void vvDicomSeriesSelector::SearchButtonRelease()
110 typedef itk::GDCMSeriesFileNames NamesGeneratorType;
111 NamesGeneratorType::Pointer nameGenerator = NamesGeneratorType::New();
112 nameGenerator->SetUseSeriesDetails(true);
113 //nameGenerator->SetDirectory(mFoldername.toStdString());
114 nameGenerator->SetRecursive(ui.mIsRecursiveCheckBox->checkState() == Qt::Checked);
116 //ds gérer recursive moi-meme pour progress ...
117 nameGenerator->SetInputDirectory(mFoldername.toStdString());
120 typedef std::vector<std::string> SeriesIdContainer;
121 const SeriesIdContainer & seriesUID = nameGenerator->GetSeriesUIDs();
123 for (unsigned int i=0; i<seriesUID.size(); i++) {
124 // std::cout << seriesUID[i] << std::endl; //ds verif existe pas déja
126 if (mListOfSeriesFilenames[seriesUID[i]]) {
127 std::cout << seriesUID[i] << " exist" << std::endl;
130 std::vector<std::string> * filenames = new std::vector<std::string>;
131 const std::vector<std::string> & temp = nameGenerator->GetFileNames(seriesUID[i]);
132 for (unsigned int j=0; j<temp.size(); j++) {
133 filenames->push_back(temp[j]);
135 mListOfSeriesFilenames[seriesUID[i]] = filenames;
137 // store first header
138 #if GDCM_MAJOR_VERSION == 2
139 gdcm::ImageReader reader;
140 reader.SetFileName( (*filenames)[0].c_str() );
142 mDicomHeader[seriesUID[i]] = &reader.GetFile();
144 gdcm::File *header = new gdcm::File();
145 header->SetFileName((*filenames)[0]);
146 header->SetMaxSizeLoadEntry(16384);
147 header->SetLoadMode(gdcm::LD_NOSHADOW);// don't load shadow tags (in order to save memory)
152 DD(header->GetEntryValue(0x0028,0x0030).c_str());
155 DD(header->GetXSize());
156 DD(header->GetYSize());
157 DD(header->GetZSize());
158 DD(header->GetXSpacing());
159 DD(header->GetYSpacing());
160 DD(header->GetZSpacing());
161 DD(header->GetXOrigin());
162 DD(header->GetYOrigin());
163 DD(header->GetZOrigin());
166 QString size = QString("%1x%2x%3")
167 .arg(header->GetXSize())
168 .arg(header->GetYSize())
169 .arg(header->GetZSize());
170 QString spacing = QString("%1x%2x%3")
171 .arg(header->GetXSpacing())
172 .arg(header->GetYSpacing())
173 .arg(header->GetZSpacing());
174 QString origin = QString("%1x%2x%3")
175 .arg(header->GetXOrigin())
176 .arg(header->GetYOrigin())
177 .arg(header->GetZOrigin());
181 mDicomHeader[seriesUID[i]] = header;
185 QListWidgetItem *newItem = new QListWidgetItem;
186 newItem->setText(seriesUID[i].c_str());
187 ui.mListWidget->insertItem(i, newItem);
189 //AddSerieToTheTable(i, *filenames);
193 //====================================================================
195 //====================================================================
196 void vvDicomSeriesSelector::itemSelectionChanged()
198 // mLabelSelected.setText(
199 mCurrentSerie = ui.mListWidget->selectedItems()[0]->text().toStdString();
200 mFilenames = mListOfSeriesFilenames[mCurrentSerie];
201 ui.mButtonBox->button(QDialogButtonBox::Open)->setEnabled(true);
203 if (mDicomInfo[mCurrentSerie] == "") {
205 // m = QString("Patient : <font color=\"blue\">%1</font><br>").arg(mDicomHeader[s]->GetEntryValue(0x0010,0x0010).c_str()); // Patient's name
206 mDicomInfo[mCurrentSerie] = MakeDicomInfo(mCurrentSerie, mDicomHeader[mCurrentSerie]);
208 ui.mDicomInfoPanel->setText(mDicomInfo[mCurrentSerie]);
211 ui.mDicomDetailsListWidget->clear();
212 for (unsigned int i=0; i<mFilenames->size(); i++) {
213 QListWidgetItem * newItem = new QListWidgetItem;
214 newItem->setText(QFileInfo((*mFilenames)[i].c_str()).fileName());
215 ui.mDicomDetailsListWidget->insertItem(i, newItem);
219 //====================================================================
221 //====================================================================
222 void vvDicomSeriesSelector::itemDetailsSelectionChanged()
224 unsigned int i = ui.mDicomDetailsListWidget->currentRow();
225 if (i<mFilenames->size()) {
226 if (mDicomDetails[(*mFilenames)[i]] == "") {
227 std::ostringstream s;
228 mDicomHeader[mCurrentSerie]->Print(s);
231 gdcm::File * header = mDicomHeader[mCurrentSerie];
232 #if GDCM_MAJOR_VERSION == 2
233 gdcm::StringFilter sf;
234 sf.SetFile( *header );
235 gdcm::DataSet &ds = header->GetDataSet();
236 gdcm::DataSet::ConstIterator it = ds.Begin();
237 for (; it != ds.End(); ++it )
239 const gdcm::DataElement & ref = *it;
240 const gdcm::Tag & tag = ref.GetTag();
241 gdcm::VR vr = gdcm::DataSetHelper::ComputeVR(*header, ds, tag);
242 if ( vr & ( gdcm::VR::OB | gdcm::VR::OF | gdcm::VR::OW | gdcm::VR::SQ | gdcm::VR::UN ) )
244 // What is the behavior for binary stuff ?
246 else /* if ( vr & gdcm::VR::VRASCII ) */
248 if ( tag.IsPublic() )
250 std::pair<std::string, std::string> p = sf.ToStringPair(tag);
251 l += QString("%1 : %2\n")
252 .arg( p.first.c_str() )
253 .arg( p.second.c_str() );
258 gdcm::DocEntry * e = header->GetFirstEntry();
260 if (e->GetName() != "gdcm::Unknown") {
261 l += QString("%1 : %2\n")
262 .arg(e->GetName().c_str())
263 .arg((header->GetEntryValue(e->GetGroup(), e->GetElement())).c_str());
265 e = header->GetNextEntry();
269 mDicomDetails[(*mFilenames)[i]] = l.toStdString();
271 ui.mDicomDetailsLabel->setText(mDicomDetails[(*mFilenames)[i]].c_str());
274 //====================================================================
276 //====================================================================
277 QString vvDicomSeriesSelector::MakeDicomInfo(std::string & s, gdcm::File *header)
279 QString n = QString("%1").arg(mListOfSeriesFilenames[s]->size());
280 #if GDCM_MAJOR_VERSION == 2
283 QString size = QString("%1x%2x%3")
284 .arg(header->GetXSize())
285 .arg(header->GetYSize())
286 .arg(header->GetZSize());
287 QString spacing = QString("%1x%2x%3")
288 .arg(header->GetXSpacing())
289 .arg(header->GetYSpacing())
290 .arg(header->GetZSpacing());
291 QString origin = QString("%1x%2x%3")
292 .arg(header->GetXOrigin())
293 .arg(header->GetYOrigin())
294 .arg(header->GetZOrigin());
296 //AddInfo( "Serie ID : ", s)+
297 AddInfo(header, "Patient : ", 0x0010,0x0010)+
298 AddInfo( "Folder : ", QFileInfo((*mFilenames)[0].c_str()).canonicalPath().toStdString())+
299 AddInfo(header, "Series Description : ", 0x0008,0x103e)+
300 AddInfo(header, "Modality : ", 0x0008,0x0060)+
301 AddInfo(header, "# images : ", 0x0020,0x0013)+
302 AddInfo( "# files : ", n.toStdString())+
303 AddInfo( "Size : ", size.toStdString())+
304 AddInfo( "Spacing : ", spacing.toStdString())+
305 AddInfo( "Origin : ", origin.toStdString())+
306 AddInfo(header, "Pixel size : ", 0x0028,0x0100)+
307 AddInfo( "Pixel type : ", header->GetPixelType());
311 //====================================================================
313 //====================================================================
314 QString vvDicomSeriesSelector::AddInfo(gdcm::File *header, QString n, uint16_t group, uint16_t elem)
316 #if GDCM_MAJOR_VERSION == 2
317 gdcm::StringFilter sf;
318 sf.SetFile( *header );
319 gdcm::Tag t( group, elem );
320 std::string s = sf.ToString( t );
321 return AddInfo(n.toStdString(), s);
323 return AddInfo(n.toStdString(), header->GetEntryValue(group, elem));
326 //====================================================================
328 //====================================================================
329 QString vvDicomSeriesSelector::AddInfo(std::string n, std::string m)
331 QString s = QString("%1 <font color=\"blue\">%2</font><br>").
332 arg(n.c_str()).arg(m.c_str());
335 //====================================================================
337 //====================================================================
338 void vvDicomSeriesSelector::AddSerieToTheTable(int i, std::vector<std::string> & filenames)
340 #if GDCM_MAJOR_VERSION == 2
342 gdcm::File *header = new gdcm::File();
343 header->SetFileName(filenames[0]);
344 header->SetMaxSizeLoadEntry(16384);
345 header->SetLoadMode(gdcm::LD_NOSHADOW);// don't load shadow tags (in order to save memory)
347 //header->Print(cout);
349 // mDicomHeader[] = header;
353 QTableWidgetItem *newItem = new
354 QTableWidgetItem(QString("# images = %1").arg(header->GetImageNumber()));
355 // newItem->setCheckState(Qt::Checked);
356 //newItem->setFlags(!Qt::ItemIsEditable);
357 DD(ui.mTableWidget->rowCount());
358 ui.mTableWidget->setItem(i, 0, newItem);
362 //====================================================================
364 #endif // VVDICOMSERIESSELECTOR_CXX