浏览代码

Merge branch 'master' of github.com:commontk/CTK

Julien Finet 14 年之前
父节点
当前提交
c2d2316adf

+ 108 - 1
Libs/DICOM/Core/ctkDICOMDatabase.cpp

@@ -74,6 +74,7 @@ public:
   QString      DatabaseFileName;
   QString      LastError;
   QSqlDatabase Database;
+  QMap<QString, QString> LoadedHeader;
 };
 
 //------------------------------------------------------------------------------
@@ -133,7 +134,7 @@ ctkDICOMDatabase::ctkDICOMDatabase(QString databaseFile)
   d->init(databaseFile);
 }
 
-ctkDICOMDatabase::ctkDICOMDatabase()
+ctkDICOMDatabase::ctkDICOMDatabase(QObject* parent)
    : d_ptr(new ctkDICOMDatabasePrivate(*this))
 {
 }
@@ -223,6 +224,112 @@ void ctkDICOMDatabase::closeDatabase()
 }
 
 //------------------------------------------------------------------------------
+QStringList ctkDICOMDatabase::studiesForPatient(QString patientUID)
+{
+  Q_D(ctkDICOMDatabase);
+  QSqlQuery query(d->Database);
+  query.prepare ( "SELECT StudyInstanceUID FROM Studies WHERE PatientsUID = ?" );
+  query.bindValue ( 0, patientUID );
+  query.exec();
+  QStringList result;
+  while (query.next()) 
+    {
+    result << query.value(0).toString();
+    }
+  return( result );
+}
+
+//------------------------------------------------------------------------------
+QStringList ctkDICOMDatabase::seriesForStudy(QString studyUID)
+{
+  Q_D(ctkDICOMDatabase);
+  QSqlQuery query(d->Database);
+  query.prepare ( "SELECT SeriesInstanceUID FROM Series WHERE StudyInstanceUID=?");
+  query.bindValue ( 0, studyUID );
+  query.exec();
+  QStringList result;
+  while (query.next()) 
+    {
+    result << query.value(0).toString();
+    }
+  return( result );
+}
+
+//------------------------------------------------------------------------------
+QStringList ctkDICOMDatabase::filesForSeries(QString seriesUID)
+{
+  Q_D(ctkDICOMDatabase);
+  QSqlQuery query(d->Database);
+  query.prepare ( "SELECT Filename FROM Images WHERE SeriesInstanceUID=?");
+  query.bindValue ( 0, seriesUID );
+  query.exec();
+  QStringList result;
+  while (query.next()) 
+    {
+    result << query.value(0).toString();
+    }
+  return( result );
+}
+
+//------------------------------------------------------------------------------
+void ctkDICOMDatabase::loadInstanceHeader (QString sopInstanceUID)
+{
+  Q_D(ctkDICOMDatabase);
+  QSqlQuery query(d->Database);
+  query.prepare ( "SELECT Filename FROM Images WHERE SOPInstanceUID=?");
+  query.bindValue ( 0, sopInstanceUID );
+  query.exec();
+  d->LoadedHeader.clear();
+  if (query.next())
+    {
+    QString fileName = query.value(0).toString();
+    this->loadFileHeader(fileName);
+    }
+  return;
+}
+
+//------------------------------------------------------------------------------
+void ctkDICOMDatabase::loadFileHeader (QString fileName)
+{
+  Q_D(ctkDICOMDatabase);
+  DcmFileFormat fileFormat;
+  OFCondition status = fileFormat.loadFile(fileName.toLatin1().data());
+  if (status.good())
+    {
+    DcmDataset *dataset = fileFormat.getDataset();
+    DcmStack stack;
+    while (dataset->nextObject(stack, true) == EC_Normal)
+      {
+      DcmObject *dO = stack.top();
+      if (dO->isaString())
+        {
+        QString tag = QString("%1,%2").arg(
+            dO->getGTag(),4,16,QLatin1Char('0')).arg(
+            dO->getETag(),4,16,QLatin1Char('0'));
+        std::ostringstream s;
+        dO->print(s);
+        d->LoadedHeader[tag] = QString(s.str().c_str());
+        }
+      }
+    }
+  return;
+}
+
+//------------------------------------------------------------------------------
+QStringList ctkDICOMDatabase::headerKeys ()
+{
+  Q_D(ctkDICOMDatabase);
+  return (d->LoadedHeader.keys());
+}
+
+//------------------------------------------------------------------------------
+QString ctkDICOMDatabase::headerValue (QString key)
+{
+  Q_D(ctkDICOMDatabase);
+  return (d->LoadedHeader[key]);
+}
+
+//------------------------------------------------------------------------------
 /*
 void ctkDICOMDatabase::insert ( DcmDataset *dataset ) {
   this->insert ( dataset, QString() );

+ 18 - 4
Libs/DICOM/Core/ctkDICOMDatabase.h

@@ -23,6 +23,7 @@
 
 // Qt includes 
 #include <QObject>
+#include <QStringList>
 #include <QSqlDatabase>
 
 #include "ctkDICOMCoreExport.h"
@@ -34,7 +35,7 @@ class CTK_DICOM_CORE_EXPORT ctkDICOMDatabase : public QObject
 {
   Q_OBJECT
 public:
-  explicit ctkDICOMDatabase();
+  explicit ctkDICOMDatabase(QObject *parent = 0);
   explicit ctkDICOMDatabase(QString databaseFile);
   virtual ~ctkDICOMDatabase();
 
@@ -51,14 +52,27 @@ public:
   ///
   /// @param databaseFile TODO
   /// @param connectionName TODO
-  virtual void openDatabase(const QString databaseFile, const QString& connectionName = "DICOM-DB" );
+  Q_INVOKABLE virtual void openDatabase(const QString databaseFile, const QString& connectionName = "DICOM-DB" );
 
   ///
   /// close the database. It must not be used afterwards.
-  void closeDatabase();
+  Q_INVOKABLE void closeDatabase();
   ///
   /// delete all data and reinitialize the database.
-  bool initializeDatabase(const char* schemaFile = ":/dicom/dicom-schema.sql");
+  Q_INVOKABLE bool initializeDatabase(const char* schemaFile = ":/dicom/dicom-schema.sql");
+
+  ///
+  /// \brief database accessors
+  Q_INVOKABLE QStringList studiesForPatient (QString patientUID);
+  Q_INVOKABLE QStringList seriesForStudy (QString studyUID);
+  Q_INVOKABLE QStringList filesForSeries (QString seriesUID);
+
+  ///
+  /// \brief load the header from a file and allow access to elements
+  Q_INVOKABLE void loadInstanceHeader (QString sopInstanceUID);
+  Q_INVOKABLE void loadFileHeader (QString fileName);
+  Q_INVOKABLE QStringList headerKeys ();
+  Q_INVOKABLE QString headerValue (QString key);
 
   /**
    * Will create an entry in the appropriate tables for this dataset.

+ 23 - 2
Libs/DICOM/Widgets/ctkDICOMAppWidget.cpp

@@ -77,8 +77,18 @@ ctkDICOMAppWidget::ctkDICOMAppWidget(QWidget* _parent):Superclass(_parent),
   d->QueryRetrieveWidget = new ctkDICOMQueryRetrieveWidget();
   d->QueryRetrieveWidget->setWindowModality ( Qt::ApplicationModal );
 
-  //initialize default directory, then listen for changes
-  this->setDatabaseDirectory(d->directoryButton->directory());
+  //initialize directory from settings, then listen for changes
+  QSettings settings;
+  if ( settings.value("DatabaseDirectory", "") == "" )
+    {
+    QString directory = QString("./ctkDICOM-Database");
+    settings.setValue("DatabaseDirectory", directory);
+    settings.sync();
+    }
+  QString databaseDirectory = settings.value("DatabaseDirectory").toString();
+  this->setDatabaseDirectory(databaseDirectory);
+  d->directoryButton->setDirectory(databaseDirectory);
+
   connect(d->directoryButton, SIGNAL(directoryChanged(const QString&)), this, SLOT(setDatabaseDirectory(const QString&)));
 
   //Initialize import widget
@@ -143,6 +153,17 @@ void ctkDICOMAppWidget::setDatabaseDirectory(const QString& directory)
   //pass DICOM database instance to Import widget
   // d->ImportDialog->setDICOMDatabase(d->DICOMDatabase);
   d->QueryRetrieveWidget->setRetrieveDatabase(d->DICOMDatabase);
+
+  // update the button and let any connected slots know about the change
+  d->directoryButton->setDirectory(directory);
+  emit databaseDirectoryChanged(directory);
+}
+
+//----------------------------------------------------------------------------
+QString ctkDICOMAppWidget::databaseDirectory() const
+{
+  QSettings settings;
+  return settings.value("DatabaseDirectory").toString();
 }
 
 void ctkDICOMAppWidget::onAddToDatabase()

+ 16 - 8
Libs/DICOM/Widgets/ctkDICOMAppWidget.h

@@ -32,22 +32,30 @@ class ctkDICOMThumbnailWidget;
 
 class CTK_DICOM_WIDGETS_EXPORT ctkDICOMAppWidget : public QWidget
 {
-Q_OBJECT;
+  Q_OBJECT
+  Q_PROPERTY(QString databaseDirectory READ databaseDirectory WRITE setDatabaseDirectory)
+
 public:
   typedef QWidget Superclass;
   explicit ctkDICOMAppWidget(QWidget* parent=0);
   virtual ~ctkDICOMAppWidget();
 
+  QString databaseDirectory() const;
+
 public slots:
-    void setDatabaseDirectory(const QString& directory);
-    void onAddToDatabase();
+  void setDatabaseDirectory(const QString& directory);
+  void onAddToDatabase();
+
+  void onDICOMModelSelected(const QModelIndex& index);
+  void onThumbnailSelected(const ctkDICOMThumbnailWidget& widget);
 
-    void onDICOMModelSelected(const QModelIndex& index);
-    void onThumbnailSelected(const ctkDICOMThumbnailWidget& widget);
+  void openImportDialog();
+  void openExportDialog();
+  void openQueryDialog();
 
-    void openImportDialog();
-    void openExportDialog();
-    void openQueryDialog();
+signals:
+  /// Emited when directory is changed
+  void databaseDirectoryChanged(const QString&);
 
 protected:
     QScopedPointer<ctkDICOMAppWidgetPrivate> d_ptr;

+ 2 - 2
Libs/Widgets/ctkCollapsibleButton.cpp

@@ -565,11 +565,11 @@ void ctkCollapsibleButton::paintEvent(QPaintEvent * _event)
     }
   if (d->Collapsed)
     {
-    style()->drawPrimitive(QStyle::PE_IndicatorArrowDown, &indicatorOpt, &p, this);
+    style()->drawPrimitive(QStyle::PE_IndicatorArrowRight, &indicatorOpt, &p, this);
     }
   else
     {
-    style()->drawPrimitive(QStyle::PE_IndicatorArrowUp, &indicatorOpt, &p, this);
+    style()->drawPrimitive(QStyle::PE_IndicatorArrowDown, &indicatorOpt, &p, this);
     }
 
   // Draw Text

+ 4 - 2
Libs/Widgets/ctkRangeWidget.cpp

@@ -470,7 +470,6 @@ void ctkRangeWidget::changeMinimumValue(double newValue)
     }
   if (!d->Changing)
     {
-    emit this->valuesChanged(newValue, this->maximumValue());
     emit this->minimumValueChanged(newValue);
 	}
 }
@@ -485,7 +484,6 @@ void ctkRangeWidget::changeMaximumValue(double newValue)
     }
   if (!d->Changing)
     {
-    emit this->valuesChanged(this->minimumValue(), newValue);
     emit this->maximumValueChanged(newValue);
     }
 }
@@ -496,6 +494,10 @@ void ctkRangeWidget::changeValues(double newMinValue, double newMaxValue)
   Q_D(ctkRangeWidget);
   d->MinimumSpinBox->setValue(newMinValue);
   d->MaximumSpinBox->setValue(newMaxValue);
+  if (!d->Changing)
+    {
+    emit this->valuesChanged(newMinValue, newMaxValue);
+    }
 }
 
 // --------------------------------------------------------------------------

+ 2 - 0
Libs/Widgets/ctkWorkflowWidgetStep.h

@@ -62,7 +62,9 @@ class CTK_WIDGETS_EXPORT ctkWorkflowWidgetStep : public QWidget, public ctkWorkf
   Q_PROPERTY(QIcon icon READ icon WRITE setIcon)
   Q_PROPERTY(QString backButtonText READ backButtonText WRITE setBackButtonText)
   Q_PROPERTY(QString nextButtonText READ nextButtonText WRITE setNextButtonText)
+  Q_FLAGS(ButtonBoxHint ButtonBoxHints)
   Q_ENUMS(ButtonBoxHint)
+  Q_PROPERTY(ButtonBoxHints buttonBoxHints READ buttonBoxHints WRITE setButtonBoxHints)
 public:
 
   enum ButtonBoxHint {