diff --git a/Applications/PluginGenerator/ProjectTemplate/CMakeExternals/MITK.cmake b/Applications/PluginGenerator/ProjectTemplate/CMakeExternals/MITK.cmake index aeccf992f3..d739fcdab4 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 "releases/master" CACHE STRING "The git tag/hash to be used when cloning from MITK_GIT_REPOSITORY") + set(MITK_GIT_TAG "v2015.05.0" 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/Modules/QtWidgets/include/QmitkStdMultiWidget.h b/Modules/QtWidgets/include/QmitkStdMultiWidget.h index 8e28454464..8ee9928d05 100644 --- a/Modules/QtWidgets/include/QmitkStdMultiWidget.h +++ b/Modules/QtWidgets/include/QmitkStdMultiWidget.h @@ -1,409 +1,408 @@ /*=================================================================== 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 QmitkStdMultiWidget_h #define QmitkStdMultiWidget_h #include "MitkQtWidgetsExports.h" #include #include #include #include #include #include #include #include #include class QHBoxLayout; class QVBoxLayout; class QGridLayout; class QSpacerItem; class QmitkLevelWindowWidget; class QmitkRenderWindow; class vtkCornerAnnotation; class vtkMitkRectangleProp; namespace mitk { class RenderingManager; } /// \ingroup QmitkModule class MITKQTWIDGETS_EXPORT QmitkStdMultiWidget : public QWidget { Q_OBJECT public: QmitkStdMultiWidget(QWidget* parent = 0, Qt::WindowFlags f = 0, mitk::RenderingManager* renderingManager = 0, mitk::BaseRenderer::RenderingMode::Type renderingMode = mitk::BaseRenderer::RenderingMode::Standard, const QString& name = "stdmulti"); virtual ~QmitkStdMultiWidget(); mitk::SliceNavigationController* GetTimeNavigationController(); void RequestUpdate(); void ForceImmediateUpdate(); mitk::MouseModeSwitcher* GetMouseModeSwitcher(); QmitkRenderWindow* GetRenderWindow1() const; QmitkRenderWindow* GetRenderWindow2() const; QmitkRenderWindow* GetRenderWindow3() const; QmitkRenderWindow* GetRenderWindow4() const; - const mitk::Point3D GetCrossPosition() const; void EnablePositionTracking(); void DisablePositionTracking(); int GetLayout() const; bool GetGradientBackgroundFlag() const; /*! \brief Access node of widget plane 1 \return DataNode holding widget plane 1 */ mitk::DataNode::Pointer GetWidgetPlane1(); /*! \brief Access node of widget plane 2 \return DataNode holding widget plane 2 */ mitk::DataNode::Pointer GetWidgetPlane2(); /*! \brief Access node of widget plane 3 \return DataNode holding widget plane 3 */ mitk::DataNode::Pointer GetWidgetPlane3(); /*! \brief Convenience method to access node of widget planes \param id number of widget plane to be returned \return DataNode holding widget plane 3 */ mitk::DataNode::Pointer GetWidgetPlane(int id); bool IsColoredRectanglesEnabled() const; bool IsDepartmentLogoEnabled() const; void InitializeWidget(); /// called when the StdMultiWidget is closed to remove the 3 widget planes and the helper node from the DataStorage void RemovePlanesFromDataStorage(); void AddPlanesToDataStorage(); void SetDataStorage( mitk::DataStorage* ds ); /** \brief Listener to the CrosshairPositionEvent Ensures the CrosshairPositionEvent is handled only once and at the end of the Qt-Event loop */ void HandleCrosshairPositionEvent(); /// activate Menu Widget. true: activated, false: deactivated void ActivateMenuWidget( bool state ); bool IsMenuWidgetEnabled() const; void SetCornerAnnotationVisibility(bool visibility); bool IsCornerAnnotationVisible(void) const; protected: void UpdateAllWidgets(); void HideAllWidgetToolbars(); mitk::DataNode::Pointer GetTopLayerNode(mitk::DataStorage::SetOfObjects::ConstPointer nodes); public slots: /// Receives the signal from HandleCrosshairPositionEvent, executes the StatusBar update void HandleCrosshairPositionEventDelayed(); void changeLayoutTo2DImagesUp(); void changeLayoutTo2DImagesLeft(); void changeLayoutToDefault(); void changeLayoutToBig3D(); void changeLayoutToWidget1(); void changeLayoutToWidget2(); void changeLayoutToWidget3(); void changeLayoutToRowWidget3And4(); void changeLayoutToColumnWidget3And4(); void changeLayoutToRowWidgetSmall3andBig4(); void changeLayoutToSmallUpperWidget2Big3and4(); void changeLayoutTo2x2Dand3DWidget(); void changeLayoutToLeft2Dand3DRight2D(); void changeLayoutTo2DUpAnd3DDown(); void Fit(); void InitPositionTracking(); void AddDisplayPlaneSubTree(); void EnableStandardLevelWindow(); void DisableStandardLevelWindow(); bool InitializeStandardViews( const mitk::Geometry3D * geometry ); void wheelEvent( QWheelEvent * e ) override; void mousePressEvent(QMouseEvent * e) override; void moveEvent( QMoveEvent* e ) override; void EnsureDisplayContainsPoint(mitk::BaseRenderer *renderer, const mitk::Point3D&p); void MoveCrossToPosition(const mitk::Point3D& newPosition); //void EnableNavigationControllerEventListening(); //void DisableNavigationControllerEventListening(); void EnableGradientBackground(); void DisableGradientBackground(); void EnableDepartmentLogo(); void DisableDepartmentLogo(); void EnableColoredRectangles(); void DisableColoredRectangles(); void SetWidgetPlaneVisibility(const char* widgetName, bool visible, mitk::BaseRenderer *renderer=NULL); void SetWidgetPlanesVisibility(bool visible, mitk::BaseRenderer *renderer=NULL); void SetWidgetPlanesLocked(bool locked); void SetWidgetPlanesRotationLocked(bool locked); void SetWidgetPlanesRotationLinked( bool link ); void SetWidgetPlaneMode( int mode ); void SetGradientBackgroundColors( const mitk::Color & upper, const mitk::Color & lower ); void SetDepartmentLogoPath( const char * path ); void SetWidgetPlaneModeToSlicing( bool activate ); void SetWidgetPlaneModeToRotation( bool activate ); void SetWidgetPlaneModeToSwivel( bool activate ); void OnLayoutDesignChanged( int layoutDesignIndex ); void ResetCrosshair(); signals: void LeftMouseClicked(mitk::Point3D pointValue); void WheelMoved(QWheelEvent*); void WidgetPlanesRotationLinked(bool); void WidgetPlanesRotationEnabled(bool); void ViewsInitialized(); void WidgetPlaneModeSlicing(bool); void WidgetPlaneModeRotation(bool); void WidgetPlaneModeSwivel(bool); void WidgetPlaneModeChange(int); void WidgetNotifyNewCrossHairMode(int); void Moved(); public: /** Define RenderWindow (public)*/ QmitkRenderWindow* mitkWidget1; QmitkRenderWindow* mitkWidget2; QmitkRenderWindow* mitkWidget3; QmitkRenderWindow* mitkWidget4; QmitkLevelWindowWidget* levelWindowWidget; /********************************/ enum { PLANE_MODE_SLICING = 0, PLANE_MODE_ROTATION, PLANE_MODE_SWIVEL }; enum { LAYOUT_DEFAULT = 0, LAYOUT_2D_IMAGES_UP, LAYOUT_2D_IMAGES_LEFT, LAYOUT_BIG_3D, LAYOUT_WIDGET1, LAYOUT_WIDGET2, LAYOUT_WIDGET3, LAYOUT_2X_2D_AND_3D_WIDGET, LAYOUT_ROW_WIDGET_3_AND_4, LAYOUT_COLUMN_WIDGET_3_AND_4, LAYOUT_ROW_WIDGET_SMALL3_AND_BIG4 , LAYOUT_SMALL_UPPER_WIDGET2_BIG3_AND4,LAYOUT_2D_AND_3D_LEFT_2D_RIGHT_WIDGET, LAYOUT_2D_UP_AND_3D_DOWN}; enum { AXIAL, SAGITTAL, CORONAL, THREE_D }; /** * @brief SetCornerAnnotation Create a corner annotation for a widget. * @param text The text of the annotation. * @param color The color. * @param widgetNumber The widget (0-3). */ void SetDecorationProperties(std::string text, mitk::Color color, int widgetNumber); /** * @brief GetRenderWindow convinience method to get a widget. * @param number of the widget (0-3) * @return The renderwindow widget. */ QmitkRenderWindow *GetRenderWindow(unsigned int number); /** * @brief SetGradientBackgroundColorForRenderWindow background for a widget. * * If two different input colors are, a gradient background is generated. * * @param upper Upper color of the gradient background. * @param lower Lower color of the gradient background. * @param widgetNumber The widget (0-3). */ void SetGradientBackgroundColorForRenderWindow(const mitk::Color &upper, const mitk::Color &lower, unsigned int widgetNumber); /** * @brief GetDecorationColorForWidget Get the color for annotation, crosshair and rectangle. * @param widgetNumber Number of the renderwindow (0-3). * @return Color in mitk format. */ mitk::Color GetDecorationColor(unsigned int widgetNumber); /** * @brief SetDecorationColor Set the color of the decoration of the 4 widgets. * * This is used to color the frame of the renderwindow and the corner annatation. * For the first 3 widgets, this color is a property of the helper object nodes * which contain the respective plane geometry. For widget 4, this is a member, * since there is no data node for this widget. */ void SetDecorationColor(unsigned int widgetNumber, mitk::Color color); /** * @brief GetCornerAnnotationText Getter for corner annotation text. * @param widgetNumber the widget number (0-3). * @return The text in the corner annotation. */ std::string GetCornerAnnotationText(unsigned int widgetNumber); /** * @brief GetGradientColors Getter for gradientbackground colors. * @param widgetNumber the widget number (0-3). * @return A pair of colors. First: upper, second: lower. */ std::pair GetGradientColors(unsigned int widgetNumber); protected: QHBoxLayout* QmitkStdMultiWidgetLayout; int m_Layout; int m_PlaneMode; mitk::RenderingManager* m_RenderingManager; mitk::LogoOverlay::Pointer m_LogoRendering; bool m_GradientBackgroundFlag; mitk::MouseModeSwitcher::Pointer m_MouseModeSwitcher; mitk::SliceNavigationController* m_TimeNavigationController; mitk::DataStorage::Pointer m_DataStorage; /** * @brief m_PlaneNode1 the 3 helper objects which contain the plane geometry. */ mitk::DataNode::Pointer m_PlaneNode1; mitk::DataNode::Pointer m_PlaneNode2; mitk::DataNode::Pointer m_PlaneNode3; /** * @brief m_ParentNodeForGeometryPlanes This helper object is added to the datastorage * and contains the 3 planes for displaying the image geometry (crosshair and 3D planes). */ mitk::DataNode::Pointer m_ParentNodeForGeometryPlanes; /** * @brief m_DecorationColorWidget4 color for annotation and rectangle of widget 4. * * For other widgets1-3, the color is a property of the respective data node. * There is no node for widget 4, hence, we need an extra member. */ mitk::Color m_DecorationColorWidget4; /** * @brief m_GradientBackgroundColors Contains the colors of the gradient background. * */ std::pair m_GradientBackgroundColors[4]; QSplitter *m_MainSplit; QSplitter *m_LayoutSplit; QSplitter *m_SubSplit1; QSplitter *m_SubSplit2; QWidget *mitkWidget1Container; QWidget *mitkWidget2Container; QWidget *mitkWidget3Container; QWidget *mitkWidget4Container; vtkSmartPointer m_CornerAnnotations[4]; vtkSmartPointer m_RectangleProps[4]; bool m_PendingCrosshairPositionEvent; bool m_CrosshairNavigationEnabled; /** * @brief CreateCornerAnnotation helper method to create a corner annotation. * @param text of the annotation. * @param color of the annotation. * @return the complete CornerAnnotation. */ vtkSmartPointer CreateCornerAnnotation(std::string text, mitk::Color color); /** * @brief FillGradientBackgroundWithBlack Internal helper method to initialize the * gradient background colors with black. */ void FillGradientBackgroundWithBlack(); }; #endif /*QmitkStdMultiWidget_h*/ diff --git a/Modules/Segmentation/DataManagement/mitkExtrudedContour.h b/Modules/Segmentation/DataManagement/mitkExtrudedContour.h index f9f8713ede..97107b56a8 100644 --- a/Modules/Segmentation/DataManagement/mitkExtrudedContour.h +++ b/Modules/Segmentation/DataManagement/mitkExtrudedContour.h @@ -1,128 +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 MITKEXTRUDEDCONTOUR_H_HEADER_INCLUDED #define MITKEXTRUDEDCONTOUR_H_HEADER_INCLUDED #include "mitkBoundingObject.h" #include #include #include #include #include class vtkLinearExtrusionFilter; class vtkPlanes; class vtkClipPolyData; class vtkLinearSubdivisionFilter; class vtkTriangleFilter; class vtkDecimatePro; class vtkPolygon; namespace mitk { //##Documentation //## @brief Data class containing a bounding-object created by //## extruding a Contour along a vector //## //## The m_Contour is extruded in the direction m_Vector until //## reaching m_ClippingGeometry. //## @ingroup Data + +/** +* \deprecatedSince{2015_05} ExtrudedContour is deprecated. It will be removed in the next release. +* Becomes obsolete. Refer to http://docs.mitk.org/nightly/InteractionMigration.html . +*/ + class MITKSEGMENTATION_EXPORT ExtrudedContour : public BoundingObject { public: mitkClassMacro(ExtrudedContour, BoundingObject); itkFactorylessNewMacro(Self) itkCloneMacro(Self) virtual mitk::ScalarType GetVolume() override; virtual bool IsInside(const Point3D& p) const override; virtual void UpdateOutputInformation() override; //##Documentation //## @brief Contour to extrude itkGetConstObjectMacro(Contour, mitk::Contour); itkSetObjectMacro(Contour, mitk::Contour); //##Documentation //## @brief Vector to specify the direction of the extrusion mitkGetVectorMacro(Vector, mitk::Vector3D); mitkSetVectorMacro(Vector, mitk::Vector3D); itkGetConstMacro(AutomaticVectorGeneration, bool); itkSetMacro(AutomaticVectorGeneration, bool); itkBooleanMacro(AutomaticVectorGeneration); //##Documentation //## @brief Optional vector to specify the orientation of the bounding-box mitkGetVectorMacro(RightVector, mitk::Vector3D); mitkSetVectorMacro(RightVector, mitk::Vector3D); //##Documentation //## @brief Optional geometry for clipping the extruded contour itkGetConstObjectMacro(ClippingGeometry, mitk::BaseGeometry); itkSetObjectMacro(ClippingGeometry, mitk::BaseGeometry); virtual unsigned long GetMTime() const override; protected: ExtrudedContour(); virtual ~ExtrudedContour(); void BuildSurface(); void BuildGeometry(); mitk::Contour::Pointer m_Contour; mitk::Vector3D m_Vector; mitk::Vector3D m_RightVector; mitk::BaseGeometry::Pointer m_ClippingGeometry; bool m_AutomaticVectorGeneration; vtkPolygon* m_Polygon; #if ((VTK_MAJOR_VERSION > 4) || ((VTK_MAJOR_VERSION==4) && (VTK_MINOR_VERSION>=4) )) double m_ProjectedContourBounds[6]; #else float m_ProjectedContourBounds[6]; #endif mitk::PlaneGeometry::Pointer m_ProjectionPlane; //##Documentation //## @brief For fast projection on plane float m_Right[3]; float m_Down[3]; #if ((VTK_MAJOR_VERSION > 4) || ((VTK_MAJOR_VERSION==4) && (VTK_MINOR_VERSION>=4) )) double m_Normal[3]; #else float m_Normal[3]; #endif float m_Origin[3]; vtkLinearExtrusionFilter* m_ExtrusionFilter; vtkTriangleFilter *m_TriangleFilter; vtkDecimatePro* m_Decimate; vtkLinearSubdivisionFilter* m_SubdivisionFilter; vtkPlanes* m_ClippingBox; vtkClipPolyData* m_ClipPolyDataFilter; itk::TimeStamp m_LastCalculateExtrusionTime; }; } #endif /* MITKEXTRUDEDCONTOUR_H_HEADER_INCLUDED */ diff --git a/Modules/XNAT/CMakeLists.txt b/Modules/XNAT/CMakeLists.txt index 37c14d6c2b..ac2e07b0c1 100644 --- a/Modules/XNAT/CMakeLists.txt +++ b/Modules/XNAT/CMakeLists.txt @@ -1,5 +1,6 @@ MITK_CREATE_MODULE( + DEPENDS MitkCore MitkQtWidgets PACKAGE_DEPENDS PUBLIC CTK|CTKXNATCore - PRIVATE Qt4 Qt5|UiTools+XmlPatterns + PRIVATE Qt4|QtGui Qt5|UiTools+XmlPatterns+Widgets ) diff --git a/Modules/XNAT/files.cmake b/Modules/XNAT/files.cmake index 766d942c9e..e26d372495 100644 --- a/Modules/XNAT/files.cmake +++ b/Modules/XNAT/files.cmake @@ -1,9 +1,33 @@ 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 + QmitkXnatUploadFromDataStorageDialog.cpp ) set(MOC_H_FILES - include/mitkXnatSessionTracker.h + include/mitkXnatSessionTracker.h + include/QmitkXnatTreeModel.h + include/QmitkXnatProjectWidget.h + include/QmitkXnatSubjectWidget.h + include/QmitkXnatExperimentWidget.h + include/QmitkXnatCreateObjectDialog.h + include/QmitkXnatUploadFromDataStorageDialog.h +) + +set(QRC_FILES + resources/xnat.qrc +) + + +set(UI_FILES + src/QmitkXnatExperimentWidgetControls.ui + src/QmitkXnatProjectWidgetControls.ui + src/QmitkXnatSubjectWidgetControls.ui + src/QmitkXnatUploadFromDataStorageDialog.ui ) diff --git a/Modules/XNAT/include/QmitkXnatCreateObjectDialog.h b/Modules/XNAT/include/QmitkXnatCreateObjectDialog.h new file mode 100644 index 0000000000..4a7afe8f21 --- /dev/null +++ b/Modules/XNAT/include/QmitkXnatCreateObjectDialog.h @@ -0,0 +1,57 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef QMITKXNATCREATEOBJECTDIALOG_H +#define QMITKXNATCREATEOBJECTDIALOG_H + +#include + +// Qt +#include +#include + +class ctkXnatObject; + +class MITKXNAT_EXPORT QmitkXnatCreateObjectDialog : public QDialog +{ + Q_OBJECT + +public: + enum SpecificType + { + //PROJECT, + SUBJECT, + EXPERIMENT + }; + + QmitkXnatCreateObjectDialog(SpecificType type, QWidget* parent = 0); + virtual ~QmitkXnatCreateObjectDialog(); + + // Returns a specific xnat object like SpecificType + ctkXnatObject* GetXnatObject(); + + protected slots: + + void OnAcceptClicked(); + void OnCancelClicked(); + +private: + SpecificType m_Type; + ctkXnatObject* m_Object; + QWidget* m_Widget; +}; + +#endif // QMITKXNATCREATEOBJECTDIALOG_H diff --git a/Modules/XNAT/include/QmitkXnatExperimentWidget.h b/Modules/XNAT/include/QmitkXnatExperimentWidget.h new file mode 100644 index 0000000000..e0cc54f7f3 --- /dev/null +++ b/Modules/XNAT/include/QmitkXnatExperimentWidget.h @@ -0,0 +1,56 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological rmatics. +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 QMITKXNATEXPERIMENTWIDGET_H +#define QMITKXNATEXPERIMENTWIDGET_H + +// XNATUI +#include +#include + +// Qt +#include + +// CTK XNAT Core +class ctkXnatExperiment; + +class MITKXNAT_EXPORT QmitkXnatExperimentWidget : public QWidget +{ + Q_OBJECT + +public: + + enum Mode + { + INFO, + CREATE + }; + + QmitkXnatExperimentWidget(Mode mode, QWidget* parent = 0); + ~QmitkXnatExperimentWidget(); + + void SetExperiment(ctkXnatExperiment* experiment); + ctkXnatExperiment* GetExperiment() const; + +protected: + Ui::QmitkXnatExperimentWidgetControls m_Controls; + +private: + Mode m_Mode; + ctkXnatExperiment* m_Experiment; +}; + +#endif // QMITKXNATEXPERIMENTWIDGET_H diff --git a/Modules/XNAT/include/QmitkXnatProjectWidget.h b/Modules/XNAT/include/QmitkXnatProjectWidget.h new file mode 100644 index 0000000000..0dddc24f17 --- /dev/null +++ b/Modules/XNAT/include/QmitkXnatProjectWidget.h @@ -0,0 +1,56 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological rmatics. +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 QMITKXNATPROJECTWIDGET_H +#define QMITKXNATPROJECTWIDGET_H + +// XNATUI +#include +#include + +// Qt +#include + +// CTK XNAT Core +class ctkXnatProject; + +class MITKXNAT_EXPORT QmitkXnatProjectWidget : public QWidget +{ + Q_OBJECT + +public: + + enum Mode + { + INFO, + CREATE + }; + + QmitkXnatProjectWidget(Mode mode, QWidget* parent = 0); + ~QmitkXnatProjectWidget(); + + void SetProject(ctkXnatProject* project); + ctkXnatProject* GetProject() const; + +protected: + Ui::QmitkXnatProjectWidgetControls m_Controls; + +private: + Mode m_Mode; + ctkXnatProject* m_Project; +}; + +#endif // QMITKXNATPROJECTWIDGET_H diff --git a/Modules/XNAT/include/QmitkXnatSubjectWidget.h b/Modules/XNAT/include/QmitkXnatSubjectWidget.h new file mode 100644 index 0000000000..545319c015 --- /dev/null +++ b/Modules/XNAT/include/QmitkXnatSubjectWidget.h @@ -0,0 +1,55 @@ +/*=================================================================== + +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 QMITKXNATSUBJECTWIDGET_H +#define QMITKXNATSUBJECTWIDGET_H + +#include +#include + +// Qt +#include + +// CTK XNAT Core +class ctkXnatSubject; + +class MITKXNAT_EXPORT QmitkXnatSubjectWidget : public QWidget +{ + Q_OBJECT + +public: + + enum Mode + { + INFO, + CREATE + }; + + QmitkXnatSubjectWidget(Mode mode, QWidget* parent = 0); + ~QmitkXnatSubjectWidget(); + + void SetSubject(ctkXnatSubject* subject); + ctkXnatSubject* GetSubject() const; + +protected: + Ui::QmitkXnatSubjectWidgetControls m_Controls; + +private: + Mode m_Mode; + ctkXnatSubject* m_Subject; +}; + +#endif // QMITKXNATSUBJECTWIDGET_H diff --git a/Modules/XNAT/include/QmitkXnatTreeModel.h b/Modules/XNAT/include/QmitkXnatTreeModel.h new file mode 100644 index 0000000000..fc680f6e71 --- /dev/null +++ b/Modules/XNAT/include/QmitkXnatTreeModel.h @@ -0,0 +1,51 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef 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; + + signals: + void ResourceDropped(const QList&, ctkXnatObject*, const QModelIndex&); + +}; + +#endif // QMITKXNATTREEMODEL_H diff --git a/Modules/XNAT/include/QmitkXnatUploadFromDataStorageDialog.h b/Modules/XNAT/include/QmitkXnatUploadFromDataStorageDialog.h new file mode 100644 index 0000000000..819621543a --- /dev/null +++ b/Modules/XNAT/include/QmitkXnatUploadFromDataStorageDialog.h @@ -0,0 +1,46 @@ +#ifndef QMITKXNATUPLOADFROMDATASTORAGEDIALOG_H +#define QMITKXNATUPLOADFROMDATASTORAGEDIALOG_H + +#include + +#include + +namespace Ui { +class QmitkXnatUploadFromDataStorageDialog; +} + +namespace mitk { +class DataStorage; +} + +class 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/experiment.ico b/Modules/XNAT/resources/experiment.ico new file mode 100644 index 0000000000..c3fc5dc17f Binary files /dev/null and b/Modules/XNAT/resources/experiment.ico differ diff --git a/Modules/XNAT/resources/project.ico b/Modules/XNAT/resources/project.ico new file mode 100644 index 0000000000..9c265052c4 Binary files /dev/null and b/Modules/XNAT/resources/project.ico differ diff --git a/Modules/XNAT/resources/server.ico b/Modules/XNAT/resources/server.ico new file mode 100644 index 0000000000..cb161d7cb6 Binary files /dev/null and b/Modules/XNAT/resources/server.ico differ diff --git a/Modules/XNAT/resources/subject.ico b/Modules/XNAT/resources/subject.ico new file mode 100644 index 0000000000..f42b26c240 Binary files /dev/null and b/Modules/XNAT/resources/subject.ico differ diff --git a/Modules/XNAT/resources/xnat.qrc b/Modules/XNAT/resources/xnat.qrc new file mode 100644 index 0000000000..7d6e5f8ecf --- /dev/null +++ b/Modules/XNAT/resources/xnat.qrc @@ -0,0 +1,8 @@ + + + server.ico + project.ico + subject.ico + experiment.ico + + diff --git a/Modules/XNAT/src/QmitkXnatCreateObjectDialog.cpp b/Modules/XNAT/src/QmitkXnatCreateObjectDialog.cpp new file mode 100644 index 0000000000..3eebfd0f7d --- /dev/null +++ b/Modules/XNAT/src/QmitkXnatCreateObjectDialog.cpp @@ -0,0 +1,169 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological rmatics. +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 "QmitkXnatCreateObjectDialog.h" + +// XNAT +#include +#include +#include + +// CTK XNAT Core +//#include +#include +#include + +// Qt +#include +#include +#include + +// Testing +#include +#include + +QmitkXnatCreateObjectDialog::QmitkXnatCreateObjectDialog(SpecificType type, QWidget* parent) + : QDialog(parent) + , m_Type(type) +{ + switch (m_Type) + { + //case PROJECT: + // m_Object = new ctkXnatProject(); + // m_Widget = new QmitkXnatProjectWidget(dynamic_cast(m_Object)); + // break; + case SUBJECT: + m_Object = new ctkXnatSubject(); + m_Widget = new QmitkXnatSubjectWidget(QmitkXnatSubjectWidget::Mode::CREATE, parent); + dynamic_cast(m_Widget)->SetSubject(dynamic_cast(m_Object)); + break; + case EXPERIMENT: + m_Object = new ctkXnatExperiment(); + m_Widget = new QmitkXnatExperimentWidget(QmitkXnatExperimentWidget::Mode::CREATE, parent); + dynamic_cast(m_Widget)->SetExperiment(dynamic_cast(m_Object)); + break; + default: + break; + } + + QList children = m_Widget->findChildren(); + foreach(QLineEdit* child, children) + { + child->setReadOnly(false); + } + + QGridLayout* grid = dynamic_cast(m_Widget->layout()); + + QPushButton* btnOk = new QPushButton("Create"); + QPushButton* btnCancel = new QPushButton("Cancel"); + + QHBoxLayout* hLayout = new QHBoxLayout(); + hLayout->addWidget(btnOk); + hLayout->addWidget(btnCancel); + + connect(btnOk, SIGNAL(clicked()), this, SLOT(OnAcceptClicked())); + connect(btnCancel, SIGNAL(clicked()), this, SLOT(OnCancelClicked())); + + grid->addLayout(hLayout, grid->rowCount() + 1, 1); + + // Fill the dialog + setLayout(grid); +} + +QmitkXnatCreateObjectDialog::~QmitkXnatCreateObjectDialog() +{ + delete m_Widget; +} + +ctkXnatObject* QmitkXnatCreateObjectDialog::GetXnatObject() +{ + return m_Object; +} + +void QmitkXnatCreateObjectDialog::OnAcceptClicked() +{ + //ctkXnatProject* project; + ctkXnatSubject* subject; + ctkXnatExperiment* experiment; + + switch (m_Type) + { + //case PROJECT: + // project = dynamic_cast(m_Widget)->GetProject(); + + // // Check mandatory field + // if (project->property("label").isEmpty()) + // { + // QMessageBox msgBox; + // msgBox.setIcon(QMessageBox::Warning); + // msgBox.setText("Please fill in an ID to create a new project!"); + // msgBox.exec(); + // return; + // } + + // m_Object = project; + // break; + + case SUBJECT: + subject = dynamic_cast(m_Widget)->GetSubject(); + + // Check mandatory field + if (subject->property("label").isEmpty()) + { + QMessageBox msgBox; + msgBox.setIcon(QMessageBox::Warning); + msgBox.setText("Please fill in an ID to create a new subject!"); + msgBox.exec(); + return; + } + + m_Object = subject; + break; + + case EXPERIMENT: + experiment = dynamic_cast(m_Widget)->GetExperiment(); + + // Check mandatory field + if (experiment->property("label").isEmpty()) + { + QMessageBox msgBox; + msgBox.setIcon(QMessageBox::Warning); + msgBox.setText("Please fill in an ID to create a new experiment!"); + msgBox.exec(); + return; + } + else if (experiment->property("xsiType").isEmpty()) + { + QMessageBox msgBox; + msgBox.setIcon(QMessageBox::Warning); + msgBox.setText("Please fill in an XSI Type to create a new experiment!"); + msgBox.exec(); + return; + } + + m_Object = experiment; + break; + + default: + break; + } + accept(); +} + +void QmitkXnatCreateObjectDialog::OnCancelClicked() +{ + reject(); +} diff --git a/Modules/XNAT/src/QmitkXnatExperimentWidget.cpp b/Modules/XNAT/src/QmitkXnatExperimentWidget.cpp new file mode 100644 index 0000000000..60f097e414 --- /dev/null +++ b/Modules/XNAT/src/QmitkXnatExperimentWidget.cpp @@ -0,0 +1,127 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological rmatics. +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 "QmitkXnatExperimentWidget.h" + +#include + +#include + +QmitkXnatExperimentWidget::QmitkXnatExperimentWidget(Mode mode, QWidget* parent) + : QWidget(parent) + , m_Mode(mode) +{ + // Create GUI widgets from the Qt Designer's .ui file + m_Controls.setupUi(this); + + if (m_Mode == Mode::INFO) + { + // make not needed row invisible + m_Controls.labelLabel->setText("ID:"); + m_Controls.mandatoryLabel->setVisible(false); + } + if (m_Mode == Mode::CREATE) + { + // change modality to xsiType + m_Controls.modalityLabel->setText("XSI Type*:"); + + // create list of all experiment session types + QStringList xsiTypeList; + xsiTypeList << ctkXnatDefaultSchemaTypes::XSI_CR_SESSION; + xsiTypeList << ctkXnatDefaultSchemaTypes::XSI_CT_SESSION; + xsiTypeList << ctkXnatDefaultSchemaTypes::XSI_DX_SESSION; + xsiTypeList << ctkXnatDefaultSchemaTypes::XSI_DX3DCRANIOFACIAL_SESSION; + xsiTypeList << ctkXnatDefaultSchemaTypes::XSI_ECG_SESSION; + xsiTypeList << ctkXnatDefaultSchemaTypes::XSI_EEG_SESSION; + xsiTypeList << ctkXnatDefaultSchemaTypes::XSI_EPS_SESSION; + xsiTypeList << ctkXnatDefaultSchemaTypes::XSI_ES_SESSION; + xsiTypeList << ctkXnatDefaultSchemaTypes::XSI_ESV_SESSION; + xsiTypeList << ctkXnatDefaultSchemaTypes::XSI_GM_SESSION; + xsiTypeList << ctkXnatDefaultSchemaTypes::XSI_GMV_SESSION; + xsiTypeList << ctkXnatDefaultSchemaTypes::XSI_HD_SESSION; + xsiTypeList << ctkXnatDefaultSchemaTypes::XSI_IO_SESSION; + xsiTypeList << ctkXnatDefaultSchemaTypes::XSI_MEG_SESSION; + xsiTypeList << ctkXnatDefaultSchemaTypes::XSI_MG_SESSION; + xsiTypeList << ctkXnatDefaultSchemaTypes::XSI_MR_SESSION; + xsiTypeList << ctkXnatDefaultSchemaTypes::XSI_OP_SESSION; + xsiTypeList << ctkXnatDefaultSchemaTypes::XSI_OPT_SESSION; + xsiTypeList << ctkXnatDefaultSchemaTypes::XSI_OTHER_DICOM_SESSION; + xsiTypeList << ctkXnatDefaultSchemaTypes::XSI_PET_SESSION; + xsiTypeList << ctkXnatDefaultSchemaTypes::XSI_RF_SESSION; + xsiTypeList << ctkXnatDefaultSchemaTypes::XSI_RT_SESSION; + xsiTypeList << ctkXnatDefaultSchemaTypes::XSI_SM_SESSION; + xsiTypeList << ctkXnatDefaultSchemaTypes::XSI_US_SESSION; + xsiTypeList << ctkXnatDefaultSchemaTypes::XSI_XA_SESSION; + xsiTypeList << ctkXnatDefaultSchemaTypes::XSI_XA3D_SESSION; + xsiTypeList << ctkXnatDefaultSchemaTypes::XSI_XC_SESSION; + xsiTypeList << ctkXnatDefaultSchemaTypes::XSI_XCV_SESSION; + + // create completer for experiment sessions + QCompleter* completer = new QCompleter(xsiTypeList, this); + m_Controls.modalityLineEdit->setCompleter(completer); + m_Controls.modalityLineEdit->setPlaceholderText("xnat::"); + } +} + +QmitkXnatExperimentWidget::~QmitkXnatExperimentWidget() +{ +} + +void QmitkXnatExperimentWidget::SetExperiment(ctkXnatExperiment* experiment) +{ + m_Experiment = experiment; + + // Set the UI labels + if (m_Experiment->parent()) + { + m_Controls.breadcrumbLabel->setText("Project:" + m_Experiment->parent()->parent()->property("name") + + " > Subject:" + m_Experiment->parent()->property("label")); + } + m_Controls.labelLineEdit->setText(m_Experiment->property("label")); + m_Controls.modalityLineEdit->setText(m_Experiment->property("modality")); + m_Controls.dateLineEdit->setText(m_Experiment->property("date")); + m_Controls.timeLineEdit->setText(m_Experiment->property("time")); + m_Controls.scannerLineEdit->setText(m_Experiment->property("scanner")); +} + +ctkXnatExperiment* QmitkXnatExperimentWidget::GetExperiment() const +{ + if (m_Mode == Mode::CREATE) + { + if (!m_Controls.labelLineEdit->text().isEmpty()) + { + m_Experiment->setProperty("label", m_Controls.labelLineEdit->text()); + } + if (!m_Controls.modalityLineEdit->text().isEmpty()) + { + m_Experiment->setProperty("xsiType", m_Controls.modalityLineEdit->text()); + } + if (!m_Controls.dateLineEdit->text().isEmpty()) + { + m_Experiment->setProperty("date", m_Controls.dateLineEdit->text()); + } + if (!m_Controls.timeLineEdit->text().isEmpty()) + { + m_Experiment->setProperty("time", m_Controls.dateLineEdit->text()); + } + if (!m_Controls.scannerLineEdit->text().isEmpty()) + { + m_Experiment->setProperty("scanner", m_Controls.scannerLineEdit->text()); + } + } + + return m_Experiment; +} diff --git a/Modules/XNAT/src/QmitkXnatExperimentWidgetControls.ui b/Modules/XNAT/src/QmitkXnatExperimentWidgetControls.ui new file mode 100644 index 0000000000..2b6eacd5d6 --- /dev/null +++ b/Modules/XNAT/src/QmitkXnatExperimentWidgetControls.ui @@ -0,0 +1,136 @@ + + + QmitkXnatExperimentWidgetControls + + + true + + + + 0 + 0 + 350 + 225 + + + + Qmitk Template + + + + + + Time: + + + + + + + Date: + + + + + + + Scanner: + + + + + + + + 75 + false + true + + + + Experiment Information + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + Modality: + + + + + + + + true + + + + + + + + + + + ID*: + + + + + + + * mandatory field + + + + + + + true + + + + + + + true + + + YYYY-MM-DD + + + + + + + true + + + hh:mm:ss + + + + + + + true + + + + + + + true + + + + + + + + diff --git a/Modules/XNAT/src/QmitkXnatProjectWidget.cpp b/Modules/XNAT/src/QmitkXnatProjectWidget.cpp new file mode 100644 index 0000000000..3c564608bc --- /dev/null +++ b/Modules/XNAT/src/QmitkXnatProjectWidget.cpp @@ -0,0 +1,73 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological rmatics. +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 "QmitkXnatProjectWidget.h" + +#include + +QmitkXnatProjectWidget::QmitkXnatProjectWidget(Mode mode, QWidget* parent) + : m_Mode(mode) + , QWidget(parent) +{ + // Create GUI widgets from the Qt Designer's .ui file + m_Controls.setupUi(this); + + if (m_Mode == Mode::INFO) + { + // make not needed row invisible + m_Controls.idLabel->setVisible(false); + m_Controls.idLineEdit->setVisible(false); + m_Controls.mandatoryLabel->setVisible(false); + } +} + +QmitkXnatProjectWidget::~QmitkXnatProjectWidget() +{ +} + +void QmitkXnatProjectWidget::SetProject(ctkXnatProject* project) +{ + m_Project = project; + + // Set the UI labels + m_Controls.nameLineEdit->setText(m_Project->property("name")); + m_Controls.descriptionLineEdit->setText(m_Project->property("description")); + if (!m_Project->property("pi_lastname").isEmpty()) + { + m_Controls.piLineEdit->setText(m_Project->property("pi_lastname") + ", " + m_Project->property("pi_firstname")); + } +} + +ctkXnatProject* QmitkXnatProjectWidget::GetProject() const +{ + if (m_Mode == Mode::CREATE) + { + if (!m_Controls.idLineEdit->text().isEmpty()) + { + m_Project->setProperty("ID", m_Controls.idLineEdit->text()); + } + if (!m_Controls.nameLineEdit->text().isEmpty()) + { + m_Project->setProperty("name", m_Controls.nameLineEdit->text()); + } + if (!m_Controls.descriptionLineEdit->text().isEmpty()) + { + m_Project->setProperty("description", m_Controls.descriptionLineEdit->text()); + } + // pi name needs to be inserted separated + } + return m_Project; +} diff --git a/Modules/XNAT/src/QmitkXnatProjectWidgetControls.ui b/Modules/XNAT/src/QmitkXnatProjectWidgetControls.ui new file mode 100644 index 0000000000..dbdbe09c2e --- /dev/null +++ b/Modules/XNAT/src/QmitkXnatProjectWidgetControls.ui @@ -0,0 +1,103 @@ + + + QmitkXnatProjectWidgetControls + + + true + + + + 0 + 0 + 350 + 154 + + + + Qmitk Template + + + + + + Description: + + + + + + + Name: + + + + + + + PI: + + + + + + + + 75 + true + + + + Project Information + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + true + + + + + + + true + + + + + + + ID*: + + + + + + + true + + + + + + + true + + + + + + + * mandatory field + + + + + + + + diff --git a/Modules/XNAT/src/QmitkXnatSubjectWidget.cpp b/Modules/XNAT/src/QmitkXnatSubjectWidget.cpp new file mode 100644 index 0000000000..136372f6f8 --- /dev/null +++ b/Modules/XNAT/src/QmitkXnatSubjectWidget.cpp @@ -0,0 +1,89 @@ +/*=================================================================== + +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 "QmitkXnatSubjectWidget.h" + +#include +#include + +QmitkXnatSubjectWidget::QmitkXnatSubjectWidget(Mode mode, QWidget* parent) + : m_Mode(mode) + , QWidget(parent) +{ + // Create GUI widgets from the Qt Designer's .ui file + m_Controls.setupUi(this); + + if (m_Mode == Mode::INFO) + { + // make not needed row invisible + m_Controls.labelLabel->setText("ID:"); + m_Controls.mandatoryLabel->setVisible(false); + } +} + +QmitkXnatSubjectWidget::~QmitkXnatSubjectWidget() +{ +} + +void QmitkXnatSubjectWidget::SetSubject(ctkXnatSubject* subject) +{ + m_Subject = subject; + + // Set the UI labels + if (m_Subject->parent()) + { + m_Controls.breadcrumbLabel->setText("Project:" + m_Subject->parent()->property("name")); + } + m_Controls.labelLineEdit->setText(m_Subject->property("label")); + m_Controls.birthdateLineEdit->setText(m_Subject->property("dob")); + m_Controls.genderLineEdit->setText(m_Subject->property("gender")); + m_Controls.handednessLineEdit->setText(m_Subject->property("handedness")); + m_Controls.heightLineEdit->setText(m_Subject->property("height")); + m_Controls.weightLineEdit->setText(m_Subject->property("weight")); +} + +ctkXnatSubject* QmitkXnatSubjectWidget::GetSubject() const +{ + if (m_Mode == CREATE) + { + if (!m_Controls.labelLineEdit->text().isEmpty()) + { + m_Subject->setProperty("label", m_Controls.labelLineEdit->text()); + } + if (!m_Controls.birthdateLineEdit->text().isEmpty()) + { + m_Subject->setProperty("dob", m_Controls.birthdateLineEdit->text()); + } + if (!m_Controls.genderLineEdit->text().isEmpty()) + { + m_Subject->setProperty("gender", m_Controls.genderLineEdit->text()); + } + if (!m_Controls.handednessLineEdit->text().isEmpty()) + { + m_Subject->setProperty("handedness", m_Controls.handednessLineEdit->text()); + } + if (!m_Controls.heightLineEdit->text().isEmpty()) + { + m_Subject->setProperty("height", m_Controls.heightLineEdit->text()); + } + if (!m_Controls.weightLineEdit->text().isEmpty()) + { + m_Subject->setProperty("weight", m_Controls.weightLineEdit->text()); + } + } + + return m_Subject; +} diff --git a/Modules/XNAT/src/QmitkXnatSubjectWidgetControls.ui b/Modules/XNAT/src/QmitkXnatSubjectWidgetControls.ui new file mode 100644 index 0000000000..49b17fb364 --- /dev/null +++ b/Modules/XNAT/src/QmitkXnatSubjectWidgetControls.ui @@ -0,0 +1,146 @@ + + + QmitkXnatSubjectWidgetControls + + + true + + + + 0 + 0 + 350 + 225 + + + + Qmitk Template + + + + + + true + + + + + + + Gender: + + + + + + + Birthdate: + + + + + + + Handedness: + + + + + + + Height (inches): + + + + + + + Weight (lbs) + + + + + + + + 75 + true + + + + Subject Information + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + true + + + + + + + + + + + true + + + YYYY-MM-DD + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + ID*: + + + + + + + * mandatory field + + + + + + + + diff --git a/Modules/XNAT/src/QmitkXnatTreeModel.cpp b/Modules/XNAT/src/QmitkXnatTreeModel.cpp new file mode 100644 index 0000000000..1c22560a11 --- /dev/null +++ b/Modules/XNAT/src/QmitkXnatTreeModel.cpp @@ -0,0 +1,116 @@ +/*=================================================================== + +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 + +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"; + } + else if(dynamic_cast(xnatObject)) + { + path = ":/xnat/subject.ico"; + } + else if(dynamic_cast(xnatObject)) + { + path = ":/xnat/experiment.ico"; + } + 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; +} diff --git a/Modules/XNAT/src/QmitkXnatUploadFromDataStorageDialog.cpp b/Modules/XNAT/src/QmitkXnatUploadFromDataStorageDialog.cpp new file mode 100644 index 0000000000..989dbfcb47 --- /dev/null +++ b/Modules/XNAT/src/QmitkXnatUploadFromDataStorageDialog.cpp @@ -0,0 +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); +} + +void QmitkXnatUploadFromDataStorageDialog::OnUploadSceneChecked() +{ +} + +void QmitkXnatUploadFromDataStorageDialog::OnCancel() +{ + this->done(CANCEL); +} + +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/Modules/XNAT/src/QmitkXnatUploadFromDataStorageDialog.ui b/Modules/XNAT/src/QmitkXnatUploadFromDataStorageDialog.ui new file mode 100644 index 0000000000..d28dc01caa --- /dev/null +++ b/Modules/XNAT/src/QmitkXnatUploadFromDataStorageDialog.ui @@ -0,0 +1,89 @@ + + + QmitkXnatUploadFromDataStorageDialog + + + + 0 + 0 + 400 + 164 + + + + Dialog + + + + + + Select the data for upload: + + + + + + + + + + Uploads all data as MITK project file + + + Upload scene as MITK project file + + + + + + + Enter project file name + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Cancel + + + + + + + false + + + Upload + + + + + + + + + + QmitkDataStorageComboBox + QComboBox +
QmitkDataStorageComboBox.h
+
+
+ + +
diff --git a/Plugins/org.mitk.gui.qt.xnat/files.cmake b/Plugins/org.mitk.gui.qt.xnat/files.cmake index 0a26dcea91..f0a27c0ce6 100644 --- a/Plugins/org.mitk.gui.qt.xnat/files.cmake +++ b/Plugins/org.mitk.gui.qt.xnat/files.cmake @@ -1,46 +1,47 @@ set(SRC_CPP_FILES ) set(INTERNAL_CPP_FILES org_mitk_gui_qt_xnatinterface_Activator.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/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 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/resources/xnat-download.png b/Plugins/org.mitk.gui.qt.xnat/resources/xnat-download.png new file mode 100644 index 0000000000..cdc6b22a4d Binary files /dev/null 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 new file mode 100644 index 0000000000..2adc69f865 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.xnat/resources/xnat-folder.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 new file mode 100644 index 0000000000..54c8236f9e Binary files /dev/null and b/Plugins/org.mitk.gui.qt.xnat/resources/xnat-upload.png differ diff --git a/Plugins/org.mitk.gui.qt.xnat/resources/xnat.qrc b/Plugins/org.mitk.gui.qt.xnat/resources/xnat.qrc new file mode 100644 index 0000000000..c0e23b477a --- /dev/null +++ b/Plugins/org.mitk.gui.qt.xnat/resources/xnat.qrc @@ -0,0 +1,7 @@ + + + xnat-download.png + xnat-upload.png + xnat-folder.png + + 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 e53676181a..eef0543255 100644 --- a/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatConnectionPreferencePage.cpp +++ b/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatConnectionPreferencePage.cpp @@ -1,280 +1,277 @@ /*=================================================================== 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 "org_mitk_gui_qt_xnatinterface_Activator.h" #include "berryIPreferencesService.h" #include "berryPlatform.h" #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::Init(berry::IWorkbench::Pointer) { - } void QmitkXnatConnectionPreferencePage::CreateQtControl(QWidget* parent) { IPreferencesService* prefService = Platform::GetPreferencesService(); berry::IPreferences::Pointer _XnatConnectionPreferencesNode = prefService->GetSystemPreferences()->Node("/XnatConnection"); 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) + catch (std::invalid_argument) { session = 0; } - if(session != 0) + if (session != 0) { - if(session->isOpen()) + if (session->isOpen()) { m_Controls.testConnectionButton->setText("Disconnect"); } else { m_Controls.testConnectionButton->setText("Connect"); } } const QIntValidator *portV = new QIntValidator(0, 65535, parent); m_Controls.inPort->setValidator(portV); const QRegExp hostRx("^(https?)://[^ /](\\S)+$"); const QRegExpValidator *hostV = new QRegExpValidator(hostRx, parent); m_Controls.inHostAddress->setValidator(hostV); - connect( m_Controls.testConnectionButton, SIGNAL(clicked()), this, SLOT(ToggleConnection()) ); + connect(m_Controls.testConnectionButton, SIGNAL(clicked()), this, SLOT(ToggleConnection())); connect(m_Controls.inHostAddress, SIGNAL(editingFinished()), this, SLOT(UrlChanged())); connect(m_Controls.inDownloadPath, SIGNAL(editingFinished()), this, SLOT(DownloadPathChanged())); this->Update(); } QWidget* QmitkXnatConnectionPreferencePage::GetQtControl() const { return m_Control; } bool QmitkXnatConnectionPreferencePage::PerformOk() { - if(!UserInformationEmpty()) + if (!UserInformationEmpty()) { IPreferences::Pointer _XnatConnectionPreferencesNode = m_XnatConnectionPreferencesNode.Lock(); - if(_XnatConnectionPreferencesNode.IsNotNull()) + 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->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.inHostAddress->text().isEmpty()) { errString += "Server Address is empty.\n"; } - if(m_Controls.inUsername->text().isEmpty()) + if (m_Controls.inUsername->text().isEmpty()) { errString += "Username is empty.\n"; } - if(m_Controls.inPassword->text().isEmpty()) + if (m_Controls.inPassword->text().isEmpty()) { errString += "Password is empty.\n"; } // if something is empty - if(!errString.isEmpty()) + if (!errString.isEmpty()) { m_Controls.testConnectionLabel->setStyleSheet("QLabel { color: red; }"); m_Controls.testConnectionLabel->setText("Connecting failed.\n" + errString); return true; } else { return false; } } void QmitkXnatConnectionPreferencePage::Update() { IPreferences::Pointer _XnatConnectionPreferencesNode = m_XnatConnectionPreferencesNode.Lock(); - if(_XnatConnectionPreferencesNode.IsNotNull()) + 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())); } } void QmitkXnatConnectionPreferencePage::UrlChanged() { m_Controls.inHostAddress->setStyleSheet("QLineEdit { background-color: white; }"); QString str = m_Controls.inHostAddress->text(); - while(str.endsWith("/")) + while (str.endsWith("/")) { - str = str.left(str.length()-1); + str = str.left(str.length() - 1); } m_Controls.inHostAddress->setText(str); QUrl url(m_Controls.inHostAddress->text()); - if(!url.isValid()) + if (!url.isValid()) { m_Controls.inHostAddress->setStyleSheet("QLineEdit { background-color: red; }"); } } void QmitkXnatConnectionPreferencePage::DownloadPathChanged() { m_Controls.inDownloadPath->setStyleSheet("QLineEdit { background-color: white; }"); QString downloadPath = m_Controls.inDownloadPath->text(); - if(!downloadPath.isEmpty()) + if (!downloadPath.isEmpty()) { - if (downloadPath.lastIndexOf("/") != downloadPath.size()-1) + if (downloadPath.lastIndexOf("/") != downloadPath.size() - 1) { downloadPath.append("/"); m_Controls.inDownloadPath->setText(downloadPath); } QFileInfo path(m_Controls.inDownloadPath->text()); - if(!path.isDir()) + if (!path.isDir()) { m_Controls.inDownloadPath->setStyleSheet("QLineEdit { background-color: red; }"); } } } 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) + catch (std::invalid_argument) { - if(!UserInformationEmpty()) + 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()) + if (session != 0 && session->isOpen()) { mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatSessionManager()->CloseXnatSession(); m_Controls.testConnectionButton->setText("Connect"); m_Controls.testConnectionLabel->clear(); } - else if(session != 0 && !session->isOpen()) + else if (session != 0 && !session->isOpen()) { m_Controls.testConnectionButton->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."); } - catch(const ctkXnatAuthenticationException& auth) + catch (const ctkXnatAuthenticationException& auth) { m_Controls.testConnectionLabel->setStyleSheet("QLabel { color: red; }"); m_Controls.testConnectionLabel->setText("Connecting failed:\nAuthentication error."); MITK_INFO << auth.message().toStdString(); mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatSessionManager()->CloseXnatSession(); } - catch(const ctkException& e) + catch (const ctkException& e) { m_Controls.testConnectionLabel->setStyleSheet("QLabel { color: red; }"); m_Controls.testConnectionLabel->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); } } diff --git a/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatEditor.cpp b/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatEditor.cpp index 68fb2bd7e5..146673de9c 100644 --- a/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatEditor.cpp +++ b/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatEditor.cpp @@ -1,565 +1,573 @@ /*=================================================================== 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 "QmitkXnatEditor.h" // Qmitk #include "QmitkXnatObjectEditorInput.h" #include "org_mitk_gui_qt_xnatinterface_Activator.h" // CTK XNAT Core #include "ctkXnatObject.h" #include "ctkXnatDataModel.h" #include "ctkXnatFile.h" #include "ctkXnatResource.h" #include "ctkXnatScan.h" #include "ctkXnatScanFolder.h" #include "ctkXnatAssessor.h" #include "ctkXnatAssessorFolder.h" #include "ctkXnatReconstruction.h" #include "ctkXnatReconstructionFolder.h" // CTK XNAT Widgets #include "ctkXnatListModel.h" // Blueberry #include #include #include // Qt #include #include #include #include #include #include // MITK #include #include // Poco #include const QString QmitkXnatEditor::EDITOR_ID = "org.mitk.editors.xnat.browser"; QmitkXnatEditor::QmitkXnatEditor() : m_DownloadPath(berry::Platform::GetPreferencesService()-> GetSystemPreferences()->Node("/XnatConnection")->Get("Download Path", "")), m_ListModel(new ctkXnatListModel()), m_Session(0), m_DataStorageServiceTracker(mitk::org_mitk_gui_qt_xnatinterface_Activator::GetContext()), m_SelectionListener(new berry::SelectionChangedAdapter(this, &QmitkXnatEditor::SelectionChanged)) { m_DataStorageServiceTracker.open(); 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() + "/"; } } QmitkXnatEditor::~QmitkXnatEditor() { delete m_ListModel; berry::ISelectionService* s = GetSite()->GetWorkbenchWindow()->GetSelectionService(); s->RemoveSelectionListener(m_SelectionListener.data()); m_DataStorageServiceTracker.close(); } bool QmitkXnatEditor::IsDirty() const { return false; } bool QmitkXnatEditor::IsSaveAsAllowed() const { return false; } void QmitkXnatEditor::Init(berry::IEditorSite::Pointer site, berry::IEditorInput::Pointer input) { this->SetSite(site); berry::QtEditorPart::SetInput(input); this->SetInput(input); } void QmitkXnatEditor::DoSave() { } void QmitkXnatEditor::DoSaveAs() { } void QmitkXnatEditor::SetInput(berry::IEditorInput::Pointer input) { QmitkXnatObjectEditorInput::Pointer oPtr = input.Cast(); if (oPtr.IsNotNull()) { berry::QtEditorPart::SetInput(oPtr); this->GetEditorInput().Cast()->GetXnatObject()->fetch(); } } void QmitkXnatEditor::SetFocus() { } void QmitkXnatEditor::CreateQtPartControl(QWidget *parent) { // create GUI widgets from the Qt Designer's .ui file m_Controls.setupUi(parent); m_Controls.buttonDownload->setEnabled(false); m_Controls.labelDownload->setText("Select a xnat file, resource, scan, or scan folder to download..."); GetSite()->GetWorkbenchWindow()->GetSelectionService()->AddSelectionListener(m_SelectionListener.data()); connect(m_Controls.treeView, SIGNAL(activated(const QModelIndex&)), this, SLOT(OnObjectActivated(const QModelIndex&))); connect(m_Controls.buttonDownload, SIGNAL(clicked()), this, SLOT(DownloadResource())); connect(m_Controls.buttonDataModel, SIGNAL(clicked()), this, SLOT(OnDataModelButtonClicked())); connect(m_Controls.buttonProject, SIGNAL(clicked()), this, SLOT(OnProjectButtonClicked())); connect(m_Controls.buttonSubject, SIGNAL(clicked()), this, SLOT(OnSubjectButtonClicked())); connect(m_Controls.buttonExperiment, SIGNAL(clicked()), this, SLOT(OnExperimentButtonClicked())); connect(m_Controls.buttonKindOfData, SIGNAL(clicked()), this, SLOT(OnKindOfDataButtonClicked())); connect(m_Controls.buttonSession, SIGNAL(clicked()), this, SLOT(OnSessionButtonClicked())); connect(m_Controls.buttonResource, SIGNAL(clicked()), this, SLOT(OnResourceButtonClicked())); connect(m_Controls.treeView, SIGNAL(clicked(const QModelIndex&)), SLOT(itemSelected(const QModelIndex&))); m_Tracker = new mitk::XnatSessionTracker(mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatModuleContext()); connect(m_Tracker, SIGNAL(AboutToBeClosed(ctkXnatSession*)), this, SLOT(CleanListModel(ctkXnatSession*))); connect(m_Tracker, SIGNAL(Opened(ctkXnatSession*)), this, SLOT(UpdateSession(ctkXnatSession*))); m_Tracker->Open(); // Makes the breadcrumb feature invisible for (int i = 0; i < m_Controls.breadcrumbHorizontalLayout->count() - 1; i++) { QLayoutItem* child = m_Controls.breadcrumbHorizontalLayout->itemAt(i); child->widget()->setVisible(false); } for (int i = 0; i < m_Controls.breadcrumbDescriptionLayout->count() - 1; i++) { QLayoutItem* child = m_Controls.breadcrumbDescriptionLayout->itemAt(i); child->widget()->setVisible(false); } QmitkXnatObjectEditorInput::Pointer oPtr = GetEditorInput().Cast(); if (oPtr.IsNotNull()) { UpdateList(); } else { 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; } UpdateSession(session); } } void QmitkXnatEditor::UpdateList() { QmitkXnatObjectEditorInput::Pointer xoPtr(GetEditorInput().Cast()); if (xoPtr.IsNull()) return; ctkXnatObject* inputObject = xoPtr->GetXnatObject(); if (inputObject == NULL) return; m_Controls.treeView->setModel(m_ListModel); m_ListModel->setRootObject(inputObject); m_Controls.treeView->reset(); // recursive method to check parents of the inputObject m_ParentCount = ParentChecker(inputObject); // breadcrumb labels for (int i = 0; i < m_Controls.breadcrumbHorizontalLayout->count() - 1; i++) { QLayoutItem* child = m_Controls.breadcrumbHorizontalLayout->itemAt(i); child->widget()->setVisible(false); } for (int i = 0; i < m_Controls.breadcrumbDescriptionLayout->count() - 1; i++) { QLayoutItem* child = m_Controls.breadcrumbDescriptionLayout->itemAt(i); child->widget()->setVisible(false); } ctkXnatObject* parent = NULL; for (int i = m_ParentCount * 2; i >= 0; i--) { if (i > 12) break; m_Controls.breadcrumbDescriptionLayout->itemAt(i)->widget()->setVisible(true); QLayoutItem* child = m_Controls.breadcrumbHorizontalLayout->itemAt(i); child->widget()->setVisible(true); if (i > 0) { m_Controls.breadcrumbHorizontalLayout->itemAt(i - 1)->widget()->setVisible(true); m_Controls.breadcrumbDescriptionLayout->itemAt(i - 1)->widget()->setVisible(true); } if (parent == NULL) { parent = inputObject; } // create breadcrumb button QPushButton* breadcrumbButton = dynamic_cast(child->widget()); breadcrumbButton->setText(parent->id()); parent = parent->parent(); i--; } m_Controls.buttonDataModel->setText("root"); m_Controls.buttonDownload->setEnabled(false); m_Controls.labelDownload->setVisible(true); } void QmitkXnatEditor::SelectionChanged(const berry::IWorkbenchPart::Pointer& sourcepart, const berry::ISelection::ConstPointer& selection) { // check for null selection if (selection.IsNull()) { return; } // exclude own selection events and check whether this kind of selection can be handled if (sourcepart != this && selection.Cast()) { berry::IStructuredSelection::ConstPointer currentSelection = selection.Cast(); // iterates over the selection for (berry::IStructuredSelection::iterator itr = currentSelection->Begin(); itr != currentSelection->End(); ++itr) { if (berry::SmartPointer objectPointer = itr->Cast()) { // get object of selected ListWidgetElement ctkXnatObject* object = objectPointer->GetQModelIndex().data(Qt::UserRole).value(); // if a file is selected, don't change the input and list view if (dynamic_cast(object) == NULL) { QmitkXnatObjectEditorInput::Pointer oPtr(new QmitkXnatObjectEditorInput(object)); berry::IEditorInput::Pointer editorInput(oPtr); if (!(editorInput == this->GetEditorInput())) this->SetInput(editorInput); UpdateList(); } } } } } void QmitkXnatEditor::DownloadResource() { - if (!m_Controls.treeView->selectionModel()->hasSelection()) + if (!m_Controls.listView->selectionModel()->hasSelection()) return; - const QModelIndex index = m_Controls.treeView->selectionModel()->currentIndex(); + const QModelIndex index = m_Controls.listView->selectionModel()->currentIndex(); QVariant variant = m_ListModel->data(index, Qt::UserRole); if (variant.isValid()) { ctkXnatObject* resource = variant.value(); if (dynamic_cast(resource) == NULL) { MITK_INFO << "Download started ..."; MITK_INFO << "..."; QString resourceName = m_ListModel->data(index, Qt::DisplayRole).toString(); QString resourcePath = m_DownloadPath + resourceName + ".zip"; resource->download(resourcePath); // Testing if the path exists QDir downDir(m_DownloadPath); if (downDir.exists(resourceName + ".zip")) { MITK_INFO << "Download of " << resourceName.toStdString() << ".zip was completed!"; } else { MITK_INFO << "Download of " << resourceName.toStdString() << ".zip failed!"; } } else { InternalFileDownload(index); } } } +void QmitkXnatEditor::DownloadFile() +{ + if (!m_Controls.listView->selectionModel()->hasSelection()) + return; + const QModelIndex index = m_Controls.listView->selectionModel()->currentIndex(); + InternalFileDownload(index); +} + void QmitkXnatEditor::ToHigherLevel() { ctkXnatObject* parent = GetEditorInput().Cast()->GetXnatObject()->parent(); if (parent == NULL) { return; } QmitkXnatObjectEditorInput::Pointer oPtr(new QmitkXnatObjectEditorInput(parent)); berry::IEditorInput::Pointer editorInput(oPtr); this->SetInput(editorInput); UpdateList(); } void QmitkXnatEditor::OnObjectActivated(const QModelIndex &index) { if (!index.isValid()) return; ctkXnatObject* child = GetEditorInput().Cast()->GetXnatObject()->children().at(index.row()); if (child != NULL) { ctkXnatFile* file = dynamic_cast(child); if (file != NULL) { // Download file and put into datamanager InternalFileDownload(index); mitk::IDataStorageService* dsService = m_DataStorageServiceTracker.getService(); if (dsService != NULL) { QString name = file->property("Name"); QString filePath = m_DownloadPath + name; if (file->property("collection") == "DICOM") { QDirIterator it(m_DownloadPath, QStringList() << name, QDir::Files, QDirIterator::Subdirectories); while (it.hasNext()) { it.next(); filePath = it.filePath(); } } 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()); } } else { // Updates the root item QmitkXnatObjectEditorInput::Pointer oPtr(new QmitkXnatObjectEditorInput(child)); berry::IEditorInput::Pointer editorInput(oPtr); this->SetInput(editorInput); this->GetEditorInput().Cast()->GetXnatObject()->fetch(); UpdateList(); } } } void QmitkXnatEditor::InternalFileDownload(const QModelIndex& index) { QVariant variant = m_ListModel->data(index, Qt::UserRole); if (variant.isValid()) { ctkXnatFile* file = dynamic_cast(variant.value()); if (file != NULL) { // Testing if the file exists QDir downDir(m_DownloadPath); if (downDir.exists(file->property("Name"))) { MITK_INFO << "File exists already!"; return; } if (file->property("collection") == QString("DICOM")) { ctkXnatObject* parent = file->parent(); QString filePath = m_DownloadPath + parent->property("label") + ".zip"; 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); } else { MITK_INFO << "Download started ..."; MITK_INFO << "..."; QString name = file->property("Name"); QString filePath = m_DownloadPath + name; file->download(filePath); // Testing if the file exists QDir downDir(m_DownloadPath); if (downDir.exists(name)) { MITK_INFO << "Download of " << file->name().toStdString() << " was completed!"; } else { MITK_INFO << "Download of " << file->name().toStdString() << " failed!"; } } } else { MITK_INFO << "Selection was not a file!"; } } } int QmitkXnatEditor::ParentChecker(ctkXnatObject* child) { int sum; if (child->parent() == NULL) { return 0; } else { sum = 1 + ParentChecker(child->parent()); } return sum; } void QmitkXnatEditor::OnDataModelButtonClicked() { for (int i = m_ParentCount; i > 0; i--) { ToHigherLevel(); } } void QmitkXnatEditor::OnProjectButtonClicked() { for (int i = m_ParentCount - 1; i > 0; i--) { ToHigherLevel(); } } void QmitkXnatEditor::OnSubjectButtonClicked() { for (int i = m_ParentCount - 2; i > 0; i--) { ToHigherLevel(); } } void QmitkXnatEditor::OnExperimentButtonClicked() { for (int i = m_ParentCount - 3; i > 0; i--) { ToHigherLevel(); } } void QmitkXnatEditor::OnKindOfDataButtonClicked() { for (int i = m_ParentCount - 4; i > 0; i--) { ToHigherLevel(); } } void QmitkXnatEditor::OnSessionButtonClicked() { for (int i = m_ParentCount - 5; i > 0; i--) { ToHigherLevel(); } } void QmitkXnatEditor::OnResourceButtonClicked() { for (int i = m_ParentCount - 6; i > 0; i--) { ToHigherLevel(); } } void QmitkXnatEditor::UpdateSession(ctkXnatSession* session) { GetSite()->GetWorkbenchWindow()->GetSelectionService()->RemoveSelectionListener(m_SelectionListener.data()); if (session != 0 && session->isOpen()) { m_Controls.labelInfo->setText("Current Position:"); m_Controls.labelInfo->setStyleSheet("QLabel { color: black; }"); // Fill model and show in the GUI QmitkXnatObjectEditorInput::Pointer xoPtr(new QmitkXnatObjectEditorInput(session->dataModel())); berry::IEditorInput::Pointer editorInput(xoPtr); this->SetInput(editorInput); this->GetEditorInput().Cast()->GetXnatObject()->fetch(); UpdateList(); } else { m_Controls.labelInfo->setText("Please check the Preferences of the XNAT Connection.\nMaybe they are not ok."); m_Controls.labelInfo->setStyleSheet("QLabel { color: red; }"); } GetSite()->GetWorkbenchWindow()->GetSelectionService()->AddSelectionListener(m_SelectionListener.data()); } void QmitkXnatEditor::CleanListModel(ctkXnatSession* session) { if (session != 0) { - m_Controls.treeView->setModel(0); + m_Controls.listView->setModel(0); m_ListModel->setRootObject(0); m_Controls.treeView->reset(); } } void QmitkXnatEditor::itemSelected(const QModelIndex &index) { ctkXnatObject* xnatObject = m_ListModel->data(index, Qt::UserRole).value(); 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; m_Controls.buttonDownload->setEnabled(downloadable); m_Controls.labelDownload->setVisible(!downloadable); } diff --git a/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatEditorControls.ui b/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatEditorControls.ui index 7681d055cf..6bc1ff5385 100644 --- a/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatEditorControls.ui +++ b/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatEditorControls.ui @@ -1,473 +1,473 @@ QmitkXnatEditorControls 0 0 719 655 0 0 QmitkTemplate xnat_icon.icoxnat_icon.ico Current Position: 0 0 Server 0 0 >> 0 0 Project 0 0 >> 0 0 Subject 0 0 >> 0 0 Experiment 0 0 >> 0 0 Kind of Data 0 0 >> 0 0 Image Session 0 0 >> 0 0 Resource Folder Qt::Horizontal 40 20 6 QLayout::SetDefaultConstraint 0 0 0 Data Model true 0 0 >> 0 0 Qt::LeftToRight Project 0 0 >> 0 0 Subject 0 0 >> 0 0 Experiment 0 0 >> 0 0 Kind of Data 0 0 >> 0 0 Session 0 0 >> 0 0 Resource Qt::Horizontal 40 20 - + Qt::Horizontal QSizePolicy::Expanding 20 20 0 0 Download 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 2eeac3fbff..28b5fd98bc 100644 --- a/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatTreeBrowserView.cpp +++ b/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatTreeBrowserView.cpp @@ -1,291 +1,830 @@ /*=================================================================== 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 // 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"; QmitkXnatTreeBrowserView::QmitkXnatTreeBrowserView() : -m_TreeModel(new ctkXnatTreeModel()), +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_DataStorageServiceTracker(mitk::org_mitk_gui_qt_xnatinterface_Activator::GetContext()) +m_DownloadPath(berry::Platform::GetPreferencesService()->GetSystemPreferences()->Node("/XnatConnection")->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_NodeMenu = new QMenu(m_Controls.treeView); + 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(NodeTableViewContextMenuRequested(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(activated(const QModelIndex&)), this, SLOT(OnActivatedNode(const QModelIndex&))); + 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(); + + ctkXnatFile* selectedXnatFile = dynamic_cast(selectedXnatObject); + + if (selectedXnatFile != nullptr) + { + this->InternalFileDownload(index, true); + } +} + +void QmitkXnatTreeBrowserView::OnUploadFromDataStorage() +{ + QmitkXnatUploadFromDataStorageDialog dialog; + dialog.SetDataStorage(this->GetDataStorage()); + int result = dialog.exec(); + + if (result == QmitkXnatUploadFromDataStorageDialog::UPLOAD) + { + 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); + 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) { // If the selected node is a file, so show it in MITK 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))); } } 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::InternalFileDownload(const QModelIndex& index, bool loadData) { QVariant variant = m_TreeModel->data(index, Qt::UserRole); if (variant.isValid()) { ctkXnatFile* file = dynamic_cast(variant.value()); if (file != NULL) { QDir downDir(m_DownloadPath); QString filePath = m_DownloadPath + file->name(); - // Testing if the file exists already + // Checking if the file exists already if (downDir.exists(file->name())) { MITK_INFO << "File '" << file->name().toStdString() << "' already exists!"; } else { if (file->property("collection") == QString("DICOM")) { 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); } else { MITK_INFO << "Download started ..."; - MITK_INFO << "..."; + + m_Controls.groupBox->setTitle("Downloading file..."); + m_Controls.groupBox->show(); + m_Controls.progressBar->setValue(0); + file->download(filePath); - // Testing if the file exists now + // Checking if the file exists now if (downDir.exists(file->name())) { - MITK_INFO << "Download of " << file->name().toStdString() << " was completed!"; + 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) { 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()); } } } else { MITK_INFO << "Selection was not a file!"; } } } 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::NodeTableViewContextMenuRequested(const QPoint & pos) +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::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(); + } + + 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(); + +// 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_NodeMenu->clear(); + m_ContextMenu->clear(); 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()) { - ctkXnatFile* file = dynamic_cast(variant.value()); - if (file != NULL) + 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) { - QAction* actShow = new QAction("Download and Open", m_NodeMenu); - QAction* actDownload = new QAction("Download", m_NodeMenu); - m_NodeMenu->addAction(actShow); - m_NodeMenu->addAction(actDownload); - connect(actShow, SIGNAL(triggered()), this, SLOT(OnContextMenuDownloadAndOpenFile())); - connect(actDownload, SIGNAL(triggered()), this, SLOT(OnContextMenuDownloadFile())); - m_NodeMenu->popup(QCursor::pos()); + 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); } } } 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 778ebe8571..9b90eb488f 100644 --- a/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatTreeBrowserView.h +++ b/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatTreeBrowserView.h @@ -1,99 +1,118 @@ /*=================================================================== 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 "ctkXnatTreeModel.h" +#include "QmitkXnatTreeModel.h" // MitkXNAT Module #include "mitkXnatSessionTracker.h" #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; virtual void CreateQtPartControl(QWidget *parent) override; - protected slots: +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 NodeTableViewContextMenuRequested(const QPoint & pos); - + void OnContextMenuRequested(const QPoint & pos); void OnContextMenuDownloadAndOpenFile(); void OnContextMenuDownloadFile(); + void OnContextMenuCreateResourceFolder(); + void OnContextMenuUploadFile(); + void OnContextMenuCreateNewSubject(); + void OnContextMenuCreateNewExperiment(); + + void OnUploadResource(const QList& , ctkXnatObject *, const QModelIndex &parentIndex); + + void OnProgress(QUuid, double); + + void itemSelected(const QModelIndex& index); + + void OnUploadFromDataStorage(); protected: virtual void SetFocus() override; Ui::QmitkXnatTreeBrowserViewControls m_Controls; -private: +private slots: + void OnXnatNodeSelected(const QModelIndex &index); + void OnDownloadSelectedXnatFile(); + void OnCreateResourceFolder(); +private: void InternalFileDownload(const QModelIndex& index, bool loadData); + void InternalFileUpload(ctkXnatFile *file); + ctkXnatResource* InternalAddResourceFolder(ctkXnatObject* parent); + berry::QtSelectionProvider::Pointer m_SelectionProvider; void SetSelectionProvider() override; ctkServiceTracker m_DataStorageServiceTracker; - ctkXnatTreeModel* m_TreeModel; + QmitkXnatTreeModel* m_TreeModel; + mitk::XnatSessionTracker* m_Tracker; QString m_DownloadPath; - QMenu* m_NodeMenu; + QMenu* m_ContextMenu; }; #endif // QMITKXNATTREEBROWSERVIEW_H diff --git a/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatTreeBrowserViewControls.ui b/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatTreeBrowserViewControls.ui index 326b50c01a..06354b8153 100644 --- a/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatTreeBrowserViewControls.ui +++ b/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatTreeBrowserViewControls.ui @@ -1,54 +1,161 @@ QmitkXnatTreeBrowserViewControls 0 0 455 - 975 + 284 0 0 QmitkTemplate - - 0 - Qt::AlignCenter 5 0 + + + + + + false + + + Upload to XNAT + + + + + + + + + + :/xnat/xnat-upload.png:/xnat/xnat-upload.png + + + + 32 + 32 + + + + + + + + false + + + Download File + + + + + + + :/xnat/xnat-download.png:/xnat/xnat-download.png + + + + 32 + 32 + + + + + + + + false + + + Create Folder + + + + + + + :/xnat/xnat-folder.png:/xnat/xnat-folder.png + + + + 32 + 32 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Dowloading file ... + + + + + + 0 + + + + + + + + + - + + +