Fraxinus  16.5.0-fx-rc3
An IGT application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
cxDicomImporter.cpp
Go to the documentation of this file.
1 /*=========================================================================
2 This file is part of CustusX, an Image Guided Therapy Application.
3 
4 Copyright (c) 2008-2014, SINTEF Department of Medical Technology
5 All rights reserved.
6 
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
9 
10 1. Redistributions of source code must retain the above copyright notice,
11  this list of conditions and the following disclaimer.
12 
13 2. Redistributions in binary form must reproduce the above copyright notice,
14  this list of conditions and the following disclaimer in the documentation
15  and/or other materials provided with the distribution.
16 
17 3. Neither the name of the copyright holder nor the names of its contributors
18  may be used to endorse or promote products derived from this software
19  without specific prior written permission.
20 
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 =========================================================================*/
32 
33 #include "cxDicomImporter.h"
34 
35 #include <QCheckBox>
36 #include <QMessageBox>
37 #include <QProgressDialog>
38 #include <QLabel>
39 #include <QFileDialog>
40 // ctkWidgets includes
41 // ctkDICOMCore includes
42 #include "ctkDICOMDatabase.h"
43 #include "ctkDICOMIndexer.h"
44 
45 #include "cxReporter.h"
46 
47 namespace cx
48 {
49 
50 DicomImporter::DicomImporter(QObject* parent): QObject(parent)
51 {
52  DICOMIndexer = QSharedPointer<ctkDICOMIndexer> (new ctkDICOMIndexer);
53  IndexerProgress = 0;
54  DisplayImportSummary = true;
55  PatientsAddedDuringImport = 0;
56  StudiesAddedDuringImport = 0;
57  SeriesAddedDuringImport = 0;
58  InstancesAddedDuringImport = 0;
59 }
60 
62 {
63  delete IndexerProgress;
64 }
65 
66 void DicomImporter::setDatabase(QSharedPointer<ctkDICOMDatabase> database)
67 {
68  if (DICOMDatabase)
69  {
70  disconnect(DICOMDatabase.data(), SIGNAL(patientAdded(int,QString,QString,QString)), this,
71  SLOT(onPatientAdded(int,QString,QString,QString)));
72  disconnect(DICOMDatabase.data(), SIGNAL(studyAdded(QString)), this, SLOT(onStudyAdded(QString)));
73  disconnect(DICOMDatabase.data(), SIGNAL(seriesAdded(QString)), this, SLOT(onSeriesAdded(QString)));
74  disconnect(DICOMDatabase.data(), SIGNAL(instanceAdded(QString)), this, SLOT(onInstanceAdded(QString)));
75  }
76 
77  DICOMDatabase = database;
78 
79  if (DICOMDatabase)
80  {
81  connect(DICOMDatabase.data(), SIGNAL(patientAdded(int,QString,QString,QString)), this,
82  SLOT(onPatientAdded(int,QString,QString,QString)));
83  connect(DICOMDatabase.data(), SIGNAL(studyAdded(QString)), this, SLOT(onStudyAdded(QString)));
84  connect(DICOMDatabase.data(), SIGNAL(seriesAdded(QString)), this, SLOT(onSeriesAdded(QString)));
85  connect(DICOMDatabase.data(), SIGNAL(instanceAdded(QString)), this, SLOT(onInstanceAdded(QString)));
86  }
87 }
88 
89 void DicomImporter::showIndexerDialog()
90 {
91  if (IndexerProgress == 0)
92  {
93  //
94  // Set up the Indexer Progress Dialog
95  //
96  IndexerProgress = new QProgressDialog( "DICOM Import", "Cancel", 0, 100, NULL,
97  Qt::WindowTitleHint | Qt::WindowSystemMenuHint);
98 
99  // We don't want the progress dialog to resize itself, so we bypass the label
100  // by creating our own
101  QLabel* progressLabel = new QLabel("Initialization...");
102  IndexerProgress->setLabel(progressLabel);
103  IndexerProgress->setWindowModality(Qt::ApplicationModal);
104  IndexerProgress->setMinimumDuration(0);
105  IndexerProgress->setValue(0);
106 
107  connect(IndexerProgress, SIGNAL(canceled()),
108  DICOMIndexer.data(), SLOT(cancel()));
109 
110  connect(DICOMIndexer.data(), SIGNAL(progress(int)),
111  IndexerProgress, SLOT(setValue(int)));
112  connect(DICOMIndexer.data(), SIGNAL(indexingFilePath(QString)),
113  progressLabel, SLOT(setText(QString)));
114  connect(DICOMIndexer.data(), SIGNAL(indexingFilePath(QString)),
115  this, SIGNAL(fileIndexed(QString)));
116  connect(DICOMIndexer.data(), SIGNAL(indexingFilePath(QString)),
117  this, SLOT(onFileIndexed(QString)));
118 
119  // close the dialog
120  connect(DICOMIndexer.data(), SIGNAL(indexingComplete()),
121  IndexerProgress, SLOT(close()));
122  // reset the database to show new data
123  connect(DICOMIndexer.data(), SIGNAL(indexingComplete()),
124  this, SIGNAL(indexingCompleted()));
125  // stop indexing and reset the database if canceled
126  connect(IndexerProgress, SIGNAL(canceled()),
127  DICOMIndexer.data(), SLOT(cancel()));
128  connect(IndexerProgress, SIGNAL(canceled()),
129  this, SIGNAL(indexingCompleted()));
130 
131  // allow users of this widget to know that the process has finished
132  connect(IndexerProgress, SIGNAL(canceled()),
133  this, SIGNAL(directoryImported()));
134  connect(DICOMIndexer.data(), SIGNAL(indexingComplete()),
135  this, SIGNAL(directoryImported()));
136  }
137  IndexerProgress->show();
138 }
139 
141 {
142  return DisplayImportSummary;
143 }
144 
146 {
147  DisplayImportSummary = onOff;
148 }
149 
151 {
152  return PatientsAddedDuringImport;
153 }
154 
156 {
157  return StudiesAddedDuringImport;
158 }
159 
161 {
162  return SeriesAddedDuringImport;
163 }
164 
166 {
167  return InstancesAddedDuringImport;
168 }
169 
170 //----------------------------------------------------------------------------
171 void DicomImporter::onFileIndexed(const QString& filePath)
172 {
173  // Update the progress dialog when the file name changes
174  // - also allows for cancel button
175  QCoreApplication::instance()->processEvents();
176 // qDebug() << "Indexing \n\n\n\n" << filePath <<"\n\n\n";
177 
178 }
179 
180 //----------------------------------------------------------------------------
181 void DicomImporter::openImportDialog()
182 {
183  QString folder = QFileDialog::getExistingDirectory(NULL, "Import DICOM files from directory ...", "", QFileDialog::ShowDirsOnly);
184  if (!folder.isEmpty())
185  onImportDirectory(folder);
186  else
187  reportWarning("No DICOM folder selected");
188 }
189 
190 //----------------------------------------------------------------------------
191 void DicomImporter::onPatientAdded(int databaseID, QString patientID, QString patientName, QString patientBirthDate )
192 {
193  Q_UNUSED(databaseID);
194  Q_UNUSED(patientID);
195  Q_UNUSED(patientName);
196  Q_UNUSED(patientBirthDate);
197  ++PatientsAddedDuringImport;
198 }
199 
200 //----------------------------------------------------------------------------
201 void DicomImporter::onStudyAdded(QString studyUID)
202 {
203  Q_UNUSED(studyUID);
204  ++StudiesAddedDuringImport;
205 }
206 
207 //----------------------------------------------------------------------------
208 void DicomImporter::onSeriesAdded(QString seriesUID)
209 {
210  Q_UNUSED(seriesUID);
211  ++SeriesAddedDuringImport;
212 }
213 
214 //----------------------------------------------------------------------------
215 void DicomImporter::onInstanceAdded(QString instanceUID)
216 {
217  Q_UNUSED(instanceUID);
218  ++InstancesAddedDuringImport;
219 }
220 
221 //----------------------------------------------------------------------------
222 void DicomImporter::onImportDirectory(QString directory)
223 {
224  if (QDir(directory).exists())
225  {
226  // reset counts
227  PatientsAddedDuringImport = 0;
228  StudiesAddedDuringImport = 0;
229  SeriesAddedDuringImport = 0;
230  InstancesAddedDuringImport = 0;
231 
232  // show progress dialog and perform indexing
233  showIndexerDialog();
234  DICOMIndexer->addDirectory(*DICOMDatabase,directory);
235 
236  // display summary result
237  if (DisplayImportSummary)
238  {
239  QString message = "Directory import completed.\n\n";
240  message += QString("%1 New Patients\n").arg(QString::number(PatientsAddedDuringImport));
241  message += QString("%1 New Studies\n").arg(QString::number(StudiesAddedDuringImport));
242  message += QString("%1 New Series\n").arg(QString::number(SeriesAddedDuringImport));
243  message += QString("%1 New Instances\n").arg(QString::number(InstancesAddedDuringImport));
244  QMessageBox::information(NULL,"DICOM Directory Import", message);
245  }
246  }
247 }
248 
249 } // namespace cx
250 
251 
void directoryImported()
void setDatabase(QSharedPointer< ctkDICOMDatabase > database)
void indexingCompleted()
int patientsAddedDuringImport()
Accessors to status of last directory import operation.
void setDisplayImportSummary(bool)
void reportWarning(QString msg)
Definition: cxLogger.cpp:91
DicomImporter(QObject *parent=NULL)
void onImportDirectory(QString directory)
void fileIndexed(QString)