diff --git a/Modules/DicomUI/Qmitk/QmitkDicomLocalStorageWidget.cpp b/Modules/DicomUI/Qmitk/QmitkDicomLocalStorageWidget.cpp index 7ed05ee4e6..c40e42b574 100644 --- a/Modules/DicomUI/Qmitk/QmitkDicomLocalStorageWidget.cpp +++ b/Modules/DicomUI/Qmitk/QmitkDicomLocalStorageWidget.cpp @@ -1,220 +1,220 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ // Qmitk #include "QmitkDicomLocalStorageWidget.h" #include #include #include // Qt #include #include #include #include const std::string QmitkDicomLocalStorageWidget::Widget_ID = "org.mitk.Widgets.QmitkDicomLocalStorageWidget"; QmitkDicomLocalStorageWidget::QmitkDicomLocalStorageWidget(QWidget *parent) : m_Controls( 0 ) ,m_LocalIndexer(new ctkDICOMIndexer()) ,m_LocalModel(new ctkDICOMModel()) { CreateQtPartControl(this); } QmitkDicomLocalStorageWidget::~QmitkDicomLocalStorageWidget() { m_LocalDatabase->closeDatabase(); delete m_LocalDatabase; delete m_LocalIndexer; delete m_LocalModel; delete m_Controls; } void QmitkDicomLocalStorageWidget::CreateQtPartControl( QWidget *parent ) { if ( !m_Controls ) { m_Controls = new Ui::QmitkDicomLocalStorageWidgetControls; m_Controls->setupUi( parent ); m_Controls->groupBox->setVisible(false); m_Controls->CancelButton->setVisible(false); m_Controls->addSortingTagButton_2->setVisible(false); m_Controls->deleteSortingTagButton_2->setVisible(false); m_Controls->InternalDataTreeView->setSortingEnabled(true); m_Controls->InternalDataTreeView->setSelectionBehavior(QAbstractItemView::SelectRows); m_Controls->InternalDataTreeView->setModel(m_LocalModel); connect(m_Controls->deleteButton,SIGNAL(clicked()),this,SLOT(OnDeleteButtonClicked())); connect(m_Controls->CancelButton, SIGNAL(clicked()), this , SLOT(OnCancelButtonClicked())); connect(m_Controls->viewInternalDataButton, SIGNAL(clicked()), this , SLOT(OnViewButtonClicked())); connect(m_Controls->SearchOption, SIGNAL(parameterChanged()), this, SLOT(OnSearchParameterChanged())); } } void QmitkDicomLocalStorageWidget::StartDicomImport(const QString& dicomData) { if (m_Watcher.isRunning()){ m_Watcher.waitForFinished(); } SetupProgressDialog(); m_Future = QtConcurrent::run(this,(void (QmitkDicomLocalStorageWidget::*)(const QString&)) &QmitkDicomLocalStorageWidget::AddDICOMData,dicomData); m_Watcher.setFuture(m_Future); } void QmitkDicomLocalStorageWidget::StartDicomImport(const QStringList& dicomData) { - mitk::ProgressBar::GetInstance()->AddStepsToDo(dicomData.count()); + //mitk::ProgressBar::GetInstance()->AddStepsToDo(dicomData.count()); if (m_Watcher.isRunning()) { m_Watcher.waitForFinished(); } m_Future = QtConcurrent::run(this,(void (QmitkDicomLocalStorageWidget::*)(const QStringList&)) &QmitkDicomLocalStorageWidget::AddDICOMData,dicomData); m_Watcher.setFuture(m_Future); } void QmitkDicomLocalStorageWidget::AddDICOMData(const QString& directory) { if(m_LocalDatabase->isOpen()) { m_LocalIndexer->addDirectory(*m_LocalDatabase,directory,m_LocalDatabase->databaseDirectory()); } m_LocalModel->setDatabase(m_LocalDatabase->database()); emit FinishedImport(directory); } void QmitkDicomLocalStorageWidget::AddDICOMData(const QStringList& patientFiles) { if(m_LocalDatabase->isOpen()) { QStringListIterator fileIterator(patientFiles); while(fileIterator.hasNext()) { m_LocalIndexer->addFile(*m_LocalDatabase,fileIterator.next(),m_LocalDatabase->databaseDirectory()); - mitk::ProgressBar::GetInstance()->Progress(); + //mitk::ProgressBar::GetInstance()->Progress(); } } m_LocalModel->setDatabase(m_LocalDatabase->database()); emit FinishedImport(patientFiles); } void QmitkDicomLocalStorageWidget::SetupProgressDialog() { m_ProgressDialog = new QProgressDialog("DICOM Import", "Cancel", 0, 100, this,Qt::WindowTitleHint | Qt::WindowSystemMenuHint); m_ProgressDialogLabel = new QLabel(tr("Initialization...")); m_ProgressDialog->setLabel(m_ProgressDialogLabel); #ifdef Q_WS_MAC // BUG: avoid deadlock of dialogs on mac m_ProgressDialog->setWindowModality(Qt::NonModal); #else m_ProgressDialog->setWindowModality(Qt::ApplicationModal); #endif m_ProgressDialog->setMinimumDuration(0); m_ProgressDialog->setValue(0); m_ProgressDialog->show(); connect(m_ProgressDialog, SIGNAL(canceled()), m_LocalIndexer, SLOT(cancel())); connect(m_LocalIndexer, SIGNAL(indexingFilePath(QString)), m_ProgressDialogLabel, SLOT(setText(QString))); connect(m_LocalIndexer, SIGNAL(progress(int)), m_ProgressDialog, SLOT(setValue(int))); connect(m_LocalIndexer, SIGNAL(progress(int)), this, SLOT(OnProgress(int))); } void QmitkDicomLocalStorageWidget::OnProgress(int progress) { Q_UNUSED(progress); QApplication::processEvents(); } void QmitkDicomLocalStorageWidget::OnDeleteButtonClicked() { QModelIndex currentIndex = m_Controls->InternalDataTreeView->currentIndex(); QString currentUID = m_LocalModel->data(currentIndex,ctkDICOMModel::UIDRole).toString(); if(m_LocalModel->data(currentIndex,ctkDICOMModel::TypeRole)==static_cast(ctkDICOMModel::SeriesType)) { m_LocalDatabase->removeSeries(currentUID); } else if(m_LocalModel->data(currentIndex,ctkDICOMModel::TypeRole)==static_cast(ctkDICOMModel::StudyType)) { m_LocalDatabase->removeStudy(currentUID); } else if(m_LocalModel->data(currentIndex,ctkDICOMModel::TypeRole)==static_cast(ctkDICOMModel::PatientType)) { m_LocalDatabase->removePatient(currentUID); } m_LocalModel->reset(); } void QmitkDicomLocalStorageWidget::OnCancelButtonClicked() { m_Watcher.cancel(); m_Watcher.waitForFinished(); m_LocalDatabase->closeDatabase(); } void QmitkDicomLocalStorageWidget::OnViewButtonClicked() { QModelIndex currentIndex = m_Controls->InternalDataTreeView->currentIndex(); if(m_LocalModel->data(currentIndex,ctkDICOMModel::TypeRole)==static_cast(ctkDICOMModel::SeriesType)) { QString seriesUID = m_LocalModel->data(currentIndex,ctkDICOMModel::UIDRole).toString(); QString seriesName = m_LocalModel->data(currentIndex).toString(); QModelIndex studyIndex = m_LocalModel->parent(currentIndex); QString studyUID = m_LocalModel->data(studyIndex,ctkDICOMModel::UIDRole).toString(); QString studyName = m_LocalModel->data(studyIndex).toString(); QModelIndex patientIndex = m_LocalModel->parent(studyIndex); - QString patientName = m_LocalModel->data(patientIndex).toString(); + QString patientName = m_LocalModel->data(patientIndex).toString(); QString filePath; filePath.append(m_LocalDatabase->databaseDirectory()); filePath.append("/dicom/"); filePath.append(studyUID); filePath.append("/"); filePath.append(seriesUID); filePath.append("/"); QStringList eventProperties; eventProperties << patientName << studyUID <setDatabase(m_LocalDatabase->database(),m_Controls->SearchOption->parameters()); } void QmitkDicomLocalStorageWidget::SetDatabaseDirectory(QString newDatatbaseDirectory) { QDir databaseDirecory = QDir(newDatatbaseDirectory); if(!databaseDirecory.exists()) { databaseDirecory.mkpath(databaseDirecory.absolutePath()); } QString newDatatbaseFile = databaseDirecory.absolutePath() + QString("/ctkDICOM.sql"); this->SetDatabase(newDatatbaseFile); } void QmitkDicomLocalStorageWidget::SetDatabase(QString databaseFile) { m_LocalDatabase = new ctkDICOMDatabase(databaseFile); m_LocalModel->setEndLevel(ctkDICOMModel::SeriesType); m_LocalModel->setDatabase(m_LocalDatabase->database()); } diff --git a/Plugins/org.mitk.gui.qt.dicom/CMakeLists.txt b/Plugins/org.mitk.gui.qt.dicom/CMakeLists.txt index f19077c93f..82b57c1fd6 100644 --- a/Plugins/org.mitk.gui.qt.dicom/CMakeLists.txt +++ b/Plugins/org.mitk.gui.qt.dicom/CMakeLists.txt @@ -1,15 +1,22 @@ project(org_mitk_gui_qt_dicom) set(QT_USE_QTSQL 1) +set(DCMTK_INSTALL_BIN ${DCMTK_DIR}/bin) include_directories(${CTK_INCLUDE_DIRS}) -MITK_INSTALL(PROGRAMS ${VAR_STORESCP}) +find_program(MITK_STORESCP storescp PATH ${DCMTK_INSTALL_BIN}) +mark_as_advanced(MITK_STORESCP) + +configure_file( org_mitk_gui_qt_dicom_config.h.in org_mitk_gui_qt_dicom_config.h @ONLY) + +MITK_INSTALL_HELPER_APP(${MITK_STORESCP}) + MACRO_CREATE_MITK_CTK_PLUGIN( EXPORT_DIRECTIVE DICOM_EXPORT EXPORTED_INCLUDE_SUFFIXES src MODULE_DEPENDENCIES QmitkExt mitkDicomUI ) target_link_libraries(${PLUGIN_TARGET} ${CTK_LIBRARIES}) diff --git a/Plugins/org.mitk.gui.qt.dicom/org_mitk_gui_qt_dicom_config.h.in b/Plugins/org.mitk.gui.qt.dicom/org_mitk_gui_qt_dicom_config.h.in new file mode 100644 index 0000000000..6492b4438b --- /dev/null +++ b/Plugins/org.mitk.gui.qt.dicom/org_mitk_gui_qt_dicom_config.h.in @@ -0,0 +1,3 @@ +// Generated file, do not edit! + +#define MITK_STORESCP "@MITK_STORESCP@" \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.dicom/src/internal/QmitkDicomDirectoryListener.cpp b/Plugins/org.mitk.gui.qt.dicom/src/internal/QmitkDicomDirectoryListener.cpp index 07de69a223..ab81bf5345 100644 --- a/Plugins/org.mitk.gui.qt.dicom/src/internal/QmitkDicomDirectoryListener.cpp +++ b/Plugins/org.mitk.gui.qt.dicom/src/internal/QmitkDicomDirectoryListener.cpp @@ -1,116 +1,141 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "QmitkDicomDirectoryListener.h" #include #include #include #include +#include QmitkDicomDirectoryListener::QmitkDicomDirectoryListener() : m_FileSystemWatcher(new QFileSystemWatcher()) +, m_IsListening(true) { - connect(m_FileSystemWatcher,SIGNAL(directoryChanged(const QString&)),this,SLOT(OnDirectoryChanged(const QString&))); + connect(m_FileSystemWatcher,SIGNAL(directoryChanged(const QString&)),this,SLOT(OnDirectoryChanged(const QString&))); } QmitkDicomDirectoryListener::~QmitkDicomDirectoryListener() { + m_IsListening = false; + RemoveTemporaryFiles(); delete m_FileSystemWatcher; } - void QmitkDicomDirectoryListener::OnDirectoryChanged(const QString&) -{ - SetFilesToImport(); - m_ImportingFiles.append(m_FilesToImport); - emit SignalAddDicomData(m_FilesToImport); -} - -void QmitkDicomDirectoryListener::OnDicomImportFinished(const QStringList& finishedFiles) { - RemoveFilesFromDirectoryAndImportingFilesList(finishedFiles); -} - -void QmitkDicomDirectoryListener::SetFilesToImport() -{ - m_FilesToImport.clear(); - QDir listenerDirectory(m_DicomListenerDirectory); - QFileInfoList entries = listenerDirectory.entryInfoList(QDir::Files); - if(!entries.isEmpty()) + if(m_IsListening) { - QFileInfoList::const_iterator file; - for(file = entries.constBegin(); file != entries.constEnd(); ++file ) + QDirIterator it( m_DicomListenerDirectory.absolutePath() , QDir::Files , QDirIterator::Subdirectories); + QString currentPath; + + m_FilesToImport.clear(); + while(it.hasNext()) { - if(!m_ImportingFiles.contains((*file).absoluteFilePath())) + it.next(); + currentPath = it.fileInfo().absoluteFilePath(); + if(!m_AlreadyImportedFiles.contains(currentPath)) { - m_FilesToImport.append((*file).absoluteFilePath()); + m_AlreadyImportedFiles.insert( currentPath , currentPath ); + m_FilesToImport.append(currentPath); } } - } + if(!m_FilesToImport.isEmpty()) + { + emit SignalAddDicomData(m_FilesToImport); + } + } } -void QmitkDicomDirectoryListener::RemoveFilesFromDirectoryAndImportingFilesList(const QStringList& files) +void QmitkDicomDirectoryListener::OnImportFinished(const QStringList& files) { - QStringListIterator fileToDeleteIterator(files); - while(fileToDeleteIterator.hasNext()) + m_IsListening = false; + RemoveTemporaryFiles(files); + RemoveAlreadyImportedEntries(files); + m_IsListening = true; +} + +void QmitkDicomDirectoryListener::OnDicomNetworkError(const QString& errorMsg) +{ + m_IsListening = false; + m_AlreadyImportedFiles.clear(); +} + +void QmitkDicomDirectoryListener::RemoveAlreadyImportedEntries(const QStringList& fileEntries) +{ + QStringListIterator it(fileEntries); + QString currentEntry; + while(it.hasNext()) { - QFile file(fileToDeleteIterator.next()); - if(m_ImportingFiles.contains(file.fileName())) + currentEntry = m_DicomListenerDirectory.absoluteFilePath(it.next()); + if(m_AlreadyImportedFiles.contains(currentEntry)) { - m_ImportingFiles.removeOne(file.fileName()); - file.remove(); + m_AlreadyImportedFiles.remove(currentEntry); } } } -void QmitkDicomDirectoryListener::SetDicomListenerDirectory(const QString& directory) +void QmitkDicomDirectoryListener::RemoveTemporaryFiles(const QStringList& fileEntries) { - if(isOnlyListenedDirectory(directory)) + QStringListIterator it(fileEntries); + QString currentEntry; + while(it.hasNext()) { - QDir listenerDirectory = QDir(directory); - CreateListenerDirectory(listenerDirectory); - - m_DicomListenerDirectory=listenerDirectory.absolutePath(); - m_FileSystemWatcher->addPath(m_DicomListenerDirectory); - MITK_INFO << m_DicomListenerDirectory.toStdString(); + currentEntry = m_DicomListenerDirectory.absoluteFilePath(it.next()); + m_DicomListenerDirectory.remove(currentEntry); } } -const QString& QmitkDicomDirectoryListener::GetDicomListenerDirectory() +void QmitkDicomDirectoryListener::RemoveTemporaryFiles() { - return m_DicomListenerDirectory; -} - -void QmitkDicomDirectoryListener::CreateListenerDirectory(const QDir& directory) -{ - if(!directory.exists()) + QDirIterator it( m_DicomListenerDirectory.absolutePath() , QDir::AllEntries , QDirIterator::Subdirectories); + while(it.hasNext()) { - directory.mkpath(directory.absolutePath()); + it.next(); + m_DicomListenerDirectory.remove(it.fileInfo().absoluteFilePath()); } } -bool QmitkDicomDirectoryListener::isOnlyListenedDirectory(const QString& directory) +void QmitkDicomDirectoryListener::SetDicomListenerDirectory(const QString& directory) { - bool isOnlyListenedDirectory = false; - if(m_FileSystemWatcher->directories().count()==0||m_FileSystemWatcher->directories().count()==1) + QDir dir(directory); + if(dir.exists()) { - if(!m_FileSystemWatcher->directories().contains(directory)) - { - isOnlyListenedDirectory = true; - } + m_DicomListenerDirectory=dir; + m_FileSystemWatcher->addPath(m_DicomListenerDirectory.absolutePath()); } - return isOnlyListenedDirectory; -} \ No newline at end of file + else + { + dir.mkpath(directory); + m_DicomListenerDirectory=dir; + m_FileSystemWatcher->addPath(m_DicomListenerDirectory.absolutePath()); + } +} + +QString QmitkDicomDirectoryListener::GetDicomListenerDirectory() +{ + return m_DicomListenerDirectory.absolutePath(); +} + +bool QmitkDicomDirectoryListener::IsListening() +{ + return m_IsListening; +} + +void QmitkDicomDirectoryListener::SetListening(bool listening) +{ + m_IsListening = listening; +} diff --git a/Plugins/org.mitk.gui.qt.dicom/src/internal/QmitkDicomDirectoryListener.h b/Plugins/org.mitk.gui.qt.dicom/src/internal/QmitkDicomDirectoryListener.h index 010cda4e90..25e58bcb6f 100644 --- a/Plugins/org.mitk.gui.qt.dicom/src/internal/QmitkDicomDirectoryListener.h +++ b/Plugins/org.mitk.gui.qt.dicom/src/internal/QmitkDicomDirectoryListener.h @@ -1,78 +1,95 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef QmitkDicomDirectoryListener_h #define QmitkDicomDirectoryListener_h #include #include +#include #include #include #include #include class QmitkDicomDirectoryListener : public QObject { Q_OBJECT public: QmitkDicomDirectoryListener(); - + virtual ~QmitkDicomDirectoryListener(); /// @brief sets listened directory, note that only one directory can be set. void SetDicomListenerDirectory(const QString&); /// @brief get filepath to the listened directory. - const QString& GetDicomListenerDirectory(); + QString GetDicomListenerDirectory(); + + /// @brief get the status whether the directorey listener is listening or not. + bool IsListening(); + + /// @brief set the directory listener listening. + void SetListening(bool listening); signals: /// @brief signal starts the dicom import of the given file (the QStringList will only contain one file here). void SignalAddDicomData(const QStringList&); public slots: /// \brief called when listener directory changes void OnDirectoryChanged(const QString&); - /// \brief called when import is finished - void OnDicomImportFinished(const QStringList&); + /// \brief called when error occours during dicom store request + void OnDicomNetworkError(const QString&); + /// \brief called when import of files is finished. + void OnImportFinished(const QStringList&); protected: - /// \brief creates directory if it's not already existing. + /// \brief creates directory if it's not already existing. void CreateListenerDirectory(const QDir& directory); - /// \brief checks wheter the given directory is the only directory that is listened. - bool isOnlyListenedDirectory(const QString& directory); - - /// \brief Composes the filename and initializes m_LastRetrievedFile with it + /// \brief Composes the filename and initializes m_LastRetrievedFile with it. void SetFilesToImport(); - /// \brief removes files from - void RemoveFilesFromDirectoryAndImportingFilesList(const QStringList& files); + /// \brief removes files from listener directory. + void RemoveTemporaryFiles(); + + /// \brief removes files in the files list from listener directory. + void RemoveTemporaryFiles(const QStringList& files); + + /// \brief removes entries from m_AlreadyImportedFiles hash table. + void RemoveAlreadyImportedEntries(const QStringList& files); QFileSystemWatcher* m_FileSystemWatcher; + QStringList m_FilesToImport; - QStringList m_ImportingFiles; - QString m_DicomListenerDirectory; + + QHash m_AlreadyImportedFiles; + + QDir m_DicomListenerDirectory; + + bool m_IsListening; }; #endif // QmitkDicomListener_h \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.dicom/src/internal/QmitkDicomEditor.cpp b/Plugins/org.mitk.gui.qt.dicom/src/internal/QmitkDicomEditor.cpp index b2039387f9..d606b6fafc 100644 --- a/Plugins/org.mitk.gui.qt.dicom/src/internal/QmitkDicomEditor.cpp +++ b/Plugins/org.mitk.gui.qt.dicom/src/internal/QmitkDicomEditor.cpp @@ -1,249 +1,250 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ // Blueberry #include #include #include #include #include #include #include #include #include "berryFileEditorInput.h" // Qmitk #include "QmitkDicomEditor.h" #include "mitkPluginActivator.h" #include //#include "mitkProgressBar.h" // Qt #include #include #include #include #include #include #include #include #include #include #include #include #include #include //CTK #include #include #include #include #include const std::string QmitkDicomEditor::EDITOR_ID = "org.mitk.editors.dicomeditor"; QmitkDicomEditor::QmitkDicomEditor() : m_Thread(new QThread()) , m_DicomDirectoryListener(new QmitkDicomDirectoryListener()) , m_StoreSCPLauncher(new QmitkStoreSCPLauncher(&m_Builder)) , m_Publisher(new QmitkDicomDataEventPublisher()) { } QmitkDicomEditor::~QmitkDicomEditor() { m_Thread->quit(); m_Thread->wait(1000); delete m_Handler; delete m_Publisher; delete m_StoreSCPLauncher; delete m_Thread; delete m_DicomDirectoryListener; } void QmitkDicomEditor::CreateQtPartControl(QWidget *parent ) { m_Controls.setupUi( parent ); m_Controls.LocalStorageButton->setIcon(QIcon(":/org.mitk.gui.qt.dicom/drive-harddisk_32.png")); m_Controls.FolderButton->setIcon(QIcon(":/org.mitk.gui.qt.dicom/folder_32.png")); m_Controls.CDButton->setIcon(QIcon(":/org.mitk.gui.qt.dicom/media-optical_32.png")); m_Controls.QueryRetrieveButton->setIcon(QIcon(":/org.mitk.gui.qt.dicom/network-workgroup_32.png")); m_Controls.StoreSCPStatusLabel->setTextFormat(Qt::RichText); m_Controls.StoreSCPStatusLabel->setText(""); TestHandler(); SetPluginDirectory(); SetDatabaseDirectory("DatabaseDirectory"); SetListenerDirectory("ListenerDirectory"); StartDicomDirectoryListener(); m_Controls.m_ctkDICOMQueryRetrieveWidget->useProgressDialog(true); connect(m_Controls.externalDataWidget,SIGNAL(SignalAddDicomData(const QString&)),m_Controls.internalDataWidget,SLOT(StartDicomImport(const QString&))); connect(m_Controls.externalDataWidget,SIGNAL(SignalAddDicomData(const QStringList&)),m_Controls.internalDataWidget,SLOT(StartDicomImport(const QStringList&))); connect(m_Controls.externalDataWidget,SIGNAL(SignalDicomToDataManager(const QStringList&)),this,SLOT(OnViewButtonAddToDataManager(const QStringList&))); connect(m_Controls.externalDataWidget,SIGNAL(SignalChangePage(int)), this, SLOT(OnChangePage(int))); connect(m_Controls.internalDataWidget,SIGNAL(FinishedImport(const QString&)),this,SLOT(OnDicomImportFinished(const QString&))); connect(m_Controls.internalDataWidget,SIGNAL(FinishedImport(const QStringList&)),this,SLOT(OnDicomImportFinished(const QStringList&))); connect(m_Controls.internalDataWidget,SIGNAL(SignalDicomToDataManager(const QStringList&)),this,SLOT(OnViewButtonAddToDataManager(const QStringList&))); connect(m_Controls.CDButton, SIGNAL(clicked()), m_Controls.externalDataWidget, SLOT(OnFolderCDImport())); connect(m_Controls.FolderButton, SIGNAL(clicked()), m_Controls.externalDataWidget, SLOT(OnFolderCDImport())); connect(m_Controls.FolderButton, SIGNAL(clicked()), this, SLOT(OnFolderCDImport())); connect(m_Controls.QueryRetrieveButton, SIGNAL(clicked()), this, SLOT(OnQueryRetrieve())); connect(m_Controls.LocalStorageButton, SIGNAL(clicked()), this, SLOT(OnLocalStorage())); - - //connect(m_Controls.radioButton,SIGNAL(clicked()),this,SLOT(StartStopStoreSCP())); } void QmitkDicomEditor::Init(berry::IEditorSite::Pointer site, berry::IEditorInput::Pointer input) { this->SetSite(site); this->SetInput(input); } void QmitkDicomEditor::SetFocus() { } berry::IPartListener::Events::Types QmitkDicomEditor::GetPartEventTypes() const { return Events::CLOSED | Events::HIDDEN | Events::VISIBLE; } void QmitkDicomEditor::OnQueryRetrieve() { OnChangePage(2); QString storagePort = m_Controls.m_ctkDICOMQueryRetrieveWidget->getServerParameters()["StoragePort"].toString(); QString storageAET = m_Controls.m_ctkDICOMQueryRetrieveWidget->getServerParameters()["StorageAETitle"].toString(); if(!((m_Builder.GetAETitle()->compare(storageAET,Qt::CaseSensitive)==0)&& (m_Builder.GetPort()->compare(storagePort,Qt::CaseSensitive)==0))) { StopStoreSCP(); StartStoreSCP(); } } void QmitkDicomEditor::OnFolderCDImport() { } void QmitkDicomEditor::OnLocalStorage() { OnChangePage(0); } void QmitkDicomEditor::OnChangePage(int page) { try{ m_Controls.stackedWidget->setCurrentIndex(page); }catch(std::exception e){ MITK_ERROR <<"error: "<< e.what(); return; } } void QmitkDicomEditor::OnDicomImportFinished(const QString&) { } void QmitkDicomEditor::OnDicomImportFinished(const QStringList&) { } void QmitkDicomEditor::StartDicomDirectoryListener() { if(!m_Thread->isRunning()) { m_DicomDirectoryListener->SetDicomListenerDirectory(m_ListenerDirectory); connect(m_DicomDirectoryListener,SIGNAL(SignalAddDicomData(const QStringList&)),m_Controls.internalDataWidget,SLOT(StartDicomImport(const QStringList&)),Qt::DirectConnection); - connect(m_Controls.internalDataWidget,SIGNAL(FinishedImport(const QStringList&)),m_DicomDirectoryListener,SLOT(OnDicomImportFinished(const QStringList&)),Qt::DirectConnection); + connect(m_Controls.internalDataWidget,SIGNAL(FinishedImport(const QStringList&)),m_DicomDirectoryListener,SLOT(OnImportFinished(const QStringList&)),Qt::DirectConnection); m_DicomDirectoryListener->moveToThread(m_Thread); m_Thread->start(); } } void QmitkDicomEditor::TestHandler() { m_Handler = new DicomEventHandler(); m_Handler->SubscribeSlots(); } void QmitkDicomEditor::OnViewButtonAddToDataManager(const QStringList& eventProperties) { ctkDictionary properties; properties["PatientName"] = eventProperties.at(0); properties["StudyUID"] = eventProperties.at(1); properties["StudyName"] = eventProperties.at(2); properties["SeriesUID"] = eventProperties.at(3); properties["SeriesName"] = eventProperties.at(4); properties["Path"] = eventProperties.at(5); m_Publisher->PublishSignals(mitk::PluginActivator::getContext()); m_Publisher->AddSeriesToDataManagerEvent(properties); } void QmitkDicomEditor::StartStoreSCP() { QString storagePort = m_Controls.m_ctkDICOMQueryRetrieveWidget->getServerParameters()["StoragePort"].toString(); QString storageAET = m_Controls.m_ctkDICOMQueryRetrieveWidget->getServerParameters()["StorageAETitle"].toString(); m_Builder.AddPort(storagePort)->AddAETitle(storageAET)->AddTransferSyntax()->AddOtherNetworkOptions()->AddMode()->AddOutputDirectory(m_ListenerDirectory); m_StoreSCPLauncher = new QmitkStoreSCPLauncher(&m_Builder); connect(m_StoreSCPLauncher, SIGNAL(SignalStatusOfStoreSCP(const QString&)), this, SLOT(OnStoreSCPStatusChanged(const QString&))); + connect(m_StoreSCPLauncher ,SIGNAL(SignalStartImport(const QStringList&)),m_Controls.internalDataWidget,SLOT(StartDicomImport(const QStringList&))); + connect(m_StoreSCPLauncher ,SIGNAL(SignalStoreSCPError(const QString&)),m_Controls.internalDataWidget,SLOT(OnCancelButtonClicked())); + connect(m_StoreSCPLauncher ,SIGNAL(SignalStoreSCPError(const QString&)),m_DicomDirectoryListener,SLOT(OnDicomNetworkError(const QString&)),Qt::DirectConnection); m_StoreSCPLauncher->StartStoreSCP(); } void QmitkDicomEditor::OnStoreSCPStatusChanged(const QString& status) { m_Controls.StoreSCPStatusLabel->setText(" "+status); } void QmitkDicomEditor::StopStoreSCP() { delete m_StoreSCPLauncher; } void QmitkDicomEditor::SetPluginDirectory() { m_PluginDirectory = mitk::PluginActivator::getContext()->getDataFile("").absolutePath(); m_PluginDirectory.append("/"); } void QmitkDicomEditor::SetDatabaseDirectory(const QString& databaseDirectory) { m_DatabaseDirectory.clear(); m_DatabaseDirectory.append(m_PluginDirectory); m_DatabaseDirectory.append(databaseDirectory); m_Controls.internalDataWidget->SetDatabaseDirectory(m_DatabaseDirectory); } void QmitkDicomEditor::SetListenerDirectory(const QString& listenerDirectory) { m_ListenerDirectory.clear(); m_ListenerDirectory.append(m_PluginDirectory); m_ListenerDirectory.append(listenerDirectory); } diff --git a/Plugins/org.mitk.gui.qt.dicom/src/internal/QmitkStoreSCPLauncher.cpp b/Plugins/org.mitk.gui.qt.dicom/src/internal/QmitkStoreSCPLauncher.cpp index 9ae32ca814..7c1a87a504 100644 --- a/Plugins/org.mitk.gui.qt.dicom/src/internal/QmitkStoreSCPLauncher.cpp +++ b/Plugins/org.mitk.gui.qt.dicom/src/internal/QmitkStoreSCPLauncher.cpp @@ -1,146 +1,215 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "QmitkStoreSCPLauncher.h" -#include #include #include #include #include #include #include #include #include #include +#include #include +#include "org_mitk_gui_qt_dicom_config.h" QmitkStoreSCPLauncher::QmitkStoreSCPLauncher(QmitkStoreSCPLauncherBuilder* builder) : m_StoreSCP(new QProcess()) { connect( m_StoreSCP, SIGNAL(error(QProcess::ProcessError)),this, SLOT(OnProcessError(QProcess::ProcessError))); connect( m_StoreSCP, SIGNAL(stateChanged(QProcess::ProcessState)),this, SLOT(OnStateChanged(QProcess::ProcessState))); + //connect( m_StoreSCP, SIGNAL(readyReadStandardError()),this, SLOT(OnReadyProcessError())); + connect( m_StoreSCP, SIGNAL(readyReadStandardOutput()),this, SLOT(OnReadyProcessOutput())); SetArgumentList(builder); + //m_StoreSCP->setStandardOutputFile("OutputLog.log"); + //m_StoreSCP->setStandardErrorFile("ErrorLog.log"); } QmitkStoreSCPLauncher::~QmitkStoreSCPLauncher() { m_StoreSCP->close(); m_StoreSCP->waitForFinished(1000); + DeleteTemporaryData(); delete m_StoreSCP; } void QmitkStoreSCPLauncher::StartStoreSCP() { FindPathToStoreSCP(); MITK_INFO << m_PathToStoreSCP.toStdString(); MITK_INFO << m_ArgumentList[7].toStdString(); m_StoreSCP->start(m_PathToStoreSCP,m_ArgumentList); } void QmitkStoreSCPLauncher::FindPathToStoreSCP() { QString appPath= QCoreApplication::applicationDirPath(); if(m_PathToStoreSCP.isEmpty()) { QString fileName; #ifdef _WIN32 - - appPath.append("/../../../DCMTK-install/bin"); fileName = "/storescp.exe"; #else - appPath.append("/../../DCMTK-install/bin"); fileName = "/storescp"; #endif - m_PathToStoreSCP.clear(); - m_PathToStoreSCP.append(fileName); + + m_PathToStoreSCP = fileName; //In developement the storescp isn't copied into bin directory if(!QFile::exists(m_PathToStoreSCP)) { - m_PathToStoreSCP = appPath; - m_PathToStoreSCP.append(fileName); + m_PathToStoreSCP = static_cast(MITK_STORESCP); + } + } +} + +void QmitkStoreSCPLauncher::OnReadyProcessOutput() +{ + QString out(m_StoreSCP->readAllStandardOutput()); + QStringList allDataList,importList; + + allDataList = out.split("\n",QString::SkipEmptyParts); + QStringListIterator it(allDataList); + + while(it.hasNext()) + { + QString output = it.next(); + if (output.contains("E: ")) + { + output.replace("E: ",""); + m_ErrorText = output; + OnProcessError(QProcess::UnknownError); + return; + } + if(output.contains("I: storing DICOM file: ")) + { + output.replace("I: storing DICOM file: ",""); + importList += output; } } + if(!importList.isEmpty()) + { + emit SignalStartImport(importList); + } } void QmitkStoreSCPLauncher::OnProcessError(QProcess::ProcessError err) { switch(err) { case QProcess::FailedToStart: - m_ErrorText = QString("Failed to start storage provider: ").append(m_StoreSCP->errorString()); + m_ErrorText.prepend("Failed to start storage provider: "); + m_ErrorText.append(m_StoreSCP->errorString()); + emit SignalStoreSCPError(m_ErrorText); + m_ErrorText.clear(); break; case QProcess::Crashed: - m_ErrorText = QString("Storage provider crashed: ").append(m_StoreSCP->errorString()); + m_ErrorText.prepend("Storage provider crashed: "); + m_ErrorText.append(m_StoreSCP->errorString()); + emit SignalStoreSCPError(m_ErrorText); + m_ErrorText.clear(); break; case QProcess::Timedout: - m_ErrorText = QString("Storage provider timeout: ").append(m_StoreSCP->errorString()); + m_ErrorText.prepend("Storage provider timeout: "); + m_ErrorText.append(m_StoreSCP->errorString()); + emit SignalStoreSCPError(m_ErrorText); + m_ErrorText.clear(); break; case QProcess::WriteError: - m_ErrorText = QString("Storage provider write error: ").append(m_StoreSCP->errorString()); + m_ErrorText.prepend("Storage provider write error: "); + m_ErrorText.append(m_StoreSCP->errorString()); + emit SignalStoreSCPError(m_ErrorText); + m_ErrorText.clear(); break; case QProcess::ReadError: - m_ErrorText = QString("Storage provider read error: ").append(m_StoreSCP->errorString()); + m_ErrorText.prepend("Storage provider read error: "); + m_ErrorText.append(m_StoreSCP->errorString()); + emit SignalStoreSCPError(m_ErrorText); + m_ErrorText.clear(); break; case QProcess::UnknownError: - m_ErrorText = QString("Storage provider unknown error: ").append(m_StoreSCP->errorString()); + m_ErrorText.prepend("Storage provider unknown error: "); + m_ErrorText.append(m_StoreSCP->errorString()); + emit SignalStoreSCPError(m_ErrorText); + m_ErrorText.clear(); break; default: - m_ErrorText = QString("Storage provider unknown error: ").append(m_StoreSCP->errorString()); + m_ErrorText.prepend("Storage provider unknown error: "); + m_ErrorText.append(m_StoreSCP->errorString()); + emit SignalStoreSCPError(m_ErrorText); + m_ErrorText.clear(); break; } } void QmitkStoreSCPLauncher::OnStateChanged(QProcess::ProcessState status) { switch(status) { case QProcess::NotRunning: - m_StatusText = QString("Storage provider not running: "); + m_StatusText.prepend("Storage provider not running!"); emit SignalStatusOfStoreSCP(m_StatusText); + m_StatusText.clear(); break; case QProcess::Starting: - m_StatusText = QString("Starting ").append(m_ArgumentList[2]).append(" on port ").append(m_ArgumentList[0]); + m_StatusText.prepend("Starting storage provider!"); emit SignalStatusOfStoreSCP(m_StatusText); + m_StatusText.clear(); break; case QProcess::Running: - m_StatusText = QString("Running ").append(m_ArgumentList[2]).append(" on port ").append(m_ArgumentList[0]);; + m_StatusText.prepend(m_ArgumentList[0]).prepend(" Port: ").prepend(m_ArgumentList[2]).prepend(" AET: ").prepend("Storage provider running! "); emit SignalStatusOfStoreSCP(m_StatusText); + m_StatusText.clear(); break; default: - m_StatusText = QString("Storage provider unknown error: "); + m_StatusText.prepend("Storage provider unknown error!"); emit SignalStatusOfStoreSCP(m_StatusText); + m_StatusText.clear(); break; } } void QmitkStoreSCPLauncher::SetArgumentList(QmitkStoreSCPLauncherBuilder* builder) { m_ArgumentList << *builder->GetPort() << QString("-aet") <<*builder->GetAETitle() << *builder->GetTransferSyntax() << *builder->GetOtherNetworkOptions() << *builder->GetMode() << QString("-od") << *builder->GetOutputDirectory(); } +void QmitkStoreSCPLauncher::DeleteTemporaryData() +{ + MITK_INFO << m_ArgumentList[7].toStdString(); + QDir dir(m_ArgumentList[7]); + QDirIterator it(dir); + while(it.hasNext()) + { + it.next(); + dir.remove(it.fileInfo().absoluteFilePath()); + } +} + QString QmitkStoreSCPLauncher::ArgumentListToQString() { QString argumentString; QStringListIterator argumentIterator(m_ArgumentList); while(argumentIterator.hasNext()) { argumentString.append(" "); argumentString.append(argumentIterator.next()); } return argumentString; } diff --git a/Plugins/org.mitk.gui.qt.dicom/src/internal/QmitkStoreSCPLauncher.h b/Plugins/org.mitk.gui.qt.dicom/src/internal/QmitkStoreSCPLauncher.h index bcfe057920..e9e9db18b7 100644 --- a/Plugins/org.mitk.gui.qt.dicom/src/internal/QmitkStoreSCPLauncher.h +++ b/Plugins/org.mitk.gui.qt.dicom/src/internal/QmitkStoreSCPLauncher.h @@ -1,51 +1,57 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef QmitkStoreSCPLauncher_h #define QmitkStoreSCPLauncher_h #include #include #include "QmitkStoreSCPLauncherBuilder.h" class QmitkStoreSCPLauncher : public QObject { Q_OBJECT public: QmitkStoreSCPLauncher(QmitkStoreSCPLauncherBuilder* builder); virtual ~QmitkStoreSCPLauncher(); public slots: void StartStoreSCP(); void OnProcessError(QProcess::ProcessError error); void OnStateChanged(QProcess::ProcessState status); + void OnReadyProcessOutput(); signals: void SignalStatusOfStoreSCP(const QString&); + void SignalStoreSCPError(const QString& errorText = ""); + void SignalStartImport(const QStringList&); + void SignalFinishedImport(); private: + void DeleteTemporaryData(); void FindPathToStoreSCP(); void SetArgumentList(QmitkStoreSCPLauncherBuilder* builder); QString ArgumentListToQString(); QString m_PathToStoreSCP; QString m_ErrorText; QString m_StatusText; QProcess* m_StoreSCP; QStringList m_ArgumentList; + QStringList m_ImportFilesList; }; #endif //QmitkStoreSCPLauncher_h \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.dicom/src/internal/QmitkStoreSCPLauncherBuilder.h b/Plugins/org.mitk.gui.qt.dicom/src/internal/QmitkStoreSCPLauncherBuilder.h index 1f0e532069..d59eb34bd0 100644 --- a/Plugins/org.mitk.gui.qt.dicom/src/internal/QmitkStoreSCPLauncherBuilder.h +++ b/Plugins/org.mitk.gui.qt.dicom/src/internal/QmitkStoreSCPLauncherBuilder.h @@ -1,51 +1,51 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef QmitkStoreSCPLauncherBuilder_h #define QmitkStoreSCPLauncherBuilder_h #include #include class QmitkStoreSCPLauncherBuilder : public QObject { Q_OBJECT public: QmitkStoreSCPLauncherBuilder(); virtual ~QmitkStoreSCPLauncherBuilder(); QmitkStoreSCPLauncherBuilder* AddPort(const QString& port = QString("105")); QmitkStoreSCPLauncherBuilder* AddAETitle(const QString& aeTitle = QString("STORESCP")); QmitkStoreSCPLauncherBuilder* AddTransferSyntax(const QString& transferSyntax = QString("+x=")); QmitkStoreSCPLauncherBuilder* AddOtherNetworkOptions(const QString& otherNetworkOptions = QString("-pm")); - QmitkStoreSCPLauncherBuilder* AddMode(const QString& mode = QString("-d")); + QmitkStoreSCPLauncherBuilder* AddMode(const QString& mode = QString("-v")); QmitkStoreSCPLauncherBuilder* AddOutputDirectory(const QString& outputDirectory); QString* GetPort(); QString* GetAETitle(); QString* GetTransferSyntax(); QString* GetOtherNetworkOptions(); QString* GetMode(); QString* GetOutputDirectory(); private: QString* m_Port; QString* m_AETitle; QString* m_TransferSyntax; QString* m_OtherNetworkOptions; QString* m_Mode; QString* m_OutputDirectory; }; #endif