Browse Source

Merge branch 'mehrtash-ctk-dicom-object-list-widget'

* mehrtash-ctk-dicom-object-list-widget: (21 commits)
  expansion of nested items in the tree is added
  copyright text modified
  corrected newline
  added BWH Copyright to ctkDICOMObjectModel files
  Fix identation issues
  ENH: current path line edit read only
  Fix some indentation issues
  ctkDICOMObjectListWidget Created
  ENH: Column widths adjusted to contents in the example tree view
  ENH: View content is not editable
  ENH: Tag HEX added to the DICOM object model
  ENH: Length added to the DICOM object model
  FIX: Hierarchy enabled by changing the order of tag and VR in the model
  ENH: Hierarchy and VR added
  ctkDICOMOBjectModelTest1 added to the project
  FIX: The method names for ctkDICOMObjectModelPrivate modified in order to resolve the qulification on member error.
  seqinsert and iteminsert methods combined in a new method tarverseDataElemnts. The code duplication for seqinsert and iteminsert is solved.
  Class name changed to ctkDICOMObjectModel and some stylistic modifications
  standard output streams commented
  seqInsert and itemInsert modified
  ...
Steve Pieper 11 years ago
parent
commit
3c12265914

+ 3 - 0
Libs/DICOM/Core/CMakeLists.txt

@@ -40,6 +40,8 @@ set(KIT_SRCS
   ctkDICOMItem.h
   ctkDICOMModel.cpp
   ctkDICOMModel.h
+  ctkDICOMObjectModel.cpp
+  ctkDICOMObjectModel.h
   ctkDICOMPersonName.cpp
   ctkDICOMPersonName.h
   ctkDICOMQuery.cpp
@@ -71,6 +73,7 @@ set(KIT_MOC_SRCS
   ctkDICOMIndexer_p.h
   ctkDICOMFilterProxyModel.h
   ctkDICOMModel.h
+  ctkDICOMObjectModel.h
   ctkDICOMQuery.h
   ctkDICOMRetrieve.h
   ctkDICOMTester.h

+ 1 - 0
Libs/DICOM/Core/Testing/Cpp/CMakeLists.txt

@@ -10,6 +10,7 @@ create_test_sourcelist(Tests ${KIT}CppTests.cpp
   ctkDICOMItemTest1.cpp
   ctkDICOMIndexerTest1.cpp
   ctkDICOMModelTest1.cpp
+  ctkDICOMObjectModelTest1.cpp
   ctkDICOMPersonNameTest1.cpp
   ctkDICOMQueryTest1.cpp
   ctkDICOMQueryTest2.cpp

+ 1 - 0
Libs/DICOM/Core/Testing/Cpp/Testing/Temporary/CTestCostData.txt

@@ -0,0 +1 @@
+---

+ 3 - 0
Libs/DICOM/Core/Testing/Cpp/Testing/Temporary/LastTest.log

@@ -0,0 +1,3 @@
+Start testing: Sep 09 13:27 Eastern Daylight Time
+----------------------------------------------------------
+End testing: Sep 09 13:27 Eastern Daylight Time

+ 60 - 0
Libs/DICOM/Core/Testing/Cpp/ctkDICOMObjectModelTest1.cpp

@@ -0,0 +1,60 @@
+/*==========================================================================
+
+  Library: CTK
+
+  Copyright (c) Brigham and Women's Hospital (BWH).
+  Copyright (c) University of Sheffield.
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+==========================================================================*/
+
+// STD includes
+#include <iostream>
+#include <algorithm>
+
+// Qt includes
+#include <QApplication>
+#include <QFileDialog>
+#include <QHeaderView>
+#include <QString>
+#include <QTimer>
+#include <QTreeView>
+
+// CTK Core
+#include "ctkDICOMObjectModel.h"
+
+int ctkDICOMObjectModelTest1( int argc, char * argv [] )
+{
+  QApplication app(argc, argv);
+  QString fileName;
+  //TODO: Add the option for reading the test file from argv
+  fileName = QFileDialog::getOpenFileName( 0,
+    "Choose a DCM File", ".","DCM (*)" );
+  ctkDICOMObjectModel dcmObjModel;
+  dcmObjModel.setFile(fileName);
+
+  QTreeView *viewer = new QTreeView();
+  viewer->setModel( &dcmObjModel);
+  viewer->expandAll();
+  viewer->resizeColumnToContents(0);
+  viewer->resizeColumnToContents(1);
+  viewer->resizeColumnToContents(2);
+  viewer->resizeColumnToContents(3);
+  viewer->resizeColumnToContents(4);
+  //viewer->header()->setResizeMode( QHeaderView::Stretch);
+  viewer->show();
+  viewer->raise();
+
+  return app.exec();
+}

+ 280 - 0
Libs/DICOM/Core/ctkDICOMObjectModel.cpp

@@ -0,0 +1,280 @@
+/*=============================================================================
+
+  Library: CTK
+
+  Copyright (c) Brigham and Women's Hospital (BWH).
+  Copyright (c) University of Sheffield.
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+=============================================================================*/
+
+// Qt include
+#include <QSharedData>
+#include <QStandardItem>
+#include <QString>
+#include <QStringList>
+
+// DCMTK includes
+#include "dcmtk/dcmdata/dcdeftag.h"
+#include "dcmtk/dcmdata/dcdatset.h"
+#include "dcmtk/dcmdata/dcfilefo.h"
+#include "dcmtk/dcmdata/dcmetinf.h"
+#include "dcmtk/dcmdata/dcitem.h"
+#include "dcmtk/ofstd/ofcond.h"
+#include "dcmtk/ofstd/ofstring.h"
+#include "dcmtk/ofstd/ofstd.h"
+
+// CTK DICOM Core
+#include "ctkDICOMObjectModel.h"
+
+//------------------------------------------------------------------------------
+class ctkDICOMObjectModelPrivate
+{
+  Q_DECLARE_PUBLIC(ctkDICOMObjectModel);
+
+protected:
+  ctkDICOMObjectModel* const q_ptr;
+
+public:
+  ctkDICOMObjectModelPrivate(ctkDICOMObjectModel&);
+  virtual ~ctkDICOMObjectModelPrivate();
+  
+  void init();
+  void itemInsert( DcmItem *dataset, QStandardItem *parent);
+  void seqInsert( DcmSequenceOfItems *dataset, QStandardItem *parent);
+  QString getTagValue( DcmElement *dcmElem);
+  QStandardItem* populateModelRow(const QString& tagName,const QString& tagHexName,
+  const QString& tagValue, const QString& VRName,
+  const QString& elementLengthQString, QStandardItem *parent);
+
+  DcmFileFormat fileFormat;
+  QStandardItem *rootItem;
+};
+
+//------------------------------------------------------------------------------
+ctkDICOMObjectModelPrivate::ctkDICOMObjectModelPrivate(ctkDICOMObjectModel& o):q_ptr(&o)
+{
+}
+
+//------------------------------------------------------------------------------
+ctkDICOMObjectModelPrivate::~ctkDICOMObjectModelPrivate()
+{
+}
+
+//------------------------------------------------------------------------------
+void ctkDICOMObjectModelPrivate::init()
+{
+  Q_Q(ctkDICOMObjectModel);
+  QStringList horizontalHeaderLabels;
+  horizontalHeaderLabels.append( QString("Tag"));
+  horizontalHeaderLabels.append( QString("Tag HEX"));
+  horizontalHeaderLabels.append( QString("VR"));
+  horizontalHeaderLabels.append( QString("Length"));
+  horizontalHeaderLabels.append( QString("Value"));
+  q->setHorizontalHeaderLabels(horizontalHeaderLabels);
+}
+
+//------------------------------------------------------------------------------
+void ctkDICOMObjectModelPrivate::itemInsert( DcmItem *dataset, QStandardItem *parent)
+{
+  DcmStack stack;
+  dataset->nextObject( stack, OFTrue);
+  for( ; stack.top(); dataset->nextObject( stack, OFFalse))
+    {
+    DcmObject *dO =  stack.top();
+    // put in the visit node function
+    QString tagValue = "";
+    DcmTag tag = dO->getTag();
+	  // std::cout<<tag;
+    QString tagName = tag.getTagName();
+    //
+    DcmTagKey tagX = tag.getXTag();
+    QString tagHexName = tagX.toString().c_str();
+    //
+    DcmVR VR = dO->getVR();
+    QString VRName = VR.getVRName();
+    //
+    // Getting length
+    int elementLength;
+    elementLength = dO->getLength();
+    QString elementLengthQString = QString::number(elementLength);
+    //
+    DcmTag tagKey = tag.getXTag();
+    if( tagKey == DCM_SequenceDelimitationItem
+        || tagKey == DCM_ItemDelimitationItem
+        || "Item" == tagName)
+      {
+      return;
+      }
+
+    DcmElement *dcmElem = dynamic_cast<DcmElement *> (dO);
+    tagValue = getTagValue(dcmElem);
+
+    // Populate QStandardModel with current DICOM element tag name and value
+    QStandardItem *tagItem = populateModelRow(tagName,tagHexName,tagValue,VRName,elementLengthQString,parent);
+
+    // Check if the DICOM object is a SQ Data element and extract the nested DICOM objects
+    if( dcmElem && !dcmElem->isLeaf())
+      {
+      // now dcmElem points to a sequence of items
+      ctkDICOMObjectModelPrivate::seqInsert( dynamic_cast<DcmSequenceOfItems*> (dcmElem), tagItem);
+      }
+  }
+}
+
+//------------------------------------------------------------------------------
+void ctkDICOMObjectModelPrivate::seqInsert( DcmSequenceOfItems *dataset, QStandardItem *parent)
+{
+  DcmObject *dO = dataset->nextInContainer(NULL);
+
+  for( ; dO; dO = dataset->nextInContainer(dO))
+    {
+    DcmElement *dcmElem = dynamic_cast<DcmElement *> (dO);
+    QString tagValue = "";
+    DcmTag tag = dO->getTag();
+    DcmTag tagKey = tag.getXTag();
+    if( tagKey == DCM_SequenceDelimitationItem
+        || tagKey == DCM_ItemDelimitationItem)
+      {
+      return;
+      }
+
+    QString tagName = tag.getTagName();
+    DcmTagKey tagX = tag.getXTag();
+    QString tagHexName = tagX.toString().c_str();
+    DcmVR VR = dO->getVR();
+    QString VRName = VR.getVRName();
+
+    // Getting length
+    int elementLength;
+    elementLength = dO->getLength();
+    QString elementLengthQString = QString::number(elementLength);
+
+    if( dcmElem)
+      {
+      tagValue = getTagValue(dcmElem);
+      }
+
+    QStandardItem *tagItem = populateModelRow(tagName,tagHexName,tagValue,VRName,elementLengthQString,parent);
+
+   if( dcmElem && !dcmElem->isLeaf())
+      {
+      ctkDICOMObjectModelPrivate::seqInsert( dynamic_cast<DcmSequenceOfItems*> (dcmElem), tagItem);
+      }
+    else if( tag.getXTag() == DCM_Item)
+      {
+      itemInsert( dynamic_cast<DcmItem*> (dO), tagItem);
+      }
+   }
+}
+
+//------------------------------------------------------------------------------
+QString ctkDICOMObjectModelPrivate::getTagValue( DcmElement *dcmElem)
+{
+  QString tagValue = "";
+  std::ostringstream value;
+  OFString part;
+  std::string sep;
+  int mult = dcmElem->getVM();
+  int pos;
+
+  if( mult>1)
+    {
+    value << "[" << mult << "] ";
+    }
+
+  for( pos=0; pos < mult; pos++)
+    {
+    value << sep;
+    OFCondition status = dcmElem->getOFString( part, pos);
+    if( status.good())
+      {
+      value << part.c_str();
+      sep = ", ";
+      }
+    }
+    if( pos < mult-1)
+      {
+      value << " ...";
+      }
+  tagValue = value.str().c_str();
+
+  return tagValue;
+}
+
+//------------------------------------------------------------------------------
+QStandardItem* ctkDICOMObjectModelPrivate::populateModelRow(const QString& tagName,
+   const QString& tagHexName, const QString& tagValue,const QString& VRName,
+   const QString& elementLengthQString, QStandardItem *parent)
+{
+  // Create items
+  QStandardItem *VRItem = new QStandardItem( VRName);
+  QStandardItem *tagItem = new QStandardItem( tagName);
+  QStandardItem *tagHexItem = new QStandardItem( tagHexName);
+  QStandardItem *lengthItem = new QStandardItem( elementLengthQString);
+  QStandardItem *valItem = new QStandardItem( tagValue);
+
+  VRItem->setFlags(VRItem->flags() & ~Qt::ItemIsEditable);
+  tagItem->setFlags(tagItem->flags() & ~Qt::ItemIsEditable);
+  tagHexItem->setFlags(tagHexItem->flags() & ~Qt::ItemIsEditable);
+  lengthItem->setFlags(lengthItem->flags() & ~Qt::ItemIsEditable);
+  valItem->setFlags(valItem->flags() & ~Qt::ItemIsEditable);
+
+  // Insert items
+  QList<QStandardItem *> modelRow;
+
+  modelRow.append( tagItem);
+  modelRow.append( tagHexItem);
+  modelRow.append( VRItem);
+  modelRow.append( lengthItem);
+  modelRow.append( valItem);
+  parent->appendRow( modelRow);
+
+  return tagItem;
+}
+
+//------------------------------------------------------------------------------
+ctkDICOMObjectModel::ctkDICOMObjectModel(QObject* parentObject)
+  : Superclass(parentObject)
+  , d_ptr(new ctkDICOMObjectModelPrivate(*this))
+{
+  Q_D(ctkDICOMObjectModel);
+  d->init();
+}
+
+//------------------------------------------------------------------------------
+ctkDICOMObjectModel::ctkDICOMObjectModel(const ctkDICOMObjectModel& other)
+{
+}
+
+//------------------------------------------------------------------------------
+ctkDICOMObjectModel::~ctkDICOMObjectModel()
+{
+}
+
+//------------------------------------------------------------------------------
+void ctkDICOMObjectModel::setFile(const QString &fileName)
+{
+  Q_D(ctkDICOMObjectModel);
+
+  OFCondition status = d->fileFormat.loadFile( fileName.toLatin1().data());
+  if( !status.good() )
+    {
+    // TODO: Through an error message.
+    }
+
+  DcmDataset *dataset = d->fileFormat.getDataset();
+  d->rootItem = ctkDICOMObjectModel::invisibleRootItem();
+  d->itemInsert( dataset, d->rootItem);
+}

+ 61 - 0
Libs/DICOM/Core/ctkDICOMObjectModel.h

@@ -0,0 +1,61 @@
+/*=============================================================================
+
+  Library: CTK
+
+  Copyright (c) Brigham and Women's Hospital (BWH) 
+  Copyright (c) University of Sheffield
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+=============================================================================*/
+
+#ifndef __ctkDICOMObjectModel_h
+#define __ctkDICOMObjectModel_h
+
+// STD includes
+#include <string>
+
+// Qt includes
+#include <QMetaType>
+#include <QStandardItemModel>
+#include <QString>
+
+#include "ctkDICOMCoreExport.h"
+
+class ctkDICOMObjectModelPrivate;
+/// \ingroup DICOM_Core
+///
+/// \brief Provides a Qt MVC-compatible wrapper around a ctkDICOMItem.
+///
+class CTK_DICOM_CORE_EXPORT ctkDICOMObjectModel
+  : public QStandardItemModel
+{
+  Q_OBJECT
+  typedef QStandardItemModel Superclass;
+  //Q_PROPERTY(setFile);
+
+public:
+
+  explicit ctkDICOMObjectModel(QObject* parent = 0);
+  ctkDICOMObjectModel(const ctkDICOMObjectModel& other);
+  virtual ~ctkDICOMObjectModel();
+  Q_INVOKABLE void setFile (const QString& fileName);
+
+protected:
+  QScopedPointer<ctkDICOMObjectModelPrivate> d_ptr;
+
+private:
+  Q_DECLARE_PRIVATE(ctkDICOMObjectModel);
+};
+
+#endif // ctkDICOMObjectModel_h

+ 4 - 0
Libs/DICOM/Widgets/CMakeLists.txt

@@ -29,6 +29,8 @@ set(KIT_SRCS
   ctkDICOMQueryRetrieveWidget.h
   ctkDICOMQueryWidget.cpp
   ctkDICOMQueryWidget.h
+  ctkDICOMObjectListWidget.cpp
+  ctkDICOMObjectListWidget.h
   ctkDICOMServerNodeWidget.cpp
   ctkDICOMServerNodeWidget.h
   ctkDICOMTableManager.h
@@ -49,6 +51,7 @@ set(KIT_MOC_SRCS
   ctkDICOMDirectoryListWidget.h
   ctkDICOMImage.h
   ctkDICOMImportWidget.h
+  ctkDICOMObjectListWidget.h
   ctkDICOMQueryRetrieveWidget.h
   ctkDICOMQueryWidget.h
   ctkDICOMServerNodeWidget.h
@@ -67,6 +70,7 @@ set(KIT_UI_FORMS
   Resources/UI/ctkDICOMListenerWidget.ui
   Resources/UI/ctkDICOMQueryRetrieveWidget.ui
   Resources/UI/ctkDICOMQueryWidget.ui
+  Resources/UI/ctkDICOMObjectListWidget.ui 
   Resources/UI/ctkDICOMServerNodeWidget.ui
   Resources/UI/ctkDICOMTableManager.ui
   Resources/UI/ctkDICOMTableView.ui

+ 55 - 0
Libs/DICOM/Widgets/Resources/UI/ctkDICOMObjectListWidget.ui

@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ctkDICOMObjectListWidget</class>
+ <widget class="QWidget" name="ctkDICOMObjectListWidget">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>359</width>
+    <height>225</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QGridLayout" name="gridLayout">
+   <item row="0" column="0">
+    <layout class="QFormLayout" name="formLayout">
+     <property name="fieldGrowthPolicy">
+      <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
+     </property>
+     <item row="1" column="0">
+      <widget class="QLabel" name="label">
+       <property name="text">
+        <string>File Paht:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="1">
+      <widget class="QLineEdit" name="currentPathLineEdit"/>
+     </item>
+    </layout>
+   </item>
+   <item row="1" column="0">
+    <layout class="QVBoxLayout" name="verticalLayout">
+     <property name="bottomMargin">
+      <number>0</number>
+     </property>
+     <item>
+      <widget class="QSlider" name="fileSlider">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QTreeView" name="dcmObjectTreeView"/>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>

+ 138 - 0
Libs/DICOM/Widgets/ctkDICOMObjectListWidget.cpp

@@ -0,0 +1,138 @@
+/*=========================================================================
+
+  Library:   CTK
+
+  Copyright (c) Brigham and Women's Hospital (BWH).
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0.txt
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+=========================================================================*/
+
+// ctkDICOMWidgets includes
+#include "ctkDICOMObjectListWidget.h"
+#include "ui_ctkDICOMObjectListWidget.h"
+
+// STD includes
+#include <iostream>
+
+// Qt includes
+#include <QString>
+#include <QStringList>
+#include <QTimer>
+
+//CTK includes
+#include <ctkDICOMObjectModel.h>
+#include <ctkLogger.h>
+static ctkLogger logger("org.commontk.DICOM.Widgets.ctkDICOMObjectListWidget");
+
+//----------------------------------------------------------------------------
+class ctkDICOMObjectListWidgetPrivate: public Ui_ctkDICOMObjectListWidget
+{
+public:
+  ctkDICOMObjectListWidgetPrivate();
+  ~ctkDICOMObjectListWidgetPrivate();
+  void populateDICOMObjectTreeView(const QString& fileName);
+
+  QString currentFile;
+  QStringList fileList;
+};
+
+//----------------------------------------------------------------------------
+// ctkDICOMObjectListWidgetPrivate methods
+
+//----------------------------------------------------------------------------
+ctkDICOMObjectListWidgetPrivate::ctkDICOMObjectListWidgetPrivate()
+{
+
+}
+
+//----------------------------------------------------------------------------
+ctkDICOMObjectListWidgetPrivate::~ctkDICOMObjectListWidgetPrivate(){
+
+}
+
+//----------------------------------------------------------------------------
+void ctkDICOMObjectListWidgetPrivate::populateDICOMObjectTreeView(const QString& fileName)
+{
+  //TODO: Check memory management
+  ctkDICOMObjectModel* dcmObjModel = new ctkDICOMObjectModel;
+  dcmObjModel->setFile(fileName);
+  std::cerr << "fileName is =" << fileName.toUtf8().constData() << "\n";
+  this->dcmObjectTreeView->reset();
+  this->dcmObjectTreeView->setModel( dcmObjModel);
+  this->dcmObjectTreeView->expandAll();
+}
+
+//----------------------------------------------------------------------------
+// ctkDICOMObjectListWidget methods
+
+//----------------------------------------------------------------------------
+ctkDICOMObjectListWidget::ctkDICOMObjectListWidget(QWidget* _parent):Superclass(_parent), 
+  d_ptr(new ctkDICOMObjectListWidgetPrivate)
+{
+  Q_D(ctkDICOMObjectListWidget);
+
+  d->setupUi(this);
+  d->currentPathLineEdit->setReadOnly(true);
+  connect(d->fileSlider, SIGNAL(valueChanged(int)), this, SLOT(updateWidget()));
+}
+
+//----------------------------------------------------------------------------
+ctkDICOMObjectListWidget::~ctkDICOMObjectListWidget()
+{
+}
+
+//----------------------------------------------------------------------------
+void ctkDICOMObjectListWidget::setCurrentFile(const QString& newFileName)
+{
+  Q_D(ctkDICOMObjectListWidget);
+  d->currentPathLineEdit->setText(newFileName);
+}
+
+// --------------------------------------------------------------------------
+void ctkDICOMObjectListWidget::setFileList(const QStringList& fileList)
+{
+  Q_D(ctkDICOMObjectListWidget);
+  d->fileList = fileList;
+  if (d-> fileList.size()> 0)
+  {
+    d->currentFile = d->fileList[0];
+    d->currentPathLineEdit->setText(d->currentFile );
+    d->populateDICOMObjectTreeView(d->currentFile );
+    d->fileSlider->setMaximum(d->fileList.size()-1);
+  }
+}
+
+// --------------------------------------------------------------------------
+QString ctkDICOMObjectListWidget::currentFile()
+{
+  Q_D(const ctkDICOMObjectListWidget);
+  return d->currentFile;
+}
+
+// --------------------------------------------------------------------------
+QStringList ctkDICOMObjectListWidget::fileList()
+{
+  Q_D(const ctkDICOMObjectListWidget);
+  return d->fileList;
+}
+
+// --------------------------------------------------------------------------
+void ctkDICOMObjectListWidget::updateWidget()
+{
+  Q_D(ctkDICOMObjectListWidget);
+  int fileNumber = d->fileSlider->value();
+  d->currentFile = d->fileList[fileNumber];
+  d->currentPathLineEdit->setText(d->currentFile);
+  d->populateDICOMObjectTreeView(d->currentFile);
+}

+ 63 - 0
Libs/DICOM/Widgets/ctkDICOMObjectListWidget.h

@@ -0,0 +1,63 @@
+/*=========================================================================
+
+  Library:   CTK
+
+  Copyright (c)  Brigham and Women's Hospital (BWH).
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0.txt
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+=========================================================================*/
+
+#ifndef __ctkDICOMObjectListWidget_h
+#define __ctkDICOMObjectListWidget_h
+
+// Qt includes 
+#include <QWidget>
+
+#include "ctkDICOMWidgetsExport.h"
+
+class ctkDICOMObjectListWidgetPrivate;
+
+/// \ingroup DICOM_Widgets
+class CTK_DICOM_WIDGETS_EXPORT ctkDICOMObjectListWidget : public QWidget
+{
+  Q_OBJECT
+  Q_PROPERTY(QString currentFile READ currentFile WRITE setCurrentFile)
+  Q_PROPERTY(QStringList fileList READ fileList WRITE setFileList)
+
+public:
+  typedef QWidget Superclass;
+  explicit ctkDICOMObjectListWidget(QWidget* parent=0);
+  virtual ~ctkDICOMObjectListWidget();
+
+  QString currentFile();
+  QStringList fileList();
+
+protected:
+  QScopedPointer<ctkDICOMObjectListWidgetPrivate> d_ptr;
+
+private:
+  Q_DECLARE_PRIVATE(ctkDICOMObjectListWidget);
+  Q_DISABLE_COPY(ctkDICOMObjectListWidget);
+
+Q_SIGNALS:
+
+public Q_SLOTS:
+  void setCurrentFile(const QString& newFileName);
+  void setFileList(const QStringList& fileList);
+
+protected Q_SLOTS:
+  void updateWidget();
+};
+
+#endif