Browse Source

added repair tool for database and also message box for importin dicom browser

Stylistic changes
Alireza Mehrtash 11 years ago
parent
commit
9e19f9e6f4

+ 83 - 0
Libs/DICOM/Core/ctkDICOMDatabase.cpp

@@ -593,6 +593,73 @@ QStringList ctkDICOMDatabase::studiesForPatient(QString dbPatientID)
 }
 
 //------------------------------------------------------------------------------
+QString ctkDICOMDatabase::studyForSeries(QString seriesUID)
+{
+  Q_D(ctkDICOMDatabase);
+  QSqlQuery query(d->Database);
+  query.prepare ( "SELECT StudyInstanceUID FROM Series WHERE SeriesInstanceUID= ?" );
+  query.bindValue ( 0, seriesUID);
+  query.exec();
+  QString result;
+  if (query.next())
+    {
+    result = query.value(0).toString();
+    }
+  return( result );
+}
+
+//------------------------------------------------------------------------------
+QString ctkDICOMDatabase::patientForStudy(QString studyUID)
+{
+  Q_D(ctkDICOMDatabase);
+  QSqlQuery query(d->Database);
+  query.prepare ( "SELECT PatientsUID FROM Studies WHERE StudyInstanceUID= ?" );
+  query.bindValue ( 0, studyUID);
+  query.exec();
+  QString result;
+  if (query.next())
+    {
+    result = query.value(0).toString();
+    }
+  return( result );
+}
+
+//------------------------------------------------------------------------------
+QHash<QString,QString> ctkDICOMDatabase::descriptionsForFile(QString fileName)
+{
+  Q_D(ctkDICOMDatabase);
+
+  QString seriesUID(this->seriesForFile(fileName));
+  QString studyUID(this->studyForSeries(seriesUID));
+  QString patientID(this->patientForStudy(studyUID));
+
+  QSqlQuery query(d->Database);
+  query.prepare ( "SELECT SeriesDescription FROM Series WHERE SeriesInstanceUID= ?" );
+  query.bindValue ( 0, seriesUID);
+  query.exec();
+  QHash<QString,QString> result;
+  if (query.next())
+  {
+    result["SeriesDescription"] =  query.value(0).toString();
+  }
+  query.prepare ( "SELECT StudyDescription FROM Studies WHERE StudyInstanceUID= ?" );
+  query.bindValue ( 0, studyUID);
+  query.exec();
+  if (query.next())
+  {
+    result["StudyDescription"] =  query.value(0).toString();
+  }
+  query.prepare ( "SELECT PatientsName FROM Patients WHERE UID= ?" );
+  query.bindValue ( 0, patientID);
+  query.exec();
+  if (query.next())
+  {
+    result["PatientsName"] =  query.value(0).toString();
+  }
+  return( result );
+}
+
+//------------------------------------------------------------------------------
 QStringList ctkDICOMDatabase::seriesForStudy(QString studyUID)
 {
   Q_D(ctkDICOMDatabase);
@@ -641,6 +708,22 @@ QString ctkDICOMDatabase::fileForInstance(QString sopInstanceUID)
 }
 
 //------------------------------------------------------------------------------
+QString ctkDICOMDatabase::seriesForFile(QString fileName)
+{
+  Q_D(ctkDICOMDatabase);
+  QSqlQuery query(d->Database);
+  query.prepare ( "SELECT SeriesInstanceUID FROM Images WHERE Filename=?");
+  query.bindValue ( 0, fileName );
+  query.exec();
+  QString result;
+  if (query.next())
+    {
+    result = query.value(0).toString();
+    }
+  return( result );
+}
+
+//------------------------------------------------------------------------------
 QString ctkDICOMDatabase::instanceForFile(QString fileName)
 {
   Q_D(ctkDICOMDatabase);

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

@@ -132,8 +132,12 @@ public:
   Q_INVOKABLE QStringList patients ();
   Q_INVOKABLE QStringList studiesForPatient (const QString patientUID);
   Q_INVOKABLE QStringList seriesForStudy (const QString studyUID);
+  Q_INVOKABLE QString studyForSeries(QString seriesUID);
+  Q_INVOKABLE QString patientForStudy(QString studyUID);
   Q_INVOKABLE QStringList filesForSeries (const QString seriesUID);
+  Q_INVOKABLE QHash<QString,QString> descriptionsForFile(QString fileName);
   Q_INVOKABLE QString fileForInstance (const QString sopInstanceUID);
+  Q_INVOKABLE QString seriesForFile (QString fileName);
   Q_INVOKABLE QString instanceForFile (const QString fileName);
   Q_INVOKABLE QDateTime insertDateTimeForInstance (const QString fileName);
 

+ 28 - 0
Libs/DICOM/Widgets/Resources/UI/ctkDICOMBrowser.ui

@@ -45,6 +45,7 @@
      <addaction name="ActionQuery"/>
      <addaction name="ActionSend"/>
      <addaction name="ActionRemove"/>
+     <addaction name="ActionRepair"/>
     </widget>
    </item>
    <item>
@@ -205,6 +206,17 @@
     <string>Remove from database</string>
    </property>
   </action>
+  <action name="ActionRepair">
+   <property name="enabled">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>Repair</string>
+   </property>
+   <property name="toolTip">
+    <string>Check whether all the files associated with images in the local Database are available on the disk.</string>
+   </property>
+  </action>
  </widget>
  <customwidgets>
   <customwidget>
@@ -289,6 +301,22 @@
     </hint>
    </hints>
   </connection>
+  <connection>
+   <sender>ActionRepair</sender>
+   <signal>triggered()</signal>
+   <receiver>ctkDICOMBrowser</receiver>
+   <slot>onRepairAction()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>-1</x>
+     <y>-1</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>400</x>
+     <y>303</y>
+    </hint>
+   </hints>
+  </connection>
  </connections>
  <slots>
   <slot>openImportDialog()</slot>

+ 104 - 8
Libs/DICOM/Widgets/ctkDICOMBrowser.cpp

@@ -23,16 +23,21 @@
 
 // Qt includes
 #include <QAction>
+#include <QApplication>
 #include <QCoreApplication>
 #include <QCheckBox>
 #include <QDebug>
+#include <QFile>
+#include <QListView>
 #include <QMessageBox>
 #include <QProgressDialog>
 #include <QSettings>
+#include <QStringListModel>
 
 // ctkWidgets includes
 #include "ctkDirectoryButton.h"
 #include "ctkFileDialog.h"
+#include "ctkMessageBox.h"
 
 // ctkDICOMCore includes
 #include "ctkDICOMDatabase.h"
@@ -245,6 +250,7 @@ ctkDICOMBrowser::ctkDICOMBrowser(QWidget* _parent):Superclass(_parent),
   //Initialize import widget
   d->ImportDialog = new ctkFileDialog();
   QCheckBox* importCheckbox = new QCheckBox("Copy on import", d->ImportDialog);
+  importCheckbox->setCheckState(Qt::Checked);
   d->ImportDialog->setBottomWidget(importCheckbox);
   d->ImportDialog->setFileMode(QFileDialog::Directory);
   d->ImportDialog->setLabelText(QFileDialog::Accept,"Import");
@@ -465,6 +471,74 @@ void ctkDICOMBrowser::onRemoveAction()
 }
 
 //----------------------------------------------------------------------------
+void ctkDICOMBrowser::onRepairAction()
+{
+  Q_D(ctkDICOMBrowser);
+
+  QMessageBox* repairMessageBox;
+  repairMessageBox = new QMessageBox;
+  repairMessageBox->setWindowTitle("Database Repair");
+
+  QStringList allFiles(d->DICOMDatabase->allFiles());
+
+  QSet<QString> corruptedSeries;
+
+  QStringList::const_iterator it;
+  for (it = allFiles.constBegin(); it!= allFiles.constEnd();++it)
+  {
+    QString fileName(*it);
+    QFile dicomFile(fileName);
+
+    if(!dicomFile.exists())
+    {
+      QString seriesUid = d->DICOMDatabase->seriesForFile(fileName);
+      corruptedSeries.insert(seriesUid);
+    }
+  }
+
+  if (corruptedSeries.size() == 0)
+  {
+    repairMessageBox->setText("All the files in the local database are available.");
+    repairMessageBox->addButton(QMessageBox::Ok);
+    repairMessageBox->exec();
+  }
+
+  else
+  {
+    QSet<QString>::iterator i;
+    for (i = corruptedSeries.begin(); i != corruptedSeries.end(); ++i)
+      {
+      QStringList fileList (d->DICOMDatabase->filesForSeries(*i));
+      QString unavailableFileNames;
+      QStringList::const_iterator it;
+      for (it= fileList.constBegin(); it!= fileList.constEnd();++it)
+      {
+        unavailableFileNames.append(*it+"\n");
+      }
+
+      QString firstFile (*(fileList.constBegin()));
+      QHash<QString,QString> descriptions (d->DICOMDatabase->descriptionsForFile(firstFile));
+
+      repairMessageBox->setText("The files for the following series are not available on the disk: \nPatient Name: "
+        + descriptions["PatientsName"]+ "\n"+
+        "Study Desciption: " + descriptions["StudyDescription"]+ "\n"+
+        "Series Desciption: " + descriptions["SeriesDescription"]+ "\n"+
+        "Do you want to remove the series from the DICOM database? ");
+
+      repairMessageBox->setDetailedText(unavailableFileNames);
+      repairMessageBox->addButton(QMessageBox::Yes);
+      repairMessageBox->addButton(QMessageBox::No);
+
+      int selection = repairMessageBox->exec();
+      if (selection == QMessageBox::Yes)
+      {
+        d->DICOMDatabase->removeSeries(*i);
+        d->dicomTableManager->updateTableViews();
+      }
+    }
+  }
+}
+//----------------------------------------------------------------------------
 void ctkDICOMBrowser::onTablesDensityComboBox(QString density)
 {
   Q_D(ctkDICOMBrowser);
@@ -522,14 +596,31 @@ void ctkDICOMBrowser::onInstanceAdded(QString instanceUID)
 void ctkDICOMBrowser::onImportDirectory(QString directory)
 {
   Q_D(ctkDICOMBrowser);
+
   if (QDir(directory).exists())
-    {
-    QCheckBox* copyOnImport = qobject_cast<QCheckBox*>(d->ImportDialog->bottomWidget());
+  {
     QString targetDirectory;
-    if (copyOnImport->checkState() == Qt::Checked)
-      {
-      targetDirectory = d->DICOMDatabase->databaseDirectory();
-      }
+
+    QCheckBox* copyOnImport = qobject_cast<QCheckBox*>(d->ImportDialog->bottomWidget());
+
+    ctkMessageBox importTypeDialog;
+    QString message("Do you want to copy the files to the local database directory or just add the links?");
+    importTypeDialog.setText(message);
+    importTypeDialog.setIcon(QMessageBox::Question);
+
+    importTypeDialog.addButton("Copy",QMessageBox::AcceptRole);
+    importTypeDialog.addButton("Add Link",QMessageBox::RejectRole);
+    importTypeDialog.setDontShowAgainSettingsKey( "MainWindow/DontConfirmCopyOnImport" );
+    int selection = importTypeDialog.exec();
+
+    if (selection== QMessageBox::AcceptRole)
+    {
+      copyOnImport->setCheckState(Qt::Checked);
+    }
+    else
+    {
+      copyOnImport->setCheckState(Qt::Unchecked);
+    }
 
     // reset counts
     d->PatientsAddedDuringImport = 0;
@@ -537,20 +628,25 @@ void ctkDICOMBrowser::onImportDirectory(QString directory)
     d->SeriesAddedDuringImport = 0;
     d->InstancesAddedDuringImport = 0;
 
+    if (copyOnImport->checkState() == Qt::Checked)
+    {
+      targetDirectory = d->DICOMDatabase->databaseDirectory();
+    }
+
     // show progress dialog and perform indexing
     d->showIndexerDialog();
     d->DICOMIndexer->addDirectory(*d->DICOMDatabase,directory,targetDirectory);
 
     // display summary result
     if (d->DisplayImportSummary)
-      {
+    {
       QString message = "Directory import completed.\n\n";
       message += QString("%1 New Patients\n").arg(QString::number(d->PatientsAddedDuringImport));
       message += QString("%1 New Studies\n").arg(QString::number(d->StudiesAddedDuringImport));
       message += QString("%1 New Series\n").arg(QString::number(d->SeriesAddedDuringImport));
       message += QString("%1 New Instances\n").arg(QString::number(d->InstancesAddedDuringImport));
       QMessageBox::information(this,"DICOM Directory Import", message);
-      }
+    }
   }
 }
 

+ 1 - 0
Libs/DICOM/Widgets/ctkDICOMBrowser.h

@@ -86,6 +86,7 @@ public Q_SLOTS:
   void openExportDialog();
   void openQueryDialog();
   void onRemoveAction();
+  void onRepairAction();
 
   void onTablesDensityComboBox(QString);