Selaa lähdekoodia

Make indexer use QFutures for background processing

Also moved private implementation stuff to separate file
Marco Nolden 13 vuotta sitten
vanhempi
commit
8daad75831

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

@@ -19,6 +19,7 @@ set(KIT_SRCS
   ctkDICOMFilterProxyModel.h
   ctkDICOMIndexer.cpp
   ctkDICOMIndexer.h
+  ctkDICOMIndexerPrivate.h
   ctkDICOMModel.cpp
   ctkDICOMModel.h
   ctkDICOMPersonName.cpp
@@ -42,6 +43,7 @@ set(KIT_MOC_SRCS
   ctkDICOMAbstractThumbnailGenerator.h
   ctkDICOMDatabase.h
   ctkDICOMIndexer.h
+  ctkDICOMIndexerPrivate.h
   ctkDICOMFilterProxyModel.h
   ctkDICOMModel.h
   ctkDICOMQuery.h

+ 51 - 20
Libs/DICOM/Core/ctkDICOMIndexer.cpp

@@ -18,6 +18,8 @@
 
 =========================================================================*/
 
+#include <tr1/functional>
+
 // Qt includes
 #include <QSqlQuery>
 #include <QSqlRecord>
@@ -31,11 +33,13 @@
 #include <QFileInfo>
 #include <QDebug>
 #include <QPixmap>
-
+#include <QtConcurrentRun>
 
 // ctkDICOM includes
 #include "ctkLogger.h"
 #include "ctkDICOMIndexer.h"
+#include "ctkDICOMIndexerPrivate.h"
+#include "ctkDICOMDatabase.h"
 
 // DCMTK includes
 #include <dcmtk/dcmdata/dcfilefo.h>
@@ -49,30 +53,41 @@
 #include <dcmtk/dcmimgle/dcmimage.h>  /* for class DicomImage */
 #include <dcmtk/dcmimage/diregist.h>  /* include support for color images */
 
+class AddFileFunctor
+{
+public:
+     AddFileFunctor(ctkDICOMIndexer* indexer, ctkDICOMDatabase& database,
+                    const QString& destinationDirectoryName = "")
+       : Indexer(indexer), Database(database), DestinationDirectoryName(destinationDirectoryName) { }
+
+     bool operator()(const QString &filePath)
+     {
+         Indexer->addFile(Database,filePath,DestinationDirectoryName);
+         return false; // make sure it is removed;
+     }
+
+     ctkDICOMIndexer* Indexer;
+     ctkDICOMDatabase& Database;
+     QString DestinationDirectoryName;
+
+ };
+
 
 //------------------------------------------------------------------------------
 static ctkLogger logger("org.commontk.dicom.DICOMIndexer" );
 //------------------------------------------------------------------------------
 
-//------------------------------------------------------------------------------
-class ctkDICOMIndexerPrivate
-{
-public:
-  ctkDICOMIndexerPrivate();
-  ~ctkDICOMIndexerPrivate();
-
-  ctkDICOMAbstractThumbnailGenerator* thumbnailGenerator;
-  bool                    Canceled;
-
-};
 
 //------------------------------------------------------------------------------
 // ctkDICOMIndexerPrivate methods
 
 //------------------------------------------------------------------------------
-ctkDICOMIndexerPrivate::ctkDICOMIndexerPrivate()
+ctkDICOMIndexerPrivate::ctkDICOMIndexerPrivate(ctkDICOMIndexer& o) : q_ptr(&o), Canceled(false), CurrentPercentageProgress(-1)
 {
-  this->Canceled = false;
+  Q_Q(ctkDICOMIndexer);
+  connect(&DirectoryImportWatcher,SIGNAL(progressValueChanged(int)),this,SLOT(OnProgress(int)));
+  connect(&DirectoryImportWatcher,SIGNAL(finished()),q,SIGNAL(indexingComplete()));
+  connect(&DirectoryImportWatcher,SIGNAL(canceled()),q,SIGNAL(indexingComplete()));
 }
 
 //------------------------------------------------------------------------------
@@ -80,13 +95,26 @@ ctkDICOMIndexerPrivate::~ctkDICOMIndexerPrivate()
 {
 }
 
+void ctkDICOMIndexerPrivate::OnProgress(int progress)
+{
+  Q_Q(ctkDICOMIndexer);
+
+  int newPercentageProgress = ( 100 * DirectoryImportFuture.progressValue() ) / DirectoryImportFuture.progressMaximum();
+  if (newPercentageProgress != CurrentPercentageProgress)
+    {
+      CurrentPercentageProgress = newPercentageProgress;
+      emit q->progress(newPercentageProgress);
+    }
+
+}
+
 //------------------------------------------------------------------------------
 
 //------------------------------------------------------------------------------
 // ctkDICOMIndexer methods
 
 //------------------------------------------------------------------------------
-ctkDICOMIndexer::ctkDICOMIndexer(QObject *parent):d_ptr(new ctkDICOMIndexerPrivate)
+ctkDICOMIndexer::ctkDICOMIndexer(QObject *parent):d_ptr(new ctkDICOMIndexerPrivate(*this))
 {
   Q_UNUSED(parent);
 }
@@ -97,10 +125,11 @@ ctkDICOMIndexer::~ctkDICOMIndexer()
 }
 
 //------------------------------------------------------------------------------
-void ctkDICOMIndexer::addFile(ctkDICOMDatabase& ctkDICOMDatabase, 
-                                   const QString& filePath,
+void ctkDICOMIndexer::addFile(ctkDICOMDatabase& database,
+                                   const QString filePath,
                                    const QString& destinationDirectoryName)
 {
+  std::cout << filePath.toStdString();
   if (!destinationDirectoryName.isEmpty())
   {
     logger.warn("Ignoring destinationDirectoryName parameter, just taking it as indication we should copy!");
@@ -108,7 +137,7 @@ void ctkDICOMIndexer::addFile(ctkDICOMDatabase& ctkDICOMDatabase,
 
   emit indexingFilePath(filePath);
 
-  ctkDICOMDatabase.insert(filePath, !destinationDirectoryName.isEmpty(), true);
+  database.insert(filePath, !destinationDirectoryName.isEmpty(), true);
 }
 
 //------------------------------------------------------------------------------
@@ -158,9 +187,11 @@ void ctkDICOMIndexer::addDirectory(ctkDICOMDatabase& ctkDICOMDatabase,
       emit progress( currentProgress );
     }
     QString filePath((*iter).c_str());
-    this->addFile(ctkDICOMDatabase, filePath, destinationDirectoryName);
+    d->FilesToIndex << filePath;
     ++iter;
   }
+  d->DirectoryImportFuture = QtConcurrent::filter(d->FilesToIndex,AddFileFunctor(this,ctkDICOMDatabase,destinationDirectoryName));
+  d->DirectoryImportWatcher.setFuture(d->DirectoryImportFuture);
 }
 
 //------------------------------------------------------------------------------
@@ -208,5 +239,5 @@ void ctkDICOMIndexer::refreshDatabase(ctkDICOMDatabase& dicomDatabase, const QSt
 void ctkDICOMIndexer::cancel()
 {
   Q_D(ctkDICOMIndexer);
-  d->Canceled = true;
+  d->DirectoryImportWatcher.cancel();
 }

+ 2 - 1
Libs/DICOM/Core/ctkDICOMIndexer.h

@@ -58,7 +58,7 @@ public:
   /// Scan the file using Dcmtk and populate the database with all the
   /// DICOM fields accordingly.
   ///
-  Q_INVOKABLE void addFile(ctkDICOMDatabase& database, const QString& filePath,
+  Q_INVOKABLE void addFile(ctkDICOMDatabase& database, const QString filePath,
                     const QString& destinationDirectoryName = "");
 
   Q_INVOKABLE void refreshDatabase(ctkDICOMDatabase& database, const QString& directoryName);
@@ -68,6 +68,7 @@ Q_SIGNALS:
   void indexingFileNumber(int);
   void indexingFilePath(QString);
   void progress(int);
+  void indexingComplete();
 
 public Q_SLOTS:
   void cancel();