diff --git a/Applications/PluginGenerator/ProjectTemplate/CMakeExternals/MITK.cmake b/Applications/PluginGenerator/ProjectTemplate/CMakeExternals/MITK.cmake index d739fcdab4..ed131a5216 100644 --- a/Applications/PluginGenerator/ProjectTemplate/CMakeExternals/MITK.cmake +++ b/Applications/PluginGenerator/ProjectTemplate/CMakeExternals/MITK.cmake @@ -1,228 +1,228 @@ #----------------------------------------------------------------------------- # MITK #----------------------------------------------------------------------------- set(MITK_DEPENDS) set(proj_DEPENDENCIES) set(proj MITK) if(NOT MITK_DIR) #----------------------------------------------------------------------------- # Create CMake options to customize the MITK build #----------------------------------------------------------------------------- option(MITK_USE_SUPERBUILD "Use superbuild for MITK" ON) option(MITK_USE_BLUEBERRY "Build the BlueBerry platform in MITK" ON) option(MITK_BUILD_EXAMPLES "Build the MITK examples" OFF) option(MITK_BUILD_ALL_PLUGINS "Build all MITK plugins" OFF) option(MITK_BUILD_TESTING "Build the MITK unit tests" OFF) option(MITK_USE_ACVD "Use Approximated Centroidal Voronoi Diagrams" OFF) option(MITK_USE_CTK "Use CTK in MITK" ${MITK_USE_BLUEBERRY}) option(MITK_USE_DCMTK "Use DCMTK in MITK" ON) option(MITK_USE_QT "Use Nokia's Qt library in MITK" ON) option(MITK_USE_OpenCV "Use Intel's OpenCV library" OFF) option(MITK_USE_SOFA "Use Simulation Open Framework Architecture" OFF) option(MITK_USE_VMTK "Use the Vascular Modeling Toolkit in MITK" OFF) option(MITK_USE_Python "Enable Python wrapping in MITK" OFF) if(MITK_USE_BLUEBERRY AND NOT MITK_USE_CTK) message("Forcing MITK_USE_CTK to ON because of MITK_USE_BLUEBERRY") set(MITK_USE_CTK ON CACHE BOOL "Use CTK in MITK" FORCE) endif() if(MITK_USE_CTK AND NOT MITK_USE_QT) message("Forcing MITK_USE_QT to ON because of MITK_USE_CTK") set(MITK_USE_QT ON CACHE BOOL "Use Nokia's Qt library in MITK" FORCE) endif() set(MITK_USE_CableSwig ${MITK_USE_Python}) set(MITK_USE_GDCM 1) set(MITK_USE_ITK 1) set(MITK_USE_VTK 1) mark_as_advanced(MITK_USE_SUPERBUILD MITK_BUILD_ALL_PLUGINS MITK_BUILD_TESTING ) set(mitk_cmake_boolean_args MITK_USE_SUPERBUILD MITK_USE_BLUEBERRY MITK_BUILD_EXAMPLES MITK_BUILD_ALL_PLUGINS MITK_USE_ACVD MITK_USE_CTK MITK_USE_DCMTK MITK_USE_QT MITK_USE_OpenCV MITK_USE_SOFA MITK_USE_VMTK MITK_USE_Python ) if(MITK_USE_Qt4) # Look for Qt at the superbuild level, to catch missing Qt libs early find_package(Qt4 4.7 REQUIRED) elseif(MITK_USE_Qt5) find_package(Qt5Widgets REQUIRED) endif() set(additional_mitk_cmakevars ) # Configure the set of default pixel types set(MITK_ACCESSBYITK_INTEGRAL_PIXEL_TYPES "int, unsigned int, short, unsigned short, char, unsigned char" CACHE STRING "List of integral pixel types used in AccessByItk and InstantiateAccessFunction macros") set(MITK_ACCESSBYITK_FLOATING_PIXEL_TYPES "double, float" CACHE STRING "List of floating pixel types used in AccessByItk and InstantiateAccessFunction macros") set(MITK_ACCESSBYITK_COMPOSITE_PIXEL_TYPES "" CACHE STRING "List of composite pixel types used in AccessByItk and InstantiateAccessFunction macros") set(MITK_ACCESSBYITK_DIMENSIONS "2,3" CACHE STRING "List of dimensions used in AccessByItk and InstantiateAccessFunction macros") foreach(_arg MITK_ACCESSBYITK_INTEGRAL_PIXEL_TYPES MITK_ACCESSBYITK_FLOATING_PIXEL_TYPES MITK_ACCESSBYITK_COMPOSITE_PIXEL_TYPES MITK_ACCESSBYITK_DIMENSIONS) mark_as_advanced(${_arg}) list(APPEND additional_mitk_cmakevars "-D${_arg}:STRING=${${_arg}}") endforeach() #----------------------------------------------------------------------------- # Create options to inject pre-build dependencies #----------------------------------------------------------------------------- foreach(proj CTK DCMTK GDCM VTK ACVD ITK OpenCV SOFA VMTK CableSwig) if(MITK_USE_${proj}) set(MITK_${proj}_DIR "${${proj}_DIR}" CACHE PATH "Path to ${proj} build directory") mark_as_advanced(MITK_${proj}_DIR) if(MITK_${proj}_DIR) list(APPEND additional_mitk_cmakevars "-D${proj}_DIR:PATH=${MITK_${proj}_DIR}") endif() endif() endforeach() set(MITK_BOOST_ROOT "${BOOST_ROOT}" CACHE PATH "Path to Boost directory") mark_as_advanced(MITK_BOOST_ROOT) if(MITK_BOOST_ROOT) list(APPEND additional_mitk_cmakevars "-DBOOST_ROOT:PATH=${MITK_BOOST_ROOT}") endif() set(MITK_SOURCE_DIR "" CACHE PATH "MITK source code location. If empty, MITK will be cloned from MITK_GIT_REPOSITORY") set(MITK_GIT_REPOSITORY "http://git.mitk.org/MITK.git" CACHE STRING "The git repository for cloning MITK") - set(MITK_GIT_TAG "v2015.05.0" CACHE STRING "The git tag/hash to be used when cloning from MITK_GIT_REPOSITORY") + set(MITK_GIT_TAG "v2015.05.2" CACHE STRING "The git tag/hash to be used when cloning from MITK_GIT_REPOSITORY") mark_as_advanced(MITK_SOURCE_DIR MITK_GIT_REPOSITORY MITK_GIT_TAG) #----------------------------------------------------------------------------- # Create the final variable containing superbuild boolean args #----------------------------------------------------------------------------- set(mitk_boolean_args) foreach(mitk_cmake_arg ${mitk_cmake_boolean_args}) list(APPEND mitk_boolean_args -D${mitk_cmake_arg}:BOOL=${${mitk_cmake_arg}}) endforeach() #----------------------------------------------------------------------------- # Additional MITK CMake variables #----------------------------------------------------------------------------- if(MITK_USE_Qt4 AND QT_QMAKE_EXECUTABLE) list(APPEND additional_mitk_cmakevars "-DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}") elseif(MITK_USE_Qt5) list(APPEND additional_mitk_cmakevars "-DDESIRED_QT_VERSION:STRING=5") endif() if(MITK_USE_CTK) list(APPEND additional_mitk_cmakevars "-DGIT_EXECUTABLE:FILEPATH=${GIT_EXECUTABLE}") endif() if(MITK_INITIAL_CACHE_FILE) list(APPEND additional_mitk_cmakevars "-DMITK_INITIAL_CACHE_FILE:INTERNAL=${MITK_INITIAL_CACHE_FILE}") endif() if(MITK_USE_SUPERBUILD) set(MITK_BINARY_DIR ${proj}-superbuild) else() set(MITK_BINARY_DIR ${proj}-build) endif() set(proj_DEPENDENCIES) set(MITK_DEPENDS ${proj}) # Configure the MITK souce code location if(NOT MITK_SOURCE_DIR) set(mitk_source_location SOURCE_DIR ${CMAKE_BINARY_DIR}/${proj} GIT_REPOSITORY ${MITK_GIT_REPOSITORY} GIT_TAG ${MITK_GIT_TAG} ) else() set(mitk_source_location SOURCE_DIR ${MITK_SOURCE_DIR} ) endif() ExternalProject_Add(${proj} ${mitk_source_location} BINARY_DIR ${MITK_BINARY_DIR} PREFIX ${proj}${ep_suffix} INSTALL_COMMAND "" CMAKE_GENERATOR ${gen} CMAKE_ARGS ${ep_common_args} ${mitk_boolean_args} ${additional_mitk_cmakevars} -DBUILD_SHARED_LIBS:BOOL=ON -DBUILD_TESTING:BOOL=${MITK_BUILD_TESTING} CMAKE_CACHE_ARGS ${ep_common_cache_args} CMAKE_CACHE_DEFAULT_ARGS ${ep_common_cache_default_args} DEPENDS ${proj_DEPENDENCIES} ) if(MITK_USE_SUPERBUILD) set(MITK_DIR "${CMAKE_CURRENT_BINARY_DIR}/${MITK_BINARY_DIR}/MITK-build") else() set(MITK_DIR "${CMAKE_CURRENT_BINARY_DIR}/${MITK_BINARY_DIR}") endif() else() # The project is provided using MITK_DIR, nevertheless since other # projects may depend on MITK, let's add an 'empty' one MacroEmptyExternalProject(${proj} "${proj_DEPENDENCIES}") # Further, do some sanity checks in the case of a pre-built MITK set(my_itk_dir ${ITK_DIR}) set(my_vtk_dir ${VTK_DIR}) find_package(MITK REQUIRED) if(my_itk_dir AND NOT my_itk_dir STREQUAL ${ITK_DIR}) message(FATAL_ERROR "ITK packages do not match:\n ${MY_PROJECT_NAME}: ${my_itk_dir}\n MITK: ${ITK_DIR}") endif() if(my_vtk_dir AND NOT my_vtk_dir STREQUAL ${VTK_DIR}) message(FATAL_ERROR "VTK packages do not match:\n ${MY_PROJECT_NAME}: ${my_vtk_dir}\n MITK: ${VTK_DIR}") endif() if(MITK_USE_Qt4) set(my_qmake_executable ${QT_QMAKE_EXECUTABLE}) if(my_qmake_executable AND MITK_QMAKE_EXECUTABLE) if(NOT my_qmake_executable STREQUAL ${MITK_QMAKE_EXECUTABLE}) message(FATAL_ERROR "Qt qmake does not match:\n ${MY_PROJECT_NAME}: ${my_qmake_executable}\n MITK: ${MITK_QMAKE_EXECUTABLE}") endif() endif() endif() endif() diff --git a/CMake/mitkFunctionGetLibrarySearchPaths.cmake b/CMake/mitkFunctionGetLibrarySearchPaths.cmake index 8dc9fdc243..6219f3bee3 100644 --- a/CMake/mitkFunctionGetLibrarySearchPaths.cmake +++ b/CMake/mitkFunctionGetLibrarySearchPaths.cmake @@ -1,172 +1,169 @@ macro(_find_package package_name) find_package(${package_name} REQUIRED PATHS ${${package_name}_DIR} PATH_SUFFIXES ${package_name} NO_DEFAULT_PATH NO_MODULE QUIET) if(NOT ${package_name}_FOUND) find_package(${package_name} REQUIRED) endif() endmacro() function(mitkFunctionGetLibrarySearchPaths search_path intermediate_dir) set(_dir_candidates "${MITK_CMAKE_RUNTIME_OUTPUT_DIRECTORY}" "${MITK_CMAKE_RUNTIME_OUTPUT_DIRECTORY}/plugins" "${MITK_CMAKE_LIBRARY_OUTPUT_DIRECTORY}" "${MITK_CMAKE_LIBRARY_OUTPUT_DIRECTORY}/plugins" ) if(MITK_EXTERNAL_PROJECT_PREFIX) list(APPEND _dir_candidates "${MITK_EXTERNAL_PROJECT_PREFIX}/bin" "${MITK_EXTERNAL_PROJECT_PREFIX}/lib" ) endif() # Determine the Qt4/5 library installation prefix set(_qmake_location ) if(MITK_USE_Qt4) set(_qmake_location ${QT_QMAKE_EXECUTABLE}) elseif(MITK_USE_Qt5 AND TARGET ${Qt5Core_QMAKE_EXECUTABLE}) get_property(_qmake_location TARGET ${Qt5Core_QMAKE_EXECUTABLE} PROPERTY IMPORT_LOCATION) endif() if(_qmake_location) if(NOT _qt_install_libs) if(WIN32) execute_process(COMMAND ${_qmake_location} -query QT_INSTALL_BINS OUTPUT_VARIABLE _qt_install_libs OUTPUT_STRIP_TRAILING_WHITESPACE) else() execute_process(COMMAND ${_qmake_location} -query QT_INSTALL_LIBS OUTPUT_VARIABLE _qt_install_libs OUTPUT_STRIP_TRAILING_WHITESPACE) endif() file(TO_CMAKE_PATH "${_qt_install_libs}" _qt_install_libs) set(_qt_install_libs ${_qt_install_libs} CACHE INTERNAL "Qt library installation prefix" FORCE) endif() if(_qt_install_libs) list(APPEND _dir_candidates ${_qt_install_libs}) endif() elseif(MITK_USE_QT) message(WARNING "The qmake executable could not be found.") endif() get_property(_additional_paths GLOBAL PROPERTY MITK_ADDITIONAL_LIBRARY_SEARCH_PATHS) if(MITK_USE_HDF5) _find_package(HDF5) get_target_property(_location hdf5 LOCATION) get_filename_component(_location ${_location} PATH) list(APPEND _additional_paths ${_location}) # This is a work-around. The hdf5-config.cmake file is not robust enough # to be included several times via find_pakcage calls. set(HDF5_LIBRARIES ${HDF5_LIBRARIES} PARENT_SCOPE) endif() if(MITK_USE_Vigra) # we cannot use _find_package(Vigra) here because the vigra-config.cmake file # always includes the target-exports files without using an include guard. This # would lead to errors when another find_package(Vigra) call is processed. The # (bad) assumption here is that for the time being, only the Classification module # is using Vigra. if(UNIX) list(APPEND _additional_paths ${Vigra_DIR}/lib) else() list(APPEND _additional_paths ${Vigra_DIR}/bin) endif() endif() if(_additional_paths) list(APPEND _dir_candidates ${_additional_paths}) endif() # The code below is sub-optimal. It makes assumptions about # the structure of the build directories, pointed to by # the *_DIR variables. Instead, we should rely on package # specific "LIBRARY_DIRS" variables, if they exist. if(WIN32) if(SOFA_DIR) list(APPEND _dir_candidates "${SOFA_DIR}/bin") endif() - if(REDLAND_INSTALL_DIR) - list(APPEND _dir_candidates "${REDLAND_INSTALL_DIR}/bin") - endif() list(APPEND _dir_candidates "${ITK_DIR}/bin") else() if(SOFA_DIR) list(APPEND _dir_candidates "${SOFA_DIR}/lib") endif() endif() if(OpenCV_DIR) set(_opencv_link_directories "${OpenCV_LIB_DIR_DBG}" "${OpenCV_LIB_DIR_OPT}" "${OpenCV_3RDPARTY_LIB_DIR_DBG}" "${OpenCV_3RDPARTY_LIB_DIR_OPT}") list(REMOVE_DUPLICATES _opencv_link_directories) if(WIN32) foreach(_opencv_link_directory ${_opencv_link_directories}) list(APPEND _dir_candidates "${_opencv_link_directory}/../bin") endforeach() else() list(APPEND _dir_candidates ${_opencv_link_directories}) endif() endif() if(MITK_USE_Python) list(APPEND _dir_candidates "${CTK_DIR}/CMakeExternals/Install/bin") list(APPEND _dir_candidates "${MITK_EXTERNAL_PROJECT_PREFIX}/lib/python2.7/bin") endif() if(MITK_USE_TOF_PMDO3 OR MITK_USE_TOF_PMDCAMCUBE OR MITK_USE_TOF_PMDCAMBOARD) list(APPEND _dir_candidates "${MITK_PMD_SDK_DIR}/plugins" "${MITK_PMD_SDK_DIR}/bin") endif() if(MITK_USE_CTK) list(APPEND _dir_candidates "${CTK_LIBRARY_DIRS}") foreach(_ctk_library ${CTK_LIBRARIES}) if(${_ctk_library}_LIBRARY_DIRS) list(APPEND _dir_candidates "${${_ctk_library}_LIBRARY_DIRS}") endif() endforeach() endif() if(MITK_USE_BLUEBERRY) if(DEFINED CTK_PLUGIN_RUNTIME_OUTPUT_DIRECTORY) if(IS_ABSOLUTE "${CTK_PLUGIN_RUNTIME_OUTPUT_DIRECTORY}") list(APPEND _dir_candidates "${CTK_PLUGIN_RUNTIME_OUTPUT_DIRECTORY}") else() list(APPEND _dir_candidates "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CTK_PLUGIN_RUNTIME_OUTPUT_DIRECTORY}") endif() endif() endif() if(MITK_LIBRARY_DIRS) list(APPEND _dir_candidates ${MITK_LIBRARY_DIRS}) endif() list(REMOVE_DUPLICATES _dir_candidates) set(_search_dirs ) foreach(_dir ${_dir_candidates}) if(EXISTS "${_dir}/${intermediate_dir}") list(APPEND _search_dirs "${_dir}/${intermediate_dir}") else() list(APPEND _search_dirs "${_dir}") endif() endforeach() # Special handling for "internal" search dirs. The intermediate directory # might not have been created yet, so we can't check for its existence. # Hence we just add it for Windows without checking. set(_internal_search_dirs "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/plugins") if(WIN32) foreach(_dir ${_internal_search_dirs}) set(_search_dirs "${_dir}/${intermediate_dir}" ${_search_dirs}) endforeach() else() set(_search_dirs ${_internal_search_dirs} ${_search_dirs}) endif() list(REMOVE_DUPLICATES _search_dirs) set(${search_path} ${_search_dirs} PARENT_SCOPE) endfunction() diff --git a/Modules/XNAT/files.cmake b/Modules/XNAT/files.cmake index e26d372495..08dc767045 100644 --- a/Modules/XNAT/files.cmake +++ b/Modules/XNAT/files.cmake @@ -1,33 +1,36 @@ file(GLOB_RECURSE H_FILES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/include/*") set(CPP_FILES mitkXnatSessionTracker.cpp QmitkXnatTreeModel.cpp QmitkXnatProjectWidget.cpp QmitkXnatSubjectWidget.cpp QmitkXnatExperimentWidget.cpp QmitkXnatCreateObjectDialog.cpp + QmitkSelectXnatUploadDestinationDialog.cpp QmitkXnatUploadFromDataStorageDialog.cpp ) set(MOC_H_FILES include/mitkXnatSessionTracker.h include/QmitkXnatTreeModel.h include/QmitkXnatProjectWidget.h include/QmitkXnatSubjectWidget.h include/QmitkXnatExperimentWidget.h include/QmitkXnatCreateObjectDialog.h + include/QmitkSelectXnatUploadDestinationDialog.h include/QmitkXnatUploadFromDataStorageDialog.h ) set(QRC_FILES resources/xnat.qrc ) set(UI_FILES src/QmitkXnatExperimentWidgetControls.ui src/QmitkXnatProjectWidgetControls.ui + src/QmitkSelectXnatUploadDestinationDialog.ui src/QmitkXnatSubjectWidgetControls.ui src/QmitkXnatUploadFromDataStorageDialog.ui ) diff --git a/Modules/XNAT/include/QmitkSelectXnatUploadDestinationDialog.h b/Modules/XNAT/include/QmitkSelectXnatUploadDestinationDialog.h new file mode 100644 index 0000000000..02e6e53b96 --- /dev/null +++ b/Modules/XNAT/include/QmitkSelectXnatUploadDestinationDialog.h @@ -0,0 +1,46 @@ +#ifndef QMITKSELECTXNATUPLOADDESTINATIONDIALOG_H +#define QMITKSELECTXNATUPLOADDESTINATIONDIALOG_H + +#include + +#include + +namespace Ui { +class QmitkSelectXnatUploadDestinationDialog; +} + +class ctkXnatObject; +class ctkXnatSession; +class QModelIndex; +class QmitkXnatTreeModel; + +class MITKXNAT_EXPORT QmitkSelectXnatUploadDestinationDialog : public QDialog +{ + Q_OBJECT + +public: + explicit QmitkSelectXnatUploadDestinationDialog(ctkXnatSession* session, const QStringList&, QWidget *parent = 0); + ~QmitkSelectXnatUploadDestinationDialog(); + + ctkXnatObject *GetUploadDestination(); + void SetXnatResourceFolderUrl(const QString& url); + +protected slots: + + void OnUpload(); + void OnSelectResource(bool selectResource); + void OnSelectFromTreeView(bool selectFromTreeView); + void OnResourceEntered(const QString &resourceEntered); + void OnResourceSelected(const QString &resource); + void OnXnatNodeSelected(const QModelIndex&); + void OnCancel(); + +private: + QmitkXnatTreeModel* m_TreeModel; + QString m_Url; + QString m_ResourceName; + bool m_CreateNewFolder; + Ui::QmitkSelectXnatUploadDestinationDialog *ui; +}; + +#endif // QMITKSELECTXNATUPLOADDESTINATIONDIALOG_H diff --git a/Modules/XNAT/include/QmitkXnatTreeModel.h b/Modules/XNAT/include/QmitkXnatTreeModel.h index fc680f6e71..90ae878886 100644 --- a/Modules/XNAT/include/QmitkXnatTreeModel.h +++ b/Modules/XNAT/include/QmitkXnatTreeModel.h @@ -1,51 +1,56 @@ /*=================================================================== 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 QMITKXNATTREEMODEL_H #define QMITKXNATTREEMODEL_H // CTK includes #include // MITK includes #include "MitkXNATExports.h" namespace mitk { class DataNode; } class MITKXNAT_EXPORT QmitkXnatTreeModel : public ctkXnatTreeModel { Q_OBJECT public: QmitkXnatTreeModel(); virtual QVariant data(const QModelIndex& index, int role) const; virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent); using QAbstractItemModel::supportedDropActions; virtual Qt::DropActions supportedDropActions(); virtual Qt::ItemFlags flags(const QModelIndex &index) const; + ctkXnatObject* GetXnatObjectFromUrl(const QString&); + signals: void ResourceDropped(const QList&, ctkXnatObject*, const QModelIndex&); +private: + ctkXnatObject *InternalGetXnatObjectFromUrl(const QString &xnatObjectType, const QString &url, ctkXnatObject *parent); + }; #endif // QMITKXNATTREEMODEL_H diff --git a/Modules/XNAT/include/QmitkXnatUploadFromDataStorageDialog.h b/Modules/XNAT/include/QmitkXnatUploadFromDataStorageDialog.h index 819621543a..ebb42cee19 100644 --- a/Modules/XNAT/include/QmitkXnatUploadFromDataStorageDialog.h +++ b/Modules/XNAT/include/QmitkXnatUploadFromDataStorageDialog.h @@ -1,46 +1,42 @@ #ifndef QMITKXNATUPLOADFROMDATASTORAGEDIALOG_H #define QMITKXNATUPLOADFROMDATASTORAGEDIALOG_H #include +#include "MitkXNATExports.h" #include namespace Ui { class QmitkXnatUploadFromDataStorageDialog; } namespace mitk { class DataStorage; } -class QmitkXnatUploadFromDataStorageDialog : public QDialog +class MITKXNAT_EXPORT QmitkXnatUploadFromDataStorageDialog : public QDialog { Q_OBJECT public: explicit QmitkXnatUploadFromDataStorageDialog(QWidget *parent = 0); ~QmitkXnatUploadFromDataStorageDialog(); void SetDataStorage(mitk::DataStorage* ds); mitk::DataNode::Pointer GetSelectedNode(); - enum - { - UPLOAD, CANCEL - }; - protected slots: void OnUpload(); void OnUploadSceneChecked(); void OnCancel(); void OnMITKProjectFileNameEntered(const QString &text); void OnDataSelected(const mitk::DataNode*); private: Ui::QmitkXnatUploadFromDataStorageDialog *ui; mitk::DataNode::Pointer m_SelectedNode; }; #endif // QMITKXNATUPLOADFROMDATASTORAGEDIALOG_H diff --git a/Modules/XNAT/resources/file.png b/Modules/XNAT/resources/file.png new file mode 100644 index 0000000000..c1d3d55ed7 Binary files /dev/null and b/Modules/XNAT/resources/file.png differ diff --git a/Modules/XNAT/resources/project.ico b/Modules/XNAT/resources/folder.ico similarity index 100% rename from Modules/XNAT/resources/project.ico rename to Modules/XNAT/resources/folder.ico diff --git a/Modules/XNAT/resources/project.png b/Modules/XNAT/resources/project.png new file mode 100644 index 0000000000..a78643c1f9 Binary files /dev/null and b/Modules/XNAT/resources/project.png differ diff --git a/Modules/XNAT/resources/resource.png b/Modules/XNAT/resources/resource.png new file mode 100644 index 0000000000..dcd64df048 Binary files /dev/null and b/Modules/XNAT/resources/resource.png differ diff --git a/Modules/XNAT/resources/scan.png b/Modules/XNAT/resources/scan.png new file mode 100644 index 0000000000..1258871eec Binary files /dev/null and b/Modules/XNAT/resources/scan.png differ diff --git a/Modules/XNAT/resources/xnat.qrc b/Modules/XNAT/resources/xnat.qrc index 7d6e5f8ecf..0249b77262 100644 --- a/Modules/XNAT/resources/xnat.qrc +++ b/Modules/XNAT/resources/xnat.qrc @@ -1,8 +1,12 @@ - server.ico - project.ico - subject.ico experiment.ico + file.png + folder.ico + project.png + resource.png + scan.png + server.ico + subject.ico diff --git a/Modules/XNAT/src/QmitkSelectXnatUploadDestinationDialog.cpp b/Modules/XNAT/src/QmitkSelectXnatUploadDestinationDialog.cpp new file mode 100644 index 0000000000..f7d5168ece --- /dev/null +++ b/Modules/XNAT/src/QmitkSelectXnatUploadDestinationDialog.cpp @@ -0,0 +1,145 @@ +#include "QmitkSelectXnatUploadDestinationDialog.h" +#include "ui_QmitkSelectXnatUploadDestinationDialog.h" + +#include +#include +#include +#include + +#include "QmitkXnatTreeModel.h" + +#include + +QmitkSelectXnatUploadDestinationDialog::QmitkSelectXnatUploadDestinationDialog(ctkXnatSession* session, const QStringList& availableResources, QWidget *parent) : + QDialog(parent), + ui(new Ui::QmitkSelectXnatUploadDestinationDialog), + m_Url(""), + m_ResourceName(""), + m_CreateNewFolder(false) +{ + ui->setupUi(this); + + m_TreeModel = new QmitkXnatTreeModel(); + m_TreeModel->addDataModel(session->dataModel()); + ui->treeView->setModel(m_TreeModel); + + connect(ui->cbSelectResources, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(OnResourceSelected(const QString&))); + connect(ui->treeView, SIGNAL(clicked(const QModelIndex&)), this, SLOT(OnXnatNodeSelected(const QModelIndex&))); + connect(ui->rbSelectResource, SIGNAL(toggled(bool)), this, SLOT(OnSelectResource(bool))); + connect(ui->rbSelectFromTreeView, SIGNAL(toggled(bool)), this, SLOT(OnSelectFromTreeView(bool))); + connect(ui->leResourceName, SIGNAL(textChanged(const QString&)), this, SLOT(OnResourceEntered(const QString&))); + connect(ui->pbCancel, SIGNAL(clicked()), this, SLOT(OnCancel())); + connect(ui->pbUpload, SIGNAL(clicked()), this, SLOT(OnUpload())); + + // Initial Setup + ui->pbUpload->setEnabled(false); + ui->leResourceName->setVisible(false); + ui->treeView->hide(); + + if (availableResources.isEmpty()) + { + ui->rbSelectFromTreeView->setChecked(true); + ui->rbSelectResource->setEnabled(false); + } + else + { + foreach (QString resourceName, availableResources) + { + ui->cbSelectResources->addItem(resourceName); + } + ui->cbSelectResources->addItem("Create new resource folder..."); + } +} + +QmitkSelectXnatUploadDestinationDialog::~QmitkSelectXnatUploadDestinationDialog() +{ + delete ui; +} + +void QmitkSelectXnatUploadDestinationDialog::OnCancel() +{ + this->done(QDialog::Rejected); +} + +void QmitkSelectXnatUploadDestinationDialog::OnUpload() +{ + this->done(QDialog::Accepted); +} + +void QmitkSelectXnatUploadDestinationDialog::OnSelectResource(bool selectResource) +{ + ui->pbUpload->setEnabled(false); + ui->cbSelectResources->setVisible(selectResource); + ui->leResourceName->setVisible(!selectResource); + ui->treeView->setVisible(!selectResource); + if (selectResource) + ui->cbSelectResources->setCurrentIndex(0); +} + +void QmitkSelectXnatUploadDestinationDialog::OnSelectFromTreeView(bool selectFromTreeView) +{ + ui->pbUpload->setEnabled(false); + ui->cbSelectResources->setVisible(!selectFromTreeView); + ui->leResourceName->setVisible(!selectFromTreeView); + ui->treeView->setVisible(selectFromTreeView); +} + +void QmitkSelectXnatUploadDestinationDialog::SetXnatResourceFolderUrl(const QString &url) +{ + m_Url = url; +} + +ctkXnatObject* QmitkSelectXnatUploadDestinationDialog::GetUploadDestination() +{ + if (ui->rbSelectResource->isChecked() && !m_Url.isEmpty() && !m_ResourceName.isEmpty()) + { + ctkXnatObject* selectedXnatObject = m_TreeModel->GetXnatObjectFromUrl(m_Url); + + ctkXnatResource* resource = new ctkXnatResource(); + resource->setName(m_ResourceName); + resource->setParent(selectedXnatObject); + if(!resource->exists()) + resource->save(); + return resource; + } + else + { + QModelIndex index = ui->treeView->selectionModel()->currentIndex(); + return m_TreeModel->xnatObject(index); + } +} + +void QmitkSelectXnatUploadDestinationDialog::OnResourceSelected(const QString& resource) +{ + if (resource.isEmpty()) + ui->pbUpload->setEnabled(false); + + if (resource != "Create new resource folder...") + { + ui->pbUpload->setEnabled(true); + m_ResourceName = resource; + ui->leResourceName->hide(); + } + else if (resource == "Create new resource folder...") + { + ui->pbUpload->setEnabled(false); + ui->leResourceName->show(); + } +} + +void QmitkSelectXnatUploadDestinationDialog::OnResourceEntered(const QString& resourceEntered) +{ + m_CreateNewFolder = !resourceEntered.isEmpty(); + ui->pbUpload->setEnabled(m_CreateNewFolder); + m_ResourceName = resourceEntered; +} + +void QmitkSelectXnatUploadDestinationDialog::OnXnatNodeSelected(const QModelIndex& index) +{ + if (!index.isValid()) + return; + + ctkXnatObject* selectedObject = m_TreeModel->xnatObject(index); + ui->pbUpload->setEnabled(dynamic_cast(selectedObject) != nullptr); +} + diff --git a/Modules/XNAT/src/QmitkSelectXnatUploadDestinationDialog.ui b/Modules/XNAT/src/QmitkSelectXnatUploadDestinationDialog.ui new file mode 100644 index 0000000000..7936ea6275 --- /dev/null +++ b/Modules/XNAT/src/QmitkSelectXnatUploadDestinationDialog.ui @@ -0,0 +1,104 @@ + + + QmitkSelectXnatUploadDestinationDialog + + + + 0 + 0 + 419 + 210 + + + + + 0 + 0 + + + + Dialog + + + + + + + + Select existing resource folder + + + true + + + buttonGroup + + + + + + + Select from Treebrowser + + + false + + + buttonGroup + + + + + + + + + + + + + + + true + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Cancel + + + + + + + Upload + + + + + + + + + + + + + diff --git a/Modules/XNAT/src/QmitkXnatTreeModel.cpp b/Modules/XNAT/src/QmitkXnatTreeModel.cpp index 1c22560a11..77ea63de39 100644 --- a/Modules/XNAT/src/QmitkXnatTreeModel.cpp +++ b/Modules/XNAT/src/QmitkXnatTreeModel.cpp @@ -1,116 +1,223 @@ /*=================================================================== 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 "QmitkXnatTreeModel.h" #include #include #include #include #include #include #include #include +#include +#include +#include +#include QmitkXnatTreeModel::QmitkXnatTreeModel () : ctkXnatTreeModel() { } QVariant QmitkXnatTreeModel::data(const QModelIndex& index, int role) const { if (!index.isValid()) { return QVariant(); } if (role == Qt::DecorationRole) { ctkXnatObject* xnatObject = this->xnatObject(index); QString path; if(dynamic_cast(xnatObject)) { path = ":/xnat/server.ico"; } else if(dynamic_cast(xnatObject)) { - path = ":/xnat/project.ico"; + path = ":/xnat/project.png"; } else if(dynamic_cast(xnatObject)) { path = ":/xnat/subject.ico"; } else if(dynamic_cast(xnatObject)) { path = ":/xnat/experiment.ico"; } + else if (dynamic_cast(xnatObject)) + { + path = ":/xnat/folder.ico"; + } + else if (dynamic_cast(xnatObject)) + { + path = ":/xnat/resource.png"; + } + else if (dynamic_cast(xnatObject)) + { + path = ":/xnat/folder.ico"; + } + else if (dynamic_cast(xnatObject)) + { + path = ":/xnat/scan.png"; + } + else if (dynamic_cast(xnatObject)) + { + path = ":/xnat/file.png"; + } return QIcon(path); } return ctkXnatTreeModel::data(index, role); } bool QmitkXnatTreeModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int /*row*/, int /*column*/, const QModelIndex &parent) { if (action == Qt::IgnoreAction) return true; // Return true if data can be handled bool returnVal (false); if (data->hasFormat(QmitkMimeTypes::DataNodePtrs)) { returnVal = true; QList droppedNodes = QmitkMimeTypes::ToDataNodePtrList(data); ctkXnatObject* parentXnatObj = this->xnatObject(parent); emit ResourceDropped(droppedNodes, parentXnatObj, parent); } return returnVal; } Qt::DropActions QmitkXnatTreeModel::supportedDropActions() { return Qt::CopyAction; } Qt::ItemFlags QmitkXnatTreeModel::flags(const QModelIndex &index) const { Qt::ItemFlags defaultFlags = ctkXnatTreeModel::flags(index); if (index.isValid()) { bool droppingAllowed = dynamic_cast(this->xnatObject(index)) != nullptr; droppingAllowed |= dynamic_cast(this->xnatObject(index)) != nullptr; droppingAllowed |= dynamic_cast(this->xnatObject(index)) != nullptr; droppingAllowed |= dynamic_cast(this->xnatObject(index)) != nullptr; // No dropping at project, session or data model level allowed if (droppingAllowed) { return Qt::ItemIsDropEnabled | defaultFlags; } else { return defaultFlags; } } else return defaultFlags; } + +ctkXnatObject* QmitkXnatTreeModel::InternalGetXnatObjectFromUrl(const QString & xnatObjectType, const QString & url, + ctkXnatObject* parent) +{ + // 1. Find project + int start = url.lastIndexOf(xnatObjectType); + if (start == -1) + return nullptr; + + start += xnatObjectType.length(); + int length = url.indexOf("/",start); + length -= start; + + parent->fetch(); + QList children = parent->children(); + foreach (ctkXnatObject* child, children) + { + if(url.indexOf(child->resourceUri()) != -1) + { + return child; + } + } + return nullptr; +} + +ctkXnatObject* QmitkXnatTreeModel::GetXnatObjectFromUrl(const QString& url) +{ + QModelIndex index = this->index(0,0,QModelIndex()); + ctkXnatObject* currentXnatObject = nullptr; + currentXnatObject = this->xnatObject(index); + if (currentXnatObject != nullptr) + { + // 1. Find project + ctkXnatObject* project = nullptr; + project = this->InternalGetXnatObjectFromUrl("projects/", url, currentXnatObject); + + // 2. Find subject + ctkXnatObject* subject = nullptr; + if (project != nullptr) + { + currentXnatObject = project; + subject = this->InternalGetXnatObjectFromUrl("subjects/", url, project); + } + + // 3. Find experiment + ctkXnatObject* experiment = nullptr; + if (subject != nullptr) + { + currentXnatObject = subject; + experiment = this->InternalGetXnatObjectFromUrl("experiments/", url, subject); + } + + // 4. Find scan + ctkXnatObject* scan = nullptr; + if (experiment != nullptr) + { + currentXnatObject = experiment; + scan = this->InternalGetXnatObjectFromUrl("scans/", url, experiment); + } + + if (scan != nullptr) + { + scan->fetch(); + QList scans = scan->children(); + foreach (ctkXnatObject* child, scans) + { + if (url.indexOf(child->resourceUri()) != -1) + { + return child; + } + } + } + + currentXnatObject->fetch(); + QList bla = currentXnatObject->children(); + foreach (ctkXnatObject* child, bla) + { + if (child->name() == "Resources") + return child; + } + } + return nullptr; +} diff --git a/Modules/XNAT/src/QmitkXnatUploadFromDataStorageDialog.cpp b/Modules/XNAT/src/QmitkXnatUploadFromDataStorageDialog.cpp index 989dbfcb47..ce633127e0 100644 --- a/Modules/XNAT/src/QmitkXnatUploadFromDataStorageDialog.cpp +++ b/Modules/XNAT/src/QmitkXnatUploadFromDataStorageDialog.cpp @@ -1,71 +1,71 @@ #include "QmitkXnatUploadFromDataStorageDialog.h" #include "ui_QmitkXnatUploadFromDataStorageDialog.h" #include #include #include #include QmitkXnatUploadFromDataStorageDialog::QmitkXnatUploadFromDataStorageDialog(QWidget *parent) : QDialog(parent), ui(new Ui::QmitkXnatUploadFromDataStorageDialog), m_SelectedNode(0) { ui->setupUi(this); // Not yet implemented ui->cbUploadMITKProject->hide(); ui->leMITKProjectFileName->hide(); // connect(ui->btnCancel, SIGNAL(clicked()), this, SLOT(OnCancel())); connect(ui->btnUpload, SIGNAL(clicked()), this, SLOT(OnUpload())); connect(ui->cbUploadMITKProject, SIGNAL(checked()), this, SLOT(OnUploadSceneChecked())); connect(ui->leMITKProjectFileName, SIGNAL(textEdited(const QString&)), this, SLOT(OnMITKProjectFileNameEntered(const QString&))); connect(ui->cBDataSelection, SIGNAL(OnSelectionChanged(const mitk::DataNode*)), this, SLOT(OnDataSelected(const mitk::DataNode*))); mitk::NodePredicateNot::Pointer noHelper = mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("helper object")); mitk::NodePredicateNot::Pointer noHidden = mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("hidden object")); mitk::NodePredicateAnd::Pointer pred = mitk::NodePredicateAnd::New(noHelper, noHidden); ui->cBDataSelection->SetPredicate(pred); } QmitkXnatUploadFromDataStorageDialog::~QmitkXnatUploadFromDataStorageDialog() { delete ui; } void QmitkXnatUploadFromDataStorageDialog::SetDataStorage(mitk::DataStorage *ds) { ui->cBDataSelection->SetDataStorage(ds); } void QmitkXnatUploadFromDataStorageDialog::OnUpload() { - this->done(UPLOAD); + this->done(QDialog::Accepted); } void QmitkXnatUploadFromDataStorageDialog::OnUploadSceneChecked() { } void QmitkXnatUploadFromDataStorageDialog::OnCancel() { - this->done(CANCEL); + this->done(QDialog::Rejected); } void QmitkXnatUploadFromDataStorageDialog::OnMITKProjectFileNameEntered(const QString& /*text*/) { } void QmitkXnatUploadFromDataStorageDialog::OnDataSelected(const mitk::DataNode* node) { m_SelectedNode = const_cast(node); if (m_SelectedNode.IsNotNull()) ui->btnUpload->setEnabled(true); } mitk::DataNode::Pointer QmitkXnatUploadFromDataStorageDialog::GetSelectedNode() { return m_SelectedNode; } diff --git a/Plugins/org.mitk.gui.qt.datamanager/resources/datamanager.qrc b/Plugins/org.mitk.gui.qt.datamanager/resources/datamanager.qrc index 4d50b384de..238c5ad627 100644 --- a/Plugins/org.mitk.gui.qt.datamanager/resources/datamanager.qrc +++ b/Plugins/org.mitk.gui.qt.datamanager/resources/datamanager.qrc @@ -1,10 +1,11 @@ - + Refresh_48.png Remove_48.png Save_48.png InvertShowSelectedNode_48.png ShowDataInfo_48.png ShowSelectedNode_48.png + xnat-icon.png diff --git a/Plugins/org.mitk.gui.qt.datamanager/resources/xnat-icon.png b/Plugins/org.mitk.gui.qt.datamanager/resources/xnat-icon.png new file mode 100644 index 0000000000..97d4e9b6df Binary files /dev/null and b/Plugins/org.mitk.gui.qt.datamanager/resources/xnat-icon.png differ diff --git a/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.cpp b/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.cpp index 74e92e6fe2..701777b54c 100644 --- a/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.cpp +++ b/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.cpp @@ -1,992 +1,995 @@ /*=================================================================== 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 "QmitkDataManagerView.h" //# Own Includes //## mitk #include "mitkDataStorageEditorInput.h" #include "mitkIDataStorageReference.h" #include "mitkNodePredicateDataType.h" #include "mitkCoreObjectFactory.h" #include "mitkColorProperty.h" #include "mitkCommon.h" #include "mitkNodePredicateData.h" #include "mitkNodePredicateNot.h" #include "mitkNodePredicateOr.h" #include "mitkNodePredicateProperty.h" #include "mitkEnumerationProperty.h" #include "mitkLookupTableProperty.h" #include "mitkProperties.h" #include #include #include #include #include //## Qmitk #include #include #include #include #include #include #include #include "src/internal/QmitkNodeTableViewKeyFilter.h" #include "src/internal/QmitkInfoDialog.h" #include "src/internal/QmitkDataManagerItemDelegate.h" //## Berry #include #include #include #include #include #include //# Toolkit Includes #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "mitkDataNodeObject.h" #include "mitkIContextMenuAction.h" #include "berryIExtensionRegistry.h" #include "mitkRenderingModeProperty.h" const QString QmitkDataManagerView::VIEW_ID = "org.mitk.views.datamanager"; QmitkDataManagerView::QmitkDataManagerView() : m_GlobalReinitOnNodeDelete(true), m_ItemDelegate(NULL) { } QmitkDataManagerView::~QmitkDataManagerView() { //Remove all registered actions from each descriptor for (std::vector< std::pair< QmitkNodeDescriptor*, QAction* > >::iterator it = m_DescriptorActionList.begin();it != m_DescriptorActionList.end(); it++) { // first== the NodeDescriptor; second== the registered QAction (it->first)->RemoveAction(it->second); } } void QmitkDataManagerView::CreateQtPartControl(QWidget* parent) { m_CurrentRowCount = 0; m_Parent = parent; //# Preferences berry::IPreferencesService* prefService = berry::Platform::GetPreferencesService(); berry::IBerryPreferences::Pointer prefs = (prefService->GetSystemPreferences()->Node(VIEW_ID)) .Cast(); assert( prefs ); prefs->OnChanged.AddListener( berry::MessageDelegate1( this , &QmitkDataManagerView::OnPreferencesChanged ) ); //# GUI m_NodeTreeModel = new QmitkDataStorageTreeModel(this->GetDataStorage()); m_NodeTreeModel->setParent( parent ); m_NodeTreeModel->SetPlaceNewNodesOnTop( prefs->GetBool("Place new nodes on top", true) ); m_SurfaceDecimation = prefs->GetBool("Use surface decimation", false); // Prepare filters m_HelperObjectFilterPredicate = mitk::NodePredicateOr::New( mitk::NodePredicateProperty::New("helper object", mitk::BoolProperty::New(true)), mitk::NodePredicateProperty::New("hidden object", mitk::BoolProperty::New(true))); m_NodeWithNoDataFilterPredicate = mitk::NodePredicateData::New(0); m_FilterModel = new QmitkDataStorageFilterProxyModel(); m_FilterModel->setSourceModel(m_NodeTreeModel); m_FilterModel->AddFilterPredicate(m_HelperObjectFilterPredicate); m_FilterModel->AddFilterPredicate(m_NodeWithNoDataFilterPredicate); //# Tree View (experimental) m_NodeTreeView = new QTreeView; m_NodeTreeView->setHeaderHidden(true); m_NodeTreeView->setSelectionMode( QAbstractItemView::ExtendedSelection ); m_NodeTreeView->setSelectionBehavior( QAbstractItemView::SelectRows ); m_NodeTreeView->setAlternatingRowColors(true); m_NodeTreeView->setDragEnabled(true); m_NodeTreeView->setDropIndicatorShown(true); m_NodeTreeView->setAcceptDrops(true); m_NodeTreeView->setContextMenuPolicy(Qt::CustomContextMenu); m_NodeTreeView->setModel(m_FilterModel); m_NodeTreeView->setTextElideMode(Qt::ElideMiddle); m_NodeTreeView->installEventFilter(new QmitkNodeTableViewKeyFilter(this)); m_ItemDelegate = new QmitkDataManagerItemDelegate(m_NodeTreeView); m_NodeTreeView->setItemDelegate(m_ItemDelegate); QObject::connect( m_NodeTreeView, SIGNAL(customContextMenuRequested(const QPoint&)) , this, SLOT(NodeTableViewContextMenuRequested(const QPoint&)) ); QObject::connect( m_NodeTreeModel, SIGNAL(rowsInserted (const QModelIndex&, int, int)) , this, SLOT(NodeTreeViewRowsInserted ( const QModelIndex&, int, int )) ); QObject::connect( m_NodeTreeModel, SIGNAL(rowsRemoved (const QModelIndex&, int, int)) , this, SLOT(NodeTreeViewRowsRemoved( const QModelIndex&, int, int )) ); QObject::connect( m_NodeTreeView->selectionModel() , SIGNAL( selectionChanged ( const QItemSelection &, const QItemSelection & ) ) , this , SLOT( NodeSelectionChanged ( const QItemSelection &, const QItemSelection & ) ) ); //# m_NodeMenu m_NodeMenu = new QMenu(m_NodeTreeView); // # Actions berry::IEditorRegistry* editorRegistry = berry::PlatformUI::GetWorkbench()->GetEditorRegistry(); QList editors = editorRegistry->GetEditors("*.mitk"); if (editors.size() > 1) { m_ShowInMapper = new QSignalMapper(this); foreach(berry::IEditorDescriptor::Pointer descriptor, editors) { QAction* action = new QAction(descriptor->GetLabel(), this); m_ShowInActions << action; m_ShowInMapper->connect(action, SIGNAL(triggered()), m_ShowInMapper, SLOT(map())); m_ShowInMapper->setMapping(action, descriptor->GetId()); } connect(m_ShowInMapper, SIGNAL(mapped(QString)), this, SLOT(ShowIn(QString))); } QmitkNodeDescriptor* unknownDataNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetUnknownDataNodeDescriptor(); QmitkNodeDescriptor* imageDataNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("Image"); QmitkNodeDescriptor* diffusionImageDataNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("DiffusionImage"); QmitkNodeDescriptor* surfaceDataNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("Surface"); QAction* globalReinitAction = new QAction(QIcon(":/org.mitk.gui.qt.datamanager/Refresh_48.png"), "Global Reinit", this); QObject::connect( globalReinitAction, SIGNAL( triggered(bool) ) , this, SLOT( GlobalReinit(bool) ) ); unknownDataNodeDescriptor->AddAction(globalReinitAction); m_DescriptorActionList.push_back(std::pair(unknownDataNodeDescriptor, globalReinitAction)); QAction* saveAction = new QmitkFileSaveAction(QIcon(":/org.mitk.gui.qt.datamanager/Save_48.png"), this->GetSite()->GetWorkbenchWindow()); unknownDataNodeDescriptor->AddAction(saveAction); m_DescriptorActionList.push_back(std::pair(unknownDataNodeDescriptor,saveAction)); QAction* removeAction = new QAction(QIcon(":/org.mitk.gui.qt.datamanager/Remove_48.png"), "Remove", this); QObject::connect( removeAction, SIGNAL( triggered(bool) ) , this, SLOT( RemoveSelectedNodes(bool) ) ); unknownDataNodeDescriptor->AddAction(removeAction); m_DescriptorActionList.push_back(std::pair(unknownDataNodeDescriptor,removeAction)); QAction* reinitAction = new QAction(QIcon(":/org.mitk.gui.qt.datamanager/Refresh_48.png"), "Reinit", this); QObject::connect( reinitAction, SIGNAL( triggered(bool) ) , this, SLOT( ReinitSelectedNodes(bool) ) ); unknownDataNodeDescriptor->AddAction(reinitAction); m_DescriptorActionList.push_back(std::pair(unknownDataNodeDescriptor,reinitAction)); // find contextMenuAction extension points and add them to the node descriptor berry::IExtensionRegistry* extensionPointService = berry::Platform::GetExtensionRegistry(); QList cmActions( extensionPointService->GetConfigurationElementsFor("org.mitk.gui.qt.datamanager.contextMenuActions") ); QList::iterator cmActionsIt; QmitkNodeDescriptor* tmpDescriptor; QAction* contextMenuAction; QVariant cmActionDataIt; m_ConfElements.clear(); int i=1; for (cmActionsIt = cmActions.begin() ; cmActionsIt != cmActions.end() ; ++cmActionsIt) { QString cmNodeDescriptorName = (*cmActionsIt)->GetAttribute("nodeDescriptorName"); QString cmLabel = (*cmActionsIt)->GetAttribute("label"); QString cmClass = (*cmActionsIt)->GetAttribute("class"); if(!cmNodeDescriptorName.isEmpty() && !cmLabel.isEmpty() && !cmClass.isEmpty()) { QString cmIcon = (*cmActionsIt)->GetAttribute("icon"); // create context menu entry here tmpDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor(cmNodeDescriptorName); if(!tmpDescriptor) { MITK_WARN << "cannot add action \"" << cmLabel << "\" because descriptor " << cmNodeDescriptorName << " does not exist"; continue; } // check if the user specified an icon attribute if ( !cmIcon.isEmpty() ) { - contextMenuAction = new QAction( QIcon(cmIcon), cmLabel, parent); + if (cmLabel == "Upload to XNAT") + contextMenuAction = new QAction(QIcon(":/org.mitk.gui.qt.datamanager/xnat-icon.png"), cmLabel, parent); + else + contextMenuAction = new QAction( QIcon(cmIcon), cmLabel, parent); } else { contextMenuAction = new QAction( cmLabel, parent); } tmpDescriptor->AddAction(contextMenuAction); m_DescriptorActionList.push_back(std::pair(tmpDescriptor,contextMenuAction)); m_ConfElements[contextMenuAction] = *cmActionsIt; cmActionDataIt.setValue(i); contextMenuAction->setData( cmActionDataIt ); connect( contextMenuAction, SIGNAL( triggered(bool) ) , this, SLOT( ContextMenuActionTriggered(bool) ) ); ++i; } } m_OpacitySlider = new QSlider; m_OpacitySlider->setMinimum(0); m_OpacitySlider->setMaximum(100); m_OpacitySlider->setOrientation(Qt::Horizontal); QObject::connect( m_OpacitySlider, SIGNAL( valueChanged(int) ) , this, SLOT( OpacityChanged(int) ) ); QLabel* _OpacityLabel = new QLabel("Opacity: "); QHBoxLayout* _OpacityWidgetLayout = new QHBoxLayout; _OpacityWidgetLayout->setContentsMargins(4,4,4,4); _OpacityWidgetLayout->addWidget(_OpacityLabel); _OpacityWidgetLayout->addWidget(m_OpacitySlider); QWidget* _OpacityWidget = new QWidget; _OpacityWidget->setLayout(_OpacityWidgetLayout); QWidgetAction* opacityAction = new QWidgetAction(this); opacityAction ->setDefaultWidget(_OpacityWidget); QObject::connect( opacityAction , SIGNAL( changed() ) , this, SLOT( OpacityActionChanged() ) ); unknownDataNodeDescriptor->AddAction(opacityAction , false); m_DescriptorActionList.push_back(std::pair(unknownDataNodeDescriptor,opacityAction)); m_ColorButton = new QPushButton; m_ColorButton->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Minimum); //m_ColorButton->setText("Change color"); QObject::connect( m_ColorButton, SIGNAL( clicked() ) , this, SLOT( ColorChanged() ) ); QLabel* _ColorLabel = new QLabel("Color: "); _ColorLabel->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum); QHBoxLayout* _ColorWidgetLayout = new QHBoxLayout; _ColorWidgetLayout->setContentsMargins(4,4,4,4); _ColorWidgetLayout->addWidget(_ColorLabel); _ColorWidgetLayout->addWidget(m_ColorButton); QWidget* _ColorWidget = new QWidget; _ColorWidget->setLayout(_ColorWidgetLayout); QWidgetAction* colorAction = new QWidgetAction(this); colorAction->setDefaultWidget(_ColorWidget); QObject::connect( colorAction, SIGNAL( changed() ) , this, SLOT( ColorActionChanged() ) ); unknownDataNodeDescriptor->AddAction(colorAction, false); m_DescriptorActionList.push_back(std::pair(unknownDataNodeDescriptor,colorAction)); m_ComponentSlider = new QmitkNumberPropertySlider; m_ComponentSlider->setOrientation(Qt::Horizontal); //QObject::connect( m_OpacitySlider, SIGNAL( valueChanged(int) ) // , this, SLOT( OpacityChanged(int) ) ); QLabel* _ComponentLabel = new QLabel("Component: "); QHBoxLayout* _ComponentWidgetLayout = new QHBoxLayout; _ComponentWidgetLayout->setContentsMargins(4,4,4,4); _ComponentWidgetLayout->addWidget(_ComponentLabel); _ComponentWidgetLayout->addWidget(m_ComponentSlider); QLabel* _ComponentValueLabel = new QLabel(); _ComponentWidgetLayout->addWidget(_ComponentValueLabel); connect(m_ComponentSlider, SIGNAL(valueChanged(int)), _ComponentValueLabel, SLOT(setNum(int))); QWidget* _ComponentWidget = new QWidget; _ComponentWidget->setLayout(_ComponentWidgetLayout); QWidgetAction* componentAction = new QWidgetAction(this); componentAction->setDefaultWidget(_ComponentWidget); QObject::connect( componentAction , SIGNAL( changed() ) , this, SLOT( ComponentActionChanged() ) ); imageDataNodeDescriptor->AddAction(componentAction, false); m_DescriptorActionList.push_back(std::pair(imageDataNodeDescriptor,componentAction)); if (diffusionImageDataNodeDescriptor!=NULL) { diffusionImageDataNodeDescriptor->AddAction(componentAction, false); m_DescriptorActionList.push_back(std::pair(diffusionImageDataNodeDescriptor,componentAction)); } m_TextureInterpolation = new QAction("Texture Interpolation", this); m_TextureInterpolation->setCheckable ( true ); QObject::connect( m_TextureInterpolation, SIGNAL( changed() ) , this, SLOT( TextureInterpolationChanged() ) ); QObject::connect( m_TextureInterpolation, SIGNAL( toggled(bool) ) , this, SLOT( TextureInterpolationToggled(bool) ) ); imageDataNodeDescriptor->AddAction(m_TextureInterpolation, false); m_DescriptorActionList.push_back(std::pair(imageDataNodeDescriptor,m_TextureInterpolation)); if (diffusionImageDataNodeDescriptor!=NULL) { diffusionImageDataNodeDescriptor->AddAction(m_TextureInterpolation, false); m_DescriptorActionList.push_back(std::pair(diffusionImageDataNodeDescriptor,m_TextureInterpolation)); } m_ColormapAction = new QAction("Colormap", this); m_ColormapAction->setMenu(new QMenu); QObject::connect( m_ColormapAction->menu(), SIGNAL( aboutToShow() ) , this, SLOT( ColormapMenuAboutToShow() ) ); imageDataNodeDescriptor->AddAction(m_ColormapAction, false); m_DescriptorActionList.push_back(std::pair(imageDataNodeDescriptor, m_ColormapAction)); if (diffusionImageDataNodeDescriptor!=NULL) { diffusionImageDataNodeDescriptor->AddAction(m_ColormapAction, false); m_DescriptorActionList.push_back(std::pair(diffusionImageDataNodeDescriptor, m_ColormapAction)); } m_SurfaceRepresentation = new QAction("Surface Representation", this); m_SurfaceRepresentation->setMenu(new QMenu(m_NodeTreeView)); QObject::connect( m_SurfaceRepresentation->menu(), SIGNAL( aboutToShow() ) , this, SLOT( SurfaceRepresentationMenuAboutToShow() ) ); surfaceDataNodeDescriptor->AddAction(m_SurfaceRepresentation, false); m_DescriptorActionList.push_back(std::pair(surfaceDataNodeDescriptor, m_SurfaceRepresentation)); QAction* showOnlySelectedNodes = new QAction(QIcon(":/org.mitk.gui.qt.datamanager/ShowSelectedNode_48.png") , "Show only selected nodes", this); QObject::connect( showOnlySelectedNodes, SIGNAL( triggered(bool) ) , this, SLOT( ShowOnlySelectedNodes(bool) ) ); unknownDataNodeDescriptor->AddAction(showOnlySelectedNodes); m_DescriptorActionList.push_back(std::pair(unknownDataNodeDescriptor, showOnlySelectedNodes)); QAction* toggleSelectedVisibility = new QAction(QIcon(":/org.mitk.gui.qt.datamanager/InvertShowSelectedNode_48.png") , "Toggle visibility", this); QObject::connect( toggleSelectedVisibility, SIGNAL( triggered(bool) ) , this, SLOT( ToggleVisibilityOfSelectedNodes(bool) ) ); unknownDataNodeDescriptor->AddAction(toggleSelectedVisibility); m_DescriptorActionList.push_back(std::pair(unknownDataNodeDescriptor,toggleSelectedVisibility)); QAction* actionShowInfoDialog = new QAction(QIcon(":/org.mitk.gui.qt.datamanager/ShowDataInfo_48.png") , "Details...", this); QObject::connect( actionShowInfoDialog, SIGNAL( triggered(bool) ) , this, SLOT( ShowInfoDialogForSelectedNodes(bool) ) ); unknownDataNodeDescriptor->AddAction(actionShowInfoDialog); m_DescriptorActionList.push_back(std::pair(unknownDataNodeDescriptor,actionShowInfoDialog)); QGridLayout* _DndFrameWidgetLayout = new QGridLayout; _DndFrameWidgetLayout->addWidget(m_NodeTreeView, 0, 0); _DndFrameWidgetLayout->setContentsMargins(0,0,0,0); m_DndFrameWidget = new QmitkDnDFrameWidget(m_Parent); m_DndFrameWidget->setLayout(_DndFrameWidgetLayout); QVBoxLayout* layout = new QVBoxLayout(parent); layout->addWidget(m_DndFrameWidget); layout->setContentsMargins(0,0,0,0); m_Parent->setLayout(layout); } void QmitkDataManagerView::SetFocus() { } void QmitkDataManagerView::ContextMenuActionTriggered( bool ) { QAction* action = qobject_cast ( sender() ); std::map::iterator it = m_ConfElements.find( action ); if( it == m_ConfElements.end() ) { MITK_WARN << "associated conf element for action " << action->text().toStdString() << " not found"; return; } berry::IConfigurationElement::Pointer confElem = it->second; mitk::IContextMenuAction* contextMenuAction = confElem->CreateExecutableExtension("class"); QString className = confElem->GetAttribute("class"); QString smoothed = confElem->GetAttribute("smoothed"); if(className == "QmitkCreatePolygonModelAction") { contextMenuAction->SetDataStorage(this->GetDataStorage()); if(smoothed == "false") { contextMenuAction->SetSmoothed(false); } else { contextMenuAction->SetSmoothed(true); } contextMenuAction->SetDecimated(m_SurfaceDecimation); } else if(className == "QmitkStatisticsAction") { contextMenuAction->SetFunctionality(this); } else if(className == "QmitkCreateSimulationAction") { contextMenuAction->SetDataStorage(this->GetDataStorage()); } contextMenuAction->Run( this->GetCurrentSelection() ); // run the action } void QmitkDataManagerView::OnPreferencesChanged(const berry::IBerryPreferences* prefs) { if( m_NodeTreeModel->GetPlaceNewNodesOnTopFlag() != prefs->GetBool("Place new nodes on top", true) ) m_NodeTreeModel->SetPlaceNewNodesOnTop( !m_NodeTreeModel->GetPlaceNewNodesOnTopFlag() ); bool hideHelperObjects = !prefs->GetBool("Show helper objects", false); if (m_FilterModel->HasFilterPredicate(m_HelperObjectFilterPredicate) != hideHelperObjects) { if (hideHelperObjects) { m_FilterModel->AddFilterPredicate(m_HelperObjectFilterPredicate); } else { m_FilterModel->RemoveFilterPredicate(m_HelperObjectFilterPredicate); } } bool hideNodesWithNoData = !prefs->GetBool("Show nodes containing no data", false); if (m_FilterModel->HasFilterPredicate(m_NodeWithNoDataFilterPredicate) != hideNodesWithNoData) { if (hideNodesWithNoData) { m_FilterModel->AddFilterPredicate(m_NodeWithNoDataFilterPredicate); } else { m_FilterModel->RemoveFilterPredicate(m_NodeWithNoDataFilterPredicate); } } m_GlobalReinitOnNodeDelete = prefs->GetBool("Call global reinit if node is deleted", true); m_NodeTreeView->expandAll(); m_SurfaceDecimation = prefs->GetBool("Use surface decimation", false); this->GlobalReinit(); } void QmitkDataManagerView::NodeTableViewContextMenuRequested( const QPoint & pos ) { QModelIndex selectedProxy = m_NodeTreeView->indexAt ( pos ); QModelIndex selected = m_FilterModel->mapToSource(selectedProxy); mitk::DataNode::Pointer node = m_NodeTreeModel->GetNode(selected); QList selectedNodes = this->GetCurrentSelection(); if(!selectedNodes.isEmpty()) { m_NodeMenu->clear(); QList actions; if(selectedNodes.size() == 1 ) { actions = QmitkNodeDescriptorManager::GetInstance()->GetActions(node); for(QList::iterator it = actions.begin(); it != actions.end(); ++it) { (*it)->setData(QVariant::fromValue(node.GetPointer())); } } else actions = QmitkNodeDescriptorManager::GetInstance()->GetActions(selectedNodes); if (!m_ShowInActions.isEmpty()) { QMenu* showInMenu = m_NodeMenu->addMenu("Show In"); showInMenu->addActions(m_ShowInActions); } m_NodeMenu->addActions(actions); m_NodeMenu->popup(QCursor::pos()); } } void QmitkDataManagerView::OpacityChanged(int value) { mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex())); if(node) { float opacity = static_cast(value)/100.0f; node->SetFloatProperty("opacity", opacity); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkDataManagerView::OpacityActionChanged() { mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex())); if(node) { float opacity = 0.0; if(node->GetFloatProperty("opacity", opacity)) { m_OpacitySlider->setValue(static_cast(opacity*100)); } } } void QmitkDataManagerView::ComponentActionChanged() { mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex())); mitk::IntProperty* componentProperty = NULL; int numComponents = 0; if(node) { componentProperty = dynamic_cast(node->GetProperty("Image.Displayed Component")); mitk::Image* img = dynamic_cast(node->GetData()); if (img != NULL) { numComponents = img->GetPixelType().GetNumberOfComponents(); } } if (componentProperty && numComponents > 1) { m_ComponentSlider->SetProperty(componentProperty); m_ComponentSlider->setMinValue(0); m_ComponentSlider->setMaxValue(numComponents-1); } else { m_ComponentSlider->SetProperty(static_cast(NULL)); } } void QmitkDataManagerView::ColorChanged() { mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex())); if(node) { mitk::Color color; mitk::ColorProperty::Pointer colorProp; node->GetProperty(colorProp,"color"); if(colorProp.IsNull()) return; color = colorProp->GetValue(); QColor initial(color.GetRed()*255,color.GetGreen()*255,color.GetBlue()*255); QColor qcolor = QColorDialog::getColor(initial,0,QString("Change color")); if (!qcolor.isValid()) return; m_ColorButton->setAutoFillBackground(true); node->SetProperty("color",mitk::ColorProperty::New(qcolor.red()/255.0,qcolor.green()/255.0,qcolor.blue()/255.0)); if (node->GetProperty("binaryimage.selectedcolor")) { node->SetProperty("binaryimage.selectedcolor",mitk::ColorProperty::New(qcolor.red()/255.0,qcolor.green()/255.0,qcolor.blue()/255.0)); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkDataManagerView::ColorActionChanged() { mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex())); if(node) { mitk::Color color; mitk::ColorProperty::Pointer colorProp; node->GetProperty(colorProp,"color"); if(colorProp.IsNull()) return; color = colorProp->GetValue(); QString styleSheet = "background-color:rgb("; styleSheet.append(QString::number(color[0]*255)); styleSheet.append(","); styleSheet.append(QString::number(color[1]*255)); styleSheet.append(","); styleSheet.append(QString::number(color[2]*255)); styleSheet.append(")"); m_ColorButton->setStyleSheet(styleSheet); } } void QmitkDataManagerView::TextureInterpolationChanged() { mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex())); if(node) { bool textureInterpolation = false; node->GetBoolProperty("texture interpolation", textureInterpolation); m_TextureInterpolation->setChecked(textureInterpolation); } } void QmitkDataManagerView::TextureInterpolationToggled( bool checked ) { mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex())); if(node) { node->SetBoolProperty("texture interpolation", checked); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkDataManagerView::ColormapActionToggled( bool /*checked*/ ) { mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex())); if(!node) return; mitk::LookupTableProperty::Pointer lookupTableProperty = dynamic_cast(node->GetProperty("LookupTable")); if (!lookupTableProperty) return; QAction* senderAction = qobject_cast(QObject::sender()); if(!senderAction) return; std::string activatedItem = senderAction->text().toStdString(); mitk::LookupTable::Pointer lookupTable = lookupTableProperty->GetValue(); if (!lookupTable) return; lookupTable->SetType(activatedItem); lookupTableProperty->SetValue(lookupTable); mitk::RenderingModeProperty::Pointer renderingMode = dynamic_cast(node->GetProperty("Image Rendering.Mode")); renderingMode->SetValue(mitk::RenderingModeProperty::LOOKUPTABLE_LEVELWINDOW_COLOR); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkDataManagerView::ColormapMenuAboutToShow() { mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex())); if(!node) return; mitk::LookupTableProperty::Pointer lookupTableProperty = dynamic_cast(node->GetProperty("LookupTable")); if (!lookupTableProperty) { mitk::LookupTable::Pointer mitkLut = mitk::LookupTable::New(); lookupTableProperty = mitk::LookupTableProperty::New(); lookupTableProperty->SetLookupTable(mitkLut); node->SetProperty("LookupTable", lookupTableProperty); } mitk::LookupTable::Pointer lookupTable = lookupTableProperty->GetValue(); if (!lookupTable) return; m_ColormapAction->menu()->clear(); QAction* tmp; int i = 0; std::string lutType = lookupTable->typenameList[i]; while (lutType != "END_OF_ARRAY") { tmp = m_ColormapAction->menu()->addAction(QString::fromStdString(lutType)); tmp->setCheckable(true); if (lutType == lookupTable->GetActiveTypeAsString()) { tmp->setChecked(true); } QObject::connect(tmp, SIGNAL(triggered(bool)), this, SLOT(ColormapActionToggled(bool))); lutType = lookupTable->typenameList[++i]; } } void QmitkDataManagerView::SurfaceRepresentationMenuAboutToShow() { mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex())); if(!node) return; mitk::EnumerationProperty* representationProp = dynamic_cast (node->GetProperty("material.representation")); if(!representationProp) return; // clear menu m_SurfaceRepresentation->menu()->clear(); QAction* tmp; // create menu entries for(mitk::EnumerationProperty::EnumConstIterator it=representationProp->Begin(); it!=representationProp->End() ; it++) { tmp = m_SurfaceRepresentation->menu()->addAction(QString::fromStdString(it->second)); tmp->setCheckable(true); if(it->second == representationProp->GetValueAsString()) { tmp->setChecked(true); } QObject::connect( tmp, SIGNAL( triggered(bool) ) , this, SLOT( SurfaceRepresentationActionToggled(bool) ) ); } } void QmitkDataManagerView::SurfaceRepresentationActionToggled( bool /*checked*/ ) { mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex())); if(!node) return; mitk::EnumerationProperty* representationProp = dynamic_cast (node->GetProperty("material.representation")); if(!representationProp) return; QAction* senderAction = qobject_cast ( QObject::sender() ); if(!senderAction) return; std::string activatedItem = senderAction->text().toStdString(); if ( activatedItem != representationProp->GetValueAsString() ) { if ( representationProp->IsValidEnumerationValue( activatedItem ) ) { representationProp->SetValue( activatedItem ); representationProp->InvokeEvent( itk::ModifiedEvent() ); representationProp->Modified(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } } void QmitkDataManagerView::ReinitSelectedNodes( bool ) { mitk::IRenderWindowPart* renderWindow = this->GetRenderWindowPart(); if (renderWindow == NULL) renderWindow = this->OpenRenderWindowPart(false); QList selectedNodes = this->GetCurrentSelection(); foreach(mitk::DataNode::Pointer node, selectedNodes) { mitk::BaseData::Pointer basedata = node->GetData(); if ( basedata.IsNotNull() && basedata->GetTimeGeometry()->IsValid() ) { renderWindow->GetRenderingManager()->InitializeViews( basedata->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true ); } } } void QmitkDataManagerView::RemoveSelectedNodes( bool ) { QModelIndexList indexesOfSelectedRowsFiltered = m_NodeTreeView->selectionModel()->selectedRows(); QModelIndexList indexesOfSelectedRows; for (int i = 0; i < indexesOfSelectedRowsFiltered.size(); ++i) { indexesOfSelectedRows.push_back(m_FilterModel->mapToSource(indexesOfSelectedRowsFiltered[i])); } if(indexesOfSelectedRows.size() < 1) { return; } std::vector selectedNodes; mitk::DataNode::Pointer node = 0; QString question = tr("Do you really want to remove "); for (QModelIndexList::iterator it = indexesOfSelectedRows.begin() ; it != indexesOfSelectedRows.end(); it++) { node = m_NodeTreeModel->GetNode(*it); // if node is not defined or if the node contains geometry data do not remove it if ( node.IsNotNull() /*& strcmp(node->GetData()->GetNameOfClass(), "PlaneGeometryData") != 0*/ ) { selectedNodes.push_back(node); question.append(QString::fromStdString(node->GetName())); question.append(", "); } } // remove the last two characters = ", " question = question.remove(question.size()-2, 2); question.append(" from data storage?"); QMessageBox::StandardButton answerButton = QMessageBox::question( m_Parent , tr("DataManager") , question , QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); if(answerButton == QMessageBox::Yes) { for (std::vector::iterator it = selectedNodes.begin() ; it != selectedNodes.end(); it++) { node = *it; this->GetDataStorage()->Remove(node); if (m_GlobalReinitOnNodeDelete) this->GlobalReinit(false); } } } void QmitkDataManagerView::MakeAllNodesInvisible( bool ) { QList nodes = m_NodeTreeModel->GetNodeSet(); foreach(mitk::DataNode::Pointer node, nodes) { node->SetVisibility(false); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkDataManagerView::ShowOnlySelectedNodes( bool ) { QList selectedNodes = this->GetCurrentSelection(); QList allNodes = m_NodeTreeModel->GetNodeSet(); foreach(mitk::DataNode::Pointer node, allNodes) { node->SetVisibility(selectedNodes.contains(node)); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkDataManagerView::ToggleVisibilityOfSelectedNodes( bool ) { QList selectedNodes = this->GetCurrentSelection(); bool isVisible = false; foreach(mitk::DataNode::Pointer node, selectedNodes) { isVisible = false; node->GetBoolProperty("visible", isVisible); node->SetVisibility(!isVisible); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkDataManagerView::ShowInfoDialogForSelectedNodes( bool ) { QList selectedNodes = this->GetCurrentSelection(); QmitkInfoDialog _QmitkInfoDialog(selectedNodes, this->m_Parent); _QmitkInfoDialog.exec(); } void QmitkDataManagerView::NodeChanged(const mitk::DataNode* /*node*/) { // m_FilterModel->invalidate(); // fix as proposed by R. Khlebnikov in the mitk-users mail from 02.09.2014 QMetaObject::invokeMethod( m_FilterModel, "invalidate", Qt::QueuedConnection ); } QItemSelectionModel *QmitkDataManagerView::GetDataNodeSelectionModel() const { return m_NodeTreeView->selectionModel(); } void QmitkDataManagerView::GlobalReinit( bool ) { mitk::IRenderWindowPart* renderWindow = this->GetRenderWindowPart(); if (renderWindow == NULL) renderWindow = this->OpenRenderWindowPart(false); // no render window available if (renderWindow == NULL) return; mitk::RenderingManager::GetInstance()->InitializeViewsByBoundingObjects(this->GetDataStorage()); } void QmitkDataManagerView::NodeTreeViewRowsRemoved ( const QModelIndex & /*parent*/, int /*start*/, int /*end*/ ) { m_CurrentRowCount = m_NodeTreeModel->rowCount(); } void QmitkDataManagerView::NodeTreeViewRowsInserted( const QModelIndex & parent, int, int ) { QModelIndex viewIndex = m_FilterModel->mapFromSource(parent); m_NodeTreeView->setExpanded(viewIndex, true); // a new row was inserted if( m_CurrentRowCount == 0 && m_NodeTreeModel->rowCount() == 1 ) { this->OpenRenderWindowPart(); m_CurrentRowCount = m_NodeTreeModel->rowCount(); } } void QmitkDataManagerView::NodeSelectionChanged( const QItemSelection & /*selected*/, const QItemSelection & /*deselected*/ ) { QList nodes = m_NodeTreeModel->GetNodeSet(); foreach(mitk::DataNode::Pointer node, nodes) { if ( node.IsNotNull() ) node->SetBoolProperty("selected", false); } nodes.clear(); nodes = this->GetCurrentSelection(); foreach(mitk::DataNode::Pointer node, nodes) { if ( node.IsNotNull() ) node->SetBoolProperty("selected", true); } //changing the selection does NOT require any rendering processes! //mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkDataManagerView::ShowIn(const QString &editorId) { berry::IWorkbenchPage::Pointer page = this->GetSite()->GetPage(); berry::IEditorInput::Pointer input(new mitk::DataStorageEditorInput(this->GetDataStorageReference())); page->OpenEditor(input, editorId, false, berry::IWorkbenchPage::MATCH_ID); } mitk::IRenderWindowPart* QmitkDataManagerView::OpenRenderWindowPart(bool activatedEditor) { if (activatedEditor) { return this->GetRenderWindowPart(QmitkAbstractView::ACTIVATE | QmitkAbstractView::OPEN); } else { return this->GetRenderWindowPart(QmitkAbstractView::BRING_TO_FRONT | QmitkAbstractView::OPEN); } } diff --git a/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkPropertyItemDelegate.cpp b/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkPropertyItemDelegate.cpp index c810ea070b..dc86dc93bf 100644 --- a/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkPropertyItemDelegate.cpp +++ b/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkPropertyItemDelegate.cpp @@ -1,384 +1,388 @@ /*=================================================================== 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 "mitkGetPropertyService.h" #include "QmitkPropertyItemDelegate.h" #include "QmitkPropertyItemModel.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include QmitkColorWidget::QmitkColorWidget(QWidget* parent) : QWidget(parent), m_LineEdit(new QLineEdit), m_Button(new QToolButton) { m_LineEdit->setText(m_Color.name()); m_Button->setText("..."); QHBoxLayout* layout = new QHBoxLayout; layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(0); layout->addWidget(m_LineEdit); layout->addWidget(m_Button); this->setFocusProxy(m_LineEdit); this->setLayout(layout); connect(m_LineEdit, SIGNAL(editingFinished()), this, SLOT(OnLineEditEditingFinished())); connect(m_Button, SIGNAL(clicked()), this, SLOT(OnButtonClicked())); } QmitkColorWidget::~QmitkColorWidget() { } QColor QmitkColorWidget::GetColor() const { return m_Color; } void QmitkColorWidget::SetColor(QColor color) { m_Color = color; m_LineEdit->setText(color.name()); } void QmitkColorWidget::OnLineEditEditingFinished() { if (!QColor::isValidColor(m_LineEdit->text())) m_LineEdit->setText("#000000"); m_Color.setNamedColor(m_LineEdit->text()); } void QmitkColorWidget::OnButtonClicked() { QColor color = QColorDialog::getColor(m_Color, QApplication::activeWindow()); if (color.isValid()) { this->SetColor(color); emit ColorPicked(); } } QmitkComboBoxListView::QmitkComboBoxListView(QComboBox* comboBox) : m_ComboBox(comboBox) { } QmitkComboBoxListView::~QmitkComboBoxListView() { } void QmitkComboBoxListView::paintEvent(QPaintEvent* event) { if (m_ComboBox != NULL) { QStyleOptionComboBox option; option.initFrom(m_ComboBox); option.editable = m_ComboBox->isEditable(); if (m_ComboBox->style()->styleHint(QStyle::SH_ComboBox_Popup, &option, m_ComboBox)) { QStyleOptionMenuItem menuOption; menuOption.initFrom(this); menuOption.palette = this->palette(); menuOption.state = QStyle::State_None; menuOption.checkType = QStyleOptionMenuItem::NotCheckable; menuOption.menuRect = event->rect(); menuOption.maxIconWidth = 0; menuOption.tabWidth = 0; QPainter painter(this->viewport()); m_ComboBox->style()->drawControl(QStyle::CE_MenuEmptyArea, &menuOption, &painter, this); } } QListView::paintEvent(event); } void QmitkComboBoxListView::resizeEvent(QResizeEvent* event) { int width = this->viewport()->width(); int height = this->contentsSize().height(); this->resizeContents(width, height); QListView::resizeEvent(event); } QStyleOptionViewItem QmitkComboBoxListView::viewOptions() const { QStyleOptionViewItem option = QListView::viewOptions(); option.showDecorationSelected = true; if (m_ComboBox != NULL) option.font = m_ComboBox->font(); return option; } class PropertyEqualTo { public: PropertyEqualTo(const mitk::BaseProperty* property) : m_Property(property) { } bool operator()(const mitk::PropertyList::PropertyMapElementType& pair) const { return pair.second.GetPointer() == m_Property; } private: const mitk::BaseProperty* m_Property; }; QmitkPropertyItemDelegate::QmitkPropertyItemDelegate(QObject* parent) : QStyledItemDelegate(parent) { } QmitkPropertyItemDelegate::~QmitkPropertyItemDelegate() { } QWidget* QmitkPropertyItemDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const { QVariant data = index.data(Qt::EditRole); if (data.isValid()) { if (data.type() == QVariant::Int) { QSpinBox* spinBox = new QSpinBox(parent); mitk::IPropertyExtensions* extensions = mitk::GetPropertyService(); std::string name = this->GetPropertyName(index); if (extensions != NULL && !name.empty() && extensions->HasExtension(name)) { mitk::IntPropertyExtension::Pointer extension = dynamic_cast(extensions->GetExtension(name).GetPointer()); if (extension.IsNotNull()) { spinBox->setMinimum(extension->GetMinimum()); spinBox->setMaximum(extension->GetMaximum()); spinBox->setSingleStep(extension->GetSingleStep()); } } connect(spinBox, SIGNAL(editingFinished()), this, SLOT(OnSpinBoxEditingFinished())); return spinBox; } if (data.type() == QVariant::Double || static_cast(data.type()) == QMetaType::Float) { QDoubleSpinBox* spinBox = new QDoubleSpinBox(parent); mitk::IPropertyExtensions* extensions = mitk::GetPropertyService(); std::string name = this->GetPropertyName(index); if (extensions != NULL && !name.empty() && extensions->HasExtension(name)) { mitk::FloatPropertyExtension::Pointer extension = dynamic_cast(extensions->GetExtension(name).GetPointer()); if (extension.IsNotNull()) { spinBox->setMinimum(extension->GetMinimum()); spinBox->setMaximum(extension->GetMaximum()); spinBox->setSingleStep(extension->GetSingleStep()); spinBox->setDecimals(extension->GetDecimals()); } } else { spinBox->setSingleStep(0.1); spinBox->setDecimals(4); } if (name == "opacity") // TODO { spinBox->setMinimum(0.0); spinBox->setMaximum(1.0); } + if (name == "ScalarsRangeMaximum" || name == "ScalarsRangeMinimum") + { + spinBox->setMaximum(5000); + } connect(spinBox, SIGNAL(editingFinished()), this, SLOT(OnSpinBoxEditingFinished())); return spinBox; } if (data.type() == QVariant::StringList) { QComboBox* comboBox = new QComboBox(parent); comboBox->setView(new QmitkComboBoxListView(comboBox)); comboBox->addItems(data.toStringList()); connect(comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(OnComboBoxCurrentIndexChanged(int))); return comboBox; } if (data.type() == QVariant::Color) { QmitkColorWidget* colorWidget = new QmitkColorWidget(parent); connect(colorWidget, SIGNAL(ColorPicked()), this, SLOT(OnColorPicked())); return colorWidget; } } return QStyledItemDelegate::createEditor(parent, option, index); } std::string QmitkPropertyItemDelegate::GetPropertyName(const QModelIndex& index) const { if (m_PropertyList.IsNotNull()) { mitk::BaseProperty* property = reinterpret_cast(index.data(mitk::PropertyRole).value()); const mitk::PropertyList::PropertyMap* propertyMap = m_PropertyList->GetMap(); mitk::PropertyList::PropertyMap::const_iterator it = std::find_if(propertyMap->begin(), propertyMap->end(), PropertyEqualTo(property)); if (it != propertyMap->end()) return it->first; } return ""; } void QmitkPropertyItemDelegate::OnComboBoxCurrentIndexChanged(int) { QComboBox* comboBox = qobject_cast(sender()); emit commitData(comboBox); emit closeEditor(comboBox); } void QmitkPropertyItemDelegate::OnSpinBoxEditingFinished() { QAbstractSpinBox* spinBox = qobject_cast(sender()); emit commitData(spinBox); emit closeEditor(spinBox); } void QmitkPropertyItemDelegate::OnColorPicked() { QmitkColorWidget* colorWidget = qobject_cast(sender()); emit commitData(colorWidget); emit closeEditor(colorWidget); } void QmitkPropertyItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { QVariant data = index.data(); if (index.column() == 1 && data.type() == QVariant::Color) { painter->fillRect(option.rect, data.value()); return; } QStyledItemDelegate::paint(painter, option, index); } void QmitkPropertyItemDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const { QVariant data = index.data(Qt::EditRole); if (!data.isValid()) return; if (data.type() == QVariant::StringList) { QComboBox* comboBox = qobject_cast(editor); comboBox->setCurrentIndex(comboBox->findText(index.data().toString())); } if (data.type() == QVariant::Color) { QmitkColorWidget* colorWidget = qobject_cast(editor); colorWidget->SetColor(data.value()); } else { QStyledItemDelegate::setEditorData(editor, index); } } void QmitkPropertyItemDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const { QVariant data = index.data(Qt::EditRole); if (!data.isValid()) return; if (data.type() == QVariant::Int) { QSpinBox* spinBox = qobject_cast(editor); model->setData(index, spinBox->value()); } else if (data.type() == QVariant::Double) { QDoubleSpinBox* spinBox = qobject_cast(editor); model->setData(index, spinBox->value()); } else if (static_cast(data.type()) == QMetaType::Float) { QDoubleSpinBox* spinBox = qobject_cast(editor); model->setData(index, static_cast(spinBox->value())); } else if (data.type() == QVariant::StringList) { QComboBox* comboBox = qobject_cast(editor); model->setData(index, comboBox->currentText()); } else if (data.type() == QVariant::Color) { QmitkColorWidget* colorWidget = qobject_cast(editor); model->setData(index, colorWidget->GetColor()); } else { QStyledItemDelegate::setModelData(editor, model, index); } } void QmitkPropertyItemDelegate::SetPropertyList(mitk::PropertyList* propertyList) { if (m_PropertyList.GetPointer() != propertyList) m_PropertyList = propertyList; } diff --git a/Plugins/org.mitk.gui.qt.registration/src/internal/QmitkPointBasedRegistrationView.cpp b/Plugins/org.mitk.gui.qt.registration/src/internal/QmitkPointBasedRegistrationView.cpp index 429aec90a8..a47bee748e 100644 --- a/Plugins/org.mitk.gui.qt.registration/src/internal/QmitkPointBasedRegistrationView.cpp +++ b/Plugins/org.mitk.gui.qt.registration/src/internal/QmitkPointBasedRegistrationView.cpp @@ -1,1326 +1,1313 @@ /*=================================================================== 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 "QmitkPointBasedRegistrationView.h" #include "ui_QmitkPointBasedRegistrationViewControls.h" #include "QmitkPointListWidget.h" #include #include #include #include "vtkPolyData.h" #include #include #include "qradiobutton.h" #include "qapplication.h" #include #include #include #include #include "qmessagebox.h" #include "mitkLandmarkWarping.h" #include #include "mitkOperationEvent.h" #include "mitkUndoController.h" #include "mitkNodePredicateDataType.h" #include "mitkNodePredicateProperty.h" #include "mitkNodePredicateAnd.h" #include "mitkNodePredicateNot.h" #include #include +#include + #include #include "mitkDataNodeObject.h" #include "berryIWorkbenchWindow.h" #include "berryISelectionService.h" +#include + const std::string QmitkPointBasedRegistrationView::VIEW_ID = "org.mitk.views.pointbasedregistration"; using namespace berry; struct SelListenerPointBasedRegistration : ISelectionListener { berryObjectMacro(SelListenerPointBasedRegistration); SelListenerPointBasedRegistration(QmitkPointBasedRegistrationView* view) { m_View = view; } void DoSelectionChanged(ISelection::ConstPointer selection) { // if(!m_View->IsVisible()) // return; // save current selection in member variable m_View->m_CurrentSelection = selection.Cast(); // do something with the selected items if(m_View->m_CurrentSelection) { if (m_View->m_CurrentSelection->Size() != 2) { if (m_View->m_FixedNode.IsNull() || m_View->m_MovingNode.IsNull()) { m_View->m_Controls.m_StatusLabel->show(); m_View->m_Controls.TextLabelFixed->hide(); m_View->m_Controls.m_FixedLabel->hide(); m_View->m_Controls.line2->hide(); m_View->m_Controls.m_FixedPointListWidget->hide(); m_View->m_Controls.TextLabelMoving->hide(); m_View->m_Controls.m_MovingLabel->hide(); m_View->m_Controls.line1->hide(); m_View->m_Controls.m_MovingPointListWidget->hide(); m_View->m_Controls.m_OpacityLabel->hide(); m_View->m_Controls.m_OpacitySlider->hide(); m_View->m_Controls.label->hide(); m_View->m_Controls.label_2->hide(); m_View->m_Controls.m_SwitchImages->hide(); m_View->m_Controls.m_ShowRedGreenValues->setEnabled(false); } } else { m_View->m_Controls.m_StatusLabel->hide(); - bool foundFixedImage = false; + bool foundFixedNode = false; mitk::DataNode::Pointer fixedNode; // iterate selection for (IStructuredSelection::iterator i = m_View->m_CurrentSelection->Begin(); i != m_View->m_CurrentSelection->End(); ++i) { // extract datatree node if (mitk::DataNodeObject::Pointer nodeObj = i->Cast()) { mitk::TNodePredicateDataType::Pointer isBaseData(mitk::TNodePredicateDataType::New()); mitk::TNodePredicateDataType::Pointer isPointSet(mitk::TNodePredicateDataType::New()); mitk::NodePredicateNot::Pointer notPointSet = mitk::NodePredicateNot::New(isPointSet); mitk::TNodePredicateDataType::Pointer isPlaneGeometryData(mitk::TNodePredicateDataType::New()); mitk::NodePredicateNot::Pointer notPlaneGeometryData = mitk::NodePredicateNot::New(isPlaneGeometryData); mitk::NodePredicateAnd::Pointer notPointSetAndNotPlaneGeometryData = mitk::NodePredicateAnd::New( notPointSet, notPlaneGeometryData ); mitk::NodePredicateAnd::Pointer predicate = mitk::NodePredicateAnd::New( isBaseData, notPointSetAndNotPlaneGeometryData ); mitk::DataStorage::SetOfObjects::ConstPointer setOfObjects = m_View->GetDataStorage()->GetSubset(predicate); mitk::DataNode::Pointer node = nodeObj->GetDataNode(); // only look at interesting types for (mitk::DataStorage::SetOfObjects::ConstIterator nodeIt = setOfObjects->Begin() ; nodeIt != setOfObjects->End(); ++nodeIt) // for each node { if(nodeIt->Value().GetPointer() == node.GetPointer()) { // was - compare() // use contain to allow other Image types to be selected, i.e. a diffusion image - if (QString( node->GetData()->GetNameOfClass() ).contains("Image") ) + if ( (QString( node->GetData()->GetNameOfClass() ).contains("Image") ) + || (QString( node->GetData()->GetNameOfClass() ).contains("Surface") ) ) { // verify that the node selected by name is really an image or derived class - mitk::Image* _image = dynamic_cast(node->GetData()); - if (_image != NULL) + mitk::BaseData* _basedata = dynamic_cast( node->GetData() ); + + // one of the data + if (_basedata != nullptr ) { - if( _image->GetDimension() == 4) + if( _basedata->GetTimeSteps() > 3 ) { m_View->m_Controls.m_StatusLabel->show(); - QMessageBox::information( NULL, "PointBasedRegistration", "Only 2D or 3D images can be processed.", QMessageBox::Ok ); + QMessageBox::information( NULL, "PointBasedRegistration", "Only 2D or 3D objects can be processed.", QMessageBox::Ok ); return; } - if (foundFixedImage == false) + + // for first, allow image and surfaces to be selected + mitk::Image::Pointer input_image = dynamic_cast(node->GetData()); + mitk::Surface::Pointer input_surface = dynamic_cast(node->GetData()); + + if ( ( input_image.IsNotNull() || input_surface.IsNotNull() ) && foundFixedNode == false ) { fixedNode = node; - foundFixedImage = true; + foundFixedNode = true; } else { - // method deleted for more information see bug-18492 + // method deleted, for more information see bug-18492 // m_View->SetImagesVisible(selection); m_View->FixedSelected(fixedNode); m_View->MovingSelected(node); m_View->m_Controls.m_StatusLabel->hide(); m_View->m_Controls.TextLabelFixed->show(); m_View->m_Controls.m_FixedLabel->show(); m_View->m_Controls.line2->show(); m_View->m_Controls.m_FixedPointListWidget->show(); m_View->m_Controls.TextLabelMoving->show(); m_View->m_Controls.m_MovingLabel->show(); m_View->m_Controls.line1->show(); m_View->m_Controls.m_MovingPointListWidget->show(); m_View->m_Controls.m_OpacityLabel->show(); m_View->m_Controls.m_OpacitySlider->show(); m_View->m_Controls.label->show(); m_View->m_Controls.label_2->show(); m_View->m_Controls.m_SwitchImages->show(); m_View->m_Controls.m_ShowRedGreenValues->setEnabled(true); } } } else { m_View->m_Controls.m_StatusLabel->show(); return; } } } } } if (m_View->m_FixedNode.IsNull() || m_View->m_MovingNode.IsNull()) { m_View->m_Controls.m_StatusLabel->show(); } } } else if (m_View->m_FixedNode.IsNull() || m_View->m_MovingNode.IsNull()) { m_View->m_Controls.m_StatusLabel->show(); } } void SelectionChanged(const IWorkbenchPart::Pointer& part, const ISelection::ConstPointer& selection) override { // check, if selection comes from datamanager if (part) { QString partname = part->GetPartName(); if(partname == "Data Manager") { // apply selection DoSelectionChanged(selection); } } } QmitkPointBasedRegistrationView* m_View; }; QmitkPointBasedRegistrationView::QmitkPointBasedRegistrationView(QObject * /*parent*/, const char * /*name*/) : QmitkFunctionality(), m_MultiWidget(NULL), m_FixedLandmarks(NULL), m_MovingLandmarks(NULL), m_MovingNode(NULL), -m_FixedNode(NULL), m_ShowRedGreen(false), m_Opacity(0.5), m_OriginalOpacity(1.0), m_Transformation(0), m_HideFixedImage(false), m_HideMovingImage(false), +m_FixedNode(NULL), m_ShowRedGreen(false), m_Opacity(0.5), m_OriginalOpacity(1.0), m_Transformation(0), m_LastTransformMatrix(nullptr), m_HideFixedImage(false), m_HideMovingImage(false), m_OldFixedLabel(""), m_OldMovingLabel(""), m_Deactivated (false), m_CurrentFixedLandmarksObserverID(0), m_CurrentMovingLandmarksObserverID(0) { m_FixedLandmarksChangedCommand = itk::SimpleMemberCommand::New(); m_FixedLandmarksChangedCommand->SetCallbackFunction(this, &QmitkPointBasedRegistrationView::updateFixedLandmarksList); m_MovingLandmarksChangedCommand = itk::SimpleMemberCommand::New(); m_MovingLandmarksChangedCommand->SetCallbackFunction(this, &QmitkPointBasedRegistrationView::updateMovingLandmarksList); this->GetDataStorage()->RemoveNodeEvent.AddListener(mitk::MessageDelegate1 ( this, &QmitkPointBasedRegistrationView::DataNodeHasBeenRemoved )); } QmitkPointBasedRegistrationView::~QmitkPointBasedRegistrationView() { if(m_SelListener) { berry::ISelectionService* s = GetSite()->GetWorkbenchWindow()->GetSelectionService(); if(s) s->RemovePostSelectionListener(m_SelListener.data()); } if (m_FixedPointSetNode.IsNotNull()) { m_Controls.m_FixedPointListWidget->DeactivateInteractor(true); m_FixedPointSetNode->SetProperty("label", mitk::StringProperty::New(m_OldFixedLabel)); } if (m_MovingPointSetNode.IsNotNull()) { m_Controls.m_MovingPointListWidget->DeactivateInteractor(true); m_MovingPointSetNode->SetProperty("label", mitk::StringProperty::New(m_OldMovingLabel)); } m_Controls.m_FixedPointListWidget->SetPointSetNode(NULL); m_Controls.m_MovingPointListWidget->SetPointSetNode(NULL); } void QmitkPointBasedRegistrationView::CreateQtPartControl(QWidget* parent) { m_Controls.setupUi(parent); m_Parent->setEnabled(false); m_Controls.m_MeanErrorLCD->hide(); m_Controls.m_MeanError->hide(); m_Controls.TextLabelFixed->hide(); m_Controls.line2->hide(); m_Controls.m_FixedPointListWidget->hide(); m_Controls.m_FixedLabel->hide(); m_Controls.TextLabelMoving->hide(); m_Controls.m_MovingLabel->hide(); m_Controls.line1->hide(); m_Controls.m_MovingPointListWidget->hide(); m_Controls.m_OpacityLabel->hide(); m_Controls.m_OpacitySlider->hide(); m_Controls.label->hide(); m_Controls.label_2->hide(); m_Controls.m_SwitchImages->hide(); m_Controls.m_ShowRedGreenValues->setEnabled(false); this->CreateConnections(); // let the point set widget know about the multi widget (cross hair updates) m_Controls.m_FixedPointListWidget->SetMultiWidget( m_MultiWidget ); m_Controls.m_MovingPointListWidget->SetMultiWidget( m_MultiWidget ); } void QmitkPointBasedRegistrationView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget) { m_Parent->setEnabled(true); m_MultiWidget = &stdMultiWidget; m_MultiWidget->SetWidgetPlanesVisibility(true); m_Controls.m_FixedPointListWidget->SetMultiWidget( m_MultiWidget ); m_Controls.m_MovingPointListWidget->SetMultiWidget( m_MultiWidget ); } void QmitkPointBasedRegistrationView::StdMultiWidgetNotAvailable() { m_Parent->setEnabled(false); m_MultiWidget = NULL; m_Controls.m_FixedPointListWidget->SetMultiWidget( NULL ); m_Controls.m_MovingPointListWidget->SetMultiWidget( NULL ); } void QmitkPointBasedRegistrationView::CreateConnections() { connect( (QObject*)(m_Controls.m_FixedPointListWidget), SIGNAL(EditPointSets(bool)), (QObject*)(m_Controls.m_MovingPointListWidget), SLOT(DeactivateInteractor(bool))); connect( (QObject*)(m_Controls.m_MovingPointListWidget), SIGNAL(EditPointSets(bool)), (QObject*)(m_Controls.m_FixedPointListWidget), SLOT(DeactivateInteractor(bool))); connect( (QObject*)(m_Controls.m_FixedPointListWidget), SIGNAL(EditPointSets(bool)), this, SLOT(HideMovingImage(bool))); connect( (QObject*)(m_Controls.m_MovingPointListWidget), SIGNAL(EditPointSets(bool)), this, SLOT(HideFixedImage(bool))); connect( (QObject*)(m_Controls.m_FixedPointListWidget), SIGNAL(PointListChanged()), this, SLOT(updateFixedLandmarksList())); connect( (QObject*)(m_Controls.m_MovingPointListWidget), SIGNAL(PointListChanged()), this, SLOT(updateMovingLandmarksList())); connect((QObject*)(m_Controls.m_Calculate),SIGNAL(clicked()),this,SLOT(calculate())); connect((QObject*)(m_Controls.m_SwitchImages),SIGNAL(clicked()),this,SLOT(SwitchImages())); connect((QObject*)(m_Controls.m_UndoTransformation),SIGNAL(clicked()),this,SLOT(UndoTransformation())); connect((QObject*)(m_Controls.m_RedoTransformation),SIGNAL(clicked()),this,SLOT(RedoTransformation())); connect((QObject*)(m_Controls.m_ShowRedGreenValues),SIGNAL(toggled(bool)),this,SLOT(showRedGreen(bool))); connect((QObject*)(m_Controls.m_OpacitySlider),SIGNAL(valueChanged(int)),this,SLOT(OpacityUpdate(int))); connect((QObject*)(m_Controls.m_SelectedTransformationClass),SIGNAL(activated(int)), this,SLOT(transformationChanged(int))); connect((QObject*)(m_Controls.m_UseICP),SIGNAL(toggled(bool)), this,SLOT(checkCalculateEnabled())); connect((QObject*)(m_Controls.m_UseICP),SIGNAL(toggled(bool)), this,SLOT(checkLandmarkError())); + connect((QObject*)(m_Controls.m_SaveLastTransformPushButton), SIGNAL(clicked()), this, SLOT(OnExportTransformButtonPushed() ) ); } void QmitkPointBasedRegistrationView::Activated() { m_Deactivated = false; mitk::RenderingManager::GetInstance()->RequestUpdateAll(); QmitkFunctionality::Activated(); this->clearTransformationLists(); if (m_SelListener.isNull()) { m_SelListener.reset(new SelListenerPointBasedRegistration(this)); this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->AddPostSelectionListener(/*"org.mitk.views.datamanager",*/ m_SelListener.data()); berry::ISelection::ConstPointer sel( this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->GetSelection("org.mitk.views.datamanager")); m_CurrentSelection = sel.Cast(); static_cast(m_SelListener.data())->DoSelectionChanged(sel); } this->OpacityUpdate(m_Controls.m_OpacitySlider->value()); this->showRedGreen(m_Controls.m_ShowRedGreenValues->isChecked()); } void QmitkPointBasedRegistrationView::Visible() { } void QmitkPointBasedRegistrationView::Deactivated() { m_Deactivated = true; if (m_FixedPointSetNode.IsNotNull()) m_FixedPointSetNode->SetProperty("label", mitk::StringProperty::New(m_OldFixedLabel)); m_Controls.m_FixedPointListWidget->SetPointSetNode(NULL); m_Controls.m_FixedPointListWidget->DeactivateInteractor(true); if (m_MovingPointSetNode.IsNotNull()) m_MovingPointSetNode->SetProperty("label", mitk::StringProperty::New(m_OldMovingLabel)); m_Controls.m_MovingPointListWidget->SetPointSetNode(NULL); m_Controls.m_MovingPointListWidget->DeactivateInteractor(true); this->setImageColor(false); if (m_FixedNode.IsNotNull()) m_FixedNode->SetOpacity(1.0); if (m_MovingNode.IsNotNull()) { m_MovingNode->SetOpacity(m_OriginalOpacity); } this->clearTransformationLists(); if (m_FixedPointSetNode.IsNotNull() && m_FixedLandmarks.IsNotNull() && m_FixedLandmarks->GetSize() == 0) { this->GetDataStorage()->Remove(m_FixedPointSetNode); } if (m_MovingPointSetNode.IsNotNull() && m_MovingLandmarks.IsNotNull() && m_MovingLandmarks->GetSize() == 0) { this->GetDataStorage()->Remove(m_MovingPointSetNode); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); m_FixedNode = NULL; m_MovingNode = NULL; if(m_FixedLandmarks.IsNotNull()) m_FixedLandmarks->RemoveObserver(m_CurrentFixedLandmarksObserverID); m_FixedLandmarks = NULL; if(m_MovingLandmarks.IsNotNull()) m_MovingLandmarks->RemoveObserver(m_CurrentMovingLandmarksObserverID); m_MovingLandmarks = NULL; m_FixedPointSetNode = NULL; m_MovingPointSetNode = NULL; m_Controls.m_FixedLabel->hide(); m_Controls.TextLabelFixed->hide(); m_Controls.line2->hide(); m_Controls.m_FixedPointListWidget->hide(); m_Controls.m_MovingLabel->hide(); m_Controls.TextLabelMoving->hide(); m_Controls.line1->hide(); m_Controls.m_MovingPointListWidget->hide(); m_Controls.m_OpacityLabel->hide(); m_Controls.m_OpacitySlider->hide(); m_Controls.label->hide(); m_Controls.label_2->hide(); m_Controls.m_SwitchImages->hide(); berry::ISelectionService* s = GetSite()->GetWorkbenchWindow()->GetSelectionService(); if(s) s->RemovePostSelectionListener(m_SelListener.data()); m_SelListener.reset(); } void QmitkPointBasedRegistrationView::Hidden() { - /* - m_Deactivated = true; - if (m_FixedPointSetNode.IsNotNull()) - m_FixedPointSetNode->SetProperty("label", mitk::StringProperty::New(m_OldFixedLabel)); - m_Controls.m_FixedPointListWidget->SetPointSetNode(NULL); - m_Controls.m_FixedPointListWidget->DeactivateInteractor(true); - if (m_MovingPointSetNode.IsNotNull()) - m_MovingPointSetNode->SetProperty("label", mitk::StringProperty::New(m_OldMovingLabel)); - m_Controls.m_MovingPointListWidget->SetPointSetNode(NULL); - m_Controls.m_MovingPointListWidget->DeactivateInteractor(true); - this->setImageColor(false); - if (m_MovingNode.IsNotNull()) - { - m_MovingNode->SetOpacity(m_OriginalOpacity); - } - this->clearTransformationLists(); - if (m_FixedPointSetNode.IsNotNull() && m_FixedLandmarks.IsNotNull() && m_FixedLandmarks->GetSize() == 0) - { - this->GetDataStorage()->Remove(m_FixedPointSetNode); - } - if (m_MovingPointSetNode.IsNotNull() && m_MovingLandmarks.IsNotNull() && m_MovingLandmarks->GetSize() == 0) - { - this->GetDataStorage()->Remove(m_MovingPointSetNode); - } - mitk::RenderingManager::GetInstance()->RequestUpdateAll(); - m_FixedNode = NULL; - m_MovingNode = NULL; - if(m_FixedLandmarks.IsNotNull()) - m_FixedLandmarks->RemoveObserver(m_CurrentFixedLandmarksObserverID); - m_FixedLandmarks = NULL; - if(m_MovingLandmarks.IsNotNull()) - m_MovingLandmarks->RemoveObserver(m_CurrentMovingLandmarksObserverID); - m_MovingLandmarks = NULL; - m_FixedPointSetNode = NULL; - m_MovingPointSetNode = NULL; - m_Controls.m_FixedLabel->hide(); - m_Controls.TextLabelFixed->hide(); - m_Controls.line2->hide(); - m_Controls.m_FixedPointListWidget->hide(); - m_Controls.m_MovingLabel->hide(); - m_Controls.TextLabelMoving->hide(); - m_Controls.line1->hide(); - m_Controls.m_MovingPointListWidget->hide(); - m_Controls.m_OpacityLabel->hide(); - m_Controls.m_OpacitySlider->hide(); - m_Controls.label->hide(); - m_Controls.label_2->hide(); - m_Controls.m_SwitchImages->hide(); - berry::ISelectionService* s = GetSite()->GetWorkbenchWindow()->GetSelectionService(); - if(s) - s->RemovePostSelectionListener(m_SelListener); - m_SelListener = NULL; - //mitk::RenderingManager::GetInstance()->RequestUpdateAll(); - //QmitkFunctionality::Deactivated();*/ } void QmitkPointBasedRegistrationView::DataNodeHasBeenRemoved(const mitk::DataNode* node) { if(node == m_FixedNode || node == m_MovingNode) { m_Controls.m_StatusLabel->show(); m_Controls.TextLabelFixed->hide(); m_Controls.m_FixedLabel->hide(); m_Controls.line2->hide(); m_Controls.m_FixedPointListWidget->hide(); m_Controls.TextLabelMoving->hide(); m_Controls.m_MovingLabel->hide(); m_Controls.line1->hide(); m_Controls.m_MovingPointListWidget->hide(); m_Controls.m_OpacityLabel->hide(); m_Controls.m_OpacitySlider->hide(); m_Controls.label->hide(); m_Controls.label_2->hide(); m_Controls.m_SwitchImages->hide(); m_Controls.m_ShowRedGreenValues->setEnabled(false); } } void QmitkPointBasedRegistrationView::FixedSelected(mitk::DataNode::Pointer fixedImage) { if(m_FixedLandmarks.IsNotNull()) m_FixedLandmarks->RemoveObserver(m_CurrentFixedLandmarksObserverID); if (fixedImage.IsNotNull()) { if (m_FixedNode != fixedImage) { // remove changes on previous selected node if (m_FixedNode.IsNotNull()) { this->setImageColor(false); m_FixedNode->SetOpacity(1.0); if (m_FixedPointSetNode.IsNotNull()) { m_FixedPointSetNode->SetProperty("label", mitk::StringProperty::New(m_OldFixedLabel)); } } + // get selected node m_FixedNode = fixedImage; - m_FixedNode->SetOpacity(0.5); + + + // force opacity 1.0 for surfaces, otherwise the point picking/interaction does not work properly + if( QString(m_FixedNode->GetData()->GetNameOfClass() ).contains("Surface") ) + m_FixedNode->SetOpacity(1.0); + else + m_FixedNode->SetOpacity(0.5); + m_FixedNode->SetVisibility(true); m_Controls.m_FixedLabel->setText(QString::fromStdString(m_FixedNode->GetName())); m_Controls.m_FixedLabel->show(); m_Controls.m_SwitchImages->show(); m_Controls.TextLabelFixed->show(); m_Controls.line2->show(); m_Controls.m_FixedPointListWidget->show(); mitk::ColorProperty::Pointer colorProperty; colorProperty = dynamic_cast(m_FixedNode->GetProperty("color")); if ( colorProperty.IsNotNull() ) { m_FixedColor = colorProperty->GetColor(); } this->setImageColor(m_ShowRedGreen); bool hasPointSetNode = false; mitk::DataStorage::SetOfObjects::ConstPointer children = this->GetDataStorage()->GetDerivations(m_FixedNode); unsigned long size; size = children->Size(); for (unsigned long i = 0; i < size; ++i) { mitk::StringProperty::Pointer nameProp = dynamic_cast(children->GetElement(i)->GetProperty("name")); if(nameProp.IsNotNull() && nameProp->GetValueAsString()=="PointBasedRegistrationNode") { m_FixedPointSetNode=children->GetElement(i); m_FixedLandmarks = dynamic_cast (m_FixedPointSetNode->GetData()); this->GetDataStorage()->Remove(m_FixedPointSetNode); hasPointSetNode = true; break; } } if (!hasPointSetNode) { m_FixedLandmarks = mitk::PointSet::New(); m_FixedPointSetNode = mitk::DataNode::New(); m_FixedPointSetNode->SetData(m_FixedLandmarks); m_FixedPointSetNode->SetProperty("name", mitk::StringProperty::New("PointBasedRegistrationNode")); } m_FixedPointSetNode->GetStringProperty("label", m_OldFixedLabel); m_FixedPointSetNode->SetProperty("label", mitk::StringProperty::New("F ")); m_FixedPointSetNode->SetProperty("color", mitk::ColorProperty::New(0.0f, 1.0f, 1.0f)); m_FixedPointSetNode->SetVisibility(true); m_Controls.m_FixedPointListWidget->SetPointSetNode(m_FixedPointSetNode); this->GetDataStorage()->Add(m_FixedPointSetNode, m_FixedNode); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } if (m_FixedPointSetNode.IsNull()) { m_FixedLandmarks = mitk::PointSet::New(); m_FixedPointSetNode = mitk::DataNode::New(); m_FixedPointSetNode->SetData(m_FixedLandmarks); m_FixedPointSetNode->SetProperty("name", mitk::StringProperty::New("PointBasedRegistrationNode")); m_FixedPointSetNode->GetStringProperty("label", m_OldFixedLabel); m_FixedPointSetNode->SetProperty("label", mitk::StringProperty::New("F ")); m_FixedPointSetNode->SetProperty("color", mitk::ColorProperty::New(0.0f, 1.0f, 1.0f)); m_FixedPointSetNode->SetVisibility(true); m_Controls.m_FixedPointListWidget->SetPointSetNode(m_FixedPointSetNode); this->GetDataStorage()->Add(m_FixedPointSetNode, m_FixedNode); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } else { m_FixedNode = NULL; if (m_FixedPointSetNode.IsNotNull()) m_FixedPointSetNode->SetProperty("label", mitk::StringProperty::New(m_OldFixedLabel)); m_FixedPointSetNode = NULL; m_FixedLandmarks = NULL; m_Controls.m_FixedPointListWidget->SetPointSetNode(m_FixedPointSetNode); m_Controls.m_FixedLabel->hide(); m_Controls.TextLabelFixed->hide(); m_Controls.line2->hide(); m_Controls.m_FixedPointListWidget->hide(); m_Controls.m_SwitchImages->hide(); } if(m_FixedLandmarks.IsNotNull()) m_CurrentFixedLandmarksObserverID = m_FixedLandmarks->AddObserver(itk::ModifiedEvent(), m_FixedLandmarksChangedCommand); } void QmitkPointBasedRegistrationView::MovingSelected(mitk::DataNode::Pointer movingImage) { if(m_MovingLandmarks.IsNotNull()) m_MovingLandmarks->RemoveObserver(m_CurrentMovingLandmarksObserverID); if (movingImage.IsNotNull()) { if (m_MovingNode != movingImage) { if (m_MovingNode.IsNotNull()) { m_MovingNode->SetOpacity(m_OriginalOpacity); if (m_FixedNode == m_MovingNode) m_FixedNode->SetOpacity(0.5); this->setImageColor(false); if (m_MovingNode != m_FixedNode) { m_MovingPointSetNode->SetProperty("label", mitk::StringProperty::New(m_OldMovingLabel)); } else { m_OldFixedLabel = m_OldMovingLabel; } } if (m_MovingPointSetNode.IsNotNull()) m_MovingPointSetNode->SetProperty("label", mitk::StringProperty::New(m_OldMovingLabel)); m_MovingNode = movingImage; m_MovingNode->SetVisibility(true); + + + // force opacity 1.0 for surfaces, otherwise the point picking/interaction does not work properly + if( QString(m_MovingNode->GetData()->GetNameOfClass() ).contains("Surface") ) + m_Opacity = 1.0; + + m_Controls.m_MovingLabel->setText(QString::fromStdString(m_MovingNode->GetName())); m_Controls.m_MovingLabel->show(); m_Controls.TextLabelMoving->show(); m_Controls.line1->show(); m_Controls.m_MovingPointListWidget->show(); m_Controls.m_OpacityLabel->show(); m_Controls.m_OpacitySlider->show(); m_Controls.label->show(); m_Controls.label_2->show(); mitk::ColorProperty::Pointer colorProperty; colorProperty = dynamic_cast(m_MovingNode->GetProperty("color")); if ( colorProperty.IsNotNull() ) { m_MovingColor = colorProperty->GetColor(); } this->setImageColor(m_ShowRedGreen); m_MovingNode->GetFloatProperty("opacity", m_OriginalOpacity); this->OpacityUpdate(m_Opacity); bool hasPointSetNode = false; mitk::DataStorage::SetOfObjects::ConstPointer children = this->GetDataStorage()->GetDerivations(m_MovingNode); unsigned long size; size = children->Size(); for (unsigned long i = 0; i < size; ++i) { mitk::StringProperty::Pointer nameProp = dynamic_cast(children->GetElement(i)->GetProperty("name")); if(nameProp.IsNotNull() && nameProp->GetValueAsString()=="PointBasedRegistrationNode") { m_MovingPointSetNode=children->GetElement(i); m_MovingLandmarks = dynamic_cast (m_MovingPointSetNode->GetData()); this->GetDataStorage()->Remove(m_MovingPointSetNode); hasPointSetNode = true; break; } } if (!hasPointSetNode) { m_MovingLandmarks = mitk::PointSet::New(); m_MovingPointSetNode = mitk::DataNode::New(); m_MovingPointSetNode->SetData(m_MovingLandmarks); m_MovingPointSetNode->SetProperty("name", mitk::StringProperty::New("PointBasedRegistrationNode")); } this->GetDataStorage()->Add(m_MovingPointSetNode, m_MovingNode); m_MovingPointSetNode->GetStringProperty("label", m_OldMovingLabel); m_MovingPointSetNode->SetProperty("label", mitk::StringProperty::New("M ")); m_MovingPointSetNode->SetProperty("color", mitk::ColorProperty::New(1.0f, 1.0f, 0.0f)); m_MovingPointSetNode->SetVisibility(true); m_Controls.m_MovingPointListWidget->SetPointSetNode(m_MovingPointSetNode); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); this->clearTransformationLists(); this->OpacityUpdate(m_Opacity); } if (m_MovingPointSetNode.IsNull()) { m_MovingLandmarks = mitk::PointSet::New(); m_MovingPointSetNode = mitk::DataNode::New(); m_MovingPointSetNode->SetData(m_MovingLandmarks); m_MovingPointSetNode->SetProperty("name", mitk::StringProperty::New("PointBasedRegistrationNode")); m_MovingPointSetNode->GetStringProperty("label", m_OldMovingLabel); m_MovingPointSetNode->SetProperty("label", mitk::StringProperty::New("M ")); m_MovingPointSetNode->SetProperty("color", mitk::ColorProperty::New(1.0f, 1.0f, 0.0f)); m_MovingPointSetNode->SetVisibility(true); m_Controls.m_MovingPointListWidget->SetPointSetNode(m_MovingPointSetNode); this->GetDataStorage()->Add(m_MovingPointSetNode, m_MovingNode); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } else { m_MovingNode = NULL; if (m_MovingPointSetNode.IsNotNull()) m_MovingPointSetNode->SetProperty("label", mitk::StringProperty::New(m_OldMovingLabel)); m_MovingPointSetNode = NULL; m_MovingLandmarks = NULL; m_Controls.m_MovingPointListWidget->SetPointSetNode(m_MovingPointSetNode); m_Controls.m_MovingLabel->hide(); m_Controls.TextLabelMoving->hide(); m_Controls.line1->hide(); m_Controls.m_MovingPointListWidget->hide(); m_Controls.m_OpacityLabel->hide(); m_Controls.m_OpacitySlider->hide(); m_Controls.label->hide(); m_Controls.label_2->hide(); } if(m_MovingLandmarks.IsNotNull()) m_CurrentMovingLandmarksObserverID = m_MovingLandmarks->AddObserver(itk::ModifiedEvent(), m_MovingLandmarksChangedCommand); } void QmitkPointBasedRegistrationView::updateMovingLandmarksList() { -// mitk::PointSet* ps = mitk::PointSet::New(); -// ps = dynamic_cast(m_MovingPointSetNode->GetData()); -// mitk::DataNode::Pointer tmpPtr = m_MovingPointSetNode; -// m_MovingLandmarks = 0; -// m_MovingLandmarks = (ps); m_MovingLandmarks = dynamic_cast(m_MovingPointSetNode->GetData()); -// m_Controls.m_MovingPointListWidget->SetPointSetNode(m_MovingPointSetNode); //Workaround: m_MovingPointListWidget->m_PointListView->m_PointListModel loses the pointer on the pointsetnode + this->checkLandmarkError(); this->CheckCalculate(); } void QmitkPointBasedRegistrationView::updateFixedLandmarksList() { m_FixedLandmarks = dynamic_cast(m_FixedPointSetNode->GetData()); + this->checkLandmarkError(); this->CheckCalculate(); } void QmitkPointBasedRegistrationView::HideFixedImage(bool hide) { m_HideFixedImage = hide; if(m_FixedNode.IsNotNull()) { m_FixedNode->SetVisibility(!hide); } - if (hide) - { - //this->reinitMovingClicked(); - } - if (!m_HideMovingImage && !m_HideFixedImage) - { - //this->globalReinitClicked(); - } + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkPointBasedRegistrationView::HideMovingImage(bool hide) { m_HideMovingImage = hide; + if(m_MovingNode.IsNotNull()) { m_MovingNode->SetVisibility(!hide); } - if (hide) - { - //this->reinitFixedClicked(); - } - if (!m_HideMovingImage && !m_HideFixedImage) - { - //this->globalReinitClicked(); - } + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } bool QmitkPointBasedRegistrationView::CheckCalculate() { - if((m_MovingPointSetNode.IsNull())||(m_FixedPointSetNode.IsNull()||m_FixedLandmarks.IsNull()||m_MovingLandmarks.IsNull())) - return false; + if(( m_MovingPointSetNode.IsNull() )|| + ( m_FixedPointSetNode.IsNull()||m_FixedLandmarks.IsNull()||m_MovingLandmarks.IsNull()) ) + return false; + if(m_MovingNode==m_FixedNode) return false; + return this->checkCalculateEnabled(); } void QmitkPointBasedRegistrationView::UndoTransformation() { if(!m_UndoPointsGeometryList.empty()) { mitk::BaseGeometry::Pointer movingLandmarksGeometry = m_MovingLandmarks->GetGeometry(0)->Clone(); m_RedoPointsGeometryList.push_back(movingLandmarksGeometry.GetPointer()); m_MovingLandmarks->SetGeometry(m_UndoPointsGeometryList.back()); m_UndoPointsGeometryList.pop_back(); //\FIXME when geometry is substituted the matrix referenced by the actor created by the mapper //is still pointing to the old one. Workaround: delete mapper m_MovingPointSetNode->SetMapper(1, NULL); mitk::BaseData::Pointer movingData = m_MovingNode->GetData(); mitk::BaseGeometry::Pointer movingGeometry = movingData->GetGeometry(0)->Clone(); m_RedoGeometryList.push_back(movingGeometry.GetPointer()); movingData->SetGeometry(m_UndoGeometryList.back()); m_UndoGeometryList.pop_back(); //\FIXME when geometry is substituted the matrix referenced by the actor created by the mapper //is still pointing to the old one. Workaround: delete mapper m_MovingNode->SetMapper(1, NULL); mitk::RenderingManager::GetInstance()->RequestUpdate(m_MultiWidget->mitkWidget4->GetRenderWindow()); movingData->GetTimeGeometry()->Update(); m_MovingLandmarks->GetTimeGeometry()->Update(); m_Controls.m_RedoTransformation->setEnabled(true); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); this->checkLandmarkError(); } if(!m_UndoPointsGeometryList.empty()) { m_Controls.m_UndoTransformation->setEnabled(true); + m_Controls.m_SaveLastTransformPushButton->setEnabled(true); } else { m_Controls.m_UndoTransformation->setEnabled(false); + m_Controls.m_SaveLastTransformPushButton->setEnabled(false); } } void QmitkPointBasedRegistrationView::RedoTransformation() { if(!m_RedoPointsGeometryList.empty()) { mitk::BaseGeometry::Pointer movingLandmarksGeometry = m_MovingLandmarks->GetGeometry(0)->Clone(); m_UndoPointsGeometryList.push_back(movingLandmarksGeometry.GetPointer()); m_MovingLandmarks->SetGeometry(m_RedoPointsGeometryList.back()); m_RedoPointsGeometryList.pop_back(); //\FIXME when geometry is substituted the matrix referenced by the actor created by the mapper //is still pointing to the old one. Workaround: delete mapper m_MovingPointSetNode->SetMapper(1, NULL); mitk::BaseData::Pointer movingData = m_MovingNode->GetData(); mitk::BaseGeometry::Pointer movingGeometry = movingData->GetGeometry(0)->Clone(); m_UndoGeometryList.push_back(movingGeometry.GetPointer()); movingData->SetGeometry(m_RedoGeometryList.back()); m_RedoGeometryList.pop_back(); //\FIXME when geometry is substituted the matrix referenced by the actor created by the mapper //is still pointing to the old one. Workaround: delete mapper m_MovingNode->SetMapper(1, NULL); mitk::RenderingManager::GetInstance()->RequestUpdate(m_MultiWidget->mitkWidget4->GetRenderWindow()); movingData->GetTimeGeometry()->Update(); m_MovingLandmarks->GetTimeGeometry()->Update(); m_Controls.m_UndoTransformation->setEnabled(true); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); this->checkLandmarkError(); } if(!m_RedoPointsGeometryList.empty()) { m_Controls.m_RedoTransformation->setEnabled(true); } else { m_Controls.m_RedoTransformation->setEnabled(false); } } void QmitkPointBasedRegistrationView::showRedGreen(bool redGreen) { m_ShowRedGreen = redGreen; this->setImageColor(m_ShowRedGreen); } void QmitkPointBasedRegistrationView::setImageColor(bool redGreen) { if (!redGreen && m_FixedNode.IsNotNull()) { m_FixedNode->SetColor(m_FixedColor); } if (!redGreen && m_MovingNode.IsNotNull()) { m_MovingNode->SetColor(m_MovingColor); } if (redGreen && m_FixedNode.IsNotNull()) { m_FixedNode->SetColor(1.0f, 0.0f, 0.0f); } if (redGreen && m_MovingNode.IsNotNull()) { m_MovingNode->SetColor(0.0f, 1.0f, 0.0f); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkPointBasedRegistrationView::OpacityUpdate(float opacity) { if (opacity > 1) { opacity = opacity/100.0f; } m_Opacity = opacity; if (m_MovingNode.IsNotNull()) { m_MovingNode->SetOpacity(m_Opacity); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkPointBasedRegistrationView::OpacityUpdate(int opacity) { float fValue = ((float)opacity)/100.0f; this->OpacityUpdate(fValue); } void QmitkPointBasedRegistrationView::clearTransformationLists() { m_Controls.m_UndoTransformation->setEnabled(false); m_Controls.m_RedoTransformation->setEnabled(false); + m_Controls.m_SaveLastTransformPushButton->setEnabled(false); m_Controls.m_MeanErrorLCD->hide(); m_Controls.m_MeanError->hide(); m_UndoGeometryList.clear(); m_UndoPointsGeometryList.clear(); m_RedoGeometryList.clear(); m_RedoPointsGeometryList.clear(); } void QmitkPointBasedRegistrationView::checkLandmarkError() { double totalDist = 0, dist = 0, dist2 = 0; mitk::Point3D point1, point2, point3; double p1[3], p2[3]; if(m_Transformation < 3) { if (m_Controls.m_UseICP->isChecked()) { if (m_MovingLandmarks.IsNotNull() && m_FixedLandmarks.IsNotNull()&& m_MovingLandmarks->GetSize() != 0 && m_FixedLandmarks->GetSize() != 0) { for(int pointId = 0; pointId < m_MovingLandmarks->GetSize(); ++pointId) { point1 = m_MovingLandmarks->GetPoint(pointId); point2 = m_FixedLandmarks->GetPoint(0); p1[0] = point1[0]; p1[1] = point1[1]; p1[2] = point1[2]; p2[0] = point2[0]; p2[1] = point2[1]; p2[2] = point2[2]; dist = vtkMath::Distance2BetweenPoints(p1, p2); for(int pointId2 = 1; pointId2 < m_FixedLandmarks->GetSize(); ++pointId2) { point2 = m_FixedLandmarks->GetPoint(pointId2); p1[0] = point1[0]; p1[1] = point1[1]; p1[2] = p1[2]; p2[0] = point2[0]; p2[1] = point2[1]; p2[2] = p2[2]; dist2 = vtkMath::Distance2BetweenPoints(p1, p2); if (dist2 < dist) { dist = dist2; } } totalDist += dist; } m_Controls.m_MeanErrorLCD->display(sqrt(totalDist/m_FixedLandmarks->GetSize())); m_Controls.m_MeanErrorLCD->show(); m_Controls.m_MeanError->show(); } else { m_Controls.m_MeanErrorLCD->hide(); m_Controls.m_MeanError->hide(); } } else { if (m_MovingLandmarks.IsNotNull() && m_FixedLandmarks.IsNotNull() && m_MovingLandmarks->GetSize() != 0 && m_FixedLandmarks->GetSize() != 0 && m_MovingLandmarks->GetSize() == m_FixedLandmarks->GetSize()) { for(int pointId = 0; pointId < m_MovingLandmarks->GetSize(); ++pointId) { point1 = m_MovingLandmarks->GetPoint(pointId); point2 = m_FixedLandmarks->GetPoint(pointId); p1[0] = point1[0]; p1[1] = point1[1]; p1[2] = point1[2]; p2[0] = point2[0]; p2[1] = point2[1]; p2[2] = point2[2]; totalDist += vtkMath::Distance2BetweenPoints(p1, p2); } m_Controls.m_MeanErrorLCD->display(sqrt(totalDist/m_FixedLandmarks->GetSize())); m_Controls.m_MeanErrorLCD->show(); m_Controls.m_MeanError->show(); } else { m_Controls.m_MeanErrorLCD->hide(); m_Controls.m_MeanError->hide(); } } } else { if (m_MovingLandmarks.IsNotNull() && m_FixedLandmarks.IsNotNull() && m_MovingLandmarks->GetSize() != 0 && m_FixedLandmarks->GetSize() != 0 && m_MovingLandmarks->GetSize() == m_FixedLandmarks->GetSize()) { for(int pointId = 0; pointId < m_MovingLandmarks->GetSize(); ++pointId) { point1 = m_MovingLandmarks->GetPoint(pointId); point2 = m_FixedLandmarks->GetPoint(pointId); p1[0] = point1[0]; p1[1] = point1[1]; p1[2] = point1[2]; p2[0] = point2[0]; p2[1] = point2[1]; p2[2] = point2[2]; totalDist += vtkMath::Distance2BetweenPoints(p1, p2); } m_Controls.m_MeanErrorLCD->display(sqrt(totalDist/m_FixedLandmarks->GetSize())); m_Controls.m_MeanErrorLCD->show(); m_Controls.m_MeanError->show(); } else { m_Controls.m_MeanErrorLCD->hide(); m_Controls.m_MeanError->hide(); } } } void QmitkPointBasedRegistrationView::transformationChanged(int transform) { m_Transformation = transform; this->checkCalculateEnabled(); this->checkLandmarkError(); } // ICP with vtkLandmarkTransformation void QmitkPointBasedRegistrationView::calculateLandmarkbasedWithICP() { if(CheckCalculate()) { mitk::BaseGeometry::Pointer pointsGeometry = m_MovingLandmarks->GetGeometry(0); mitk::BaseGeometry::Pointer movingLandmarksGeometry = m_MovingLandmarks->GetGeometry(0)->Clone(); m_UndoPointsGeometryList.push_back(movingLandmarksGeometry.GetPointer()); mitk::BaseData::Pointer originalData = m_MovingNode->GetData(); mitk::BaseGeometry::Pointer originalDataGeometry = originalData->GetGeometry(0)->Clone(); m_UndoGeometryList.push_back(originalDataGeometry.GetPointer()); vtkIdType pointId; vtkPoints* vPointsSource=vtkPoints::New(); vtkCellArray* vCellsSource=vtkCellArray::New(); for(pointId=0; pointIdGetSize();++pointId) { mitk::Point3D pointSource=m_MovingLandmarks->GetPoint(pointId); vPointsSource->InsertNextPoint(pointSource[0],pointSource[1],pointSource[2]); vCellsSource->InsertNextCell(1, &pointId); } vtkPoints* vPointsTarget=vtkPoints::New(); vtkCellArray* vCellsTarget = vtkCellArray::New(); for(pointId=0; pointIdGetSize();++pointId) { mitk::Point3D pointTarget=m_FixedLandmarks->GetPoint(pointId); vPointsTarget->InsertNextPoint(pointTarget[0],pointTarget[1],pointTarget[2]); vCellsTarget->InsertNextCell(1, &pointId); } vtkPolyData* vPointSetSource=vtkPolyData::New(); vtkPolyData* vPointSetTarget=vtkPolyData::New(); vPointSetTarget->SetPoints(vPointsTarget); vPointSetTarget->SetVerts(vCellsTarget); vPointSetSource->SetPoints(vPointsSource); vPointSetSource->SetVerts(vCellsSource); vtkIterativeClosestPointTransform * icp=vtkIterativeClosestPointTransform::New(); icp->SetCheckMeanDistance(1); icp->SetSource(vPointSetSource); icp->SetTarget(vPointSetTarget); icp->SetMaximumNumberOfIterations(50); icp->StartByMatchingCentroidsOn(); vtkLandmarkTransform * transform=icp->GetLandmarkTransform(); if(m_Transformation==0) { transform->SetModeToRigidBody(); } if(m_Transformation==1) { transform->SetModeToSimilarity(); } if(m_Transformation==2) { transform->SetModeToAffine(); } vtkMatrix4x4 * matrix=icp->GetMatrix(); double determinant = fabs(matrix->Determinant()); if((determinant < mitk::eps) || (determinant > 100) || (determinant < 0.01) || (determinant==itk::NumericTraits::infinity()) || (determinant==itk::NumericTraits::quiet_NaN()) || (determinant==itk::NumericTraits::signaling_NaN()) || (determinant==-itk::NumericTraits::infinity()) || (determinant==-itk::NumericTraits::quiet_NaN()) || (determinant==-itk::NumericTraits::signaling_NaN()) || (!(determinant <= 0) && !(determinant > 0))) { QMessageBox msgBox; msgBox.setText("Suspicious determinant of matrix calculated by ICP.\n" "Please select more points or other points!" ); msgBox.exec(); return; } pointsGeometry->Compose(matrix); m_MovingLandmarks->GetTimeGeometry()->Update(); mitk::BaseData::Pointer movingData = m_MovingNode->GetData(); mitk::BaseGeometry::Pointer movingGeometry = movingData->GetGeometry(0); movingGeometry->Compose(matrix); movingData->GetTimeGeometry()->Update(); m_Controls.m_UndoTransformation->setEnabled(true); m_Controls.m_RedoTransformation->setEnabled(false); + m_Controls.m_SaveLastTransformPushButton->setEnabled(true); m_RedoGeometryList.clear(); m_RedoPointsGeometryList.clear(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); this->checkLandmarkError(); } } // only vtkLandmarkTransformation void QmitkPointBasedRegistrationView::calculateLandmarkbased() { if(CheckCalculate()) { mitk::BaseGeometry::Pointer pointsGeometry = m_MovingLandmarks->GetGeometry(0); mitk::BaseGeometry::Pointer movingLandmarksGeometry = m_MovingLandmarks->GetGeometry(0)->Clone(); m_UndoPointsGeometryList.push_back(movingLandmarksGeometry.GetPointer()); mitk::BaseData::Pointer originalData = m_MovingNode->GetData(); mitk::BaseGeometry::Pointer originalDataGeometry = originalData->GetGeometry(0)->Clone(); m_UndoGeometryList.push_back(originalDataGeometry.GetPointer()); vtkIdType pointId; vtkPoints* vPointsSource=vtkPoints::New(); for(pointId = 0; pointId < m_MovingLandmarks->GetSize(); ++pointId) { mitk::Point3D sourcePoint = m_MovingLandmarks->GetPoint(pointId); vPointsSource->InsertNextPoint(sourcePoint[0],sourcePoint[1],sourcePoint[2]); } vtkPoints* vPointsTarget=vtkPoints::New(); for(pointId=0; pointIdGetSize();++pointId) { mitk::Point3D targetPoint=m_FixedLandmarks->GetPoint(pointId); vPointsTarget->InsertNextPoint(targetPoint[0],targetPoint[1],targetPoint[2]); } vtkLandmarkTransform * transform= vtkLandmarkTransform::New(); transform->SetSourceLandmarks(vPointsSource); transform->SetTargetLandmarks(vPointsTarget); if(m_Transformation==0) { transform->SetModeToRigidBody(); } if(m_Transformation==1) { transform->SetModeToSimilarity(); } if(m_Transformation==2) { transform->SetModeToAffine(); } vtkMatrix4x4 * matrix=transform->GetMatrix(); + + m_LastTransformMatrix = matrix->NewInstance(); + m_LastTransformMatrix->DeepCopy( matrix ); + + double determinant = fabs(matrix->Determinant()); if((determinant < mitk::eps) || (determinant > 100) || (determinant < 0.01) || (determinant==itk::NumericTraits::infinity()) || (determinant==itk::NumericTraits::quiet_NaN()) || (determinant==itk::NumericTraits::signaling_NaN()) || (determinant==-itk::NumericTraits::infinity()) || (determinant==-itk::NumericTraits::quiet_NaN()) || (determinant==-itk::NumericTraits::signaling_NaN()) || (!(determinant <= 0) && !(determinant > 0))) { QMessageBox msgBox; msgBox.setText("Suspicious determinant of matrix calculated.\n" "Please select more points or other points!" ); msgBox.exec(); return; } pointsGeometry->Compose(matrix); m_MovingLandmarks->GetTimeGeometry()->Update(); mitk::BaseData::Pointer movingData = m_MovingNode->GetData(); mitk::BaseGeometry::Pointer movingGeometry = movingData->GetGeometry(0); movingGeometry->Compose(matrix); movingData->GetTimeGeometry()->Update(); m_Controls.m_UndoTransformation->setEnabled(true); + m_Controls.m_SaveLastTransformPushButton->setEnabled(true); m_Controls.m_RedoTransformation->setEnabled(false); m_RedoGeometryList.clear(); m_RedoPointsGeometryList.clear(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); this->checkLandmarkError(); } } void QmitkPointBasedRegistrationView::calculateLandmarkWarping() { mitk::LandmarkWarping* registration = new mitk::LandmarkWarping(); mitk::LandmarkWarping::FixedImageType::Pointer fixedImage = mitk::LandmarkWarping::FixedImageType::New(); mitk::Image::Pointer fimage = dynamic_cast(m_FixedNode->GetData()); mitk::LandmarkWarping::MovingImageType::Pointer movingImage = mitk::LandmarkWarping::MovingImageType::New(); mitk::Image::Pointer mimage = dynamic_cast(m_MovingNode->GetData()); if (fimage.IsNotNull() && /*fimage->GetDimension() == 2 || */ fimage->GetDimension() == 3 && mimage.IsNotNull() && mimage->GetDimension() == 3) { mitk::CastToItkImage(fimage, fixedImage); mitk::CastToItkImage(mimage, movingImage); registration->SetFixedImage(fixedImage); registration->SetMovingImage(movingImage); unsigned int pointId; mitk::Point3D sourcePoint, targetPoint; mitk::LandmarkWarping::LandmarkContainerType::Pointer fixedLandmarks = mitk::LandmarkWarping::LandmarkContainerType::New(); mitk::LandmarkWarping::LandmarkPointType point; for(pointId = 0; pointId < (unsigned int)m_FixedLandmarks->GetSize(); ++pointId) { fimage->GetGeometry(0)->WorldToItkPhysicalPoint(m_FixedLandmarks->GetPoint(pointId), point); fixedLandmarks->InsertElement( pointId, point); } mitk::LandmarkWarping::LandmarkContainerType::Pointer movingLandmarks = mitk::LandmarkWarping::LandmarkContainerType::New(); for(pointId = 0; pointId < (unsigned int)m_MovingLandmarks->GetSize(); ++pointId) { mitk::BaseData::Pointer fixedData = m_FixedNode->GetData(); mitk::BaseGeometry::Pointer fixedGeometry = fixedData->GetGeometry(0); fixedGeometry->WorldToItkPhysicalPoint(m_MovingLandmarks->GetPoint(pointId), point); movingLandmarks->InsertElement( pointId, point); } registration->SetLandmarks(fixedLandmarks.GetPointer(), movingLandmarks.GetPointer()); mitk::LandmarkWarping::MovingImageType::Pointer output = registration->Register(); if (output.IsNotNull()) { mitk::Image::Pointer image = mitk::Image::New(); mitk::CastToMitkImage(output, image); m_MovingNode->SetData(image); mitk::LevelWindowProperty::Pointer levWinProp = mitk::LevelWindowProperty::New(); mitk::LevelWindow levelWindow; levelWindow.SetAuto( image ); levWinProp->SetLevelWindow(levelWindow); m_MovingNode->GetPropertyList()->SetProperty("levelwindow",levWinProp); movingLandmarks = registration->GetTransformedTargetLandmarks(); mitk::PointSet::PointDataIterator it; it = m_MovingLandmarks->GetPointSet()->GetPointData()->Begin(); //increase the eventId to encapsulate the coming operations mitk::OperationEvent::IncCurrObjectEventId(); mitk::OperationEvent::ExecuteIncrement(); for(pointId=0; pointIdSize();++pointId, ++it) { int position = it->Index(); mitk::PointSet::PointType pt = m_MovingLandmarks->GetPoint(position); mitk::Point3D undoPoint = ( pt ); point = movingLandmarks->GetElement(pointId); fimage->GetGeometry(0)->ItkPhysicalPointToWorld(point, pt); mitk::PointOperation* doOp = new mitk::PointOperation(mitk::OpMOVE, pt, position); //undo operation mitk::PointOperation* undoOp = new mitk::PointOperation(mitk::OpMOVE, undoPoint, position); mitk::OperationEvent* operationEvent = new mitk::OperationEvent(m_MovingLandmarks, doOp, undoOp, "Move point"); mitk::UndoController::GetCurrentUndoModel()->SetOperationEvent(operationEvent); //execute the Operation m_MovingLandmarks->ExecuteOperation(doOp); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); this->clearTransformationLists(); this->checkLandmarkError(); } } } bool QmitkPointBasedRegistrationView::checkCalculateEnabled() { if (m_FixedLandmarks.IsNotNull() && m_MovingLandmarks.IsNotNull()) { int fixedPoints = m_FixedLandmarks->GetSize(); int movingPoints = m_MovingLandmarks->GetSize(); if (m_Transformation == 0 || m_Transformation == 1 || m_Transformation == 2) { if (m_Controls.m_UseICP->isChecked()) { if((movingPoints > 0 && fixedPoints > 0)) { m_Controls.m_Calculate->setEnabled(true); return true; } else { m_Controls.m_Calculate->setEnabled(false); return false; } } else { if ((movingPoints == fixedPoints) && movingPoints > 0) { m_Controls.m_Calculate->setEnabled(true); return true; } else { m_Controls.m_Calculate->setEnabled(false); return false; } } } else { m_Controls.m_Calculate->setEnabled(true); return true; } } else { return false; } } void QmitkPointBasedRegistrationView::calculate() { if (m_Transformation == 0 || m_Transformation == 1 || m_Transformation == 2) { if (m_Controls.m_UseICP->isChecked()) { if (m_MovingLandmarks->GetSize() == 1 && m_FixedLandmarks->GetSize() == 1) { this->calculateLandmarkbased(); } else { this->calculateLandmarkbasedWithICP(); } } else { this->calculateLandmarkbased(); } } else { this->calculateLandmarkWarping(); } } void QmitkPointBasedRegistrationView::SwitchImages() { mitk::DataNode::Pointer newMoving = m_FixedNode; mitk::DataNode::Pointer newFixed = m_MovingNode; this->FixedSelected(newFixed); this->MovingSelected(newMoving); } +void QmitkPointBasedRegistrationView::OnExportTransformButtonPushed() +{ + // handle transform export + QString filename = QFileDialog::getSaveFileName(0, "Save transform file as plain matrix", "", ".txt"); + QFile f( filename ); + f.open( QIODevice::WriteOnly ); + + // write out text + QTextStream outstream(&f); + outstream << "# Plain text transform matrix " << "\n" << "# Saved from the PointBasedRegistration Plugin \n"; + + std::stringstream matrix_ss; + m_LastTransformMatrix->Print( matrix_ss ); + outstream << matrix_ss.str().c_str(); + + f.close(); +} diff --git a/Plugins/org.mitk.gui.qt.registration/src/internal/QmitkPointBasedRegistrationView.h b/Plugins/org.mitk.gui.qt.registration/src/internal/QmitkPointBasedRegistrationView.h index c13212acc1..4f151eec53 100644 --- a/Plugins/org.mitk.gui.qt.registration/src/internal/QmitkPointBasedRegistrationView.h +++ b/Plugins/org.mitk.gui.qt.registration/src/internal/QmitkPointBasedRegistrationView.h @@ -1,292 +1,259 @@ /*=================================================================== 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. ===================================================================*/ #if !defined(QMITK_POINTBASEDREGISTRATION_H__INCLUDED) #define QMITK_POINTBASEDREGISTRATION_H__INCLUDED #include "QmitkFunctionality.h" #include "berryISelectionListener.h" #include "berryIStructuredSelection.h" //#include "mitkTestingConfig.h" // IMPORTANT: this defines or undefines BUILD_TESTING ! #include #include #include //#include "QmitkMessageBoxHelper.h" #include "ui_QmitkPointBasedRegistrationViewControls.h" #include /*! \brief The PointBasedRegistration functionality is used to perform point based registration. This functionality allows you to register 2D as well as 3D images in a rigid and deformable manner via corresponding PointSets. Register means to align two images, so that they become as similar as possible. Therefore you have to set corresponding points in both images, which will be matched. The movement, which has to be performed on the points to align them will be performed on the moving image as well. The result is shown in the multi-widget. For more informations see: \ref QmitkPointBasedRegistrationUserManual \sa QmitkFunctionality \ingroup Functionalities \ingroup PointBasedRegistration */ class REGISTRATION_EXPORT QmitkPointBasedRegistrationView : public QmitkFunctionality { friend struct SelListenerPointBasedRegistration; Q_OBJECT public: static const std::string VIEW_ID; /*! \brief Default constructor */ QmitkPointBasedRegistrationView(QObject *parent=0, const char *name=0); /*! \brief Default destructor */ virtual ~QmitkPointBasedRegistrationView(); /*! \brief method for creating the applications main widget */ virtual void CreateQtPartControl(QWidget *parent) override; /*! \brief Sets the StdMultiWidget and connects it to the functionality. */ virtual void StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget) override; /*! \brief Removes the StdMultiWidget and disconnects it from the functionality. */ virtual void StdMultiWidgetNotAvailable() override; /*! \brief Method for creating the connections of main and control widget */ virtual void CreateConnections(); virtual void Activated() override; virtual void Deactivated() override; virtual void Visible() override; virtual void Hidden() override; - // - // #ifdef BUILD_TESTING - // / ** - // \brief Testing entry point - // * / - // virtual int TestYourself(); - // - // / ** - // \brief Helper method for testing - // * / - // bool TestAllTools(); - // - // - // protected slots: - // /** - // \brief Helper method for testing - // */ - // void RegistrationErrorDialogFound( QWidget* widget ); - // - // /** - // \brief Helper method for testing - // */ - // void ClearPointSetDialogFound( QWidget* widget ); - // - // private: - // bool m_MessageBox; - // - // - // public: - // #else - // // slot function is needed, because moc ignores our #ifdefs - // void RegistrationErrorDialogFound( QWidget* widget ) {} - // // slot function is needed, because moc ignores our #ifdefs - // void ClearPointSetDialogFound(QWidget* widget){} - // #endif - - void DataNodeHasBeenRemoved(const mitk::DataNode* node); + void DataNodeHasBeenRemoved(const mitk::DataNode* node); protected slots: /*! \brief Sets the fixed Image according to TreeNodeSelector widget */ void FixedSelected(mitk::DataNode::Pointer fixedImage); /*! \brief Sets the moving Image according to TreeNodeSelector widget */ void MovingSelected(mitk::DataNode::Pointer movingImage); /*! \brief Calculates registration with vtkLandmarkTransform */ void calculateLandmarkbased(); /*! \brief Calculates registration with itkLandmarkWarping */ void calculateLandmarkWarping(); /*! \brief Calculates registration with ICP and vtkLandmarkTransform */ void calculateLandmarkbasedWithICP(); /*! \brief lets the fixed image become invisible and the moving image visible */ void HideMovingImage(bool hide); /*! \brief lets the moving image become invisible and the fixed image visible */ void HideFixedImage(bool hide); /*! \brief Checks if registration is possible */ bool CheckCalculate(); /*! \brief Performs an undo for the last transform. */ void UndoTransformation(); /*! \brief Performs a redo for the last undo transform. */ void RedoTransformation(); /*! \brief Stores whether the image will be shown in grayvalues or in red for fixed image and green for moving image @param show if true, then images will be shown in red and green */ void showRedGreen(bool show); /*! \brief Sets the selected opacity for moving image @param opacity the selected opacity */ void OpacityUpdate(float opacity); /*! \brief Sets the selected opacity for moving image @param opacity the selected opacity */ void OpacityUpdate(int opacity); /*! \brief Updates the moving landmarks */ void updateMovingLandmarksList(); /*! \brief Updates the fixed landmarks */ void updateFixedLandmarksList(); /*! \brief Sets the images to gray values or fixed image to red and moving image to green @param redGreen if true, then images will be shown in red and green */ void setImageColor(bool redGreen); /*! \brief Clears the undo and redo transformation lists. */ void clearTransformationLists(); /*! \brief Calculates the landmark error for the selected transformation. */ void checkLandmarkError(); /*! \brief Changes the transformation type and calls checkLandmarkError(). */ void transformationChanged(int transform); /*! \brief Checks whether the registration can be performed. */ bool checkCalculateEnabled(); /*! \brief Performs the registration. */ void calculate(); void SwitchImages(); + void OnExportTransformButtonPushed(); + protected: QScopedPointer m_SelListener; berry::IStructuredSelection::ConstPointer m_CurrentSelection; /*! * default main widget containing 4 windows showing 3 * orthogonal slices of the volume and a 3d render window */ QmitkStdMultiWidget * m_MultiWidget; /*! * control widget to make all changes for point based registration */ Ui::QmitkPointBasedRegistrationControls m_Controls; mitk::PointSet::Pointer m_FixedLandmarks; mitk::PointSet::Pointer m_MovingLandmarks; mitk::DataNode::Pointer m_MovingPointSetNode; mitk::DataNode::Pointer m_FixedPointSetNode; mitk::DataNode::Pointer m_MovingNode; mitk::DataNode::Pointer m_FixedNode; std::list m_UndoGeometryList; std::list m_UndoPointsGeometryList; std::list m_RedoGeometryList; std::list m_RedoPointsGeometryList; bool m_ShowRedGreen; float m_Opacity; float m_OriginalOpacity; mitk::Color m_FixedColor; mitk::Color m_MovingColor; int m_Transformation; + vtkMatrix4x4 * m_LastTransformMatrix; bool m_HideFixedImage; bool m_HideMovingImage; std::string m_OldFixedLabel; std::string m_OldMovingLabel; bool m_Deactivated; int m_CurrentFixedLandmarksObserverID; int m_CurrentMovingLandmarksObserverID; itk::SimpleMemberCommand::Pointer m_FixedLandmarksChangedCommand; itk::SimpleMemberCommand::Pointer m_MovingLandmarksChangedCommand; }; #endif // !defined(QMITK_POINTBASEDREGISTRATION_H__INCLUDED) diff --git a/Plugins/org.mitk.gui.qt.registration/src/internal/QmitkPointBasedRegistrationViewControls.ui b/Plugins/org.mitk.gui.qt.registration/src/internal/QmitkPointBasedRegistrationViewControls.ui index 1a808f1eea..60243b102d 100644 --- a/Plugins/org.mitk.gui.qt.registration/src/internal/QmitkPointBasedRegistrationViewControls.ui +++ b/Plugins/org.mitk.gui.qt.registration/src/internal/QmitkPointBasedRegistrationViewControls.ui @@ -1,617 +1,711 @@ QmitkPointBasedRegistrationControls 0 0 - 287 - 404 + 506 + 914 0 0 0 0 PointBasedRegistration 255 0 0 255 0 0 118 116 108 You have to select two images from Data Manager using CTRL + left click! Switch fixed and moving image 0 0 75 true Fixed Data true - + + 0 + + + 0 + + + 0 + + 0 50 false Dataset: false QFrame::HLine QFrame::Sunken 0 0 0 0 75 true Moving Data true - + + 0 + + + 0 + + + 0 + + 0 50 false Dataset: false 50 false Moving Image Opacity: false 50 false 0% 0 0 100 50 Qt::Horizontal 50 false 100% QFrame::HLine QFrame::Sunken 0 0 0 0 75 true Display Options true - + + 0 + + + 0 + + + 0 + + 0 0 0 50 false Show Images Red/Green 75 true Registration true - + + 0 + + + 0 + + + 0 + + 0 50 false Method: false 0 0 50 false Rigid Similarity Affine LandmarkWarping 50 false Use ICP (order of landmarks doesn't matter) false 0 0 150 0 50 false Register :/QmitkPointBasedRegistrationView/PointBasedRegistration.xpm:/QmitkPointBasedRegistrationView/PointBasedRegistration.xpm 0 0 50 false Error between Landmarks (RMS): false 0 0 50 false QFrame::NoFrame QFrame::Raised false - + 9 QLCDNumber::Flat 0.000000000000000 0 false 0 0 50 false Undo Transformation :/org.mitk.gui.qt.ext/edit-undo.png:/org.mitk.gui.qt.ext/edit-undo.png false 0 0 50 false Redo Transformation :/org.mitk.gui.qt.ext/edit-redo.png:/org.mitk.gui.qt.ext/edit-redo.png + + + + 10 + + + + + + 50 + false + + + + Export last registration matrix: + + + + + + + false + + + + 50 + false + + + + Save Transform + + + + + + + + + Qt::Horizontal + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + Qt::Vertical + + QSizePolicy::Ignored + - 1 - 1 + 20 + 40 QmitkPointListWidget QWidget
QmitkPointListWidget.h
mitkDataNode.h mitkPointSet.h mitkInteractionConst.h mitkBaseData.h -
diff --git a/Plugins/org.mitk.gui.qt.xnat/files.cmake b/Plugins/org.mitk.gui.qt.xnat/files.cmake index f0a27c0ce6..f87c5845f7 100644 --- a/Plugins/org.mitk.gui.qt.xnat/files.cmake +++ b/Plugins/org.mitk.gui.qt.xnat/files.cmake @@ -1,47 +1,50 @@ set(SRC_CPP_FILES ) set(INTERNAL_CPP_FILES org_mitk_gui_qt_xnatinterface_Activator.cpp + QmitkUploadToXNATAction.cpp QmitkXnatTreeBrowserView.cpp QmitkXnatConnectionPreferencePage.cpp QmitkXnatSessionManager.cpp ) set(UI_FILES src/internal/QmitkXnatTreeBrowserViewControls.ui src/internal/QmitkXnatConnectionPreferencePageControls.ui ) set(MOC_H_FILES src/internal/org_mitk_gui_qt_xnatinterface_Activator.h + src/internal/QmitkUploadToXNATAction.h src/internal/QmitkXnatTreeBrowserView.h src/internal/QmitkXnatConnectionPreferencePage.h ) # list of resource files which can be used by the plug-in # system without loading the plug-ins shared library, # for example the icon used in the menu and tabs for the # plug-in views in the workbench set(CACHED_RESOURCE_FILES resources/icon.xpm resources/xnat_treebrowser_icon.xpm + resources/xnat-icon.png plugin.xml ) # list of Qt .qrc files which contain additional resources # specific to this plugin set(QRC_FILES resources/xnat.qrc ) set(CPP_FILES ) foreach(file ${SRC_CPP_FILES}) set(CPP_FILES ${CPP_FILES} src/${file}) endforeach(file ${SRC_CPP_FILES}) foreach(file ${INTERNAL_CPP_FILES}) set(CPP_FILES ${CPP_FILES} src/internal/${file}) endforeach(file ${INTERNAL_CPP_FILES}) diff --git a/Plugins/org.mitk.gui.qt.xnat/manifest_headers.cmake b/Plugins/org.mitk.gui.qt.xnat/manifest_headers.cmake index 98df66b9e8..e2123e2708 100644 --- a/Plugins/org.mitk.gui.qt.xnat/manifest_headers.cmake +++ b/Plugins/org.mitk.gui.qt.xnat/manifest_headers.cmake @@ -1,5 +1,5 @@ set(Plugin-Name "XNAT Plugin") set(Plugin-Version "0.1") set(Plugin-Vendor "DKFZ, Medical and Biological Informatics") set(Plugin-ContactAddress "") -set(Require-Plugin org.mitk.gui.qt.common) +set(Require-Plugin org.mitk.gui.qt.common org.mitk.gui.qt.datamanager) diff --git a/Plugins/org.mitk.gui.qt.xnat/plugin.xml b/Plugins/org.mitk.gui.qt.xnat/plugin.xml index 52064ddba4..1a390df830 100644 --- a/Plugins/org.mitk.gui.qt.xnat/plugin.xml +++ b/Plugins/org.mitk.gui.qt.xnat/plugin.xml @@ -1,49 +1,53 @@ Search, browse and view the data in a XNAT-Installation Search, browse and view the data in a XNAT-Installation + + + + diff --git a/Plugins/org.mitk.gui.qt.xnat/resources/xnat-download.png b/Plugins/org.mitk.gui.qt.xnat/resources/xnat-download.png index cdc6b22a4d..feb16dc69e 100644 Binary files a/Plugins/org.mitk.gui.qt.xnat/resources/xnat-download.png and b/Plugins/org.mitk.gui.qt.xnat/resources/xnat-download.png differ diff --git a/Plugins/org.mitk.gui.qt.xnat/resources/xnat-folder.png b/Plugins/org.mitk.gui.qt.xnat/resources/xnat-folder.png index 2adc69f865..651782ccfb 100644 Binary files a/Plugins/org.mitk.gui.qt.xnat/resources/xnat-folder.png and b/Plugins/org.mitk.gui.qt.xnat/resources/xnat-folder.png differ diff --git a/Plugins/org.mitk.gui.qt.xnat/resources/xnat-icon.png b/Plugins/org.mitk.gui.qt.xnat/resources/xnat-icon.png new file mode 100644 index 0000000000..97d4e9b6df Binary files /dev/null and b/Plugins/org.mitk.gui.qt.xnat/resources/xnat-icon.png differ diff --git a/Plugins/org.mitk.gui.qt.xnat/resources/xnat-upload.png b/Plugins/org.mitk.gui.qt.xnat/resources/xnat-upload.png index 54c8236f9e..c83716b6dc 100644 Binary files a/Plugins/org.mitk.gui.qt.xnat/resources/xnat-upload.png and b/Plugins/org.mitk.gui.qt.xnat/resources/xnat-upload.png differ diff --git a/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkUploadToXNATAction.cpp b/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkUploadToXNATAction.cpp new file mode 100644 index 0000000000..03c43a9a95 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkUploadToXNATAction.cpp @@ -0,0 +1,199 @@ +/*=================================================================== + +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 "QmitkUploadToXNATAction.h" + +//needed for qApp +#include + +#include "org_mitk_gui_qt_xnatinterface_Activator.h" +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +void ShowInfoMessage() +{ + QMessageBox infoBox; + infoBox.setIcon(QMessageBox::Information); + infoBox.setText("You are not connected to a XNAT server!"); + infoBox.setInformativeText("Please use the 'Connect' button in the Preferences."); + infoBox.exec(); +} + +QmitkUploadToXNATAction::QmitkUploadToXNATAction() +{ +} + +QmitkUploadToXNATAction::~QmitkUploadToXNATAction() +{ +} + +void QmitkUploadToXNATAction::Run( const QList &selectedNodes ) +{ + if (selectedNodes.size() != 1) + { + QMessageBox infoBox; + infoBox.setIcon(QMessageBox::Information); + infoBox.setText("Please select only one data node for upload"); + infoBox.exec(); + } + + // Try to get the XNAT session + us::ServiceReference modServiceRef = mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatModuleContext()->GetServiceReference(); + + if (!modServiceRef) + { + ShowInfoMessage(); + return; + } + + us::ModuleContext* xnatModuleContext = mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatModuleContext(); + + if (xnatModuleContext == nullptr) + { + ShowInfoMessage(); + return; + } + + ctkXnatSession *session(nullptr); + session = xnatModuleContext->GetService(modServiceRef); + if (session == nullptr || !session->isOpen()) + { + ShowInfoMessage(); + return; + } + + mitk::DataNode* selectedNode = selectedNodes.at(0); + + if (selectedNode == nullptr) + return; + + ctkServiceTracker dataStorageServiceTracker (mitk::org_mitk_gui_qt_xnatinterface_Activator::GetContext()); + dataStorageServiceTracker.open(); + mitk::IDataStorageService* dsService = dataStorageServiceTracker.getService(); + mitk::DataStorage::Pointer dataStorage = dsService->GetDataStorage()->GetDataStorage(); + + mitk::NodePredicateProperty::Pointer pred = mitk::NodePredicateProperty::New("xnat.url"); + mitk::DataStorage::SetOfObjects::ConstPointer result = dataStorage->GetSources(selectedNode, pred); + mitk::DataStorage::SetOfObjects::ConstIterator it = result->Begin(); + + QList resourceFolders; + QStringList resourceNames; + QString url; + for (;it != result->End(); ++it) + { + mitk::DataNode::Pointer node = it->Value(); + + std::string xnatUrl(""); + node->GetStringProperty("xnat.url", xnatUrl); + url = QString::fromStdString(xnatUrl); + + int start = url.lastIndexOf("resources/") + 10; //length of "resources/" + url = url.left(start); + + QUuid uid = session->httpGet(url); + resourceFolders = session->httpResults(uid, ctkXnatDefaultSchemaTypes::XSI_RESOURCE); + + foreach (ctkXnatObject* obj, resourceFolders) + { + resourceNames << obj->name(); + } + } + + // Dialog for selecting the upload destination + QmitkSelectXnatUploadDestinationDialog dialog(session, resourceNames); + dialog.setWindowTitle("Select XNAT upload destination"); + dialog.SetXnatResourceFolderUrl(url); + int returnValue = dialog.exec(); + + if (returnValue == QDialog::Accepted) + { + // Save node + QString fileName (QString::fromStdString(selectedNode->GetName())); + + if (dynamic_cast(selectedNode->GetData())) + { + fileName.append(".nrrd"); + } + else if (dynamic_cast(selectedNode->GetData())) + { + fileName.append(".vtk"); + } + else if (dynamic_cast(selectedNode->GetData())) + { + fileName.append(".mps"); + } + else + { + MITK_WARN << "Could not upload file! File-type not supported"; + QMessageBox msgbox; + msgbox.setText("Could not upload file! File-type not supported"); + msgbox.setIcon(QMessageBox::Critical); + msgbox.exec(); + return; + } + + QString xnatFolder = "XNAT_UPLOADS"; + QDir dir(mitk::org_mitk_gui_qt_xnatinterface_Activator::GetContext()->getDataFile("").absoluteFilePath()); + dir.mkdir(xnatFolder); + + fileName = dir.path().append("/" + fileName); + mitk::IOUtil::Save (selectedNode->GetData(), fileName.toStdString()); + + // Upload the file to XNAT + ctkXnatObject* uploadDestination = dialog.GetUploadDestination(); + if (uploadDestination != nullptr) + { + ctkXnatFile* file = new ctkXnatFile(uploadDestination); + file->setLocalFilePath(fileName); + QFileInfo fileInfo (fileName); + file->setName(fileInfo.fileName()); + file->save(); + } + } + dataStorageServiceTracker.close(); +} + +void QmitkUploadToXNATAction::SetDataStorage(mitk::DataStorage* /*dataStorage*/) +{ + //not needed +} + +void QmitkUploadToXNATAction::SetFunctionality(berry::QtViewPart* /*functionality*/) +{ + //not needed +} + +void QmitkUploadToXNATAction::SetSmoothed(bool /*smoothed*/) +{ + //not needed +} + +void QmitkUploadToXNATAction::SetDecimated(bool /*smoothed*/) +{ + //not needed +} diff --git a/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkUploadToXNATAction.h b/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkUploadToXNATAction.h new file mode 100644 index 0000000000..b2a5925b51 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkUploadToXNATAction.h @@ -0,0 +1,50 @@ +/*=================================================================== + +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 QMITK_UPLOADTOXNATACTION_H +#define QMITK_UPLOADTOXNATACTION_H + +#include "mitkIContextMenuAction.h" + +#include "org_mitk_gui_qt_xnat_Export.h" + +#include "mitkDataNode.h" + +class XNAT_EXPORT QmitkUploadToXNATAction : public QObject, public mitk::IContextMenuAction +{ + Q_OBJECT + Q_INTERFACES(mitk::IContextMenuAction) + +public: + + QmitkUploadToXNATAction(); + virtual ~QmitkUploadToXNATAction(); + + //interface methods + void Run( const QList& selectedNodes ) override; + + // Setters + void SetDataStorage(mitk::DataStorage* dataStorage) override; + void SetSmoothed(bool smoothed) override; + void SetDecimated(bool decimated) override; + void SetFunctionality(berry::QtViewPart* functionality) override; + +private: + + typedef QList NodeList; + +}; + +#endif // QMITK_UPLOADTOXNATACTION_H diff --git a/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatConnectionPreferencePage.cpp b/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatConnectionPreferencePage.cpp index eef0543255..6f245ce7ad 100644 --- a/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatConnectionPreferencePage.cpp +++ b/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatConnectionPreferencePage.cpp @@ -1,277 +1,316 @@ /*=================================================================== 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 "QmitkXnatConnectionPreferencePage.h" +#include "QmitkXnatTreeBrowserView.h" #include "org_mitk_gui_qt_xnatinterface_Activator.h" #include "berryIPreferencesService.h" #include "berryPlatform.h" +#include #include #include #include #include #include #include #include #include "ctkXnatSession.h" #include "ctkXnatLoginProfile.h" #include "ctkXnatException.h" #include using namespace berry; QmitkXnatConnectionPreferencePage::QmitkXnatConnectionPreferencePage() : m_Control(0) { } void QmitkXnatConnectionPreferencePage::Init(berry::IWorkbench::Pointer) { } void QmitkXnatConnectionPreferencePage::CreateQtControl(QWidget* parent) { IPreferencesService* prefService = Platform::GetPreferencesService(); - berry::IPreferences::Pointer _XnatConnectionPreferencesNode = prefService->GetSystemPreferences()->Node("/XnatConnection"); + berry::IPreferences::Pointer _XnatConnectionPreferencesNode = prefService->GetSystemPreferences()->Node(QmitkXnatTreeBrowserView::VIEW_ID); m_XnatConnectionPreferencesNode = _XnatConnectionPreferencesNode; m_Controls.setupUi(parent); m_Control = new QWidget(parent); m_Control->setLayout(m_Controls.gridLayout); ctkXnatSession* session; try { session = mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatModuleContext()->GetService( mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatModuleContext()->GetServiceReference()); } catch (std::invalid_argument) { - session = 0; + session = nullptr; } - if (session != 0) + if (session != nullptr) { if (session->isOpen()) { - m_Controls.testConnectionButton->setText("Disconnect"); + m_Controls.xnatTestConnectionButton->setText("Disconnect"); } else { - m_Controls.testConnectionButton->setText("Connect"); + m_Controls.xnatTestConnectionButton->setText("Connect"); } } const QIntValidator *portV = new QIntValidator(0, 65535, parent); - m_Controls.inPort->setValidator(portV); + m_Controls.inXnatPort->setValidator(portV); const QRegExp hostRx("^(https?)://[^ /](\\S)+$"); const QRegExpValidator *hostV = new QRegExpValidator(hostRx, parent); - m_Controls.inHostAddress->setValidator(hostV); + m_Controls.inXnatHostAddress->setValidator(hostV); - connect(m_Controls.testConnectionButton, SIGNAL(clicked()), this, SLOT(ToggleConnection())); + connect(m_Controls.xnatTestConnectionButton, SIGNAL(clicked()), this, SLOT(ToggleConnection())); - connect(m_Controls.inHostAddress, SIGNAL(editingFinished()), this, SLOT(UrlChanged())); - connect(m_Controls.inDownloadPath, SIGNAL(editingFinished()), this, SLOT(DownloadPathChanged())); + connect(m_Controls.inXnatHostAddress, SIGNAL(editingFinished()), this, SLOT(UrlChanged())); + connect(m_Controls.inXnatDownloadPath, SIGNAL(editingFinished()), this, SLOT(DownloadPathChanged())); + + connect(m_Controls.cbUseNetworkProxy, SIGNAL(toggled(bool)), this, SLOT(onUseNetworkProxy(bool))); + + connect(m_Controls.btnDownloadPath, SIGNAL(clicked()), this, SLOT(OnDownloadPathButtonClicked())); + + m_Controls.groupBoxProxySettings->setVisible(m_Controls.cbUseNetworkProxy->isChecked()); this->Update(); } QWidget* QmitkXnatConnectionPreferencePage::GetQtControl() const { return m_Control; } bool QmitkXnatConnectionPreferencePage::PerformOk() { if (!UserInformationEmpty()) { IPreferences::Pointer _XnatConnectionPreferencesNode = m_XnatConnectionPreferencesNode.Lock(); if (_XnatConnectionPreferencesNode.IsNotNull()) { - _XnatConnectionPreferencesNode->Put(m_Controls.hostAddressLabel->text(), m_Controls.inHostAddress->text()); - _XnatConnectionPreferencesNode->Put(m_Controls.portLabel->text(), m_Controls.inPort->text()); - _XnatConnectionPreferencesNode->Put(m_Controls.usernameLabel->text(), m_Controls.inUsername->text()); - _XnatConnectionPreferencesNode->Put(m_Controls.passwortLabel->text(), m_Controls.inPassword->text()); - _XnatConnectionPreferencesNode->Put(m_Controls.downloadPathLabel->text(), m_Controls.inDownloadPath->text()); - + _XnatConnectionPreferencesNode->Put(m_Controls.xnatHostAddressLabel->text(), m_Controls.inXnatHostAddress->text()); + _XnatConnectionPreferencesNode->Put(m_Controls.xnatPortLabel->text(), m_Controls.inXnatPort->text()); + _XnatConnectionPreferencesNode->Put(m_Controls.xnatUsernameLabel->text(), m_Controls.inXnatUsername->text()); + _XnatConnectionPreferencesNode->Put(m_Controls.xnatPasswortLabel->text(), m_Controls.inXnatPassword->text()); + _XnatConnectionPreferencesNode->Put(m_Controls.xnatDownloadPathLabel->text(), m_Controls.inXnatDownloadPath->text()); + + // Network proxy settings + _XnatConnectionPreferencesNode->PutBool(m_Controls.cbUseNetworkProxy->text(), m_Controls.cbUseNetworkProxy->isChecked()); + _XnatConnectionPreferencesNode->Put(m_Controls.proxyAddressLabel->text(), m_Controls.inProxyAddress->text()); + _XnatConnectionPreferencesNode->Put(m_Controls.proxyPortLabel->text(), m_Controls.inProxyPort->text()); + _XnatConnectionPreferencesNode->Put(m_Controls.proxyUsernameLabel->text(), m_Controls.inProxyUsername->text()); + _XnatConnectionPreferencesNode->Put(m_Controls.proxyPasswordLabel->text(), m_Controls.inProxyPassword->text()); _XnatConnectionPreferencesNode->Flush(); return true; } } else { QMessageBox::critical(QApplication::activeWindow(), "Saving Preferences failed", "The connection parameters in XNAT Preferences were empty.\nPlease use the 'Connect' button to validate the connection parameters."); } return false; } void QmitkXnatConnectionPreferencePage::PerformCancel() { } bool QmitkXnatConnectionPreferencePage::UserInformationEmpty() { // To check empty QLineEdits in the following QString errString; - if (m_Controls.inHostAddress->text().isEmpty()) + if (m_Controls.inXnatHostAddress->text().isEmpty()) { errString += "Server Address is empty.\n"; } - if (m_Controls.inUsername->text().isEmpty()) + if (m_Controls.inXnatUsername->text().isEmpty()) { errString += "Username is empty.\n"; } - if (m_Controls.inPassword->text().isEmpty()) + if (m_Controls.inXnatPassword->text().isEmpty()) { errString += "Password is empty.\n"; } // if something is empty if (!errString.isEmpty()) { - m_Controls.testConnectionLabel->setStyleSheet("QLabel { color: red; }"); - m_Controls.testConnectionLabel->setText("Connecting failed.\n" + errString); + m_Controls.xnatTestConnectionLabel->setStyleSheet("QLabel { color: red; }"); + m_Controls.xnatTestConnectionLabel->setText("Connecting failed.\n" + errString); return true; } else { return false; } } void QmitkXnatConnectionPreferencePage::Update() { IPreferences::Pointer _XnatConnectionPreferencesNode = m_XnatConnectionPreferencesNode.Lock(); if (_XnatConnectionPreferencesNode.IsNotNull()) { - m_Controls.inHostAddress->setText(_XnatConnectionPreferencesNode->Get( - m_Controls.hostAddressLabel->text(), m_Controls.inHostAddress->text())); - m_Controls.inPort->setText(_XnatConnectionPreferencesNode->Get( - m_Controls.portLabel->text(), m_Controls.inPort->text())); - m_Controls.inUsername->setText(_XnatConnectionPreferencesNode->Get( - m_Controls.usernameLabel->text(), m_Controls.inUsername->text())); - m_Controls.inPassword->setText(_XnatConnectionPreferencesNode->Get( - m_Controls.passwortLabel->text(), m_Controls.inPassword->text())); - m_Controls.inDownloadPath->setText(_XnatConnectionPreferencesNode->Get( - m_Controls.downloadPathLabel->text(), m_Controls.inDownloadPath->text())); + m_Controls.inXnatHostAddress->setText(_XnatConnectionPreferencesNode->Get( + m_Controls.xnatHostAddressLabel->text(), m_Controls.inXnatHostAddress->text())); + m_Controls.inXnatPort->setText(_XnatConnectionPreferencesNode->Get( + m_Controls.xnatPortLabel->text(), m_Controls.inXnatPort->text())); + m_Controls.inXnatUsername->setText(_XnatConnectionPreferencesNode->Get( + m_Controls.xnatUsernameLabel->text(), m_Controls.inXnatUsername->text())); + m_Controls.inXnatPassword->setText(_XnatConnectionPreferencesNode->Get( + m_Controls.xnatPasswortLabel->text(), m_Controls.inXnatPassword->text())); + m_Controls.inXnatDownloadPath->setText(_XnatConnectionPreferencesNode->Get( + m_Controls.xnatDownloadPathLabel->text(), m_Controls.inXnatDownloadPath->text())); + + // Network proxy settings + m_Controls.cbUseNetworkProxy->setChecked(_XnatConnectionPreferencesNode->GetBool( + m_Controls.cbUseNetworkProxy->text(), false)); + m_Controls.inProxyAddress->setText(_XnatConnectionPreferencesNode->Get( + m_Controls.proxyAddressLabel->text(), m_Controls.inProxyAddress->text())); + m_Controls.inProxyPort->setText(_XnatConnectionPreferencesNode->Get( + m_Controls.proxyPortLabel->text(), m_Controls.inProxyPort->text())); + m_Controls.inProxyUsername->setText(_XnatConnectionPreferencesNode->Get( + m_Controls.proxyUsernameLabel->text(), m_Controls.inProxyUsername->text())); + m_Controls.inProxyPassword->setText(_XnatConnectionPreferencesNode->Get( + m_Controls.proxyPasswordLabel->text(), m_Controls.inProxyPassword->text())); } } void QmitkXnatConnectionPreferencePage::UrlChanged() { - m_Controls.inHostAddress->setStyleSheet("QLineEdit { background-color: white; }"); - QString str = m_Controls.inHostAddress->text(); + m_Controls.inXnatHostAddress->setStyleSheet("QLineEdit { background-color: white; }"); + QString str = m_Controls.inXnatHostAddress->text(); while (str.endsWith("/")) { str = str.left(str.length() - 1); } - m_Controls.inHostAddress->setText(str); + m_Controls.inXnatHostAddress->setText(str); - QUrl url(m_Controls.inHostAddress->text()); + QUrl url(m_Controls.inXnatHostAddress->text()); if (!url.isValid()) { - m_Controls.inHostAddress->setStyleSheet("QLineEdit { background-color: red; }"); + m_Controls.inXnatHostAddress->setStyleSheet("QLineEdit { background-color: red; }"); } } void QmitkXnatConnectionPreferencePage::DownloadPathChanged() { - m_Controls.inDownloadPath->setStyleSheet("QLineEdit { background-color: white; }"); - QString downloadPath = m_Controls.inDownloadPath->text(); + m_Controls.inXnatDownloadPath->setStyleSheet("QLineEdit { background-color: white; }"); + QString downloadPath = m_Controls.inXnatDownloadPath->text(); if (!downloadPath.isEmpty()) { if (downloadPath.lastIndexOf("/") != downloadPath.size() - 1) { downloadPath.append("/"); - m_Controls.inDownloadPath->setText(downloadPath); + m_Controls.inXnatDownloadPath->setText(downloadPath); } - QFileInfo path(m_Controls.inDownloadPath->text()); + QFileInfo path(m_Controls.inXnatDownloadPath->text()); if (!path.isDir()) { - m_Controls.inDownloadPath->setStyleSheet("QLineEdit { background-color: red; }"); + m_Controls.inXnatDownloadPath->setStyleSheet("QLineEdit { background-color: red; }"); } } } +void QmitkXnatConnectionPreferencePage::onUseNetworkProxy(bool status) +{ + m_Controls.groupBoxProxySettings->setVisible(status); +} + +void QmitkXnatConnectionPreferencePage::OnDownloadPathButtonClicked() +{ + QString dir = QFileDialog::getExistingDirectory(); + if (!dir.endsWith("/") || !dir.endsWith("\\")) + dir.append("/"); + m_Controls.inXnatDownloadPath->setText(dir); +} + void QmitkXnatConnectionPreferencePage::ToggleConnection() { ctkXnatSession* session = 0; try { session = mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatModuleContext()->GetService( mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatModuleContext()->GetServiceReference()); } catch (std::invalid_argument) { if (!UserInformationEmpty()) { PerformOk(); mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatSessionManager()->CreateXnatSession(); session = mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatModuleContext()->GetService( mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatModuleContext()->GetServiceReference()); } } if (session != 0 && session->isOpen()) { mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatSessionManager()->CloseXnatSession(); - m_Controls.testConnectionButton->setText("Connect"); - m_Controls.testConnectionLabel->clear(); + m_Controls.xnatTestConnectionButton->setText("Connect"); + m_Controls.xnatTestConnectionLabel->clear(); } else if (session != 0 && !session->isOpen()) { - m_Controls.testConnectionButton->setEnabled(false); + m_Controls.xnatTestConnectionButton->setEnabled(false); try { mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatSessionManager()->OpenXnatSession(); - m_Controls.testConnectionButton->setText("Disconnect"); - m_Controls.testConnectionLabel->setStyleSheet("QLabel { color: green; }"); - m_Controls.testConnectionLabel->setText("Connecting successful."); + m_Controls.xnatTestConnectionButton->setText("Disconnect"); + m_Controls.xnatTestConnectionLabel->setStyleSheet("QLabel { color: green; }"); + m_Controls.xnatTestConnectionLabel->setText("Connecting successful."); } catch (const ctkXnatAuthenticationException& auth) { - m_Controls.testConnectionLabel->setStyleSheet("QLabel { color: red; }"); - m_Controls.testConnectionLabel->setText("Connecting failed:\nAuthentication error."); + m_Controls.xnatTestConnectionLabel->setStyleSheet("QLabel { color: red; }"); + m_Controls.xnatTestConnectionLabel->setText("Connecting failed:\nAuthentication error."); MITK_INFO << auth.message().toStdString(); mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatSessionManager()->CloseXnatSession(); } catch (const ctkException& e) { - m_Controls.testConnectionLabel->setStyleSheet("QLabel { color: red; }"); - m_Controls.testConnectionLabel->setText("Connecting failed:\nInvalid Server Adress"); + m_Controls.xnatTestConnectionLabel->setStyleSheet("QLabel { color: red; }"); + m_Controls.xnatTestConnectionLabel->setText("Connecting failed:\nInvalid Server Adress"); MITK_INFO << e.message().toStdString(); mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatSessionManager()->CloseXnatSession(); } - m_Controls.testConnectionButton->setEnabled(true); + m_Controls.xnatTestConnectionButton->setEnabled(true); } } diff --git a/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatConnectionPreferencePage.h b/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatConnectionPreferencePage.h index c597dcc6b2..5b2feb14e8 100644 --- a/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatConnectionPreferencePage.h +++ b/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatConnectionPreferencePage.h @@ -1,84 +1,87 @@ /*=================================================================== 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 QMITKXNATCONNECTIONPREFERENCEPAGE_H_ #define QMITKXNATCONNECTIONPREFERENCEPAGE_H_ #include "berryIQtPreferencePage.h" #include #include "ui_QmitkXnatConnectionPreferencePageControls.h" class QWidget; class QLineEdit; struct QmitkXnatConnectionPreferencePage : public QObject, public berry::IQtPreferencePage { Q_OBJECT Q_INTERFACES(berry::IPreferencePage) public: QmitkXnatConnectionPreferencePage(); void Init(berry::IWorkbench::Pointer workbench) override; void CreateQtControl(QWidget* widget) override; QWidget* GetQtControl() const override; /// /// \see IPreferencePage::PerformOk() /// virtual bool PerformOk() override; /// /// \see IPreferencePage::PerformCancel() /// virtual void PerformCancel() override; /// /// \see IPreferencePage::Update() /// virtual void Update() override; protected slots: virtual void UrlChanged(); virtual void DownloadPathChanged(); + void OnDownloadPathButtonClicked(); /// /// Toggles the Connection in the Service Registry from opened to closed or the other way around. /// virtual void ToggleConnection(); + virtual void onUseNetworkProxy(bool); + protected: Ui::QmitkXnatConnectionPreferencePageControls m_Controls; QWidget* m_Control; berry::IPreferences::WeakPtr m_XnatConnectionPreferencesNode; private: /// /// Checks if the entered user information is empty. /// virtual bool UserInformationEmpty(); }; #endif /* QMITKXNATCONNECTIONPREFERENCEPAGE_H_ */ diff --git a/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatConnectionPreferencePageControls.ui b/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatConnectionPreferencePageControls.ui index 9b26a9b683..92edcda670 100644 --- a/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatConnectionPreferencePageControls.ui +++ b/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatConnectionPreferencePageControls.ui @@ -1,143 +1,262 @@ QmitkXnatConnectionPreferencePageControls 0 0 742 - 208 + 349 0 0 653 116 16777215 16777215 Form - - - - Port - - - - - - - <html><head/><body><p>Examples:</p><p>https://central.xnat.org<br/>http://localhost/xnat</p></body></html> - - - http(s):// - - - - - - - - 50 - 16777215 - - - - Standard-Port: 80 - - - - - - - - + + - Username + Use Network Proxy - - - - - - testuser + + true - - - Server Address + + + XNAT Connection Settings + + + + + Server Address + + + + + + + <html><head/><body><p>Examples:</p><p>https://central.xnat.org<br/>http://localhost/xnat</p></body></html> + + + http(s):// + + + + + + + Port + + + + + + + + 50 + 16777215 + + + + Standard-Port: 80 + + + + + + + + + + Username + + + + + + + testuser + + + + + + + Password + + + + + + + QLineEdit::Password + + + testpassword + + + + + + + Download Path + + + + + + + + + + Connect + + + + + + + Qt::LeftToRight + + + 1 + + + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + + + ... + + + + - - - - Password - - - - - - - QLineEdit::Password - - - testpassword - - - - - - - - - Download Path + + + Network Proxy Settings + + + + + + 50 + 16777215 + + + + Standard-Port: 80 + + + + + + + + + + Proxy Password + + + + + + + Proxy Username + + + + + + + <html><head/><body><p>Examples:</p><p>https://central.xnat.org<br/>http://localhost/xnat</p></body></html> + + + http(s):// + + + + + + + Proxy Port + + + + + + + QLineEdit::Password + + + testpassword + + + + + + + testuser + + + + + + + Proxy Server Address + + + + - - - Connect - - - - - - - Qt::LeftToRight - - - 1 + + + Qt::Vertical - - - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + 20 + 40 + - + diff --git a/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatSessionManager.cpp b/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatSessionManager.cpp index 142fb9cefd..c05c0952f5 100644 --- a/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatSessionManager.cpp +++ b/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatSessionManager.cpp @@ -1,87 +1,106 @@ /*=================================================================== 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 "QmitkXnatSessionManager.h" +#include "QmitkXnatTreeBrowserView.h" #include "org_mitk_gui_qt_xnatinterface_Activator.h" #include "berryPlatform.h" #include "berryIPreferences.h" #include "mitkLogMacros.h" -#include #include +#include +#include #include "ctkXnatSession.h" #include "ctkXnatException.h" QmitkXnatSessionManager::QmitkXnatSessionManager() : m_Session(0) { } QmitkXnatSessionManager::~QmitkXnatSessionManager() { if(m_SessionRegistration != 0) { m_SessionRegistration.Unregister(); } if(m_Session != 0) { delete m_Session; } } void QmitkXnatSessionManager::OpenXnatSession() { ctkXnatSession* session = mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatModuleContext()->GetService(m_SessionRegistration.GetReference()); if(session == NULL) return; if(!session->isOpen()) { session->open(); } } void QmitkXnatSessionManager::CreateXnatSession() { berry::IPreferencesService* prefService = berry::Platform::GetPreferencesService(); - berry::IPreferences::Pointer nodeConnectionPref = prefService->GetSystemPreferences()->Node("/XnatConnection"); + berry::IPreferences::Pointer nodeConnectionPref = prefService->GetSystemPreferences()->Node(QmitkXnatTreeBrowserView::VIEW_ID); QUrl url(nodeConnectionPref->Get("Server Address", "")); url.setPort(nodeConnectionPref->Get("Port", "").toInt()); ctkXnatLoginProfile profile; profile.setName("Default"); profile.setServerUrl(url); profile.setUserName(nodeConnectionPref->Get("Username", "")); profile.setPassword(nodeConnectionPref->Get("Password", "")); profile.setDefault(true); m_Session = new ctkXnatSession(profile); + if (nodeConnectionPref->Get("Proxy Server Address", "").length() != 0) + { + QNetworkProxy proxy; + proxy.setType(QNetworkProxy::HttpProxy); + proxy.setHostName(nodeConnectionPref->Get("Proxy Server Address", "")); + proxy.setPort(nodeConnectionPref->Get("Proxy Port", "").toUShort()); + + if (nodeConnectionPref->Get("Proxy Username", "").length() != 0 && + nodeConnectionPref->Get("Proxy Password", "").length() != 0) + { + proxy.setUser(nodeConnectionPref->Get("Proxy Username", "")); + proxy.setPassword(nodeConnectionPref->Get("Proxy Password", "")); + } + // Setting the proxy + m_Session->setHttpNetworkProxy(proxy); + } + m_SessionRegistration = mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatModuleContext()->RegisterService(m_Session); } void QmitkXnatSessionManager::CloseXnatSession() { ctkXnatSession* session = mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatModuleContext()->GetService(m_SessionRegistration.GetReference()); session->close(); m_SessionRegistration.Unregister(); m_SessionRegistration = 0; delete m_Session; m_Session = 0; } diff --git a/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatTreeBrowserView.cpp b/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatTreeBrowserView.cpp index 28b5fd98bc..0d41437fea 100644 --- a/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatTreeBrowserView.cpp +++ b/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatTreeBrowserView.cpp @@ -1,830 +1,993 @@ /*=================================================================== 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 "QmitkXnatTreeBrowserView.h" // Qmitk #include "org_mitk_gui_qt_xnatinterface_Activator.h" // Blueberry #include #include // CTK XNAT Core #include #include #include #include #include #include "ctkXnatFile.h" #include #include #include #include #include #include #include #include // MITK XNAT #include #include #include #include +#include // Qt #include +#include #include #include #include #include #include #include -#include +#include #include #include // MITK #include #include #include // Poco #include -const std::string QmitkXnatTreeBrowserView::VIEW_ID = "org.mitk.views.xnat.treebrowser"; +const QString QmitkXnatTreeBrowserView::VIEW_ID = "org.mitk.views.xnat.treebrowser"; QmitkXnatTreeBrowserView::QmitkXnatTreeBrowserView() : m_DataStorageServiceTracker(mitk::org_mitk_gui_qt_xnatinterface_Activator::GetContext()), m_TreeModel(new QmitkXnatTreeModel()), m_Tracker(0), -m_DownloadPath(berry::Platform::GetPreferencesService()->GetSystemPreferences()->Node("/XnatConnection")->Get("Download Path", "")) +m_DownloadPath(berry::Platform::GetPreferencesService()->GetSystemPreferences()->Node(VIEW_ID)->Get("Download Path", "")) { m_DataStorageServiceTracker.open(); // Set DownloadPath if (m_DownloadPath.isEmpty()) { QString xnatFolder = "XNAT_DOWNLOADS"; QDir dir(mitk::org_mitk_gui_qt_xnatinterface_Activator::GetContext()->getDataFile("").absoluteFilePath()); dir.mkdir(xnatFolder); dir.setPath(dir.path() + "/" + xnatFolder); m_DownloadPath = dir.path() + "/"; } } QmitkXnatTreeBrowserView::~QmitkXnatTreeBrowserView() { m_DataStorageServiceTracker.close(); delete m_TreeModel; delete m_Tracker; } void QmitkXnatTreeBrowserView::SetFocus() { } void QmitkXnatTreeBrowserView::CreateQtPartControl(QWidget *parent) { // Create GUI widgets from the Qt Designer's .ui file m_Controls.setupUi(parent); m_Controls.treeView->setModel(m_TreeModel); m_Controls.treeView->header()->hide(); m_Controls.treeView->setSelectionMode(QAbstractItemView::ExtendedSelection); m_Controls.treeView->setAcceptDrops(true); m_Controls.treeView->setDropIndicatorShown(true); m_Controls.labelError->setText("Please use the 'Connect' button in the Preferences."); m_Controls.labelError->setStyleSheet("QLabel { color: red; }"); m_SelectionProvider = new berry::QtSelectionProvider(); this->SetSelectionProvider(); m_Controls.treeView->setSelectionMode(QAbstractItemView::SingleSelection); m_Controls.treeView->setContextMenuPolicy(Qt::CustomContextMenu); m_Controls.groupBox->hide(); m_Tracker = new mitk::XnatSessionTracker(mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatModuleContext()); m_ContextMenu = new QMenu(m_Controls.treeView); connect(m_Controls.treeView, SIGNAL(clicked(const QModelIndex&)), SLOT(itemSelected(const QModelIndex&))); connect(m_Controls.treeView, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(OnContextMenuRequested(const QPoint&))); connect(m_Tracker, SIGNAL(AboutToBeClosed(ctkXnatSession*)), this, SLOT(CleanTreeModel(ctkXnatSession*))); connect(m_Tracker, SIGNAL(Opened(ctkXnatSession*)), this, SLOT(UpdateSession(ctkXnatSession*))); m_Tracker->Open(); ctkXnatSession* session; try { session = mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatModuleContext()->GetService( mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatModuleContext()->GetServiceReference()); } catch (std::invalid_argument) { session = 0; } if (session != 0) { m_Controls.labelError->setVisible(false); } else { m_Controls.labelError->setVisible(true); } connect(m_Controls.treeView, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(OnActivatedNode(const QModelIndex&))); connect(m_Controls.treeView, SIGNAL(clicked(const QModelIndex&)), this, SLOT(OnXnatNodeSelected(const QModelIndex&))); connect(m_TreeModel, SIGNAL(ResourceDropped(const QList&, ctkXnatObject*, const QModelIndex&)), this, SLOT(OnUploadResource(const QList&, ctkXnatObject*, const QModelIndex&))); connect(m_Controls.btnXnatUpload, SIGNAL(clicked()), this, SLOT(OnUploadFromDataStorage())); connect(m_Controls.btnXnatDownload, SIGNAL(clicked()), this, SLOT(OnDownloadSelectedXnatFile())); connect(m_Controls.btnCreateXnatFolder, SIGNAL(clicked()), this, SLOT(OnCreateResourceFolder())); } void QmitkXnatTreeBrowserView::OnCreateResourceFolder() { QModelIndex index = m_Controls.treeView->selectionModel()->currentIndex(); if(!index.isValid()) return; ctkXnatObject* parent = index.data(Qt::UserRole).value(); this->InternalAddResourceFolder(parent); m_TreeModel->refresh(index); } void QmitkXnatTreeBrowserView::OnDownloadSelectedXnatFile() { QModelIndex index = m_Controls.treeView->selectionModel()->currentIndex(); if(!index.isValid()) return; ctkXnatObject* selectedXnatObject = index.data(Qt::UserRole).value(); + bool enableDownload = dynamic_cast(selectedXnatObject) != nullptr; + enableDownload |= dynamic_cast(selectedXnatObject) != nullptr; - ctkXnatFile* selectedXnatFile = dynamic_cast(selectedXnatObject); - - if (selectedXnatFile != nullptr) + if (enableDownload) { this->InternalFileDownload(index, true); } } void QmitkXnatTreeBrowserView::OnUploadFromDataStorage() { QmitkXnatUploadFromDataStorageDialog dialog; dialog.SetDataStorage(this->GetDataStorage()); int result = dialog.exec(); - - if (result == QmitkXnatUploadFromDataStorageDialog::UPLOAD) + if (result == QDialog::Accepted) { QList nodes; nodes << dialog.GetSelectedNode().GetPointer(); QModelIndex index = m_Controls.treeView->selectionModel()->currentIndex(); if (!index.isValid()) return; ctkXnatObject* parent = m_TreeModel->xnatObject(index); this->OnUploadResource(nodes, parent, index); } } void QmitkXnatTreeBrowserView::OnXnatNodeSelected(const QModelIndex& index) { // Enable download button if (!index.isValid()) return; ctkXnatObject* selectedXnatObject = index.data(Qt::UserRole).value(); - bool enableDownload = dynamic_cast(selectedXnatObject); + bool enableDownload = dynamic_cast(selectedXnatObject) != nullptr; + enableDownload |= dynamic_cast(selectedXnatObject) != nullptr; m_Controls.btnXnatDownload->setEnabled(enableDownload); bool enableCreateFolder = dynamic_cast(selectedXnatObject) != nullptr; enableCreateFolder |= dynamic_cast(selectedXnatObject) != nullptr; enableCreateFolder |= dynamic_cast(selectedXnatObject) != nullptr; m_Controls.btnCreateXnatFolder->setEnabled(enableCreateFolder); bool enableUpload = dynamic_cast(selectedXnatObject) != nullptr; m_Controls.btnXnatUpload->setEnabled(enableUpload); } void QmitkXnatTreeBrowserView::OnActivatedNode(const QModelIndex& index) { if (!index.isValid()) return; - ctkXnatFile* file = dynamic_cast(index.data(Qt::UserRole).value()); - if (file != NULL) + + ctkXnatObject* selectedXnatObject = index.data(Qt::UserRole).value(); + bool enableDownload = dynamic_cast(selectedXnatObject) != nullptr; + enableDownload |= dynamic_cast(selectedXnatObject) != nullptr; + if (enableDownload) { - // If the selected node is a file, so show it in MITK - InternalFileDownload(index, true); + QMessageBox msgBox; + QString msg ("Do you want to download "+selectedXnatObject->name()+"?"); + msgBox.setWindowTitle("MITK XNAT upload"); + msgBox.setText(msg); + msgBox.setIcon(QMessageBox::Question); + msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); + int result = msgBox.exec(); + if (result == QMessageBox::Ok) + InternalFileDownload(index, true); } } void QmitkXnatTreeBrowserView::SetSelectionProvider() { GetSite()->SetSelectionProvider(m_SelectionProvider); } void QmitkXnatTreeBrowserView::UpdateSession(ctkXnatSession* session) { if (session != 0 && session->isOpen()) { m_Controls.labelError->setVisible(false); // Fill model and show in the GUI m_TreeModel->addDataModel(session->dataModel()); m_Controls.treeView->reset(); m_SelectionProvider->SetItemSelectionModel(m_Controls.treeView->selectionModel()); connect(session, SIGNAL(progress(QUuid,double)), this, SLOT(OnProgress(QUuid,double))); + connect(session, SIGNAL(sessionTimedOut()), this, SLOT(sessionTimedOutMsg())); + connect(session, SIGNAL(sessionAboutToBeTimedOut()), this, SLOT(sessionTimesOutSoonMsg())); } } void QmitkXnatTreeBrowserView::CleanTreeModel(ctkXnatSession* session) { if (session != 0) { m_TreeModel->removeDataModel(session->dataModel()); m_Controls.treeView->reset(); } } void QmitkXnatTreeBrowserView::OnProgress(QUuid /*queryID*/, double progress) { unsigned int currentProgress = progress*100; if (m_Controls.groupBox->isHidden()) { m_Controls.groupBox->show(); m_Controls.progressBar->setValue(0); } m_Controls.progressBar->setValue(currentProgress); } +void QmitkXnatTreeBrowserView::OnPreferencesChanged(const berry::IBerryPreferences* prefs) +{ + QString downloadPath = prefs->Get("Download Path", ""); + QDir downloadDir (downloadPath); + if (downloadPath.length() != 0 && downloadDir.exists()) + m_DownloadPath = downloadPath; +} + void QmitkXnatTreeBrowserView::InternalFileDownload(const QModelIndex& index, bool loadData) { - QVariant variant = m_TreeModel->data(index, Qt::UserRole); - if (variant.isValid()) + if (!index.isValid()) + return; + + ctkXnatObject* xnatObject = m_TreeModel->xnatObject(index); + if (xnatObject != nullptr) { - ctkXnatFile* file = dynamic_cast(variant.value()); - if (file != NULL) + // The path to the downloaded file + QString filePath; + QDir downloadPath (m_DownloadPath); + QString serverURL = berry::Platform::GetPreferencesService()->GetSystemPreferences()->Node(VIEW_ID)->Get("Server Address", ""); + bool isDICOM (false); + + // If a scan was selected, downloading the contained DICOM folder as ZIP + ctkXnatScan* scan = dynamic_cast(xnatObject); + + if (scan != nullptr) + { + isDICOM = true; + + if (!scan->isFetched()) + scan->fetch(); + + QList children = scan->children(); + + foreach (ctkXnatObject* obj, children) + { + if (obj->name() == "DICOM") + { + QString folderName = obj->resourceUri(); + folderName.replace("/","_"); + downloadPath = m_DownloadPath + folderName; + this->InternalDICOMDownload(obj, downloadPath); + serverURL = obj->resourceUri(); + } + } + } + else { - QDir downDir(m_DownloadPath); - QString filePath = m_DownloadPath + file->name(); + ctkXnatFile* file = dynamic_cast(xnatObject); + + if (file == nullptr) + { + MITK_ERROR << "Selected XNAT object not downloadable!"; + return; + } + + filePath = m_DownloadPath + file->name(); // Checking if the file exists already - if (downDir.exists(file->name())) + if (downloadPath.exists(file->name())) { MITK_INFO << "File '" << file->name().toStdString() << "' already exists!"; + serverURL = file->parent()->resourceUri(); } else { if (file->property("collection") == QString("DICOM")) { + isDICOM = true; ctkXnatObject* parent = file->parent(); - - filePath = m_DownloadPath + parent->property("label") + ".zip"; - - m_Controls.groupBox->setTitle("Downloading DICOM series..."); - m_Controls.groupBox->show(); - m_Controls.progressBar->setValue(0); - - parent->download(filePath); - - std::ifstream in(filePath.toStdString().c_str(), std::ios::binary); - poco_assert(in); - - // decompress to XNAT_DOWNLOAD dir - Poco::Zip::Decompress dec(in, Poco::Path(m_DownloadPath.toStdString())); - dec.decompressAllFiles(); - - in.close(); - QFile::remove(filePath); + QString folderName = parent->resourceUri(); + folderName.replace("/","_"); + downloadPath = m_DownloadPath + folderName; + this->InternalDICOMDownload(parent, downloadPath); + serverURL = parent->resourceUri(); } else { - MITK_INFO << "Download started ..."; - - m_Controls.groupBox->setTitle("Downloading file..."); - m_Controls.groupBox->show(); - m_Controls.progressBar->setValue(0); + this->SetStatusInformation("Downloading file " + file->name()); file->download(filePath); + serverURL = file->parent()->resourceUri(); // Checking if the file exists now - if (downDir.exists(file->name())) + if (downloadPath.exists(file->name())) { MITK_INFO << "Download of " << file->name().toStdString() << " completed!"; QMessageBox msgBox; msgBox.setText("Download of " + file->name() + " completed!"); msgBox.setIcon(QMessageBox::Information); msgBox.exec(); m_Controls.groupBox->hide(); } else { MITK_INFO << "Download of " << file->name().toStdString() << " failed!"; QMessageBox msgBox; msgBox.setText("Download of " + file->name() + " failed!"); msgBox.setIcon(QMessageBox::Critical); msgBox.exec(); m_Controls.groupBox->hide(); return; } } } - if (downDir.exists(file->name()) || file->property("collection") == "DICOM") + } + if (loadData) + { + QFileInfoList fileList; + if (isDICOM) { - if (loadData) - { - if (file->property("collection") == "DICOM") - { - // Search for the downloaded file an its file path - QDirIterator it(m_DownloadPath, QStringList() << file->name(), QDir::Files, QDirIterator::Subdirectories); - while (it.hasNext()) { - it.next(); - filePath = it.filePath(); - } - } - - if (filePath.isEmpty()) - { - MITK_INFO << "Decompressing failed!"; - return; - } - else if (!QFile(filePath).exists()) - { - MITK_INFO << "Decompressing failed!"; - return; - } - - mitk::IDataStorageService* dsService = m_DataStorageServiceTracker.getService(); - mitk::DataStorage::Pointer dataStorage = dsService->GetDataStorage()->GetDataStorage(); - QStringList list; - list << filePath; - try - { - QmitkIOUtil::Load(list, *dataStorage); - } - catch (const mitk::Exception& e) - { - MITK_INFO << e; - return; - } - mitk::RenderingManager::GetInstance()->InitializeViewsByBoundingObjects( - dsService->GetDataStorage()->GetDataStorage()); - } + fileList = downloadPath.entryInfoList(QDir::Files); + } + else + { + QFileInfo fileInfo(filePath); + fileList << fileInfo; } + + mitk::StringProperty::Pointer xnatURL = mitk::StringProperty::New(serverURL.toStdString()); + this->InternalOpenFiles(fileList, xnatURL); } - else + } +} + +void QmitkXnatTreeBrowserView::InternalDICOMDownload(ctkXnatObject *obj, QDir &DICOMDirPath) +{ + + QString filePath = m_DownloadPath + obj->property("label") + ".zip"; + + this->SetStatusInformation("Downloading DICOM series " + obj->parent()->name()); + obj->download(filePath); + + std::ifstream in(filePath.toStdString().c_str(), std::ios::binary); + poco_assert(in); + + // decompress to XNAT_DOWNLOAD dir + Poco::Zip::Decompress dec(in, Poco::Path(DICOMDirPath.path().toStdString()), true); + dec.decompressAllFiles(); + + in.close(); + QFile::remove(filePath); + + // Checking if the file exists now + if (DICOMDirPath.exists()) + { + MITK_INFO << "Download of DICOM series " << obj->parent()->name().toStdString() << " completed!"; + QMessageBox msgBox; + msgBox.setText("Download of DICOM series " + obj->parent()->name() + " completed!"); + msgBox.setIcon(QMessageBox::Information); + msgBox.exec(); + m_Controls.groupBox->hide(); + } + else + { + MITK_INFO << "Download of DICOM series " << obj->parent()->name().toStdString() << " failed!"; + QMessageBox msgBox; + msgBox.setText("Download of DICOM series " + obj->parent()->name() + " failed!"); + msgBox.setIcon(QMessageBox::Critical); + msgBox.exec(); + m_Controls.groupBox->hide(); + } +} + +void QmitkXnatTreeBrowserView::InternalOpenFiles(const QFileInfoList & fileList, mitk::StringProperty::Pointer xnatURL) +{ + + if (fileList.isEmpty()) + { + MITK_WARN << "No files available for laoding!"; + return; + } + + mitk::IDataStorageService* dsService = m_DataStorageServiceTracker.getService(); + mitk::DataStorage::Pointer dataStorage = dsService->GetDataStorage()->GetDataStorage(); + QStringList list; + list << fileList.at(0).absoluteFilePath(); + try + { + mitk::DataStorage::SetOfObjects::Pointer nodes = QmitkIOUtil::Load(list, *dataStorage); + if (nodes->size() == 1) { - MITK_INFO << "Selection was not a file!"; + mitk::DataNode* node = nodes->at(0); + node->SetProperty("xnat.url", xnatURL); } } + catch (const mitk::Exception& e) + { + MITK_INFO << e; + return; + } + mitk::RenderingManager::GetInstance()->InitializeViewsByBoundingObjects( + dsService->GetDataStorage()->GetDataStorage()); } void QmitkXnatTreeBrowserView::OnContextMenuDownloadFile() { QModelIndex index = m_Controls.treeView->currentIndex(); InternalFileDownload(index, false); } void QmitkXnatTreeBrowserView::OnContextMenuDownloadAndOpenFile() { QModelIndex index = m_Controls.treeView->currentIndex(); InternalFileDownload(index, true); } void QmitkXnatTreeBrowserView::OnContextMenuCreateResourceFolder() { const QModelIndex index = m_Controls.treeView->selectionModel()->currentIndex(); ctkXnatObject* parentObject = m_TreeModel->xnatObject(index); if (parentObject != nullptr) { this->InternalAddResourceFolder(parentObject); } } ctkXnatResource* QmitkXnatTreeBrowserView::InternalAddResourceFolder(ctkXnatObject *parent) { bool ok; QString folderName = QInputDialog::getText(m_Controls.treeView, tr("Create XNAT resource folder"), tr("Folder name:"), QLineEdit::Normal, tr("data"), &ok); if (ok) { if (folderName.isEmpty()) folderName = "NO LABEL"; return parent->addResourceFolder(folderName); } else { return nullptr; } } void QmitkXnatTreeBrowserView::InternalFileUpload(ctkXnatFile* file) { m_Controls.groupBox->setTitle("Uploading file..."); m_Controls.groupBox->show(); try { file->save(); MITK_INFO << "Upload of " << file->name().toStdString() << " completed!"; QMessageBox msgBox; msgBox.setText("Upload of " + file->name() + " completed!"); msgBox.setIcon(QMessageBox::Information); msgBox.show(); msgBox.exec(); } catch (ctkXnatException &e) { QMessageBox msgbox; msgbox.setText(e.what()); msgbox.setIcon(QMessageBox::Critical); msgbox.exec(); m_Controls.progressBar->setValue(0); } m_Controls.groupBox->hide(); } void QmitkXnatTreeBrowserView::OnContextMenuUploadFile() { QString filename = QFileDialog::getOpenFileName(m_Controls.treeView, tr("Open File"), QDir::homePath()); const QModelIndex index = m_Controls.treeView->selectionModel()->currentIndex(); ctkXnatResource* resource = dynamic_cast(m_TreeModel->xnatObject(index)); if (resource) { ctkXnatFile* file = new ctkXnatFile(resource); file->setLocalFilePath(filename); QFileInfo fileInfo (filename); file->setName(fileInfo.fileName()); this->InternalFileUpload(file); m_TreeModel->addChildNode(index, file); } } +void QmitkXnatTreeBrowserView::OnContextMenuCopyXNATUrlToClipboard() +{ + const QModelIndex index = m_Controls.treeView->selectionModel()->currentIndex(); + ctkXnatObject* currentXnatObject = m_TreeModel->xnatObject(index); + if (currentXnatObject != nullptr) + { + QString serverURL = berry::Platform::GetPreferencesService()->GetSystemPreferences()->Node(VIEW_ID)->Get("Server Address", ""); + serverURL.append(currentXnatObject->resourceUri()); + QClipboard *clipboard = QApplication::clipboard(); + clipboard->setText(serverURL); + } +} + +void QmitkXnatTreeBrowserView::OnContextMenuRefreshItem() +{ + const QModelIndex index = m_Controls.treeView->selectionModel()->currentIndex(); + if (index.isValid()) + { + this->m_TreeModel->refresh(index); + } +} + void QmitkXnatTreeBrowserView::OnUploadResource(const QList& droppedNodes, ctkXnatObject* parentObject, const QModelIndex& parentIndex) { if (parentObject == nullptr) return; //1. If not dropped on a resource, create a new folder ctkXnatResource* resource = dynamic_cast(parentObject); if (resource == nullptr) { resource = this->InternalAddResourceFolder(parentObject); } if (resource == nullptr) { MITK_WARN << "Could not upload file! No resource available!"; QMessageBox msgbox; msgbox.setText("Could not upload file! No resource available!"); msgbox.setIcon(QMessageBox::Critical); msgbox.exec(); return; } //2. Save files locally //3. Upload file mitk::DataNode* node = NULL; foreach (node, droppedNodes) { mitk::BaseData* data = node->GetData(); if (!data) return; QString fileName (QString::fromStdString(node->GetName())); ctkXnatFile* xnatFile = new ctkXnatFile(resource); if (dynamic_cast(data)) { fileName.append(".nrrd"); } else if (dynamic_cast(data)) { fileName.append(".vtk"); } else if (dynamic_cast(data)) { fileName.append(".mps"); } else { MITK_WARN << "Could not upload file! File-type not supported"; QMessageBox msgbox; msgbox.setText("Could not upload file! File-type not supported"); msgbox.setIcon(QMessageBox::Critical); msgbox.exec(); + return; } xnatFile->setName(fileName); QString xnatFolder = "XNAT_UPLOADS"; QDir dir(mitk::org_mitk_gui_qt_xnatinterface_Activator::GetContext()->getDataFile("").absoluteFilePath()); dir.mkdir(xnatFolder); fileName = dir.path().append("/" + fileName); mitk::IOUtil::Save (data, fileName.toStdString()); // TODO Check if file exists // AbstractFileReader::SetDefaultDataNodeProperties // und in die andere SetDefaultDataNodeProperties // PropertyName klein: mtime.initial + Kommentar mitk::StringProperty::Pointer orignalFilePath = mitk::StringProperty::New(); node->GetProperty(orignalFilePath, "path"); xnatFile->setLocalFilePath(fileName); this->InternalFileUpload(xnatFile); - MITK_INFO << "XNAT-OBJECT: "<xnatObject(parentIndex)->name(); + QFile::remove(fileName); -// m_TreeModel->addChildNode(parentIndex, xnatFile); m_TreeModel->refresh(parentIndex); // The filename for uploading // QFileInfo fileInfo; // if (surface) // { // // Save surface // fileName.append(".stl"); // xnatFile->setName(fileName); // dir.setPath(dir.path().append("/" + fileName)); // QString origFile = QString::fromStdString(orignalFilePath->GetValueAsString()); // origFile.append("/" + fileName); // origFile.append(".stl"); // fileInfo.setFile(origFile); // if (!fileInfo.exists()) // mitk::IOUtil::SaveSurface(surface, dir.path().toStdString()); // } // this->uploadFileToXnat(xnatFile, dir.path()); - - // TODO delete file!!! } } void QmitkXnatTreeBrowserView::OnContextMenuRequested(const QPoint & pos) { m_ContextMenu->clear(); + + QAction* actRefreshItem = new QAction("Refresh", m_ContextMenu); + m_ContextMenu->addAction(actRefreshItem); + connect(actRefreshItem, SIGNAL(triggered()), this, SLOT(OnContextMenuRefreshItem())); + m_ContextMenu->popup(QCursor::pos()); + + QAction* actGetXNATURL = new QAction("Copy XNAT URL to clipboard", m_ContextMenu); + m_ContextMenu->addAction(actGetXNATURL); + connect(actGetXNATURL, SIGNAL(triggered()), this, SLOT(OnContextMenuCopyXNATUrlToClipboard())); + m_ContextMenu->addSeparator(); + QModelIndex index = m_Controls.treeView->indexAt(pos); ctkXnatObject* xnatObject = m_TreeModel->xnatObject(index); bool downloadable = false; downloadable |= dynamic_cast(xnatObject)!=NULL; downloadable |= dynamic_cast(xnatObject)!=NULL; downloadable |= dynamic_cast(xnatObject)!=NULL; downloadable |= dynamic_cast(xnatObject)!=NULL; downloadable |= dynamic_cast(xnatObject)!=NULL; downloadable |= dynamic_cast(xnatObject)!=NULL; downloadable |= dynamic_cast(xnatObject)!=NULL; downloadable |= dynamic_cast(xnatObject)!=NULL; bool canHaveResourceFolder = false; canHaveResourceFolder |= dynamic_cast(xnatObject) != NULL; canHaveResourceFolder |= dynamic_cast(xnatObject) != NULL; canHaveResourceFolder |= dynamic_cast(xnatObject) != NULL; bool uploadFilePossible = false; uploadFilePossible |= dynamic_cast(xnatObject) != NULL; uploadFilePossible |= dynamic_cast(xnatObject) != NULL; uploadFilePossible |= dynamic_cast(xnatObject) != NULL; if (downloadable) { QAction* actDownload = new QAction("Download", m_ContextMenu); connect(actDownload, SIGNAL(triggered()), this, SLOT(OnContextMenuDownloadFile())); m_ContextMenu->addAction(actDownload); ctkXnatFile* file = dynamic_cast(xnatObject); if (file) { QAction* actView = new QAction("Download and Open", m_ContextMenu); connect(actView, SIGNAL(triggered()), this, SLOT(OnContextMenuDownloadAndOpenFile())); m_ContextMenu->addAction(actView); } } if (canHaveResourceFolder) { QAction* actCreateResource = new QAction("Add resource folder", m_ContextMenu); connect(actCreateResource, SIGNAL(triggered()), this, SLOT(OnContextMenuCreateResourceFolder())); m_ContextMenu->addAction(actCreateResource); } if (uploadFilePossible) { QAction* actUploadFile = new QAction("Upload File", m_ContextMenu); connect(actUploadFile, SIGNAL(triggered()), this, SLOT(OnContextMenuUploadFile())); m_ContextMenu->addAction(actUploadFile); } ctkXnatProject* project = dynamic_cast(xnatObject); if (project != NULL) { QAction* actCreateSubject = new QAction("Create new subject", m_ContextMenu); m_ContextMenu->addAction(actCreateSubject); connect(actCreateSubject, SIGNAL(triggered()), this, SLOT(OnContextMenuCreateNewSubject())); m_ContextMenu->popup(QCursor::pos()); } ctkXnatSubject* subject = dynamic_cast(xnatObject); if (subject != NULL) { QAction* actCreateExperiment = new QAction("Create new experiment", m_ContextMenu); m_ContextMenu->addAction(actCreateExperiment); connect(actCreateExperiment, SIGNAL(triggered()), this, SLOT(OnContextMenuCreateNewExperiment())); m_ContextMenu->popup(QCursor::pos()); } m_ContextMenu->popup(QCursor::pos()); } void QmitkXnatTreeBrowserView::itemSelected(const QModelIndex& index) { QLayout* layout = m_Controls.infoVerticalLayout; QLayoutItem *child; while ((child = layout->takeAt(0)) != 0) { delete child->widget(); } QVariant variant = m_TreeModel->data(index, Qt::UserRole); if (variant.isValid()) { ctkXnatSession *session = mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatModuleContext()->GetService( mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatModuleContext()->GetServiceReference()); ctkXnatObject* object = variant.value(); ctkXnatProject* project = dynamic_cast(object); ctkXnatSubject* subject = dynamic_cast(object); ctkXnatExperiment* experiment = dynamic_cast(object); if (project != NULL) { QmitkXnatProjectWidget* widget = new QmitkXnatProjectWidget(QmitkXnatProjectWidget::Mode::INFO); widget->SetProject(project); layout->addWidget(widget); } else if (subject != NULL) { QMap paramMap; paramMap.insert("columns", "dob,gender,handedness,weight,height"); QUuid requestID = session->httpGet(QString("%1/subjects").arg(subject->parent()->resourceUri()), paramMap); QList results = session->httpSync(requestID); foreach(const QVariantMap& propertyMap, results) { QMapIterator it(propertyMap); bool isConcretSubject = false; if (it.hasNext()) { it.next(); QString str = it.key().toLatin1().data(); QVariant var = it.value(); // After CTK Change (subjectID = name) to (subjectID = ID) // CHANGE TO: if (var == subject->property("ID")) if (var == subject->property("URI").right(11)) { isConcretSubject = true; } else { isConcretSubject = false; } it.toFront(); } while (it.hasNext() && isConcretSubject) { it.next(); QString str = it.key().toLatin1().data(); QVariant var = it.value(); subject->setProperty(str, var); } } QmitkXnatSubjectWidget* widget = new QmitkXnatSubjectWidget(QmitkXnatSubjectWidget::Mode::INFO); widget->SetSubject(subject); layout->addWidget(widget); } else if (experiment != NULL) { QMap paramMap; paramMap.insert("columns", "date,time,scanner,modality"); QUuid requestID = session->httpGet(QString("%1/experiments").arg(experiment->parent()->resourceUri()), paramMap); QList results = session->httpSync(requestID); foreach(const QVariantMap& propertyMap, results) { QMapIterator it(propertyMap); bool isConcretExperiment = false; if (it.hasNext()) { it.next(); QString str = it.key().toLatin1().data(); QVariant var = it.value(); if (var == experiment->property("URI")) { isConcretExperiment = true; } else { isConcretExperiment = false; } it.toFront(); } while (it.hasNext() && isConcretExperiment) { it.next(); QString str = it.key().toLatin1().data(); QVariant var = it.value(); experiment->setProperty(str, var); } } QmitkXnatExperimentWidget* widget = new QmitkXnatExperimentWidget(QmitkXnatExperimentWidget::Mode::INFO); widget->SetExperiment(experiment); layout->addWidget(widget); } } } void QmitkXnatTreeBrowserView::OnContextMenuCreateNewSubject() { QModelIndex index = m_Controls.treeView->currentIndex(); QVariant variant = m_TreeModel->data(index, Qt::UserRole); if (variant.isValid()) { QmitkXnatCreateObjectDialog* dialog = new QmitkXnatCreateObjectDialog(QmitkXnatCreateObjectDialog::SpecificType::SUBJECT); if (dialog->exec() == QDialog::Accepted) { ctkXnatProject* project = dynamic_cast(variant.value()); ctkXnatSubject* subject = dynamic_cast(dialog->GetXnatObject()); subject->setParent(project); subject->save(); // Get xnat session from micro service ctkXnatSession* session = mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatModuleContext()->GetService( mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatModuleContext()->GetServiceReference()); // Update View m_TreeModel->removeDataModel(session->dataModel()); UpdateSession(session); } } } void QmitkXnatTreeBrowserView::OnContextMenuCreateNewExperiment() { QModelIndex index = m_Controls.treeView->currentIndex(); QVariant variant = m_TreeModel->data(index, Qt::UserRole); if (variant.isValid()) { QmitkXnatCreateObjectDialog* dialog = new QmitkXnatCreateObjectDialog(QmitkXnatCreateObjectDialog::SpecificType::EXPERIMENT); if (dialog->exec() == QDialog::Accepted) { ctkXnatSubject* subject = dynamic_cast(variant.value()); ctkXnatExperiment* experiment = dynamic_cast(dialog->GetXnatObject()); experiment->setParent(subject); experiment->setProperty("xsiType", experiment->imageModality()); experiment->save(); // Get xnat session from micro service ctkXnatSession* session = mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatModuleContext()->GetService( mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatModuleContext()->GetServiceReference()); // Update View m_TreeModel->removeDataModel(session->dataModel()); UpdateSession(session); } } } + +void QmitkXnatTreeBrowserView::SetStatusInformation(const QString& text) +{ + m_Controls.groupBox->setTitle(text); + m_Controls.progressBar->setValue(0); + m_Controls.groupBox->show(); +} + +void QmitkXnatTreeBrowserView::sessionTimedOutMsg() +{ + ctkXnatSession* session = qobject_cast(QObject::sender()); + + if (session == nullptr) + return; + + ctkXnatDataModel* dataModel = session->dataModel(); + m_TreeModel->removeDataModel(dataModel); + m_Controls.treeView->reset(); + session->close(); + m_Controls.labelError->show(); + QMessageBox::warning(m_Controls.treeView, "Session Timeout", "The session timed out."); +} + +void QmitkXnatTreeBrowserView::sessionTimesOutSoonMsg() +{ + ctkXnatSession* session = qobject_cast(QObject::sender()); + + if (session == nullptr) + return; + + QMessageBox msgBox; + msgBox.setIcon(QMessageBox::Warning); + msgBox.setWindowTitle("Session Timeout Soon"); + msgBox.setText("The session will time out in 1 minute.\nDo you want to renew the session?"); + msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + msgBox.setDefaultButton(QMessageBox::No); + msgBox.show(); + QTimer* timer = new QTimer(this); + timer->start(60000); + this->connect(timer, SIGNAL(timeout()), &msgBox, SLOT(reject())); + if (msgBox.exec() == QMessageBox::Yes){ + session->renew(); + } + timer->stop(); +} diff --git a/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatTreeBrowserView.h b/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatTreeBrowserView.h index 9b90eb488f..b443681770 100644 --- a/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatTreeBrowserView.h +++ b/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatTreeBrowserView.h @@ -1,118 +1,134 @@ /*=================================================================== 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 QMITKXNATTREEBROWSERVIEW_H #define QMITKXNATTREEBROWSERVIEW_H #include #include #include "ui_QmitkXnatTreeBrowserViewControls.h" // ctkXnatCore #include "ctkXnatSession.h" // ctkXnatWidget #include "QmitkXnatTreeModel.h" // MitkXNAT Module #include "mitkXnatSessionTracker.h" #include #include +#include + class QMenu; + /*! \brief QmitkXnatTreeBrowserView \warning This class is not yet documented. Use "git blame" and ask the author to provide basic documentation. \sa QmitkFunctionality \ingroup ${plugin_target}_internal */ class QmitkXnatTreeBrowserView : public QmitkAbstractView { // this is needed for all Qt objects that should have a Qt meta-object // (everything that derives from QObject and wants to have signal/slots) Q_OBJECT public: QmitkXnatTreeBrowserView(); ~QmitkXnatTreeBrowserView(); - static const std::string VIEW_ID; + static const QString VIEW_ID; virtual void CreateQtPartControl(QWidget *parent) override; protected slots: /// \brief Opens or reuses the xnat editor with the activated node as root item. void OnActivatedNode(const QModelIndex& index); /// \brief Updates the ctkXnatSession and the user interface void UpdateSession(ctkXnatSession* session); /// \brief Cleans the tree model void CleanTreeModel(ctkXnatSession* session); void OnContextMenuRequested(const QPoint & pos); void OnContextMenuDownloadAndOpenFile(); void OnContextMenuDownloadFile(); void OnContextMenuCreateResourceFolder(); void OnContextMenuUploadFile(); void OnContextMenuCreateNewSubject(); void OnContextMenuCreateNewExperiment(); + void OnContextMenuCopyXNATUrlToClipboard(); + void OnContextMenuRefreshItem(); void OnUploadResource(const QList& , ctkXnatObject *, const QModelIndex &parentIndex); void OnProgress(QUuid, double); void itemSelected(const QModelIndex& index); void OnUploadFromDataStorage(); + void sessionTimedOutMsg(); + void sessionTimesOutSoonMsg(); + protected: virtual void SetFocus() override; Ui::QmitkXnatTreeBrowserViewControls m_Controls; private slots: void OnXnatNodeSelected(const QModelIndex &index); void OnDownloadSelectedXnatFile(); void OnCreateResourceFolder(); private: + + void OnPreferencesChanged(const berry::IBerryPreferences*) override; + void InternalFileDownload(const QModelIndex& index, bool loadData); + void InternalDICOMDownload(ctkXnatObject* obj, QDir &DICOMDirPath); void InternalFileUpload(ctkXnatFile *file); ctkXnatResource* InternalAddResourceFolder(ctkXnatObject* parent); + void InternalOpenFiles(const QFileInfoList&, mitk::StringProperty::Pointer xnatURL); + + void SetStatusInformation(const QString&); + berry::QtSelectionProvider::Pointer m_SelectionProvider; void SetSelectionProvider() override; ctkServiceTracker m_DataStorageServiceTracker; QmitkXnatTreeModel* m_TreeModel; mitk::XnatSessionTracker* m_Tracker; QString m_DownloadPath; QMenu* m_ContextMenu; }; #endif // QMITKXNATTREEBROWSERVIEW_H diff --git a/Plugins/org.mitk.gui.qt.xnat/src/internal/org_mitk_gui_qt_xnatinterface_Activator.cpp b/Plugins/org.mitk.gui.qt.xnat/src/internal/org_mitk_gui_qt_xnatinterface_Activator.cpp index af07fd153d..db5c9ec13f 100644 --- a/Plugins/org.mitk.gui.qt.xnat/src/internal/org_mitk_gui_qt_xnatinterface_Activator.cpp +++ b/Plugins/org.mitk.gui.qt.xnat/src/internal/org_mitk_gui_qt_xnatinterface_Activator.cpp @@ -1,71 +1,73 @@ /*=================================================================== 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 "org_mitk_gui_qt_xnatinterface_Activator.h" #include +#include "QmitkUploadToXNATAction.h" #include "QmitkXnatTreeBrowserView.h" #include "QmitkXnatConnectionPreferencePage.h" #include #include US_INITIALIZE_MODULE namespace mitk { -ctkPluginContext* org_mitk_gui_qt_xnatinterface_Activator::m_Context = 0; -us::ModuleContext* org_mitk_gui_qt_xnatinterface_Activator::m_ModuleContext = 0; +ctkPluginContext* org_mitk_gui_qt_xnatinterface_Activator::m_Context = nullptr; +us::ModuleContext* org_mitk_gui_qt_xnatinterface_Activator::m_ModuleContext = nullptr; QmitkXnatSessionManager* org_mitk_gui_qt_xnatinterface_Activator::GetXnatSessionManager() { static QmitkXnatSessionManager manager; return &manager; } ctkPluginContext* org_mitk_gui_qt_xnatinterface_Activator::GetContext() { return m_Context; } us::ModuleContext* org_mitk_gui_qt_xnatinterface_Activator::GetXnatModuleContext() { return m_ModuleContext; } void org_mitk_gui_qt_xnatinterface_Activator::start(ctkPluginContext* context) { this->m_Context = context; this->m_ModuleContext = us::GetModuleContext(); BERRY_REGISTER_EXTENSION_CLASS(QmitkXnatTreeBrowserView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkXnatConnectionPreferencePage, context) + BERRY_REGISTER_EXTENSION_CLASS(QmitkUploadToXNATAction, context) } void org_mitk_gui_qt_xnatinterface_Activator::stop(ctkPluginContext* context) { Q_UNUSED(context) Q_UNUSED(us::GetModuleContext()) this->m_Context = 0; this->m_ModuleContext = 0; } } #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) Q_EXPORT_PLUGIN2(org_mitk_gui_qt_xnatinterface, mitk::org_mitk_gui_qt_xnatinterface_Activator) #endif