Index: mbi/Modules/QtDicomBrowser/QtDicomBrowser.ui =================================================================== --- mbi/Modules/QtDicomBrowser/QtDicomBrowser.ui (revision 20166) +++ mbi/Modules/QtDicomBrowser/QtDicomBrowser.ui (working copy) @@ -15,20 +15,56 @@ - - - - 0 - 0 - - - - DICOM Browsing - - - false - - + + + + + + 0 + 0 + + + + DICOM Browsing + + + false + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 231 + 21 + + + + + + + + + 0 + 0 + + + + Status: + + + false + + + + @@ -46,6 +82,19 @@ + + + + 0 + 0 + + + + Remove Dir + + + + Qt::Horizontal @@ -61,25 +110,68 @@ + + + + + 0 + 0 + + + + Refresh DB + + + + + + + false + + + + 0 + 0 + + + + Stop Refresh + + + - - - - 0 - 0 - - - - - - + - Qt::Horizontal + Qt::Vertical - - + + + + 0 + 0 + + + + + + Qt::Horizontal + + + + false + + + QAbstractItemView::SelectRows + + + + + QAbstractItemView::SelectRows + + + Index: mbi/Modules/QtDicomBrowser/QtDicomBrowser.cpp =================================================================== --- mbi/Modules/QtDicomBrowser/QtDicomBrowser.cpp (revision 20166) +++ mbi/Modules/QtDicomBrowser/QtDicomBrowser.cpp (working copy) @@ -1,37 +1,246 @@ #include "QtDicomBrowser.h" +#include +#include +#include #include -#include -#include -#include #include -#include -#include "mbilog.h" +#include -void QtDicomBrowser::test() { - QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE"); - db.setDatabaseName( "/local/nolden/nfs-bin/test.db" ); - if (!db.open()) { - LOG_ERROR << "Cannot access DICOM db"; - }; - m_StudiesModel = new QSqlQueryModel(); - m_StudiesModel->setQuery("SELECT Studies.StudyDate, Studies.StudyDescription, Patients.PatientsName, Patients.PatientsBirthDate from Patients,Studies where Patients.UID = Studies.PatientsUID"); - m_StudiesView->setModel(m_StudiesModel); +QtDicomBrowser::QtDicomBrowser(QWidget *parent) + : QWidget(parent), m_StudiesModel(0), m_SeriesModel(0), m_DirectoryList(), m_DirectoryListModel(m_DirectoryList), m_Refreshing(false) +{ + setupUi(this); + this->setAttribute(Qt::WA_DeleteOnClose); + this->m_DB = new QSqlDatabase(QSqlDatabase::addDatabase("QSQLITE")); + connect(m_AddDirectoryButton, SIGNAL(clicked()), this, SLOT(AddDirectoryClicked())); + connect(m_RemoveDirectoryButton, SIGNAL(clicked()), this, SLOT(RemoveDirectoryClicked())); + connect(m_RefreshButton, SIGNAL(clicked()), this, SLOT(RefreshClicked())); + connect(m_StopRefreshButton, SIGNAL(clicked()), this, SLOT(StopRefreshClicked())); + connect(m_StudiesView, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(StudiesViewDoubleClicked(const QModelIndex&))); + connect(m_SeriesView, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(SeriesViewDoubleClicked(const QModelIndex&))); + connect(&m_Indexer, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(IndexerFinished(int, QProcess::ExitStatus))); - // m_SeriesModel = new QSqlQueryModel - + this->m_DirectoryListView->setEditTriggers(QAbstractItemView::NoEditTriggers); + this->m_DirectoryListView->setModel(&this->m_DirectoryListModel); + this->m_StatusLabel->setText(QString("Status: DB NOT connected!")); } -void QtDicomBrowser::AddDirectoryClicked() { - QString dir = QFileDialog::getExistingDirectory(this, tr("Open Directory")); - if (m_DirectoryList.indexOf(dir) == -1) { - m_DirectoryList.push_back(dir); - m_DirectoryListModel.setStringList(m_DirectoryList); - } +QtDicomBrowser::~QtDicomBrowser() +{ + if (this->m_StudiesModel) + { + delete this->m_StudiesModel; + } + if (this->m_SeriesModel) + { + delete this->m_SeriesModel; + } - -}; + if (this->m_DB->isOpen()) + { + this->m_DB->close(); + } + delete this->m_DB; +} + +bool QtDicomBrowser::AddDirectory(const QString &dir) +{ + if (!this->m_Refreshing && !dir.isEmpty() && (this->m_DirectoryList.indexOf(dir) == -1)) + { + this->m_DirectoryList.push_back(dir); + this->m_DirectoryListModel.setStringList(this->m_DirectoryList); + emit dirAdded(); + return true; + } + + return false; +} + +bool QtDicomBrowser::SetDataBase(const QString &db) +{ + if (this->m_DB->isOpen()) + { + this->m_DB->close(); + } + + this->m_DB->setDatabaseName(db); + + if (this->m_DB->open()) + { + this->m_DbPath = db; + this->LoadStudies(); + return true; + } + + this->m_StatusLabel->setText(QString("Status: DB NOT connected!")); + return false; +} + +void QtDicomBrowser::LoadStudies() +{ + if (this->m_DB->isOpen()) + { + if (this->m_StudiesModel) + { + delete this->m_StudiesModel; + } + + this->m_StudiesModel = new QSqlQueryModel(); + this->m_StudiesModel->setQuery("SELECT Studies.StudyInstanceUID, Studies.StudyDate as Date, Studies.StudyDescription, Patients.PatientsName, Patients.PatientsBirthDate from Patients,Studies where Patients.UID = Studies.PatientsUID"); + this->m_StudiesView->setModel(this->m_StudiesModel); + connect(m_StudiesView->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), this, SLOT(StudiesSelectionChanged(const QItemSelection&, const QItemSelection&))); + this->m_StudiesView->setColumnHidden(0, true); + this->m_StatusLabel->setText(QString("Status: DB connected.")); + } + else + { + this->m_StatusLabel->setText(QString("Status: DB NOT connected!")); + } +} + +void QtDicomBrowser::AddDirectoryClicked() +{ + this->AddDirectory(QFileDialog::getExistingDirectory(this, tr("Open Directory"))); +} + +void QtDicomBrowser::RemoveDirectoryClicked() +{ + QModelIndex index = this->m_DirectoryListView->selectionModel()->currentIndex(); + + if (index.isValid()) + { + this->m_DirectoryList.removeAt(index.row()); + this->m_DirectoryListModel.setStringList(this->m_DirectoryList); + emit dirRemoved(); + } +} + +void QtDicomBrowser::RefreshClicked() +{ + QSqlQuery sql_query; + + sql_query.exec("DELETE FROM Config"); + sql_query.exec("DELETE FROM ImageProcessing"); + sql_query.exec("DELETE FROM Images"); + sql_query.exec("DELETE FROM Patients"); + sql_query.exec("DELETE FROM ResectionPlans"); + sql_query.exec("DELETE FROM Series"); + sql_query.exec("DELETE FROM Studies"); + + this->m_StudiesView->setModel(0); + this->m_SeriesView->setModel(0); + + if (this->m_DB->isOpen() && !this->m_DirectoryList.empty()) + { + this->m_ActDir = 0; + this->RefreshingModus(true); + this->Refresh(); + } +} + +void QtDicomBrowser::StopRefreshClicked() +{ + this->m_ActDir = this->m_DirectoryList.size(); + this->m_Indexer.terminate(); + this->RefreshingModus(false); + this->LoadStudies(); +} + +void QtDicomBrowser::StudiesSelectionChanged(const QItemSelection&, const QItemSelection&) +{ + this->m_SeriesView->setModel(0); +} + +void QtDicomBrowser::StudiesViewDoubleClicked(const QModelIndex &index) +{ + QString query("SELECT Series.SeriesInstanceUID, Series.SeriesNumber, Series.SeriesDate, Series.SeriesDescription from Series where Series.StudyInstanceUID = '"); + + query.append(this->m_StudiesModel->record(index.row()).value(0).toString()); + query.append("'"); + + if (this->m_SeriesModel) + { + delete this->m_SeriesModel; + } + + this->m_SeriesModel = new QSqlQueryModel(); + this->m_SeriesModel->setQuery(query); + this->m_SeriesView->setModel(this->m_SeriesModel); + this->m_SeriesView->setColumnHidden(0, true); +} + +void QtDicomBrowser::SeriesViewDoubleClicked(const QModelIndex &index) +{ + QString query("SELECT Filename FROM Images WHERE Images.SeriesInstanceUID = '"); + + query.append(this->m_SeriesModel->record(index.row()).value(0).toString()); + query.append("'"); + + QSqlQuery sql_query(query); + + this->m_Filenames.clear(); + + while (sql_query.next()) + { + this->m_Filenames.push_back(sql_query.value(0).toString()); + } + + emit serieSelected(this->m_Filenames); +} + +void QtDicomBrowser::IndexerFinished(int exitCode, QProcess::ExitStatus exitStatus) +{ + this->LoadStudies(); + + if (this->m_ActDir == this->m_DirectoryList.size()) + { + this->RefreshingModus(false); + } + else + { + this->Refresh(); + } +} + +void QtDicomBrowser::RefreshingModus(bool refreshing) +{ + this->m_AddDirectoryButton->setEnabled(!refreshing); + this->m_RemoveDirectoryButton->setEnabled(!refreshing); + this->m_RefreshButton->setEnabled(!refreshing); + this->m_StopRefreshButton->setEnabled(refreshing); + this->m_Refreshing = refreshing; +} + +void QtDicomBrowser::Refresh() +{ + if (this->m_ActDir < this->m_DirectoryList.size()) + { + QString + indexer("/localhome/noldenlocal/mitk/binDebug/mitk/bin/DicomIndexer"), + directory(this->m_DirectoryList.at(this->m_ActDir)), + status("Status: Loading directory '"); + QStringList arguments; + + status.append(directory); + status.append("'"); + + this->m_StatusLabel->setText(status); + + arguments << "--add-dir" << this->m_DbPath << directory; + ++this->m_ActDir; + + this->m_Indexer.setProcessChannelMode(QProcess::ForwardedChannels); + this->m_Indexer.start(indexer, arguments); + + if (!this->m_Indexer.waitForStarted(5000)) + { + this->m_StatusLabel->setText(QString("Status: Refresh failed!")); + this->RefreshingModus(false); + } + } +} Index: mbi/Modules/QtDicomBrowser/QtDicomBrowser.h =================================================================== --- mbi/Modules/QtDicomBrowser/QtDicomBrowser.h (revision 20166) +++ mbi/Modules/QtDicomBrowser/QtDicomBrowser.h (working copy) @@ -5,32 +5,55 @@ #include #include +#include #include +class QSqlDatabase; class QSqlQueryModel; -class QtDicomBrowser_EXPORT QtDicomBrowser : public QWidget, public Ui::QtDicomBrowser +class QtDicomBrowser_EXPORT QtDicomBrowser : public QWidget, public Ui::QtDicomBrowser { - Q_OBJECT +Q_OBJECT - public: - QtDicomBrowser(QWidget *parent = 0) : QWidget(parent), m_DirectoryList(), m_DirectoryListModel(m_DirectoryList) { - setupUi(this); - connect(m_AddDirectoryButton,SIGNAL(clicked()),this,SLOT(AddDirectoryClicked())); - m_DirectoryListView->setEditTriggers(QAbstractItemView::NoEditTriggers); - m_DirectoryListView->setModel(&m_DirectoryListModel); - test(); - } - void test(); - public slots: - void AddDirectoryClicked(); - protected: - QSqlQueryModel* m_StudiesModel; - QSqlQueryModel* m_SeriesModel; - QStringList m_DirectoryList; - QStringListModel m_DirectoryListModel; +public: + QtDicomBrowser(QWidget *parent = 0); + ~QtDicomBrowser(); + bool AddDirectory(const QString &dir); + bool SetDataBase(const QString &db); + + inline const QStringList& DirList() const + { + return this->m_DirectoryList; + } +public slots: + void AddDirectoryClicked(); + void RemoveDirectoryClicked(); + void RefreshClicked(); + void StopRefreshClicked(); + void StudiesSelectionChanged(const QItemSelection&, const QItemSelection&); + void StudiesViewDoubleClicked(const QModelIndex &index); + void SeriesViewDoubleClicked(const QModelIndex &index); + void IndexerFinished(int exitCode, QProcess::ExitStatus exitStatus); +signals: + void dirAdded(); + void dirRemoved(); + void serieSelected(const QStringList &filenames); +protected: + QString m_DbPath; + QSqlDatabase *m_DB; + QSqlQueryModel *m_StudiesModel; + QSqlQueryModel *m_SeriesModel; + QStringList m_DirectoryList, m_Filenames; + QStringListModel m_DirectoryListModel; + QProcess m_Indexer; + bool m_Refreshing; + int m_ActDir; + + void LoadStudies(); + void RefreshingModus(bool refreshing); + void Refresh(); }; #endif - + Index: mbi/Modules/QtDicomBrowser/Testing/QtDicomBrowserTest.cpp =================================================================== --- mbi/Modules/QtDicomBrowser/Testing/QtDicomBrowserTest.cpp (revision 20166) +++ mbi/Modules/QtDicomBrowser/Testing/QtDicomBrowserTest.cpp (working copy) @@ -1,11 +1,12 @@ #include #include -int QtDicomBrowserTest(int argc,char** argv) { +int QtDicomBrowserTest(int argc,char** const argv) { QApplication a( argc, argv ); QtDicomBrowser *w = new QtDicomBrowser(); + w->SetDataBase("/home/santos/local-data/test.db"); w->show(); return a.exec(); Index: mbi/Modules/QtDicomBrowser/CMakeLists.txt =================================================================== --- mbi/Modules/QtDicomBrowser/CMakeLists.txt (revision 20166) +++ mbi/Modules/QtDicomBrowser/CMakeLists.txt (working copy) @@ -2,9 +2,9 @@ SET(QT_USE_QTSQL 1) MITK_CREATE_MODULE(QtDicomBrowser - DEPENDS mbilog Mitk + DEPENDS Mitk DicomIndex PACKAGE_DEPENDS QT QVTK QT_MODULE ) -# ADD_SUBDIRECTORY(Testing) +ADD_SUBDIRECTORY(Testing) Index: mbi/Modules/DicomIndexer/DicomIndexer.h =================================================================== --- mbi/Modules/DicomIndexer/DicomIndexer.h (revision 20166) +++ mbi/Modules/DicomIndexer/DicomIndexer.h (working copy) @@ -1,8 +1,9 @@ #ifndef DICOMINDEXER_H #define DICOMINDEXER_H #include +#include -void CleanUp(); +DicomIndex_EXPORT void CleanUp(); void ResetLock(); void ExecuteSqlScript(const std::string& dbFilename, const std::string& scriptFilename); @@ -49,7 +50,7 @@ * - if // does not exist, create it * - move the file to this directory */ -int DicomIndexer(int argc, char ** argv); +DicomIndex_EXPORT int DicomIndexer(int argc, char ** argv); #endif Index: mbi/Modules/DicomIndexer/files.cmake =================================================================== --- mbi/Modules/DicomIndexer/files.cmake (revision 20166) +++ mbi/Modules/DicomIndexer/files.cmake (working copy) @@ -1,4 +1,5 @@ SET(CPP_FILES DicomIndexer.cpp + #DicomIndexerMain.cpp ) Index: mbi/Modules/DicomIndexer/DicomIndexer.cpp =================================================================== --- mbi/Modules/DicomIndexer/DicomIndexer.cpp (revision 20166) +++ mbi/Modules/DicomIndexer/DicomIndexer.cpp (working copy) @@ -46,7 +46,6 @@ #include #include #include - #include "DicomIndexer.h" int DicomIndexer(int argc, char ** argv) @@ -83,7 +82,7 @@ //Poco::File dbFile(dbFilename); //if (dbFile.exists()) //{ - // LOG_ERROR << "Database file already exists. Please choose another filename." + // LOG_ERROR << "Database file already exists. Please choose another filename." // return EXIT_SUCCESS; //} @@ -121,7 +120,7 @@ if ( argc > 4 && "--move-files" == std::string(argv[4]) ) dest_directory.assign(argv[5]); - else moveFiles = false; + else moveFiles = false; LOG_INFO << "Scanning " << src_directory << " for new series, putting indexed series in " << dest_directory; @@ -162,7 +161,7 @@ if (!db.open()) return; QFile scriptFile(scriptFilename.c_str()); - if (!scriptFile.open(QFile::ReadOnly)) + if (!scriptFile.open(QFile::ReadOnly)) { LOG_ERROR << "Error: could not open sql script file: " << scriptFilename; return; @@ -179,10 +178,10 @@ QSqlQuery query(db); - for (QStringList::iterator it = sqlCommandsLines.begin(); it != sqlCommandsLines.end()-1; ++it) - { + for (QStringList::iterator it = sqlCommandsLines.begin(); it != sqlCommandsLines.end()-1; ++it) + { query.exec(*it); - if (query.lastError().type()) + if (query.lastError().type()) LOG_ERROR << "There was an error during execution of the statement: " << (*it).toStdString(); } @@ -195,12 +194,12 @@ { QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE"); db.setDatabaseName( dbFilename.c_str() ); - if (!db.open()) return; + if (!db.open()) return; QSqlQuery query("SELECT Filename FROM Images"); LOG_INFO << "isValid:" << query.isValid() << "\n"; LOG_INFO << "size:" << query.size() << "\n"; - while (query.next()) + while (query.next()) { QString dir_name = query.value(0).toString(); @@ -214,7 +213,7 @@ db.setDatabaseName( db_filename.c_str() ); if (!db.open()) return; - db.transaction(); + db.transaction(); OFList originalDcmtkFileNames; OFList dcmtkFileNames; @@ -246,20 +245,20 @@ OFCondition status = fileformat.loadFile(filename.c_str()); ++iter; - if (!status.good()) + if (!status.good()) { LOG_ERROR << "Could not load " << filename << "\nDCMTK says: " << status.text(); continue; } - OFString patientsName = "", patientID = "", patientsBirthDate = "", patientsBirthTime = "", patientsSex = "", + OFString patientsName = "", patientID = "", patientsBirthDate = "", patientsBirthTime = "", patientsSex = "", patientComments = ""; - OFString studyInstanceUID = "", studyID = "", studyDate = "", studyTime = "", + OFString studyInstanceUID = "", studyID = "", studyDate = "", studyTime = "", accessionNumber = "", modalitiesInStudy = "", referringPhysician = "", studyDescription = ""; - OFString seriesInstanceUID = "", seriesDate = "", seriesTime = "", - seriesDescription = "", bodyPartExamined = "", frameOfReferenceUID = "", + OFString seriesInstanceUID = "", seriesDate = "", seriesTime = "", + seriesDescription = "", bodyPartExamined = "", frameOfReferenceUID = "", contrastAgent = "", scanningSequence = ""; Sint32 seriesNumber = 0, acquisitionNumber = 0, echoNumber = 0, temporalPosition = 0; @@ -268,19 +267,19 @@ int patientUID = -1; //If the following fields can not be evaluated, cancel evaluation of the DICOM file - if (!fileformat.getDataset()->findAndGetOFString(DCM_PatientsName, patientsName).good()) + if (!fileformat.getDataset()->findAndGetOFString(DCM_PatientsName, patientsName).good()) { LOG_ERROR << "Could not read DCM_PatientsName from " << filename; continue; } - - if (!fileformat.getDataset()->findAndGetOFString(DCM_StudyInstanceUID, studyInstanceUID).good()) + + if (!fileformat.getDataset()->findAndGetOFString(DCM_StudyInstanceUID, studyInstanceUID).good()) { LOG_ERROR << "Could not read DCM_StudyInstanceUID from " << filename; continue; } - if (!fileformat.getDataset()->findAndGetOFString(DCM_SeriesInstanceUID, seriesInstanceUID).good()) + if (!fileformat.getDataset()->findAndGetOFString(DCM_SeriesInstanceUID, seriesInstanceUID).good()) { LOG_ERROR << "Could not read DCM_SeriesInstanceUID from " << filename; continue; @@ -329,12 +328,12 @@ QSqlQuery check_exists_query; std::stringstream check_exists_query_string; check_exists_query_string << "SELECT * FROM Patients WHERE PatientID = '" << patientID << "'"; - check_exists_query.exec(check_exists_query_string.str().c_str()); + check_exists_query.exec(check_exists_query_string.str().c_str()); //check_exists_query_string.flush(); bool patientExists = false; - while (check_exists_query.next()) + while (check_exists_query.next()) { patientExists = true; QString checkPatientsName = check_exists_query.value(check_exists_query.record().indexOf("PatientsName")).toString(); @@ -355,10 +354,10 @@ std::stringstream query_string; - query_string << "INSERT INTO Patients VALUES( NULL,'" << patientsName << "','" << patientID << "','" << patientsBirthDate << "','" + query_string << "INSERT INTO Patients VALUES( NULL,'" << patientsName << "','" << patientID << "','" << patientsBirthDate << "','" << patientsBirthTime << "','" << patientsSex << "','" << patientComments << "')"; - query.exec(query_string.str().c_str()); + query.exec(query_string.str().c_str()); patientUID = query.lastInsertId().toInt(); LOG_INFO << "Query result: " << patientUID << "\n"; @@ -382,19 +381,19 @@ QSqlQuery check_exists_query; std::stringstream check_exists_query_string; check_exists_query_string << "SELECT * FROM Studies WHERE StudyInstanceUID = '" << studyInstanceUID << "'"; - check_exists_query.exec(check_exists_query_string.str().c_str()); + check_exists_query.exec(check_exists_query_string.str().c_str()); if(!check_exists_query.next()) { std::stringstream query_string; - query_string << "INSERT INTO Studies VALUES('" - << studyInstanceUID << "','" << patientUID << "','" << studyID << "','" - << studyDate << "','" << studyTime << "','" << accessionNumber << "','" + query_string << "INSERT INTO Studies VALUES('" + << studyInstanceUID << "','" << patientUID << "','" << studyID << "','" + << studyDate << "','" << studyTime << "','" << accessionNumber << "','" << modalitiesInStudy << "','" << referringPhysician << "','" << studyDescription << "')"; - query.exec(query_string.str().c_str()); + query.exec(query_string.str().c_str()); } } @@ -410,20 +409,20 @@ QSqlQuery check_exists_query; std::stringstream check_exists_query_string; check_exists_query_string << "SELECT * FROM Series WHERE SeriesInstanceUID = '" << seriesInstanceUID << "'"; - check_exists_query.exec(check_exists_query_string.str().c_str()); + check_exists_query.exec(check_exists_query_string.str().c_str()); if(!check_exists_query.next()) { std::stringstream query_string; - query_string << "INSERT INTO Series VALUES('" - << seriesInstanceUID << "','" << studyInstanceUID << "','" << (int) seriesNumber << "','" << seriesDate << "','" - << seriesTime << "','" << seriesDescription << "','" << bodyPartExamined << "','" - << frameOfReferenceUID << "','" << (int) acquisitionNumber << "','" << contrastAgent << "','" + query_string << "INSERT INTO Series VALUES('" + << seriesInstanceUID << "','" << studyInstanceUID << "','" << (int) seriesNumber << "','" << seriesDate << "','" + << seriesTime << "','" << seriesDescription << "','" << bodyPartExamined << "','" + << frameOfReferenceUID << "','" << (int) acquisitionNumber << "','" << contrastAgent << "','" << scanningSequence << "','" << (int) echoNumber << "','" << (int) temporalPosition << "')"; - query.exec(query_string.str().c_str()); + query.exec(query_string.str().c_str()); } } @@ -443,10 +442,10 @@ std::stringstream destDirectoryPath; if((dest_directory[dest_directory.length()-1] != '/') && (dest_directory[dest_directory.length()-1] != '\\')) destDirectoryPath << dest_directory << Poco::Path::separator() << seriesInstanceUID.c_str(); - else + else destDirectoryPath << dest_directory << seriesInstanceUID.c_str(); - LOG_INFO << "last symbol: " << dest_directory[dest_directory.length()-1] + LOG_INFO << "last symbol: " << dest_directory[dest_directory.length()-1] << "\ndestDirectoryPath: " << destDirectoryPath.str() << "\n"; Poco::File directory(destDirectoryPath.str()); @@ -464,23 +463,24 @@ //Add Filename to Database //------------------------ - std::stringstream relativeFilePath; - relativeFilePath << seriesInstanceUID.c_str() << "/" << currentFilePath.getFileName(); +// std::stringstream relativeFilePath; +// relativeFilePath << seriesInstanceUID.c_str() << "/" << currentFilePath.getFileName(); QSqlQuery check_exists_query; std::stringstream check_exists_query_string; - check_exists_query_string << "SELECT * FROM Images WHERE Filename = '" << relativeFilePath.str() << "'"; - check_exists_query.exec(check_exists_query_string.str().c_str()); +// check_exists_query_string << "SELECT * FROM Images WHERE Filename = '" << relativeFilePath.str() << "'"; + check_exists_query_string << "SELECT * FROM Images WHERE Filename = '" << filename << "'"; + check_exists_query.exec(check_exists_query_string.str().c_str()); if(!check_exists_query.next()) { std::stringstream query_string; //To save absolute path: destDirectoryPath.str() - query_string << "INSERT INTO Images VALUES('" - << relativeFilePath.str() << "','" << seriesInstanceUID << "')"; + query_string << "INSERT INTO Images VALUES('" + << /*relativeFilePath.str()*/ filename << "','" << seriesInstanceUID << "')"; - query.exec(query_string.str().c_str()); + query.exec(query_string.str().c_str()); } } Index: mbi/Modules/DicomIndexer/CMakeLists.txt =================================================================== --- mbi/Modules/DicomIndexer/CMakeLists.txt (revision 20166) +++ mbi/Modules/DicomIndexer/CMakeLists.txt (working copy) @@ -3,6 +3,7 @@ IF( NOT WIN32 ) ADD_DEFINITIONS(-DHAVE_CONFIG_H) ENDIF( NOT WIN32 ) + IF(DCMTK_FOUND) MITK_CREATE_MODULE(DicomIndex INCLUDE_DIRS ${DCMTK_INCLUDE_DIR} @@ -11,10 +12,11 @@ PACKAGE_DEPENDS Poco QT QT_MODULE ) + IF( NOT WIN32 ) TARGET_LINK_LIBRARIES(${MODULE_NAME} wrap) ENDIF( NOT WIN32 ) -MESSAGE("%%%% POCO: ${Poco_LIBRARIES}") + MITK_USE_MODULE(DicomIndex) ADD_EXECUTABLE(DicomIndexer DicomIndexerMain.cpp) TARGET_LINK_LIBRARIES(DicomIndexer ${ALL_LIBRARIES}) Index: mbi/Modules/CMakeLists.txt =================================================================== --- mbi/Modules/CMakeLists.txt (revision 20166) +++ mbi/Modules/CMakeLists.txt (working copy) @@ -19,5 +19,6 @@ ADD_SUBDIRECTORY(IGTUI) ADD_SUBDIRECTORY(LymphNodeTools) ADD_SUBDIRECTORY(ShapeModelTools) +ADD_SUBDIRECTORY(DicomIndexer) ADD_SUBDIRECTORY(QtDicomBrowser) Index: mbi-sb/Q4Applications/Mitk3M3/CMakeLists.txt =================================================================== --- mbi-sb/Q4Applications/Mitk3M3/CMakeLists.txt (revision 20166) +++ mbi-sb/Q4Applications/Mitk3M3/CMakeLists.txt (working copy) @@ -24,6 +24,7 @@ QT4_WRAP_CPP(CPP_FILES QTranslucentSplashScreen.h) QT4_ADD_RESOURCES(CPP_FILES splashscreen.qrc) ADD_EXECUTABLE(Mitk3M3 ${CPP_FILES}) +ADD_DEPENDENCIES(Mitk3M3 DicomIndexer) TARGET_LINK_LIBRARIES(Mitk3M3 optimized PocoFoundation debug PocoFoundationd @@ -53,8 +54,8 @@ org.mitk.gui.qt.imagestatistics org.mitk.gui.qt.diffusionimaging org.mitk.diffusionimaging +org.mitk.gui.qt.dicombrowser - ) FOREACH(_3m3_dep ${_3m3_bundles}) Index: mbi-sb/BundlesQt/org.mitk.gui.qt.dicombrowser/src/internal/QmitkDICOMBrowserView.cpp =================================================================== --- mbi-sb/BundlesQt/org.mitk.gui.qt.dicombrowser/src/internal/QmitkDICOMBrowserView.cpp (revision 20166) +++ mbi-sb/BundlesQt/org.mitk.gui.qt.dicombrowser/src/internal/QmitkDICOMBrowserView.cpp (working copy) @@ -19,15 +19,21 @@ #include "QmitkDICOMBrowserView.h" #include "mitkNodePredicateDataType.h" - +#include #include "QmitkDataStorageComboBox.h" #include "QmitkStdMultiWidget.h" #include #include +#include #include "QtDicomBrowser.h" +#include +#include + +#include + const std::string QmitkDICOMBrowserView::VIEW_ID = "org.mitk.views.dicombrowser"; QmitkDICOMBrowserView::QmitkDICOMBrowserView() @@ -44,12 +50,51 @@ void QmitkDICOMBrowserView::CreateQtPartControl(QWidget *parent) { if (!m_Controls) - { + { + Poco::Path dbPath(Poco::Path::home()); + dbPath.append(Poco::Path(".Mitk3M3/dicom.db")); + QFile file(dbPath.toString().c_str()); + + if (!file.exists()) + { + file.open(QIODevice::WriteOnly); + file.close(); + +#ifdef WIN32 + QString indexer("DicomIndexer.exe"); +#else + QString indexer("DicomIndexer"); +#endif + + QString init_db_script(mitk::StandardFileLocations::GetInstance()->FindFile("dicomDB.sql","../mbi/Modules/DicomIndexer").c_str()); + + QStringList arguments; + QProcess indexerapp; + connect(&indexerapp,SIGNAL(error(QProcess::ProcessError)), this, SLOT(OnProcessError(QProcess::ProcessError))); + + arguments << "--exec-sql-script" << file.fileName() << init_db_script; + LOG_INFO << "No DICOM database. Calling " << indexer.toLocal8Bit().constData() << " " << arguments.join(" ").toLocal8Bit().constData(); + + indexerapp.setProcessChannelMode(QProcess::ForwardedChannels); + indexerapp.start(indexer, arguments); + indexerapp.waitForFinished(-1); + // file should be removed + LOG_ERROR << "Process error" << indexerapp.error(); + + // throw std::runtime_error("Error creating DICOM db"); + + } + + + // create GUI widgets m_Controls = new QtDicomBrowser(parent); + m_Controls->SetDataBase(file.fileName()); QVBoxLayout* layout = new QVBoxLayout; layout->addWidget(m_Controls); parent->setLayout(layout); + this->CreateConnections(); + this->LoadDirPreferences(); } } @@ -67,7 +112,9 @@ { if ( m_Controls ) { - // connect( (QObject*)(m_Controls->m_Button), SIGNAL(clicked()), this, SLOT(DoSomething()) ); + connect(m_Controls, SIGNAL(dirAdded()), this, SLOT(UpdateDirPreferences())); + connect(m_Controls, SIGNAL(dirRemoved()), this, SLOT(UpdateDirPreferences())); + connect(m_Controls, SIGNAL(serieSelected(const QStringList&)), this, SLOT(serieSelected(const QStringList&))); } } @@ -81,8 +128,71 @@ QmitkFunctionality::Deactivated(); } -void QmitkDICOMBrowserView::DoSomething() +void QmitkDICOMBrowserView::UpdateDirPreferences() { + cherry::IPreferencesService::Pointer prefService + = cherry::Platform::GetServiceRegistry().GetServiceById(cherry::IPreferencesService::ID); + cherry::IPreferences::Pointer pref = prefService->GetSystemPreferences()->Node(cherry::QtPreferences::QT_STYLES_NODE); + const QStringList &dir_list = this->m_Controls->DirList(); + const int size = dir_list.size(); + std::string paths; + + for (int i = 0; i < size; ++i) + { + paths += dir_list[i].toStdString() + ";"; + } + + pref->Put(cherry::QtPreferences::QT_STYLE_SEARCHPATHS, paths); + pref->Flush(); } +void QmitkDICOMBrowserView::serieSelected(const QStringList &filenames) +{ + typedef itk::Image ImageType; + typedef itk::ImageSeriesReader ReaderType; + const int size = filenames.size(); + std::vector n_filenames; + + n_filenames.reserve(size); + + for (int i = 0; i < size; ++i) + { + n_filenames.push_back(filenames[i].toStdString()); + } + + itk::DICOMImageIO2::Pointer io = itk::DICOMImageIO2::New(); + ReaderType::Pointer reader = ReaderType::New(); + + reader->SetFileNames(n_filenames); + reader->SetImageIO(io); + reader->ReverseOrderOff(); + reader->Update(); + + mitk::Image::Pointer image = mitk::Image::New(); + mitk::DataTreeNode::Pointer node = mitk::DataTreeNode::New(); + + image->InitializeByItk(reader->GetOutput()); + image->SetImportVolume(reader->GetOutput()->GetBufferPointer()); + node->SetData(image); + node->SetName("DCM Image"); + this->GetDefaultDataStorage()->Add(node); +} + +void QmitkDICOMBrowserView::LoadDirPreferences() +{ + cherry::IPreferencesService::Pointer prefService + = cherry::Platform::GetServiceRegistry().GetServiceById(cherry::IPreferencesService::ID); + cherry::IPreferences::Pointer pref = prefService->GetSystemPreferences()->Node(cherry::QtPreferences::QT_STYLES_NODE); + QString paths = QString::fromStdString(pref->Get(cherry::QtPreferences::QT_STYLE_SEARCHPATHS, "")); + QStringList pathList = paths.split(";", QString::SkipEmptyParts); + QStringListIterator it(pathList); + + while (it.hasNext()) + { + this->m_Controls->AddDirectory(it.next()); + } +} +void QmitkDICOMBrowserView::OnProcessError(QProcess::ProcessError error) { + LOG_ERROR << "DICOM process error: " << error; +} Index: mbi-sb/BundlesQt/org.mitk.gui.qt.dicombrowser/src/internal/QmitkDICOMBrowserView.h =================================================================== --- mbi-sb/BundlesQt/org.mitk.gui.qt.dicombrowser/src/internal/QmitkDICOMBrowserView.h (revision 20166) +++ mbi-sb/BundlesQt/org.mitk.gui.qt.dicombrowser/src/internal/QmitkDICOMBrowserView.h (working copy) @@ -22,6 +22,7 @@ #include #include +#include class QtDicomBrowser; @@ -37,17 +38,13 @@ */ class QmitkDICOMBrowserView : public QObject, public QmitkFunctionality { - // this is needed for all Qt objects that should have a MOC object (everything that derives from QObject) Q_OBJECT - - public: - +public: static const std::string VIEW_ID; QmitkDICOMBrowserView(); virtual ~QmitkDICOMBrowserView(); - virtual void CreateQtPartControl(QWidget *parent); /// \brief Creation of the connections of main and control widget @@ -55,22 +52,19 @@ /// \brief Called when the functionality is activated virtual void Activated(); - virtual void Deactivated(); - virtual void StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget); virtual void StdMultiWidgetNotAvailable(); - +public slots: + void UpdateDirPreferences(); + void serieSelected(const QStringList &filenames); protected slots: - - /// \brief Called when the user clicks the GUI button - void DoSomething(); - + void OnProcessError(QProcess::ProcessError error); protected: - QtDicomBrowser* m_Controls; - QmitkStdMultiWidget* m_MultiWidget; + + void LoadDirPreferences(); }; Index: mbi-sb/BundlesQt/org.mitk.gui.qt.dicombrowser/CMakeLists.txt =================================================================== --- mbi-sb/BundlesQt/org.mitk.gui.qt.dicombrowser/CMakeLists.txt (revision 20166) +++ mbi-sb/BundlesQt/org.mitk.gui.qt.dicombrowser/CMakeLists.txt (working copy) @@ -1,2 +1,4 @@ -MACRO_CREATE_MITK_PLUGIN(QmitkExt QtDicomBrowser) +MACRO_CREATE_MITK_PLUGIN(QmitkExt QtDicomBrowser DicomIndex) + +