Fraxinus  16.5.0-fx-rc9
An IGT application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
cxDICOMThumbnailListWidget.cpp
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Library: CTK
4 
5  Copyright (c) Kitware Inc.
6 
7  Licensed under the Apache License, Version 2.0 (the "License");
8  you may not use this file except in compliance with the License.
9  You may obtain a copy of the License at
10 
11  http://www.apache.org/licenses/LICENSE-2.0.txt
12 
13  Unless required by applicable law or agreed to in writing, software
14  distributed under the License is distributed on an "AS IS" BASIS,
15  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  See the License for the specific language governing permissions and
17  limitations under the License.
18 
19 =========================================================================*/
20 
21 // Qt include
22 #include <QDateTime>
23 #include <QDir>
24 #include <QFile>
25 #include <QFileInfo>
26 #include <QGridLayout>
27 #include <QMetaType>
28 #include <QPersistentModelIndex>
29 #include <QPixmap>
30 #include <QPushButton>
31 #include <QResizeEvent>
32 
33 // ctk includes
34 #include "ctkLogger.h"
35 
36 // ctkWidgets includes
37 #include "ctkFlowLayout.h"
38 #include "ctkThumbnailListWidget_p.h"
39 //#include "ui_ctkThumbnailListWidget.h"
40 
41 //ctkDICOMCore includes
42 #include "ctkDICOMDatabase.h"
43 #include "ctkDICOMFilterProxyModel.h"
44 #include "cxDICOMModel.h"
45 
46 // ctkDICOMWidgets includes
48 #include "ctkThumbnailLabel.h"
49 
50 // STD includes
51 #include <iostream>
52 
53 // DCMTK includes
54 #include <dcmimage.h>
55 
56 static ctkLogger logger("org.commontk.DICOM.Widgets.DICOMThumbnailListWidget");
57 
58 Q_DECLARE_METATYPE(QPersistentModelIndex);
59 
60 namespace cx
61 {
62 typedef DICOMModel ctkDICOMModel;
63 
64 //----------------------------------------------------------------------------
65 class DICOMThumbnailListWidgetPrivate : ctkThumbnailListWidgetPrivate
66 {
67  Q_DECLARE_PUBLIC(DICOMThumbnailListWidget);
68 public:
69  typedef ctkThumbnailListWidgetPrivate Superclass;
70 
72 
73  QSharedPointer<ctkDICOMDatabase> Database;
75  QModelIndex CurrentSelectedModel;
76 
77 // void addThumbnailWidget(const QModelIndex &imageIndex, const QModelIndex& sourceIndex, const QString& text);
78 
79  void addPatientThumbnails(const QModelIndex& patientIndex);
80  void addStudyThumbnails(const QModelIndex& studyIndex);
81  void addSeriesThumbnails(const QModelIndex& seriesIndex);
82 
83  void addThumbnailWidget(QString filename, const QString &text);
84  void addThumbnailWidget(QString studyUid, QString seriesUid, QString imageUid, QString caption);
85  QStringList getFilesForImage(QString studyUid, QString seriesUid, QString imageUid);
86  QStringList getThumbnailsForSeries(QString studyUid, QString seriesUid);
87 
88 private:
89  Q_DISABLE_COPY( DICOMThumbnailListWidgetPrivate );
90 };
91 
92 //----------------------------------------------------------------------------
93 // DICOMThumbnailListWidgetPrivate methods
94 
95 //----------------------------------------------------------------------------
98  : Superclass(parent)
99 {
100 
101 }
102 
103 //----------------------------------------------------------------------------
105 ::addPatientThumbnails(const QModelIndex &index)
106 {
107  QModelIndex patientIndex = index;
108 
109  ctkDICOMModel* model = const_cast<ctkDICOMModel*>(
110  qobject_cast<const ctkDICOMModel*>(index.model()));
111 
112  if(model)
113  {
114  model->fetchMore(patientIndex);
115  const int studyCount = model->rowCount(patientIndex);
116 
117  for(int i=0; i<studyCount; i++)
118  {
119  QModelIndex studyIndex = patientIndex.child(i, 0);
120 
121  this->addStudyThumbnails(studyIndex);
122  }
123  }
124 }
125 
126 //----------------------------------------------------------------------------
128 {
129  QModelIndex studyIndex = index;
130 
131  ctkDICOMModel* model = const_cast<ctkDICOMModel*>(qobject_cast<const ctkDICOMModel*>(index.model()));
132 
133  if (!model)
134  {
135  return;
136  }
137  model->fetchMore(studyIndex);
138 
139  const int seriesCount = model->rowCount(studyIndex);
140 
141  for(int i=0; i<seriesCount; i++)
142  {
143  QModelIndex seriesIndex = studyIndex.child(i, 0);
144  model->fetchMore(seriesIndex);
145 
146  QString studyUid = model->data(studyIndex ,ctkDICOMModel::UIDRole).toString();
147  QString seriesUid = model->data(seriesIndex ,ctkDICOMModel::UIDRole).toString();
148 
149  QString caption = model->data(seriesIndex, Qt::DisplayRole).toString();
150 
151  QStringList thumbnails = this->getThumbnailsForSeries(studyUid, seriesUid);
152 
153  if (thumbnails.empty())
154  continue;
155  QString file = thumbnails[thumbnails.size()/2];
156  this->addThumbnailWidget(file, caption);
157  }
158 
159 }
160 
162 {
163  QModelIndex studyIndex = index.parent();
164  QModelIndex seriesIndex = index;
165 
166  ctkDICOMModel* model = const_cast<ctkDICOMModel*>(qobject_cast<const ctkDICOMModel*>(index.model()));
167  std::cout << "DICOMThumbnailListWidgetPrivate::addSeriesThumbnails " << model << std::endl;
168 
169  if (!model)
170  {
171  return;
172  }
173  model->fetchMore(seriesIndex);
174 
175  QString studyUid = model->data(studyIndex ,ctkDICOMModel::UIDRole).toString();
176  QString seriesUid = model->data(seriesIndex ,ctkDICOMModel::UIDRole).toString();
177 
178  QStringList thumbnails = this->getThumbnailsForSeries(studyUid, seriesUid);
179  std::cout << "Thumbnails: " << thumbnails.size() << std::endl;
180 
181  for (int i=0; i<thumbnails.size(); ++i)
182  {
183  std::cout << " Thumbnail: " << thumbnails[i].toStdString() << std::endl;
184  int humanIndex = i+1;
185  QString caption = QString("Image %1").arg(humanIndex);
186  this->addThumbnailWidget(thumbnails[i], caption);
187  }
188 
189 // for (int i=0; i<files.size(); ++i)
190 // {
191 // QString imageUid = Database->instanceForFile(files[i]);
192 // QString caption = QString("Image %1").arg(i);
193 // this->addThumbnailWidget(studyUid, seriesUid, imageUid, caption);
194 // }
195 }
196 
197 //----------------------------------------------------------------------------
198 
199 QStringList DICOMThumbnailListWidgetPrivate::getThumbnailsForSeries(QString studyUid, QString seriesUid)
200 {
201  std::cout << "DICOMThumbnailListWidgetPrivate::getThumbnailsForSeries" << std::endl;
202  QStringList files = Database->filesForSeries(seriesUid);
203 
204  QStringList thumbnails;
205  for (int i=0; i<files.size(); ++i)
206  {
207  QString imageUid = Database->instanceForFile(files[i]);
208  QStringList filenames = this->getFilesForImage(studyUid, seriesUid, imageUid);
209  thumbnails << filenames;
210  }
211  return thumbnails;
212 }
213 
214 void DICOMThumbnailListWidgetPrivate::addThumbnailWidget(QString studyUid, QString seriesUid, QString imageUid, QString caption)
215 {
216  QStringList filenames = this->getFilesForImage(studyUid, seriesUid, imageUid);
217 
218  for (int i=0; i<filenames.size(); ++i)
219  {
220  this->addThumbnailWidget(filenames[0], QString("%1-%2").arg(caption).arg(i));
221  }
222 }
223 
227 QStringList DICOMThumbnailListWidgetPrivate::getFilesForImage(QString studyUid, QString seriesUid, QString imageUid)
228 {
229  QString baseFilename = QString("%1/thumbs/%2/%3/%4.png")
230  .arg(this->DatabaseDirectory)
231  .arg(studyUid)
232  .arg(seriesUid)
233  .arg(imageUid);
234 
235  QStringList retval;
236 
237  QStringList splitPath = baseFilename.split(".");
238 
239  for (int i=0; true; ++i)
240  {
241  splitPath.back() = QString("frame_%1.png").arg(i);
242  QString frameFilename = splitPath.join(".");
243 
244  if(!QFileInfo(frameFilename).exists())
245  break;
246  retval << frameFilename;
247  }
248 
249  // if no multiimage found, fallback to singleimage.
250  if(retval.empty() && QFileInfo(baseFilename).exists())
251  {
252  retval << baseFilename;
253  return retval;
254  }
255 
256  return retval;
257 }
258 
259 void DICOMThumbnailListWidgetPrivate::addThumbnailWidget(QString filename, const QString &text)
260 {
261  if(!QFileInfo(filename).exists())
262  {
263 // qDebug() << "Thumbnail not found: " << filename;
264  return;
265  }
266 
267  ctkThumbnailLabel* widget = new ctkThumbnailLabel(this->ScrollAreaContentWidget);
268 
269  QString widgetLabel = text;
270  widget->setText( widgetLabel );
271  QPixmap pix(filename);
272 // logger.debug("Setting pixmap to " + filename);
273  if(this->ThumbnailSize.isValid())
274  {
275  widget->setFixedSize(this->ThumbnailSize);
276  }
277  widget->setPixmap(pix);
278 
279  this->addThumbnail(widget);
280 }
281 
282 
283 //----------------------------------------------------------------------------
284 // DICOMThumbnailListWidget methods
285 
286 //----------------------------------------------------------------------------
288  : Superclass(new DICOMThumbnailListWidgetPrivate(this), _parent)
289 {
290 
291 }
292 
293 //----------------------------------------------------------------------------
295 {
296 
297 }
298 
299 //----------------------------------------------------------------------------
300 void DICOMThumbnailListWidget::setDatabaseDirectory(const QString &directory){
302 
303  d->DatabaseDirectory = directory;
304 }
305 
306 void DICOMThumbnailListWidget::setDatabase(QSharedPointer<ctkDICOMDatabase> database)
307 {
309  d->Database = database;
310 }
311 
312 //----------------------------------------------------------------------------
313 void DICOMThumbnailListWidget::addThumbnails(const QModelIndex &index)
314 {
315 // qDebug() << "==DICOMThumbnailListWidget::addThumbnails" ;
316 
318 
319  this->clearThumbnails();
320 
321  ctkDICOMModel* model = const_cast<ctkDICOMModel*>(qobject_cast<const ctkDICOMModel*>(index.model()));
322 
323  if(model)
324  {
325  QModelIndex index0 = index.sibling(index.row(), 0);
326 
327  d->CurrentSelectedModel = index0;
328 
329  if ( model->data(index0,ctkDICOMModel::TypeRole) == static_cast<int>(ctkDICOMModel::PatientType) )
330  {
331  d->addPatientThumbnails(index0);
332  }
333  else if ( model->data(index0,ctkDICOMModel::TypeRole) == static_cast<int>(ctkDICOMModel::StudyType) )
334  {
335  d->addStudyThumbnails(index0);
336  }
337  else if ( model->data(index0,ctkDICOMModel::TypeRole) == static_cast<int>(ctkDICOMModel::SeriesType) )
338  {
339  d->addSeriesThumbnails(index0);
340  }
341  }
342 
343  this->setCurrentThumbnail(0);
344 }
345 
346 } // namespace cx
347 
virtual int rowCount(const QModelIndex &parent=QModelIndex()) const
void addThumbnailWidget(QString filename, const QString &text)
void setDatabaseDirectory(const QString &directory)
QSharedPointer< ctkDICOMDatabase > Database
virtual void fetchMore(const QModelIndex &parent)
virtual QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const
DICOMModel ctkDICOMModel
void addThumbnails(const QModelIndex &index)
void addPatientThumbnails(const QModelIndex &patientIndex)
void addSeriesThumbnails(const QModelIndex &seriesIndex)
Q_DECLARE_METATYPE(QPersistentModelIndex)
DICOMThumbnailListWidgetPrivate(DICOMThumbnailListWidget *parent)
void setDatabase(QSharedPointer< ctkDICOMDatabase > database)
QStringList getThumbnailsForSeries(QString studyUid, QString seriesUid)
QStringList getFilesForImage(QString studyUid, QString seriesUid, QString imageUid)
void addStudyThumbnails(const QModelIndex &studyIndex)