Fraxinus  16.5.0-fx-rc1
An IGT application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
cxDicomWidget.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 <QApplication>
34 #include <QDesktopWidget>
35 #include <QDir>
36 #undef REGISTERED
37 #include "ctkServiceTracker.h"
38 #include "ctkDICOMBrowser.h"
39 #include "ctkDICOMAppWidget.h"
40 #include "cxDICOMAppWidget.h"
41 #include "ctkDICOMTableManager.h"
42 #include "ctkDICOMObjectListWidget.h"
43 #include "ctkPluginContext.h"
44 #include "cxDicomWidget.h"
45 #include "cxProfile.h"
46 #include "cxTypeConversions.h"
47 #include "cxDicomConverter.h"
48 #include "cxLogger.h"
49 
50 #include "cxPatientModelService.h"
51 #include "cxDicomImageReader.h"
52 #include "cxVisServices.h"
53 #include "cxViewService.h"
54 #include "cxSettings.h"
55 
56 namespace cx
57 {
58 
59 DicomWidget::DicomWidget(ctkPluginContext *context, QWidget *parent) :
60  BaseWidget(parent, "DicomWidget", "Dicom"),
61  mVerticalLayout(new QVBoxLayout(this)),
62  mBrowser(NULL),
63  mContext(context)
64 {
65  this->setModified();
66 
67 }
68 
70 {
71  this->deleteDICOMDB();
72 }
73 
75 {
76  if (!mBrowser)
77  {
78  this->createUI();
79  }
80 }
81 
82 void DicomWidget::createUI()
83 {
84  if (mBrowser)
85  return;
86 
87  this->setToolTip("Import DICOM data");
88  //Add detailed button
89  mViewHeaderAction = this->createAction(this,
90  QIcon(),
91  "View", "View header info for first selected series",
92  SLOT(onViewHeader()));
93  mImportIntoCustusXAction = this->createAction(this,
94  QIcon(),
95  "Import", "Import selected series into application",
96  SLOT(onImportIntoCustusXAction()));
97 
98  mBrowser = new DICOMAppWidget;
99  mBrowser->addActionToToolbar(mViewHeaderAction);
100  mBrowser->addActionToToolbar(mImportIntoCustusXAction);
101 
102  mVerticalLayout->setMargin(0);
103  mVerticalLayout->addWidget(mBrowser);
104 
105  this->setupDatabaseDirectory();
106 }
107 
109 {
110  QString databaseDirectory = profile()->getSettingsPath() + "/DICOMDatabase";
111 
112  return databaseDirectory;
113 }
114 
115 void DicomWidget::setupDatabaseDirectory()
116 {
117  QString databaseDirectory = this->getDICOMDatabaseDirectory();
118 
119  QDir qdir(databaseDirectory);
120  if ( !qdir.exists(databaseDirectory) )
121  {
122  if ( !qdir.mkpath(databaseDirectory) )
123  {
124  CX_LOG_CHANNEL_ERROR("dicom") << "Could not create database directory \"" << databaseDirectory;
125  }
126  }
127 
128  CX_LOG_CHANNEL_INFO("dicom") << "DatabaseDirectory set to: " << databaseDirectory;
129  mBrowser->setDatabaseDirectory(databaseDirectory);
130 }
131 
132 QStringList DicomWidget::currentSeriesSelection()
133 {
134  return mBrowser->getSelectedSeries();
135 }
136 
137 void DicomWidget::onViewHeader()
138 {
139  QStringList series = this->currentSeriesSelection();
140  std::cout << series.join("\n").toStdString() << std::endl;
141 
142  QStringList files;
143  for (int i=0; i<series.size(); ++i)
144  {
145  QStringList current = this->getDatabase()->filesForSeries(series[i]);
146  files.append(current);
147  }
148  files.sort();
149 
150  ctkDICOMObjectListWidget* window = new ctkDICOMObjectListWidget;
151  window->setWindowTitle("DICOM File Header");
152  window->setFileList(files);
153 
154  QWidget* screen = qApp->desktop()->screen(qApp->desktop()->screenNumber(this));
155  QRect rect = screen->geometry();
156  rect.setWidth(rect.width()*0.66);
157  window->setGeometry(rect);
158 
159  window->show();
160 }
161 
162 void DicomWidget::onImportIntoCustusXAction()
163 {
164  QStringList series = this->currentSeriesSelection();
165 
166  if (series.empty())
167  CX_LOG_CHANNEL_WARNING("dicom") << "No DICOM series selected, import failed.";
168 
169  for (unsigned i=0; i<series.size(); ++i)
170  {
171  this->importSeries(series[i]);
172  }
173 }
174 
175 void DicomWidget::deleteDICOMDB()
176 {
177  CX_LOG_CHANNEL_INFO("dicom") << "Deleting DICOM database: " << this->getDICOMDatabaseDirectory();
178  bool autoDeleteDICOMDB = settings()->value("Automation/autoDeleteDICOMDatabase").toBool();
179  if(autoDeleteDICOMDB)
180  {
181  ctkDICOMDatabase* database = this->getDatabase();
182  if(database)
183  {
184  QStringList patients = database->patients();
185  foreach(QString patient , patients)
186  {
187  this->getDatabase()->removePatient(patient);
188  }
189  }
190  }
191 }
192 
193 void DicomWidget::importSeries(QString seriesUid)
194 {
195  cx::DicomConverter converter;
196  converter.setDicomDatabase(this->getDatabase());
197  cx::ImagePtr convertedImage = converter.convertToImage(seriesUid);
198 
199  if (!convertedImage)
200  {
201  reportError(QString("Failed to convert DICOM series %1").arg(seriesUid));
202  return;
203  }
204 
205  this->loadIntoPatientModel(convertedImage, seriesUid);
206 }
207 
208 void DicomWidget::loadIntoPatientModel(ImagePtr image, QString seriesUid)
209 {
210  VisServicesPtr services = VisServices::create(mContext);
211 
212  if (!services->patient()->isNull())
213  {
214  services->patient()->insertData(image);
215  services->view()->autoShowData(image);
216  report(QString("Loaded DICOM series %1 as %2").arg(seriesUid).arg(image->getName()));
217  }
218  else
219  {
220  reportWarning(QString("Failed to load DICOM series %1 as %2: no PatientModelService.").arg(seriesUid).arg(image->getName()));
221  }
222 }
223 
224 ctkDICOMDatabase* DicomWidget::getDatabase() const
225 {
226  if(mBrowser)
227  return mBrowser->database();
228  else
229  return NULL;
230 }
231 
232 } /* namespace cx */
#define CX_LOG_CHANNEL_INFO(channel)
Definition: cxLogger.h:123
cxResource_EXPORT ProfilePtr profile()
Definition: cxProfile.cpp:176
QStringList getSelectedSeries()
void reportError(QString msg)
Definition: cxLogger.cpp:92
boost::shared_ptr< class VisServices > VisServicesPtr
Definition: cxMainWindow.h:62
ctkDICOMDatabase * database()
virtual void prePaintEvent()
boost::shared_ptr< class Image > ImagePtr
Definition: cxDicomWidget.h:48
void setDicomDatabase(ctkDICOMDatabase *database)
static VisServicesPtr create(ctkPluginContext *context)
void addActionToToolbar(QAction *action)
#define CX_LOG_CHANNEL_WARNING(channel)
Definition: cxLogger.h:125
QVariant value(const QString &key, const QVariant &defaultValue=QVariant()) const
Definition: cxSettings.cpp:87
DicomWidget(ctkPluginContext *context, QWidget *parent=0)
QAction * createAction(QObject *parent, QIcon iconName, QString text, QString tip, T slot, QLayout *layout=NULL, QToolButton *button=new QToolButton())
Definition: cxBaseWidget.h:149
ImagePtr convertToImage(QString seriesUid)
void reportWarning(QString msg)
Definition: cxLogger.cpp:91
Settings * settings()
Shortcut for accessing the settings instance.
Definition: cxSettings.cpp:42
QString getDICOMDatabaseDirectory()
ctkDICOMDatabase * getDatabase() const
Interface for QWidget which handles widgets uniformly for the system.
Definition: cxBaseWidget.h:108
void report(QString msg)
Definition: cxLogger.cpp:90
virtual ~DicomWidget()
void setDatabaseDirectory(const QString &directory)
#define CX_LOG_CHANNEL_ERROR(channel)
Definition: cxLogger.h:126