From: tbaudier Date: Mon, 17 Oct 2016 07:14:13 +0000 (+0200) Subject: Merge branch 'vectorImage' X-Git-Tag: v1.4.0~2^2 X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=commitdiff_plain;h=9d0852ea8d1aed251f77c98d68426a49b6c52cbf;hp=85e5c2db06fc4689445dab0adbd41441eca15eaf;p=clitk.git Merge branch 'vectorImage' --- diff --git a/CMakeLists.txt b/CMakeLists.txt index f0ed562..3bb8fc5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,7 +31,7 @@ include(${CLITK_SOURCE_DIR}/cmake/dependencies.cmake) include(${CLITK_SOURCE_DIR}/cmake/build_opt.cmake) #========================================================= #========================================================= - +SET(vvPacsConnection true) # Select what is compiled add_subdirectory(${CLITK_SOURCE_DIR}/common ${PROJECT_BINARY_DIR}/common) add_subdirectory(${CLITK_SOURCE_DIR}/tools ${PROJECT_BINARY_DIR}/tools) diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 5a700ac..e17c4dc 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -67,7 +67,7 @@ endif(CLITK_MEMORY_INFO) if(CLITK_USE_SYSTEM_GDCM) find_package(GDCM REQUIRED) include(${GDCM_USE_FILE}) - target_link_libraries(clitkCommon vtkgdcm gdcmDICT gdcmMSFF) + target_link_libraries(clitkCommon vtkgdcm gdcmDICT gdcmMSFF gdcmMEXD) endif() #========================================================= diff --git a/common/clitkConfiguration.h.in b/common/clitkConfiguration.h.in index b6a8e79..8080206 100644 --- a/common/clitkConfiguration.h.in +++ b/common/clitkConfiguration.h.in @@ -25,6 +25,7 @@ #cmakedefine01 CLITK_MEMORY_INFO #cmakedefine01 CLITK_PRIVATE_FEATURES #cmakedefine01 CLITK_USE_SYSTEM_GDCM +#cmakedefine01 CLITK_USE_PACS_CONNECTION // Global environment variables #define OS_NAME "@CMAKE_SYSTEM@" diff --git a/vv/CMakeLists.txt b/vv/CMakeLists.txt index a0a227f..f43f41a 100644 --- a/vv/CMakeLists.txt +++ b/vv/CMakeLists.txt @@ -7,8 +7,7 @@ if(COMMAND cmake_policy) cmake_policy(SET CMP0007 NEW) endif(COMMAND cmake_policy) #========================================================= - - +OPTION(CLITK_USE_PACS_CONNECTION "USE PACS CONNECTION" OFF) #========================================================= #List of vv tools to compile set(vv_TOOLS @@ -91,8 +90,8 @@ set(vv_SRCS vvSlicerManager.cxx vvSlicerManagerCommand.cxx vvUtils.cxx -# vvMaximumIntensityProjection.cxx - vvMesh.cxx +# vvMaximumIntensityProjection.cxx + vvMesh.cxx vvMeshActor.cxx vvMeshReader.cxx vvMidPosition.cxx @@ -110,7 +109,6 @@ set(vv_SRCS #========================================================= # Qt related commands - if(vv_QT_VERSION VERSION_GREATER "4") find_package(Qt5Widgets REQUIRED) find_package(Qt5Network REQUIRED) @@ -176,6 +174,28 @@ if(vv_QT_VERSION VERSION_GREATER "4") else() QT4_ADD_RESOURCES(vv_SRCS vvIcons.qrc) endif() + +# Add DICOM SERVER gui selector if the adequate GDCM is available +if(CLITK_USE_PACS_CONNECTION) + SET(vv_SRCS ${vv_SRCS} + vvQPacsConnection.cxx + vvPacsSettingsDialog.cxx + vvDicomServerQueryFactory.cxx + ) + if(vv_QT_VERSION VERSION_GREATER "4") + qt5_wrap_cpp(vv_SRCS vvQPacsConnection.h + vvPacsSettingsDialog.h) + qt5_wrap_ui(vv_UI_CXX + qt_ui/vvPacsConnection.ui + qt_ui/vvPacsSettingsDialog.ui) + else() + QT4_WRAP_CPP(vv_SRCS vvQPacsConnection.h + vvPacsSettingsDialog.h) + QT4_WRAP_UI(vv_UI_CXX + qt_ui/vvPacsConnection.ui + qt_ui/vvPacsSettingsDialog.ui) + endif() +endif(CLITK_USE_PACS_CONNECTION) # Add the autotools in the header vvToolsList.h for initialization of the dummy # variables in vv.cxx for the tools contained in vvLib diff --git a/vv/icons/basket_download.png b/vv/icons/basket_download.png new file mode 100644 index 0000000..0038c1c Binary files /dev/null and b/vv/icons/basket_download.png differ diff --git a/vv/icons/bullet_info.png b/vv/icons/bullet_info.png new file mode 100644 index 0000000..326cf65 Binary files /dev/null and b/vv/icons/bullet_info.png differ diff --git a/vv/icons/edit.png b/vv/icons/edit.png new file mode 100644 index 0000000..c97e3a3 Binary files /dev/null and b/vv/icons/edit.png differ diff --git a/vv/qt_ui/vvMainWindow.ui b/vv/qt_ui/vvMainWindow.ui index cf2371c..ec4051a 100644 --- a/vv/qt_ui/vvMainWindow.ui +++ b/vv/qt_ui/vvMainWindow.ui @@ -872,6 +872,7 @@ + @@ -1276,6 +1277,11 @@ true + + + Connect Pacs + + diff --git a/vv/qt_ui/vvPacsConnection.ui b/vv/qt_ui/vvPacsConnection.ui new file mode 100644 index 0000000..659eca3 --- /dev/null +++ b/vv/qt_ui/vvPacsConnection.ui @@ -0,0 +1,906 @@ + + + vvPacsConnection + + + + 0 + 0 + 933 + 802 + + + + + Calibri + 9 + 75 + true + + + + Form + + + + false + + + + 110 + 10 + 91 + 16 + + + + Patient ID + + + + + + 110 + 30 + 101 + 21 + + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAlwaysOff + + + false + + + + + + 10 + 40 + 75 + 23 + + + + SCAN + + + + + + 10 + 70 + 75 + 23 + + + + CLEAR + + + + + + 250 + 30 + 101 + 21 + + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAlwaysOff + + + false + + + + + false + + + + 250 + 10 + 91 + 16 + + + + Patient name + + + + + + 10 + 160 + 51 + 51 + + + + ... + + + + :/common/icons/basket_download.png:/common/icons/basket_download.png + + + + 32 + 32 + + + + + + + 90 + 140 + 311 + 271 + + + + + 11 + + + + Patients + + + + true + + + + 20 + 20 + 281 + 231 + + + + Qt::ScrollBarAlwaysOn + + + true + + + false + + + + + + + 410 + 150 + 451 + 271 + + + + + 11 + + + + Studies + + + + + 40 + 20 + 411 + 231 + + + + + + + + 110 + 450 + 281 + 311 + + + + + + + 450 + 450 + 411 + 311 + + + + + + + 90 + 430 + 321 + 341 + + + + + 11 + + + + Series + + + + + + 420 + 430 + 451 + 341 + + + + + 11 + + + + Images + + + + + false + + + + 110 + 80 + 101 + 21 + + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAlwaysOff + + + false + + + + + false + + + + 110 + 60 + 91 + 16 + + + + Physician Ref. + + + + + false + + + + 250 + 60 + 91 + 16 + + + + Study Description + + + + + false + + + + 250 + 80 + 101 + 21 + + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAlwaysOff + + + false + + + + + true + + + + 390 + 0 + 271 + 131 + + + + 0 + + + + false + + + Modalities + + + + + 0 + 10 + 264 + 72 + + + + + + + + + MR + + + true + + + + + + + CR + + + true + + + + + + + OT + + + true + + + + + + + RF + + + true + + + + + + + SC + + + true + + + + + + + CT + + + true + + + + + + + + + + + US + + + true + + + + + + + NM + + + true + + + + + + + DR + + + true + + + + + + + SR + + + true + + + + + + + XA + + + true + + + + + + + MG + + + true + + + + + + + + + false + + + All + + + true + + + + + + + + + false + + + Date + + + + + 20 + 20 + 101 + 22 + + + + + Before + + + + + After + + + + + Between + + + + + + + 130 + 20 + 110 + 22 + + + + + + + 130 + 50 + 110 + 22 + + + + + + + + + 680 + 0 + 251 + 151 + + + + 0 + + + + Network + + + + + 20 + 40 + 191 + 22 + + + + + + + Network management + + + + + 180 + 90 + 61 + 23 + + + + Save + + + + + + 0 + 0 + 179 + 120 + + + + + + + false + + + Name + + + + + + + + + + + + + false + + + Adress + + + + + + + + + + false + + + Port + + + + + + + + + + false + + + AE Title + + + + + + + + + 180 + 10 + 61 + 23 + + + + Remove + + + + + + + true + + + + 10 + 210 + 71 + 16 + + + + Import Data + + + + + true + + + + 10 + 530 + 51 + 20 + + + + Help + + + Qt::AlignCenter + + + + + + 10 + 480 + 51 + 51 + + + + ... + + + + :/common/icons/bullet_info.png:/common/icons/bullet_info.png + + + + 32 + 32 + + + + + + + 10 + 400 + 51 + 51 + + + + + + + + :/common/icons/edit.png:/common/icons/edit.png + + + + 32 + 32 + + + + + + true + + + + 20 + 450 + 41 + 21 + + + + Options + + + + + + 10 + 580 + 51 + 51 + + + + ... + + + + :/common/icons/standardbutton-cancel-16.png:/common/icons/standardbutton-cancel-16.png + + + + 32 + 32 + + + + + + true + + + + 10 + 630 + 51 + 20 + + + + Exit + + + Qt::AlignCenter + + + groupBox_4 + groupBox_3 + label_ID + patientID + scanButton + clearButton + patientName + label_NAME + importButton + groupBox + groupBox_2 + seriesTreeView + imagesTreeView + text_PHYS + label_PHYS + label_SDESC + text_SDESC + tabFilter + tabNetwork + label_2 + label_help + helpButton + optionsButton + label_email_2 + exitButton + label_exit + + + scanButton + patientID + clearButton + patientName + importButton + seriesTreeView + imagesTreeView + text_PHYS + text_SDESC + tabFilter + tabNetwork + helpButton + optionsButton + patientTreeView + studyTreeView + check_MR + check_CR + check_OT + check_RF + check_SC + check_CT + check_US + check_NM + check_DR + check_SR + check_XA + check_MG + check_ModAll + comboDate + dateEdit + dateBetweenEdit + networkCombo + NetworkButton + NameEdit + AETitleEdit + AdressEdit + PortEdit + removeNetworkButton + + + + + + diff --git a/vv/qt_ui/vvPacsSettingsDialog.ui b/vv/qt_ui/vvPacsSettingsDialog.ui new file mode 100644 index 0000000..a64e15d --- /dev/null +++ b/vv/qt_ui/vvPacsSettingsDialog.ui @@ -0,0 +1,132 @@ + + + vvPacsSettingsDialog + + + + 0 + 0 + 400 + 201 + + + + PACS settings + + + + + 40 + 160 + 341 + 32 + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + 20 + 20 + 361 + 120 + + + + + + + false + + + Name + + + + + + + + + + + + + false + + + Adress + + + + + + + + + + false + + + Port + + + + + + + + + + false + + + AE Title + + + + + + + + + + buttonBox + accepted() + vvPacsSettingsDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + vvPacsSettingsDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/vv/vv.cxx b/vv/vv.cxx index c0ad009..2502866 100644 --- a/vv/vv.cxx +++ b/vv/vv.cxx @@ -53,6 +53,7 @@ #include #include #include +#pragma comment(lib, "ws2_32.lib") typedef enum {O_BASE,O_OVERLAY,O_FUSION,O_VF,O_CONTOUR,O_LANDMARKS} OpenModeType; typedef enum {P_NORMAL,P_SEQUENCE,P_WINDOW,P_LEVEL} ParseModeType; diff --git a/vv/vvDicomServerQueryFactory.cxx b/vv/vvDicomServerQueryFactory.cxx new file mode 100644 index 0000000..1e31f24 --- /dev/null +++ b/vv/vvDicomServerQueryFactory.cxx @@ -0,0 +1,175 @@ +#include "vvDicomServerQueryFactory.h" + + +gdcm::SmartPointer vvDicomServerQueryFactory::composeQuerySeries( std::vector< std::pair > keys ) +{ + gdcm::EQueryLevel theLevel = gdcm::eSeries; + gdcm::ERootType theRoot = gdcm::ePatientRootType;//ePatientRootType; + return gdcm::CompositeNetworkFunctions::ConstructQuery(theRoot, theLevel ,keys); +} + + +vvQuery vvDicomServerQueryFactory::getQueryforStudy(const std::string patient_id, bool bdisplay) +{ + vvQuery query; + query.keys = getQueryKeysforStudy( patient_id, bdisplay); + query.theRoot = gdcm::ePatientRootType; + query.theLevel = gdcm::eStudy; + m_query = getQueryPatient("",patient_id); + return query; +} + +std::vector< std::pair > vvDicomServerQueryFactory::getQueryKeysforStudy(const std::string patient_id, bool bdisplay) +{ + std::vector< std::pair > keys; + + + // Study Description + gdcm::Tag tagsdc(0x0008,0x1030); + keys.push_back(std::make_pair(tagsdc, "")); + // Study date + gdcm::Tag tagdb(0x0008,0x0020); + keys.push_back(std::make_pair(tagdb, "")); + // Study Hour + gdcm::Tag tagsdh(0x0008,0x0030); + keys.push_back(std::make_pair(tagsdh, "")); + + // Study UID + gdcm::Tag tagsid(0x020,0x000d); + keys.push_back(std::make_pair(tagsid, "")); + + if (!bdisplay) + { + // Patient ID + gdcm::Tag tagsd(0x0010,0x0020); + keys.push_back(std::make_pair(tagsd, patient_id)); + } + + return keys; +} + +vvQuery vvDicomServerQueryFactory::getQueryforImages(const std::string patient_id, const std::string study_id, const std::string series_id,bool bdisplay) +{ + vvQuery query; + query.keys = getQueryKeysforImages( patient_id, study_id, series_id, bdisplay); + query.theRoot = gdcm::ePatientRootType; + query.theLevel = gdcm::eImage; + m_query = query; + return query; +} + +std::vector< std::pair > vvDicomServerQueryFactory::getQueryKeysforImages(const std::string patient_id, const std::string study_id, const std::string series_id,bool bdisplay) +{ + + std::vector< std::pair > keys; + + if (!bdisplay) + { + //Patient UID + keys.push_back(std::make_pair(gdcm::Tag (0x0010,0x0020), patient_id)); + + //Study UID + // keys.push_back(std::make_pair(gdcm::Tag(0x0020,0x000d), study_id)); + + //Series UID + keys.push_back(std::make_pair(gdcm::Tag(0x0020,0x000e), series_id)); + } + // Image Description + + keys.push_back(std::make_pair(gdcm::Tag(0x0020,0x0013), "")); + //SOP Instance UID + keys.push_back(std::make_pair(gdcm::Tag(0x0008,0x0018), "")); + return keys; +} + + + +vvQuery vvDicomServerQueryFactory::getQueryPatient(const std::string i_patname, const std::string i_patid) +{ + vvQuery query; + query.theRoot = gdcm::ePatientRootType; + query.theLevel = gdcm::ePatient; + query.keys = getPatientKeys(i_patname, i_patid); + m_query = query; + return query; + +} + +std::vector< std::pair > vvDicomServerQueryFactory::getPatientKeys(const std::string i_patname, const std::string i_patid) +{ + std::vector< std::pair > keys; + // Patient Name + gdcm::Tag tag(0x0010,0x0010); + keys.push_back(std::make_pair(tag, i_patname)); + + //// Patient ID + gdcm::Tag tagpid(0x0010,0x0020); + keys.push_back(std::make_pair(tagpid, i_patid)); + return keys; +} + + +vvQuery vvDicomServerQueryFactory::getQueryforSeries(const std::string patient_id, const std::string series_id, bool bdisplay) +{ + vvQuery query; + query.theRoot = gdcm::ePatientRootType; + query.theLevel = gdcm::eSeries; + query.keys = getSeriesKeys(patient_id, series_id, bdisplay); + m_query = query; + return query; +} +std::vector< std::pair > vvDicomServerQueryFactory::getSeriesKeys(const std::string patient_id, const std::string study_id, bool bdisplay) +{ + std::vector< std::pair > keys; + // Modality + keys.push_back(std::make_pair(gdcm::Tag(0x0008,0x0060), "")); + // Study date + + keys.push_back(std::make_pair(gdcm::Tag(0x0008,0x103e),"")); +// Series Instance UID + keys.push_back(std::make_pair(gdcm::Tag(0x0020,0x000e), "")); + + + + if(!bdisplay) + { + //Patient UID + keys.push_back(std::make_pair(gdcm::Tag (0x0010,0x0020), patient_id)); + + //Study UID + keys.push_back(std::make_pair(gdcm::Tag(0x0020,0x000d), study_id)); + // Study Instance UID + gdcm::Tag tagsid(0x0020,0x1209); + // keys.push_back(std::make_pair(tagsid, study_id)); + } + + return keys; +} + +void vvDicomServerQueryFactory::setQueryforImage(const std::string patient_id, const std::string study_id, const std::string series_id,const std::string image_id) +{ + vvQuery query; + query.theRoot = gdcm::ePatientRootType; + query.theLevel = gdcm::eImage; + query.keys = getQueryKeysforImage(patient_id, study_id, series_id, image_id); + m_query = query; +} + +std::vector< std::pair > vvDicomServerQueryFactory::getQueryKeysforImage(const std::string patient_id, const std::string study_id, const std::string series_id,const std::string image_id) +{ + + std::vector< std::pair > keys; + + //Patient UID + keys.push_back(std::make_pair(gdcm::Tag (0x0010,0x0020), patient_id)); + + //Study UID + keys.push_back(std::make_pair(gdcm::Tag(0x0020,0x000d), study_id)); + + //Series UID + keys.push_back(std::make_pair(gdcm::Tag(0x0020,0x000e), series_id)); + + //SOP Instance UID + keys.push_back(std::make_pair(gdcm::Tag(0x0008,0x0018), image_id)); + return keys; +} \ No newline at end of file diff --git a/vv/vvDicomServerQueryFactory.h b/vv/vvDicomServerQueryFactory.h new file mode 100644 index 0000000..1b2f19c --- /dev/null +++ b/vv/vvDicomServerQueryFactory.h @@ -0,0 +1,45 @@ +#ifndef __vvDicomServerQueryFactory_h_INCLUDED__ +#define __vvDicomServerQueryFactory_h_INCLUDED__ + +#include "gdcmCompositeNetworkFunctions.h" + + +struct vvQuery{ + gdcm::ERootType theRoot; + gdcm::EQueryLevel theLevel; + std::vector< std::pair > keys; +}; + +class vvDicomServerQueryFactory { + +public: + + vvDicomServerQueryFactory(){} + ~vvDicomServerQueryFactory(){} + + gdcm::SmartPointer composeQuerySeries( std::vector< std::pair > keys); + gdcm::SmartPointer composeQueryStudy( std::string m_patient); + + vvQuery getQueryforImages(const std::string patient_id, const std::string study_id, const std::string series_id,bool bdisplay); + vvQuery getQueryforSeries(const std::string patient_id, const std::string study_id, bool bdisplay); + vvQuery getQueryforStudy(const std::string patient_id, bool bdisplay); + vvQuery getQueryPatient(const std::string i_patname, const std::string i_patid); + void setQueryforImage(const std::string patient_id, const std::string study_id,const std::string series_id,const std::string image_id); + + + std::vector< std::pair > getQueryKeysforStudy(const std::string patient_id, bool bdisplay); + std::vector< std::pair > getPatientKeys(const std::string , const std::string ); + std::vector< std::pair > getSeriesKeys(const std::string patient_id, const std::string study_id, bool bdisplay); + std::vector< std::pair > getQueryKeysforImages(const std::string patient_id, const std::string study_id, const std::string series_id,bool bdisplay); + std::vector< std::pair > getQueryKeysforImage(const std::string patient_id, const std::string study_id, const std::string series_id,const std::string image_id); + + + vvQuery getMoveQuery() { return m_query;} + +private: + + vvQuery m_query; + + +}; +#endif // __vvDicomServerQueryFactory_h_INCLUDED__ diff --git a/vv/vvIcons.qrc b/vv/vvIcons.qrc index e160460..a5e31cc 100644 --- a/vv/vvIcons.qrc +++ b/vv/vvIcons.qrc @@ -41,5 +41,8 @@ icons/standardbutton-apply-16.png icons/standardbutton-cancel-16.png icons/identity.png + icons/basket_download.png + icons/edit.png + icons/bullet_info.png diff --git a/vv/vvMainWindow.cxx b/vv/vvMainWindow.cxx index 79b2805..958cf5c 100644 --- a/vv/vvMainWindow.cxx +++ b/vv/vvMainWindow.cxx @@ -48,6 +48,9 @@ It is distributed under dual licence #include "vvMeshReader.h" #include "vvSaveState.h" #include "vvReadState.h" +#ifdef CLITK_USE_PACS_CONNECTION +#include "vvQPacsConnection.h" +#endif #include "clitkConfiguration.h" #include "clitkMatrix.h" #ifdef Q_OS_OSX @@ -131,6 +134,8 @@ vvMainWindow::vvMainWindow():vvMainWindowBase() { setupUi(this); // this sets up the GUI + setDicomClient(); + //Qt::WindowFlags flags = windowFlags(); //setWindowFlags(flags | Qt::WindowStaysOnTopHint); @@ -230,6 +235,9 @@ vvMainWindow::vvMainWindow():vvMainWindowBase() documentation = new vvDocumentation(); help_dialog = new vvHelpDialog(); dicomSeriesSelector = new vvDicomSeriesSelector(); +#ifdef CLITK_USE_PACS_CONNECTION + PacsConnection = new vvQPacsConnection(); +#endif inverseButton->setEnabled(0); actionAdd_overlay_image_to_current_image->setEnabled(0); @@ -272,6 +280,9 @@ vvMainWindow::vvMainWindow():vvMainWindowBase() connect(actionWarp_image_with_vector_field,SIGNAL(triggered()),this,SLOT(WarpImage())); connect(actionLoad_images,SIGNAL(triggered()),this,SLOT(OpenImages())); connect(actionOpen_Dicom,SIGNAL(triggered()),this,SLOT(OpenDicom())); + #ifdef CLITK_USE_PACS_CONNECTION +connect(actionConnect_Pacs,SIGNAL(triggered()),this,SLOT(ConnectPacs())); +#endif // connect(actionOpen_Dicom_Struct,SIGNAL(triggered()),this,SLOT(OpenDCStructContour())); connect(actionOpen_VTK_contour,SIGNAL(triggered()),this,SLOT(OpenVTKContour())); connect(actionOpen_Multiple_Images_As_One,SIGNAL(triggered()),this,SLOT(MergeImages())); @@ -758,7 +769,24 @@ void vvMainWindow::OpenDicom() files = *(dicomSeriesSelector->GetFilenames()); LoadImages(files, vvImageReader::DICOM); } -} +} +#ifdef CLITK_USE_PACS_CONNECTION +void vvMainWindow::ConnectPacs() +{ + std::vector files; + + //std::cout << "dicomSeriesSelector " << std::endl; +if (PacsConnection->exec() == QDialog::Accepted) { + for (int i = 0; i < PacsConnection->getSeriesCount(); i++) + { + files = PacsConnection->getFileNames(i); + LoadImages(files, vvImageReader::DICOM); + } + PacsConnection->clearMove(); + } + } + +#endif //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ diff --git a/vv/vvMainWindow.h b/vv/vvMainWindow.h index 9253fa0..8f5b41c 100644 --- a/vv/vvMainWindow.h +++ b/vv/vvMainWindow.h @@ -1,7 +1,7 @@ /*========================================================================= Program: vv http://www.creatis.insa-lyon.fr/rio/vv - Authors belong to: + Authors belong to: - University of LYON http://www.universite-lyon.fr/ - Léon Bérard cancer center http://www.centreleonberard.fr - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr @@ -39,6 +39,9 @@ class vtkImageData; class vtkRenderer; class vtkMatrix4x4; class vvDicomSeriesSelector; +#ifdef CLITK_USE_PACS_CONNECTION +class vvQPacsConnection; +#endif class vvSlicer; class QTreeWidget; @@ -91,6 +94,9 @@ public slots: void SliceImages(); void MergeImagesWithTime(); void OpenDicom(); +#ifdef CLITK_USE_PACS_CONNECTION + void ConnectPacs(); +#endif ///Open a vtkPolyData surface mesh and display it over the current image void OpenVTKContour(); void SaveAs(); @@ -194,6 +200,10 @@ private: vvDocumentation *documentation; vvDicomSeriesSelector *dicomSeriesSelector; +#ifdef CLITK_USE_PACS_CONNECTION + vvQPacsConnection *PacsConnection; +#endif + bool viewMode; bool playMode; diff --git a/vv/vvPacsSettingsDialog.cxx b/vv/vvPacsSettingsDialog.cxx new file mode 100644 index 0000000..7cde608 --- /dev/null +++ b/vv/vvPacsSettingsDialog.cxx @@ -0,0 +1,19 @@ +#include "vvPacsSettingsDialog.h" +#include "vvQPacsConnection.h" +#include "vvUtils.h" + +vvPacsSettingsDialog::vvPacsSettingsDialog(QWidget *i_parent) + : QDialog(i_parent) + { + mparent = i_parent; + ui.setupUi(this); + update(); + } + +void vvPacsSettingsDialog::accept() +{ + + AddDicomServer(ui.NameEdit->text().toStdString(),ui.AETitleEdit->text().toStdString(),ui.AdressEdit->text().toStdString(), ui.PortEdit->text().toStdString()); +((vvQPacsConnection*)this->parent())->refreshNetworks(); + close(); +} \ No newline at end of file diff --git a/vv/vvPacsSettingsDialog.h b/vv/vvPacsSettingsDialog.h new file mode 100644 index 0000000..13ad661 --- /dev/null +++ b/vv/vvPacsSettingsDialog.h @@ -0,0 +1,22 @@ +#ifndef __vvPacsSettingsDialog_H +#define __vvPacsSettingsDialog_H +#include "ui_vvPacsSettingsDialog.h" +#include +#include + + class vvPacsSettingsDialog : public QDialog + { + Q_OBJECT + public: + + vvPacsSettingsDialog(QWidget *parent=0); + + ~vvPacsSettingsDialog(){} + private: + QWidget *mparent; + Ui::vvPacsSettingsDialog ui; +private slots: + void accept(); + + }; +#endif //__vvPacsSettingsDialog_H diff --git a/vv/vvQPacsConnection.cxx b/vv/vvQPacsConnection.cxx new file mode 100644 index 0000000..4ae0d33 --- /dev/null +++ b/vv/vvQPacsConnection.cxx @@ -0,0 +1,449 @@ +#include "vvQPacsConnection.h" +#include "gdcmCompositeNetworkFunctions.h" +#include +#include +#include +#include +#include +#include "vvPacsSettingsDialog.h" +#include "vvUtils.h" +#include +#include +#include + + +vvQPacsConnection::vvQPacsConnection(QWidget *i_parent) + :QDialog(i_parent) +{ + ui.setupUi(this); + setWindowTitle(QString::fromUtf8("PACS CONNECTION")); + createTreeView(); + ui.tabFilter->setTabText(0,QString(tr("Modality"))); + ui.tabFilter->setTabText(1,QString(tr("Date"))); + + ui. tabNetwork->setTabText(0,QString(tr("Network"))); + ui. tabNetwork->setTabText(1,QString(tr("Configuration"))); + ui.check_ModAll->setEnabled(true); + ui.networkCombo->addItem(""); + ui.networkCombo->addItems(getDicomServers()); + + // Connection + connect(ui.networkCombo,SIGNAL(currentIndexChanged(int)),this,SLOT(chooseServer(int))); + connect(ui.removeNetworkButton,SIGNAL(clicked()),this,SLOT(removeServer())); + connect(ui.NetworkButton,SIGNAL(clicked()),this,SLOT(modifyServer())); + connect(ui.exitButton,SIGNAL(clicked()),this,SLOT(close())); + + update(); +} + +// Exit window +bool vvQPacsConnection::close() +{ + QApplication::restoreOverrideCursor(); + return QWidget::close(); +} + +// remote a Dicom Server in VV settings +void vvQPacsConnection::removeServer() +{ + removeDicomServer(m_nickname); + ui.networkCombo->removeItem(ui.networkCombo->findText(QString(m_nickname.c_str()))); + m_nickname=""; + refreshNetworks(); +} + +// modify a Dicom Server in VV settings +void vvQPacsConnection::modifyServer() +{ + int indexCombo = ui.networkCombo->currentIndex(); + removeDicomServer(m_nickname); + AddDicomServer(ui.NameEdit->text().toStdString(),ui.AETitleEdit->text().toStdString(),ui.AdressEdit->text().toStdString(),ui.PortEdit->text().toStdString()); + ui.networkCombo->clear(); + ui.networkCombo->addItem(QString()); + ui.networkCombo->addItems(getDicomServers()); + ui.networkCombo->setCurrentIndex(indexCombo); +} + +// refresh the list of Dicom Servers available from VV settings +void vvQPacsConnection::refreshNetworks() +{ + ui.networkCombo->clear(); + ui.networkCombo->addItem(QString()); + ui.networkCombo->addItems(getDicomServers()); + ui.NameEdit->setText(QString()); + ui.AETitleEdit->setText(QString()); + ui.AdressEdit->setText(QString()); + ui.PortEdit->setText(QString()); + ui.tabNetwork->setCurrentIndex(0); +} + +void vvQPacsConnection::on_clearButton_clicked() +{ + Patientmodel->removeRows(0, Patientmodel->rowCount(),QModelIndex()); + Studymodel->removeRows(0, Studymodel->rowCount(),QModelIndex()); + Seriesmodel->removeRows(0, Seriesmodel->rowCount(),QModelIndex()); + Imagesmodel->removeRows(0, Imagesmodel->rowCount(),QModelIndex()); +} + +void vvQPacsConnection::on_scanButton_clicked() +{ + cleanTree(); + manageStudiesFilter(true); + + // test first if echo works + bool didItWork = gdcm::CompositeNetworkFunctions::CEcho(m_adress.c_str(), atoi(m_port.c_str()), getDicomClientAETitle().c_str(), m_nickname.c_str() ); + if (didItWork) + { + m_level =gdcm::ePatient; + std::vector theDataSet; + f_query = mQFactory.getQueryPatient(ui.patientName->toPlainText().toStdString(), ui.patientID->toPlainText().toStdString()); + + bool cfindWork = gdcm::CompositeNetworkFunctions::CFind(m_adress.c_str(), atoi(m_port.c_str()), + gdcm::CompositeNetworkFunctions::ConstructQuery(f_query.theRoot, f_query.theLevel ,f_query.keys), + theDataSet, getDicomClientAETitle().c_str() , m_nickname.c_str()); + if( cfindWork) + { + convertDataSet(theDataSet,Patientmodel,mQFactory.getPatientKeys("","")); + } // end cfindwork + } // end didItwork +} + + +/// show Options DialogBox to set a new Dicom Server +void vvQPacsConnection::on_optionsButton_clicked() +{ + vvPacsSettingsDialog *dg = new vvPacsSettingsDialog(this); + dg->show(); +} + +void vvQPacsConnection::convertDataSet(std::vector i_ds, QStandardItemModel *i_model, std::vector< std::pair > keys) +{ + + std::vector::iterator it_ds = i_ds.begin(); + for(; it_ds != i_ds.end(); it_ds++) + { + QList items; + const gdcm::DataSet ds = (*it_ds); + std::vector< std::pair >::iterator it_key = keys.begin(); + int ind = 0; + for(; it_key != keys.end(); it_key++, ind++) + { + gdcm::DataElement de = ds.GetDataElement((*it_key).first); + QStandardItem *item = new QStandardItem; + const gdcm::ByteValue *bv = (de).GetByteValue(); + if( !de.IsEmpty() ) + { + std::string buffer = std::string( bv->GetPointer(), bv->GetLength() ); + item->setText(tr(buffer.c_str())); + } + else + { + item->setText(tr("")); + } + if(ind ==0) + { + item->setCheckable(true); + } + items.push_back(item); + } + i_model->appendRow(items); + } +} + +// TreeViews creation +void vvQPacsConnection::createTreeView() +{ + // Patient Tree View + Patientmodel = new QStandardItemModel(0,2,this); + QStringList Patientlist; + Patientlist.push_back(tr("PATIENT NAME")); + Patientlist.push_back(tr("PATIENT ID")); + Patientmodel->setHorizontalHeaderLabels(Patientlist); + ui.patientTreeView->setModel(Patientmodel); + ui.patientTreeView->setEnabled(true); + connect(ui.patientTreeView, SIGNAL(clicked(QModelIndex)), this, SLOT(selectStudies(QModelIndex))); + + // Study Tree View + Studymodel = new QStandardItemModel(0,3,this); + QStringList Studylist; + Studylist.push_back(tr("DESCRIPTION")); + Studylist.push_back(tr("DATE")); + Studylist.push_back(tr("HOUR")); + Studylist.push_back(tr("STUDY ID")); + Studymodel->setHorizontalHeaderLabels(Studylist); + ui.studyTreeView->setModel(Studymodel); + connect(ui.studyTreeView, SIGNAL(clicked(QModelIndex)), this, SLOT(selectSeries(QModelIndex))); + + + // Series Tree View + Seriesmodel = new QStandardItemModel(0,2,this); + QStringList Serieslist; + Serieslist.push_back(tr("MODALITY")); + Serieslist.push_back(tr("DESCRIPTION")); + Serieslist.push_back(tr("no. accept.")); + Seriesmodel->setHorizontalHeaderLabels(Serieslist); + ui.seriesTreeView->setModel(Seriesmodel); + connect(ui.seriesTreeView, SIGNAL(clicked(QModelIndex)), this, SLOT(selectImages(QModelIndex))); + connect(ui.imagesTreeView, SIGNAL(clicked(QModelIndex)), this, SLOT(selectImage(QModelIndex))); + // Images Tree View + Imagesmodel = new QStandardItemModel(0,1,this); + QStringList Imageslist; + Imageslist.push_back(tr("instance number")); + Imageslist.push_back(tr("sopuid")); + Imagesmodel->setHorizontalHeaderLabels(Imageslist); + ui.imagesTreeView->setModel(Imagesmodel); +} + +// clean the different model Trees +void vvQPacsConnection::cleanTree() +{ + Patientmodel->removeRows(0,Patientmodel->rowCount()); + Studymodel->removeRows(0,Patientmodel->rowCount()); + Seriesmodel->removeRows(0,Patientmodel->rowCount()); + Imagesmodel->removeRows(0,Patientmodel->rowCount()); + +} + +void vvQPacsConnection::selectStudies(const QModelIndex &index) +{ + + m_patient= Patientmodel->data(index.sibling(index.row(),1)).toString().toStdString(); + Studymodel->removeRows(0, Studymodel->rowCount(),QModelIndex()); + Seriesmodel->removeRows(0, Seriesmodel->rowCount(),QModelIndex()); + Imagesmodel->removeRows(0, Imagesmodel->rowCount(),QModelIndex()); + manageSeriesFilter(true); + convertDataSet( findQuery( mQFactory.getQueryforStudy(m_patient, false)) , Studymodel, mQFactory.getQueryKeysforStudy("",true)); +} + + +void vvQPacsConnection::clearMove() +{ + +} + +void vvQPacsConnection::selectSeries(const QModelIndex &index) +{ + m_study= Studymodel->data(index.sibling(index.row(),3)).toString().toStdString(); + Seriesmodel->removeRows(0, Seriesmodel->rowCount()); + Imagesmodel->removeRows(0, Imagesmodel->rowCount()); + convertDataSet( findQuery( mQFactory.getQueryforSeries(m_patient,m_study, false)), Seriesmodel, mQFactory.getSeriesKeys("","",true)); + +} + +void vvQPacsConnection::selectImages(const QModelIndex &index) +{ + m_series = Seriesmodel->data(index.sibling(index.row(),2)).toString().toStdString(); + Imagesmodel->removeRows(0, Imagesmodel->rowCount(),QModelIndex()); + convertDataSet( findQuery( mQFactory.getQueryforImages(m_patient,m_study, m_series, false) ), Imagesmodel, mQFactory.getQueryKeysforImages("","","",true)); + +} + +void vvQPacsConnection::selectImage(const QModelIndex &index) +{ + std::string _image = Imagesmodel->data(index.sibling(index.row(),1)).toString().toStdString(); + mQFactory.setQueryforImage(m_patient,m_study, m_series, _image); + +} + + +std::vector vvQPacsConnection::findQuery(vvQuery i_query) +{ + std::vector theDataSet; + gdcm::CompositeNetworkFunctions::CFind(m_adress.c_str(), atoi(m_port.c_str()), + gdcm::CompositeNetworkFunctions::ConstructQuery(i_query.theRoot, i_query.theLevel,i_query.keys), theDataSet, + getDicomClientAETitle().c_str(), m_nickname.c_str()); + return theDataSet; +} + +void vvQPacsConnection::manageStudiesFilter(bool i_enable) +{ + ui.text_PHYS->setEnabled(i_enable); + ui.text_SDESC->setEnabled(i_enable); + ui.dateTab->setEnabled(i_enable); + +} + +void vvQPacsConnection::manageSeriesFilter(bool i_enable) +{ + ui.modalityTab->setEnabled(i_enable); +} + + +std::vector< std::pair > vvQPacsConnection::getStudyKeys(const std::string i_val) +{ + std::vector< std::pair > keys; + // Study Description + gdcm::Tag tagsdc(0x0008,0x1030); + keys.push_back(std::make_pair(tagsdc, "")); + // Study date + gdcm::Tag tagdb(0x0008,0x0020); + keys.push_back(std::make_pair(tagdb, "")); + // Study Hour + gdcm::Tag tagsdh(0x0008,0x0030); + keys.push_back(std::make_pair(tagsdh, "")); + // Study Instance UID + gdcm::Tag tagsid(0x0020,0x000d); + keys.push_back(std::make_pair(tagsid, i_val)); + + return keys; +} + +std::vector< std::pair > vvQPacsConnection::getKeys() +{ + std::vector< std::pair > keys; + // Patient Name + gdcm::Tag tag(0x0010,0x0010); + keys.push_back(std::make_pair(tag, "")); + + //// Patient ID + gdcm::Tag tagpid(0x0010,0x0020); + keys.push_back(std::make_pair(tagpid, "")); + + // Modality + gdcm::Tag tagmod(0x0008,0x0061); + keys.push_back(std::make_pair(tagmod, "")); + + // date of birth + gdcm::Tag tagdb(0x0010,0x0030); + keys.push_back(std::make_pair(tagdb, "")); + + // Study Date + gdcm::Tag tagsd(0x0020,0x000D); + keys.push_back(std::make_pair(tagsd, "")); + + //// Study Time + //gdcm::Tag tagst(8,30); + //keys.push_back(std::make_pair(tagst, "")); + + //// Study Description + //gdcm::Tag tagsdc(8,1030); + //keys.push_back(std::make_pair(tagsdc, "")); + + //// Accession + //gdcm::Tag tagacc(8,50); + //keys.push_back(std::make_pair(tagacc, "")); + + return keys; +} + +void vvQPacsConnection::on_check_ModAll_clicked(bool state) +{ + ui.check_MR->setEnabled(!state); + ui.check_CR->setEnabled(!state); + ui.check_OT->setEnabled(!state); + ui.check_RF->setEnabled(!state); + ui.check_SC->setEnabled(!state); + ui.check_CT->setEnabled(!state); + ui.check_US->setEnabled(!state); + ui.check_NM->setEnabled(!state); + ui.check_DR->setEnabled(!state); + ui.check_US->setEnabled(!state); + ui.check_NM->setEnabled(!state); + ui.check_DR->setEnabled(!state); + ui.check_SR->setEnabled(!state); + ui.check_XA->setEnabled(!state); + ui.check_MG->setEnabled(!state); + if(state) + { + ui.check_MR->setChecked(state); + ui.check_CR->setChecked(state); + ui.check_OT->setChecked(state); + ui.check_RF->setChecked(state); + ui.check_SC->setChecked(state); + ui.check_CT->setChecked(state); + ui.check_US->setChecked(state); + ui.check_NM->setChecked(state); + ui.check_DR->setChecked(state); + ui.check_US->setChecked(state); + ui.check_NM->setChecked(state); + ui.check_DR->setChecked(state); + ui.check_SR->setChecked(state); + ui.check_XA->setChecked(state); + ui.check_MG->setChecked(state); + } + +} + +void vvQPacsConnection::chooseServer(int index) +{ + std::map < std::string, std:: string> values = getDicomServer(ui.networkCombo->currentText()); + m_port = values["PORT"]; + m_aetitle = values["AETITLE"]; + m_adress= values["ADRESS"]; + m_nickname = values["nickname"]; + ui.AdressEdit->setText(QString(m_adress.c_str())); + ui.AETitleEdit->setText(QString(m_aetitle.c_str())); + ui.NameEdit->setText(QString(m_nickname.c_str())); + ui.PortEdit->setText(QString(m_port.c_str())); +} + +void vvQPacsConnection::on_importButton_clicked() + { + setCursor(QCursor(Qt::WaitCursor)); + QString path = QString::fromStdString(getCMoveDirectory()); + QDir dirpath (path); + if (dirpath.exists()) + { + QFileInfoList list = dirpath.entryInfoList( QDir::Files); + QFileInfoList::iterator it_file = dirpath.entryInfoList( QDir::Files).begin(); + for(int i = 0; i < list.length() ; i++) + { + QFile::remove(list.at(i).filePath()); + } + } + else + { + dirpath.mkdir(path); + } + bool didItWork = gdcm::CompositeNetworkFunctions::CMove(m_adress.c_str(),atoi(m_port.c_str()), + gdcm::CompositeNetworkFunctions::ConstructQuery(mQFactory.getMoveQuery().theRoot, mQFactory.getMoveQuery().theLevel ,mQFactory.getMoveQuery().keys, gdcm::eMove), + getDicomClientPort(), getDicomClientAETitle().c_str(), m_aetitle.c_str(), path.toStdString().c_str() ); + gdcm::Directory theDir; + theDir.Load(path.toStdString().c_str()); + //m_files = theDir.GetFilenames(); + + typedef itk::GDCMSeriesFileNames NamesGeneratorType; + NamesGeneratorType::Pointer nameGenerator = NamesGeneratorType::New(); + nameGenerator->SetUseSeriesDetails(true); + + //ds gerer recursive moi-meme pour progress ... + nameGenerator->SetInputDirectory(path.toStdString()); + + // insert in table + typedef std::vector SeriesIdContainer; + const SeriesIdContainer & seriesUID = nameGenerator->GetSeriesUIDs(); + std::map* > mListOfSeriesFilenames; + + + m_fileseries.clear(); + + for (unsigned int i=0; iGetFileNames(seriesUID[i])); + } + + accept(); + setCursor(QCursor(Qt::ArrowCursor)); + } + + + +std::vector vvQPacsConnection::getFileNames(int i_series) +{ + std::vector filenames; + gdcm::Directory::FilenamesType::iterator it = m_fileseries[i_series].begin(); + for (;it != m_fileseries[i_series].end(); it++) + filenames.push_back(it->c_str()); + return filenames; +} +std::vector< std::pair > vvQPacsConnection::fillMoveKeys() +{ + std::vector< std::pair > keys; + switch(m_level) + { + case gdcm::ePatient: + //keys.push_back(getPatientKeys("","")); + break; + } + + return keys; +} diff --git a/vv/vvQPacsConnection.h b/vv/vvQPacsConnection.h new file mode 100644 index 0000000..4c98458 --- /dev/null +++ b/vv/vvQPacsConnection.h @@ -0,0 +1,91 @@ +#ifndef __vvQPacsConnection_h_INCLUDED__ +#define __vvQPacsConnection_h_INCLUDED__ + +#include +#include "ui_vvPacsConnection.h" +#include "gdcmCompositeNetworkFunctions.h" +#include +#include +#include +#include "vvDicomServerQueryFactory.h" + + /** + * \ingroup GUI + */ + //===================================================================== + //====================================================================== + + + +class vvQPacsConnection : public QDialog +{ + Q_OBJECT +public: + //vvQPacsConnection(){} + vvQPacsConnection(QWidget *parent=0); + + ~vvQPacsConnection(){} + void refreshNetworks(); + std::vector getFileNames(int i_series); + int getSeriesCount() { return m_fileseries.size();} + void clearMove(); + +public slots: + void selectStudies(const QModelIndex &index); + void selectSeries(const QModelIndex &index); + void selectImages(const QModelIndex &index); + void selectImage(const QModelIndex &index); + private slots: + void on_scanButton_clicked(); + void on_clearButton_clicked(); + void on_optionsButton_clicked(); + void on_check_ModAll_clicked(bool state); + void on_importButton_clicked(); + void chooseServer(int index); + void removeServer(); + bool close(); + void modifyServer(); + + private : + + + Ui::vvPacsConnection ui; + std::vector< std::pair > getKeys(); + std::vector< std::pair > getStudyKeys(const std::string); + std::vector findQuery(vvQuery i_query); + + void manageStudiesFilter(bool i_enable); + void createTreeView(); + void cleanTree(); + void setNewPacs(); + QStandardItemModel *Patientmodel; + QStandardItemModel *Studymodel; + QStandardItemModel *Seriesmodel; + QStandardItemModel *Imagesmodel; + void convertDataSet(std::vector i_ds, QStandardItemModel *i_model, std::vector< std::pair > keys); + void manageSeriesFilter(bool i_enable); + std::vector< std::pair > fillMoveKeys(); + std::string m_patient; + std::string m_study; + std::string m_series; + gdcm::EQueryLevel m_level; + std::string m_port; + std::string m_aetitle; + std::string m_adress; + std::string m_nickname; + vvDicomServerQueryFactory mQFactory; + vvQuery m_query; + vvQuery f_query; + gdcm::Directory::FilenamesType m_files; + std::vector < gdcm::Directory::FilenamesType> m_fileseries; + + + + }; // class vvQPacsConnection + //===================================================================== + + + +#endif // __vvQPacsConnection_h_INCLUDED__ + + diff --git a/vv/vvUtils.cxx b/vv/vvUtils.cxx index 3ef9cc6..b787c9f 100644 --- a/vv/vvUtils.cxx +++ b/vv/vvUtils.cxx @@ -48,6 +48,113 @@ FileListType GetRecentlyOpenedImages() return result; } +// Set parameters for VV (AETITLE, port-scu) to allow c-move. +void setDicomClient() +{ + QSettings settings(getVVSettingsPath(), getSettingsOptionFormat()); + if (! settings.childGroups().contains("DICOMCLIENT")) + { + settings.beginGroup(QString::fromStdString("DICOMCLIENT")); + settings.setValue("AETITLE",QString::fromStdString("VVDICOMSCU")); + settings.setValue("port",QString::number(1234)); + settings.setValue("directory",QDir::homePath() +QString::fromStdString("/.move")); + settings.endGroup(); + } +} + +// get VV-AETITLE for c-move. parameters +std::string getDicomClientAETitle() +{ + std::string result =""; + QSettings settings(getVVSettingsPath(), getSettingsOptionFormat()); + settings.beginGroup(QString::fromStdString("DICOMCLIENT")); + result = settings.value("AETITLE").toString().toStdString(); + settings.endGroup(); + return result; +} + +// get the directory where the dicom files will be stored during c-move action. +std::string getCMoveDirectory() +{ + std::string result =""; + QSettings settings(getVVSettingsPath(), getSettingsOptionFormat()); + settings.beginGroup(QString::fromStdString("DICOMCLIENT")); + result = settings.value("directory").toString().toStdString(); + settings.endGroup(); + return result; +} + +// get VV-PORT-SCU for c-move. parameters +int getDicomClientPort() +{ + int result; + QSettings settings(getVVSettingsPath(), getSettingsOptionFormat()); + settings.beginGroup(QString::fromStdString("DICOMCLIENT")); + result = settings.value("port").toString().toInt(); + settings.endGroup(); + return result; +} + +/// Add a new Dicom Server +void AddDicomServer(std::string nickname, std::string aetitle, std::string adress, std::string port) +{ + QSettings settings(getVVSettingsPath(), getSettingsOptionFormat()); + settings.beginGroup(QString::fromStdString("DICOMSERVER")); + settings.beginWriteArray(QString::fromStdString(nickname)); + settings.setValue("nickname",QString::fromStdString(nickname)); + settings.setValue("AETITLE",QString::fromStdString(aetitle)); + settings.setValue("ADRESS",QString::fromStdString(adress)); + settings.setValue("PORT",QString::fromStdString(port)); + settings.endGroup(); +} + +/// Remove a Dicom Server +void removeDicomServer(std::string nickname) +{ + QSettings settings(getVVSettingsPath(), getSettingsOptionFormat()); + settings.beginGroup(QString::fromStdString("DICOMSERVER")); + std::string temp = nickname + "//"; + settings.remove(QString::fromStdString(temp + "nickname")); + settings.remove(QString::fromStdString(temp + "AETITLE")); + settings.remove(QString::fromStdString(temp + "ADRESS")); + settings.remove(QString::fromStdString(temp + "PORT")); + settings.endGroup(); +} + + + + +/// get the list of a Dicom Server +QStringList getDicomServers() +{ + + QStringList list; + QSettings settings(getVVSettingsPath(), getSettingsOptionFormat()); + settings.beginGroup(QString::fromStdString("DICOMSERVER")); + QStringList keys = settings.allKeys(); + for(int i =0; i < keys.size(); i++) + { + QString val = keys.at(i); + if (val.contains("nickname")) + list.push_back(settings.value(val).toString()); + } + return list; +} + +/// get needed Infos for a Dicom Server +std::map getDicomServer(QString nickname) +{ + std::map< std::string, std::string >results; + QSettings settings(getVVSettingsPath(), getSettingsOptionFormat()); + settings.beginGroup(QString::fromStdString("DICOMSERVER")); + settings.beginReadArray(nickname); + QStringList keys = settings.childKeys(); + for (int i = 0; i getDicomServer(QString nickname); #endif