Selaa lähdekoodia

Implement search-as-you-type on local SQLite database

Search on patient name, study name, series name is working. However, ctkDICOMModel is currently initialized again after each query.
nherlambang 14 vuotta sitten
vanhempi
commit
671f04130d

+ 54 - 4
Libs/DICOM/Core/ctkDICOMModel.cpp

@@ -67,6 +67,7 @@ public:
   QSqlDatabase DataBase;
   QList<QMap<int, QVariant> > Headers;
   QString      Sort;
+  QMap<QString, QVariant> SearchParameters;
 
   ctkDICOMModel::IndexType displayLevel;
 };
@@ -293,6 +294,7 @@ void ctkDICOMModelPrivate::updateQueries(Node* node)const
 {
   // are you kidding me, it should be virtualized here :-)
   QString query;
+  QString condition;
   switch(node->Type)
     {
     default:
@@ -300,22 +302,34 @@ void ctkDICOMModelPrivate::updateQueries(Node* node)const
       break;
     case ctkDICOMModel::RootType:
       //query = QString("SELECT  FROM ");
-      query = this->generateQuery("UID as UID, PatientsName as Name, PatientsAge as Age, PatientsBirthDate as Date, PatientID as \"Subject ID\"","Patients");
+      if(this->SearchParameters["Name"].toString() != ""){
+        condition.append("PatientsName LIKE \"%" + this->SearchParameters["Name"].toString() + "%\"");
+      }
+      query = this->generateQuery("UID as UID, PatientsName as Name, PatientsAge as Age, PatientsBirthDate as Date, PatientID as \"Subject ID\"","Patients", condition);
       logger.debug ( "ctkDICOMModelPrivate::updateQueries for Root: query is: " + query );
       break;
     case ctkDICOMModel::PatientType:
       //query = QString("SELECT  FROM Studies WHERE PatientsUID='%1'").arg(node->UID);
-      query = this->generateQuery("StudyInstanceUID as UID, StudyDescription as Name, ModalitiesInStudy as Scan, StudyDate as Date, AccessionNumber as Number, ReferringPhysician as Institution, ReferringPhysician as Referrer, PerformingPhysiciansName as Performer", "Studies",QString("PatientsUID='%1'").arg(node->UID));
+      if(this->SearchParameters["Study"].toString() != ""){
+        condition.append("StudyDescription LIKE \"%" + this->SearchParameters["Study"].toString() + "%\"" + " AND ");
+      }
+      query = this->generateQuery("StudyInstanceUID as UID, StudyDescription as Name, ModalitiesInStudy as Scan, StudyDate as Date, AccessionNumber as Number, ReferringPhysician as Institution, ReferringPhysician as Referrer, PerformingPhysiciansName as Performer", "Studies", condition + QString("PatientsUID='%1'").arg(node->UID));
       logger.debug ( "ctkDICOMModelPrivate::updateQueries for Patient: query is: " + query );
       break;
     case ctkDICOMModel::StudyType:
+      if(this->SearchParameters["Series"].toString() != ""){
+        condition.append("SeriesDescription LIKE \"%" + this->SearchParameters["Series"].toString() + "%\"" + " AND ");
+      }
       //query = QString("SELECT SeriesInstanceUID as UID, SeriesDescription as Name, BodyPartExamined as Scan, SeriesDate as Date, AcquisitionNumber as Number FROM Series WHERE StudyInstanceUID='%1'").arg(node->UID);
-      query = this->generateQuery("SeriesInstanceUID as UID, SeriesDescription as Name, BodyPartExamined as Scan, SeriesDate as Date, AcquisitionNumber as Number","Series",QString("StudyInstanceUID='%1'").arg(node->UID));
+      query = this->generateQuery("SeriesInstanceUID as UID, SeriesDescription as Name, BodyPartExamined as Scan, SeriesDate as Date, AcquisitionNumber as Number","Series",condition + QString("StudyInstanceUID='%1'").arg(node->UID));
       logger.debug ( "ctkDICOMModelPrivate::updateQueries for Study: query is: " + query );
       break;
     case ctkDICOMModel::SeriesType:
+      if(this->SearchParameters["ID"].toString() != ""){
+        condition.append("SOPInstanceUID LIKE \"%" + this->SearchParameters["ID"].toString() + "%\"" + " AND ");
+      }
       //query = QString("SELECT Filename as UID, Filename as Name, SeriesInstanceUID as Date FROM Images WHERE SeriesInstanceUID='%1'").arg(node->UID);
-      query = this->generateQuery("SOPInstanceUID as UID, Filename as Name, SeriesInstanceUID as Date", "Images", QString("SeriesInstanceUID='%1'").arg(node->UID));
+      query = this->generateQuery("SOPInstanceUID as UID, Filename as Name, SeriesInstanceUID as Date", "Images", condition + QString("SeriesInstanceUID='%1'").arg(node->UID));
       logger.debug ( "ctkDICOMModelPrivate::updateQueries for Series: query is: " + query );
       break;
     case ctkDICOMModel::ImageType:
@@ -668,6 +682,42 @@ void ctkDICOMModel::setDatabase(const QSqlDatabase &db)
   d->fetch(QModelIndex(), 256);
 }
 
+//------------------------------------------------------------------------------
+void ctkDICOMModel::setDatabase(const QSqlDatabase &db,const QMap<QString, QVariant>& parameters)
+{
+  Q_D(ctkDICOMModel);
+
+  this->beginResetModel();
+  d->DataBase = db;
+  d->SearchParameters = parameters;
+
+  delete d->RootNode;
+  d->RootNode = 0;
+
+  if (d->DataBase.tables().empty())
+    {
+    //Q_ASSERT(d->DataBase.isOpen());
+    this->endResetModel();
+    return;
+    }
+
+  d->RootNode = d->createNode(-1, QModelIndex());
+
+  this->endResetModel();
+
+  // TODO, use hasQuerySize everywhere, not only in setDataBase()
+  bool hasQuerySize = d->RootNode->Query.driver()->hasFeature(QSqlDriver::QuerySize);
+  if (hasQuerySize && d->RootNode->Query.size() > 0)
+    {
+    int newRowCount= d->RootNode->Query.size();
+    beginInsertRows(QModelIndex(), 0, qMax(0, newRowCount - 1));
+    d->RootNode->RowCount = newRowCount;
+    d->RootNode->AtEnd = true;
+    endInsertRows();
+    }
+  d->fetch(QModelIndex(), 256);
+}
+
 void ctkDICOMModel::setDisplayLevel(ctkDICOMModel::IndexType level){
     Q_D(ctkDICOMModel);
 

+ 1 - 0
Libs/DICOM/Core/ctkDICOMModel.h

@@ -53,6 +53,7 @@ public:
   virtual ~ctkDICOMModel();
 
   void setDatabase(const QSqlDatabase& dataBase);
+  void setDatabase(const QSqlDatabase& dataBase, const QMap<QString,QVariant>& parameters);
   void setDisplayLevel(ctkDICOMModel::IndexType level);
 
   virtual bool canFetchMore ( const QModelIndex & parent ) const;

+ 7 - 6
Libs/DICOM/Widgets/ctkDICOMAppWidget.cpp

@@ -160,17 +160,12 @@ ctkDICOMAppWidget::ctkDICOMAppWidget(QWidget* _parent):Superclass(_parent),
   connect(d->ThumbnailsWidget, SIGNAL(doubleClicked(const ctkDICOMThumbnailWidget&)), this, SLOT(onThumbnailDoubleClicked(const ctkDICOMThumbnailWidget&)));
   connect(d->ImportDialog, SIGNAL(fileSelected(QString)),this,SLOT(onImportDirectory(QString)));
 
-  //connect(d->DICOMDatabase.data(), SIGNAL( databaseChanged() ), &(d->DICOMModel), SLOT( reset() ) );
   connect(d->QueryRetrieveWidget, SIGNAL( canceled() ), d->QueryRetrieveWidget, SLOT( hide() ) );
 
   connect(d->imagePreview, SIGNAL(requestNextImage()), this, SLOT(onNextImage()));
   connect(d->imagePreview, SIGNAL(requestPreviousImage()), this, SLOT(onPreviousImage()));
 
-  connect(d->SearchOption, SIGNAL(nameSearchTextChanged(QString)), &(d->DICOMProxyModel), SLOT(setNameSearchText(QString)));
-  connect(d->SearchOption, SIGNAL(studySearchTextChanged(QString)), &(d->DICOMProxyModel), SLOT(setStudySearchText(QString)));
-  connect(d->SearchOption, SIGNAL(seriesSearchTextChanged(QString)), &(d->DICOMProxyModel), SLOT(setSeriesSearchText(QString)));
-  connect(d->SearchOption, SIGNAL(idSearchTextChanged(QString)), &(d->DICOMProxyModel), SLOT(setIdSearchText(QString)));
-
+  connect(d->SearchOption, SIGNAL(parameterChanged()), this, SLOT(onSearchParameterChanged()));
 }
 
 //----------------------------------------------------------------------------
@@ -575,3 +570,9 @@ void ctkDICOMAppWidget::onThumbnailWidthSliderValueChanged(int val){
   Q_D(ctkDICOMAppWidget);
   d->ThumbnailsWidget->setThumbnailWidth(val);
 }
+
+//----------------------------------------------------------------------------
+void ctkDICOMAppWidget::onSearchParameterChanged(){
+  Q_D(ctkDICOMAppWidget);
+  d->DICOMModel.setDatabase(d->DICOMDatabase->database(), d->SearchOption->parameters());
+}

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

@@ -89,6 +89,9 @@ protected slots:
     /// To be called when the value of thumbnail size slider bar is changed
     void onThumbnailWidthSliderValueChanged(int val);
 
+    /// To be called when search parameters in query widget changed
+    void onSearchParameterChanged();
+
 private:
   Q_DECLARE_PRIVATE(ctkDICOMAppWidget);
   Q_DISABLE_COPY(ctkDICOMAppWidget);