Browse Source

Implement slice number slider bar for image preview

nherlambang 14 years ago
parent
commit
eb1cfa9967

+ 1 - 1
Libs/DICOM/Core/ctkDICOMModel.cpp

@@ -480,7 +480,7 @@ void ctkDICOMModel::fetchMore ( const QModelIndex & parentValue )
 Qt::ItemFlags ctkDICOMModel::flags ( const QModelIndex & modelIndex ) const
 {
   Q_D(const ctkDICOMModel);
-  Qt::ItemFlags indexFlags = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
+  Qt::ItemFlags indexFlags = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable;
   if (modelIndex.column() != 0)
     {
     return indexFlags;

+ 46 - 7
Libs/DICOM/Widgets/Resources/UI/ctkDICOMAppWidget.ui

@@ -20,9 +20,18 @@
    <string>ctkDICOMAppWidget</string>
   </property>
   <layout class="QVBoxLayout" name="verticalLayout_2">
-   <item>
-    <layout class="QHBoxLayout" name="HorizontalLayout_3"/>
-   </item>
+   <property name="leftMargin">
+    <number>0</number>
+   </property>
+   <property name="topMargin">
+    <number>0</number>
+   </property>
+   <property name="rightMargin">
+    <number>0</number>
+   </property>
+   <property name="bottomMargin">
+    <number>12</number>
+   </property>
    <item>
     <widget class="QToolBar" name="ToolBar">
      <property name="windowTitle">
@@ -41,6 +50,12 @@
     <layout class="QVBoxLayout" name="VerticalLayout">
      <item>
       <layout class="QHBoxLayout" name="TopLayout">
+       <property name="leftMargin">
+        <number>12</number>
+       </property>
+       <property name="rightMargin">
+        <number>12</number>
+       </property>
        <item>
         <widget class="QLabel" name="DatabaseNameLabel">
          <property name="maximumSize">
@@ -80,10 +95,13 @@
       </layout>
      </item>
      <item>
-      <layout class="QHBoxLayout" name="QueryLayout" stretch="0,1,0">
-       <item>
-        <layout class="QHBoxLayout" name="horizontalLayout_4"/>
-       </item>
+      <layout class="QHBoxLayout" name="QueryLayout" stretch="1,0">
+       <property name="leftMargin">
+        <number>12</number>
+       </property>
+       <property name="rightMargin">
+        <number>12</number>
+       </property>
        <item>
         <widget class="QTreeView" name="TreeView">
          <property name="alternatingRowColors">
@@ -128,6 +146,15 @@
      </item>
      <item>
       <layout class="QHBoxLayout" name="ViewerLayout">
+       <property name="leftMargin">
+        <number>12</number>
+       </property>
+       <property name="rightMargin">
+        <number>12</number>
+       </property>
+       <property name="bottomMargin">
+        <number>0</number>
+       </property>
        <item>
         <layout class="QVBoxLayout" name="verticalLayout">
          <item>
@@ -359,6 +386,18 @@
            <layout class="QHBoxLayout" name="horizontalLayout_2">
             <item>
              <widget class="QCheckBox" name="AutoPlayCheckbox">
+              <property name="sizePolicy">
+               <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+                <horstretch>0</horstretch>
+                <verstretch>0</verstretch>
+               </sizepolicy>
+              </property>
+              <property name="maximumSize">
+               <size>
+                <width>90</width>
+                <height>16777215</height>
+               </size>
+              </property>
               <property name="text">
                <string>auto-play</string>
               </property>

+ 1 - 1
Libs/DICOM/Widgets/Resources/UI/ctkDICOMQueryWidget.ui

@@ -32,7 +32,7 @@
       </size>
      </property>
      <property name="currentIndex">
-      <number>3</number>
+      <number>0</number>
      </property>
      <widget class="QWidget" name="Name">
       <attribute name="title">

+ 24 - 0
Libs/DICOM/Widgets/ctkDICOMAppWidget.cpp

@@ -164,8 +164,11 @@ ctkDICOMAppWidget::ctkDICOMAppWidget(QWidget* _parent):Superclass(_parent),
 
   connect(d->ImagePreview, SIGNAL(requestNextImage()), this, SLOT(onNextImage()));
   connect(d->ImagePreview, SIGNAL(requestPreviousImage()), this, SLOT(onPreviousImage()));
+  connect(d->ImagePreview, SIGNAL(imageDisplayed(int, int)), this, SLOT(onImagePreviewDisplayed(int,int)));
 
   connect(d->SearchOption, SIGNAL(parameterChanged()), this, SLOT(onSearchParameterChanged()));
+
+  connect(d->PlaySlider, SIGNAL(valueChanged(int)), d->ImagePreview, SLOT(displayImage(int)));
 }
 
 //----------------------------------------------------------------------------
@@ -377,6 +380,12 @@ void ctkDICOMAppWidget::onNextImage(){
 
         imageID = (imageID+1)%imageCount;
 
+        int max = d->PlaySlider->maximum();
+        if(imageID > 0 && imageID < max)
+          {
+            d->PlaySlider->setValue(imageID);
+          }
+
         QModelIndex nextIndex = currentIndex.sibling(imageID, 0);
 
         d->ImagePreview->onModelSelected(nextIndex);
@@ -405,6 +414,12 @@ void ctkDICOMAppWidget::onPreviousImage(){
         imageID--;
         if(imageID < 0) imageID += imageCount;
 
+        int max = d->PlaySlider->maximum();
+        if(imageID > 0 && imageID < max)
+          {
+            d->PlaySlider->setValue(imageID);
+          }
+
         QModelIndex prevIndex = currentIndex.sibling(imageID, 0);
 
         d->ImagePreview->onModelSelected(prevIndex);
@@ -582,3 +597,12 @@ void ctkDICOMAppWidget::onSearchParameterChanged(){
   d->ImagePreview->clearImages();
   d->ImagePreview->onModelSelected(d->DICOMModel.index(0,0));
 }
+
+//----------------------------------------------------------------------------
+void ctkDICOMAppWidget::onImagePreviewDisplayed(int imageID, int count){
+  Q_D(ctkDICOMAppWidget);
+
+  d->PlaySlider->setMinimum(0);
+  d->PlaySlider->setMaximum(count-1);
+  d->PlaySlider->setValue(imageID);
+}

+ 3 - 0
Libs/DICOM/Widgets/ctkDICOMAppWidget.h

@@ -92,6 +92,9 @@ protected slots:
     /// To be called when search parameters in query widget changed
     void onSearchParameterChanged();
 
+    /// To be called after image preview displayed an image
+    void onImagePreviewDisplayed(int imageID, int count);
+
 private:
   Q_DECLARE_PRIVATE(ctkDICOMAppWidget);
   Q_DISABLE_COPY(ctkDICOMAppWidget);

+ 56 - 30
Libs/DICOM/Widgets/ctkDICOMDatasetView.cpp

@@ -60,15 +60,11 @@ public:
 
   ctkDICOMDatasetViewPrivate( ctkDICOMDatasetView& object );
 
-  QString databaseDirectory;
-
-  QModelIndex currentImageIndex;
-
-  QPoint oldMousePos;
-
-  double dicomIntensityLevel;
-
-  double dicomIntensityWindow;
+  QString DatabaseDirectory;
+  QModelIndex CurrentImageIndex;
+  QPoint OldMousePos;
+  double DicomIntensityLevel;
+  double DicomIntensityWindow;
 
   void init();
 
@@ -94,9 +90,9 @@ void ctkDICOMDatasetViewPrivate::init()
 
   q->setMouseTracking(true);
 
-  this->dicomIntensityLevel = 0;
+  this->DicomIntensityLevel = 0;
 
-  this->dicomIntensityWindow = 0;
+  this->DicomIntensityWindow = 0;
 
   /*
   this->Window->setParent(q);
@@ -117,7 +113,7 @@ void ctkDICOMDatasetViewPrivate::setImage(const QModelIndex &imageIndex, bool de
         QModelIndex seriesIndex = imageIndex.parent();
         QModelIndex studyIndex = seriesIndex.parent();
 
-        QString dicomPath = this->databaseDirectory;
+        QString dicomPath = this->DatabaseDirectory;
         dicomPath.append("/dicom/").append(model->data(studyIndex ,ctkDICOMModel::UIDRole).toString());
         dicomPath.append("/").append(model->data(seriesIndex ,ctkDICOMModel::UIDRole).toString());
         dicomPath.append("/").append(model->data(imageIndex ,ctkDICOMModel::UIDRole).toString());
@@ -127,7 +123,9 @@ void ctkDICOMDatasetViewPrivate::setImage(const QModelIndex &imageIndex, bool de
 
             q->clearImages();
             q->addImage(dcmImage, defaultIntensity);
-            this->currentImageIndex = imageIndex;
+            this->CurrentImageIndex = imageIndex;
+
+            q->emitImageDisplayedSignal(imageIndex.row(), model->rowCount(seriesIndex));
         }else{
             q->clearImages();
         }
@@ -203,7 +201,7 @@ void ctkDICOMDatasetViewPrivate::onImageModelSelected(const QModelIndex &index){
     if(model){
         QModelIndex imageIndex = index;
 
-        if(index.parent() == this->currentImageIndex.parent()){
+        if(index.parent() == this->CurrentImageIndex.parent()){
             this->setImage(imageIndex, false);
         }else{
             this->setImage(imageIndex, true);
@@ -241,14 +239,14 @@ ctkDICOMDatasetView::~ctkDICOMDatasetView()
 void ctkDICOMDatasetView::setDatabaseDirectory(const QString &directory){
     Q_D(ctkDICOMDatasetView);
 
-    d->databaseDirectory = directory;
+    d->DatabaseDirectory = directory;
 }
 
 // -------------------------------------------------------------------------
 QModelIndex ctkDICOMDatasetView::currentImageIndex(){
     Q_D(ctkDICOMDatasetView);
 
-    return d->currentImageIndex;
+    return d->CurrentImageIndex;
 }
 
 // -------------------------------------------------------------------------
@@ -265,9 +263,9 @@ void ctkDICOMDatasetView::addImage( DicomImage & dcmImage, bool defaultIntensity
     if ((dcmImage.getStatus() == EIS_Normal)){
         if(defaultIntensity){
             dcmImage.setWindow(0);
-            dcmImage.getWindow(d->dicomIntensityLevel, d->dicomIntensityWindow);
+            dcmImage.getWindow(d->DicomIntensityLevel, d->DicomIntensityWindow);
         }else{
-            dcmImage.setWindow(d->dicomIntensityLevel, d->dicomIntensityWindow);
+            dcmImage.setWindow(d->DicomIntensityLevel, d->DicomIntensityWindow);
         }
         /* get image extension */
         const unsigned long width = dcmImage.getWidth();
@@ -303,7 +301,7 @@ void ctkDICOMDatasetView::mousePressEvent(QMouseEvent* event){
     Q_D(ctkDICOMDatasetView);
 
     event->accept();
-    d->oldMousePos = event->pos();
+    d->OldMousePos = event->pos();
 }
 
 // -------------------------------------------------------------------------
@@ -313,30 +311,30 @@ void ctkDICOMDatasetView::mouseMoveEvent(QMouseEvent* event){
     if(event->buttons() == Qt::RightButton){
         event->accept();
         QPoint nowPos = event->pos();
-        if(nowPos.y() > d->oldMousePos.y()){
+        if(nowPos.y() > d->OldMousePos.y()){
             emit requestNextImage();
-            d->oldMousePos = event->pos();
-        }else if(nowPos.y() < d->oldMousePos.y()){
+            d->OldMousePos = event->pos();
+        }else if(nowPos.y() < d->OldMousePos.y()){
             emit requestPreviousImage();
-            d->oldMousePos = event->pos();
+            d->OldMousePos = event->pos();
         }
     }else if(event->buttons() == Qt::MidButton){
         event->accept();
         QPoint nowPos = event->pos();
 
-        this->setZoom(this->zoom() - (nowPos.y()-d->oldMousePos.y())/100.0);
+        this->setZoom(this->zoom() - (nowPos.y()-d->OldMousePos.y())/100.0);
 
-        d->oldMousePos = event->pos();
+        d->OldMousePos = event->pos();
     }else if(event->buttons() == Qt::LeftButton){
         event->accept();
         QPoint nowPos = event->pos();
 
-        d->dicomIntensityWindow += (5*(nowPos.x()-d->oldMousePos.x()));
-        d->dicomIntensityLevel -= (5*(nowPos.y()-d->oldMousePos.y()));
+        d->DicomIntensityWindow += (5*(nowPos.x()-d->OldMousePos.x()));
+        d->DicomIntensityLevel -= (5*(nowPos.y()-d->OldMousePos.y()));
 
-        d->setImage(d->currentImageIndex, false);
+        d->setImage(d->CurrentImageIndex, false);
 
-        d->oldMousePos = event->pos();
+        d->OldMousePos = event->pos();
     }
 
     Superclass::mouseMoveEvent(event);
@@ -351,7 +349,6 @@ void ctkDICOMDatasetView::onModelSelected(const QModelIndex &index){
     if(model){
         QModelIndex index0 = index.sibling(index.row(), 0);
 
-
         if ( model->data(index0,ctkDICOMModel::TypeRole) == static_cast<int>(ctkDICOMModel::PatientType) ){
             d->onPatientModelSelected(index0);
         }else if ( model->data(index0,ctkDICOMModel::TypeRole) == static_cast<int>(ctkDICOMModel::StudyType) ){
@@ -363,3 +360,32 @@ void ctkDICOMDatasetView::onModelSelected(const QModelIndex &index){
         }
     }
 }
+
+// -------------------------------------------------------------------------
+void ctkDICOMDatasetView::displayImage(int imageIndex){
+  Q_D(ctkDICOMDatasetView);
+
+  if(d->CurrentImageIndex.isValid())
+    {
+      QModelIndex seriesIndex = d->CurrentImageIndex.parent();
+      ctkDICOMModel* model = const_cast<ctkDICOMModel*>(qobject_cast<const ctkDICOMModel*>(seriesIndex.model()));
+
+      if(model)
+        {
+          if(imageIndex >= 0 && imageIndex < model->rowCount(seriesIndex))
+            {
+            this->onModelSelected(model->index(imageIndex, 0, seriesIndex));
+            }
+          else
+            {
+            logger.debug("out of index");
+            }
+        }
+    }
+}
+
+// -------------------------------------------------------------------------
+void ctkDICOMDatasetView::emitImageDisplayedSignal(int imageID, int count){
+  emit imageDisplayed(imageID, count);
+}
+

+ 6 - 1
Libs/DICOM/Widgets/ctkDICOMDatasetView.h

@@ -62,15 +62,18 @@ signals:
   void requestNextImage();
   void requestPreviousImage();
 
+  void imageDisplayed(int imageID, int count);
+
 public slots:
 
   void addImage( const QImage & image );
 
-  // TEST
   void addImage( DicomImage & dcmImage, bool defaultIntensity = true);
 
   void onModelSelected(const QModelIndex& index);
 
+  void displayImage(int imageIndex);
+
   virtual void update( bool zoomChanged=false, bool sizeChanged=false );
 
 protected:
@@ -91,6 +94,8 @@ private:
 
   Q_DISABLE_COPY( ctkDICOMDatasetView );
 
+  void emitImageDisplayedSignal(int imageID, int count);
+
 };
 
 #endif

+ 16 - 10
Libs/DICOM/Widgets/ctkDICOMThumbnailListWidget.cpp

@@ -266,26 +266,32 @@ void ctkDICOMThumbnailListWidget::selectThumbnail(int index){
     if(index >= count)return;
 
     for(int i=0; i<count; i++)
-    {
-        ctkDICOMThumbnailWidget* thumbnailWidget = qobject_cast<ctkDICOMThumbnailWidget*>(d->ScrollAreaContentWidget->layout()->itemAt(i)->widget());
-        if(i == index)
+      {
+      ctkDICOMThumbnailWidget* thumbnailWidget = qobject_cast<ctkDICOMThumbnailWidget*>(d->ScrollAreaContentWidget->layout()->itemAt(i)->widget());
+      if(i == index)
         {
-            thumbnailWidget->setSelected(true);
-            d->ScrollArea->ensureWidgetVisible(thumbnailWidget);
+        thumbnailWidget->setSelected(true);
+        d->ScrollArea->ensureWidgetVisible(thumbnailWidget);
         }
-        else
+      else
         {
-            thumbnailWidget->setSelected(false);
+        thumbnailWidget->setSelected(false);
         }
-    }
+      }
 }
 
 //----------------------------------------------------------------------------
 void ctkDICOMThumbnailListWidget::selectThumbnail(const QModelIndex &index){
     Q_D(ctkDICOMThumbnailListWidget);
 
-    if(!d->CurrentSelectedModel.isValid())return;
-    if(index.parent() != d->CurrentSelectedModel)return;
+    if(!d->CurrentSelectedModel.isValid())
+      {
+      return;
+      }
+    if(index.parent() != d->CurrentSelectedModel)
+      {
+      return;
+      }
 
     ctkDICOMModel* model = const_cast<ctkDICOMModel*>(qobject_cast<const ctkDICOMModel*>(index.model()));