| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575 | 
							- /*=========================================================================
 
-   Library:   CTK
 
-   Copyright (c) Kitware Inc.
 
-   Licensed under the Apache License, Version 2.0 (the "License");
 
-   you may not use this file except in compliance with the License.
 
-   You may obtain a copy of the License at
 
-       http://www.apache.org/licenses/LICENSE-2.0.txt
 
-   Unless required by applicable law or agreed to in writing, software
 
-   distributed under the License is distributed on an "AS IS" BASIS,
 
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
-   See the License for the specific language governing permissions and
 
-   limitations under the License.
 
- =========================================================================*/
 
- // Qt includes
 
- #include <QSqlQuery>
 
- #include <QSqlRecord>
 
- #include <QSqlError>
 
- #include <QVariant>
 
- #include <QDate>
 
- #include <QStringList>
 
- #include <QSet>
 
- #include <QFile>
 
- #include <QDirIterator>
 
- #include <QFileInfo>
 
- #include <QDebug>
 
- #include <QPixmap>
 
- // ctkDICOM includes
 
- #include "ctkLogger.h"
 
- #include "ctkDICOMIndexer.h"
 
- #include "ctkDICOMAbstractThumbnailGenerator.h"
 
- // DCMTK includes
 
- #include <dcmtk/dcmdata/dcfilefo.h>
 
- #include <dcmtk/dcmdata/dcfilefo.h>
 
- #include <dcmtk/dcmdata/dcdeftag.h>
 
- #include <dcmtk/dcmdata/dcdatset.h>
 
- #include <dcmtk/ofstd/ofcond.h>
 
- #include <dcmtk/ofstd/ofstring.h>
 
- #include <dcmtk/ofstd/ofstd.h>        /* for class OFStandard */
 
- #include <dcmtk/dcmdata/dcddirif.h>   /* for class DicomDirInterface */
 
- #include <dcmtk/dcmimgle/dcmimage.h>  /* for class DicomImage */
 
- #include <dcmtk/dcmimage/diregist.h>  /* include support for color images */
 
- //------------------------------------------------------------------------------
 
- static ctkLogger logger("org.commontk.dicom.DICOMIndexer" );
 
- //------------------------------------------------------------------------------
 
- //------------------------------------------------------------------------------
 
- class ctkDICOMIndexerPrivate
 
- {
 
- public:
 
-   ctkDICOMIndexerPrivate();
 
-   ~ctkDICOMIndexerPrivate();
 
-   ctkDICOMAbstractThumbnailGenerator* thumbnailGenerator;
 
-   /// these are for optimizing the import of image sequences
 
-   /// since most information are identical for all slices
 
-   OFString lastPatientID;
 
-   OFString lastPatientsName;
 
-   OFString lastPatientsBirthDate;
 
-   OFString lastStudyInstanceUID;
 
-   OFString lastSeriesInstanceUID;
 
-   int lastPatientUID;
 
- };
 
- //------------------------------------------------------------------------------
 
- // ctkDICOMIndexerPrivate methods
 
- //------------------------------------------------------------------------------
 
- ctkDICOMIndexerPrivate::ctkDICOMIndexerPrivate()
 
- {
 
-     this->thumbnailGenerator = NULL;
 
-     this->lastPatientID = "";
 
-     this->lastPatientsName = "";
 
-     this->lastPatientsBirthDate = "";
 
-     this->lastStudyInstanceUID = "";
 
-     this->lastSeriesInstanceUID = "";
 
-     this->lastPatientUID = -1;
 
- }
 
- //------------------------------------------------------------------------------
 
- ctkDICOMIndexerPrivate::~ctkDICOMIndexerPrivate()
 
- {
 
- }
 
- //------------------------------------------------------------------------------
 
- //------------------------------------------------------------------------------
 
- // ctkDICOMIndexer methods
 
- //------------------------------------------------------------------------------
 
- ctkDICOMIndexer::ctkDICOMIndexer(QObject *parent):d_ptr(new ctkDICOMIndexerPrivate)
 
- {
 
-   Q_UNUSED(parent);
 
- }
 
- //------------------------------------------------------------------------------
 
- ctkDICOMIndexer::~ctkDICOMIndexer()
 
- {
 
- }
 
- //------------------------------------------------------------------------------
 
- bool ctkDICOMIndexer::loggedExec(QSqlQuery& query)
 
- {
 
-   return (this->loggedExec(query, QString("")));
 
- }
 
- //------------------------------------------------------------------------------
 
- bool ctkDICOMIndexer::loggedExec(QSqlQuery& query, const QString& queryString)
 
- {
 
-   bool success;
 
-   if (queryString.compare(""))
 
-     {
 
-     success = query.exec(queryString);
 
-     }
 
-   else
 
-     {
 
-     success = query.exec();
 
-     }
 
-   if (!success)
 
-     {
 
-     QSqlError sqlError = query.lastError();
 
-     logger.debug( "SQL failed\n Bad SQL: " + query.lastQuery());
 
-     logger.debug( "Error text: " + sqlError.text());
 
-     }
 
-   else
 
-     {
 
-   logger.debug( "SQL worked!\n SQL: " + query.lastQuery());
 
-     }
 
-   return (success);
 
- }
 
- //------------------------------------------------------------------------------
 
- void ctkDICOMIndexer::addFile(ctkDICOMDatabase& ctkDICOMDatabase, 
 
-                                    const QString& filePath,
 
-                                    const QString& destinationDirectoryName,
 
-                                    bool createHierarchy,
 
-                                    bool createThumbnails)
 
- {
 
-   Q_D(ctkDICOMIndexer);
 
-   logger.setDebug();
 
-   DcmFileFormat fileformat;
 
-   DcmDataset *dataset;
 
-   std::string filename = filePath.toStdString();
 
-   emit indexingFilePath(filePath);
 
-   /// first we check if the file is already in the database
 
-   QSqlQuery check_filename_query(ctkDICOMDatabase.database());
 
-   check_filename_query.prepare("SELECT InsertTimestamp FROM Images WHERE Filename == ?");
 
-   check_filename_query.bindValue(0,filePath);
 
-   this->loggedExec(check_filename_query);
 
-   if (
 
-     check_filename_query.next() &&
 
-     QFileInfo(filePath).lastModified() < QDateTime::fromString(check_filename_query.value(0).toString(),Qt::ISODate)
 
-     )
 
-     {
 
-     logger.debug( "File " + filePath + " already added.");
 
-     return;
 
-     }
 
-   check_filename_query.finish();
 
-   logger.debug( "Processing " + filePath ); 
 
-   OFCondition status = fileformat.loadFile(filename.c_str());
 
-   dataset = fileformat.getDataset();
 
-   if (!status.good())
 
-   {
 
-     logger.error( "Could not load " + filePath );
 
-     logger.error( "DCMTK says: " + QString(status.text()) );
 
-     return;
 
-   }
 
-   OFString patientsName, patientID, patientsBirthDate, patientsBirthTime, patientsSex,
 
-     patientComments, patientsAge;
 
-   OFString studyInstanceUID, studyID, studyDate, studyTime,
 
-     accessionNumber, modalitiesInStudy, institutionName, performingPhysiciansName, referringPhysician, studyDescription;
 
-   OFString seriesInstanceUID, seriesDate, seriesTime,
 
-     seriesDescription, bodyPartExamined, frameOfReferenceUID,
 
-     contrastAgent, scanningSequence;
 
-   OFString instanceNumber, sopInstanceUID ;
 
-   Sint32 seriesNumber = 0, acquisitionNumber = 0, echoNumber = 0, temporalPosition = 0;
 
-   //The patient UID is a unique number within the database, generated by the sqlite autoincrement
 
-   //Thus, this is _not_ the DICOM Patient ID.
 
-   int patientUID = -1;
 
-   //If the following fields can not be evaluated, cancel evaluation of the DICOM file
 
-   if (!dataset->findAndGetOFString(DCM_PatientName, patientsName).good())
 
-   {
 
-     logger.error( "Could not read DCM_PatientName from " + filePath );
 
-     return;
 
-   }
 
-   if (!dataset->findAndGetOFString(DCM_StudyInstanceUID, studyInstanceUID).good())
 
-   {
 
-     logger.error( "Could not read DCM_StudyInstanceUID from " + filePath );
 
-     return;
 
-   }
 
-   if (!dataset->findAndGetOFString(DCM_SeriesInstanceUID, seriesInstanceUID).good())
 
-   {
 
-     logger.error( "Could not read DCM_SeriesInstanceUID from " + filePath );
 
-     return;
 
-   }
 
-   if (!dataset->findAndGetOFString(DCM_SOPInstanceUID, sopInstanceUID).good())
 
-   {
 
-     logger.error( "Could not read DCM_SOPInstanceUID from " + filePath );
 
-     return;
 
-   }
 
-   if (!dataset->findAndGetOFString(DCM_InstanceNumber, instanceNumber).good())
 
-   {
 
-     logger.error( "Could not read DCM_InstanceNumber from " + filePath );
 
-     return;
 
-   }
 
-   dataset->findAndGetOFString(DCM_PatientID, patientID);
 
-   dataset->findAndGetOFString(DCM_PatientBirthDate, patientsBirthDate);
 
-   dataset->findAndGetOFString(DCM_PatientBirthTime, patientsBirthTime);
 
-   dataset->findAndGetOFString(DCM_PatientSex, patientsSex);
 
-   dataset->findAndGetOFString(DCM_PatientAge, patientsAge);
 
-   dataset->findAndGetOFString(DCM_PatientComments, patientComments);
 
-   dataset->findAndGetOFString(DCM_StudyID, studyID);
 
-   dataset->findAndGetOFString(DCM_StudyDate, studyDate);
 
-   dataset->findAndGetOFString(DCM_StudyTime, studyTime);
 
-   dataset->findAndGetOFString(DCM_AccessionNumber, accessionNumber);
 
-   dataset->findAndGetOFString(DCM_ModalitiesInStudy, modalitiesInStudy);
 
-   dataset->findAndGetOFString(DCM_InstitutionName, institutionName);
 
-   dataset->findAndGetOFString(DCM_PerformingPhysicianName, performingPhysiciansName);
 
-   dataset->findAndGetOFString(DCM_ReferringPhysicianName, referringPhysician);
 
-   dataset->findAndGetOFString(DCM_StudyDescription, studyDescription);
 
-   dataset->findAndGetOFString(DCM_SeriesDate, seriesDate);
 
-   dataset->findAndGetOFString(DCM_SeriesTime, seriesTime);
 
-   dataset->findAndGetOFString(DCM_SeriesDescription, seriesDescription);
 
-   dataset->findAndGetOFString(DCM_BodyPartExamined, bodyPartExamined);
 
-   dataset->findAndGetOFString(DCM_FrameOfReferenceUID, frameOfReferenceUID);
 
-   dataset->findAndGetOFString(DCM_ContrastBolusAgent, contrastAgent);
 
-   dataset->findAndGetOFString(DCM_ScanningSequence, scanningSequence);
 
-   dataset->findAndGetSint32(DCM_SeriesNumber, seriesNumber);
 
-   dataset->findAndGetSint32(DCM_AcquisitionNumber, acquisitionNumber);
 
-   dataset->findAndGetSint32(DCM_EchoNumbers, echoNumber);
 
-   dataset->findAndGetSint32(DCM_TemporalPositionIdentifier, temporalPosition);
 
-   logger.debug( "Adding new items to database:" );
 
-   logger.debug( "studyID: " + QString(studyID.c_str()) );
 
-   logger.debug( "seriesInstanceUID: " + QString(seriesInstanceUID.c_str()) );
 
-   logger.debug( "Patient's Name: " + QString(patientsName.c_str()) );
 
-   //-----------------------
 
-   //Add Patient to Database
 
-   //-----------------------
 
-   //Speed up: Check if patient is the same as in last file; very probable, as all images belonging to a study have the same patient
 
-   bool patientExists = false;
 
-   if(d->lastPatientID.compare(patientID) || d->lastPatientsBirthDate.compare(patientsBirthDate) || d->lastPatientsName.compare(patientsName))
 
-   {
 
-     //Check if patient is already present in the db
 
-     QSqlQuery check_exists_query(ctkDICOMDatabase.database());
 
-     std::stringstream check_exists_query_string;
 
-     check_exists_query_string << "SELECT * FROM Patients WHERE PatientID = '" << patientID << "'";
 
-     this->loggedExec(check_exists_query, check_exists_query_string.str().c_str());
 
-     /// we check only patients with the same PatientID
 
-     /// PatientID is not unique in DICOM, so we also compare Name and BirthDate
 
-     /// and assume this is sufficient
 
-     while (check_exists_query.next())
 
-     {
 
-       if (
 
-           check_exists_query.record().value("PatientsName").toString() == patientsName.c_str() &&
 
-           check_exists_query.record().value("PatientsBirthDate").toString() == patientsBirthDate.c_str()
 
-          )
 
-       {
 
-         /// found it
 
-         patientUID = check_exists_query.value(check_exists_query.record().indexOf("UID")).toInt();
 
-         patientExists = true;
 
-         break;
 
-       }
 
-     }
 
-     check_exists_query.finish();
 
-     if(!patientExists)
 
-     {
 
-       QSqlQuery insert_patient_query(ctkDICOMDatabase.database());
 
-       std::stringstream query_string;
 
-       query_string << "INSERT INTO Patients VALUES( NULL,'"
 
-       << patientsName << "','"
 
-       << patientID << "','"
 
-       << patientsBirthDate << "','"
 
-       << patientsBirthTime << "','"
 
-       << patientsSex << "','"
 
-       << patientsAge << "','"
 
-       << patientComments << "')";
 
-       this->loggedExec(insert_patient_query, query_string.str().c_str());
 
-       patientUID = insert_patient_query.lastInsertId().toInt();
 
-       insert_patient_query.finish();
 
-       QString patientUIDQString;
 
-       patientUIDQString.setNum(patientUID);
 
-       logger.debug( "New patient inserted: " + patientUIDQString );
 
-     }
 
-   }
 
-   else
 
-     {
 
-     patientUID = d->lastPatientUID;
 
-     }
 
-   /// keep this for the next image
 
-   d->lastPatientUID = patientUID;
 
-   d->lastPatientID = patientID;
 
-   d->lastPatientsBirthDate = patientsBirthDate;
 
-   d->lastPatientsName = patientsName;
 
-   //---------------------
 
-   //Add Study to Database
 
-   //---------------------
 
-   if(d->lastStudyInstanceUID.compare(studyInstanceUID))
 
-   {
 
-     QSqlQuery check_exists_query(ctkDICOMDatabase.database());
 
-     std::stringstream check_exists_query_string;
 
-     check_exists_query_string << "SELECT * FROM Studies WHERE StudyInstanceUID = '" << studyInstanceUID << "'";
 
-     this->loggedExec(check_exists_query, check_exists_query_string.str().c_str());
 
-     logger.debug( "Checking for study: " + QString(studyInstanceUID.c_str()) );
 
-     if(!check_exists_query.next())
 
-     {
 
-       QSqlQuery insert_query(ctkDICOMDatabase.database());
 
-       std::stringstream query_string;
 
-       // TODO: all INSERTS should be changed to use the prepare/bindValue methods
 
-       // to avoid quoting issues
 
-       insert_query.prepare("INSERT INTO Studies (StudyInstanceUID, PatientsUID, StudyID, StudyDate, StudyTime, AccessionNumber, ModalitiesInStudy, InstitutionName, ReferringPhysician, PerformingPhysiciansName, StudyDescription) VALUES (:StudyInstanceUID, :PatientsUID, :StudyID, :StudyDate, :StudyTime, :AccessionNumber, :ModalitiesInStudy, :InstitutionName, :ReferringPhysician, :PerformingPhysiciansName, :StudyDescription)");
 
-       insert_query.bindValue(":StudyInstanceUID", QString(studyInstanceUID.c_str()));
 
-       insert_query.bindValue(":PatientsUID", patientUID);
 
-       insert_query.bindValue(":StudyID", QString(studyID.c_str()));
 
-       insert_query.bindValue(":StudyDate", QDate::fromString(studyDate.c_str(), "yyyyMMdd").toString("yyyy-MM-dd"));
 
-       insert_query.bindValue(":StudyTime", QString(studyTime.c_str()));
 
-       insert_query.bindValue(":AccessionNumber", QString(accessionNumber.c_str()));
 
-       insert_query.bindValue(":ModalitiesInStudy", QString(modalitiesInStudy.c_str()));
 
-       insert_query.bindValue(":InstitutionName", QString(institutionName.c_str()));
 
-       insert_query.bindValue(":ReferringPhysician", QString(referringPhysician.c_str()));
 
-       insert_query.bindValue(":PerformingPhysiciansName", QString(performingPhysiciansName.c_str()));
 
-       insert_query.bindValue(":StudyDescription", QString(studyDescription.c_str()));
 
-       this->loggedExec(insert_query);
 
-       logger.debug( "Inserted study: " + QString(studyInstanceUID.c_str()) );
 
-     }
 
-   }
 
-   d->lastStudyInstanceUID = studyInstanceUID;
 
-   //----------------------
 
-   //Add Series to Database
 
-   //----------------------
 
-   if(d->lastSeriesInstanceUID.compare(seriesInstanceUID))
 
-   {
 
-     QSqlQuery check_exists_query(ctkDICOMDatabase.database());
 
-     std::stringstream check_exists_query_string;
 
-     check_exists_query_string << "SELECT * FROM Series WHERE SeriesInstanceUID = '" << seriesInstanceUID << "'";
 
-     this->loggedExec(check_exists_query, check_exists_query_string.str().c_str());
 
-     logger.debug( "Checking series: " + QString(seriesInstanceUID.c_str()) );
 
-     if(!check_exists_query.next())
 
-     {
 
-       QSqlQuery insert_query(ctkDICOMDatabase.database());
 
-       std::stringstream query_string;
 
-       query_string << "INSERT INTO Series VALUES('"
 
-         << seriesInstanceUID << "','"
 
-         << studyInstanceUID << "','"
 
-         << static_cast<int>(seriesNumber) << "','"
 
-         << QDate::fromString(seriesDate.c_str(), "yyyyMMdd").toString("yyyy-MM-dd").toStdString() << "','"
 
-         << seriesTime << "','"
 
-         << seriesDescription << "','"
 
-         << bodyPartExamined << "','"
 
-         << frameOfReferenceUID << "','"
 
-         << static_cast<int>(acquisitionNumber) << "','"
 
-         << contrastAgent << "','"
 
-         << scanningSequence << "','"
 
-         << static_cast<int>(echoNumber) << "','"
 
-         << static_cast<int>(temporalPosition) << "')";
 
-       this->loggedExec(insert_query, query_string.str().c_str());
 
-       logger.debug( "Inserted series: " + QString(seriesInstanceUID.c_str()) );
 
-     }
 
-   }
 
-   d->lastSeriesInstanceUID = seriesInstanceUID;
 
-   QString studySeriesDirectory = QString(studyInstanceUID.c_str()) + "/" + seriesInstanceUID.c_str();
 
-   //----------------------------------
 
-   //Move file to destination directory
 
-   //----------------------------------
 
-   QString finalFilePath(filePath);
 
-   if (!destinationDirectoryName.isEmpty())
 
-   {
 
-     QFile currentFile( filePath );
 
-     QDir destinationDir(destinationDirectoryName + "/dicom");
 
-     finalFilePath = sopInstanceUID.c_str();
 
-     if (createHierarchy)
 
-     {
 
-       destinationDir.mkpath(studySeriesDirectory);
 
-       finalFilePath.prepend( destinationDir.absolutePath() + "/"  + studySeriesDirectory + "/" );
 
-     }
 
-     currentFile.copy(finalFilePath);
 
-     logger.debug( "Copy file from: " + filePath );
 
-     logger.debug( "Copy file to  : " + finalFilePath );
 
-   }
 
-   logger.debug(QString("finalFilePath: ") + finalFilePath);
 
-   if (createThumbnails)
 
-   {
 
-     if(d->thumbnailGenerator)
 
-     {
 
-       QString thumbnailBaseDir =  ctkDICOMDatabase.databaseDirectory() + "/thumbs/";
 
-       QString thumbnailFilename = thumbnailBaseDir + "/" + ctkDICOMDatabase.pathForDataset(dataset) + ".png";
 
-       QFileInfo thumbnailInfo(thumbnailFilename);
 
-       if ( ! ( thumbnailInfo.exists() && thumbnailInfo.lastModified() < QFileInfo(finalFilePath).lastModified() ) )
 
-       {
 
-         QDir(thumbnailBaseDir).mkpath(studySeriesDirectory);
 
-         DicomImage dcmtkImage(QDir::toNativeSeparators(finalFilePath).toStdString().c_str());
 
-         d->thumbnailGenerator->generateThumbnail(&dcmtkImage, thumbnailFilename);
 
-       }
 
-     }
 
-   }
 
-   //------------------------
 
-   //Add Filename to Database
 
-   //------------------------
 
- //    std::stringstream relativeFilePath;
 
- //    relativeFilePath << seriesInstanceUID.c_str() << "/" << currentFilePath.getFileName();
 
-   logger.debug(QString("Adding file path to dabase: ") + finalFilePath);
 
-   QSqlQuery check_exists_query(ctkDICOMDatabase.database());
 
-   std::stringstream check_exists_query_string;
 
- //    check_exists_query_string << "SELECT * FROM Images WHERE Filename = '" << relativeFilePath.str() << "'";
 
-   check_exists_query_string << "SELECT * FROM Images WHERE SOPInstanceUID = '" << sopInstanceUID << "'";
 
-   this->loggedExec(check_exists_query, check_exists_query_string.str().c_str());
 
-   if(!check_exists_query.next())
 
-   {
 
-     QSqlQuery insert_query(ctkDICOMDatabase.database());
 
-     std::stringstream query_string;
 
-     //To save absolute path: destDirectoryPath.str()
 
-     query_string << "INSERT INTO Images VALUES('"
 
-       << sopInstanceUID << "','" << finalFilePath.toStdString() << "','" << seriesInstanceUID << "','" << QDateTime::currentDateTime().toString(Qt::ISODate).toStdString() << "')";
 
-     this->loggedExec(insert_query, query_string.str().c_str());
 
-     logger.debug(QString("added file path to dabase: ") + query_string.str().c_str());
 
-   }
 
- }
 
- //------------------------------------------------------------------------------
 
- void ctkDICOMIndexer::addDirectory(ctkDICOMDatabase& ctkDICOMDatabase, 
 
-                                    const QString& directoryName,
 
-                                    const QString& destinationDirectoryName,
 
-                                    bool createHierarchy,
 
-                                    bool createThumbnails)
 
- {
 
-   const std::string src_directory(directoryName.toStdString());
 
-   OFList<OFString> originalDcmtkFileNames;
 
-   OFList<OFString> dcmtkFileNames;
 
-   OFStandard::searchDirectoryRecursively( QDir::toNativeSeparators(src_directory.c_str()).toAscii().data(), originalDcmtkFileNames, "", "");
 
-   // hack to reverse list of filenames (not neccessary when image loading works correctly)
 
-   for ( OFListIterator(OFString) iter = originalDcmtkFileNames.begin(); iter != originalDcmtkFileNames.end(); ++iter )
 
-   {
 
-     dcmtkFileNames.push_front( *iter );
 
-   }
 
-   OFListIterator(OFString) iter = dcmtkFileNames.begin();
 
-   OFListIterator(OFString) last = dcmtkFileNames.end();
 
-   if(iter == last) return;
 
-   emit foundFilesToIndex(dcmtkFileNames.size());
 
-   /* iterate over all input filenames */
 
-   int fileNumber = 0;
 
-   while (iter != last)
 
-   {
 
-     emit indexingFileNumber(++fileNumber);
 
-     QString filePath((*iter).c_str());
 
-     this->addFile(ctkDICOMDatabase, filePath, destinationDirectoryName, createHierarchy, createThumbnails);
 
-     ++iter;
 
-   }
 
- }
 
- //------------------------------------------------------------------------------
 
- void ctkDICOMIndexer::refreshDatabase(ctkDICOMDatabase& ctkDICOMDatabase, const QString& directoryName)
 
- {
 
-   /// get all filenames from the database
 
-   QSqlQuery allFilesQuery(ctkDICOMDatabase.database());
 
-   QStringList databaseFileNames;
 
-   QStringList filesToRemove;
 
-   this->loggedExec(allFilesQuery, "SELECT Filename from Images;");
 
-   while (allFilesQuery.next())
 
-     {
 
-     QString fileName = allFilesQuery.value(0).toString();
 
-     databaseFileNames.append(fileName);
 
-     if (! QFile::exists(fileName) )
 
-       {
 
-       filesToRemove.append(fileName);
 
-       }
 
-     }
 
-   QSet<QString> filesytemFiles;
 
-   QDirIterator dirIt(directoryName);
 
-   while (dirIt.hasNext())
 
-     {
 
-     filesytemFiles.insert(dirIt.next());
 
-     }
 
-   
 
-   // TODO: it looks like this function was never finished...
 
-   // 
 
-   // I guess the next step is to remove all filesToRemove from the database
 
-   // and also to add filesystemFiles into the database tables
 
- }
 
- //------------------------------------------------------------------------------
 
- void ctkDICOMIndexer::setThumbnailGenerator(ctkDICOMAbstractThumbnailGenerator *generator){
 
-     Q_D(ctkDICOMIndexer);
 
-     d->thumbnailGenerator = generator;
 
- }
 
- //------------------------------------------------------------------------------
 
- ctkDICOMAbstractThumbnailGenerator* ctkDICOMIndexer::thumbnailGenerator(){
 
-     Q_D(ctkDICOMIndexer);
 
-     return d->thumbnailGenerator;
 
- }
 
 
  |